]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: Define R5900 MMI3 opcode constants
[mirror_qemu.git] / target / mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
c684822a 24#include "qemu/osdep.h"
6af0bf9c 25#include "cpu.h"
26aa3d9a 26#include "internal.h"
76cad711 27#include "disas/disas.h"
63c91552 28#include "exec/exec-all.h"
57fec1fe 29#include "tcg-op.h"
f08b6170 30#include "exec/cpu_ldst.h"
d3d93c6c 31#include "hw/mips/cpudevs.h"
6af0bf9c 32
2ef6175a
RH
33#include "exec/helper-proto.h"
34#include "exec/helper-gen.h"
3b3c1694 35#include "exec/semihost.h"
a7812ae4 36
b44a7fb1 37#include "target/mips/trace.h"
a7e30d84 38#include "trace-tcg.h"
b28425ba 39#include "exec/translator.h"
508127e2 40#include "exec/log.h"
a7e30d84 41
fb7729e2 42#define MIPS_DEBUG_DISAS 0
6af0bf9c 43
7a387fff
TS
44/* MIPS major opcodes */
45#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
46
47enum {
48 /* indirect opcode tables */
7a387fff
TS
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 57 /* arithmetic with immediate */
7a387fff
TS
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
324d9e32 62 /* logic with immediate */
7a387fff
TS
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
324d9e32 67 /* arithmetic with immediate */
7a387fff
TS
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
e37e863f 70 /* Jump and branches */
7a387fff
TS
71 OPC_J = (0x02 << 26),
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
b231c103 81 OPC_JALX = (0x1D << 26),
d4ea6acd 82 OPC_DAUI = (0x1D << 26),
e37e863f 83 /* Load and stores */
7a387fff
TS
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
364d4831 90 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
364d4831 105 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
e37e863f 109 /* Floating point load/store */
7a387fff
TS
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
31837be3
YK
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
7a387fff
TS
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
239dfebe
YK
145 /* MSA ASE, same as MDMX */
146 OPC_MSA = OPC_MDMX,
e37e863f 147 /* Cache and prefetch */
7a387fff
TS
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
152};
153
154/* PC-relative address computation / loads */
155#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157enum {
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
162
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
166
167 /* Other */
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
169};
170
171/* MIPS special opcodes */
7a387fff
TS
172#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173
e37e863f
FB
174enum {
175 /* Shifts */
7a387fff 176 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 181 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 185 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 193 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 199 /* Multiplication / division */
7a387fff
TS
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 208
e37e863f 209 /* 2 registers arithmetic / logic */
7a387fff
TS
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 224 /* Jumps */
7a387fff
TS
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 227 /* Traps */
7a387fff
TS
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 234 /* HI / LO registers load & stores */
7a387fff
TS
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 239 /* Conditional moves */
7a387fff
TS
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 242
b691d9d2
LA
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
245
7a387fff 246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
247
248 /* Special */
a0d700e4 249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
254
7a387fff
TS
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259};
260
b42ee5e1
LA
261/* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265enum {
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
274
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
283
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
289
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
292};
293
e9c71dd1
TS
294/* Multiplication variants of the vr54xx. */
295#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297enum {
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312};
313
7a387fff
TS
314/* REGIMM (rt field) opcodes */
315#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317enum {
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
334
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
337};
338
7a387fff
TS
339/* Special2 opcodes */
340#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
341
e37e863f 342enum {
7a387fff
TS
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
349 /* Loongson 2F */
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 362 /* Misc */
7a387fff
TS
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 367 /* Special */
7a387fff
TS
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
369};
370
371/* Special3 opcodes */
372#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
373
374enum {
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
388
389 /* Loongson 2E */
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
402
403 /* MIPS DSP Load */
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 425 /* MIPS DSP Append Sub-class */
26690560 426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 431
76964147
JH
432 /* EVA */
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
449
4368b29a 450 /* R6 */
bf7910c6
LA
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
457};
458
7a387fff
TS
459/* BSHFL opcodes */
460#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
e37e863f 462enum {
15eacb9b
YK
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
467 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
469};
470
7a387fff
TS
471/* DBSHFL opcodes */
472#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
473
e37e863f 474enum {
15eacb9b
YK
475 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
476 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
477 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
480};
481
e45a93e2
JL
482/* MIPS DSP REGIMM opcodes */
483enum {
484 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 485 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
486};
487
9b1a1d68
JL
488#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489/* MIPS DSP Load */
490enum {
491 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
493 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 494 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
495};
496
461c08df
JL
497#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498enum {
499 /* MIPS DSP Arithmetic Sub-class */
500 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
505 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
506 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
512 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
513 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
516 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
517 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
523 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
524 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
525};
526
527#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
543 /* MIPS DSP Multiply Sub-class insns */
544 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
548};
549
550#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
566 /* DSP Bit/Manipulation Sub-class */
567 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
572};
573
574#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
584 /* DSP Compare-Pick Sub-class */
585 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 600};
a22260ae 601
77c5fa8b
JL
602#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603enum {
604 /* MIPS DSP GPR-Based Shift Sub-class */
605 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
627};
461c08df 628
a22260ae
JL
629#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630enum {
631 /* MIPS DSP Multiply Sub-class insns */
632 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
654};
655
1cb6686c
JL
656#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657enum {
658 /* DSP Bit/Manipulation Sub-class */
659 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
660};
661
26690560
JL
662#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663enum {
df6126a7 664 /* MIPS DSP Append Sub-class */
26690560
JL
665 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
666 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
668};
669
b53371ed
JL
670#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
672 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
685 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
686 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
687 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
688 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
689 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
690};
691
461c08df
JL
692#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
693enum {
694 /* MIPS DSP Arithmetic Sub-class */
695 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
712 /* DSP Bit/Manipulation Sub-class */
713 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 719};
461c08df 720
461c08df
JL
721#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722enum {
a22260ae
JL
723 /* MIPS DSP Multiply Sub-class insns */
724 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
729 /* MIPS DSP Arithmetic Sub-class */
730 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
751};
461c08df 752
461c08df
JL
753#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754enum {
26690560
JL
755 /* DSP Compare-Pick Sub-class */
756 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
775 /* MIPS DSP Arithmetic Sub-class */
776 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
784};
461c08df 785
26690560
JL
786#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787enum {
df6126a7 788 /* DSP Append Sub-class */
26690560
JL
789 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
790 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
793};
26690560 794
b53371ed
JL
795#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796enum {
797 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
799 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
819};
820
1cb6686c
JL
821#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
822enum {
823 /* DSP Bit/Manipulation Sub-class */
824 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
825};
1cb6686c 826
a22260ae
JL
827#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828enum {
829 /* MIPS DSP Multiply Sub-class insns */
830 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
856};
a22260ae 857
77c5fa8b
JL
858#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
859enum {
860 /* MIPS DSP GPR-Based Shift Sub-class */
861 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
887};
77c5fa8b 888
7a387fff
TS
889/* Coprocessor 0 (rs field) */
890#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
891
6ea83fed 892enum {
7a387fff
TS
893 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
894 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 895 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
896 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
897 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 898 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 899 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
900 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
901 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 902 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
903 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
904 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
905 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
906 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
907 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
908 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
909 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
910 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
911 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
912 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
913 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
914 OPC_C0_A = (0x1A << 21) | OPC_CP0,
915 OPC_C0_B = (0x1B << 21) | OPC_CP0,
916 OPC_C0_C = (0x1C << 21) | OPC_CP0,
917 OPC_C0_D = (0x1D << 21) | OPC_CP0,
918 OPC_C0_E = (0x1E << 21) | OPC_CP0,
919 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 920};
7a387fff
TS
921
922/* MFMC0 opcodes */
b48cfdff 923#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
924
925enum {
ead9360e
TS
926 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
929 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
930 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
932 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
934};
935
936/* Coprocessor 0 (with rs == C0) */
937#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
938
939enum {
940 OPC_TLBR = 0x01 | OPC_C0,
941 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
942 OPC_TLBINV = 0x03 | OPC_C0,
943 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
944 OPC_TLBWR = 0x06 | OPC_C0,
945 OPC_TLBP = 0x08 | OPC_C0,
946 OPC_RFE = 0x10 | OPC_C0,
947 OPC_ERET = 0x18 | OPC_C0,
948 OPC_DERET = 0x1F | OPC_C0,
949 OPC_WAIT = 0x20 | OPC_C0,
950};
951
952/* Coprocessor 1 (rs field) */
953#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
bf4120ad
NF
955/* Values for the fmt field in FP instructions */
956enum {
957 /* 0 - 15 are reserved */
e459440a
AJ
958 FMT_S = 16, /* single fp */
959 FMT_D = 17, /* double fp */
960 FMT_E = 18, /* extended fp */
961 FMT_Q = 19, /* quad fp */
962 FMT_W = 20, /* 32-bit fixed */
963 FMT_L = 21, /* 64-bit fixed */
964 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
965 /* 23 - 31 are reserved */
966};
967
7a387fff
TS
968enum {
969 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
970 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
971 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 972 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
973 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
974 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
975 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 976 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 977 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
978 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
979 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
980 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
981 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
982 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
983 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
984 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
985 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
986 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
987 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
988 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
989 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
990 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
991 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
992 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
993 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
994 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
995 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
996 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
997 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
998 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
999};
1000
5a5012ec
TS
1001#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1002#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1003
7a387fff
TS
1004enum {
1005 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1006 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1007 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1008 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1009};
1010
5a5012ec
TS
1011enum {
1012 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1013 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1014};
1015
1016enum {
1017 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1018 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1019};
7a387fff
TS
1020
1021#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1022
1023enum {
1024 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1025 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1026 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1027 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1028 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1029 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1030 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1031 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1032 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1033 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1034 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1035};
1036
bd277fa1
RH
1037#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039enum {
1040 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1041 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1043 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1044 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1045 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1047 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1048
1049 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1050 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1052 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1053 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1054 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1056 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1057
1058 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1059 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1063 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1064 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1065 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1066
1067 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1072 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1073 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1074 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1075
1076 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1077 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1078 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1079 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1080 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1081 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1082
1083 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1091 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1092 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1093 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1094 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1095 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1098 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1099 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1100 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1101 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1106 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1107 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1113 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1114 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1119 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1121 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1122 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1126 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1128 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1130 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131};
1132
1133
e0c84da7
TS
1134#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136enum {
1137 OPC_LWXC1 = 0x00 | OPC_CP3,
1138 OPC_LDXC1 = 0x01 | OPC_CP3,
1139 OPC_LUXC1 = 0x05 | OPC_CP3,
1140 OPC_SWXC1 = 0x08 | OPC_CP3,
1141 OPC_SDXC1 = 0x09 | OPC_CP3,
1142 OPC_SUXC1 = 0x0D | OPC_CP3,
1143 OPC_PREFX = 0x0F | OPC_CP3,
1144 OPC_ALNV_PS = 0x1E | OPC_CP3,
1145 OPC_MADD_S = 0x20 | OPC_CP3,
1146 OPC_MADD_D = 0x21 | OPC_CP3,
1147 OPC_MADD_PS = 0x26 | OPC_CP3,
1148 OPC_MSUB_S = 0x28 | OPC_CP3,
1149 OPC_MSUB_D = 0x29 | OPC_CP3,
1150 OPC_MSUB_PS = 0x2E | OPC_CP3,
1151 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1152 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1153 OPC_NMADD_PS= 0x36 | OPC_CP3,
1154 OPC_NMSUB_S = 0x38 | OPC_CP3,
1155 OPC_NMSUB_D = 0x39 | OPC_CP3,
1156 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157};
1158
239dfebe
YK
1159/* MSA Opcodes */
1160#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1161enum {
1162 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1163 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1164 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1165 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1166 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1167 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1168 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1169 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1170 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1171 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1172 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1173 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1174 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1175 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1176 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1177 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1178 OPC_MSA_ELM = 0x19 | OPC_MSA,
1179 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1180 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1181 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1182 OPC_MSA_VEC = 0x1E | OPC_MSA,
1183
1184 /* MI10 instruction */
1185 OPC_LD_B = (0x20) | OPC_MSA,
1186 OPC_LD_H = (0x21) | OPC_MSA,
1187 OPC_LD_W = (0x22) | OPC_MSA,
1188 OPC_LD_D = (0x23) | OPC_MSA,
1189 OPC_ST_B = (0x24) | OPC_MSA,
1190 OPC_ST_H = (0x25) | OPC_MSA,
1191 OPC_ST_W = (0x26) | OPC_MSA,
1192 OPC_ST_D = (0x27) | OPC_MSA,
1193};
1194
1195enum {
1196 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1198 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1199 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1200 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1201 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1202 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1203 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1204 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1205 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1206 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1207 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1208 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210 /* I8 instruction */
1211 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1212 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1214 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1215 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1216 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1217 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1218 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1220 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222 /* VEC/2R/2RF instruction */
1223 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1224 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1225 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1226 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1227 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1228 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1229 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1230
1231 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1232 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1233
1234 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240 /* 2RF instruction df(bit 16) = _w, _d */
1241 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1242 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1245 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1246 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1247 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1248 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1249 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1250 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1251 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1252 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1253 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1254 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1255 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1256 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1257
1258 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1260 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1261 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1262 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1263 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1264 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1265 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1266 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1267 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1268 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1269 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1270 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1272 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1274 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1275 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1276 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1278 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1279 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1282 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1283 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1284 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1285 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1292 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1293 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1294 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1295 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1296 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1297 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1298 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1299 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1300 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1301 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1310 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1311 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1312 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1313 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1314 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1315 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1316 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1317 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1318 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1319 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1320 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1321 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334 /* 3RF instruction _df(bit 21) = _w, _d */
1335 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1336 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1337 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1338 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1339 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1340 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1342 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1343 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1346 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1348 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1351 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1353 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1357 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1358 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1361 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1362 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1363 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1364 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1365 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1366 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1367 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1369 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1370 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1372 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1373 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1379 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1380 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1381 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1382 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1383 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1384 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1385 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1386 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1387 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1388 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1389 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1390};
1391
b158d449
AM
1392
1393/*
1394 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1395 * ============================================
1396 *
1397 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1398 * instructions set. It is designed to fit the needs of signal, graphical and
1399 * video processing applications. MXU instruction set is used in Xburst family
1400 * of microprocessors by Ingenic.
1401 *
1402 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1403 * the control register.
1404 *
1d0e663c
AM
1405 * The notation used in MXU assembler mnemonics:
1406 *
1407 * XRa, XRb, XRc, XRd - MXU registers
1408 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1409 * s12 - a subfield of an instruction code
1410 * strd2 - a subfield of an instruction code
1411 * eptn2 - a subfield of an instruction code
1412 * eptn3 - a subfield of an instruction code
1413 * optn2 - a subfield of an instruction code
1414 * optn3 - a subfield of an instruction code
1415 * sft4 - a subfield of an instruction code
1416 *
1417 * Load/Store instructions Multiplication instructions
1418 * ----------------------- ---------------------------
1419 *
1420 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1421 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1422 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1423 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1424 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1425 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1426 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1427 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1428 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1429 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1430 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1431 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1432 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1433 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1434 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1435 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1436 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1437 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1438 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1439 * S16SDI XRa, Rb, s10, eptn2
1440 * S8LDD XRa, Rb, s8, eptn3
1441 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1442 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1443 * S8SDI XRa, Rb, s8, eptn3
1444 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1445 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1446 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1447 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1448 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1449 * S32CPS XRa, XRb, XRc
1450 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1451 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1452 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1453 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1454 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1455 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1456 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1457 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1458 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1459 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1460 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1461 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1462 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1463 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1464 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1465 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1466 * Q8SLT XRa, XRb, XRc
1467 * Q8SLTU XRa, XRb, XRc
1468 * Q8MOVZ XRa, XRb, XRc Shift instructions
1469 * Q8MOVN XRa, XRb, XRc ------------------
1470 *
1471 * D32SLL XRa, XRb, XRc, XRd, sft4
1472 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1473 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1474 * D32SARL XRa, XRb, XRc, sft4
1475 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1476 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1477 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1478 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1479 * Q16SLL XRa, XRb, XRc, XRd, sft4
1480 * Q16SLR XRa, XRb, XRc, XRd, sft4
1481 * Miscelaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1482 * ------------------------- Q16SLLV XRa, XRb, Rb
1483 * Q16SLRV XRa, XRb, Rb
1484 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1485 * S32ALN XRa, XRb, XRc, Rb
1486 * S32ALNI XRa, XRb, XRc, s3
1487 * S32LUI XRa, s8, optn3 Move instructions
1488 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1489 * S32EXTRV XRa, XRb, Rs, Rt
1490 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1491 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1492 *
9ef5bff9
AM
1493 *
1494 * bits
1495 * 05..00
1496 *
1497 * ┌─ 000000 ─ OPC_MXU_S32MADD
1498 * ├─ 000001 ─ OPC_MXU_S32MADDU
1499 * ├─ 000010 ─ <not assigned>
1500 * │ 20..18
1501 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1502 * │ ├─ 001 ─ OPC_MXU_S32MIN
1503 * │ ├─ 010 ─ OPC_MXU_D16MAX
1504 * │ ├─ 011 ─ OPC_MXU_D16MIN
1505 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1506 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1507 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1508 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1509 * ├─ 000100 ─ OPC_MXU_S32MSUB
1510 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1511 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1512 * │ ├─ 001 ─ OPC_MXU_D16SLT
1513 * │ ├─ 010 ─ OPC_MXU_D16AVG
1514 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1515 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1516 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1517 * │ └─ 111 ─ OPC_MXU_Q8ADD
1518 * │
1519 * │ 20..18
1520 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1521 * │ ├─ 010 ─ OPC_MXU_D16CPS
1522 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1523 * │ └─ 110 ─ OPC_MXU_Q16SAT
1524 * ├─ 001000 ─ OPC_MXU_D16MUL
1525 * │ 25..24
1526 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1527 * │ └─ 01 ─ OPC_MXU_D16MULE
1528 * ├─ 001010 ─ OPC_MXU_D16MAC
1529 * ├─ 001011 ─ OPC_MXU_D16MACF
1530 * ├─ 001100 ─ OPC_MXU_D16MADL
1531 * │ 25..24
1532 * ├─ 001101 ─ OPC_MXU__POOL04 ─┬─ 00 ─ OPC_MXU_S16MAD
1533 * │ └─ 01 ─ OPC_MXU_S16MAD_1
1534 * ├─ 001110 ─ OPC_MXU_Q16ADD
1535 * ├─ 001111 ─ OPC_MXU_D16MACE
1536 * │ 23
1537 * ├─ 010000 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32LDD
1538 * │ └─ 1 ─ OPC_MXU_S32LDDR
1539 * │
1540 * │ 23
1541 * ├─ 010001 ─ OPC_MXU__POOL06 ─┬─ 0 ─ OPC_MXU_S32STD
1542 * │ └─ 1 ─ OPC_MXU_S32STDR
1543 * │
1544 * │ 13..10
1545 * ├─ 010010 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1546 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1547 * │
1548 * │ 13..10
1549 * ├─ 010011 ─ OPC_MXU__POOL08 ─┬─ 0000 ─ OPC_MXU_S32STDV
1550 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1551 * │
1552 * │ 23
1553 * ├─ 010100 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32LDI
1554 * │ └─ 1 ─ OPC_MXU_S32LDIR
1555 * │
1556 * │ 23
1557 * ├─ 010101 ─ OPC_MXU__POOL10 ─┬─ 0 ─ OPC_MXU_S32SDI
1558 * │ └─ 1 ─ OPC_MXU_S32SDIR
1559 * │
1560 * │ 13..10
1561 * ├─ 010110 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1562 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1563 * │
1564 * │ 13..10
1565 * ├─ 010111 ─ OPC_MXU__POOL12 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1566 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1567 * ├─ 011000 ─ OPC_MXU_D32ADD
1568 * │ 23..22
1569 * MXU ├─ 011001 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_D32ACC
1570 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1571 * │ └─ 10 ─ OPC_MXU_D32ASUM
1572 * ├─ 011010 ─ <not assigned>
1573 * │ 23..22
1574 * ├─ 011011 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q16ACC
1575 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1576 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1577 * │
1578 * │ 23..22
1579 * ├─ 011100 ─ OPC_MXU__POOL15 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1580 * │ ├─ 01 ─ OPC_MXU_D8SUM
1581 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1582 * ├─ 011110 ─ <not assigned>
1583 * ├─ 011111 ─ <not assigned>
1584 * ├─ 100000 ─ <not assigned>
1585 * ├─ 100001 ─ <not assigned>
1586 * ├─ 100010 ─ OPC_MXU_S8LDD
1587 * ├─ 100011 ─ OPC_MXU_S8STD
1588 * ├─ 100100 ─ OPC_MXU_S8LDI
1589 * ├─ 100101 ─ OPC_MXU_S8SDI
1590 * │ 15..14
1591 * ├─ 100110 ─ OPC_MXU__POOL16 ─┬─ 00 ─ OPC_MXU_S32MUL
1592 * │ ├─ 00 ─ OPC_MXU_S32MULU
1593 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1594 * │ └─ 00 ─ OPC_MXU_S32EXTRV
1595 * │
1596 * │ 20..18
1597 * ├─ 100111 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_D32SARW
1598 * │ ├─ 001 ─ OPC_MXU_S32ALN
1599 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1600 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1601 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1602 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1603 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1604 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1605 * ├─ 101000 ─ <not assigned>
1606 * ├─ 101001 ─ <not assigned>
1607 * ├─ 101010 ─ <not assigned>
1608 * ├─ 101011 ─ <not assigned>
1609 * ├─ 101100 ─ <not assigned>
1610 * ├─ 101101 ─ <not assigned>
1611 * ├─ 101110 ─ OPC_MXU_S32M2I
1612 * ├─ 101111 ─ OPC_MXU_S32I2M
1613 * ├─ 110000 ─ OPC_MXU_D32SLL
1614 * ├─ 110001 ─ OPC_MXU_D32SLR
1615 * ├─ 110010 ─ OPC_MXU_D32SARL
1616 * ├─ 110011 ─ OPC_MXU_D32SAR
1617 * ├─ 110100 ─ OPC_MXU_Q16SLL
1618 * ├─ 110101 ─ OPC_MXU_Q16SLR 20..18
1619 * ├─ 110110 ─ OPC_MXU__POOL18 ─┬─ 000 ─ OPC_MXU_D32SLLV
1620 * │ ├─ 001 ─ OPC_MXU_D32SLRV
1621 * │ ├─ 010 ─ OPC_MXU_D32SARV
1622 * │ ├─ 011 ─ OPC_MXU_Q16SLLV
1623 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1624 * │ └─ 101 ─ OPC_MXU_Q16SARV
1625 * ├─ 110111 ─ OPC_MXU_Q16SAR
1626 * │ 23..22
1627 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1628 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1629 * │
1630 * │ 20..18
1631 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1632 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1633 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1634 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1635 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1636 * │ └─ 101 ─ OPC_MXU_S32MOV
1637 * │
1638 * │ 23..22
1639 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1640 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1641 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1642 * ├─ 111100 ─ OPC_MXU_Q8MADL
1643 * ├─ 111101 ─ OPC_MXU_S32SFL
1644 * ├─ 111110 ─ OPC_MXU_Q8SAD
1645 * └─ 111111 ─ <not assigned>
1646 *
1647 *
b158d449
AM
1648 * Compiled after:
1649 *
1650 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1651 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1652 */
1653
8bacd1ff
AM
1654enum {
1655 OPC_MXU_S32MADD = 0x00,
1656 OPC_MXU_S32MADDU = 0x01,
1657 /* not assigned 0x02 */
1658 OPC_MXU__POOL00 = 0x03,
1659 OPC_MXU_S32MSUB = 0x04,
1660 OPC_MXU_S32MSUBU = 0x05,
1661 OPC_MXU__POOL01 = 0x06,
1662 OPC_MXU__POOL02 = 0x07,
1663 OPC_MXU_D16MUL = 0x08,
1664 OPC_MXU__POOL03 = 0x09,
1665 OPC_MXU_D16MAC = 0x0A,
1666 OPC_MXU_D16MACF = 0x0B,
1667 OPC_MXU_D16MADL = 0x0C,
1668 OPC_MXU__POOL04 = 0x0D,
1669 OPC_MXU_Q16ADD = 0x0E,
1670 OPC_MXU_D16MACE = 0x0F,
1671 OPC_MXU__POOL05 = 0x10,
1672 OPC_MXU__POOL06 = 0x11,
1673 OPC_MXU__POOL07 = 0x12,
1674 OPC_MXU__POOL08 = 0x13,
1675 OPC_MXU__POOL09 = 0x14,
1676 OPC_MXU__POOL10 = 0x15,
1677 OPC_MXU__POOL11 = 0x16,
1678 OPC_MXU__POOL12 = 0x17,
1679 OPC_MXU_D32ADD = 0x18,
1680 OPC_MXU__POOL13 = 0x19,
1681 /* not assigned 0x1A */
1682 OPC_MXU__POOL14 = 0x1B,
1683 OPC_MXU__POOL15 = 0x1C,
1684 OPC_MXU_Q8ACCE = 0x1D,
1685 /* not assigned 0x1E */
1686 /* not assigned 0x1F */
1687 /* not assigned 0x20 */
1688 /* not assigned 0x21 */
1689 OPC_MXU_S8LDD = 0x22,
1690 OPC_MXU_S8STD = 0x23,
1691 OPC_MXU_S8LDI = 0x24,
1692 OPC_MXU_S8SDI = 0x25,
1693 OPC_MXU__POOL16 = 0x26,
1694 OPC_MXU__POOL17 = 0x27,
1695 OPC_MXU_LXB = 0x28,
1696 /* not assigned 0x29 */
1697 OPC_MXU_S16LDD = 0x2A,
1698 OPC_MXU_S16STD = 0x2B,
1699 OPC_MXU_S16LDI = 0x2C,
1700 OPC_MXU_S16SDI = 0x2D,
1701 OPC_MXU_S32M2I = 0x2E,
1702 OPC_MXU_S32I2M = 0x2F,
1703 OPC_MXU_D32SLL = 0x30,
1704 OPC_MXU_D32SLR = 0x31,
1705 OPC_MXU_D32SARL = 0x32,
1706 OPC_MXU_D32SAR = 0x33,
1707 OPC_MXU_Q16SLL = 0x34,
1708 OPC_MXU_Q16SLR = 0x35,
1709 OPC_MXU__POOL18 = 0x36,
1710 OPC_MXU_Q16SAR = 0x37,
1711 OPC_MXU__POOL19 = 0x38,
1712 OPC_MXU__POOL20 = 0x39,
1713 OPC_MXU__POOL21 = 0x3A,
1714 OPC_MXU_Q16SCOP = 0x3B,
1715 OPC_MXU_Q8MADL = 0x3C,
1716 OPC_MXU_S32SFL = 0x3D,
1717 OPC_MXU_Q8SAD = 0x3E,
1718 /* not assigned 0x3F */
1719};
1720
1721
1722/*
1723 * MXU pool 00
1724 */
1725enum {
1726 OPC_MXU_S32MAX = 0x00,
1727 OPC_MXU_S32MIN = 0x01,
1728 OPC_MXU_D16MAX = 0x02,
1729 OPC_MXU_D16MIN = 0x03,
1730 OPC_MXU_Q8MAX = 0x04,
1731 OPC_MXU_Q8MIN = 0x05,
1732 OPC_MXU_Q8SLT = 0x06,
1733 OPC_MXU_Q8SLTU = 0x07,
1734};
1735
1736/*
1737 * MXU pool 01
1738 */
1739enum {
1740 OPC_MXU_S32SLT = 0x00,
1741 OPC_MXU_D16SLT = 0x01,
1742 OPC_MXU_D16AVG = 0x02,
1743 OPC_MXU_D16AVGR = 0x03,
1744 OPC_MXU_Q8AVG = 0x04,
1745 OPC_MXU_Q8AVGR = 0x05,
1746 OPC_MXU_Q8ADD = 0x07,
1747};
1748
1749/*
1750 * MXU pool 02
1751 */
1752enum {
1753 OPC_MXU_S32CPS = 0x00,
1754 OPC_MXU_D16CPS = 0x02,
1755 OPC_MXU_Q8ABD = 0x04,
1756 OPC_MXU_Q16SAT = 0x06,
1757};
1758
1759/*
1760 * MXU pool 03
1761 */
1762enum {
1763 OPC_MXU_D16MULF = 0x00,
1764 OPC_MXU_D16MULE = 0x01,
1765};
1766
1767/*
1768 * MXU pool 04
1769 */
1770enum {
1771 OPC_MXU_S16MAD = 0x00,
1772 OPC_MXU_S16MAD_1 = 0x01,
1773};
1774
1775/*
1776 * MXU pool 05
1777 */
1778enum {
1779 OPC_MXU_S32LDD = 0x00,
1780 OPC_MXU_S32LDDR = 0x01,
1781};
1782
1783/*
1784 * MXU pool 06
1785 */
1786enum {
1787 OPC_MXU_S32STD = 0x00,
1788 OPC_MXU_S32STDR = 0x01,
1789};
1790
1791/*
1792 * MXU pool 07
1793 */
1794enum {
1795 OPC_MXU_S32LDDV = 0x00,
1796 OPC_MXU_S32LDDVR = 0x01,
1797};
1798
1799/*
1800 * MXU pool 08
1801 */
1802enum {
1803 OPC_MXU_S32STDV = 0x00,
1804 OPC_MXU_S32STDVR = 0x01,
1805};
1806
1807/*
1808 * MXU pool 09
1809 */
1810enum {
1811 OPC_MXU_S32LDI = 0x00,
1812 OPC_MXU_S32LDIR = 0x01,
1813};
1814
1815/*
1816 * MXU pool 10
1817 */
1818enum {
1819 OPC_MXU_S32SDI = 0x00,
1820 OPC_MXU_S32SDIR = 0x01,
1821};
1822
1823/*
1824 * MXU pool 11
1825 */
1826enum {
1827 OPC_MXU_S32LDIV = 0x00,
1828 OPC_MXU_S32LDIVR = 0x01,
1829};
1830
1831/*
1832 * MXU pool 12
1833 */
1834enum {
1835 OPC_MXU_S32SDIV = 0x00,
1836 OPC_MXU_S32SDIVR = 0x01,
1837};
1838
1839/*
1840 * MXU pool 13
1841 */
1842enum {
1843 OPC_MXU_D32ACC = 0x00,
1844 OPC_MXU_D32ACCM = 0x01,
1845 OPC_MXU_D32ASUM = 0x02,
1846};
1847
1848/*
1849 * MXU pool 14
1850 */
1851enum {
1852 OPC_MXU_Q16ACC = 0x00,
1853 OPC_MXU_Q16ACCM = 0x01,
1854 OPC_MXU_Q16ASUM = 0x02,
1855};
1856
1857/*
1858 * MXU pool 15
1859 */
1860enum {
1861 OPC_MXU_Q8ADDE = 0x00,
1862 OPC_MXU_D8SUM = 0x01,
1863 OPC_MXU_D8SUMC = 0x02,
1864};
1865
1866/*
1867 * MXU pool 16
1868 */
1869enum {
1870 OPC_MXU_S32MUL = 0x00,
1871 OPC_MXU_S32MULU = 0x01,
1872 OPC_MXU_S32EXTR = 0x02,
1873 OPC_MXU_S32EXTRV = 0x03,
1874};
1875
1876/*
1877 * MXU pool 17
1878 */
1879enum {
1880 OPC_MXU_D32SARW = 0x00,
1881 OPC_MXU_S32ALN = 0x01,
1882 OPC_MXU_S32ALNI = 0x02,
1883 OPC_MXU_S32NOR = 0x03,
1884 OPC_MXU_S32AND = 0x04,
1885 OPC_MXU_S32OR = 0x05,
1886 OPC_MXU_S32XOR = 0x06,
1887 OPC_MXU_S32LUI = 0x07,
1888};
1889
1890/*
1891 * MXU pool 18
1892 */
1893enum {
1894 OPC_MXU_D32SLLV = 0x00,
1895 OPC_MXU_D32SLRV = 0x01,
1896 OPC_MXU_D32SARV = 0x03,
1897 OPC_MXU_Q16SLLV = 0x04,
1898 OPC_MXU_Q16SLRV = 0x05,
1899 OPC_MXU_Q16SARV = 0x07,
1900};
1901
1902/*
1903 * MXU pool 19
1904 */
1905enum {
1906 OPC_MXU_Q8MUL = 0x00,
1907 OPC_MXU_Q8MULSU = 0x01,
1908};
1909
1910/*
1911 * MXU pool 20
1912 */
1913enum {
1914 OPC_MXU_Q8MOVZ = 0x00,
1915 OPC_MXU_Q8MOVN = 0x01,
1916 OPC_MXU_D16MOVZ = 0x02,
1917 OPC_MXU_D16MOVN = 0x03,
1918 OPC_MXU_S32MOVZ = 0x04,
1919 OPC_MXU_S32MOVN = 0x05,
1920};
1921
1922/*
1923 * MXU pool 21
1924 */
1925enum {
1926 OPC_MXU_Q8MAC = 0x00,
1927 OPC_MXU_Q8MACSU = 0x01,
1928};
1929
497f072b
FN
1930/*
1931 * Overview of the TX79-specific instruction set
1932 * =============================================
1933 *
1934 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1935 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1936 * instructions and certain multimedia instructions (MMIs). These MMIs
1937 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1938 * or sixteen 8-bit paths.
1939 *
1940 * Reference:
1941 *
1942 * The Toshiba TX System RISC TX79 Core Architecture manual,
1943 * https://wiki.qemu.org/File:C790.pdf
1944 *
1945 * Three-Operand Multiply and Multiply-Add (4 instructions)
1946 * --------------------------------------------------------
1947 * MADD [rd,] rs, rt Multiply/Add
1948 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1949 * MULT [rd,] rs, rt Multiply (3-operand)
1950 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1951 *
1952 * Multiply Instructions for Pipeline 1 (10 instructions)
1953 * ------------------------------------------------------
1954 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1955 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1956 * DIV1 rs, rt Divide Pipeline 1
1957 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1958 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1959 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1960 * MFHI1 rd Move From HI1 Register
1961 * MFLO1 rd Move From LO1 Register
1962 * MTHI1 rs Move To HI1 Register
1963 * MTLO1 rs Move To LO1 Register
1964 *
1965 * Arithmetic (19 instructions)
1966 * ----------------------------
1967 * PADDB rd, rs, rt Parallel Add Byte
1968 * PSUBB rd, rs, rt Parallel Subtract Byte
1969 * PADDH rd, rs, rt Parallel Add Halfword
1970 * PSUBH rd, rs, rt Parallel Subtract Halfword
1971 * PADDW rd, rs, rt Parallel Add Word
1972 * PSUBW rd, rs, rt Parallel Subtract Word
1973 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1974 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1975 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1976 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1977 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1978 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1979 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1980 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1981 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1982 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1983 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1984 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1985 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1986 *
1987 * Min/Max (4 instructions)
1988 * ------------------------
1989 * PMAXH rd, rs, rt Parallel Maximum Halfword
1990 * PMINH rd, rs, rt Parallel Minimum Halfword
1991 * PMAXW rd, rs, rt Parallel Maximum Word
1992 * PMINW rd, rs, rt Parallel Minimum Word
1993 *
1994 * Absolute (2 instructions)
1995 * -------------------------
1996 * PABSH rd, rt Parallel Absolute Halfword
1997 * PABSW rd, rt Parallel Absolute Word
1998 *
1999 * Logical (4 instructions)
2000 * ------------------------
2001 * PAND rd, rs, rt Parallel AND
2002 * POR rd, rs, rt Parallel OR
2003 * PXOR rd, rs, rt Parallel XOR
2004 * PNOR rd, rs, rt Parallel NOR
2005 *
2006 * Shift (9 instructions)
2007 * ----------------------
2008 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2009 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2010 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2011 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2012 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2013 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2014 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2015 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2016 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2017 *
2018 * Compare (6 instructions)
2019 * ------------------------
2020 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2021 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2022 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2023 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2024 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2025 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2026 *
2027 * LZC (1 instruction)
2028 * -------------------
2029 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2030 *
2031 * Quadword Load and Store (2 instructions)
2032 * ----------------------------------------
2033 * LQ rt, offset(base) Load Quadword
2034 * SQ rt, offset(base) Store Quadword
2035 *
2036 * Multiply and Divide (19 instructions)
2037 * -------------------------------------
2038 * PMULTW rd, rs, rt Parallel Multiply Word
2039 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2040 * PDIVW rs, rt Parallel Divide Word
2041 * PDIVUW rs, rt Parallel Divide Unsigned Word
2042 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2043 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2044 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2045 * PMULTH rd, rs, rt Parallel Multiply Halfword
2046 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2047 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2048 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2049 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2050 * PDIVBW rs, rt Parallel Divide Broadcast Word
2051 * PMFHI rd Parallel Move From HI Register
2052 * PMFLO rd Parallel Move From LO Register
2053 * PMTHI rs Parallel Move To HI Register
2054 * PMTLO rs Parallel Move To LO Register
2055 * PMFHL rd Parallel Move From HI/LO Register
2056 * PMTHL rs Parallel Move To HI/LO Register
2057 *
2058 * Pack/Extend (11 instructions)
2059 * -----------------------------
2060 * PPAC5 rd, rt Parallel Pack to 5 bits
2061 * PPACB rd, rs, rt Parallel Pack to Byte
2062 * PPACH rd, rs, rt Parallel Pack to Halfword
2063 * PPACW rd, rs, rt Parallel Pack to Word
2064 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2065 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2066 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2067 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2068 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2069 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2070 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2071 *
2072 * Others (16 instructions)
2073 * ------------------------
2074 * PCPYH rd, rt Parallel Copy Halfword
2075 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2076 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2077 * PREVH rd, rt Parallel Reverse Halfword
2078 * PINTH rd, rs, rt Parallel Interleave Halfword
2079 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2080 * PEXEH rd, rt Parallel Exchange Even Halfword
2081 * PEXCH rd, rt Parallel Exchange Center Halfword
2082 * PEXEW rd, rt Parallel Exchange Even Word
2083 * PEXCW rd, rt Parallel Exchange Center Word
2084 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2085 * MFSA rd Move from Shift Amount Register
2086 * MTSA rs Move to Shift Amount Register
2087 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2088 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2089 * PROT3W rd, rt Parallel Rotate 3 Words
f99c0d6d
FN
2090 *
2091 * The TX79-specific Multimedia Instruction encodings
2092 * ==================================================
2093 *
2094 * TX79 Multimedia Instruction encoding table keys:
2095 *
2096 * * This code is reserved for future use. An attempt to execute it
2097 * causes a Reserved Instruction exception.
2098 * % This code indicates an instruction class. The instruction word
2099 * must be further decoded by examining additional tables that show
2100 * the values for other instruction fields.
2101 * # This code is reserved for the unsupported instructions DMULT,
2102 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2103 * to execute it causes a Reserved Instruction exception.
2104 *
2105 * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2106 *
2107 * 31 26 0
2108 * +--------+----------------------------------------+
2109 * | opcode | |
2110 * +--------+----------------------------------------+
2111 *
2112 * opcode bits 28..26
2113 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2114 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2115 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2116 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2117 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2118 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2119 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2120 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2121 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2122 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2123 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 2124 */
b158d449 2125
f99c0d6d
FN
2126enum {
2127 TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2128 TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
2129 TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2130};
2131
d3297211
FN
2132/*
2133 * TX79 Multimedia Instructions with opcode field = MMI:
2134 *
2135 * 31 26 5 0
2136 * +--------+-------------------------------+--------+
2137 * | MMI | |function|
2138 * +--------+-------------------------------+--------+
2139 *
2140 * function bits 2..0
2141 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2142 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2143 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2144 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2145 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2146 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2147 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2148 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2149 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2150 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2151 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2152 */
2153
2154#define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2155enum {
2156 TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2157 TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2158 TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
2159 TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2160 TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2161 TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2162 TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2163 TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2164 TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2165 TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2166 TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2167 TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2168 TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2169 TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
2170 TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
2171 TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2172 TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2173 TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
2174 TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
2175 TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
2176 TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
2177 TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
2178 TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
2179 TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
2180 TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
2181};
2182
3ef65697
FN
2183/*
2184 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2185 *
2186 * 31 26 10 6 5 0
2187 * +--------+----------------------+--------+--------+
2188 * | MMI | |function| MMI0 |
2189 * +--------+----------------------+--------+--------+
2190 *
2191 * function bits 7..6
2192 * bits | 0 | 1 | 2 | 3
2193 * 10..8 | 00 | 01 | 10 | 11
2194 * -------+-------+-------+-------+-------
2195 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2196 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2197 * 2 010 | PADDB | PSUBB | PCGTB | *
2198 * 3 011 | * | * | * | *
2199 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2200 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2201 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2202 * 7 111 | * | * | PEXT5 | PPAC5
2203 */
2204
2205#define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2206enum {
2207 TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2208 TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2209 TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2210 TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2211 TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2212 TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2213 TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2214 TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2215 TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2216 TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2217 TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2218 TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2219 TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2220 TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2221 TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2222 TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2223 TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2224 TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2225 TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2226 TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2227 TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2228 TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2229 TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2230 TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2231 TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2232};
2233
77596541
FN
2234/*
2235 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2236 *
2237 * 31 26 10 6 5 0
2238 * +--------+----------------------+--------+--------+
2239 * | MMI | |function| MMI1 |
2240 * +--------+----------------------+--------+--------+
2241 *
2242 * function bits 7..6
2243 * bits | 0 | 1 | 2 | 3
2244 * 10..8 | 00 | 01 | 10 | 11
2245 * -------+-------+-------+-------+-------
2246 * 0 000 | * | PABSW | PCEQW | PMINW
2247 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2248 * 2 010 | * | * | PCEQB | *
2249 * 3 011 | * | * | * | *
2250 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2251 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2252 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2253 * 7 111 | * | * | * | *
2254 */
2255
2256#define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2257enum {
2258 TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2259 TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2260 TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2261 TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2262 TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2263 TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2264 TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2265 TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2266 TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2267 TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2268 TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2269 TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2270 TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2271 TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2272 TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2273 TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2274 TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2275 TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2276};
2277
6c03ef6a
FN
2278/*
2279 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2280 *
2281 * 31 26 10 6 5 0
2282 * +--------+----------------------+--------+--------+
2283 * | MMI | |function| MMI2 |
2284 * +--------+----------------------+--------+--------+
2285 *
2286 * function bits 7..6
2287 * bits | 0 | 1 | 2 | 3
2288 * 10..8 | 00 | 01 | 10 | 11
2289 * -------+-------+-------+-------+-------
2290 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2291 * 1 001 | PMSUBW| * | * | *
2292 * 2 010 | PMFHI | PMFLO | PINTH | *
2293 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2294 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2295 * 5 101 | PMSUBH| PHMSBH| * | *
2296 * 6 110 | * | * | PEXEH | PREVH
2297 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2298 */
2299
2300#define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2301enum {
2302 TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2303 TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2304 TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2305 TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2306 TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2307 TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2308 TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2309 TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2310 TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2311 TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2312 TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2313 TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2314 TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2315 TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2316 TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2317 TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2318 TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2319 TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2320 TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2321 TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2322 TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2323 TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2324};
2325
dd581bf9
FN
2326/*
2327 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2328 *
2329 * 31 26 10 6 5 0
2330 * +--------+----------------------+--------+--------+
2331 * | MMI | |function| MMI3 |
2332 * +--------+----------------------+--------+--------+
2333 *
2334 * function bits 7..6
2335 * bits | 0 | 1 | 2 | 3
2336 * 10..8 | 00 | 01 | 10 | 11
2337 * -------+-------+-------+-------+-------
2338 * 0 000 |PMADDUW| * | * | PSRAVW
2339 * 1 001 | * | * | * | *
2340 * 2 010 | PMTHI | PMTLO | PINTEH| *
2341 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2342 * 4 100 | * | * | POR | PNOR
2343 * 5 101 | * | * | * | *
2344 * 6 110 | * | * | PEXCH | PCPYH
2345 * 7 111 | * | * | PEXCW | *
2346 */
2347
2348#define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2349enum {
2350 TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2351 TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2352 TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2353 TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2354 TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2355 TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2356 TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2357 TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2358 TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2359 TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2360 TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2361 TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2362 TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2363};
2364
39454628 2365/* global register indices */
a7812ae4 2366static TCGv cpu_gpr[32], cpu_PC;
340fff72 2367static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
2368static TCGv cpu_dspctrl, btarget, bcond;
2369static TCGv_i32 hflags;
a7812ae4 2370static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 2371static TCGv_i64 fpu_f64[32];
863f264d 2372static TCGv_i64 msa_wr_d[64];
aa0bf00b 2373
022c62cb 2374#include "exec/gen-icount.h"
2e70f6ef 2375
895c2d04 2376#define gen_helper_0e0i(name, arg) do { \
a7812ae4 2377 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 2378 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
2379 tcg_temp_free_i32(helper_tmp); \
2380 } while(0)
be24bb4f 2381
895c2d04 2382#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 2383 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 2384 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
2385 tcg_temp_free_i32(helper_tmp); \
2386 } while(0)
be24bb4f 2387
895c2d04
BS
2388#define gen_helper_1e0i(name, ret, arg1) do { \
2389 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2390 gen_helper_##name(ret, cpu_env, helper_tmp); \
2391 tcg_temp_free_i32(helper_tmp); \
2392 } while(0)
2393
2394#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2395 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2396 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2397 tcg_temp_free_i32(helper_tmp); \
2398 } while(0)
2399
2400#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2401 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2402 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2403 tcg_temp_free_i32(helper_tmp); \
2404 } while(0)
2405
2406#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 2407 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 2408 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
2409 tcg_temp_free_i32(helper_tmp); \
2410 } while(0)
be24bb4f 2411
895c2d04 2412#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 2413 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 2414 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
2415 tcg_temp_free_i32(helper_tmp); \
2416 } while(0)
c239529e 2417
8e9ade68 2418typedef struct DisasContext {
eeb3bba8
EC
2419 DisasContextBase base;
2420 target_ulong saved_pc;
18f440ed 2421 target_ulong page_start;
8e9ade68 2422 uint32_t opcode;
f9c9cd63 2423 uint64_t insn_flags;
5ab5c041 2424 int32_t CP0_Config1;
49735f76 2425 int32_t CP0_Config2;
ab77fc61
DN
2426 int32_t CP0_Config3;
2427 int32_t CP0_Config5;
8e9ade68
TS
2428 /* Routine used to access memory */
2429 int mem_idx;
be3a8c53 2430 TCGMemOp default_tcg_memop_mask;
8e9ade68 2431 uint32_t hflags, saved_hflags;
8e9ade68 2432 target_ulong btarget;
d279279e 2433 bool ulri;
e98c0d17 2434 int kscrexist;
7207c7f9 2435 bool rxi;
9456c2fb 2436 int ie;
aea14095
LA
2437 bool bi;
2438 bool bp;
5204ea79
LA
2439 uint64_t PAMask;
2440 bool mvh;
76964147 2441 bool eva;
cec56a73 2442 bool sc;
5204ea79 2443 int CP0_LLAddr_shift;
e29c9628 2444 bool ps;
01bc435b 2445 bool vp;
c870e3f5 2446 bool cmgcr;
f6d4dd81 2447 bool mrp;
87552089 2448 bool nan2008;
6be77480 2449 bool abs2008;
8e9ade68
TS
2450} DisasContext;
2451
b28425ba
EC
2452#define DISAS_STOP DISAS_TARGET_0
2453#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2454
d73ee8a2
RH
2455static const char * const regnames[] = {
2456 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2457 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2458 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2459 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2460};
6af0bf9c 2461
d73ee8a2
RH
2462static const char * const regnames_HI[] = {
2463 "HI0", "HI1", "HI2", "HI3",
2464};
4b2eb8d2 2465
d73ee8a2
RH
2466static const char * const regnames_LO[] = {
2467 "LO0", "LO1", "LO2", "LO3",
2468};
4b2eb8d2 2469
d73ee8a2
RH
2470static const char * const fregnames[] = {
2471 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2472 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2473 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2474 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2475};
958fb4a9 2476
863f264d
YK
2477static const char * const msaregnames[] = {
2478 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2479 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2480 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2481 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2482 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2483 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2484 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2485 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2486 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2487 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2488 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2489 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2490 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2491 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2492 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2493 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2494};
2495
9d68ac14 2496#define LOG_DISAS(...) \
fb7729e2
RH
2497 do { \
2498 if (MIPS_DEBUG_DISAS) { \
9d68ac14 2499 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
2500 } \
2501 } while (0)
2502
9d68ac14 2503#define MIPS_INVAL(op) \
fb7729e2
RH
2504 do { \
2505 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
2506 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2507 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
2508 ctx->base.pc_next, ctx->opcode, op, \
2509 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2510 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
2511 } \
2512 } while (0)
958fb4a9 2513
8e9ade68
TS
2514/* General purpose registers moves. */
2515static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 2516{
8e9ade68
TS
2517 if (reg == 0)
2518 tcg_gen_movi_tl(t, 0);
2519 else
4b2eb8d2 2520 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
2521}
2522
8e9ade68 2523static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 2524{
8e9ade68 2525 if (reg != 0)
4b2eb8d2 2526 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
2527}
2528
8e9ade68 2529/* Moves to/from shadow registers. */
be24bb4f 2530static inline void gen_load_srsgpr (int from, int to)
aaa9128a 2531{
d9bea114 2532 TCGv t0 = tcg_temp_new();
be24bb4f
TS
2533
2534 if (from == 0)
d9bea114 2535 tcg_gen_movi_tl(t0, 0);
8e9ade68 2536 else {
d9bea114 2537 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2538 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2539
7db13fae 2540 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2541 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2542 tcg_gen_andi_i32(t2, t2, 0xf);
2543 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2544 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2545 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2546
d9bea114 2547 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2548 tcg_temp_free_ptr(addr);
d9bea114 2549 tcg_temp_free_i32(t2);
8e9ade68 2550 }
d9bea114
AJ
2551 gen_store_gpr(t0, to);
2552 tcg_temp_free(t0);
aaa9128a
TS
2553}
2554
be24bb4f 2555static inline void gen_store_srsgpr (int from, int to)
aaa9128a 2556{
be24bb4f 2557 if (to != 0) {
d9bea114
AJ
2558 TCGv t0 = tcg_temp_new();
2559 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2560 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2561
d9bea114 2562 gen_load_gpr(t0, from);
7db13fae 2563 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2564 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2565 tcg_gen_andi_i32(t2, t2, 0xf);
2566 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2567 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2568 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2569
d9bea114 2570 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2571 tcg_temp_free_ptr(addr);
d9bea114
AJ
2572 tcg_temp_free_i32(t2);
2573 tcg_temp_free(t0);
8e9ade68 2574 }
aaa9128a
TS
2575}
2576
eab9944c
LA
2577/* Tests */
2578static inline void gen_save_pc(target_ulong pc)
2579{
2580 tcg_gen_movi_tl(cpu_PC, pc);
2581}
2582
2583static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2584{
2585 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2586 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2587 gen_save_pc(ctx->base.pc_next);
2588 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2589 }
2590 if (ctx->hflags != ctx->saved_hflags) {
2591 tcg_gen_movi_i32(hflags, ctx->hflags);
2592 ctx->saved_hflags = ctx->hflags;
2593 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2594 case MIPS_HFLAG_BR:
2595 break;
2596 case MIPS_HFLAG_BC:
2597 case MIPS_HFLAG_BL:
2598 case MIPS_HFLAG_B:
2599 tcg_gen_movi_tl(btarget, ctx->btarget);
2600 break;
2601 }
2602 }
2603}
2604
2605static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2606{
2607 ctx->saved_hflags = ctx->hflags;
2608 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2609 case MIPS_HFLAG_BR:
2610 break;
2611 case MIPS_HFLAG_BC:
2612 case MIPS_HFLAG_BL:
2613 case MIPS_HFLAG_B:
2614 ctx->btarget = env->btarget;
2615 break;
2616 }
2617}
2618
2619static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2620{
2621 TCGv_i32 texcp = tcg_const_i32(excp);
2622 TCGv_i32 terr = tcg_const_i32(err);
2623 save_cpu_state(ctx, 1);
2624 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2625 tcg_temp_free_i32(terr);
2626 tcg_temp_free_i32(texcp);
eeb3bba8 2627 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2628}
2629
2630static inline void generate_exception(DisasContext *ctx, int excp)
2631{
eab9944c
LA
2632 gen_helper_0e0i(raise_exception, excp);
2633}
2634
9c708c7f
PD
2635static inline void generate_exception_end(DisasContext *ctx, int excp)
2636{
2637 generate_exception_err(ctx, excp, 0);
2638}
2639
aaa9128a 2640/* Floating point register moves. */
7c979afd 2641static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2642{
7c979afd
LA
2643 if (ctx->hflags & MIPS_HFLAG_FRE) {
2644 generate_exception(ctx, EXCP_RI);
2645 }
ecc7b3aa 2646 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2647}
2648
7c979afd 2649static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2650{
7c979afd
LA
2651 TCGv_i64 t64;
2652 if (ctx->hflags & MIPS_HFLAG_FRE) {
2653 generate_exception(ctx, EXCP_RI);
2654 }
2655 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2656 tcg_gen_extu_i32_i64(t64, t);
2657 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2658 tcg_temp_free_i64(t64);
6d066274
AJ
2659}
2660
7f6613ce 2661static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2662{
7f6613ce 2663 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2664 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2665 } else {
7c979afd 2666 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2667 }
6d066274
AJ
2668}
2669
7f6613ce 2670static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2671{
7f6613ce
PJ
2672 if (ctx->hflags & MIPS_HFLAG_F64) {
2673 TCGv_i64 t64 = tcg_temp_new_i64();
2674 tcg_gen_extu_i32_i64(t64, t);
2675 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2676 tcg_temp_free_i64(t64);
2677 } else {
7c979afd 2678 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2679 }
aa0bf00b 2680}
6ea83fed 2681
d73ee8a2 2682static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2683{
f364515c 2684 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2685 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2686 } else {
d73ee8a2 2687 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2688 }
2689}
6ea83fed 2690
d73ee8a2 2691static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2692{
f364515c 2693 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2694 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2695 } else {
d73ee8a2
RH
2696 TCGv_i64 t0;
2697 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2698 t0 = tcg_temp_new_i64();
6d066274 2699 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2700 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2701 tcg_temp_free_i64(t0);
aa0bf00b
TS
2702 }
2703}
6ea83fed 2704
d94536f4 2705static inline int get_fp_bit (int cc)
a16336e4 2706{
d94536f4
AJ
2707 if (cc)
2708 return 24 + cc;
2709 else
2710 return 23;
a16336e4
TS
2711}
2712
48d38ca5 2713/* Addresses computation */
941694d0 2714static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2715{
941694d0 2716 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2717
2718#if defined(TARGET_MIPS64)
01f72885 2719 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2720 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2721 }
2722#endif
4ad40f36
FB
2723}
2724
bf0718c5
SM
2725static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2726 target_long ofs)
2727{
2728 tcg_gen_addi_tl(ret, base, ofs);
2729
2730#if defined(TARGET_MIPS64)
2731 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2732 tcg_gen_ext32s_i64(ret, ret);
2733 }
2734#endif
2735}
2736
31837be3
YK
2737/* Addresses computation (translation time) */
2738static target_long addr_add(DisasContext *ctx, target_long base,
2739 target_long offset)
2740{
2741 target_long sum = base + offset;
2742
2743#if defined(TARGET_MIPS64)
2744 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2745 sum = (int32_t)sum;
2746 }
2747#endif
2748 return sum;
2749}
2750
71f303cd 2751/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
2752static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2753{
2754#if defined(TARGET_MIPS64)
71f303cd
RH
2755 tcg_gen_ext32s_i64(ret, arg);
2756#else
2757 tcg_gen_extrl_i64_i32(ret, arg);
2758#endif
2759}
2760
2761/* Sign-extract the high 32-bits to a target_long. */
2762static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2763{
2764#if defined(TARGET_MIPS64)
2765 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2766#else
71f303cd 2767 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2768#endif
2769}
2770
356265ae 2771static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2772{
fe253235 2773 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 2774 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
2775}
2776
356265ae 2777static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 2778{
fe253235 2779 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
2780 generate_exception_err(ctx, EXCP_CpU, 1);
2781}
2782
b8aa4598
TS
2783/* Verify that the processor is running with COP1X instructions enabled.
2784 This is associated with the nabla symbol in the MIPS32 and MIPS64
2785 opcode tables. */
2786
356265ae 2787static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
2788{
2789 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 2790 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
2791}
2792
2793/* Verify that the processor is running with 64-bit floating-point
2794 operations enabled. */
2795
356265ae 2796static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2797{
b8aa4598 2798 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 2799 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2800}
2801
2802/*
2803 * Verify if floating point register is valid; an operation is not defined
2804 * if bit 0 of any register specification is set and the FR bit in the
2805 * Status register equals zero, since the register numbers specify an
2806 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2807 * in the Status register equals one, both even and odd register numbers
2808 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2809 *
2810 * Multiple 64 bit wide registers can be checked by calling
2811 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2812 */
356265ae 2813static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2814{
fe253235 2815 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 2816 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2817}
2818
853c3240
JL
2819/* Verify that the processor is running with DSP instructions enabled.
2820 This is enabled by CP0 Status register MX(24) bit.
2821 */
2822
2823static inline void check_dsp(DisasContext *ctx)
2824{
2825 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2826 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2827 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2828 } else {
9c708c7f 2829 generate_exception_end(ctx, EXCP_RI);
ad153f15 2830 }
853c3240
JL
2831 }
2832}
2833
908f6be1 2834static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2835{
908f6be1 2836 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2837 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2838 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2839 } else {
9c708c7f 2840 generate_exception_end(ctx, EXCP_RI);
ad153f15 2841 }
853c3240
JL
2842 }
2843}
2844
908f6be1 2845static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2846{
908f6be1 2847 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2848 if (ctx->insn_flags & ASE_DSP) {
2849 generate_exception_end(ctx, EXCP_DSPDIS);
2850 } else {
2851 generate_exception_end(ctx, EXCP_RI);
2852 }
2853 }
2854}
2855
3a95e3a7 2856/* This code generates a "reserved instruction" exception if the
e189e748 2857 CPU does not support the instruction set corresponding to flags. */
f9c9cd63 2858static inline void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2859{
d75c135e 2860 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 2861 generate_exception_end(ctx, EXCP_RI);
d75c135e 2862 }
3a95e3a7
TS
2863}
2864
fecd2646
LA
2865/* This code generates a "reserved instruction" exception if the
2866 CPU has corresponding flag set which indicates that the instruction
2867 has been removed. */
f9c9cd63 2868static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2869{
2870 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 2871 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
2872 }
2873}
2874
e29c9628
YK
2875/* This code generates a "reserved instruction" exception if the
2876 CPU does not support 64-bit paired-single (PS) floating point data type */
2877static inline void check_ps(DisasContext *ctx)
2878{
2879 if (unlikely(!ctx->ps)) {
2880 generate_exception(ctx, EXCP_RI);
2881 }
2882 check_cp1_64bitmode(ctx);
2883}
2884
c7986fd6 2885#ifdef TARGET_MIPS64
e189e748
TS
2886/* This code generates a "reserved instruction" exception if 64-bit
2887 instructions are not enabled. */
356265ae 2888static inline void check_mips_64(DisasContext *ctx)
e189e748 2889{
fe253235 2890 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 2891 generate_exception_end(ctx, EXCP_RI);
e189e748 2892}
c7986fd6 2893#endif
e189e748 2894
5204ea79
LA
2895#ifndef CONFIG_USER_ONLY
2896static inline void check_mvh(DisasContext *ctx)
2897{
2898 if (unlikely(!ctx->mvh)) {
2899 generate_exception(ctx, EXCP_RI);
2900 }
2901}
2902#endif
2903
0b16dcd1
AR
2904/*
2905 * This code generates a "reserved instruction" exception if the
2906 * Config5 XNP bit is set.
2907 */
2908static inline void check_xnp(DisasContext *ctx)
2909{
2910 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2911 generate_exception_end(ctx, EXCP_RI);
2912 }
2913}
2914
5e31fdd5
YK
2915#ifndef CONFIG_USER_ONLY
2916/*
2917 * This code generates a "reserved instruction" exception if the
2918 * Config3 PW bit is NOT set.
2919 */
2920static inline void check_pw(DisasContext *ctx)
2921{
2922 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2923 generate_exception_end(ctx, EXCP_RI);
2924 }
2925}
2926#endif
2927
9affc1c5
AR
2928/*
2929 * This code generates a "reserved instruction" exception if the
2930 * Config3 MT bit is NOT set.
2931 */
2932static inline void check_mt(DisasContext *ctx)
2933{
2934 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2935 generate_exception_end(ctx, EXCP_RI);
2936 }
2937}
2938
2939#ifndef CONFIG_USER_ONLY
2940/*
2941 * This code generates a "coprocessor unusable" exception if CP0 is not
2942 * available, and, if that is not the case, generates a "reserved instruction"
2943 * exception if the Config5 MT bit is NOT set. This is needed for availability
2944 * control of some of MT ASE instructions.
2945 */
2946static inline void check_cp0_mt(DisasContext *ctx)
2947{
2948 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2949 generate_exception_err(ctx, EXCP_CpU, 0);
2950 } else {
2951 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2952 generate_exception_err(ctx, EXCP_RI, 0);
2953 }
2954 }
2955}
2956#endif
2957
fb32f8c8
DN
2958/*
2959 * This code generates a "reserved instruction" exception if the
2960 * Config5 NMS bit is set.
2961 */
2962static inline void check_nms(DisasContext *ctx)
2963{
2964 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2965 generate_exception_end(ctx, EXCP_RI);
2966 }
2967}
2968
0b16dcd1 2969
8153667c
NF
2970/* Define small wrappers for gen_load_fpr* so that we have a uniform
2971 calling interface for 32 and 64-bit FPRs. No sense in changing
2972 all callers for gen_load_fpr32 when we need the CTX parameter for
2973 this one use. */
7c979afd 2974#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
2975#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2976#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2977static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2978 int ft, int fs, int cc) \
2979{ \
2980 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
2981 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
2982 switch (ifmt) { \
2983 case FMT_PS: \
e29c9628 2984 check_ps(ctx); \
8153667c
NF
2985 break; \
2986 case FMT_D: \
2987 if (abs) { \
2988 check_cop1x(ctx); \
2989 } \
2990 check_cp1_registers(ctx, fs | ft); \
2991 break; \
2992 case FMT_S: \
2993 if (abs) { \
2994 check_cop1x(ctx); \
2995 } \
2996 break; \
2997 } \
2998 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
2999 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3000 switch (n) { \
895c2d04
BS
3001 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3002 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3003 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3004 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3005 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3006 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3007 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3008 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3009 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3010 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3011 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3012 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3013 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3014 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3015 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3016 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
3017 default: abort(); \
3018 } \
3019 tcg_temp_free_i##bits (fp0); \
3020 tcg_temp_free_i##bits (fp1); \
3021}
3022
3023FOP_CONDS(, 0, d, FMT_D, 64)
3024FOP_CONDS(abs, 1, d, FMT_D, 64)
3025FOP_CONDS(, 0, s, FMT_S, 32)
3026FOP_CONDS(abs, 1, s, FMT_S, 32)
3027FOP_CONDS(, 0, ps, FMT_PS, 64)
3028FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3029#undef FOP_CONDS
3f493883
YK
3030
3031#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3032static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3033 int ft, int fs, int fd) \
3034{ \
3035 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3036 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 3037 if (ifmt == FMT_D) { \
3f493883 3038 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
3039 } \
3040 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3041 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3042 switch (n) { \
3043 case 0: \
3044 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3045 break; \
3046 case 1: \
3047 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3048 break; \
3049 case 2: \
3050 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3051 break; \
3052 case 3: \
3053 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3054 break; \
3055 case 4: \
3056 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3057 break; \
3058 case 5: \
3059 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3060 break; \
3061 case 6: \
3062 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3063 break; \
3064 case 7: \
3065 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3066 break; \
3067 case 8: \
3068 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3069 break; \
3070 case 9: \
3071 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3072 break; \
3073 case 10: \
3074 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3075 break; \
3076 case 11: \
3077 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3078 break; \
3079 case 12: \
3080 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3081 break; \
3082 case 13: \
3083 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3084 break; \
3085 case 14: \
3086 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3087 break; \
3088 case 15: \
3089 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3090 break; \
3091 case 17: \
3092 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3093 break; \
3094 case 18: \
3095 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3096 break; \
3097 case 19: \
3098 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3099 break; \
3100 case 25: \
3101 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3102 break; \
3103 case 26: \
3104 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3105 break; \
3106 case 27: \
3107 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3108 break; \
3109 default: \
3110 abort(); \
3111 } \
3112 STORE; \
3113 tcg_temp_free_i ## bits (fp0); \
3114 tcg_temp_free_i ## bits (fp1); \
3115}
3116
3117FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 3118FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 3119#undef FOP_CONDNS
8153667c
NF
3120#undef gen_ldcmp_fpr32
3121#undef gen_ldcmp_fpr64
3122
958fb4a9 3123/* load/store instructions. */
e7139c44 3124#ifdef CONFIG_USER_ONLY
d9bea114 3125#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3126static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3127 DisasContext *ctx) \
d9bea114
AJ
3128{ \
3129 TCGv t0 = tcg_temp_new(); \
3130 tcg_gen_mov_tl(t0, arg1); \
3131 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
3132 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3133 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 3134 tcg_temp_free(t0); \
aaa9128a 3135}
e7139c44
AJ
3136#else
3137#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3138static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3139 DisasContext *ctx) \
e7139c44 3140{ \
dd4096cd 3141 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
3142}
3143#endif
aaa9128a
TS
3144OP_LD_ATOMIC(ll,ld32s);
3145#if defined(TARGET_MIPS64)
3146OP_LD_ATOMIC(lld,ld64);
3147#endif
3148#undef OP_LD_ATOMIC
3149
590bc601
PB
3150#ifdef CONFIG_USER_ONLY
3151#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3152static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3153 DisasContext *ctx) \
590bc601
PB
3154{ \
3155 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
3156 TCGLabel *l1 = gen_new_label(); \
3157 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
3158 \
3159 tcg_gen_andi_tl(t0, arg2, almask); \
3160 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 3161 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
3162 generate_exception(ctx, EXCP_AdES); \
3163 gen_set_label(l1); \
7db13fae 3164 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
3165 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3166 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
3167 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3168 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 3169 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
3170 gen_set_label(l2); \
3171 tcg_gen_movi_tl(t0, 0); \
3172 gen_store_gpr(t0, rt); \
3173 tcg_temp_free(t0); \
3174}
3175#else
3176#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3177static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3178 DisasContext *ctx) \
590bc601
PB
3179{ \
3180 TCGv t0 = tcg_temp_new(); \
dd4096cd 3181 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 3182 gen_store_gpr(t0, rt); \
590bc601
PB
3183 tcg_temp_free(t0); \
3184}
3185#endif
590bc601 3186OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 3187#if defined(TARGET_MIPS64)
590bc601 3188OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
3189#endif
3190#undef OP_ST_ATOMIC
3191
662d7485 3192static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 3193 int base, int offset)
662d7485
NF
3194{
3195 if (base == 0) {
3196 tcg_gen_movi_tl(addr, offset);
3197 } else if (offset == 0) {
3198 gen_load_gpr(addr, base);
3199 } else {
3200 tcg_gen_movi_tl(addr, offset);
3201 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3202 }
3203}
3204
364d4831
NF
3205static target_ulong pc_relative_pc (DisasContext *ctx)
3206{
eeb3bba8 3207 target_ulong pc = ctx->base.pc_next;
364d4831
NF
3208
3209 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3210 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3211
3212 pc -= branch_bytes;
3213 }
3214
3215 pc &= ~(target_ulong)3;
3216 return pc;
3217}
3218
5c13fdfd 3219/* Load */
d75c135e 3220static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 3221 int rt, int base, int offset)
6af0bf9c 3222{
fc40787a 3223 TCGv t0, t1, t2;
dd4096cd 3224 int mem_idx = ctx->mem_idx;
afa88c3a 3225
d75c135e 3226 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
3227 /* Loongson CPU uses a load to zero register for prefetch.
3228 We emulate it as a NOP. On other CPU we must perform the
3229 actual memory access. */
afa88c3a
AJ
3230 return;
3231 }
6af0bf9c 3232
afa88c3a 3233 t0 = tcg_temp_new();
662d7485 3234 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 3235
6af0bf9c 3236 switch (opc) {
d26bc211 3237#if defined(TARGET_MIPS64)
6e473128 3238 case OPC_LWU:
dd4096cd 3239 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 3240 ctx->default_tcg_memop_mask);
78723684 3241 gen_store_gpr(t0, rt);
6e473128 3242 break;
6af0bf9c 3243 case OPC_LD:
dd4096cd 3244 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 3245 ctx->default_tcg_memop_mask);
78723684 3246 gen_store_gpr(t0, rt);
6af0bf9c 3247 break;
7a387fff 3248 case OPC_LLD:
bf7910c6 3249 case R6_OPC_LLD:
dd4096cd 3250 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 3251 gen_store_gpr(t0, rt);
7a387fff 3252 break;
6af0bf9c 3253 case OPC_LDL:
3cee3050 3254 t1 = tcg_temp_new();
908680c6
AJ
3255 /* Do a byte access to possibly trigger a page
3256 fault with the unaligned address. */
dd4096cd 3257 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3258 tcg_gen_andi_tl(t1, t0, 7);
3259#ifndef TARGET_WORDS_BIGENDIAN
3260 tcg_gen_xori_tl(t1, t1, 7);
3261#endif
3262 tcg_gen_shli_tl(t1, t1, 3);
3263 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3264 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 3265 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3266 t2 = tcg_const_tl(-1);
3267 tcg_gen_shl_tl(t2, t2, t1);
78723684 3268 gen_load_gpr(t1, rt);
eb02cc3f 3269 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3270 tcg_temp_free(t2);
3271 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3272 tcg_temp_free(t1);
fc40787a 3273 gen_store_gpr(t0, rt);
6af0bf9c 3274 break;
6af0bf9c 3275 case OPC_LDR:
3cee3050 3276 t1 = tcg_temp_new();
908680c6
AJ
3277 /* Do a byte access to possibly trigger a page
3278 fault with the unaligned address. */
dd4096cd 3279 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3280 tcg_gen_andi_tl(t1, t0, 7);
3281#ifdef TARGET_WORDS_BIGENDIAN
3282 tcg_gen_xori_tl(t1, t1, 7);
3283#endif
3284 tcg_gen_shli_tl(t1, t1, 3);
3285 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3286 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
3287 tcg_gen_shr_tl(t0, t0, t1);
3288 tcg_gen_xori_tl(t1, t1, 63);
3289 t2 = tcg_const_tl(0xfffffffffffffffeull);
3290 tcg_gen_shl_tl(t2, t2, t1);
78723684 3291 gen_load_gpr(t1, rt);
fc40787a
AJ
3292 tcg_gen_and_tl(t1, t1, t2);
3293 tcg_temp_free(t2);
3294 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3295 tcg_temp_free(t1);
fc40787a 3296 gen_store_gpr(t0, rt);
6af0bf9c 3297 break;
364d4831 3298 case OPC_LDPC:
3cee3050 3299 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3300 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3301 tcg_temp_free(t1);
dd4096cd 3302 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
3303 gen_store_gpr(t0, rt);
3304 break;
6af0bf9c 3305#endif
364d4831 3306 case OPC_LWPC:
3cee3050 3307 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3308 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3309 tcg_temp_free(t1);
dd4096cd 3310 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
3311 gen_store_gpr(t0, rt);
3312 break;
76964147
JH
3313 case OPC_LWE:
3314 mem_idx = MIPS_HFLAG_UM;
3315 /* fall through */
6af0bf9c 3316 case OPC_LW:
dd4096cd 3317 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 3318 ctx->default_tcg_memop_mask);
78723684 3319 gen_store_gpr(t0, rt);
6af0bf9c 3320 break;
76964147
JH
3321 case OPC_LHE:
3322 mem_idx = MIPS_HFLAG_UM;
3323 /* fall through */
6af0bf9c 3324 case OPC_LH:
dd4096cd 3325 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 3326 ctx->default_tcg_memop_mask);
78723684 3327 gen_store_gpr(t0, rt);
6af0bf9c 3328 break;
76964147
JH
3329 case OPC_LHUE:
3330 mem_idx = MIPS_HFLAG_UM;
3331 /* fall through */
6af0bf9c 3332 case OPC_LHU:
dd4096cd 3333 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 3334 ctx->default_tcg_memop_mask);
78723684 3335 gen_store_gpr(t0, rt);
6af0bf9c 3336 break;
76964147
JH
3337 case OPC_LBE:
3338 mem_idx = MIPS_HFLAG_UM;
3339 /* fall through */
6af0bf9c 3340 case OPC_LB:
dd4096cd 3341 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 3342 gen_store_gpr(t0, rt);
6af0bf9c 3343 break;
76964147
JH
3344 case OPC_LBUE:
3345 mem_idx = MIPS_HFLAG_UM;
3346 /* fall through */
6af0bf9c 3347 case OPC_LBU:
dd4096cd 3348 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 3349 gen_store_gpr(t0, rt);
6af0bf9c 3350 break;
76964147
JH
3351 case OPC_LWLE:
3352 mem_idx = MIPS_HFLAG_UM;
3353 /* fall through */
6af0bf9c 3354 case OPC_LWL:
3cee3050 3355 t1 = tcg_temp_new();
908680c6
AJ
3356 /* Do a byte access to possibly trigger a page
3357 fault with the unaligned address. */
dd4096cd 3358 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3359 tcg_gen_andi_tl(t1, t0, 3);
3360#ifndef TARGET_WORDS_BIGENDIAN
3361 tcg_gen_xori_tl(t1, t1, 3);
3362#endif
3363 tcg_gen_shli_tl(t1, t1, 3);
3364 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3365 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 3366 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3367 t2 = tcg_const_tl(-1);
3368 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3369 gen_load_gpr(t1, rt);
eb02cc3f 3370 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3371 tcg_temp_free(t2);
3372 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3373 tcg_temp_free(t1);
fc40787a
AJ
3374 tcg_gen_ext32s_tl(t0, t0);
3375 gen_store_gpr(t0, rt);
6af0bf9c 3376 break;
76964147
JH
3377 case OPC_LWRE:
3378 mem_idx = MIPS_HFLAG_UM;
3379 /* fall through */
6af0bf9c 3380 case OPC_LWR:
3cee3050 3381 t1 = tcg_temp_new();
908680c6
AJ
3382 /* Do a byte access to possibly trigger a page
3383 fault with the unaligned address. */
dd4096cd 3384 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3385 tcg_gen_andi_tl(t1, t0, 3);
3386#ifdef TARGET_WORDS_BIGENDIAN
3387 tcg_gen_xori_tl(t1, t1, 3);
3388#endif
3389 tcg_gen_shli_tl(t1, t1, 3);
3390 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3391 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
3392 tcg_gen_shr_tl(t0, t0, t1);
3393 tcg_gen_xori_tl(t1, t1, 31);
3394 t2 = tcg_const_tl(0xfffffffeull);
3395 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3396 gen_load_gpr(t1, rt);
fc40787a
AJ
3397 tcg_gen_and_tl(t1, t1, t2);
3398 tcg_temp_free(t2);
3399 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3400 tcg_temp_free(t1);
c728154b 3401 tcg_gen_ext32s_tl(t0, t0);
fc40787a 3402 gen_store_gpr(t0, rt);
6af0bf9c 3403 break;
76964147
JH
3404 case OPC_LLE:
3405 mem_idx = MIPS_HFLAG_UM;
3406 /* fall through */
6af0bf9c 3407 case OPC_LL:
4368b29a 3408 case R6_OPC_LL:
dd4096cd 3409 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 3410 gen_store_gpr(t0, rt);
6af0bf9c 3411 break;
d66c7132 3412 }
d66c7132 3413 tcg_temp_free(t0);
d66c7132
AJ
3414}
3415
0b16dcd1
AR
3416static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3417 uint32_t reg1, uint32_t reg2)
3418{
3419 TCGv taddr = tcg_temp_new();
3420 TCGv_i64 tval = tcg_temp_new_i64();
3421 TCGv tmp1 = tcg_temp_new();
3422 TCGv tmp2 = tcg_temp_new();
3423
3424 gen_base_offset_addr(ctx, taddr, base, offset);
3425 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3426#ifdef TARGET_WORDS_BIGENDIAN
3427 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3428#else
3429 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3430#endif
3431 gen_store_gpr(tmp1, reg1);
3432 tcg_temp_free(tmp1);
3433 gen_store_gpr(tmp2, reg2);
3434 tcg_temp_free(tmp2);
3435 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3436 tcg_temp_free_i64(tval);
3437 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3438 tcg_temp_free(taddr);
3439}
3440
5c13fdfd
AJ
3441/* Store */
3442static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 3443 int base, int offset)
5c13fdfd 3444{
5c13fdfd
AJ
3445 TCGv t0 = tcg_temp_new();
3446 TCGv t1 = tcg_temp_new();
dd4096cd 3447 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3448
3449 gen_base_offset_addr(ctx, t0, base, offset);
3450 gen_load_gpr(t1, rt);
3451 switch (opc) {
3452#if defined(TARGET_MIPS64)
3453 case OPC_SD:
dd4096cd 3454 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3455 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3456 break;
3457 case OPC_SDL:
dd4096cd 3458 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3459 break;
3460 case OPC_SDR:
dd4096cd 3461 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3462 break;
3463#endif
76964147
JH
3464 case OPC_SWE:
3465 mem_idx = MIPS_HFLAG_UM;
3466 /* fall through */
5c13fdfd 3467 case OPC_SW:
dd4096cd 3468 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3469 ctx->default_tcg_memop_mask);
5c13fdfd 3470 break;
76964147
JH
3471 case OPC_SHE:
3472 mem_idx = MIPS_HFLAG_UM;
3473 /* fall through */
5c13fdfd 3474 case OPC_SH:
dd4096cd 3475 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3476 ctx->default_tcg_memop_mask);
5c13fdfd 3477 break;
76964147
JH
3478 case OPC_SBE:
3479 mem_idx = MIPS_HFLAG_UM;
3480 /* fall through */
5c13fdfd 3481 case OPC_SB:
dd4096cd 3482 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3483 break;
76964147
JH
3484 case OPC_SWLE:
3485 mem_idx = MIPS_HFLAG_UM;
3486 /* fall through */
5c13fdfd 3487 case OPC_SWL:
dd4096cd 3488 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3489 break;
76964147
JH
3490 case OPC_SWRE:
3491 mem_idx = MIPS_HFLAG_UM;
3492 /* fall through */
5c13fdfd 3493 case OPC_SWR:
dd4096cd 3494 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3495 break;
3496 }
5c13fdfd
AJ
3497 tcg_temp_free(t0);
3498 tcg_temp_free(t1);
3499}
3500
3501
d66c7132
AJ
3502/* Store conditional */
3503static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3504 int base, int16_t offset)
3505{
d66c7132 3506 TCGv t0, t1;
dd4096cd 3507 int mem_idx = ctx->mem_idx;
d66c7132 3508
2d2826b9 3509#ifdef CONFIG_USER_ONLY
d66c7132 3510 t0 = tcg_temp_local_new();
d66c7132 3511 t1 = tcg_temp_local_new();
2d2826b9
AJ
3512#else
3513 t0 = tcg_temp_new();
3514 t1 = tcg_temp_new();
3515#endif
3516 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
3517 gen_load_gpr(t1, rt);
3518 switch (opc) {
3519#if defined(TARGET_MIPS64)
3520 case OPC_SCD:
bf7910c6 3521 case R6_OPC_SCD:
dd4096cd 3522 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
3523 break;
3524#endif
76964147
JH
3525 case OPC_SCE:
3526 mem_idx = MIPS_HFLAG_UM;
3527 /* fall through */
6af0bf9c 3528 case OPC_SC:
4368b29a 3529 case R6_OPC_SC:
dd4096cd 3530 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 3531 break;
6af0bf9c 3532 }
78723684 3533 tcg_temp_free(t1);
d66c7132 3534 tcg_temp_free(t0);
6af0bf9c
FB
3535}
3536
0b16dcd1
AR
3537static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3538 uint32_t reg1, uint32_t reg2)
3539{
3540 TCGv taddr = tcg_temp_local_new();
3541 TCGv lladdr = tcg_temp_local_new();
3542 TCGv_i64 tval = tcg_temp_new_i64();
3543 TCGv_i64 llval = tcg_temp_new_i64();
3544 TCGv_i64 val = tcg_temp_new_i64();
3545 TCGv tmp1 = tcg_temp_new();
3546 TCGv tmp2 = tcg_temp_new();
3547 TCGLabel *lab_fail = gen_new_label();
3548 TCGLabel *lab_done = gen_new_label();
3549
3550 gen_base_offset_addr(ctx, taddr, base, offset);
3551
3552 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3553 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3554
3555 gen_load_gpr(tmp1, reg1);
3556 gen_load_gpr(tmp2, reg2);
3557
3558#ifdef TARGET_WORDS_BIGENDIAN
3559 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3560#else
3561 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3562#endif
3563
3564 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3565 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3566 ctx->mem_idx, MO_64);
3567 if (reg1 != 0) {
3568 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3569 }
3570 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3571
3572 gen_set_label(lab_fail);
3573
3574 if (reg1 != 0) {
3575 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3576 }
3577 gen_set_label(lab_done);
3578 tcg_gen_movi_tl(lladdr, -1);
3579 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3580}
3581
6ea83fed 3582/* Load and store */
7a387fff 3583static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 3584 TCGv t0)
6ea83fed 3585{
6ea83fed 3586 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 3587 memory access. */
6ea83fed
FB
3588 switch (opc) {
3589 case OPC_LWC1:
b6d96bed 3590 {
a7812ae4 3591 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3592 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3593 ctx->default_tcg_memop_mask);
7c979afd 3594 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3595 tcg_temp_free_i32(fp0);
b6d96bed 3596 }
6ea83fed
FB
3597 break;
3598 case OPC_SWC1:
b6d96bed 3599 {
a7812ae4 3600 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3601 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3602 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3603 ctx->default_tcg_memop_mask);
a7812ae4 3604 tcg_temp_free_i32(fp0);
b6d96bed 3605 }
6ea83fed
FB
3606 break;
3607 case OPC_LDC1:
b6d96bed 3608 {
a7812ae4 3609 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3610 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3611 ctx->default_tcg_memop_mask);
b6d96bed 3612 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3613 tcg_temp_free_i64(fp0);
b6d96bed 3614 }
6ea83fed
FB
3615 break;
3616 case OPC_SDC1:
b6d96bed 3617 {
a7812ae4 3618 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3619 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3620 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3621 ctx->default_tcg_memop_mask);
a7812ae4 3622 tcg_temp_free_i64(fp0);
b6d96bed 3623 }
6ea83fed
FB
3624 break;
3625 default:
9d68ac14 3626 MIPS_INVAL("flt_ldst");
9c708c7f 3627 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 3628 break;
6ea83fed 3629 }
6ea83fed 3630}
6ea83fed 3631
5ab5c041
AJ
3632static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3633 int rs, int16_t imm)
26ebe468 3634{
b52d3bfa
YK
3635 TCGv t0 = tcg_temp_new();
3636
5ab5c041 3637 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3638 check_cp1_enabled(ctx);
d9224450
MR
3639 switch (op) {
3640 case OPC_LDC1:
3641 case OPC_SDC1:
3642 check_insn(ctx, ISA_MIPS2);
3643 /* Fallthrough */
3644 default:
b52d3bfa
YK
3645 gen_base_offset_addr(ctx, t0, rs, imm);
3646 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3647 }
26ebe468
NF
3648 } else {
3649 generate_exception_err(ctx, EXCP_CpU, 1);
3650 }
b52d3bfa 3651 tcg_temp_free(t0);
26ebe468
NF
3652}
3653
6af0bf9c 3654/* Arithmetic with immediate operand */
d75c135e 3655static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3656 int rt, int rs, int imm)
6af0bf9c 3657{
324d9e32 3658 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3659
7a387fff 3660 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
3661 /* If no destination, treat it as a NOP.
3662 For addi, we must generate the overflow exception when needed. */
324d9e32 3663 return;
6af0bf9c
FB
3664 }
3665 switch (opc) {
3666 case OPC_ADDI:
48d38ca5 3667 {
324d9e32
AJ
3668 TCGv t0 = tcg_temp_local_new();
3669 TCGv t1 = tcg_temp_new();
3670 TCGv t2 = tcg_temp_new();
42a268c2 3671 TCGLabel *l1 = gen_new_label();
48d38ca5 3672
324d9e32
AJ
3673 gen_load_gpr(t1, rs);
3674 tcg_gen_addi_tl(t0, t1, uimm);
3675 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3676
324d9e32
AJ
3677 tcg_gen_xori_tl(t1, t1, ~uimm);
3678 tcg_gen_xori_tl(t2, t0, uimm);
3679 tcg_gen_and_tl(t1, t1, t2);
3680 tcg_temp_free(t2);
3681 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3682 tcg_temp_free(t1);
48d38ca5
TS
3683 /* operands of same sign, result different sign */
3684 generate_exception(ctx, EXCP_OVERFLOW);
3685 gen_set_label(l1);
78723684 3686 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3687 gen_store_gpr(t0, rt);
3688 tcg_temp_free(t0);
48d38ca5 3689 }
6af0bf9c
FB
3690 break;
3691 case OPC_ADDIU:
324d9e32
AJ
3692 if (rs != 0) {
3693 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3694 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3695 } else {
3696 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3697 }
6af0bf9c 3698 break;
d26bc211 3699#if defined(TARGET_MIPS64)
7a387fff 3700 case OPC_DADDI:
48d38ca5 3701 {
324d9e32
AJ
3702 TCGv t0 = tcg_temp_local_new();
3703 TCGv t1 = tcg_temp_new();
3704 TCGv t2 = tcg_temp_new();
42a268c2 3705 TCGLabel *l1 = gen_new_label();
48d38ca5 3706
324d9e32
AJ
3707 gen_load_gpr(t1, rs);
3708 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3709
324d9e32
AJ
3710 tcg_gen_xori_tl(t1, t1, ~uimm);
3711 tcg_gen_xori_tl(t2, t0, uimm);
3712 tcg_gen_and_tl(t1, t1, t2);
3713 tcg_temp_free(t2);
3714 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3715 tcg_temp_free(t1);
48d38ca5
TS
3716 /* operands of same sign, result different sign */
3717 generate_exception(ctx, EXCP_OVERFLOW);
3718 gen_set_label(l1);
324d9e32
AJ
3719 gen_store_gpr(t0, rt);
3720 tcg_temp_free(t0);
48d38ca5 3721 }
7a387fff
TS
3722 break;
3723 case OPC_DADDIU:
324d9e32
AJ
3724 if (rs != 0) {
3725 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3726 } else {
3727 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3728 }
7a387fff
TS
3729 break;
3730#endif
324d9e32 3731 }
324d9e32
AJ
3732}
3733
3734/* Logic with immediate operand */
d75c135e 3735static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3736 int rt, int rs, int16_t imm)
324d9e32
AJ
3737{
3738 target_ulong uimm;
324d9e32
AJ
3739
3740 if (rt == 0) {
3741 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3742 return;
3743 }
3744 uimm = (uint16_t)imm;
3745 switch (opc) {
6af0bf9c 3746 case OPC_ANDI:
324d9e32
AJ
3747 if (likely(rs != 0))
3748 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3749 else
3750 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
3751 break;
3752 case OPC_ORI:
324d9e32
AJ
3753 if (rs != 0)
3754 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3755 else
3756 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3757 break;
3758 case OPC_XORI:
324d9e32
AJ
3759 if (likely(rs != 0))
3760 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3761 else
3762 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3763 break;
3764 case OPC_LUI:
d4ea6acd
LA
3765 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3766 /* OPC_AUI */
3767 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3768 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3769 } else {
3770 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3771 }
7c2c3ea3
EJ
3772 break;
3773
3774 default:
6af0bf9c 3775 break;
324d9e32 3776 }
324d9e32
AJ
3777}
3778
3779/* Set on less than with immediate operand */
d75c135e 3780static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3781 int rt, int rs, int16_t imm)
324d9e32
AJ
3782{
3783 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3784 TCGv t0;
3785
3786 if (rt == 0) {
3787 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3788 return;
3789 }
3790 t0 = tcg_temp_new();
3791 gen_load_gpr(t0, rs);
3792 switch (opc) {
3793 case OPC_SLTI:
e68dd28f 3794 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3795 break;
3796 case OPC_SLTIU:
e68dd28f 3797 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3798 break;
3799 }
324d9e32
AJ
3800 tcg_temp_free(t0);
3801}
3802
3803/* Shifts with immediate operand */
d75c135e 3804static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3805 int rt, int rs, int16_t imm)
3806{
3807 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3808 TCGv t0;
3809
3810 if (rt == 0) {
3811 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3812 return;
3813 }
3814
3815 t0 = tcg_temp_new();
3816 gen_load_gpr(t0, rs);
3817 switch (opc) {
6af0bf9c 3818 case OPC_SLL:
78723684 3819 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3820 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3821 break;
3822 case OPC_SRA:
324d9e32 3823 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3824 break;
3825 case OPC_SRL:
ea63e2c3
NF
3826 if (uimm != 0) {
3827 tcg_gen_ext32u_tl(t0, t0);
3828 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3829 } else {
3830 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 3831 }
ea63e2c3
NF
3832 break;
3833 case OPC_ROTR:
3834 if (uimm != 0) {
3835 TCGv_i32 t1 = tcg_temp_new_i32();
3836
3837 tcg_gen_trunc_tl_i32(t1, t0);
3838 tcg_gen_rotri_i32(t1, t1, uimm);
3839 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3840 tcg_temp_free_i32(t1);
3399e30f
NF
3841 } else {
3842 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 3843 }
7a387fff 3844 break;
d26bc211 3845#if defined(TARGET_MIPS64)
7a387fff 3846 case OPC_DSLL:
324d9e32 3847 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3848 break;
3849 case OPC_DSRA:
324d9e32 3850 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3851 break;
3852 case OPC_DSRL:
ea63e2c3 3853 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
3854 break;
3855 case OPC_DROTR:
3856 if (uimm != 0) {
3857 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
3858 } else {
3859 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 3860 }
7a387fff
TS
3861 break;
3862 case OPC_DSLL32:
324d9e32 3863 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3864 break;
3865 case OPC_DSRA32:
324d9e32 3866 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3867 break;
3868 case OPC_DSRL32:
ea63e2c3 3869 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
3870 break;
3871 case OPC_DROTR32:
3872 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 3873 break;
7a387fff 3874#endif
6af0bf9c 3875 }
78723684 3876 tcg_temp_free(t0);
6af0bf9c
FB
3877}
3878
3879/* Arithmetic */
d75c135e
AJ
3880static void gen_arith(DisasContext *ctx, uint32_t opc,
3881 int rd, int rs, int rt)
6af0bf9c 3882{
7a387fff
TS
3883 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3884 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
3885 /* If no destination, treat it as a NOP.
3886 For add & sub, we must generate the overflow exception when needed. */
460f00c4 3887 return;
185f0762 3888 }
460f00c4 3889
6af0bf9c
FB
3890 switch (opc) {
3891 case OPC_ADD:
48d38ca5 3892 {
460f00c4
AJ
3893 TCGv t0 = tcg_temp_local_new();
3894 TCGv t1 = tcg_temp_new();
3895 TCGv t2 = tcg_temp_new();
42a268c2 3896 TCGLabel *l1 = gen_new_label();
48d38ca5 3897
460f00c4
AJ
3898 gen_load_gpr(t1, rs);
3899 gen_load_gpr(t2, rt);
3900 tcg_gen_add_tl(t0, t1, t2);
3901 tcg_gen_ext32s_tl(t0, t0);
3902 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3903 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3904 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3905 tcg_temp_free(t2);
3906 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3907 tcg_temp_free(t1);
48d38ca5
TS
3908 /* operands of same sign, result different sign */
3909 generate_exception(ctx, EXCP_OVERFLOW);
3910 gen_set_label(l1);
460f00c4
AJ
3911 gen_store_gpr(t0, rd);
3912 tcg_temp_free(t0);
48d38ca5 3913 }
6af0bf9c
FB
3914 break;
3915 case OPC_ADDU:
460f00c4
AJ
3916 if (rs != 0 && rt != 0) {
3917 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3918 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3919 } else if (rs == 0 && rt != 0) {
3920 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3921 } else if (rs != 0 && rt == 0) {
3922 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3923 } else {
3924 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3925 }
6af0bf9c
FB
3926 break;
3927 case OPC_SUB:
48d38ca5 3928 {
460f00c4
AJ
3929 TCGv t0 = tcg_temp_local_new();
3930 TCGv t1 = tcg_temp_new();
3931 TCGv t2 = tcg_temp_new();
42a268c2 3932 TCGLabel *l1 = gen_new_label();
48d38ca5 3933
460f00c4
AJ
3934 gen_load_gpr(t1, rs);
3935 gen_load_gpr(t2, rt);
3936 tcg_gen_sub_tl(t0, t1, t2);
3937 tcg_gen_ext32s_tl(t0, t0);
3938 tcg_gen_xor_tl(t2, t1, t2);
3939 tcg_gen_xor_tl(t1, t0, t1);
3940 tcg_gen_and_tl(t1, t1, t2);
3941 tcg_temp_free(t2);
3942 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3943 tcg_temp_free(t1);
31e3104f 3944 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
3945 generate_exception(ctx, EXCP_OVERFLOW);
3946 gen_set_label(l1);
460f00c4
AJ
3947 gen_store_gpr(t0, rd);
3948 tcg_temp_free(t0);
48d38ca5 3949 }
6af0bf9c
FB
3950 break;
3951 case OPC_SUBU:
460f00c4
AJ
3952 if (rs != 0 && rt != 0) {
3953 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3954 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3955 } else if (rs == 0 && rt != 0) {
3956 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 3957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
3958 } else if (rs != 0 && rt == 0) {
3959 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3960 } else {
3961 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3962 }
6af0bf9c 3963 break;
d26bc211 3964#if defined(TARGET_MIPS64)
7a387fff 3965 case OPC_DADD:
48d38ca5 3966 {
460f00c4
AJ
3967 TCGv t0 = tcg_temp_local_new();
3968 TCGv t1 = tcg_temp_new();
3969 TCGv t2 = tcg_temp_new();
42a268c2 3970 TCGLabel *l1 = gen_new_label();
48d38ca5 3971
460f00c4
AJ
3972 gen_load_gpr(t1, rs);
3973 gen_load_gpr(t2, rt);
3974 tcg_gen_add_tl(t0, t1, t2);
3975 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3976 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3977 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3978 tcg_temp_free(t2);
3979 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3980 tcg_temp_free(t1);
48d38ca5
TS
3981 /* operands of same sign, result different sign */
3982 generate_exception(ctx, EXCP_OVERFLOW);
3983 gen_set_label(l1);
460f00c4
AJ
3984 gen_store_gpr(t0, rd);
3985 tcg_temp_free(t0);
48d38ca5 3986 }
7a387fff
TS
3987 break;
3988 case OPC_DADDU:
460f00c4
AJ
3989 if (rs != 0 && rt != 0) {
3990 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3991 } else if (rs == 0 && rt != 0) {
3992 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3993 } else if (rs != 0 && rt == 0) {
3994 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3995 } else {
3996 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3997 }
7a387fff
TS
3998 break;
3999 case OPC_DSUB:
48d38ca5 4000 {
460f00c4
AJ
4001 TCGv t0 = tcg_temp_local_new();
4002 TCGv t1 = tcg_temp_new();
4003 TCGv t2 = tcg_temp_new();
42a268c2 4004 TCGLabel *l1 = gen_new_label();
48d38ca5 4005
460f00c4
AJ
4006 gen_load_gpr(t1, rs);
4007 gen_load_gpr(t2, rt);
4008 tcg_gen_sub_tl(t0, t1, t2);
4009 tcg_gen_xor_tl(t2, t1, t2);
4010 tcg_gen_xor_tl(t1, t0, t1);
4011 tcg_gen_and_tl(t1, t1, t2);
4012 tcg_temp_free(t2);
4013 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4014 tcg_temp_free(t1);
31e3104f 4015 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4016 generate_exception(ctx, EXCP_OVERFLOW);
4017 gen_set_label(l1);
460f00c4
AJ
4018 gen_store_gpr(t0, rd);
4019 tcg_temp_free(t0);
48d38ca5 4020 }
7a387fff
TS
4021 break;
4022 case OPC_DSUBU:
460f00c4
AJ
4023 if (rs != 0 && rt != 0) {
4024 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4025 } else if (rs == 0 && rt != 0) {
4026 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4027 } else if (rs != 0 && rt == 0) {
4028 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4029 } else {
4030 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4031 }
7a387fff
TS
4032 break;
4033#endif
460f00c4
AJ
4034 case OPC_MUL:
4035 if (likely(rs != 0 && rt != 0)) {
4036 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4037 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4038 } else {
4039 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4040 }
6af0bf9c 4041 break;
460f00c4 4042 }
460f00c4
AJ
4043}
4044
4045/* Conditional move */
d75c135e 4046static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 4047 int rd, int rs, int rt)
460f00c4 4048{
acf12465 4049 TCGv t0, t1, t2;
460f00c4
AJ
4050
4051 if (rd == 0) {
acf12465 4052 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4053 return;
4054 }
4055
acf12465
AJ
4056 t0 = tcg_temp_new();
4057 gen_load_gpr(t0, rt);
4058 t1 = tcg_const_tl(0);
4059 t2 = tcg_temp_new();
4060 gen_load_gpr(t2, rs);
460f00c4
AJ
4061 switch (opc) {
4062 case OPC_MOVN:
acf12465 4063 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 4064 break;
460f00c4 4065 case OPC_MOVZ:
acf12465 4066 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 4067 break;
b691d9d2
LA
4068 case OPC_SELNEZ:
4069 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
4070 break;
4071 case OPC_SELEQZ:
4072 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 4073 break;
460f00c4 4074 }
acf12465
AJ
4075 tcg_temp_free(t2);
4076 tcg_temp_free(t1);
4077 tcg_temp_free(t0);
460f00c4
AJ
4078}
4079
4080/* Logic */
d75c135e 4081static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 4082 int rd, int rs, int rt)
460f00c4 4083{
460f00c4
AJ
4084 if (rd == 0) {
4085 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4086 return;
4087 }
4088
4089 switch (opc) {
6af0bf9c 4090 case OPC_AND:
460f00c4
AJ
4091 if (likely(rs != 0 && rt != 0)) {
4092 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4093 } else {
4094 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4095 }
6af0bf9c
FB
4096 break;
4097 case OPC_NOR:
460f00c4
AJ
4098 if (rs != 0 && rt != 0) {
4099 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4100 } else if (rs == 0 && rt != 0) {
4101 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4102 } else if (rs != 0 && rt == 0) {
4103 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4104 } else {
4105 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4106 }
6af0bf9c
FB
4107 break;
4108 case OPC_OR:
460f00c4
AJ
4109 if (likely(rs != 0 && rt != 0)) {
4110 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4111 } else if (rs == 0 && rt != 0) {
4112 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4113 } else if (rs != 0 && rt == 0) {
4114 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4115 } else {
4116 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4117 }
6af0bf9c
FB
4118 break;
4119 case OPC_XOR:
460f00c4
AJ
4120 if (likely(rs != 0 && rt != 0)) {
4121 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4122 } else if (rs == 0 && rt != 0) {
4123 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4124 } else if (rs != 0 && rt == 0) {
4125 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4126 } else {
4127 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4128 }
6af0bf9c 4129 break;
460f00c4 4130 }
460f00c4
AJ
4131}
4132
4133/* Set on lower than */
d75c135e 4134static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 4135 int rd, int rs, int rt)
460f00c4 4136{
460f00c4
AJ
4137 TCGv t0, t1;
4138
4139 if (rd == 0) {
4140 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4141 return;
4142 }
4143
4144 t0 = tcg_temp_new();
4145 t1 = tcg_temp_new();
4146 gen_load_gpr(t0, rs);
4147 gen_load_gpr(t1, rt);
4148 switch (opc) {
4149 case OPC_SLT:
e68dd28f 4150 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 4151 break;
460f00c4 4152 case OPC_SLTU:
e68dd28f 4153 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
4154 break;
4155 }
460f00c4
AJ
4156 tcg_temp_free(t0);
4157 tcg_temp_free(t1);
4158}
20c4c97c 4159
460f00c4 4160/* Shifts */
d75c135e
AJ
4161static void gen_shift(DisasContext *ctx, uint32_t opc,
4162 int rd, int rs, int rt)
460f00c4 4163{
460f00c4 4164 TCGv t0, t1;
20c4c97c 4165
460f00c4
AJ
4166 if (rd == 0) {
4167 /* If no destination, treat it as a NOP.
4168 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
4169 return;
4170 }
4171
4172 t0 = tcg_temp_new();
4173 t1 = tcg_temp_new();
4174 gen_load_gpr(t0, rs);
4175 gen_load_gpr(t1, rt);
4176 switch (opc) {
6af0bf9c 4177 case OPC_SLLV:
78723684
TS
4178 tcg_gen_andi_tl(t0, t0, 0x1f);
4179 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 4180 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
4181 break;
4182 case OPC_SRAV:
78723684 4183 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 4184 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
4185 break;
4186 case OPC_SRLV:
ea63e2c3
NF
4187 tcg_gen_ext32u_tl(t1, t1);
4188 tcg_gen_andi_tl(t0, t0, 0x1f);
4189 tcg_gen_shr_tl(t0, t1, t0);
4190 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
4191 break;
4192 case OPC_ROTRV:
4193 {
4194 TCGv_i32 t2 = tcg_temp_new_i32();
4195 TCGv_i32 t3 = tcg_temp_new_i32();
4196
4197 tcg_gen_trunc_tl_i32(t2, t0);
4198 tcg_gen_trunc_tl_i32(t3, t1);
4199 tcg_gen_andi_i32(t2, t2, 0x1f);
4200 tcg_gen_rotr_i32(t2, t3, t2);
4201 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4202 tcg_temp_free_i32(t2);
4203 tcg_temp_free_i32(t3);
5a63bcb2 4204 }
7a387fff 4205 break;
d26bc211 4206#if defined(TARGET_MIPS64)
7a387fff 4207 case OPC_DSLLV:
78723684 4208 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4209 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4210 break;
4211 case OPC_DSRAV:
78723684 4212 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4213 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4214 break;
4215 case OPC_DSRLV:
ea63e2c3
NF
4216 tcg_gen_andi_tl(t0, t0, 0x3f);
4217 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
4218 break;
4219 case OPC_DROTRV:
4220 tcg_gen_andi_tl(t0, t0, 0x3f);
4221 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 4222 break;
7a387fff 4223#endif
6af0bf9c 4224 }
78723684
TS
4225 tcg_temp_free(t0);
4226 tcg_temp_free(t1);
6af0bf9c
FB
4227}
4228
4229/* Arithmetic on HI/LO registers */
26135ead 4230static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 4231{
6af0bf9c 4232 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 4233 /* Treat as NOP. */
a1f6684d 4234 return;
6af0bf9c 4235 }
4133498f 4236
4133498f
JL
4237 if (acc != 0) {
4238 check_dsp(ctx);
4239 }
4240
6af0bf9c
FB
4241 switch (opc) {
4242 case OPC_MFHI:
4133498f
JL
4243#if defined(TARGET_MIPS64)
4244 if (acc != 0) {
4245 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4246 } else
4247#endif
4248 {
4249 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4250 }
6af0bf9c
FB
4251 break;
4252 case OPC_MFLO:
4133498f
JL
4253#if defined(TARGET_MIPS64)
4254 if (acc != 0) {
4255 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4256 } else
4257#endif
4258 {
4259 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4260 }
6af0bf9c
FB
4261 break;
4262 case OPC_MTHI:
4133498f
JL
4263 if (reg != 0) {
4264#if defined(TARGET_MIPS64)
4265 if (acc != 0) {
4266 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4267 } else
4268#endif
4269 {
4270 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4271 }
4272 } else {
4273 tcg_gen_movi_tl(cpu_HI[acc], 0);
4274 }
6af0bf9c
FB
4275 break;
4276 case OPC_MTLO:
4133498f
JL
4277 if (reg != 0) {
4278#if defined(TARGET_MIPS64)
4279 if (acc != 0) {
4280 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4281 } else
4282#endif
4283 {
4284 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4285 }
4286 } else {
4287 tcg_gen_movi_tl(cpu_LO[acc], 0);
4288 }
6af0bf9c 4289 break;
6af0bf9c 4290 }
6af0bf9c
FB
4291}
4292
d4ea6acd
LA
4293static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4294 TCGMemOp memop)
4295{
4296 TCGv t0 = tcg_const_tl(addr);
4297 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4298 gen_store_gpr(t0, reg);
4299 tcg_temp_free(t0);
4300}
4301
ab39ee45
YK
4302static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4303 int rs)
d4ea6acd
LA
4304{
4305 target_long offset;
4306 target_long addr;
4307
ab39ee45 4308 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
4309 case OPC_ADDIUPC:
4310 if (rs != 0) {
4311 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4312 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4313 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4314 }
4315 break;
4316 case R6_OPC_LWPC:
4317 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4318 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4319 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4320 break;
4321#if defined(TARGET_MIPS64)
4322 case OPC_LWUPC:
4323 check_mips_64(ctx);
4324 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4325 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4326 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4327 break;
4328#endif
4329 default:
ab39ee45 4330 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
4331 case OPC_AUIPC:
4332 if (rs != 0) {
ab39ee45
YK
4333 offset = sextract32(ctx->opcode, 0, 16) << 16;
4334 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4335 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4336 }
4337 break;
4338 case OPC_ALUIPC:
4339 if (rs != 0) {
ab39ee45
YK
4340 offset = sextract32(ctx->opcode, 0, 16) << 16;
4341 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
4342 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4343 }
4344 break;
4345#if defined(TARGET_MIPS64)
4346 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4347 case R6_OPC_LDPC + (1 << 16):
4348 case R6_OPC_LDPC + (2 << 16):
4349 case R6_OPC_LDPC + (3 << 16):
4350 check_mips_64(ctx);
4351 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 4352 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
4353 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4354 break;
4355#endif
4356 default:
4357 MIPS_INVAL("OPC_PCREL");
9c708c7f 4358 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
4359 break;
4360 }
4361 break;
4362 }
4363}
4364
b42ee5e1
LA
4365static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4366{
b42ee5e1
LA
4367 TCGv t0, t1;
4368
4369 if (rd == 0) {
4370 /* Treat as NOP. */
b42ee5e1
LA
4371 return;
4372 }
4373
4374 t0 = tcg_temp_new();
4375 t1 = tcg_temp_new();
4376
4377 gen_load_gpr(t0, rs);
4378 gen_load_gpr(t1, rt);
4379
4380 switch (opc) {
4381 case R6_OPC_DIV:
4382 {
4383 TCGv t2 = tcg_temp_new();
4384 TCGv t3 = tcg_temp_new();
4385 tcg_gen_ext32s_tl(t0, t0);
4386 tcg_gen_ext32s_tl(t1, t1);
4387 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4388 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4389 tcg_gen_and_tl(t2, t2, t3);
4390 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4391 tcg_gen_or_tl(t2, t2, t3);
4392 tcg_gen_movi_tl(t3, 0);
4393 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4394 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4395 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4396 tcg_temp_free(t3);
4397 tcg_temp_free(t2);
4398 }
b42ee5e1
LA
4399 break;
4400 case R6_OPC_MOD:
4401 {
4402 TCGv t2 = tcg_temp_new();
4403 TCGv t3 = tcg_temp_new();
4404 tcg_gen_ext32s_tl(t0, t0);
4405 tcg_gen_ext32s_tl(t1, t1);
4406 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4407 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4408 tcg_gen_and_tl(t2, t2, t3);
4409 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4410 tcg_gen_or_tl(t2, t2, t3);
4411 tcg_gen_movi_tl(t3, 0);
4412 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4413 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4414 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4415 tcg_temp_free(t3);
4416 tcg_temp_free(t2);
4417 }
b42ee5e1
LA
4418 break;
4419 case R6_OPC_DIVU:
4420 {
4421 TCGv t2 = tcg_const_tl(0);
4422 TCGv t3 = tcg_const_tl(1);
4423 tcg_gen_ext32u_tl(t0, t0);
4424 tcg_gen_ext32u_tl(t1, t1);
4425 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4426 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4427 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4428 tcg_temp_free(t3);
4429 tcg_temp_free(t2);
4430 }
b42ee5e1
LA
4431 break;
4432 case R6_OPC_MODU:
4433 {
4434 TCGv t2 = tcg_const_tl(0);
4435 TCGv t3 = tcg_const_tl(1);
4436 tcg_gen_ext32u_tl(t0, t0);
4437 tcg_gen_ext32u_tl(t1, t1);
4438 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4439 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4440 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4441 tcg_temp_free(t3);
4442 tcg_temp_free(t2);
4443 }
b42ee5e1
LA
4444 break;
4445 case R6_OPC_MUL:
4446 {
4447 TCGv_i32 t2 = tcg_temp_new_i32();
4448 TCGv_i32 t3 = tcg_temp_new_i32();
4449 tcg_gen_trunc_tl_i32(t2, t0);
4450 tcg_gen_trunc_tl_i32(t3, t1);
4451 tcg_gen_mul_i32(t2, t2, t3);
4452 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4453 tcg_temp_free_i32(t2);
4454 tcg_temp_free_i32(t3);
4455 }
b42ee5e1
LA
4456 break;
4457 case R6_OPC_MUH:
4458 {
4459 TCGv_i32 t2 = tcg_temp_new_i32();
4460 TCGv_i32 t3 = tcg_temp_new_i32();
4461 tcg_gen_trunc_tl_i32(t2, t0);
4462 tcg_gen_trunc_tl_i32(t3, t1);
4463 tcg_gen_muls2_i32(t2, t3, t2, t3);
4464 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4465 tcg_temp_free_i32(t2);
4466 tcg_temp_free_i32(t3);
4467 }
b42ee5e1
LA
4468 break;
4469 case R6_OPC_MULU:
4470 {
4471 TCGv_i32 t2 = tcg_temp_new_i32();
4472 TCGv_i32 t3 = tcg_temp_new_i32();
4473 tcg_gen_trunc_tl_i32(t2, t0);
4474 tcg_gen_trunc_tl_i32(t3, t1);
4475 tcg_gen_mul_i32(t2, t2, t3);
4476 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4477 tcg_temp_free_i32(t2);
4478 tcg_temp_free_i32(t3);
4479 }
b42ee5e1
LA
4480 break;
4481 case R6_OPC_MUHU:
4482 {
4483 TCGv_i32 t2 = tcg_temp_new_i32();
4484 TCGv_i32 t3 = tcg_temp_new_i32();
4485 tcg_gen_trunc_tl_i32(t2, t0);
4486 tcg_gen_trunc_tl_i32(t3, t1);
4487 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4488 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4489 tcg_temp_free_i32(t2);
4490 tcg_temp_free_i32(t3);
4491 }
b42ee5e1
LA
4492 break;
4493#if defined(TARGET_MIPS64)
4494 case R6_OPC_DDIV:
4495 {
4496 TCGv t2 = tcg_temp_new();
4497 TCGv t3 = tcg_temp_new();
4498 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4499 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4500 tcg_gen_and_tl(t2, t2, t3);
4501 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4502 tcg_gen_or_tl(t2, t2, t3);
4503 tcg_gen_movi_tl(t3, 0);
4504 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4505 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4506 tcg_temp_free(t3);
4507 tcg_temp_free(t2);
4508 }
b42ee5e1
LA
4509 break;
4510 case R6_OPC_DMOD:
4511 {
4512 TCGv t2 = tcg_temp_new();
4513 TCGv t3 = tcg_temp_new();
4514 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4515 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4516 tcg_gen_and_tl(t2, t2, t3);
4517 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4518 tcg_gen_or_tl(t2, t2, t3);
4519 tcg_gen_movi_tl(t3, 0);
4520 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4521 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4522 tcg_temp_free(t3);
4523 tcg_temp_free(t2);
4524 }
b42ee5e1
LA
4525 break;
4526 case R6_OPC_DDIVU:
4527 {
4528 TCGv t2 = tcg_const_tl(0);
4529 TCGv t3 = tcg_const_tl(1);
4530 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4531 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4532 tcg_temp_free(t3);
4533 tcg_temp_free(t2);
4534 }
b42ee5e1
LA
4535 break;
4536 case R6_OPC_DMODU:
4537 {
4538 TCGv t2 = tcg_const_tl(0);
4539 TCGv t3 = tcg_const_tl(1);
4540 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4541 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4542 tcg_temp_free(t3);
4543 tcg_temp_free(t2);
4544 }
b42ee5e1
LA
4545 break;
4546 case R6_OPC_DMUL:
4547 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4548 break;
4549 case R6_OPC_DMUH:
4550 {
4551 TCGv t2 = tcg_temp_new();
4552 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4553 tcg_temp_free(t2);
4554 }
b42ee5e1
LA
4555 break;
4556 case R6_OPC_DMULU:
4557 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4558 break;
4559 case R6_OPC_DMUHU:
4560 {
4561 TCGv t2 = tcg_temp_new();
4562 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4563 tcg_temp_free(t2);
4564 }
b42ee5e1
LA
4565 break;
4566#endif
4567 default:
9d68ac14 4568 MIPS_INVAL("r6 mul/div");
9c708c7f 4569 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
4570 goto out;
4571 }
b42ee5e1
LA
4572 out:
4573 tcg_temp_free(t0);
4574 tcg_temp_free(t1);
4575}
4576
26135ead
RS
4577static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4578 int acc, int rs, int rt)
6af0bf9c 4579{
d45f89f4
AJ
4580 TCGv t0, t1;
4581
51127181
AJ
4582 t0 = tcg_temp_new();
4583 t1 = tcg_temp_new();
6af0bf9c 4584
78723684
TS
4585 gen_load_gpr(t0, rs);
4586 gen_load_gpr(t1, rt);
51127181 4587
26135ead
RS
4588 if (acc != 0) {
4589 check_dsp(ctx);
4590 }
4591
6af0bf9c
FB
4592 switch (opc) {
4593 case OPC_DIV:
48d38ca5 4594 {
51127181
AJ
4595 TCGv t2 = tcg_temp_new();
4596 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4597 tcg_gen_ext32s_tl(t0, t0);
4598 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4599 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4600 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4601 tcg_gen_and_tl(t2, t2, t3);
4602 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4603 tcg_gen_or_tl(t2, t2, t3);
4604 tcg_gen_movi_tl(t3, 0);
4605 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4606 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4607 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4608 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4609 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4610 tcg_temp_free(t3);
4611 tcg_temp_free(t2);
48d38ca5 4612 }
6af0bf9c
FB
4613 break;
4614 case OPC_DIVU:
48d38ca5 4615 {
51127181
AJ
4616 TCGv t2 = tcg_const_tl(0);
4617 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4618 tcg_gen_ext32u_tl(t0, t0);
4619 tcg_gen_ext32u_tl(t1, t1);
51127181 4620 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4621 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4622 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4623 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4624 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4625 tcg_temp_free(t3);
4626 tcg_temp_free(t2);
48d38ca5 4627 }
6af0bf9c
FB
4628 break;
4629 case OPC_MULT:
214c465f 4630 {
ce1dd5d1
RH
4631 TCGv_i32 t2 = tcg_temp_new_i32();
4632 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4633 tcg_gen_trunc_tl_i32(t2, t0);
4634 tcg_gen_trunc_tl_i32(t3, t1);
4635 tcg_gen_muls2_i32(t2, t3, t2, t3);
4636 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4637 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4638 tcg_temp_free_i32(t2);
4639 tcg_temp_free_i32(t3);
214c465f 4640 }
6af0bf9c
FB
4641 break;
4642 case OPC_MULTU:
214c465f 4643 {
ce1dd5d1
RH
4644 TCGv_i32 t2 = tcg_temp_new_i32();
4645 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4646 tcg_gen_trunc_tl_i32(t2, t0);
4647 tcg_gen_trunc_tl_i32(t3, t1);
4648 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4649 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4650 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4651 tcg_temp_free_i32(t2);
4652 tcg_temp_free_i32(t3);
214c465f 4653 }
6af0bf9c 4654 break;
d26bc211 4655#if defined(TARGET_MIPS64)
7a387fff 4656 case OPC_DDIV:
48d38ca5 4657 {
51127181
AJ
4658 TCGv t2 = tcg_temp_new();
4659 TCGv t3 = tcg_temp_new();
4660 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4661 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4662 tcg_gen_and_tl(t2, t2, t3);
4663 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4664 tcg_gen_or_tl(t2, t2, t3);
4665 tcg_gen_movi_tl(t3, 0);
4666 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4667 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4668 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4669 tcg_temp_free(t3);
4670 tcg_temp_free(t2);
48d38ca5 4671 }
7a387fff
TS
4672 break;
4673 case OPC_DDIVU:
48d38ca5 4674 {
51127181
AJ
4675 TCGv t2 = tcg_const_tl(0);
4676 TCGv t3 = tcg_const_tl(1);
4677 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4678 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4679 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4680 tcg_temp_free(t3);
4681 tcg_temp_free(t2);
48d38ca5 4682 }
7a387fff
TS
4683 break;
4684 case OPC_DMULT:
26135ead 4685 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4686 break;
4687 case OPC_DMULTU:
26135ead 4688 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4689 break;
4690#endif
6af0bf9c 4691 case OPC_MADD:
214c465f 4692 {
d45f89f4
AJ
4693 TCGv_i64 t2 = tcg_temp_new_i64();
4694 TCGv_i64 t3 = tcg_temp_new_i64();
4695
4696 tcg_gen_ext_tl_i64(t2, t0);
4697 tcg_gen_ext_tl_i64(t3, t1);
4698 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4699 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4700 tcg_gen_add_i64(t2, t2, t3);
4701 tcg_temp_free_i64(t3);
71f303cd
RH
4702 gen_move_low32(cpu_LO[acc], t2);
4703 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4704 tcg_temp_free_i64(t2);
214c465f 4705 }
6af0bf9c
FB
4706 break;
4707 case OPC_MADDU:
4133498f 4708 {
d45f89f4
AJ
4709 TCGv_i64 t2 = tcg_temp_new_i64();
4710 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4711
78723684
TS
4712 tcg_gen_ext32u_tl(t0, t0);
4713 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4714 tcg_gen_extu_tl_i64(t2, t0);
4715 tcg_gen_extu_tl_i64(t3, t1);
4716 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4717 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4718 tcg_gen_add_i64(t2, t2, t3);
4719 tcg_temp_free_i64(t3);
71f303cd
RH
4720 gen_move_low32(cpu_LO[acc], t2);
4721 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4722 tcg_temp_free_i64(t2);
214c465f 4723 }
6af0bf9c
FB
4724 break;
4725 case OPC_MSUB:
214c465f 4726 {
d45f89f4
AJ
4727 TCGv_i64 t2 = tcg_temp_new_i64();
4728 TCGv_i64 t3 = tcg_temp_new_i64();
4729
4730 tcg_gen_ext_tl_i64(t2, t0);
4731 tcg_gen_ext_tl_i64(t3, t1);
4732 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4733 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4734 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4735 tcg_temp_free_i64(t3);
71f303cd
RH
4736 gen_move_low32(cpu_LO[acc], t2);
4737 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4738 tcg_temp_free_i64(t2);
214c465f 4739 }
6af0bf9c
FB
4740 break;
4741 case OPC_MSUBU:
214c465f 4742 {
d45f89f4
AJ
4743 TCGv_i64 t2 = tcg_temp_new_i64();
4744 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4745
78723684
TS
4746 tcg_gen_ext32u_tl(t0, t0);
4747 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4748 tcg_gen_extu_tl_i64(t2, t0);
4749 tcg_gen_extu_tl_i64(t3, t1);
4750 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4751 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4752 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4753 tcg_temp_free_i64(t3);
71f303cd
RH
4754 gen_move_low32(cpu_LO[acc], t2);
4755 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4756 tcg_temp_free_i64(t2);
214c465f 4757 }
6af0bf9c
FB
4758 break;
4759 default:
9d68ac14 4760 MIPS_INVAL("mul/div");
9c708c7f 4761 generate_exception_end(ctx, EXCP_RI);
78723684 4762 goto out;
6af0bf9c 4763 }
78723684
TS
4764 out:
4765 tcg_temp_free(t0);
4766 tcg_temp_free(t1);
6af0bf9c
FB
4767}
4768
e9c71dd1
TS
4769static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4770 int rd, int rs, int rt)
4771{
f157bfe1
AJ
4772 TCGv t0 = tcg_temp_new();
4773 TCGv t1 = tcg_temp_new();
e9c71dd1 4774
6c5c1e20
TS
4775 gen_load_gpr(t0, rs);
4776 gen_load_gpr(t1, rt);
e9c71dd1
TS
4777
4778 switch (opc) {
4779 case OPC_VR54XX_MULS:
895c2d04 4780 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 4781 break;
e9c71dd1 4782 case OPC_VR54XX_MULSU:
895c2d04 4783 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 4784 break;
e9c71dd1 4785 case OPC_VR54XX_MACC:
895c2d04 4786 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 4787 break;
e9c71dd1 4788 case OPC_VR54XX_MACCU:
895c2d04 4789 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 4790 break;
e9c71dd1 4791 case OPC_VR54XX_MSAC:
895c2d04 4792 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 4793 break;
e9c71dd1 4794 case OPC_VR54XX_MSACU:
895c2d04 4795 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 4796 break;
e9c71dd1 4797 case OPC_VR54XX_MULHI:
895c2d04 4798 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 4799 break;
e9c71dd1 4800 case OPC_VR54XX_MULHIU:
895c2d04 4801 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 4802 break;
e9c71dd1 4803 case OPC_VR54XX_MULSHI:
895c2d04 4804 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 4805 break;
e9c71dd1 4806 case OPC_VR54XX_MULSHIU:
895c2d04 4807 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 4808 break;
e9c71dd1 4809 case OPC_VR54XX_MACCHI:
895c2d04 4810 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 4811 break;
e9c71dd1 4812 case OPC_VR54XX_MACCHIU:
895c2d04 4813 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 4814 break;
e9c71dd1 4815 case OPC_VR54XX_MSACHI:
895c2d04 4816 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 4817 break;
e9c71dd1 4818 case OPC_VR54XX_MSACHIU:
895c2d04 4819 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 4820 break;
e9c71dd1
TS
4821 default:
4822 MIPS_INVAL("mul vr54xx");
9c708c7f 4823 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4824 goto out;
e9c71dd1 4825 }
6c5c1e20 4826 gen_store_gpr(t0, rd);
6c5c1e20
TS
4827
4828 out:
4829 tcg_temp_free(t0);
4830 tcg_temp_free(t1);
e9c71dd1
TS
4831}
4832
7a387fff 4833static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4834 int rd, int rs)
4835{
20e1fb52 4836 TCGv t0;
6c5c1e20 4837
6af0bf9c 4838 if (rd == 0) {
ead9360e 4839 /* Treat as NOP. */
20e1fb52 4840 return;
6af0bf9c 4841 }
1a0196c5 4842 t0 = cpu_gpr[rd];
6c5c1e20 4843 gen_load_gpr(t0, rs);
1a0196c5 4844
6af0bf9c
FB
4845 switch (opc) {
4846 case OPC_CLO:
4267d3e6 4847 case R6_OPC_CLO:
1a0196c5
RH
4848#if defined(TARGET_MIPS64)
4849 case OPC_DCLO:
4850 case R6_OPC_DCLO:
4851#endif
4852 tcg_gen_not_tl(t0, t0);
6af0bf9c 4853 break;
1a0196c5
RH
4854 }
4855
4856 switch (opc) {
4857 case OPC_CLO:
4858 case R6_OPC_CLO:
6af0bf9c 4859 case OPC_CLZ:
4267d3e6 4860 case R6_OPC_CLZ:
1a0196c5
RH
4861 tcg_gen_ext32u_tl(t0, t0);
4862 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4863 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 4864 break;
d26bc211 4865#if defined(TARGET_MIPS64)
7a387fff 4866 case OPC_DCLO:
4267d3e6 4867 case R6_OPC_DCLO:
7a387fff 4868 case OPC_DCLZ:
4267d3e6 4869 case R6_OPC_DCLZ:
1a0196c5 4870 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
4871 break;
4872#endif
6af0bf9c 4873 }
6af0bf9c
FB
4874}
4875
161f85e6 4876/* Godson integer instructions */
bd277fa1
RH
4877static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4878 int rd, int rs, int rt)
161f85e6 4879{
161f85e6
AJ
4880 TCGv t0, t1;
4881
4882 if (rd == 0) {
4883 /* Treat as NOP. */
161f85e6
AJ
4884 return;
4885 }
4886
4887 switch (opc) {
4888 case OPC_MULT_G_2E:
4889 case OPC_MULT_G_2F:
4890 case OPC_MULTU_G_2E:
4891 case OPC_MULTU_G_2F:
4892#if defined(TARGET_MIPS64)
4893 case OPC_DMULT_G_2E:
4894 case OPC_DMULT_G_2F:
4895 case OPC_DMULTU_G_2E:
4896 case OPC_DMULTU_G_2F:
4897#endif
4898 t0 = tcg_temp_new();
4899 t1 = tcg_temp_new();
4900 break;
4901 default:
4902 t0 = tcg_temp_local_new();
4903 t1 = tcg_temp_local_new();
4904 break;
4905 }
4906
4907 gen_load_gpr(t0, rs);
4908 gen_load_gpr(t1, rt);
4909
4910 switch (opc) {
4911 case OPC_MULT_G_2E:
4912 case OPC_MULT_G_2F:
4913 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4914 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
4915 break;
4916 case OPC_MULTU_G_2E:
4917 case OPC_MULTU_G_2F:
4918 tcg_gen_ext32u_tl(t0, t0);
4919 tcg_gen_ext32u_tl(t1, t1);
4920 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4921 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
4922 break;
4923 case OPC_DIV_G_2E:
4924 case OPC_DIV_G_2F:
4925 {
42a268c2
RH
4926 TCGLabel *l1 = gen_new_label();
4927 TCGLabel *l2 = gen_new_label();
4928 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4929 tcg_gen_ext32s_tl(t0, t0);
4930 tcg_gen_ext32s_tl(t1, t1);
4931 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4932 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4933 tcg_gen_br(l3);
4934 gen_set_label(l1);
4935 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4937 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4938 tcg_gen_br(l3);
4939 gen_set_label(l2);
4940 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4941 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4942 gen_set_label(l3);
4943 }
161f85e6
AJ
4944 break;
4945 case OPC_DIVU_G_2E:
4946 case OPC_DIVU_G_2F:
4947 {
42a268c2
RH
4948 TCGLabel *l1 = gen_new_label();
4949 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4950 tcg_gen_ext32u_tl(t0, t0);
4951 tcg_gen_ext32u_tl(t1, t1);
4952 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4953 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4954 tcg_gen_br(l2);
4955 gen_set_label(l1);
4956 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4958 gen_set_label(l2);
4959 }
161f85e6
AJ
4960 break;
4961 case OPC_MOD_G_2E:
4962 case OPC_MOD_G_2F:
4963 {
42a268c2
RH
4964 TCGLabel *l1 = gen_new_label();
4965 TCGLabel *l2 = gen_new_label();
4966 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4967 tcg_gen_ext32u_tl(t0, t0);
4968 tcg_gen_ext32u_tl(t1, t1);
4969 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4970 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4971 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4972 gen_set_label(l1);
4973 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4974 tcg_gen_br(l3);
4975 gen_set_label(l2);
4976 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4977 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4978 gen_set_label(l3);
4979 }
161f85e6
AJ
4980 break;
4981 case OPC_MODU_G_2E:
4982 case OPC_MODU_G_2F:
4983 {
42a268c2
RH
4984 TCGLabel *l1 = gen_new_label();
4985 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4986 tcg_gen_ext32u_tl(t0, t0);
4987 tcg_gen_ext32u_tl(t1, t1);
4988 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4989 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4990 tcg_gen_br(l2);
4991 gen_set_label(l1);
4992 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4994 gen_set_label(l2);
4995 }
161f85e6
AJ
4996 break;
4997#if defined(TARGET_MIPS64)
4998 case OPC_DMULT_G_2E:
4999 case OPC_DMULT_G_2F:
5000 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5001 break;
5002 case OPC_DMULTU_G_2E:
5003 case OPC_DMULTU_G_2F:
5004 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5005 break;
5006 case OPC_DDIV_G_2E:
5007 case OPC_DDIV_G_2F:
5008 {
42a268c2
RH
5009 TCGLabel *l1 = gen_new_label();
5010 TCGLabel *l2 = gen_new_label();
5011 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5012 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5013 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5014 tcg_gen_br(l3);
5015 gen_set_label(l1);
5016 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5017 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5018 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5019 tcg_gen_br(l3);
5020 gen_set_label(l2);
5021 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5022 gen_set_label(l3);
5023 }
161f85e6
AJ
5024 break;
5025 case OPC_DDIVU_G_2E:
5026 case OPC_DDIVU_G_2F:
5027 {
42a268c2
RH
5028 TCGLabel *l1 = gen_new_label();
5029 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5030 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5031 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5032 tcg_gen_br(l2);
5033 gen_set_label(l1);
5034 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5035 gen_set_label(l2);
5036 }
161f85e6
AJ
5037 break;
5038 case OPC_DMOD_G_2E:
5039 case OPC_DMOD_G_2F:
5040 {
42a268c2
RH
5041 TCGLabel *l1 = gen_new_label();
5042 TCGLabel *l2 = gen_new_label();
5043 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5044 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5045 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5047 gen_set_label(l1);
5048 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5049 tcg_gen_br(l3);
5050 gen_set_label(l2);
5051 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5052 gen_set_label(l3);
5053 }
161f85e6
AJ
5054 break;
5055 case OPC_DMODU_G_2E:
5056 case OPC_DMODU_G_2F:
5057 {
42a268c2
RH
5058 TCGLabel *l1 = gen_new_label();
5059 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5061 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5062 tcg_gen_br(l2);
5063 gen_set_label(l1);
5064 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5065 gen_set_label(l2);
5066 }
161f85e6
AJ
5067 break;
5068#endif
5069 }
5070
161f85e6
AJ
5071 tcg_temp_free(t0);
5072 tcg_temp_free(t1);
5073}
5074
bd277fa1
RH
5075/* Loongson multimedia instructions */
5076static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5077{
bd277fa1
RH
5078 uint32_t opc, shift_max;
5079 TCGv_i64 t0, t1;
5080
5081 opc = MASK_LMI(ctx->opcode);
5082 switch (opc) {
5083 case OPC_ADD_CP2:
5084 case OPC_SUB_CP2:
5085 case OPC_DADD_CP2:
5086 case OPC_DSUB_CP2:
5087 t0 = tcg_temp_local_new_i64();
5088 t1 = tcg_temp_local_new_i64();
5089 break;
5090 default:
5091 t0 = tcg_temp_new_i64();
5092 t1 = tcg_temp_new_i64();
5093 break;
5094 }
5095
b5a587b6 5096 check_cp1_enabled(ctx);
bd277fa1
RH
5097 gen_load_fpr64(ctx, t0, rs);
5098 gen_load_fpr64(ctx, t1, rt);
5099
5100#define LMI_HELPER(UP, LO) \
9d68ac14 5101 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 5102#define LMI_HELPER_1(UP, LO) \
9d68ac14 5103 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 5104#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 5105 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
5106
5107 switch (opc) {
5108 LMI_HELPER(PADDSH, paddsh);
5109 LMI_HELPER(PADDUSH, paddush);
5110 LMI_HELPER(PADDH, paddh);
5111 LMI_HELPER(PADDW, paddw);
5112 LMI_HELPER(PADDSB, paddsb);
5113 LMI_HELPER(PADDUSB, paddusb);
5114 LMI_HELPER(PADDB, paddb);
5115
5116 LMI_HELPER(PSUBSH, psubsh);
5117 LMI_HELPER(PSUBUSH, psubush);
5118 LMI_HELPER(PSUBH, psubh);
5119 LMI_HELPER(PSUBW, psubw);
5120 LMI_HELPER(PSUBSB, psubsb);
5121 LMI_HELPER(PSUBUSB, psubusb);
5122 LMI_HELPER(PSUBB, psubb);
5123
5124 LMI_HELPER(PSHUFH, pshufh);
5125 LMI_HELPER(PACKSSWH, packsswh);
5126 LMI_HELPER(PACKSSHB, packsshb);
5127 LMI_HELPER(PACKUSHB, packushb);
5128
5129 LMI_HELPER(PUNPCKLHW, punpcklhw);
5130 LMI_HELPER(PUNPCKHHW, punpckhhw);
5131 LMI_HELPER(PUNPCKLBH, punpcklbh);
5132 LMI_HELPER(PUNPCKHBH, punpckhbh);
5133 LMI_HELPER(PUNPCKLWD, punpcklwd);
5134 LMI_HELPER(PUNPCKHWD, punpckhwd);
5135
5136 LMI_HELPER(PAVGH, pavgh);
5137 LMI_HELPER(PAVGB, pavgb);
5138 LMI_HELPER(PMAXSH, pmaxsh);
5139 LMI_HELPER(PMINSH, pminsh);
5140 LMI_HELPER(PMAXUB, pmaxub);
5141 LMI_HELPER(PMINUB, pminub);
5142
5143 LMI_HELPER(PCMPEQW, pcmpeqw);
5144 LMI_HELPER(PCMPGTW, pcmpgtw);
5145 LMI_HELPER(PCMPEQH, pcmpeqh);
5146 LMI_HELPER(PCMPGTH, pcmpgth);
5147 LMI_HELPER(PCMPEQB, pcmpeqb);
5148 LMI_HELPER(PCMPGTB, pcmpgtb);
5149
5150 LMI_HELPER(PSLLW, psllw);
5151 LMI_HELPER(PSLLH, psllh);
5152 LMI_HELPER(PSRLW, psrlw);
5153 LMI_HELPER(PSRLH, psrlh);
5154 LMI_HELPER(PSRAW, psraw);
5155 LMI_HELPER(PSRAH, psrah);
5156
5157 LMI_HELPER(PMULLH, pmullh);
5158 LMI_HELPER(PMULHH, pmulhh);
5159 LMI_HELPER(PMULHUH, pmulhuh);
5160 LMI_HELPER(PMADDHW, pmaddhw);
5161
5162 LMI_HELPER(PASUBUB, pasubub);
5163 LMI_HELPER_1(BIADD, biadd);
5164 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5165
5166 LMI_DIRECT(PADDD, paddd, add);
5167 LMI_DIRECT(PSUBD, psubd, sub);
5168 LMI_DIRECT(XOR_CP2, xor, xor);
5169 LMI_DIRECT(NOR_CP2, nor, nor);
5170 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 5171 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 5172
9099a36b
H
5173 case OPC_PANDN:
5174 tcg_gen_andc_i64(t0, t1, t0);
5175 break;
5176
bd277fa1
RH
5177 case OPC_PINSRH_0:
5178 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
5179 break;
5180 case OPC_PINSRH_1:
5181 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
5182 break;
5183 case OPC_PINSRH_2:
5184 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
5185 break;
5186 case OPC_PINSRH_3:
5187 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
5188 break;
5189
5190 case OPC_PEXTRH:
5191 tcg_gen_andi_i64(t1, t1, 3);
5192 tcg_gen_shli_i64(t1, t1, 4);
5193 tcg_gen_shr_i64(t0, t0, t1);
5194 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
5195 break;
5196
5197 case OPC_ADDU_CP2:
5198 tcg_gen_add_i64(t0, t0, t1);
5199 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5200 break;
5201 case OPC_SUBU_CP2:
5202 tcg_gen_sub_i64(t0, t0, t1);
5203 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5204 break;
5205
5206 case OPC_SLL_CP2:
bd277fa1
RH
5207 shift_max = 32;
5208 goto do_shift;
5209 case OPC_SRL_CP2:
bd277fa1
RH
5210 shift_max = 32;
5211 goto do_shift;
5212 case OPC_SRA_CP2:
bd277fa1
RH
5213 shift_max = 32;
5214 goto do_shift;
5215 case OPC_DSLL_CP2:
bd277fa1
RH
5216 shift_max = 64;
5217 goto do_shift;
5218 case OPC_DSRL_CP2:
bd277fa1
RH
5219 shift_max = 64;
5220 goto do_shift;
5221 case OPC_DSRA_CP2:
bd277fa1
RH
5222 shift_max = 64;
5223 goto do_shift;
5224 do_shift:
5225 /* Make sure shift count isn't TCG undefined behaviour. */
5226 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5227
5228 switch (opc) {
5229 case OPC_SLL_CP2:
5230 case OPC_DSLL_CP2:
5231 tcg_gen_shl_i64(t0, t0, t1);
5232 break;
5233 case OPC_SRA_CP2:
5234 case OPC_DSRA_CP2:
5235 /* Since SRA is UndefinedResult without sign-extended inputs,
5236 we can treat SRA and DSRA the same. */
5237 tcg_gen_sar_i64(t0, t0, t1);
5238 break;
5239 case OPC_SRL_CP2:
5240 /* We want to shift in zeros for SRL; zero-extend first. */
5241 tcg_gen_ext32u_i64(t0, t0);
5242 /* FALLTHRU */
5243 case OPC_DSRL_CP2:
5244 tcg_gen_shr_i64(t0, t0, t1);
5245 break;
5246 }
5247
5248 if (shift_max == 32) {
5249 tcg_gen_ext32s_i64(t0, t0);
5250 }
5251
5252 /* Shifts larger than MAX produce zero. */
5253 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5254 tcg_gen_neg_i64(t1, t1);
5255 tcg_gen_and_i64(t0, t0, t1);
5256 break;
5257
5258 case OPC_ADD_CP2:
5259 case OPC_DADD_CP2:
5260 {
5261 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5262 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5263
5264 tcg_gen_mov_i64(t2, t0);
5265 tcg_gen_add_i64(t0, t1, t2);
5266 if (opc == OPC_ADD_CP2) {
5267 tcg_gen_ext32s_i64(t0, t0);
5268 }
5269 tcg_gen_xor_i64(t1, t1, t2);
5270 tcg_gen_xor_i64(t2, t2, t0);
5271 tcg_gen_andc_i64(t1, t2, t1);
5272 tcg_temp_free_i64(t2);
5273 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5274 generate_exception(ctx, EXCP_OVERFLOW);
5275 gen_set_label(lab);
bd277fa1
RH
5276 break;
5277 }
5278
5279 case OPC_SUB_CP2:
5280 case OPC_DSUB_CP2:
5281 {
5282 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5283 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5284
5285 tcg_gen_mov_i64(t2, t0);
5286 tcg_gen_sub_i64(t0, t1, t2);
5287 if (opc == OPC_SUB_CP2) {
5288 tcg_gen_ext32s_i64(t0, t0);
5289 }
5290 tcg_gen_xor_i64(t1, t1, t2);
5291 tcg_gen_xor_i64(t2, t2, t0);
5292 tcg_gen_and_i64(t1, t1, t2);
5293 tcg_temp_free_i64(t2);
5294 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5295 generate_exception(ctx, EXCP_OVERFLOW);
5296 gen_set_label(lab);
bd277fa1
RH
5297 break;
5298 }
5299
5300 case OPC_PMULUW:
5301 tcg_gen_ext32u_i64(t0, t0);
5302 tcg_gen_ext32u_i64(t1, t1);
5303 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
5304 break;
5305
5306 case OPC_SEQU_CP2:
5307 case OPC_SEQ_CP2:
5308 case OPC_SLTU_CP2:
5309 case OPC_SLT_CP2:
5310 case OPC_SLEU_CP2:
5311 case OPC_SLE_CP2:
5312 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5313 FD field is the CC field? */
5314 default:
9d68ac14 5315 MIPS_INVAL("loongson_cp2");
9c708c7f 5316 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
5317 return;
5318 }
5319
5320#undef LMI_HELPER
5321#undef LMI_DIRECT
5322
5323 gen_store_fpr64(ctx, t0, rd);
5324
bd277fa1
RH
5325 tcg_temp_free_i64(t0);
5326 tcg_temp_free_i64(t1);
5327}
5328
6af0bf9c 5329/* Traps */
7a387fff 5330static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5331 int rs, int rt, int16_t imm)
5332{
5333 int cond;
cdc0faa6 5334 TCGv t0 = tcg_temp_new();
1ba74fb8 5335 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
5336
5337 cond = 0;
5338 /* Load needed operands */
5339 switch (opc) {
5340 case OPC_TEQ:
5341 case OPC_TGE:
5342 case OPC_TGEU:
5343 case OPC_TLT:
5344 case OPC_TLTU:
5345 case OPC_TNE:
5346 /* Compare two registers */
5347 if (rs != rt) {
be24bb4f
TS
5348 gen_load_gpr(t0, rs);
5349 gen_load_gpr(t1, rt);
6af0bf9c
FB
5350 cond = 1;
5351 }
179e32bb 5352 break;
6af0bf9c
FB
5353 case OPC_TEQI:
5354 case OPC_TGEI:
5355 case OPC_TGEIU:
5356 case OPC_TLTI:
5357 case OPC_TLTIU:
5358 case OPC_TNEI:
5359 /* Compare register to immediate */
5360 if (rs != 0 || imm != 0) {
be24bb4f
TS
5361 gen_load_gpr(t0, rs);
5362 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
5363 cond = 1;
5364 }
5365 break;
5366 }
5367 if (cond == 0) {
5368 switch (opc) {
5369 case OPC_TEQ: /* rs == rs */
5370 case OPC_TEQI: /* r0 == 0 */
5371 case OPC_TGE: /* rs >= rs */
5372 case OPC_TGEI: /* r0 >= 0 */
5373 case OPC_TGEU: /* rs >= rs unsigned */
5374 case OPC_TGEIU: /* r0 >= 0 unsigned */
5375 /* Always trap */
9c708c7f 5376 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
5377 break;
5378 case OPC_TLT: /* rs < rs */
5379 case OPC_TLTI: /* r0 < 0 */
5380 case OPC_TLTU: /* rs < rs unsigned */
5381 case OPC_TLTIU: /* r0 < 0 unsigned */
5382 case OPC_TNE: /* rs != rs */
5383 case OPC_TNEI: /* r0 != 0 */
ead9360e 5384 /* Never trap: treat as NOP. */
cdc0faa6 5385 break;
6af0bf9c
FB
5386 }
5387 } else {
42a268c2 5388 TCGLabel *l1 = gen_new_label();
cdc0faa6 5389
6af0bf9c
FB
5390 switch (opc) {
5391 case OPC_TEQ:
5392 case OPC_TEQI:
cdc0faa6 5393 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
5394 break;
5395 case OPC_TGE:
5396 case OPC_TGEI:
cdc0faa6 5397 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
5398 break;
5399 case OPC_TGEU:
5400 case OPC_TGEIU:
cdc0faa6 5401 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
5402 break;
5403 case OPC_TLT:
5404 case OPC_TLTI:
cdc0faa6 5405 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
5406 break;
5407 case OPC_TLTU:
5408 case OPC_TLTIU:
cdc0faa6 5409 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
5410 break;
5411 case OPC_TNE:
5412 case OPC_TNEI:
cdc0faa6 5413 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 5414 break;
6af0bf9c 5415 }
cdc0faa6 5416 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
5417 gen_set_label(l1);
5418 }
be24bb4f
TS
5419 tcg_temp_free(t0);
5420 tcg_temp_free(t1);
6af0bf9c
FB
5421}
5422
90aa39a1
SF
5423static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5424{
eeb3bba8 5425 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
5426 return false;
5427 }
5428
5429#ifndef CONFIG_USER_ONLY
eeb3bba8 5430 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
5431#else
5432 return true;
5433#endif
5434}
5435
356265ae 5436static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 5437{
90aa39a1 5438 if (use_goto_tb(ctx, dest)) {
57fec1fe 5439 tcg_gen_goto_tb(n);
9b9e4393 5440 gen_save_pc(dest);
07ea28b4 5441 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 5442 } else {
9b9e4393 5443 gen_save_pc(dest);
eeb3bba8 5444 if (ctx->base.singlestep_enabled) {
7b270ef2 5445 save_cpu_state(ctx, 0);
9c708c7f 5446 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 5447 }
7f11636d 5448 tcg_gen_lookup_and_goto_ptr();
6e256c93 5449 }
c53be334
FB
5450}
5451
6af0bf9c 5452/* Branches (before delay slot) */
7a387fff 5453static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 5454 int insn_bytes,
b231c103
YK
5455 int rs, int rt, int32_t offset,
5456 int delayslot_size)
6af0bf9c 5457{
d077b6f7 5458 target_ulong btgt = -1;
3ad4bb2d 5459 int blink = 0;
2fdbad25 5460 int bcond_compute = 0;
1ba74fb8
AJ
5461 TCGv t0 = tcg_temp_new();
5462 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
5463
5464 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 5465#ifdef MIPS_DEBUG_DISAS
339cd2a8 5466 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 5467 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 5468#endif
9c708c7f 5469 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5470 goto out;
3ad4bb2d 5471 }
6af0bf9c 5472
6af0bf9c
FB
5473 /* Load needed operands */
5474 switch (opc) {
5475 case OPC_BEQ:
5476 case OPC_BEQL:
5477 case OPC_BNE:
5478 case OPC_BNEL:
5479 /* Compare two registers */
5480 if (rs != rt) {
6c5c1e20
TS
5481 gen_load_gpr(t0, rs);
5482 gen_load_gpr(t1, rt);
2fdbad25 5483 bcond_compute = 1;
6af0bf9c 5484 }
eeb3bba8 5485 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
5486 break;
5487 case OPC_BGEZ:
5488 case OPC_BGEZAL:
5489 case OPC_BGEZALL:
5490 case OPC_BGEZL:
5491 case OPC_BGTZ:
5492 case OPC_BGTZL:
5493 case OPC_BLEZ:
5494 case OPC_BLEZL:
5495 case OPC_BLTZ:
5496 case OPC_BLTZAL:
5497 case OPC_BLTZALL:
5498 case OPC_BLTZL:
5499 /* Compare to zero */
5500 if (rs != 0) {
6c5c1e20 5501 gen_load_gpr(t0, rs);
2fdbad25 5502 bcond_compute = 1;
6af0bf9c 5503 }
eeb3bba8 5504 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 5505 break;
e45a93e2
JL
5506 case OPC_BPOSGE32:
5507#if defined(TARGET_MIPS64)
5508 case OPC_BPOSGE64:
5509 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5510#else
5511 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5512#endif
5513 bcond_compute = 1;
eeb3bba8 5514 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 5515 break;
6af0bf9c
FB
5516 case OPC_J:
5517 case OPC_JAL:
364d4831 5518 case OPC_JALX:
6af0bf9c 5519 /* Jump to immediate */
eeb3bba8
EC
5520 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5521 (uint32_t)offset;
6af0bf9c
FB
5522 break;
5523 case OPC_JR:
5524 case OPC_JALR:
5525 /* Jump to register */
7a387fff
TS
5526 if (offset != 0 && offset != 16) {
5527 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 5528 others are reserved. */
923617a3 5529 MIPS_INVAL("jump hint");
9c708c7f 5530 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5531 goto out;
6af0bf9c 5532 }
d077b6f7 5533 gen_load_gpr(btarget, rs);
6af0bf9c
FB
5534 break;
5535 default:
5536 MIPS_INVAL("branch/jump");
9c708c7f 5537 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5538 goto out;
6af0bf9c 5539 }
2fdbad25 5540 if (bcond_compute == 0) {
6af0bf9c
FB
5541 /* No condition to be computed */
5542 switch (opc) {
5543 case OPC_BEQ: /* rx == rx */
5544 case OPC_BEQL: /* rx == rx likely */
5545 case OPC_BGEZ: /* 0 >= 0 */
5546 case OPC_BGEZL: /* 0 >= 0 likely */
5547 case OPC_BLEZ: /* 0 <= 0 */
5548 case OPC_BLEZL: /* 0 <= 0 likely */
5549 /* Always take */
4ad40f36 5550 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5551 break;
5552 case OPC_BGEZAL: /* 0 >= 0 */
5553 case OPC_BGEZALL: /* 0 >= 0 likely */
5554 /* Always take and link */
5555 blink = 31;
4ad40f36 5556 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5557 break;
5558 case OPC_BNE: /* rx != rx */
5559 case OPC_BGTZ: /* 0 > 0 */
5560 case OPC_BLTZ: /* 0 < 0 */
ead9360e 5561 /* Treat as NOP. */
6c5c1e20 5562 goto out;
eeef26cd 5563 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
5564 /* Handle as an unconditional branch to get correct delay
5565 slot checking. */
5566 blink = 31;
eeb3bba8 5567 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 5568 ctx->hflags |= MIPS_HFLAG_B;
3c824109 5569 break;
eeef26cd 5570 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 5571 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 5572 /* Skip the instruction in the delay slot */
eeb3bba8 5573 ctx->base.pc_next += 4;
6c5c1e20 5574 goto out;
6af0bf9c
FB
5575 case OPC_BNEL: /* rx != rx likely */
5576 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
5577 case OPC_BLTZL: /* 0 < 0 likely */
5578 /* Skip the instruction in the delay slot */
eeb3bba8 5579 ctx->base.pc_next += 4;
6c5c1e20 5580 goto out;
6af0bf9c 5581 case OPC_J:
4ad40f36 5582 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5583 break;
364d4831
NF
5584 case OPC_JALX:
5585 ctx->hflags |= MIPS_HFLAG_BX;
5586 /* Fallthrough */
6af0bf9c
FB
5587 case OPC_JAL:
5588 blink = 31;
4ad40f36 5589 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5590 break;
5591 case OPC_JR:
4ad40f36 5592 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5593 break;
5594 case OPC_JALR:
5595 blink = rt;
4ad40f36 5596 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5597 break;
5598 default:
5599 MIPS_INVAL("branch/jump");
9c708c7f 5600 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5601 goto out;
6af0bf9c
FB
5602 }
5603 } else {
5604 switch (opc) {
5605 case OPC_BEQ:
e68dd28f 5606 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5607 goto not_likely;
5608 case OPC_BEQL:
e68dd28f 5609 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5610 goto likely;
5611 case OPC_BNE:
e68dd28f 5612 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5613 goto not_likely;
5614 case OPC_BNEL:
e68dd28f 5615 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5616 goto likely;
5617 case OPC_BGEZ:
e68dd28f 5618 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5619 goto not_likely;
5620 case OPC_BGEZL:
e68dd28f 5621 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5622 goto likely;
5623 case OPC_BGEZAL:
e68dd28f 5624 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5625 blink = 31;
5626 goto not_likely;
5627 case OPC_BGEZALL:
e68dd28f 5628 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5629 blink = 31;
6af0bf9c
FB
5630 goto likely;
5631 case OPC_BGTZ:
e68dd28f 5632 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5633 goto not_likely;
5634 case OPC_BGTZL:
e68dd28f 5635 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5636 goto likely;
5637 case OPC_BLEZ:
e68dd28f 5638 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5639 goto not_likely;
5640 case OPC_BLEZL:
e68dd28f 5641 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5642 goto likely;
5643 case OPC_BLTZ:
e68dd28f 5644 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5645 goto not_likely;
5646 case OPC_BLTZL:
e68dd28f 5647 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5648 goto likely;
e45a93e2
JL
5649 case OPC_BPOSGE32:
5650 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5651 goto not_likely;
5652#if defined(TARGET_MIPS64)
5653 case OPC_BPOSGE64:
5654 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5655 goto not_likely;
5656#endif
6af0bf9c 5657 case OPC_BLTZAL:
e68dd28f 5658 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5659 blink = 31;
6af0bf9c 5660 not_likely:
4ad40f36 5661 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5662 break;
5663 case OPC_BLTZALL:
e68dd28f 5664 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5665 blink = 31;
6af0bf9c 5666 likely:
4ad40f36 5667 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5668 break;
c53f4a62
TS
5669 default:
5670 MIPS_INVAL("conditional branch/jump");
9c708c7f 5671 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5672 goto out;
6af0bf9c 5673 }
6af0bf9c 5674 }
9b9e4393 5675
d077b6f7 5676 ctx->btarget = btgt;
b231c103
YK
5677
5678 switch (delayslot_size) {
5679 case 2:
5680 ctx->hflags |= MIPS_HFLAG_BDS16;
5681 break;
5682 case 4:
5683 ctx->hflags |= MIPS_HFLAG_BDS32;
5684 break;
5685 }
5686
6af0bf9c 5687 if (blink > 0) {
b231c103 5688 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
5689 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5690
eeb3bba8
EC
5691 tcg_gen_movi_tl(cpu_gpr[blink],
5692 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 5693 }
6c5c1e20
TS
5694
5695 out:
364d4831
NF
5696 if (insn_bytes == 2)
5697 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
5698 tcg_temp_free(t0);
5699 tcg_temp_free(t1);
6af0bf9c
FB
5700}
5701
764371d2
SM
5702
5703/* nanoMIPS Branches */
5704static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5705 int insn_bytes,
5706 int rs, int rt, int32_t offset)
5707{
5708 target_ulong btgt = -1;
5709 int bcond_compute = 0;
5710 TCGv t0 = tcg_temp_new();
5711 TCGv t1 = tcg_temp_new();
5712
5713 /* Load needed operands */
5714 switch (opc) {
5715 case OPC_BEQ:
5716 case OPC_BNE:
5717 /* Compare two registers */
5718 if (rs != rt) {
5719 gen_load_gpr(t0, rs);
5720 gen_load_gpr(t1, rt);
5721 bcond_compute = 1;
5722 }
5723 btgt = ctx->base.pc_next + insn_bytes + offset;
5724 break;
5725 case OPC_BGEZAL:
5726 /* Compare to zero */
5727 if (rs != 0) {
5728 gen_load_gpr(t0, rs);
5729 bcond_compute = 1;
5730 }
5731 btgt = ctx->base.pc_next + insn_bytes + offset;
5732 break;
5733 case OPC_BPOSGE32:
5734 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5735 bcond_compute = 1;
5736 btgt = ctx->base.pc_next + insn_bytes + offset;
5737 break;
5738 case OPC_JR:
5739 case OPC_JALR:
5740 /* Jump to register */
5741 if (offset != 0 && offset != 16) {
5742 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5743 others are reserved. */
5744 MIPS_INVAL("jump hint");
5745 generate_exception_end(ctx, EXCP_RI);
5746 goto out;
5747 }
5748 gen_load_gpr(btarget, rs);
5749 break;
5750 default:
5751 MIPS_INVAL("branch/jump");
5752 generate_exception_end(ctx, EXCP_RI);
5753 goto out;
5754 }
5755 if (bcond_compute == 0) {
5756 /* No condition to be computed */
5757 switch (opc) {
5758 case OPC_BEQ: /* rx == rx */
5759 /* Always take */
5760 ctx->hflags |= MIPS_HFLAG_B;
5761 break;
5762 case OPC_BGEZAL: /* 0 >= 0 */
5763 /* Always take and link */
5764 tcg_gen_movi_tl(cpu_gpr[31],
5765 ctx->base.pc_next + insn_bytes);
5766 ctx->hflags |= MIPS_HFLAG_B;
5767 break;
5768 case OPC_BNE: /* rx != rx */
5769 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5770 /* Skip the instruction in the delay slot */
5771 ctx->base.pc_next += 4;
5772 goto out;
5773 case OPC_JR:
5774 ctx->hflags |= MIPS_HFLAG_BR;
5775 break;
5776 case OPC_JALR:
5777 if (rt > 0) {
5778 tcg_gen_movi_tl(cpu_gpr[rt],
5779 ctx->base.pc_next + insn_bytes);
5780 }
5781 ctx->hflags |= MIPS_HFLAG_BR;
5782 break;
5783 default:
5784 MIPS_INVAL("branch/jump");
5785 generate_exception_end(ctx, EXCP_RI);
5786 goto out;
5787 }
5788 } else {
5789 switch (opc) {
5790 case OPC_BEQ:
5791 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5792 goto not_likely;
5793 case OPC_BNE:
5794 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5795 goto not_likely;
5796 case OPC_BGEZAL:
5797 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5798 tcg_gen_movi_tl(cpu_gpr[31],
5799 ctx->base.pc_next + insn_bytes);
5800 goto not_likely;
5801 case OPC_BPOSGE32:
5802 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5803 not_likely:
5804 ctx->hflags |= MIPS_HFLAG_BC;
5805 break;
5806 default:
5807 MIPS_INVAL("conditional branch/jump");
5808 generate_exception_end(ctx, EXCP_RI);
5809 goto out;
5810 }
5811 }
5812
5813 ctx->btarget = btgt;
5814
5815 out:
5816 if (insn_bytes == 2) {
5817 ctx->hflags |= MIPS_HFLAG_B16;
5818 }
5819 tcg_temp_free(t0);
5820 tcg_temp_free(t1);
5821}
5822
5823
7a387fff
TS
5824/* special3 bitfield operations */
5825static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 5826 int rs, int lsb, int msb)
7a387fff 5827{
a7812ae4
PB
5828 TCGv t0 = tcg_temp_new();
5829 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
5830
5831 gen_load_gpr(t1, rs);
7a387fff
TS
5832 switch (opc) {
5833 case OPC_EXT:
b7f26e52 5834 if (lsb + msb > 31) {
7a387fff 5835 goto fail;
b7f26e52 5836 }
505ad7c2 5837 if (msb != 31) {
6eebb7a4 5838 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 5839 } else {
6eebb7a4
RH
5840 /* The two checks together imply that lsb == 0,
5841 so this is a simple sign-extension. */
5842 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 5843 }
7a387fff 5844 break;
c6d6dd7c 5845#if defined(TARGET_MIPS64)
7a387fff 5846 case OPC_DEXTU:
b7f26e52
RH
5847 lsb += 32;
5848 goto do_dext;
5849 case OPC_DEXTM:
5850 msb += 32;
5851 goto do_dext;
7a387fff 5852 case OPC_DEXT:
b7f26e52
RH
5853 do_dext:
5854 if (lsb + msb > 63) {
5855 goto fail;
5856 }
6eebb7a4 5857 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 5858 break;
c6d6dd7c 5859#endif
7a387fff 5860 case OPC_INS:
b7f26e52 5861 if (lsb > msb) {
7a387fff 5862 goto fail;
b7f26e52 5863 }
6c5c1e20 5864 gen_load_gpr(t0, rt);
e0d002f1 5865 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 5866 tcg_gen_ext32s_tl(t0, t0);
7a387fff 5867 break;
c6d6dd7c 5868#if defined(TARGET_MIPS64)
7a387fff 5869 case OPC_DINSU:
b7f26e52
RH
5870 lsb += 32;
5871 /* FALLTHRU */
5872 case OPC_DINSM:
5873 msb += 32;
5874 /* FALLTHRU */
7a387fff 5875 case OPC_DINS:
b7f26e52
RH
5876 if (lsb > msb) {
5877 goto fail;
5878 }
6c5c1e20 5879 gen_load_gpr(t0, rt);
e0d002f1 5880 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 5881 break;
c6d6dd7c 5882#endif
7a387fff
TS
5883 default:
5884fail:
5885 MIPS_INVAL("bitops");
9c708c7f 5886 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
5887 tcg_temp_free(t0);
5888 tcg_temp_free(t1);
7a387fff
TS
5889 return;
5890 }
6c5c1e20
TS
5891 gen_store_gpr(t0, rt);
5892 tcg_temp_free(t0);
5893 tcg_temp_free(t1);
7a387fff
TS
5894}
5895
49bcf33c
AJ
5896static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5897{
3a55fa47 5898 TCGv t0;
49bcf33c 5899
3a55fa47
AJ
5900 if (rd == 0) {
5901 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
5902 return;
5903 }
5904
5905 t0 = tcg_temp_new();
5906 gen_load_gpr(t0, rt);
49bcf33c
AJ
5907 switch (op2) {
5908 case OPC_WSBH:
3a55fa47
AJ
5909 {
5910 TCGv t1 = tcg_temp_new();
06a57e5c 5911 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
5912
5913 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5914 tcg_gen_and_tl(t1, t1, t2);
5915 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5916 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5917 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 5918 tcg_temp_free(t2);
3a55fa47
AJ
5919 tcg_temp_free(t1);
5920 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5921 }
49bcf33c
AJ
5922 break;
5923 case OPC_SEB:
3a55fa47 5924 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5925 break;
5926 case OPC_SEH:
3a55fa47 5927 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5928 break;
5929#if defined(TARGET_MIPS64)
5930 case OPC_DSBH:
3a55fa47
AJ
5931 {
5932 TCGv t1 = tcg_temp_new();
06a57e5c 5933 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
5934
5935 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5936 tcg_gen_and_tl(t1, t1, t2);
5937 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5938 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5939 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5940 tcg_temp_free(t2);
3a55fa47
AJ
5941 tcg_temp_free(t1);
5942 }
49bcf33c
AJ
5943 break;
5944 case OPC_DSHD:
3a55fa47
AJ
5945 {
5946 TCGv t1 = tcg_temp_new();
06a57e5c 5947 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
5948
5949 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
5950 tcg_gen_and_tl(t1, t1, t2);
5951 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5952 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
5953 tcg_gen_or_tl(t0, t0, t1);
5954 tcg_gen_shri_tl(t1, t0, 32);
5955 tcg_gen_shli_tl(t0, t0, 32);
5956 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5957 tcg_temp_free(t2);
3a55fa47
AJ
5958 tcg_temp_free(t1);
5959 }
49bcf33c
AJ
5960 break;
5961#endif
5962 default:
5963 MIPS_INVAL("bsfhl");
9c708c7f 5964 generate_exception_end(ctx, EXCP_RI);
49bcf33c 5965 tcg_temp_free(t0);
49bcf33c
AJ
5966 return;
5967 }
49bcf33c 5968 tcg_temp_free(t0);
49bcf33c
AJ
5969}
5970
1f1b4c00
YK
5971static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5972 int imm2)
5973{
5974 TCGv t0;
5975 TCGv t1;
5976 if (rd == 0) {
5977 /* Treat as NOP. */
5978 return;
5979 }
5980 t0 = tcg_temp_new();
5981 t1 = tcg_temp_new();
5982 gen_load_gpr(t0, rs);
5983 gen_load_gpr(t1, rt);
5984 tcg_gen_shli_tl(t0, t0, imm2 + 1);
5985 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5986 if (opc == OPC_LSA) {
5987 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5988 }
5989
5990 tcg_temp_free(t1);
5991 tcg_temp_free(t0);
5992
5993 return;
5994}
5995
821f2008
JH
5996static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5997 int rt, int bits)
284b731a 5998{
1f1b4c00
YK
5999 TCGv t0;
6000 if (rd == 0) {
6001 /* Treat as NOP. */
6002 return;
6003 }
6004 t0 = tcg_temp_new();
821f2008
JH
6005 if (bits == 0 || bits == wordsz) {
6006 if (bits == 0) {
6007 gen_load_gpr(t0, rt);
6008 } else {
6009 gen_load_gpr(t0, rs);
6010 }
6011 switch (wordsz) {
6012 case 32:
51243852
MD
6013 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6014 break;
6015#if defined(TARGET_MIPS64)
821f2008 6016 case 64:
51243852
MD
6017 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6018 break;
6019#endif
6020 }
1f1b4c00
YK
6021 } else {
6022 TCGv t1 = tcg_temp_new();
821f2008 6023 gen_load_gpr(t0, rt);
1f1b4c00 6024 gen_load_gpr(t1, rs);
821f2008
JH
6025 switch (wordsz) {
6026 case 32:
1f1b4c00
YK
6027 {
6028 TCGv_i64 t2 = tcg_temp_new_i64();
6029 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 6030 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
6031 gen_move_low32(cpu_gpr[rd], t2);
6032 tcg_temp_free_i64(t2);
6033 }
6034 break;
284b731a 6035#if defined(TARGET_MIPS64)
821f2008
JH
6036 case 64:
6037 tcg_gen_shli_tl(t0, t0, bits);
6038 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
6039 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6040 break;
284b731a 6041#endif
1f1b4c00
YK
6042 }
6043 tcg_temp_free(t1);
6044 }
6045
6046 tcg_temp_free(t0);
6047}
6048
821f2008
JH
6049static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6050 int bp)
6051{
6052 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6053}
6054
6055static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6056 int shift)
6057{
6058 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6059}
6060
1f1b4c00
YK
6061static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6062{
6063 TCGv t0;
6064 if (rd == 0) {
6065 /* Treat as NOP. */
6066 return;
6067 }
6068 t0 = tcg_temp_new();
6069 gen_load_gpr(t0, rt);
6070 switch (opc) {
6071 case OPC_BITSWAP:
6072 gen_helper_bitswap(cpu_gpr[rd], t0);
6073 break;
6074#if defined(TARGET_MIPS64)
6075 case OPC_DBITSWAP:
6076 gen_helper_dbitswap(cpu_gpr[rd], t0);
6077 break;
6078#endif
6079 }
6080 tcg_temp_free(t0);
284b731a
LA
6081}
6082
1f1b4c00
YK
6083#ifndef CONFIG_USER_ONLY
6084/* CP0 (MMU and control) */
5204ea79
LA
6085static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6086{
6087 TCGv_i64 t0 = tcg_temp_new_i64();
6088 TCGv_i64 t1 = tcg_temp_new_i64();
6089
6090 tcg_gen_ext_tl_i64(t0, arg);
6091 tcg_gen_ld_i64(t1, cpu_env, off);
6092#if defined(TARGET_MIPS64)
6093 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6094#else
6095 tcg_gen_concat32_i64(t1, t1, t0);
6096#endif
6097 tcg_gen_st_i64(t1, cpu_env, off);
6098 tcg_temp_free_i64(t1);
6099 tcg_temp_free_i64(t0);
6100}
6101
6102static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6103{
6104 TCGv_i64 t0 = tcg_temp_new_i64();
6105 TCGv_i64 t1 = tcg_temp_new_i64();
6106
6107 tcg_gen_ext_tl_i64(t0, arg);
6108 tcg_gen_ld_i64(t1, cpu_env, off);
6109 tcg_gen_concat32_i64(t1, t1, t0);
6110 tcg_gen_st_i64(t1, cpu_env, off);
6111 tcg_temp_free_i64(t1);
6112 tcg_temp_free_i64(t0);
6113}
6114
6115static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6116{
6117 TCGv_i64 t0 = tcg_temp_new_i64();
6118
6119 tcg_gen_ld_i64(t0, cpu_env, off);
6120#if defined(TARGET_MIPS64)
6121 tcg_gen_shri_i64(t0, t0, 30);
6122#else
6123 tcg_gen_shri_i64(t0, t0, 32);
6124#endif
6125 gen_move_low32(arg, t0);
6126 tcg_temp_free_i64(t0);
6127}
6128
6129static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6130{
6131 TCGv_i64 t0 = tcg_temp_new_i64();
6132
6133 tcg_gen_ld_i64(t0, cpu_env, off);
6134 tcg_gen_shri_i64(t0, t0, 32 + shift);
6135 gen_move_low32(arg, t0);
6136 tcg_temp_free_i64(t0);
6137}
6138
d9bea114 6139static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 6140{
d9bea114 6141 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 6142
d9bea114
AJ
6143 tcg_gen_ld_i32(t0, cpu_env, off);
6144 tcg_gen_ext_i32_tl(arg, t0);
6145 tcg_temp_free_i32(t0);
4f57689a
TS
6146}
6147
d9bea114 6148static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 6149{
d9bea114
AJ
6150 tcg_gen_ld_tl(arg, cpu_env, off);
6151 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
6152}
6153
d9bea114 6154static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 6155{
d9bea114 6156 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 6157
d9bea114
AJ
6158 tcg_gen_trunc_tl_i32(t0, arg);
6159 tcg_gen_st_i32(t0, cpu_env, off);
6160 tcg_temp_free_i32(t0);
f1aa6320
TS
6161}
6162
c98d3d79
YK
6163#define CP0_CHECK(c) \
6164 do { \
6165 if (!(c)) { \
6166 goto cp0_unimplemented; \
6167 } \
6168 } while (0)
6169
5204ea79
LA
6170static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6171{
6172 const char *rn = "invalid";
6173
5204ea79
LA
6174 switch (reg) {
6175 case 2:
6176 switch (sel) {
6177 case 0:
59488dda 6178 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6179 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6180 rn = "EntryLo0";
6181 break;
6182 default:
c98d3d79 6183 goto cp0_unimplemented;
5204ea79
LA
6184 }
6185 break;
6186 case 3:
6187 switch (sel) {
6188 case 0:
59488dda 6189 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6190 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6191 rn = "EntryLo1";
6192 break;
6193 default:
c98d3d79 6194 goto cp0_unimplemented;
5204ea79
LA
6195 }
6196 break;
6197 case 17:
6198 switch (sel) {
6199 case 0:
6200 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6201 ctx->CP0_LLAddr_shift);
6202 rn = "LLAddr";
6203 break;
f6d4dd81
YK
6204 case 1:
6205 CP0_CHECK(ctx->mrp);
6206 gen_helper_mfhc0_maar(arg, cpu_env);
6207 rn = "MAAR";
6208 break;
5204ea79 6209 default:
c98d3d79 6210 goto cp0_unimplemented;
5204ea79
LA
6211 }
6212 break;
6213 case 28:
6214 switch (sel) {
6215 case 0:
6216 case 2:
6217 case 4:
6218 case 6:
6219 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6220 rn = "TagLo";
6221 break;
6222 default:
c98d3d79 6223 goto cp0_unimplemented;
5204ea79
LA
6224 }
6225 break;
6226 default:
c98d3d79 6227 goto cp0_unimplemented;
5204ea79 6228 }
b44a7fb1 6229 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
6230 return;
6231
c98d3d79 6232cp0_unimplemented:
965447ee 6233 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6234 tcg_gen_movi_tl(arg, 0);
6235}
6236
6237static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6238{
6239 const char *rn = "invalid";
6240 uint64_t mask = ctx->PAMask >> 36;
6241
5204ea79
LA
6242 switch (reg) {
6243 case 2:
6244 switch (sel) {
6245 case 0:
59488dda 6246 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6247 tcg_gen_andi_tl(arg, arg, mask);
6248 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6249 rn = "EntryLo0";
6250 break;
6251 default:
c98d3d79 6252 goto cp0_unimplemented;
5204ea79
LA
6253 }
6254 break;
6255 case 3:
6256 switch (sel) {
6257 case 0:
59488dda 6258 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6259 tcg_gen_andi_tl(arg, arg, mask);
6260 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6261 rn = "EntryLo1";
6262 break;
6263 default:
c98d3d79 6264 goto cp0_unimplemented;
5204ea79
LA
6265 }
6266 break;
6267 case 17:
6268 switch (sel) {
6269 case 0:
6270 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6271 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6272 relevant for modern MIPS cores supporting MTHC0, therefore
6273 treating MTHC0 to LLAddr as NOP. */
6274 rn = "LLAddr";
6275 break;
f6d4dd81
YK
6276 case 1:
6277 CP0_CHECK(ctx->mrp);
6278 gen_helper_mthc0_maar(cpu_env, arg);
6279 rn = "MAAR";
6280 break;
5204ea79 6281 default:
c98d3d79 6282 goto cp0_unimplemented;
5204ea79
LA
6283 }
6284 break;
6285 case 28:
6286 switch (sel) {
6287 case 0:
6288 case 2:
6289 case 4:
6290 case 6:
6291 tcg_gen_andi_tl(arg, arg, mask);
6292 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6293 rn = "TagLo";
6294 break;
6295 default:
c98d3d79 6296 goto cp0_unimplemented;
5204ea79
LA
6297 }
6298 break;
6299 default:
c98d3d79 6300 goto cp0_unimplemented;
5204ea79 6301 }
b44a7fb1 6302 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 6303
c98d3d79 6304cp0_unimplemented:
965447ee 6305 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6306}
6307
e98c0d17
LA
6308static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6309{
6310 if (ctx->insn_flags & ISA_MIPS32R6) {
6311 tcg_gen_movi_tl(arg, 0);
6312 } else {
6313 tcg_gen_movi_tl(arg, ~0);
6314 }
6315}
6316
d75c135e 6317static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 6318{
7a387fff 6319 const char *rn = "invalid";
873eb012 6320
e189e748 6321 if (sel != 0)
d75c135e 6322 check_insn(ctx, ISA_MIPS32);
e189e748 6323
873eb012
TS
6324 switch (reg) {
6325 case 0:
7a387fff
TS
6326 switch (sel) {
6327 case 0:
7db13fae 6328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
6329 rn = "Index";
6330 break;
6331 case 1:
f31b035a 6332 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6333 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 6334 rn = "MVPControl";
ead9360e 6335 break;
7a387fff 6336 case 2:
f31b035a 6337 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6338 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 6339 rn = "MVPConf0";
ead9360e 6340 break;
7a387fff 6341 case 3:
f31b035a 6342 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6343 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 6344 rn = "MVPConf1";
ead9360e 6345 break;
01bc435b
YK
6346 case 4:
6347 CP0_CHECK(ctx->vp);
6348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6349 rn = "VPControl";
6350 break;
7a387fff 6351 default:
f31b035a 6352 goto cp0_unimplemented;
7a387fff 6353 }
873eb012
TS
6354 break;
6355 case 1:
7a387fff
TS
6356 switch (sel) {
6357 case 0:
f31b035a 6358 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6359 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 6360 rn = "Random";
2423f660 6361 break;
7a387fff 6362 case 1:
f31b035a 6363 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 6365 rn = "VPEControl";
ead9360e 6366 break;
7a387fff 6367 case 2:
f31b035a 6368 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 6370 rn = "VPEConf0";
ead9360e 6371 break;
7a387fff 6372 case 3:
f31b035a 6373 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 6375 rn = "VPEConf1";
ead9360e 6376 break;
7a387fff 6377 case 4:
f31b035a 6378 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6379 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 6380 rn = "YQMask";
ead9360e 6381 break;
7a387fff 6382 case 5:
f31b035a 6383 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6384 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 6385 rn = "VPESchedule";
ead9360e 6386 break;
7a387fff 6387 case 6:
f31b035a 6388 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6389 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 6390 rn = "VPEScheFBack";
ead9360e 6391 break;
7a387fff 6392 case 7:
f31b035a 6393 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 6395 rn = "VPEOpt";
ead9360e 6396 break;
7a387fff 6397 default:
f31b035a 6398 goto cp0_unimplemented;
7a387fff 6399 }
873eb012
TS
6400 break;
6401 case 2:
7a387fff
TS
6402 switch (sel) {
6403 case 0:
284b731a
LA
6404 {
6405 TCGv_i64 tmp = tcg_temp_new_i64();
6406 tcg_gen_ld_i64(tmp, cpu_env,
6407 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 6408#if defined(TARGET_MIPS64)
284b731a
LA
6409 if (ctx->rxi) {
6410 /* Move RI/XI fields to bits 31:30 */
6411 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6412 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6413 }
7207c7f9 6414#endif
284b731a
LA
6415 gen_move_low32(arg, tmp);
6416 tcg_temp_free_i64(tmp);
6417 }
2423f660
TS
6418 rn = "EntryLo0";
6419 break;
7a387fff 6420 case 1:
f31b035a 6421 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6422 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6423 rn = "TCStatus";
ead9360e 6424 break;
7a387fff 6425 case 2:
f31b035a 6426 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6427 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6428 rn = "TCBind";
ead9360e 6429 break;
7a387fff 6430 case 3:
f31b035a 6431 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6432 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 6433 rn = "TCRestart";
ead9360e 6434 break;
7a387fff 6435 case 4:
f31b035a 6436 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6437 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 6438 rn = "TCHalt";
ead9360e 6439 break;
7a387fff 6440 case 5:
f31b035a 6441 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6442 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 6443 rn = "TCContext";
ead9360e 6444 break;
7a387fff 6445 case 6:
f31b035a 6446 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6447 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 6448 rn = "TCSchedule";
ead9360e 6449 break;
7a387fff 6450 case 7:
f31b035a 6451 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6452 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 6453 rn = "TCScheFBack";
ead9360e 6454 break;
7a387fff 6455 default:
f31b035a 6456 goto cp0_unimplemented;
7a387fff 6457 }
873eb012
TS
6458 break;
6459 case 3:
7a387fff
TS
6460 switch (sel) {
6461 case 0:
284b731a
LA
6462 {
6463 TCGv_i64 tmp = tcg_temp_new_i64();
6464 tcg_gen_ld_i64(tmp, cpu_env,
6465 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 6466#if defined(TARGET_MIPS64)
284b731a
LA
6467 if (ctx->rxi) {
6468 /* Move RI/XI fields to bits 31:30 */
6469 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6470 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6471 }
7207c7f9 6472#endif
284b731a
LA
6473 gen_move_low32(arg, tmp);
6474 tcg_temp_free_i64(tmp);
6475 }
2423f660
TS
6476 rn = "EntryLo1";
6477 break;
01bc435b
YK
6478 case 1:
6479 CP0_CHECK(ctx->vp);
6480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6481 rn = "GlobalNumber";
6482 break;
7a387fff 6483 default:
f31b035a 6484 goto cp0_unimplemented;
1579a72e 6485 }
873eb012
TS
6486 break;
6487 case 4:
7a387fff
TS
6488 switch (sel) {
6489 case 0:
7db13fae 6490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 6491 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6492 rn = "Context";
6493 break;
7a387fff 6494 case 1:
d9bea114 6495// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6496 rn = "ContextConfig";
f31b035a 6497 goto cp0_unimplemented;
d279279e 6498 case 2:
f31b035a 6499 CP0_CHECK(ctx->ulri);
e40df9a8
JH
6500 tcg_gen_ld_tl(arg, cpu_env,
6501 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6502 tcg_gen_ext32s_tl(arg, arg);
f31b035a 6503 rn = "UserLocal";
d279279e 6504 break;
7a387fff 6505 default:
f31b035a 6506 goto cp0_unimplemented;
1579a72e 6507 }
873eb012
TS
6508 break;
6509 case 5:
7a387fff
TS
6510 switch (sel) {
6511 case 0:
7db13fae 6512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6513 rn = "PageMask";
6514 break;
7a387fff 6515 case 1:
d75c135e 6516 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6518 rn = "PageGrain";
6519 break;
cec56a73
JH
6520 case 2:
6521 CP0_CHECK(ctx->sc);
6522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6523 tcg_gen_ext32s_tl(arg, arg);
6524 rn = "SegCtl0";
6525 break;
6526 case 3:
6527 CP0_CHECK(ctx->sc);
6528 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6529 tcg_gen_ext32s_tl(arg, arg);
6530 rn = "SegCtl1";
6531 break;
6532 case 4:
6533 CP0_CHECK(ctx->sc);
6534 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6535 tcg_gen_ext32s_tl(arg, arg);
6536 rn = "SegCtl2";
6537 break;
5e31fdd5
YK
6538 case 5:
6539 check_pw(ctx);
6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6541 rn = "PWBase";
6542 break;
fa75ad14
YK
6543 case 6:
6544 check_pw(ctx);
6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6546 rn = "PWField";
6547 break;
20b28ebc
YK
6548 case 7:
6549 check_pw(ctx);
6550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6551 rn = "PWSize";
6552 break;
7a387fff 6553 default:
f31b035a 6554 goto cp0_unimplemented;
1579a72e 6555 }
873eb012
TS
6556 break;
6557 case 6:
7a387fff
TS
6558 switch (sel) {
6559 case 0:
7db13fae 6560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6561 rn = "Wired";
6562 break;
7a387fff 6563 case 1:
d75c135e 6564 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6566 rn = "SRSConf0";
ead9360e 6567 break;
7a387fff 6568 case 2:
d75c135e 6569 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6571 rn = "SRSConf1";
ead9360e 6572 break;
7a387fff 6573 case 3:
d75c135e 6574 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6576 rn = "SRSConf2";
ead9360e 6577 break;
7a387fff 6578 case 4:
d75c135e 6579 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6581 rn = "SRSConf3";
ead9360e 6582 break;
7a387fff 6583 case 5:
d75c135e 6584 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6586 rn = "SRSConf4";
ead9360e 6587 break;
103be64c
YK
6588 case 6:
6589 check_pw(ctx);
6590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6591 rn = "PWCtl";
6592 break;
7a387fff 6593 default:
f31b035a 6594 goto cp0_unimplemented;
1579a72e 6595 }
873eb012 6596 break;
8c0fdd85 6597 case 7:
7a387fff
TS
6598 switch (sel) {
6599 case 0:
d75c135e 6600 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6602 rn = "HWREna";
6603 break;
7a387fff 6604 default:
f31b035a 6605 goto cp0_unimplemented;
1579a72e 6606 }
8c0fdd85 6607 break;
873eb012 6608 case 8:
7a387fff
TS
6609 switch (sel) {
6610 case 0:
7db13fae 6611 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 6612 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 6613 rn = "BadVAddr";
2423f660 6614 break;
aea14095 6615 case 1:
f31b035a
LA
6616 CP0_CHECK(ctx->bi);
6617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6618 rn = "BadInstr";
aea14095
LA
6619 break;
6620 case 2:
f31b035a
LA
6621 CP0_CHECK(ctx->bp);
6622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6623 rn = "BadInstrP";
aea14095 6624 break;
25beba9b
SM
6625 case 3:
6626 CP0_CHECK(ctx->bi);
6627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6628 tcg_gen_andi_tl(arg, arg, ~0xffff);
6629 rn = "BadInstrX";
6630 break;
6631 default:
f31b035a 6632 goto cp0_unimplemented;
aea14095 6633 }
873eb012
TS
6634 break;
6635 case 9:
7a387fff
TS
6636 switch (sel) {
6637 case 0:
2e70f6ef 6638 /* Mark as an IO operation because we read the time. */
eeb3bba8 6639 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6640 gen_io_start();
bd79255d 6641 }
895c2d04 6642 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6643 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6644 gen_io_end();
2e70f6ef 6645 }
55807224 6646 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6647 after reading count. DISAS_STOP isn't sufficient, we need to
6648 ensure we break completely out of translated code. */
eeb3bba8
EC
6649 gen_save_pc(ctx->base.pc_next + 4);
6650 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6651 rn = "Count";
6652 break;
6653 /* 6,7 are implementation dependent */
7a387fff 6654 default:
f31b035a 6655 goto cp0_unimplemented;
2423f660 6656 }
873eb012
TS
6657 break;
6658 case 10:
7a387fff
TS
6659 switch (sel) {
6660 case 0:
7db13fae 6661 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 6662 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6663 rn = "EntryHi";
6664 break;
7a387fff 6665 default:
f31b035a 6666 goto cp0_unimplemented;
1579a72e 6667 }
873eb012
TS
6668 break;
6669 case 11:
7a387fff
TS
6670 switch (sel) {
6671 case 0:
7db13fae 6672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6673 rn = "Compare";
6674 break;
6675 /* 6,7 are implementation dependent */
7a387fff 6676 default:
f31b035a 6677 goto cp0_unimplemented;
2423f660 6678 }
873eb012
TS
6679 break;
6680 case 12:
7a387fff
TS
6681 switch (sel) {
6682 case 0:
7db13fae 6683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6684 rn = "Status";
6685 break;
7a387fff 6686 case 1:
d75c135e 6687 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6689 rn = "IntCtl";
6690 break;
7a387fff 6691 case 2:
d75c135e 6692 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6694 rn = "SRSCtl";
6695 break;
7a387fff 6696 case 3:
d75c135e 6697 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 6699 rn = "SRSMap";
fd88b6ab 6700 break;
7a387fff 6701 default:
f31b035a 6702 goto cp0_unimplemented;
7a387fff 6703 }
873eb012
TS
6704 break;
6705 case 13:
7a387fff
TS
6706 switch (sel) {
6707 case 0:
7db13fae 6708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6709 rn = "Cause";
6710 break;
7a387fff 6711 default:
f31b035a 6712 goto cp0_unimplemented;
7a387fff 6713 }
873eb012
TS
6714 break;
6715 case 14:
7a387fff
TS
6716 switch (sel) {
6717 case 0:
7db13fae 6718 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 6719 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6720 rn = "EPC";
6721 break;
7a387fff 6722 default:
f31b035a 6723 goto cp0_unimplemented;
1579a72e 6724 }
873eb012
TS
6725 break;
6726 case 15:
7a387fff
TS
6727 switch (sel) {
6728 case 0:
7db13fae 6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6730 rn = "PRid";
6731 break;
7a387fff 6732 case 1:
d75c135e 6733 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
6734 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6735 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6736 rn = "EBase";
6737 break;
c870e3f5
YK
6738 case 3:
6739 check_insn(ctx, ISA_MIPS32R2);
6740 CP0_CHECK(ctx->cmgcr);
6741 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6742 tcg_gen_ext32s_tl(arg, arg);
6743 rn = "CMGCRBase";
6744 break;
7a387fff 6745 default:
f31b035a 6746 goto cp0_unimplemented;
7a387fff 6747 }
873eb012
TS
6748 break;
6749 case 16:
6750 switch (sel) {
6751 case 0:
7db13fae 6752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
6753 rn = "Config";
6754 break;
6755 case 1:
7db13fae 6756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
6757 rn = "Config1";
6758 break;
7a387fff 6759 case 2:
7db13fae 6760 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
6761 rn = "Config2";
6762 break;
6763 case 3:
7db13fae 6764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
6765 rn = "Config3";
6766 break;
b4160af1
PJ
6767 case 4:
6768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6769 rn = "Config4";
6770 break;
b4dd99a3
PJ
6771 case 5:
6772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6773 rn = "Config5";
6774 break;
e397ee33
TS
6775 /* 6,7 are implementation dependent */
6776 case 6:
7db13fae 6777 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
6778 rn = "Config6";
6779 break;
6780 case 7:
7db13fae 6781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
6782 rn = "Config7";
6783 break;
873eb012 6784 default:
f31b035a 6785 goto cp0_unimplemented;
873eb012
TS
6786 }
6787 break;
6788 case 17:
7a387fff
TS
6789 switch (sel) {
6790 case 0:
895c2d04 6791 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
6792 rn = "LLAddr";
6793 break;
f6d4dd81
YK
6794 case 1:
6795 CP0_CHECK(ctx->mrp);
6796 gen_helper_mfc0_maar(arg, cpu_env);
6797 rn = "MAAR";
6798 break;
6799 case 2:
6800 CP0_CHECK(ctx->mrp);
6801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6802 rn = "MAARI";
6803 break;
7a387fff 6804 default:
f31b035a 6805 goto cp0_unimplemented;
7a387fff 6806 }
873eb012
TS
6807 break;
6808 case 18:
7a387fff 6809 switch (sel) {
c2e19f3c
AM
6810 case 0:
6811 case 1:
6812 case 2:
6813 case 3:
6814 case 4:
6815 case 5:
6816 case 6:
6817 case 7:
fa192d49 6818 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6819 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
6820 rn = "WatchLo";
6821 break;
7a387fff 6822 default:
f31b035a 6823 goto cp0_unimplemented;
7a387fff 6824 }
873eb012
TS
6825 break;
6826 case 19:
7a387fff 6827 switch (sel) {
c2e19f3c
AM
6828 case 0:
6829 case 1:
6830 case 2:
6831 case 3:
6832 case 4:
6833 case 5:
6834 case 6:
6835 case 7:
fa192d49 6836 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6837 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6838 rn = "WatchHi";
6839 break;
7a387fff 6840 default:
f31b035a 6841 goto cp0_unimplemented;
7a387fff 6842 }
873eb012 6843 break;
8c0fdd85 6844 case 20:
7a387fff
TS
6845 switch (sel) {
6846 case 0:
d26bc211 6847#if defined(TARGET_MIPS64)
d75c135e 6848 check_insn(ctx, ISA_MIPS3);
7db13fae 6849 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 6850 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6851 rn = "XContext";
6852 break;
703eaf37 6853#endif
7a387fff 6854 default:
f31b035a 6855 goto cp0_unimplemented;
7a387fff 6856 }
8c0fdd85
TS
6857 break;
6858 case 21:
7a387fff 6859 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6860 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6861 switch (sel) {
6862 case 0:
7db13fae 6863 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6864 rn = "Framemask";
6865 break;
7a387fff 6866 default:
f31b035a 6867 goto cp0_unimplemented;
7a387fff 6868 }
8c0fdd85
TS
6869 break;
6870 case 22:
d9bea114 6871 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6872 rn = "'Diagnostic"; /* implementation dependent */
6873 break;
873eb012 6874 case 23:
7a387fff
TS
6875 switch (sel) {
6876 case 0:
895c2d04 6877 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6878 rn = "Debug";
6879 break;
7a387fff 6880 case 1:
d9bea114 6881// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 6882 rn = "TraceControl";
3570d7f6 6883 goto cp0_unimplemented;
7a387fff 6884 case 2:
d9bea114 6885// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 6886 rn = "TraceControl2";
3570d7f6 6887 goto cp0_unimplemented;
7a387fff 6888 case 3:
d9bea114 6889// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 6890 rn = "UserTraceData";
3570d7f6 6891 goto cp0_unimplemented;
7a387fff 6892 case 4:
d9bea114 6893// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 6894 rn = "TraceBPC";
3570d7f6 6895 goto cp0_unimplemented;
7a387fff 6896 default:
f31b035a 6897 goto cp0_unimplemented;
7a387fff 6898 }
873eb012
TS
6899 break;
6900 case 24:
7a387fff
TS
6901 switch (sel) {
6902 case 0:
f0b3f3ae 6903 /* EJTAG support */
7db13fae 6904 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 6905 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6906 rn = "DEPC";
6907 break;
7a387fff 6908 default:
f31b035a 6909 goto cp0_unimplemented;
7a387fff 6910 }
873eb012 6911 break;
8c0fdd85 6912 case 25:
7a387fff
TS
6913 switch (sel) {
6914 case 0:
7db13fae 6915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6916 rn = "Performance0";
7a387fff
TS
6917 break;
6918 case 1:
d9bea114 6919// gen_helper_mfc0_performance1(arg);
2423f660 6920 rn = "Performance1";
3570d7f6 6921 goto cp0_unimplemented;
7a387fff 6922 case 2:
d9bea114 6923// gen_helper_mfc0_performance2(arg);
2423f660 6924 rn = "Performance2";
3570d7f6 6925 goto cp0_unimplemented;
7a387fff 6926 case 3:
d9bea114 6927// gen_helper_mfc0_performance3(arg);
2423f660 6928 rn = "Performance3";
3570d7f6 6929 goto cp0_unimplemented;
7a387fff 6930 case 4:
d9bea114 6931// gen_helper_mfc0_performance4(arg);
2423f660 6932 rn = "Performance4";
3570d7f6 6933 goto cp0_unimplemented;
7a387fff 6934 case 5:
d9bea114 6935// gen_helper_mfc0_performance5(arg);
2423f660 6936 rn = "Performance5";
3570d7f6 6937 goto cp0_unimplemented;
7a387fff 6938 case 6:
d9bea114 6939// gen_helper_mfc0_performance6(arg);
2423f660 6940 rn = "Performance6";
3570d7f6 6941 goto cp0_unimplemented;
7a387fff 6942 case 7:
d9bea114 6943// gen_helper_mfc0_performance7(arg);
2423f660 6944 rn = "Performance7";
3570d7f6 6945 goto cp0_unimplemented;
7a387fff 6946 default:
f31b035a 6947 goto cp0_unimplemented;
7a387fff 6948 }
8c0fdd85
TS
6949 break;
6950 case 26:
0d74a222
LA
6951 switch (sel) {
6952 case 0:
6953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6954 rn = "ErrCtl";
6955 break;
6956 default:
6957 goto cp0_unimplemented;
6958 }
da80682b 6959 break;
8c0fdd85 6960 case 27:
7a387fff 6961 switch (sel) {
c2e19f3c
AM
6962 case 0:
6963 case 1:
6964 case 2:
6965 case 3:
d9bea114 6966 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6967 rn = "CacheErr";
6968 break;
7a387fff 6969 default:
f31b035a 6970 goto cp0_unimplemented;
7a387fff 6971 }
8c0fdd85 6972 break;
873eb012
TS
6973 case 28:
6974 switch (sel) {
6975 case 0:
7a387fff
TS
6976 case 2:
6977 case 4:
6978 case 6:
284b731a
LA
6979 {
6980 TCGv_i64 tmp = tcg_temp_new_i64();
6981 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6982 gen_move_low32(arg, tmp);
6983 tcg_temp_free_i64(tmp);
6984 }
873eb012
TS
6985 rn = "TagLo";
6986 break;
6987 case 1:
7a387fff
TS
6988 case 3:
6989 case 5:
6990 case 7:
7db13fae 6991 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
6992 rn = "DataLo";
6993 break;
6994 default:
f31b035a 6995 goto cp0_unimplemented;
873eb012
TS
6996 }
6997 break;
8c0fdd85 6998 case 29:
7a387fff
TS
6999 switch (sel) {
7000 case 0:
7001 case 2:
7002 case 4:
7003 case 6:
7db13fae 7004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
7005 rn = "TagHi";
7006 break;
7007 case 1:
7008 case 3:
7009 case 5:
7010 case 7:
7db13fae 7011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
7012 rn = "DataHi";
7013 break;
7014 default:
f31b035a 7015 goto cp0_unimplemented;
7a387fff 7016 }
8c0fdd85 7017 break;
873eb012 7018 case 30:
7a387fff
TS
7019 switch (sel) {
7020 case 0:
7db13fae 7021 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 7022 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7023 rn = "ErrorEPC";
7024 break;
7a387fff 7025 default:
f31b035a 7026 goto cp0_unimplemented;
7a387fff 7027 }
873eb012
TS
7028 break;
7029 case 31:
7a387fff
TS
7030 switch (sel) {
7031 case 0:
f0b3f3ae 7032 /* EJTAG support */
7db13fae 7033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7034 rn = "DESAVE";
7035 break;
c2e19f3c
AM
7036 case 2:
7037 case 3:
7038 case 4:
7039 case 5:
7040 case 6:
7041 case 7:
f31b035a
LA
7042 CP0_CHECK(ctx->kscrexist & (1 << sel));
7043 tcg_gen_ld_tl(arg, cpu_env,
7044 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7045 tcg_gen_ext32s_tl(arg, arg);
7046 rn = "KScratch";
e98c0d17 7047 break;
7a387fff 7048 default:
f31b035a 7049 goto cp0_unimplemented;
7a387fff 7050 }
873eb012
TS
7051 break;
7052 default:
f31b035a 7053 goto cp0_unimplemented;
873eb012 7054 }
b44a7fb1 7055 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
7056 return;
7057
f31b035a 7058cp0_unimplemented:
965447ee 7059 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7060 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
7061}
7062
d75c135e 7063static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 7064{
7a387fff
TS
7065 const char *rn = "invalid";
7066
e189e748 7067 if (sel != 0)
d75c135e 7068 check_insn(ctx, ISA_MIPS32);
e189e748 7069
eeb3bba8 7070 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7071 gen_io_start();
bd79255d 7072 }
2e70f6ef 7073
8c0fdd85
TS
7074 switch (reg) {
7075 case 0:
7a387fff
TS
7076 switch (sel) {
7077 case 0:
895c2d04 7078 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
7079 rn = "Index";
7080 break;
7081 case 1:
f31b035a 7082 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7083 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 7084 rn = "MVPControl";
ead9360e 7085 break;
7a387fff 7086 case 2:
f31b035a 7087 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7088 /* ignored */
7a387fff 7089 rn = "MVPConf0";
ead9360e 7090 break;
7a387fff 7091 case 3:
f31b035a 7092 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7093 /* ignored */
7a387fff 7094 rn = "MVPConf1";
ead9360e 7095 break;
01bc435b
YK
7096 case 4:
7097 CP0_CHECK(ctx->vp);
7098 /* ignored */
7099 rn = "VPControl";
7100 break;
7a387fff 7101 default:
f31b035a 7102 goto cp0_unimplemented;
7a387fff 7103 }
8c0fdd85
TS
7104 break;
7105 case 1:
7a387fff
TS
7106 switch (sel) {
7107 case 0:
2423f660 7108 /* ignored */
7a387fff 7109 rn = "Random";
2423f660 7110 break;
7a387fff 7111 case 1:
f31b035a 7112 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7113 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 7114 rn = "VPEControl";
ead9360e 7115 break;
7a387fff 7116 case 2:
f31b035a 7117 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7118 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 7119 rn = "VPEConf0";
ead9360e 7120 break;
7a387fff 7121 case 3:
f31b035a 7122 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7123 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 7124 rn = "VPEConf1";
ead9360e 7125 break;
7a387fff 7126 case 4:
f31b035a 7127 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7128 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 7129 rn = "YQMask";
ead9360e 7130 break;
7a387fff 7131 case 5:
f31b035a 7132 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7133 tcg_gen_st_tl(arg, cpu_env,
7134 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 7135 rn = "VPESchedule";
ead9360e 7136 break;
7a387fff 7137 case 6:
f31b035a 7138 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7139 tcg_gen_st_tl(arg, cpu_env,
7140 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 7141 rn = "VPEScheFBack";
ead9360e 7142 break;
7a387fff 7143 case 7:
f31b035a 7144 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7145 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 7146 rn = "VPEOpt";
ead9360e 7147 break;
7a387fff 7148 default:
f31b035a 7149 goto cp0_unimplemented;
7a387fff 7150 }
8c0fdd85
TS
7151 break;
7152 case 2:
7a387fff
TS
7153 switch (sel) {
7154 case 0:
895c2d04 7155 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
7156 rn = "EntryLo0";
7157 break;
7a387fff 7158 case 1:
f31b035a 7159 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7160 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7161 rn = "TCStatus";
ead9360e 7162 break;
7a387fff 7163 case 2:
f31b035a 7164 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7165 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7166 rn = "TCBind";
ead9360e 7167 break;
7a387fff 7168 case 3:
f31b035a 7169 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7170 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7171 rn = "TCRestart";
ead9360e 7172 break;
7a387fff 7173 case 4:
f31b035a 7174 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7175 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7176 rn = "TCHalt";
ead9360e 7177 break;
7a387fff 7178 case 5:
f31b035a 7179 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7180 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7181 rn = "TCContext";
ead9360e 7182 break;
7a387fff 7183 case 6:
f31b035a 7184 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7185 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7186 rn = "TCSchedule";
ead9360e 7187 break;
7a387fff 7188 case 7:
f31b035a 7189 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7190 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7191 rn = "TCScheFBack";
ead9360e 7192 break;
7a387fff 7193 default:
f31b035a 7194 goto cp0_unimplemented;
7a387fff 7195 }
8c0fdd85
TS
7196 break;
7197 case 3:
7a387fff
TS
7198 switch (sel) {
7199 case 0:
895c2d04 7200 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
7201 rn = "EntryLo1";
7202 break;
01bc435b
YK
7203 case 1:
7204 CP0_CHECK(ctx->vp);
7205 /* ignored */
7206 rn = "GlobalNumber";
7207 break;
7a387fff 7208 default:
f31b035a 7209 goto cp0_unimplemented;
876d4b07 7210 }
8c0fdd85
TS
7211 break;
7212 case 4:
7a387fff
TS
7213 switch (sel) {
7214 case 0:
895c2d04 7215 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7216 rn = "Context";
7217 break;
7a387fff 7218 case 1:
895c2d04 7219// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7220 rn = "ContextConfig";
f31b035a 7221 goto cp0_unimplemented;
d279279e 7222 case 2:
f31b035a
LA
7223 CP0_CHECK(ctx->ulri);
7224 tcg_gen_st_tl(arg, cpu_env,
7225 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7226 rn = "UserLocal";
d279279e 7227 break;
7a387fff 7228 default:
f31b035a 7229 goto cp0_unimplemented;
876d4b07 7230 }
8c0fdd85
TS
7231 break;
7232 case 5:
7a387fff
TS
7233 switch (sel) {
7234 case 0:
895c2d04 7235 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7236 rn = "PageMask";
7237 break;
7a387fff 7238 case 1:
d75c135e 7239 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7240 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 7241 rn = "PageGrain";
eeb3bba8 7242 ctx->base.is_jmp = DISAS_STOP;
2423f660 7243 break;
cec56a73
JH
7244 case 2:
7245 CP0_CHECK(ctx->sc);
7246 gen_helper_mtc0_segctl0(cpu_env, arg);
7247 rn = "SegCtl0";
7248 break;
7249 case 3:
7250 CP0_CHECK(ctx->sc);
7251 gen_helper_mtc0_segctl1(cpu_env, arg);
7252 rn = "SegCtl1";
7253 break;
7254 case 4:
7255 CP0_CHECK(ctx->sc);
7256 gen_helper_mtc0_segctl2(cpu_env, arg);
7257 rn = "SegCtl2";
7258 break;
5e31fdd5
YK
7259 case 5:
7260 check_pw(ctx);
7261 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7262 rn = "PWBase";
7263 break;
fa75ad14
YK
7264 case 6:
7265 check_pw(ctx);
7266 gen_helper_mtc0_pwfield(cpu_env, arg);
7267 rn = "PWField";
7268 break;
20b28ebc
YK
7269 case 7:
7270 check_pw(ctx);
7271 gen_helper_mtc0_pwsize(cpu_env, arg);
7272 rn = "PWSize";
7273 break;
7a387fff 7274 default:
f31b035a 7275 goto cp0_unimplemented;
876d4b07 7276 }
8c0fdd85
TS
7277 break;
7278 case 6:
7a387fff
TS
7279 switch (sel) {
7280 case 0:
895c2d04 7281 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7282 rn = "Wired";
7283 break;
7a387fff 7284 case 1:
d75c135e 7285 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7286 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7287 rn = "SRSConf0";
ead9360e 7288 break;
7a387fff 7289 case 2:
d75c135e 7290 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7291 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7292 rn = "SRSConf1";
ead9360e 7293 break;
7a387fff 7294 case 3:
d75c135e 7295 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7296 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7297 rn = "SRSConf2";
ead9360e 7298 break;
7a387fff 7299 case 4:
d75c135e 7300 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7301 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7302 rn = "SRSConf3";
ead9360e 7303 break;
7a387fff 7304 case 5:
d75c135e 7305 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7306 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7307 rn = "SRSConf4";
ead9360e 7308 break;
103be64c
YK
7309 case 6:
7310 check_pw(ctx);
7311 gen_helper_mtc0_pwctl(cpu_env, arg);
7312 rn = "PWCtl";
7313 break;
7a387fff 7314 default:
f31b035a 7315 goto cp0_unimplemented;
876d4b07 7316 }
8c0fdd85
TS
7317 break;
7318 case 7:
7a387fff
TS
7319 switch (sel) {
7320 case 0:
d75c135e 7321 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7322 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7323 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7324 rn = "HWREna";
7325 break;
7a387fff 7326 default:
f31b035a 7327 goto cp0_unimplemented;
876d4b07 7328 }
8c0fdd85
TS
7329 break;
7330 case 8:
aea14095
LA
7331 switch (sel) {
7332 case 0:
7333 /* ignored */
7334 rn = "BadVAddr";
7335 break;
7336 case 1:
7337 /* ignored */
7338 rn = "BadInstr";
7339 break;
7340 case 2:
7341 /* ignored */
7342 rn = "BadInstrP";
7343 break;
25beba9b
SM
7344 case 3:
7345 /* ignored */
7346 rn = "BadInstrX";
7347 break;
aea14095 7348 default:
f31b035a 7349 goto cp0_unimplemented;
aea14095 7350 }
8c0fdd85
TS
7351 break;
7352 case 9:
7a387fff
TS
7353 switch (sel) {
7354 case 0:
895c2d04 7355 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7356 rn = "Count";
7357 break;
876d4b07 7358 /* 6,7 are implementation dependent */
7a387fff 7359 default:
f31b035a 7360 goto cp0_unimplemented;
876d4b07 7361 }
8c0fdd85
TS
7362 break;
7363 case 10:
7a387fff
TS
7364 switch (sel) {
7365 case 0:
895c2d04 7366 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7367 rn = "EntryHi";
7368 break;
7a387fff 7369 default:
f31b035a 7370 goto cp0_unimplemented;
876d4b07 7371 }
8c0fdd85
TS
7372 break;
7373 case 11:
7a387fff
TS
7374 switch (sel) {
7375 case 0:
895c2d04 7376 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7377 rn = "Compare";
7378 break;
7379 /* 6,7 are implementation dependent */
7a387fff 7380 default:
f31b035a 7381 goto cp0_unimplemented;
876d4b07 7382 }
8c0fdd85
TS
7383 break;
7384 case 12:
7a387fff
TS
7385 switch (sel) {
7386 case 0:
867abc7e 7387 save_cpu_state(ctx, 1);
895c2d04 7388 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7389 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7390 gen_save_pc(ctx->base.pc_next + 4);
7391 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7392 rn = "Status";
7393 break;
7a387fff 7394 case 1:
d75c135e 7395 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7396 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7397 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7398 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7399 rn = "IntCtl";
7400 break;
7a387fff 7401 case 2:
d75c135e 7402 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7403 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7404 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7405 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7406 rn = "SRSCtl";
7407 break;
7a387fff 7408 case 3:
d75c135e 7409 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7410 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7411 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7412 ctx->base.is_jmp = DISAS_STOP;
2423f660 7413 rn = "SRSMap";
fd88b6ab 7414 break;
7a387fff 7415 default:
f31b035a 7416 goto cp0_unimplemented;
876d4b07 7417 }
8c0fdd85
TS
7418 break;
7419 case 13:
7a387fff
TS
7420 switch (sel) {
7421 case 0:
867abc7e 7422 save_cpu_state(ctx, 1);
895c2d04 7423 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7424 /* Stop translation as we may have triggered an interrupt.
7425 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7426 * translated code to check for pending interrupts. */
eeb3bba8
EC
7427 gen_save_pc(ctx->base.pc_next + 4);
7428 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7429 rn = "Cause";
7430 break;
7a387fff 7431 default:
f31b035a 7432 goto cp0_unimplemented;
876d4b07 7433 }
8c0fdd85
TS
7434 break;
7435 case 14:
7a387fff
TS
7436 switch (sel) {
7437 case 0:
d54a299b 7438 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7439 rn = "EPC";
7440 break;
7a387fff 7441 default:
f31b035a 7442 goto cp0_unimplemented;
876d4b07 7443 }
8c0fdd85
TS
7444 break;
7445 case 15:
7a387fff
TS
7446 switch (sel) {
7447 case 0:
2423f660
TS
7448 /* ignored */
7449 rn = "PRid";
7450 break;
7a387fff 7451 case 1:
d75c135e 7452 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7453 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7454 rn = "EBase";
7455 break;
7a387fff 7456 default:
f31b035a 7457 goto cp0_unimplemented;
1579a72e 7458 }
8c0fdd85
TS
7459 break;
7460 case 16:
7461 switch (sel) {
7462 case 0:
895c2d04 7463 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 7464 rn = "Config";
2423f660 7465 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7466 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
7467 break;
7468 case 1:
e397ee33 7469 /* ignored, read only */
7a387fff
TS
7470 rn = "Config1";
7471 break;
7472 case 2:
895c2d04 7473 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 7474 rn = "Config2";
2423f660 7475 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7476 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 7477 break;
7a387fff 7478 case 3:
90f12d73 7479 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 7480 rn = "Config3";
90f12d73 7481 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7482 ctx->base.is_jmp = DISAS_STOP;
7a387fff 7483 break;
b4160af1
PJ
7484 case 4:
7485 gen_helper_mtc0_config4(cpu_env, arg);
7486 rn = "Config4";
eeb3bba8 7487 ctx->base.is_jmp = DISAS_STOP;
b4160af1 7488 break;
b4dd99a3
PJ
7489 case 5:
7490 gen_helper_mtc0_config5(cpu_env, arg);
7491 rn = "Config5";
7492 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7493 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 7494 break;
e397ee33
TS
7495 /* 6,7 are implementation dependent */
7496 case 6:
7497 /* ignored */
7498 rn = "Config6";
7499 break;
7500 case 7:
7501 /* ignored */
7502 rn = "Config7";
7503 break;
8c0fdd85
TS
7504 default:
7505 rn = "Invalid config selector";
f31b035a 7506 goto cp0_unimplemented;
8c0fdd85
TS
7507 }
7508 break;
7509 case 17:
7a387fff
TS
7510 switch (sel) {
7511 case 0:
895c2d04 7512 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7513 rn = "LLAddr";
7514 break;
f6d4dd81
YK
7515 case 1:
7516 CP0_CHECK(ctx->mrp);
7517 gen_helper_mtc0_maar(cpu_env, arg);
7518 rn = "MAAR";
7519 break;
7520 case 2:
7521 CP0_CHECK(ctx->mrp);
7522 gen_helper_mtc0_maari(cpu_env, arg);
7523 rn = "MAARI";
7524 break;
7a387fff 7525 default:
f31b035a 7526 goto cp0_unimplemented;
7a387fff 7527 }
8c0fdd85
TS
7528 break;
7529 case 18:
7a387fff 7530 switch (sel) {
c2e19f3c
AM
7531 case 0:
7532 case 1:
7533 case 2:
7534 case 3:
7535 case 4:
7536 case 5:
7537 case 6:
7538 case 7:
fa192d49 7539 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7540 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7541 rn = "WatchLo";
7542 break;
7a387fff 7543 default:
f31b035a 7544 goto cp0_unimplemented;
7a387fff 7545 }
8c0fdd85
TS
7546 break;
7547 case 19:
7a387fff 7548 switch (sel) {
c2e19f3c
AM
7549 case 0:
7550 case 1:
7551 case 2:
7552 case 3:
7553 case 4:
7554 case 5:
7555 case 6:
7556 case 7:
fa192d49 7557 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7558 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7559 rn = "WatchHi";
7560 break;
7a387fff 7561 default:
f31b035a 7562 goto cp0_unimplemented;
7a387fff 7563 }
8c0fdd85
TS
7564 break;
7565 case 20:
7a387fff
TS
7566 switch (sel) {
7567 case 0:
d26bc211 7568#if defined(TARGET_MIPS64)
d75c135e 7569 check_insn(ctx, ISA_MIPS3);
895c2d04 7570 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7571 rn = "XContext";
7572 break;
703eaf37 7573#endif
7a387fff 7574 default:
f31b035a 7575 goto cp0_unimplemented;
7a387fff 7576 }
8c0fdd85
TS
7577 break;
7578 case 21:
7a387fff 7579 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7580 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7581 switch (sel) {
7582 case 0:
895c2d04 7583 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7584 rn = "Framemask";
7585 break;
7a387fff 7586 default:
f31b035a 7587 goto cp0_unimplemented;
7a387fff
TS
7588 }
7589 break;
8c0fdd85 7590 case 22:
7a387fff
TS
7591 /* ignored */
7592 rn = "Diagnostic"; /* implementation dependent */
2423f660 7593 break;
8c0fdd85 7594 case 23:
7a387fff
TS
7595 switch (sel) {
7596 case 0:
895c2d04 7597 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7598 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7599 gen_save_pc(ctx->base.pc_next + 4);
7600 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7601 rn = "Debug";
7602 break;
7a387fff 7603 case 1:
895c2d04 7604// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 7605 rn = "TraceControl";
8487327a 7606 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7607 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7608 goto cp0_unimplemented;
7a387fff 7609 case 2:
895c2d04 7610// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 7611 rn = "TraceControl2";
8487327a 7612 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7613 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7614 goto cp0_unimplemented;
7a387fff 7615 case 3:
8487327a 7616 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7617 ctx->base.is_jmp = DISAS_STOP;
895c2d04 7618// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 7619 rn = "UserTraceData";
8487327a 7620 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7621 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7622 goto cp0_unimplemented;
7a387fff 7623 case 4:
895c2d04 7624// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7625 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7626 ctx->base.is_jmp = DISAS_STOP;
2423f660 7627 rn = "TraceBPC";
3570d7f6 7628 goto cp0_unimplemented;
7a387fff 7629 default:
f31b035a 7630 goto cp0_unimplemented;
7a387fff 7631 }
8c0fdd85
TS
7632 break;
7633 case 24:
7a387fff
TS
7634 switch (sel) {
7635 case 0:
f1aa6320 7636 /* EJTAG support */
d54a299b 7637 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7638 rn = "DEPC";
7639 break;
7a387fff 7640 default:
f31b035a 7641 goto cp0_unimplemented;
7a387fff 7642 }
8c0fdd85
TS
7643 break;
7644 case 25:
7a387fff
TS
7645 switch (sel) {
7646 case 0:
895c2d04 7647 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7648 rn = "Performance0";
7649 break;
7a387fff 7650 case 1:
d9bea114 7651// gen_helper_mtc0_performance1(arg);
2423f660 7652 rn = "Performance1";
3570d7f6 7653 goto cp0_unimplemented;
7a387fff 7654 case 2:
d9bea114 7655// gen_helper_mtc0_performance2(arg);
2423f660 7656 rn = "Performance2";
3570d7f6 7657 goto cp0_unimplemented;
7a387fff 7658 case 3:
d9bea114 7659// gen_helper_mtc0_performance3(arg);
2423f660 7660 rn = "Performance3";
3570d7f6 7661 goto cp0_unimplemented;
7a387fff 7662 case 4:
d9bea114 7663// gen_helper_mtc0_performance4(arg);
2423f660 7664 rn = "Performance4";
3570d7f6 7665 goto cp0_unimplemented;
7a387fff 7666 case 5:
d9bea114 7667// gen_helper_mtc0_performance5(arg);
2423f660 7668 rn = "Performance5";
3570d7f6 7669 goto cp0_unimplemented;
7a387fff 7670 case 6:
d9bea114 7671// gen_helper_mtc0_performance6(arg);
2423f660 7672 rn = "Performance6";
3570d7f6 7673 goto cp0_unimplemented;
7a387fff 7674 case 7:
d9bea114 7675// gen_helper_mtc0_performance7(arg);
2423f660 7676 rn = "Performance7";
3570d7f6 7677 goto cp0_unimplemented;
7a387fff 7678 default:
f31b035a 7679 goto cp0_unimplemented;
7a387fff 7680 }
8c0fdd85
TS
7681 break;
7682 case 26:
0d74a222
LA
7683 switch (sel) {
7684 case 0:
7685 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7686 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7687 rn = "ErrCtl";
7688 break;
7689 default:
7690 goto cp0_unimplemented;
7691 }
2423f660 7692 break;
8c0fdd85 7693 case 27:
7a387fff 7694 switch (sel) {
c2e19f3c
AM
7695 case 0:
7696 case 1:
7697 case 2:
7698 case 3:
2423f660
TS
7699 /* ignored */
7700 rn = "CacheErr";
7701 break;
7a387fff 7702 default:
f31b035a 7703 goto cp0_unimplemented;
7a387fff 7704 }
8c0fdd85
TS
7705 break;
7706 case 28:
7707 switch (sel) {
7708 case 0:
7a387fff
TS
7709 case 2:
7710 case 4:
7711 case 6:
895c2d04 7712 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
7713 rn = "TagLo";
7714 break;
7a387fff
TS
7715 case 1:
7716 case 3:
7717 case 5:
7718 case 7:
895c2d04 7719 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
7720 rn = "DataLo";
7721 break;
8c0fdd85 7722 default:
f31b035a 7723 goto cp0_unimplemented;
8c0fdd85
TS
7724 }
7725 break;
7726 case 29:
7a387fff
TS
7727 switch (sel) {
7728 case 0:
7729 case 2:
7730 case 4:
7731 case 6:
895c2d04 7732 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
7733 rn = "TagHi";
7734 break;
7735 case 1:
7736 case 3:
7737 case 5:
7738 case 7:
895c2d04 7739 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
7740 rn = "DataHi";
7741 break;
7742 default:
7743 rn = "invalid sel";
f31b035a 7744 goto cp0_unimplemented;
7a387fff 7745 }
8c0fdd85
TS
7746 break;
7747 case 30:
7a387fff
TS
7748 switch (sel) {
7749 case 0:
d54a299b 7750 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7751 rn = "ErrorEPC";
7752 break;
7a387fff 7753 default:
f31b035a 7754 goto cp0_unimplemented;
7a387fff 7755 }
8c0fdd85
TS
7756 break;
7757 case 31:
7a387fff
TS
7758 switch (sel) {
7759 case 0:
f1aa6320 7760 /* EJTAG support */
7db13fae 7761 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7762 rn = "DESAVE";
7763 break;
c2e19f3c
AM
7764 case 2:
7765 case 3:
7766 case 4:
7767 case 5:
7768 case 6:
7769 case 7:
f31b035a
LA
7770 CP0_CHECK(ctx->kscrexist & (1 << sel));
7771 tcg_gen_st_tl(arg, cpu_env,
7772 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7773 rn = "KScratch";
e98c0d17 7774 break;
7a387fff 7775 default:
f31b035a 7776 goto cp0_unimplemented;
7a387fff 7777 }
8c0fdd85
TS
7778 break;
7779 default:
f31b035a 7780 goto cp0_unimplemented;
8c0fdd85 7781 }
b44a7fb1
PMD
7782 trace_mips_translate_c0("mtc0", rn, reg, sel);
7783
bf20dc07 7784 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7785 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7786 gen_io_end();
b28425ba 7787 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7788 * translated code to check for pending interrupts. */
eeb3bba8
EC
7789 gen_save_pc(ctx->base.pc_next + 4);
7790 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7791 }
8c0fdd85
TS
7792 return;
7793
f31b035a 7794cp0_unimplemented:
965447ee 7795 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
7796}
7797
d26bc211 7798#if defined(TARGET_MIPS64)
d75c135e 7799static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7800{
7801 const char *rn = "invalid";
7802
e189e748 7803 if (sel != 0)
d75c135e 7804 check_insn(ctx, ISA_MIPS64);
e189e748 7805
9c2149c8
TS
7806 switch (reg) {
7807 case 0:
7808 switch (sel) {
7809 case 0:
7db13fae 7810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
7811 rn = "Index";
7812 break;
7813 case 1:
f31b035a 7814 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7815 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 7816 rn = "MVPControl";
ead9360e 7817 break;
9c2149c8 7818 case 2:
f31b035a 7819 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7820 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 7821 rn = "MVPConf0";
ead9360e 7822 break;
9c2149c8 7823 case 3:
f31b035a 7824 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7825 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 7826 rn = "MVPConf1";
ead9360e 7827 break;
01bc435b
YK
7828 case 4:
7829 CP0_CHECK(ctx->vp);
7830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7831 rn = "VPControl";
7832 break;
9c2149c8 7833 default:
f31b035a 7834 goto cp0_unimplemented;
9c2149c8
TS
7835 }
7836 break;
7837 case 1:
7838 switch (sel) {
7839 case 0:
f31b035a 7840 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 7841 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 7842 rn = "Random";
2423f660 7843 break;
9c2149c8 7844 case 1:
f31b035a 7845 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7846 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 7847 rn = "VPEControl";
ead9360e 7848 break;
9c2149c8 7849 case 2:
f31b035a 7850 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 7852 rn = "VPEConf0";
ead9360e 7853 break;
9c2149c8 7854 case 3:
f31b035a 7855 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 7857 rn = "VPEConf1";
ead9360e 7858 break;
9c2149c8 7859 case 4:
f31b035a 7860 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7861 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 7862 rn = "YQMask";
ead9360e 7863 break;
9c2149c8 7864 case 5:
f31b035a 7865 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7866 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7867 rn = "VPESchedule";
ead9360e 7868 break;
9c2149c8 7869 case 6:
f31b035a 7870 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7871 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7872 rn = "VPEScheFBack";
ead9360e 7873 break;
9c2149c8 7874 case 7:
f31b035a 7875 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 7877 rn = "VPEOpt";
ead9360e 7878 break;
9c2149c8 7879 default:
f31b035a 7880 goto cp0_unimplemented;
9c2149c8
TS
7881 }
7882 break;
7883 case 2:
7884 switch (sel) {
7885 case 0:
7db13fae 7886 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
7887 rn = "EntryLo0";
7888 break;
9c2149c8 7889 case 1:
f31b035a 7890 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7891 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 7892 rn = "TCStatus";
ead9360e 7893 break;
9c2149c8 7894 case 2:
f31b035a 7895 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7896 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 7897 rn = "TCBind";
ead9360e 7898 break;
9c2149c8 7899 case 3:
f31b035a 7900 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7901 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 7902 rn = "TCRestart";
ead9360e 7903 break;
9c2149c8 7904 case 4:
f31b035a 7905 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7906 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 7907 rn = "TCHalt";
ead9360e 7908 break;
9c2149c8 7909 case 5:
f31b035a 7910 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7911 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 7912 rn = "TCContext";
ead9360e 7913 break;
9c2149c8 7914 case 6:
f31b035a 7915 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7916 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 7917 rn = "TCSchedule";
ead9360e 7918 break;
9c2149c8 7919 case 7:
f31b035a 7920 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7921 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 7922 rn = "TCScheFBack";
ead9360e 7923 break;
9c2149c8 7924 default:
f31b035a 7925 goto cp0_unimplemented;
9c2149c8
TS
7926 }
7927 break;
7928 case 3:
7929 switch (sel) {
7930 case 0:
7db13fae 7931 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
7932 rn = "EntryLo1";
7933 break;
01bc435b
YK
7934 case 1:
7935 CP0_CHECK(ctx->vp);
7936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7937 rn = "GlobalNumber";
7938 break;
9c2149c8 7939 default:
f31b035a 7940 goto cp0_unimplemented;
1579a72e 7941 }
9c2149c8
TS
7942 break;
7943 case 4:
7944 switch (sel) {
7945 case 0:
7db13fae 7946 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
7947 rn = "Context";
7948 break;
9c2149c8 7949 case 1:
d9bea114 7950// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 7951 rn = "ContextConfig";
f31b035a 7952 goto cp0_unimplemented;
d279279e 7953 case 2:
f31b035a
LA
7954 CP0_CHECK(ctx->ulri);
7955 tcg_gen_ld_tl(arg, cpu_env,
7956 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7957 rn = "UserLocal";
d279279e 7958 break;
9c2149c8 7959 default:
f31b035a 7960 goto cp0_unimplemented;
876d4b07 7961 }
9c2149c8
TS
7962 break;
7963 case 5:
7964 switch (sel) {
7965 case 0:
7db13fae 7966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
7967 rn = "PageMask";
7968 break;
9c2149c8 7969 case 1:
d75c135e 7970 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
7972 rn = "PageGrain";
7973 break;
cec56a73
JH
7974 case 2:
7975 CP0_CHECK(ctx->sc);
7976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7977 rn = "SegCtl0";
7978 break;
7979 case 3:
7980 CP0_CHECK(ctx->sc);
7981 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7982 rn = "SegCtl1";
7983 break;
7984 case 4:
7985 CP0_CHECK(ctx->sc);
7986 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7987 rn = "SegCtl2";
7988 break;
5e31fdd5
YK
7989 case 5:
7990 check_pw(ctx);
7991 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7992 rn = "PWBase";
7993 break;
fa75ad14
YK
7994 case 6:
7995 check_pw(ctx);
7996 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7997 rn = "PWField";
7998 break;
20b28ebc
YK
7999 case 7:
8000 check_pw(ctx);
8001 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8002 rn = "PWSize";
8003 break;
9c2149c8 8004 default:
f31b035a 8005 goto cp0_unimplemented;
876d4b07 8006 }
9c2149c8
TS
8007 break;
8008 case 6:
8009 switch (sel) {
8010 case 0:
7db13fae 8011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
8012 rn = "Wired";
8013 break;
9c2149c8 8014 case 1:
d75c135e 8015 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 8017 rn = "SRSConf0";
ead9360e 8018 break;
9c2149c8 8019 case 2:
d75c135e 8020 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 8022 rn = "SRSConf1";
ead9360e 8023 break;
9c2149c8 8024 case 3:
d75c135e 8025 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8026 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 8027 rn = "SRSConf2";
ead9360e 8028 break;
9c2149c8 8029 case 4:
d75c135e 8030 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8031 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 8032 rn = "SRSConf3";
ead9360e 8033 break;
9c2149c8 8034 case 5:
d75c135e 8035 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8036 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 8037 rn = "SRSConf4";
ead9360e 8038 break;
103be64c
YK
8039 case 6:
8040 check_pw(ctx);
8041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8042 rn = "PWCtl";
8043 break;
9c2149c8 8044 default:
f31b035a 8045 goto cp0_unimplemented;
876d4b07 8046 }
9c2149c8
TS
8047 break;
8048 case 7:
8049 switch (sel) {
8050 case 0:
d75c135e 8051 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8052 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
8053 rn = "HWREna";
8054 break;
9c2149c8 8055 default:
f31b035a 8056 goto cp0_unimplemented;
876d4b07 8057 }
9c2149c8
TS
8058 break;
8059 case 8:
8060 switch (sel) {
8061 case 0:
7db13fae 8062 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 8063 rn = "BadVAddr";
2423f660 8064 break;
aea14095 8065 case 1:
f31b035a
LA
8066 CP0_CHECK(ctx->bi);
8067 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8068 rn = "BadInstr";
aea14095
LA
8069 break;
8070 case 2:
f31b035a
LA
8071 CP0_CHECK(ctx->bp);
8072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8073 rn = "BadInstrP";
aea14095 8074 break;
25beba9b
SM
8075 case 3:
8076 CP0_CHECK(ctx->bi);
8077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8078 tcg_gen_andi_tl(arg, arg, ~0xffff);
8079 rn = "BadInstrX";
8080 break;
9c2149c8 8081 default:
f31b035a 8082 goto cp0_unimplemented;
876d4b07 8083 }
9c2149c8
TS
8084 break;
8085 case 9:
8086 switch (sel) {
8087 case 0:
2e70f6ef 8088 /* Mark as an IO operation because we read the time. */
eeb3bba8 8089 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8090 gen_io_start();
bd79255d 8091 }
895c2d04 8092 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 8093 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8094 gen_io_end();
2e70f6ef 8095 }
55807224 8096 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
8097 after reading count. DISAS_STOP isn't sufficient, we need to
8098 ensure we break completely out of translated code. */
eeb3bba8
EC
8099 gen_save_pc(ctx->base.pc_next + 4);
8100 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8101 rn = "Count";
8102 break;
8103 /* 6,7 are implementation dependent */
9c2149c8 8104 default:
f31b035a 8105 goto cp0_unimplemented;
876d4b07 8106 }
9c2149c8
TS
8107 break;
8108 case 10:
8109 switch (sel) {
8110 case 0:
7db13fae 8111 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
8112 rn = "EntryHi";
8113 break;
9c2149c8 8114 default:
f31b035a 8115 goto cp0_unimplemented;
876d4b07 8116 }
9c2149c8
TS
8117 break;
8118 case 11:
8119 switch (sel) {
8120 case 0:
7db13fae 8121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
8122 rn = "Compare";
8123 break;
876d4b07 8124 /* 6,7 are implementation dependent */
9c2149c8 8125 default:
f31b035a 8126 goto cp0_unimplemented;
876d4b07 8127 }
9c2149c8
TS
8128 break;
8129 case 12:
8130 switch (sel) {
8131 case 0:
7db13fae 8132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
8133 rn = "Status";
8134 break;
9c2149c8 8135 case 1:
d75c135e 8136 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
8138 rn = "IntCtl";
8139 break;
9c2149c8 8140 case 2:
d75c135e 8141 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
8143 rn = "SRSCtl";
8144 break;
9c2149c8 8145 case 3:
d75c135e 8146 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
8148 rn = "SRSMap";
8149 break;
9c2149c8 8150 default:
f31b035a 8151 goto cp0_unimplemented;
876d4b07 8152 }
9c2149c8
TS
8153 break;
8154 case 13:
8155 switch (sel) {
8156 case 0:
7db13fae 8157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
8158 rn = "Cause";
8159 break;
9c2149c8 8160 default:
f31b035a 8161 goto cp0_unimplemented;
876d4b07 8162 }
9c2149c8
TS
8163 break;
8164 case 14:
8165 switch (sel) {
8166 case 0:
7db13fae 8167 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8168 rn = "EPC";
8169 break;
9c2149c8 8170 default:
f31b035a 8171 goto cp0_unimplemented;
876d4b07 8172 }
9c2149c8
TS
8173 break;
8174 case 15:
8175 switch (sel) {
8176 case 0:
7db13fae 8177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
8178 rn = "PRid";
8179 break;
9c2149c8 8180 case 1:
d75c135e 8181 check_insn(ctx, ISA_MIPS32R2);
74dbf824 8182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
8183 rn = "EBase";
8184 break;
c870e3f5
YK
8185 case 3:
8186 check_insn(ctx, ISA_MIPS32R2);
8187 CP0_CHECK(ctx->cmgcr);
8188 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8189 rn = "CMGCRBase";
8190 break;
9c2149c8 8191 default:
f31b035a 8192 goto cp0_unimplemented;
876d4b07 8193 }
9c2149c8
TS
8194 break;
8195 case 16:
8196 switch (sel) {
8197 case 0:
7db13fae 8198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
8199 rn = "Config";
8200 break;
8201 case 1:
7db13fae 8202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
8203 rn = "Config1";
8204 break;
8205 case 2:
7db13fae 8206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
8207 rn = "Config2";
8208 break;
8209 case 3:
7db13fae 8210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
8211 rn = "Config3";
8212 break;
faf1f68b
LA
8213 case 4:
8214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8215 rn = "Config4";
8216 break;
8217 case 5:
8218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8219 rn = "Config5";
8220 break;
9c2149c8 8221 /* 6,7 are implementation dependent */
f0b3f3ae 8222 case 6:
7db13fae 8223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
8224 rn = "Config6";
8225 break;
8226 case 7:
7db13fae 8227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
8228 rn = "Config7";
8229 break;
9c2149c8 8230 default:
f31b035a 8231 goto cp0_unimplemented;
9c2149c8
TS
8232 }
8233 break;
8234 case 17:
8235 switch (sel) {
8236 case 0:
895c2d04 8237 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
8238 rn = "LLAddr";
8239 break;
f6d4dd81
YK
8240 case 1:
8241 CP0_CHECK(ctx->mrp);
8242 gen_helper_dmfc0_maar(arg, cpu_env);
8243 rn = "MAAR";
8244 break;
8245 case 2:
8246 CP0_CHECK(ctx->mrp);
8247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8248 rn = "MAARI";
8249 break;
9c2149c8 8250 default:
f31b035a 8251 goto cp0_unimplemented;
9c2149c8
TS
8252 }
8253 break;
8254 case 18:
8255 switch (sel) {
c2e19f3c
AM
8256 case 0:
8257 case 1:
8258 case 2:
8259 case 3:
8260 case 4:
8261 case 5:
8262 case 6:
8263 case 7:
fa192d49 8264 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8265 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
8266 rn = "WatchLo";
8267 break;
9c2149c8 8268 default:
f31b035a 8269 goto cp0_unimplemented;
9c2149c8
TS
8270 }
8271 break;
8272 case 19:
8273 switch (sel) {
c2e19f3c
AM
8274 case 0:
8275 case 1:
8276 case 2:
8277 case 3:
8278 case 4:
8279 case 5:
8280 case 6:
8281 case 7:
fa192d49 8282 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8283 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
8284 rn = "WatchHi";
8285 break;
9c2149c8 8286 default:
f31b035a 8287 goto cp0_unimplemented;
9c2149c8
TS
8288 }
8289 break;
8290 case 20:
8291 switch (sel) {
8292 case 0:
d75c135e 8293 check_insn(ctx, ISA_MIPS3);
7db13fae 8294 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
8295 rn = "XContext";
8296 break;
9c2149c8 8297 default:
f31b035a 8298 goto cp0_unimplemented;
9c2149c8
TS
8299 }
8300 break;
8301 case 21:
8302 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 8303 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
8304 switch (sel) {
8305 case 0:
7db13fae 8306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
8307 rn = "Framemask";
8308 break;
9c2149c8 8309 default:
f31b035a 8310 goto cp0_unimplemented;
9c2149c8
TS
8311 }
8312 break;
8313 case 22:
d9bea114 8314 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8315 rn = "'Diagnostic"; /* implementation dependent */
8316 break;
9c2149c8
TS
8317 case 23:
8318 switch (sel) {
8319 case 0:
895c2d04 8320 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
8321 rn = "Debug";
8322 break;
9c2149c8 8323 case 1:
895c2d04 8324// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 8325 rn = "TraceControl";
3570d7f6 8326 goto cp0_unimplemented;
9c2149c8 8327 case 2:
895c2d04 8328// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 8329 rn = "TraceControl2";
3570d7f6 8330 goto cp0_unimplemented;
9c2149c8 8331 case 3:
895c2d04 8332// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 8333 rn = "UserTraceData";
3570d7f6 8334 goto cp0_unimplemented;
9c2149c8 8335 case 4:
895c2d04 8336// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 8337 rn = "TraceBPC";
3570d7f6 8338 goto cp0_unimplemented;
9c2149c8 8339 default:
f31b035a 8340 goto cp0_unimplemented;
9c2149c8
TS
8341 }
8342 break;
8343 case 24:
8344 switch (sel) {
8345 case 0:
f0b3f3ae 8346 /* EJTAG support */
7db13fae 8347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8348 rn = "DEPC";
8349 break;
9c2149c8 8350 default:
f31b035a 8351 goto cp0_unimplemented;
9c2149c8
TS
8352 }
8353 break;
8354 case 25:
8355 switch (sel) {
8356 case 0:
7db13fae 8357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 8358 rn = "Performance0";
9c2149c8
TS
8359 break;
8360 case 1:
d9bea114 8361// gen_helper_dmfc0_performance1(arg);
2423f660 8362 rn = "Performance1";
3570d7f6 8363 goto cp0_unimplemented;
9c2149c8 8364 case 2:
d9bea114 8365// gen_helper_dmfc0_performance2(arg);
2423f660 8366 rn = "Performance2";
3570d7f6 8367 goto cp0_unimplemented;
9c2149c8 8368 case 3:
d9bea114 8369// gen_helper_dmfc0_performance3(arg);
2423f660 8370 rn = "Performance3";
3570d7f6 8371 goto cp0_unimplemented;
9c2149c8 8372 case 4:
d9bea114 8373// gen_helper_dmfc0_performance4(arg);
2423f660 8374 rn = "Performance4";
3570d7f6 8375 goto cp0_unimplemented;
9c2149c8 8376 case 5:
d9bea114 8377// gen_helper_dmfc0_performance5(arg);
2423f660 8378 rn = "Performance5";
3570d7f6 8379 goto cp0_unimplemented;
9c2149c8 8380 case 6:
d9bea114 8381// gen_helper_dmfc0_performance6(arg);
2423f660 8382 rn = "Performance6";
3570d7f6 8383 goto cp0_unimplemented;
9c2149c8 8384 case 7:
d9bea114 8385// gen_helper_dmfc0_performance7(arg);
2423f660 8386 rn = "Performance7";
3570d7f6 8387 goto cp0_unimplemented;
9c2149c8 8388 default:
f31b035a 8389 goto cp0_unimplemented;
9c2149c8
TS
8390 }
8391 break;
8392 case 26:
0d74a222
LA
8393 switch (sel) {
8394 case 0:
8395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8396 rn = "ErrCtl";
8397 break;
8398 default:
8399 goto cp0_unimplemented;
8400 }
da80682b 8401 break;
9c2149c8
TS
8402 case 27:
8403 switch (sel) {
8404 /* ignored */
c2e19f3c
AM
8405 case 0:
8406 case 1:
8407 case 2:
8408 case 3:
d9bea114 8409 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8410 rn = "CacheErr";
8411 break;
9c2149c8 8412 default:
f31b035a 8413 goto cp0_unimplemented;
9c2149c8
TS
8414 }
8415 break;
8416 case 28:
8417 switch (sel) {
8418 case 0:
8419 case 2:
8420 case 4:
8421 case 6:
7db13fae 8422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
8423 rn = "TagLo";
8424 break;
8425 case 1:
8426 case 3:
8427 case 5:
8428 case 7:
7db13fae 8429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
8430 rn = "DataLo";
8431 break;
8432 default:
f31b035a 8433 goto cp0_unimplemented;
9c2149c8
TS
8434 }
8435 break;
8436 case 29:
8437 switch (sel) {
8438 case 0:
8439 case 2:
8440 case 4:
8441 case 6:
7db13fae 8442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
8443 rn = "TagHi";
8444 break;
8445 case 1:
8446 case 3:
8447 case 5:
8448 case 7:
7db13fae 8449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
8450 rn = "DataHi";
8451 break;
8452 default:
f31b035a 8453 goto cp0_unimplemented;
9c2149c8
TS
8454 }
8455 break;
8456 case 30:
8457 switch (sel) {
8458 case 0:
7db13fae 8459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8460 rn = "ErrorEPC";
8461 break;
9c2149c8 8462 default:
f31b035a 8463 goto cp0_unimplemented;
9c2149c8
TS
8464 }
8465 break;
8466 case 31:
8467 switch (sel) {
8468 case 0:
f0b3f3ae 8469 /* EJTAG support */
7db13fae 8470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8471 rn = "DESAVE";
8472 break;
c2e19f3c
AM
8473 case 2:
8474 case 3:
8475 case 4:
8476 case 5:
8477 case 6:
8478 case 7:
f31b035a
LA
8479 CP0_CHECK(ctx->kscrexist & (1 << sel));
8480 tcg_gen_ld_tl(arg, cpu_env,
8481 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8482 rn = "KScratch";
e98c0d17 8483 break;
9c2149c8 8484 default:
f31b035a 8485 goto cp0_unimplemented;
9c2149c8
TS
8486 }
8487 break;
8488 default:
f31b035a 8489 goto cp0_unimplemented;
9c2149c8 8490 }
b44a7fb1 8491 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
8492 return;
8493
f31b035a 8494cp0_unimplemented:
965447ee 8495 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 8496 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
8497}
8498
d75c135e 8499static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8500{
8501 const char *rn = "invalid";
8502
e189e748 8503 if (sel != 0)
d75c135e 8504 check_insn(ctx, ISA_MIPS64);
e189e748 8505
eeb3bba8 8506 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8507 gen_io_start();
bd79255d 8508 }
2e70f6ef 8509
9c2149c8
TS
8510 switch (reg) {
8511 case 0:
8512 switch (sel) {
8513 case 0:
895c2d04 8514 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
8515 rn = "Index";
8516 break;
8517 case 1:
f31b035a 8518 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8519 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 8520 rn = "MVPControl";
ead9360e 8521 break;
9c2149c8 8522 case 2:
f31b035a 8523 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8524 /* ignored */
9c2149c8 8525 rn = "MVPConf0";
ead9360e 8526 break;
9c2149c8 8527 case 3:
f31b035a 8528 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8529 /* ignored */
9c2149c8 8530 rn = "MVPConf1";
ead9360e 8531 break;
01bc435b
YK
8532 case 4:
8533 CP0_CHECK(ctx->vp);
8534 /* ignored */
8535 rn = "VPControl";
8536 break;
9c2149c8 8537 default:
f31b035a 8538 goto cp0_unimplemented;
9c2149c8
TS
8539 }
8540 break;
8541 case 1:
8542 switch (sel) {
8543 case 0:
2423f660 8544 /* ignored */
9c2149c8 8545 rn = "Random";
2423f660 8546 break;
9c2149c8 8547 case 1:
f31b035a 8548 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8549 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 8550 rn = "VPEControl";
ead9360e 8551 break;
9c2149c8 8552 case 2:
f31b035a 8553 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8554 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 8555 rn = "VPEConf0";
ead9360e 8556 break;
9c2149c8 8557 case 3:
f31b035a 8558 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8559 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 8560 rn = "VPEConf1";
ead9360e 8561 break;
9c2149c8 8562 case 4:
f31b035a 8563 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8564 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 8565 rn = "YQMask";
ead9360e 8566 break;
9c2149c8 8567 case 5:
f31b035a 8568 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8569 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8570 rn = "VPESchedule";
ead9360e 8571 break;
9c2149c8 8572 case 6:
f31b035a 8573 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8574 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8575 rn = "VPEScheFBack";
ead9360e 8576 break;
9c2149c8 8577 case 7:
f31b035a 8578 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8579 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 8580 rn = "VPEOpt";
ead9360e 8581 break;
9c2149c8 8582 default:
f31b035a 8583 goto cp0_unimplemented;
9c2149c8
TS
8584 }
8585 break;
8586 case 2:
8587 switch (sel) {
8588 case 0:
7207c7f9 8589 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
8590 rn = "EntryLo0";
8591 break;
9c2149c8 8592 case 1:
f31b035a 8593 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8594 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 8595 rn = "TCStatus";
ead9360e 8596 break;
9c2149c8 8597 case 2:
f31b035a 8598 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8599 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 8600 rn = "TCBind";
ead9360e 8601 break;
9c2149c8 8602 case 3:
f31b035a 8603 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8604 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 8605 rn = "TCRestart";
ead9360e 8606 break;
9c2149c8 8607 case 4:
f31b035a 8608 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8609 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 8610 rn = "TCHalt";
ead9360e 8611 break;
9c2149c8 8612 case 5:
f31b035a 8613 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8614 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 8615 rn = "TCContext";
ead9360e 8616 break;
9c2149c8 8617 case 6:
f31b035a 8618 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8619 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 8620 rn = "TCSchedule";
ead9360e 8621 break;
9c2149c8 8622 case 7:
f31b035a 8623 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8624 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 8625 rn = "TCScheFBack";
ead9360e 8626 break;
9c2149c8 8627 default:
f31b035a 8628 goto cp0_unimplemented;
9c2149c8
TS
8629 }
8630 break;
8631 case 3:
8632 switch (sel) {
8633 case 0:
7207c7f9 8634 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
8635 rn = "EntryLo1";
8636 break;
01bc435b
YK
8637 case 1:
8638 CP0_CHECK(ctx->vp);
8639 /* ignored */
8640 rn = "GlobalNumber";
8641 break;
9c2149c8 8642 default:
f31b035a 8643 goto cp0_unimplemented;
876d4b07 8644 }
9c2149c8
TS
8645 break;
8646 case 4:
8647 switch (sel) {
8648 case 0:
895c2d04 8649 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
8650 rn = "Context";
8651 break;
9c2149c8 8652 case 1:
895c2d04 8653// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 8654 rn = "ContextConfig";
f31b035a 8655 goto cp0_unimplemented;
d279279e 8656 case 2:
f31b035a
LA
8657 CP0_CHECK(ctx->ulri);
8658 tcg_gen_st_tl(arg, cpu_env,
8659 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8660 rn = "UserLocal";
d279279e 8661 break;
9c2149c8 8662 default:
f31b035a 8663 goto cp0_unimplemented;
876d4b07 8664 }
9c2149c8
TS
8665 break;
8666 case 5:
8667 switch (sel) {
8668 case 0:
895c2d04 8669 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
8670 rn = "PageMask";
8671 break;
9c2149c8 8672 case 1:
d75c135e 8673 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8674 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
8675 rn = "PageGrain";
8676 break;
cec56a73
JH
8677 case 2:
8678 CP0_CHECK(ctx->sc);
8679 gen_helper_mtc0_segctl0(cpu_env, arg);
8680 rn = "SegCtl0";
8681 break;
8682 case 3:
8683 CP0_CHECK(ctx->sc);
8684 gen_helper_mtc0_segctl1(cpu_env, arg);
8685 rn = "SegCtl1";
8686 break;
8687 case 4:
8688 CP0_CHECK(ctx->sc);
8689 gen_helper_mtc0_segctl2(cpu_env, arg);
8690 rn = "SegCtl2";
8691 break;
5e31fdd5
YK
8692 case 5:
8693 check_pw(ctx);
8694 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8695 rn = "PWBase";
8696 break;
fa75ad14
YK
8697 case 6:
8698 check_pw(ctx);
8699 gen_helper_mtc0_pwfield(cpu_env, arg);
8700 rn = "PWField";
8701 break;
20b28ebc
YK
8702 case 7:
8703 check_pw(ctx);
8704 gen_helper_mtc0_pwsize(cpu_env, arg);
8705 rn = "PWSize";
8706 break;
9c2149c8 8707 default:
f31b035a 8708 goto cp0_unimplemented;
876d4b07 8709 }
9c2149c8
TS
8710 break;
8711 case 6:
8712 switch (sel) {
8713 case 0:
895c2d04 8714 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
8715 rn = "Wired";
8716 break;
9c2149c8 8717 case 1:
d75c135e 8718 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8719 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 8720 rn = "SRSConf0";
ead9360e 8721 break;
9c2149c8 8722 case 2:
d75c135e 8723 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8724 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 8725 rn = "SRSConf1";
ead9360e 8726 break;
9c2149c8 8727 case 3:
d75c135e 8728 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8729 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 8730 rn = "SRSConf2";
ead9360e 8731 break;
9c2149c8 8732 case 4:
d75c135e 8733 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8734 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 8735 rn = "SRSConf3";
ead9360e 8736 break;
9c2149c8 8737 case 5:
d75c135e 8738 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8739 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 8740 rn = "SRSConf4";
ead9360e 8741 break;
103be64c
YK
8742 case 6:
8743 check_pw(ctx);
8744 gen_helper_mtc0_pwctl(cpu_env, arg);
8745 rn = "PWCtl";
8746 break;
9c2149c8 8747 default:
f31b035a 8748 goto cp0_unimplemented;
876d4b07 8749 }
9c2149c8
TS
8750 break;
8751 case 7:
8752 switch (sel) {
8753 case 0:
d75c135e 8754 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8755 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8756 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8757 rn = "HWREna";
8758 break;
9c2149c8 8759 default:
f31b035a 8760 goto cp0_unimplemented;
876d4b07 8761 }
9c2149c8
TS
8762 break;
8763 case 8:
aea14095
LA
8764 switch (sel) {
8765 case 0:
8766 /* ignored */
8767 rn = "BadVAddr";
8768 break;
8769 case 1:
8770 /* ignored */
8771 rn = "BadInstr";
8772 break;
8773 case 2:
8774 /* ignored */
8775 rn = "BadInstrP";
8776 break;
25beba9b
SM
8777 case 3:
8778 /* ignored */
8779 rn = "BadInstrX";
8780 break;
aea14095 8781 default:
f31b035a 8782 goto cp0_unimplemented;
aea14095 8783 }
9c2149c8
TS
8784 break;
8785 case 9:
8786 switch (sel) {
8787 case 0:
895c2d04 8788 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
8789 rn = "Count";
8790 break;
876d4b07 8791 /* 6,7 are implementation dependent */
9c2149c8 8792 default:
f31b035a 8793 goto cp0_unimplemented;
876d4b07
TS
8794 }
8795 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8796 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8797 break;
8798 case 10:
8799 switch (sel) {
8800 case 0:
895c2d04 8801 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
8802 rn = "EntryHi";
8803 break;
9c2149c8 8804 default:
f31b035a 8805 goto cp0_unimplemented;
876d4b07 8806 }
9c2149c8
TS
8807 break;
8808 case 11:
8809 switch (sel) {
8810 case 0:
895c2d04 8811 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
8812 rn = "Compare";
8813 break;
876d4b07 8814 /* 6,7 are implementation dependent */
9c2149c8 8815 default:
f31b035a 8816 goto cp0_unimplemented;
876d4b07 8817 }
de9a95f0 8818 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8819 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8820 break;
8821 case 12:
8822 switch (sel) {
8823 case 0:
867abc7e 8824 save_cpu_state(ctx, 1);
895c2d04 8825 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8826 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8827 gen_save_pc(ctx->base.pc_next + 4);
8828 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8829 rn = "Status";
8830 break;
9c2149c8 8831 case 1:
d75c135e 8832 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8833 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8834 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8835 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8836 rn = "IntCtl";
8837 break;
9c2149c8 8838 case 2:
d75c135e 8839 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8840 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8841 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8842 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8843 rn = "SRSCtl";
8844 break;
9c2149c8 8845 case 3:
d75c135e 8846 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8847 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8848 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8849 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8850 rn = "SRSMap";
8851 break;
8852 default:
f31b035a 8853 goto cp0_unimplemented;
876d4b07 8854 }
9c2149c8
TS
8855 break;
8856 case 13:
8857 switch (sel) {
8858 case 0:
867abc7e 8859 save_cpu_state(ctx, 1);
895c2d04 8860 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
8861 /* Stop translation as we may have triggered an interrupt.
8862 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8863 * translated code to check for pending interrupts. */
eeb3bba8
EC
8864 gen_save_pc(ctx->base.pc_next + 4);
8865 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8866 rn = "Cause";
8867 break;
9c2149c8 8868 default:
f31b035a 8869 goto cp0_unimplemented;
876d4b07 8870 }
9c2149c8
TS
8871 break;
8872 case 14:
8873 switch (sel) {
8874 case 0:
7db13fae 8875 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8876 rn = "EPC";
8877 break;
9c2149c8 8878 default:
f31b035a 8879 goto cp0_unimplemented;
876d4b07 8880 }
9c2149c8
TS
8881 break;
8882 case 15:
8883 switch (sel) {
8884 case 0:
2423f660
TS
8885 /* ignored */
8886 rn = "PRid";
8887 break;
9c2149c8 8888 case 1:
d75c135e 8889 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8890 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
8891 rn = "EBase";
8892 break;
9c2149c8 8893 default:
f31b035a 8894 goto cp0_unimplemented;
876d4b07 8895 }
9c2149c8
TS
8896 break;
8897 case 16:
8898 switch (sel) {
8899 case 0:
895c2d04 8900 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 8901 rn = "Config";
2423f660 8902 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8903 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8904 break;
8905 case 1:
1fc7bf6e 8906 /* ignored, read only */
9c2149c8
TS
8907 rn = "Config1";
8908 break;
8909 case 2:
895c2d04 8910 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 8911 rn = "Config2";
2423f660 8912 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8913 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8914 break;
8915 case 3:
90f12d73 8916 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 8917 rn = "Config3";
90f12d73 8918 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8919 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8920 break;
faf1f68b
LA
8921 case 4:
8922 /* currently ignored */
8923 rn = "Config4";
8924 break;
8925 case 5:
8926 gen_helper_mtc0_config5(cpu_env, arg);
8927 rn = "Config5";
8928 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8929 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 8930 break;
9c2149c8
TS
8931 /* 6,7 are implementation dependent */
8932 default:
8933 rn = "Invalid config selector";
f31b035a 8934 goto cp0_unimplemented;
9c2149c8 8935 }
9c2149c8
TS
8936 break;
8937 case 17:
8938 switch (sel) {
8939 case 0:
895c2d04 8940 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
8941 rn = "LLAddr";
8942 break;
f6d4dd81
YK
8943 case 1:
8944 CP0_CHECK(ctx->mrp);
8945 gen_helper_mtc0_maar(cpu_env, arg);
8946 rn = "MAAR";
8947 break;
8948 case 2:
8949 CP0_CHECK(ctx->mrp);
8950 gen_helper_mtc0_maari(cpu_env, arg);
8951 rn = "MAARI";
8952 break;
9c2149c8 8953 default:
f31b035a 8954 goto cp0_unimplemented;
9c2149c8
TS
8955 }
8956 break;
8957 case 18:
8958 switch (sel) {
c2e19f3c
AM
8959 case 0:
8960 case 1:
8961 case 2:
8962 case 3:
8963 case 4:
8964 case 5:
8965 case 6:
8966 case 7:
fa192d49 8967 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8968 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
8969 rn = "WatchLo";
8970 break;
9c2149c8 8971 default:
f31b035a 8972 goto cp0_unimplemented;
9c2149c8
TS
8973 }
8974 break;
8975 case 19:
8976 switch (sel) {
c2e19f3c
AM
8977 case 0:
8978 case 1:
8979 case 2:
8980 case 3:
8981 case 4:
8982 case 5:
8983 case 6:
8984 case 7:
fa192d49 8985 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8986 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
8987 rn = "WatchHi";
8988 break;
9c2149c8 8989 default:
f31b035a 8990 goto cp0_unimplemented;
9c2149c8
TS
8991 }
8992 break;
8993 case 20:
8994 switch (sel) {
8995 case 0:
d75c135e 8996 check_insn(ctx, ISA_MIPS3);
895c2d04 8997 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
8998 rn = "XContext";
8999 break;
9c2149c8 9000 default:
f31b035a 9001 goto cp0_unimplemented;
9c2149c8
TS
9002 }
9003 break;
9004 case 21:
9005 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 9006 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
9007 switch (sel) {
9008 case 0:
895c2d04 9009 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
9010 rn = "Framemask";
9011 break;
9c2149c8 9012 default:
f31b035a 9013 goto cp0_unimplemented;
9c2149c8
TS
9014 }
9015 break;
9016 case 22:
9017 /* ignored */
9018 rn = "Diagnostic"; /* implementation dependent */
876d4b07 9019 break;
9c2149c8
TS
9020 case 23:
9021 switch (sel) {
9022 case 0:
895c2d04 9023 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 9024 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9025 gen_save_pc(ctx->base.pc_next + 4);
9026 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9027 rn = "Debug";
9028 break;
9c2149c8 9029 case 1:
895c2d04 9030// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 9031 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9032 ctx->base.is_jmp = DISAS_STOP;
2423f660 9033 rn = "TraceControl";
3570d7f6 9034 goto cp0_unimplemented;
9c2149c8 9035 case 2:
895c2d04 9036// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 9037 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9038 ctx->base.is_jmp = DISAS_STOP;
2423f660 9039 rn = "TraceControl2";
3570d7f6 9040 goto cp0_unimplemented;
9c2149c8 9041 case 3:
895c2d04 9042// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 9043 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9044 ctx->base.is_jmp = DISAS_STOP;
2423f660 9045 rn = "UserTraceData";
3570d7f6 9046 goto cp0_unimplemented;
9c2149c8 9047 case 4:
895c2d04 9048// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 9049 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9050 ctx->base.is_jmp = DISAS_STOP;
2423f660 9051 rn = "TraceBPC";
3570d7f6 9052 goto cp0_unimplemented;
9c2149c8 9053 default:
f31b035a 9054 goto cp0_unimplemented;
9c2149c8 9055 }
9c2149c8
TS
9056 break;
9057 case 24:
9058 switch (sel) {
9059 case 0:
f1aa6320 9060 /* EJTAG support */
7db13fae 9061 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
9062 rn = "DEPC";
9063 break;
9c2149c8 9064 default:
f31b035a 9065 goto cp0_unimplemented;
9c2149c8
TS
9066 }
9067 break;
9068 case 25:
9069 switch (sel) {
9070 case 0:
895c2d04 9071 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
9072 rn = "Performance0";
9073 break;
9c2149c8 9074 case 1:
895c2d04 9075// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 9076 rn = "Performance1";
3570d7f6 9077 goto cp0_unimplemented;
9c2149c8 9078 case 2:
895c2d04 9079// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 9080 rn = "Performance2";
3570d7f6 9081 goto cp0_unimplemented;
9c2149c8 9082 case 3:
895c2d04 9083// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 9084 rn = "Performance3";
3570d7f6 9085 goto cp0_unimplemented;
9c2149c8 9086 case 4:
895c2d04 9087// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 9088 rn = "Performance4";
3570d7f6 9089 goto cp0_unimplemented;
9c2149c8 9090 case 5:
895c2d04 9091// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 9092 rn = "Performance5";
3570d7f6 9093 goto cp0_unimplemented;
9c2149c8 9094 case 6:
895c2d04 9095// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 9096 rn = "Performance6";
3570d7f6 9097 goto cp0_unimplemented;
9c2149c8 9098 case 7:
895c2d04 9099// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 9100 rn = "Performance7";
3570d7f6 9101 goto cp0_unimplemented;
9c2149c8 9102 default:
f31b035a 9103 goto cp0_unimplemented;
9c2149c8 9104 }
876d4b07 9105 break;
9c2149c8 9106 case 26:
0d74a222
LA
9107 switch (sel) {
9108 case 0:
9109 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 9110 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
9111 rn = "ErrCtl";
9112 break;
9113 default:
9114 goto cp0_unimplemented;
9115 }
876d4b07 9116 break;
9c2149c8
TS
9117 case 27:
9118 switch (sel) {
c2e19f3c
AM
9119 case 0:
9120 case 1:
9121 case 2:
9122 case 3:
2423f660
TS
9123 /* ignored */
9124 rn = "CacheErr";
9125 break;
9c2149c8 9126 default:
f31b035a 9127 goto cp0_unimplemented;
9c2149c8 9128 }
876d4b07 9129 break;
9c2149c8
TS
9130 case 28:
9131 switch (sel) {
9132 case 0:
9133 case 2:
9134 case 4:
9135 case 6:
895c2d04 9136 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
9137 rn = "TagLo";
9138 break;
9139 case 1:
9140 case 3:
9141 case 5:
9142 case 7:
895c2d04 9143 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
9144 rn = "DataLo";
9145 break;
9146 default:
f31b035a 9147 goto cp0_unimplemented;
9c2149c8
TS
9148 }
9149 break;
9150 case 29:
9151 switch (sel) {
9152 case 0:
9153 case 2:
9154 case 4:
9155 case 6:
895c2d04 9156 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
9157 rn = "TagHi";
9158 break;
9159 case 1:
9160 case 3:
9161 case 5:
9162 case 7:
895c2d04 9163 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
9164 rn = "DataHi";
9165 break;
9166 default:
9167 rn = "invalid sel";
f31b035a 9168 goto cp0_unimplemented;
9c2149c8 9169 }
876d4b07 9170 break;
9c2149c8
TS
9171 case 30:
9172 switch (sel) {
9173 case 0:
7db13fae 9174 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
9175 rn = "ErrorEPC";
9176 break;
9c2149c8 9177 default:
f31b035a 9178 goto cp0_unimplemented;
9c2149c8
TS
9179 }
9180 break;
9181 case 31:
9182 switch (sel) {
9183 case 0:
f1aa6320 9184 /* EJTAG support */
7db13fae 9185 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
9186 rn = "DESAVE";
9187 break;
c2e19f3c
AM
9188 case 2:
9189 case 3:
9190 case 4:
9191 case 5:
9192 case 6:
9193 case 7:
f31b035a
LA
9194 CP0_CHECK(ctx->kscrexist & (1 << sel));
9195 tcg_gen_st_tl(arg, cpu_env,
9196 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9197 rn = "KScratch";
e98c0d17 9198 break;
9c2149c8 9199 default:
f31b035a 9200 goto cp0_unimplemented;
9c2149c8 9201 }
9c2149c8
TS
9202 break;
9203 default:
f31b035a 9204 goto cp0_unimplemented;
9c2149c8 9205 }
b44a7fb1
PMD
9206 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9207
bf20dc07 9208 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 9209 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 9210 gen_io_end();
b28425ba 9211 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 9212 * translated code to check for pending interrupts. */
eeb3bba8
EC
9213 gen_save_pc(ctx->base.pc_next + 4);
9214 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 9215 }
9c2149c8
TS
9216 return;
9217
f31b035a 9218cp0_unimplemented:
965447ee 9219 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 9220}
d26bc211 9221#endif /* TARGET_MIPS64 */
9c2149c8 9222
7db13fae 9223static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
9224 int u, int sel, int h)
9225{
9226 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9227 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
9228
9229 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9230 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9231 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 9232 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9233 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9234 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 9235 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9236 else if (u == 0) {
9237 switch (rt) {
5a25ce94
EI
9238 case 1:
9239 switch (sel) {
9240 case 1:
895c2d04 9241 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
9242 break;
9243 case 2:
895c2d04 9244 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
9245 break;
9246 default:
9247 goto die;
9248 break;
9249 }
9250 break;
ead9360e
TS
9251 case 2:
9252 switch (sel) {
9253 case 1:
895c2d04 9254 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
9255 break;
9256 case 2:
895c2d04 9257 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
9258 break;
9259 case 3:
895c2d04 9260 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
9261 break;
9262 case 4:
895c2d04 9263 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
9264 break;
9265 case 5:
895c2d04 9266 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
9267 break;
9268 case 6:
895c2d04 9269 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
9270 break;
9271 case 7:
895c2d04 9272 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
9273 break;
9274 default:
d75c135e 9275 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9276 break;
9277 }
9278 break;
9279 case 10:
9280 switch (sel) {
9281 case 0:
895c2d04 9282 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
9283 break;
9284 default:
d75c135e 9285 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9286 break;
9287 }
9288 case 12:
9289 switch (sel) {
9290 case 0:
895c2d04 9291 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
9292 break;
9293 default:
d75c135e 9294 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9295 break;
9296 }
5a25ce94
EI
9297 case 13:
9298 switch (sel) {
9299 case 0:
895c2d04 9300 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
9301 break;
9302 default:
9303 goto die;
9304 break;
9305 }
9306 break;
9307 case 14:
9308 switch (sel) {
9309 case 0:
895c2d04 9310 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
9311 break;
9312 default:
9313 goto die;
9314 break;
9315 }
9316 break;
9317 case 15:
9318 switch (sel) {
9319 case 1:
895c2d04 9320 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
9321 break;
9322 default:
9323 goto die;
9324 break;
9325 }
9326 break;
9327 case 16:
9328 switch (sel) {
c2e19f3c
AM
9329 case 0:
9330 case 1:
9331 case 2:
9332 case 3:
9333 case 4:
9334 case 5:
9335 case 6:
9336 case 7:
895c2d04 9337 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
9338 break;
9339 default:
9340 goto die;
9341 break;
9342 }
9343 break;
ead9360e
TS
9344 case 23:
9345 switch (sel) {
9346 case 0:
895c2d04 9347 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
9348 break;
9349 default:
d75c135e 9350 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9351 break;
9352 }
9353 break;
9354 default:
d75c135e 9355 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9356 }
9357 } else switch (sel) {
9358 /* GPR registers. */
9359 case 0:
895c2d04 9360 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
9361 break;
9362 /* Auxiliary CPU registers */
9363 case 1:
9364 switch (rt) {
9365 case 0:
895c2d04 9366 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
9367 break;
9368 case 1:
895c2d04 9369 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
9370 break;
9371 case 2:
895c2d04 9372 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
9373 break;
9374 case 4:
895c2d04 9375 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
9376 break;
9377 case 5:
895c2d04 9378 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
9379 break;
9380 case 6:
895c2d04 9381 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
9382 break;
9383 case 8:
895c2d04 9384 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
9385 break;
9386 case 9:
895c2d04 9387 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
9388 break;
9389 case 10:
895c2d04 9390 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
9391 break;
9392 case 12:
895c2d04 9393 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
9394 break;
9395 case 13:
895c2d04 9396 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
9397 break;
9398 case 14:
895c2d04 9399 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
9400 break;
9401 case 16:
895c2d04 9402 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
9403 break;
9404 default:
9405 goto die;
9406 }
9407 break;
9408 /* Floating point (COP1). */
9409 case 2:
9410 /* XXX: For now we support only a single FPU context. */
9411 if (h == 0) {
a7812ae4 9412 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9413
7c979afd 9414 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 9415 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9416 tcg_temp_free_i32(fp0);
ead9360e 9417 } else {
a7812ae4 9418 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9419
7f6613ce 9420 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 9421 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9422 tcg_temp_free_i32(fp0);
ead9360e
TS
9423 }
9424 break;
9425 case 3:
9426 /* XXX: For now we support only a single FPU context. */
895c2d04 9427 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
9428 break;
9429 /* COP2: Not implemented. */
9430 case 4:
9431 case 5:
9432 /* fall through */
9433 default:
9434 goto die;
9435 }
b44a7fb1 9436 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
9437 gen_store_gpr(t0, rd);
9438 tcg_temp_free(t0);
ead9360e
TS
9439 return;
9440
9441die:
1a3fd9c3 9442 tcg_temp_free(t0);
d12d51d5 9443 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 9444 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9445}
9446
7db13fae 9447static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
9448 int u, int sel, int h)
9449{
9450 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9451 TCGv t0 = tcg_temp_local_new();
ead9360e 9452
1a3fd9c3 9453 gen_load_gpr(t0, rt);
ead9360e 9454 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9455 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9456 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
9457 /* NOP */ ;
9458 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9459 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9460 /* NOP */ ;
9461 else if (u == 0) {
9462 switch (rd) {
5a25ce94
EI
9463 case 1:
9464 switch (sel) {
9465 case 1:
895c2d04 9466 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
9467 break;
9468 case 2:
895c2d04 9469 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
9470 break;
9471 default:
9472 goto die;
9473 break;
9474 }
9475 break;
ead9360e
TS
9476 case 2:
9477 switch (sel) {
9478 case 1:
895c2d04 9479 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
9480 break;
9481 case 2:
895c2d04 9482 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
9483 break;
9484 case 3:
895c2d04 9485 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
9486 break;
9487 case 4:
895c2d04 9488 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
9489 break;
9490 case 5:
895c2d04 9491 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
9492 break;
9493 case 6:
895c2d04 9494 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
9495 break;
9496 case 7:
895c2d04 9497 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
9498 break;
9499 default:
d75c135e 9500 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9501 break;
9502 }
9503 break;
9504 case 10:
9505 switch (sel) {
9506 case 0:
895c2d04 9507 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
9508 break;
9509 default:
d75c135e 9510 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9511 break;
9512 }
9513 case 12:
9514 switch (sel) {
9515 case 0:
895c2d04 9516 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
9517 break;
9518 default:
d75c135e 9519 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9520 break;
9521 }
5a25ce94
EI
9522 case 13:
9523 switch (sel) {
9524 case 0:
895c2d04 9525 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
9526 break;
9527 default:
9528 goto die;
9529 break;
9530 }
9531 break;
9532 case 15:
9533 switch (sel) {
9534 case 1:
895c2d04 9535 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
9536 break;
9537 default:
9538 goto die;
9539 break;
9540 }
9541 break;
ead9360e
TS
9542 case 23:
9543 switch (sel) {
9544 case 0:
895c2d04 9545 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
9546 break;
9547 default:
d75c135e 9548 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9549 break;
9550 }
9551 break;
9552 default:
d75c135e 9553 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9554 }
9555 } else switch (sel) {
9556 /* GPR registers. */
9557 case 0:
895c2d04 9558 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
9559 break;
9560 /* Auxiliary CPU registers */
9561 case 1:
9562 switch (rd) {
9563 case 0:
895c2d04 9564 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
9565 break;
9566 case 1:
895c2d04 9567 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
9568 break;
9569 case 2:
895c2d04 9570 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
9571 break;
9572 case 4:
895c2d04 9573 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
9574 break;
9575 case 5:
895c2d04 9576 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
9577 break;
9578 case 6:
895c2d04 9579 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
9580 break;
9581 case 8:
895c2d04 9582 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
9583 break;
9584 case 9:
895c2d04 9585 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
9586 break;
9587 case 10:
895c2d04 9588 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
9589 break;
9590 case 12:
895c2d04 9591 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
9592 break;
9593 case 13:
895c2d04 9594 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
9595 break;
9596 case 14:
895c2d04 9597 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
9598 break;
9599 case 16:
895c2d04 9600 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
9601 break;
9602 default:
9603 goto die;
9604 }
9605 break;
9606 /* Floating point (COP1). */
9607 case 2:
9608 /* XXX: For now we support only a single FPU context. */
9609 if (h == 0) {
a7812ae4 9610 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9611
9612 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9613 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 9614 tcg_temp_free_i32(fp0);
ead9360e 9615 } else {
a7812ae4 9616 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9617
9618 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9619 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 9620 tcg_temp_free_i32(fp0);
ead9360e
TS
9621 }
9622 break;
9623 case 3:
9624 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
9625 {
9626 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9627
9628 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9629 tcg_temp_free_i32(fs_tmp);
9630 }
4cf8a45f 9631 /* Stop translation as we may have changed hflags */
eeb3bba8 9632 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
9633 break;
9634 /* COP2: Not implemented. */
9635 case 4:
9636 case 5:
9637 /* fall through */
9638 default:
9639 goto die;
9640 }
b44a7fb1 9641 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9642 tcg_temp_free(t0);
ead9360e
TS
9643 return;
9644
9645die:
1a3fd9c3 9646 tcg_temp_free(t0);
d12d51d5 9647 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 9648 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9649}
9650
7db13fae 9651static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 9652{
287c4b84 9653 const char *opn = "ldst";
6af0bf9c 9654
2e15497c 9655 check_cp0_enabled(ctx);
6af0bf9c
FB
9656 switch (opc) {
9657 case OPC_MFC0:
9658 if (rt == 0) {
ead9360e 9659 /* Treat as NOP. */
6af0bf9c
FB
9660 return;
9661 }
d75c135e 9662 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9663 opn = "mfc0";
9664 break;
9665 case OPC_MTC0:
1a3fd9c3 9666 {
1fc7bf6e 9667 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9668
9669 gen_load_gpr(t0, rt);
d75c135e 9670 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9671 tcg_temp_free(t0);
9672 }
6af0bf9c
FB
9673 opn = "mtc0";
9674 break;
d26bc211 9675#if defined(TARGET_MIPS64)
9c2149c8 9676 case OPC_DMFC0:
d75c135e 9677 check_insn(ctx, ISA_MIPS3);
9c2149c8 9678 if (rt == 0) {
ead9360e 9679 /* Treat as NOP. */
9c2149c8
TS
9680 return;
9681 }
d75c135e 9682 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
9683 opn = "dmfc0";
9684 break;
9685 case OPC_DMTC0:
d75c135e 9686 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 9687 {
1fc7bf6e 9688 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9689
9690 gen_load_gpr(t0, rt);
d75c135e 9691 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9692 tcg_temp_free(t0);
9693 }
9c2149c8
TS
9694 opn = "dmtc0";
9695 break;
534ce69f 9696#endif
5204ea79
LA
9697 case OPC_MFHC0:
9698 check_mvh(ctx);
9699 if (rt == 0) {
9700 /* Treat as NOP. */
9701 return;
9702 }
9703 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9704 opn = "mfhc0";
9705 break;
9706 case OPC_MTHC0:
9707 check_mvh(ctx);
9708 {
9709 TCGv t0 = tcg_temp_new();
9710 gen_load_gpr(t0, rt);
9711 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9712 tcg_temp_free(t0);
9713 }
9714 opn = "mthc0";
9715 break;
ead9360e 9716 case OPC_MFTR:
9affc1c5 9717 check_cp0_enabled(ctx);
ead9360e
TS
9718 if (rd == 0) {
9719 /* Treat as NOP. */
9720 return;
9721 }
6c5c1e20 9722 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 9723 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
9724 opn = "mftr";
9725 break;
9726 case OPC_MTTR:
9affc1c5 9727 check_cp0_enabled(ctx);
6c5c1e20 9728 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
9729 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9730 opn = "mttr";
9731 break;
6af0bf9c 9732 case OPC_TLBWI:
6af0bf9c 9733 opn = "tlbwi";
c01fccd2 9734 if (!env->tlb->helper_tlbwi)
29929e34 9735 goto die;
895c2d04 9736 gen_helper_tlbwi(cpu_env);
6af0bf9c 9737 break;
9456c2fb
LA
9738 case OPC_TLBINV:
9739 opn = "tlbinv";
9740 if (ctx->ie >= 2) {
9741 if (!env->tlb->helper_tlbinv) {
9742 goto die;
9743 }
9744 gen_helper_tlbinv(cpu_env);
9745 } /* treat as nop if TLBINV not supported */
9746 break;
9747 case OPC_TLBINVF:
9748 opn = "tlbinvf";
9749 if (ctx->ie >= 2) {
9750 if (!env->tlb->helper_tlbinvf) {
9751 goto die;
9752 }
9753 gen_helper_tlbinvf(cpu_env);
9754 } /* treat as nop if TLBINV not supported */
9755 break;
6af0bf9c 9756 case OPC_TLBWR:
6af0bf9c 9757 opn = "tlbwr";
c01fccd2 9758 if (!env->tlb->helper_tlbwr)
29929e34 9759 goto die;
895c2d04 9760 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
9761 break;
9762 case OPC_TLBP:
6af0bf9c 9763 opn = "tlbp";
c01fccd2 9764 if (!env->tlb->helper_tlbp)
29929e34 9765 goto die;
895c2d04 9766 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
9767 break;
9768 case OPC_TLBR:
6af0bf9c 9769 opn = "tlbr";
c01fccd2 9770 if (!env->tlb->helper_tlbr)
29929e34 9771 goto die;
895c2d04 9772 gen_helper_tlbr(cpu_env);
6af0bf9c 9773 break;
ce9782f4 9774 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
9775 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9776 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 9777 goto die;
ce9782f4
LA
9778 } else {
9779 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9780 if (ctx->opcode & (1 << bit_shift)) {
9781 /* OPC_ERETNC */
9782 opn = "eretnc";
9783 check_insn(ctx, ISA_MIPS32R5);
9784 gen_helper_eretnc(cpu_env);
9785 } else {
9786 /* OPC_ERET */
9787 opn = "eret";
9788 check_insn(ctx, ISA_MIPS2);
9789 gen_helper_eret(cpu_env);
9790 }
eeb3bba8 9791 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 9792 }
6af0bf9c
FB
9793 break;
9794 case OPC_DERET:
9795 opn = "deret";
d75c135e 9796 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
9797 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9798 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9799 goto die;
9800 }
6af0bf9c 9801 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 9802 MIPS_INVAL(opn);
9c708c7f 9803 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 9804 } else {
895c2d04 9805 gen_helper_deret(cpu_env);
eeb3bba8 9806 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
9807 }
9808 break;
4ad40f36
FB
9809 case OPC_WAIT:
9810 opn = "wait";
d75c135e 9811 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
9812 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9813 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9814 goto die;
9815 }
4ad40f36 9816 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 9817 ctx->base.pc_next += 4;
4ad40f36 9818 save_cpu_state(ctx, 1);
eeb3bba8 9819 ctx->base.pc_next -= 4;
895c2d04 9820 gen_helper_wait(cpu_env);
eeb3bba8 9821 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 9822 break;
6af0bf9c 9823 default:
29929e34 9824 die:
923617a3 9825 MIPS_INVAL(opn);
9c708c7f 9826 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
9827 return;
9828 }
2abf314d 9829 (void)opn; /* avoid a compiler warning */
6af0bf9c 9830}
f1aa6320 9831#endif /* !CONFIG_USER_ONLY */
6af0bf9c 9832
6ea83fed 9833/* CP1 Branches (before delay slot) */
d75c135e
AJ
9834static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9835 int32_t cc, int32_t offset)
6ea83fed
FB
9836{
9837 target_ulong btarget;
a7812ae4 9838 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 9839
339cd2a8 9840 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 9841 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
9842 goto out;
9843 }
9844
e189e748 9845 if (cc != 0)
d75c135e 9846 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 9847
eeb3bba8 9848 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 9849
7a387fff
TS
9850 switch (op) {
9851 case OPC_BC1F:
d94536f4
AJ
9852 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9853 tcg_gen_not_i32(t0, t0);
9854 tcg_gen_andi_i32(t0, t0, 1);
9855 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9856 goto not_likely;
7a387fff 9857 case OPC_BC1FL:
d94536f4
AJ
9858 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9859 tcg_gen_not_i32(t0, t0);
9860 tcg_gen_andi_i32(t0, t0, 1);
9861 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9862 goto likely;
7a387fff 9863 case OPC_BC1T:
d94536f4
AJ
9864 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9865 tcg_gen_andi_i32(t0, t0, 1);
9866 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 9867 goto not_likely;
7a387fff 9868 case OPC_BC1TL:
d94536f4
AJ
9869 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9870 tcg_gen_andi_i32(t0, t0, 1);
9871 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
9872 likely:
9873 ctx->hflags |= MIPS_HFLAG_BL;
9874 break;
5a5012ec 9875 case OPC_BC1FANY2:
a16336e4 9876 {
d94536f4
AJ
9877 TCGv_i32 t1 = tcg_temp_new_i32();
9878 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9879 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 9880 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9881 tcg_temp_free_i32(t1);
d94536f4
AJ
9882 tcg_gen_andi_i32(t0, t0, 1);
9883 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9884 }
5a5012ec
TS
9885 goto not_likely;
9886 case OPC_BC1TANY2:
a16336e4 9887 {
d94536f4
AJ
9888 TCGv_i32 t1 = tcg_temp_new_i32();
9889 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9890 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9891 tcg_gen_or_i32(t0, t0, t1);
9892 tcg_temp_free_i32(t1);
9893 tcg_gen_andi_i32(t0, t0, 1);
9894 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9895 }
5a5012ec
TS
9896 goto not_likely;
9897 case OPC_BC1FANY4:
a16336e4 9898 {
d94536f4
AJ
9899 TCGv_i32 t1 = tcg_temp_new_i32();
9900 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9901 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 9902 tcg_gen_and_i32(t0, t0, t1);
d94536f4 9903 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 9904 tcg_gen_and_i32(t0, t0, t1);
d94536f4 9905 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 9906 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9907 tcg_temp_free_i32(t1);
d94536f4
AJ
9908 tcg_gen_andi_i32(t0, t0, 1);
9909 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9910 }
5a5012ec
TS
9911 goto not_likely;
9912 case OPC_BC1TANY4:
a16336e4 9913 {
d94536f4
AJ
9914 TCGv_i32 t1 = tcg_temp_new_i32();
9915 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9916 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9917 tcg_gen_or_i32(t0, t0, t1);
9918 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9919 tcg_gen_or_i32(t0, t0, t1);
9920 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9921 tcg_gen_or_i32(t0, t0, t1);
9922 tcg_temp_free_i32(t1);
9923 tcg_gen_andi_i32(t0, t0, 1);
9924 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9925 }
5a5012ec
TS
9926 not_likely:
9927 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
9928 break;
9929 default:
9d68ac14 9930 MIPS_INVAL("cp1 cond branch");
9c708c7f 9931 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 9932 goto out;
6ea83fed 9933 }
6ea83fed 9934 ctx->btarget = btarget;
b231c103 9935 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 9936 out:
a7812ae4 9937 tcg_temp_free_i32(t0);
6ea83fed
FB
9938}
9939
31837be3
YK
9940/* R6 CP1 Branches */
9941static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
9942 int32_t ft, int32_t offset,
9943 int delayslot_size)
31837be3
YK
9944{
9945 target_ulong btarget;
31837be3
YK
9946 TCGv_i64 t0 = tcg_temp_new_i64();
9947
9948 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9949#ifdef MIPS_DEBUG_DISAS
339cd2a8 9950 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 9951 "\n", ctx->base.pc_next);
31837be3 9952#endif
9c708c7f 9953 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
9954 goto out;
9955 }
9956
9957 gen_load_fpr64(ctx, t0, ft);
9958 tcg_gen_andi_i64(t0, t0, 1);
9959
eeb3bba8 9960 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
9961
9962 switch (op) {
9963 case OPC_BC1EQZ:
9964 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
9965 ctx->hflags |= MIPS_HFLAG_BC;
9966 break;
9967 case OPC_BC1NEZ:
9968 /* t0 already set */
31837be3
YK
9969 ctx->hflags |= MIPS_HFLAG_BC;
9970 break;
9971 default:
9d68ac14 9972 MIPS_INVAL("cp1 cond branch");
9c708c7f 9973 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
9974 goto out;
9975 }
9976
9977 tcg_gen_trunc_i64_tl(bcond, t0);
9978
31837be3 9979 ctx->btarget = btarget;
65935f07
YK
9980
9981 switch (delayslot_size) {
9982 case 2:
9983 ctx->hflags |= MIPS_HFLAG_BDS16;
9984 break;
9985 case 4:
9986 ctx->hflags |= MIPS_HFLAG_BDS32;
9987 break;
9988 }
31837be3
YK
9989
9990out:
9991 tcg_temp_free_i64(t0);
9992}
9993
6af0bf9c 9994/* Coprocessor 1 (FPU) */
5a5012ec 9995
5a5012ec
TS
9996#define FOP(func, fmt) (((fmt) << 21) | (func))
9997
bf4120ad
NF
9998enum fopcode {
9999 OPC_ADD_S = FOP(0, FMT_S),
10000 OPC_SUB_S = FOP(1, FMT_S),
10001 OPC_MUL_S = FOP(2, FMT_S),
10002 OPC_DIV_S = FOP(3, FMT_S),
10003 OPC_SQRT_S = FOP(4, FMT_S),
10004 OPC_ABS_S = FOP(5, FMT_S),
10005 OPC_MOV_S = FOP(6, FMT_S),
10006 OPC_NEG_S = FOP(7, FMT_S),
10007 OPC_ROUND_L_S = FOP(8, FMT_S),
10008 OPC_TRUNC_L_S = FOP(9, FMT_S),
10009 OPC_CEIL_L_S = FOP(10, FMT_S),
10010 OPC_FLOOR_L_S = FOP(11, FMT_S),
10011 OPC_ROUND_W_S = FOP(12, FMT_S),
10012 OPC_TRUNC_W_S = FOP(13, FMT_S),
10013 OPC_CEIL_W_S = FOP(14, FMT_S),
10014 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 10015 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
10016 OPC_MOVCF_S = FOP(17, FMT_S),
10017 OPC_MOVZ_S = FOP(18, FMT_S),
10018 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 10019 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
10020 OPC_RECIP_S = FOP(21, FMT_S),
10021 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
10022 OPC_SELNEZ_S = FOP(23, FMT_S),
10023 OPC_MADDF_S = FOP(24, FMT_S),
10024 OPC_MSUBF_S = FOP(25, FMT_S),
10025 OPC_RINT_S = FOP(26, FMT_S),
10026 OPC_CLASS_S = FOP(27, FMT_S),
10027 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 10028 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 10029 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 10030 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 10031 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 10032 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 10033 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
10034 OPC_RSQRT2_S = FOP(31, FMT_S),
10035 OPC_CVT_D_S = FOP(33, FMT_S),
10036 OPC_CVT_W_S = FOP(36, FMT_S),
10037 OPC_CVT_L_S = FOP(37, FMT_S),
10038 OPC_CVT_PS_S = FOP(38, FMT_S),
10039 OPC_CMP_F_S = FOP (48, FMT_S),
10040 OPC_CMP_UN_S = FOP (49, FMT_S),
10041 OPC_CMP_EQ_S = FOP (50, FMT_S),
10042 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10043 OPC_CMP_OLT_S = FOP (52, FMT_S),
10044 OPC_CMP_ULT_S = FOP (53, FMT_S),
10045 OPC_CMP_OLE_S = FOP (54, FMT_S),
10046 OPC_CMP_ULE_S = FOP (55, FMT_S),
10047 OPC_CMP_SF_S = FOP (56, FMT_S),
10048 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10049 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10050 OPC_CMP_NGL_S = FOP (59, FMT_S),
10051 OPC_CMP_LT_S = FOP (60, FMT_S),
10052 OPC_CMP_NGE_S = FOP (61, FMT_S),
10053 OPC_CMP_LE_S = FOP (62, FMT_S),
10054 OPC_CMP_NGT_S = FOP (63, FMT_S),
10055
10056 OPC_ADD_D = FOP(0, FMT_D),
10057 OPC_SUB_D = FOP(1, FMT_D),
10058 OPC_MUL_D = FOP(2, FMT_D),
10059 OPC_DIV_D = FOP(3, FMT_D),
10060 OPC_SQRT_D = FOP(4, FMT_D),
10061 OPC_ABS_D = FOP(5, FMT_D),
10062 OPC_MOV_D = FOP(6, FMT_D),
10063 OPC_NEG_D = FOP(7, FMT_D),
10064 OPC_ROUND_L_D = FOP(8, FMT_D),
10065 OPC_TRUNC_L_D = FOP(9, FMT_D),
10066 OPC_CEIL_L_D = FOP(10, FMT_D),
10067 OPC_FLOOR_L_D = FOP(11, FMT_D),
10068 OPC_ROUND_W_D = FOP(12, FMT_D),
10069 OPC_TRUNC_W_D = FOP(13, FMT_D),
10070 OPC_CEIL_W_D = FOP(14, FMT_D),
10071 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 10072 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
10073 OPC_MOVCF_D = FOP(17, FMT_D),
10074 OPC_MOVZ_D = FOP(18, FMT_D),
10075 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 10076 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
10077 OPC_RECIP_D = FOP(21, FMT_D),
10078 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
10079 OPC_SELNEZ_D = FOP(23, FMT_D),
10080 OPC_MADDF_D = FOP(24, FMT_D),
10081 OPC_MSUBF_D = FOP(25, FMT_D),
10082 OPC_RINT_D = FOP(26, FMT_D),
10083 OPC_CLASS_D = FOP(27, FMT_D),
10084 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 10085 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 10086 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 10087 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 10088 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 10089 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 10090 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
10091 OPC_RSQRT2_D = FOP(31, FMT_D),
10092 OPC_CVT_S_D = FOP(32, FMT_D),
10093 OPC_CVT_W_D = FOP(36, FMT_D),
10094 OPC_CVT_L_D = FOP(37, FMT_D),
10095 OPC_CMP_F_D = FOP (48, FMT_D),
10096 OPC_CMP_UN_D = FOP (49, FMT_D),
10097 OPC_CMP_EQ_D = FOP (50, FMT_D),
10098 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10099 OPC_CMP_OLT_D = FOP (52, FMT_D),
10100 OPC_CMP_ULT_D = FOP (53, FMT_D),
10101 OPC_CMP_OLE_D = FOP (54, FMT_D),
10102 OPC_CMP_ULE_D = FOP (55, FMT_D),
10103 OPC_CMP_SF_D = FOP (56, FMT_D),
10104 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10105 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10106 OPC_CMP_NGL_D = FOP (59, FMT_D),
10107 OPC_CMP_LT_D = FOP (60, FMT_D),
10108 OPC_CMP_NGE_D = FOP (61, FMT_D),
10109 OPC_CMP_LE_D = FOP (62, FMT_D),
10110 OPC_CMP_NGT_D = FOP (63, FMT_D),
10111
10112 OPC_CVT_S_W = FOP(32, FMT_W),
10113 OPC_CVT_D_W = FOP(33, FMT_W),
10114 OPC_CVT_S_L = FOP(32, FMT_L),
10115 OPC_CVT_D_L = FOP(33, FMT_L),
10116 OPC_CVT_PS_PW = FOP(38, FMT_W),
10117
10118 OPC_ADD_PS = FOP(0, FMT_PS),
10119 OPC_SUB_PS = FOP(1, FMT_PS),
10120 OPC_MUL_PS = FOP(2, FMT_PS),
10121 OPC_DIV_PS = FOP(3, FMT_PS),
10122 OPC_ABS_PS = FOP(5, FMT_PS),
10123 OPC_MOV_PS = FOP(6, FMT_PS),
10124 OPC_NEG_PS = FOP(7, FMT_PS),
10125 OPC_MOVCF_PS = FOP(17, FMT_PS),
10126 OPC_MOVZ_PS = FOP(18, FMT_PS),
10127 OPC_MOVN_PS = FOP(19, FMT_PS),
10128 OPC_ADDR_PS = FOP(24, FMT_PS),
10129 OPC_MULR_PS = FOP(26, FMT_PS),
10130 OPC_RECIP2_PS = FOP(28, FMT_PS),
10131 OPC_RECIP1_PS = FOP(29, FMT_PS),
10132 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10133 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10134
10135 OPC_CVT_S_PU = FOP(32, FMT_PS),
10136 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10137 OPC_CVT_S_PL = FOP(40, FMT_PS),
10138 OPC_PLL_PS = FOP(44, FMT_PS),
10139 OPC_PLU_PS = FOP(45, FMT_PS),
10140 OPC_PUL_PS = FOP(46, FMT_PS),
10141 OPC_PUU_PS = FOP(47, FMT_PS),
10142 OPC_CMP_F_PS = FOP (48, FMT_PS),
10143 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10144 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10145 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10146 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10147 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10148 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10149 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10150 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10151 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10152 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10153 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10154 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10155 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10156 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10157 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10158};
10159
3f493883
YK
10160enum r6_f_cmp_op {
10161 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10162 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10163 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10164 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10165 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10166 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10167 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10168 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10169 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10170 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10171 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10172 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10173 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10174 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10175 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10176 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10177 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10178 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10179 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10180 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10181 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10182 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10183
10184 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10185 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10186 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10187 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10188 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10189 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10190 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10191 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10192 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10193 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10194 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10195 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10196 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10197 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10198 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10199 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10200 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10201 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10202 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10203 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10204 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10205 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10206};
7a387fff 10207static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 10208{
72c3a3ee 10209 TCGv t0 = tcg_temp_new();
6ea83fed
FB
10210
10211 switch (opc) {
10212 case OPC_MFC1:
b6d96bed 10213 {
a7812ae4 10214 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10215
7c979afd 10216 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 10217 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10218 tcg_temp_free_i32(fp0);
6958549d 10219 }
6c5c1e20 10220 gen_store_gpr(t0, rt);
6ea83fed
FB
10221 break;
10222 case OPC_MTC1:
6c5c1e20 10223 gen_load_gpr(t0, rt);
b6d96bed 10224 {
a7812ae4 10225 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10226
10227 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10228 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 10229 tcg_temp_free_i32(fp0);
6958549d 10230 }
6ea83fed
FB
10231 break;
10232 case OPC_CFC1:
895c2d04 10233 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 10234 gen_store_gpr(t0, rt);
6ea83fed
FB
10235 break;
10236 case OPC_CTC1:
6c5c1e20 10237 gen_load_gpr(t0, rt);
9c708c7f 10238 save_cpu_state(ctx, 0);
736d120a
PJ
10239 {
10240 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10241
10242 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10243 tcg_temp_free_i32(fs_tmp);
10244 }
4cf8a45f 10245 /* Stop translation as we may have changed hflags */
eeb3bba8 10246 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 10247 break;
72c3a3ee 10248#if defined(TARGET_MIPS64)
9c2149c8 10249 case OPC_DMFC1:
72c3a3ee 10250 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 10251 gen_store_gpr(t0, rt);
5a5012ec 10252 break;
9c2149c8 10253 case OPC_DMTC1:
6c5c1e20 10254 gen_load_gpr(t0, rt);
72c3a3ee 10255 gen_store_fpr64(ctx, t0, fs);
5a5012ec 10256 break;
72c3a3ee 10257#endif
5a5012ec 10258 case OPC_MFHC1:
b6d96bed 10259 {
a7812ae4 10260 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10261
7f6613ce 10262 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 10263 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10264 tcg_temp_free_i32(fp0);
6958549d 10265 }
6c5c1e20 10266 gen_store_gpr(t0, rt);
5a5012ec
TS
10267 break;
10268 case OPC_MTHC1:
6c5c1e20 10269 gen_load_gpr(t0, rt);
b6d96bed 10270 {
a7812ae4 10271 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10272
10273 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 10274 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 10275 tcg_temp_free_i32(fp0);
6958549d 10276 }
5a5012ec 10277 break;
6ea83fed 10278 default:
9d68ac14 10279 MIPS_INVAL("cp1 move");
9c708c7f 10280 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10281 goto out;
6ea83fed 10282 }
6c5c1e20
TS
10283
10284 out:
10285 tcg_temp_free(t0);
6ea83fed
FB
10286}
10287
5a5012ec
TS
10288static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10289{
42a268c2 10290 TCGLabel *l1;
e214b9bb 10291 TCGCond cond;
af58f9ca
AJ
10292 TCGv_i32 t0;
10293
10294 if (rd == 0) {
10295 /* Treat as NOP. */
10296 return;
10297 }
6ea83fed 10298
e214b9bb 10299 if (tf)
e214b9bb 10300 cond = TCG_COND_EQ;
27848470
TS
10301 else
10302 cond = TCG_COND_NE;
10303
af58f9ca
AJ
10304 l1 = gen_new_label();
10305 t0 = tcg_temp_new_i32();
fa31af0e 10306 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 10307 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10308 tcg_temp_free_i32(t0);
af58f9ca
AJ
10309 if (rs == 0) {
10310 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10311 } else {
10312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10313 }
e214b9bb 10314 gen_set_label(l1);
5a5012ec
TS
10315}
10316
7c979afd
LA
10317static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10318 int tf)
a16336e4 10319{
a16336e4 10320 int cond;
cbc37b28 10321 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 10322 TCGLabel *l1 = gen_new_label();
a16336e4 10323
a16336e4
TS
10324 if (tf)
10325 cond = TCG_COND_EQ;
10326 else
10327 cond = TCG_COND_NE;
10328
fa31af0e 10329 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10330 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10331 gen_load_fpr32(ctx, t0, fs);
10332 gen_store_fpr32(ctx, t0, fd);
a16336e4 10333 gen_set_label(l1);
cbc37b28 10334 tcg_temp_free_i32(t0);
5a5012ec 10335}
a16336e4 10336
b6d96bed 10337static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 10338{
a16336e4 10339 int cond;
cbc37b28
AJ
10340 TCGv_i32 t0 = tcg_temp_new_i32();
10341 TCGv_i64 fp0;
42a268c2 10342 TCGLabel *l1 = gen_new_label();
a16336e4 10343
a16336e4
TS
10344 if (tf)
10345 cond = TCG_COND_EQ;
10346 else
10347 cond = TCG_COND_NE;
10348
fa31af0e 10349 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10350 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10351 tcg_temp_free_i32(t0);
11f94258 10352 fp0 = tcg_temp_new_i64();
9bf3eb2c 10353 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 10354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10355 tcg_temp_free_i64(fp0);
cbc37b28 10356 gen_set_label(l1);
a16336e4
TS
10357}
10358
7f6613ce
PJ
10359static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10360 int cc, int tf)
a16336e4
TS
10361{
10362 int cond;
cbc37b28 10363 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
10364 TCGLabel *l1 = gen_new_label();
10365 TCGLabel *l2 = gen_new_label();
a16336e4
TS
10366
10367 if (tf)
10368 cond = TCG_COND_EQ;
10369 else
10370 cond = TCG_COND_NE;
10371
fa31af0e 10372 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10373 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10374 gen_load_fpr32(ctx, t0, fs);
10375 gen_store_fpr32(ctx, t0, fd);
a16336e4 10376 gen_set_label(l1);
9bf3eb2c 10377
fa31af0e 10378 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 10379 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
10380 gen_load_fpr32h(ctx, t0, fs);
10381 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 10382 tcg_temp_free_i32(t0);
a16336e4 10383 gen_set_label(l2);
a16336e4
TS
10384}
10385
e7f16abb
LA
10386static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10387 int fs)
10388{
10389 TCGv_i32 t1 = tcg_const_i32(0);
10390 TCGv_i32 fp0 = tcg_temp_new_i32();
10391 TCGv_i32 fp1 = tcg_temp_new_i32();
10392 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10393 gen_load_fpr32(ctx, fp0, fd);
10394 gen_load_fpr32(ctx, fp1, ft);
10395 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
10396
10397 switch (op1) {
10398 case OPC_SEL_S:
10399 tcg_gen_andi_i32(fp0, fp0, 1);
10400 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10401 break;
10402 case OPC_SELEQZ_S:
10403 tcg_gen_andi_i32(fp1, fp1, 1);
10404 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10405 break;
10406 case OPC_SELNEZ_S:
10407 tcg_gen_andi_i32(fp1, fp1, 1);
10408 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10409 break;
10410 default:
10411 MIPS_INVAL("gen_sel_s");
9c708c7f 10412 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10413 break;
10414 }
10415
7c979afd 10416 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10417 tcg_temp_free_i32(fp2);
10418 tcg_temp_free_i32(fp1);
10419 tcg_temp_free_i32(fp0);
10420 tcg_temp_free_i32(t1);
10421}
10422
10423static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10424 int fs)
10425{
10426 TCGv_i64 t1 = tcg_const_i64(0);
10427 TCGv_i64 fp0 = tcg_temp_new_i64();
10428 TCGv_i64 fp1 = tcg_temp_new_i64();
10429 TCGv_i64 fp2 = tcg_temp_new_i64();
10430 gen_load_fpr64(ctx, fp0, fd);
10431 gen_load_fpr64(ctx, fp1, ft);
10432 gen_load_fpr64(ctx, fp2, fs);
10433
10434 switch (op1) {
10435 case OPC_SEL_D:
10436 tcg_gen_andi_i64(fp0, fp0, 1);
10437 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10438 break;
10439 case OPC_SELEQZ_D:
10440 tcg_gen_andi_i64(fp1, fp1, 1);
10441 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10442 break;
10443 case OPC_SELNEZ_D:
10444 tcg_gen_andi_i64(fp1, fp1, 1);
10445 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10446 break;
10447 default:
10448 MIPS_INVAL("gen_sel_d");
9c708c7f 10449 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10450 break;
10451 }
10452
10453 gen_store_fpr64(ctx, fp0, fd);
10454 tcg_temp_free_i64(fp2);
10455 tcg_temp_free_i64(fp1);
10456 tcg_temp_free_i64(fp0);
10457 tcg_temp_free_i64(t1);
10458}
6ea83fed 10459
bf4120ad 10460static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 10461 int ft, int fs, int fd, int cc)
6ea83fed 10462{
7a387fff 10463 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
10464 switch (op1) {
10465 case OPC_ADD_S:
b6d96bed 10466 {
a7812ae4
PB
10467 TCGv_i32 fp0 = tcg_temp_new_i32();
10468 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10469
7c979afd
LA
10470 gen_load_fpr32(ctx, fp0, fs);
10471 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10473 tcg_temp_free_i32(fp1);
7c979afd 10474 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10475 tcg_temp_free_i32(fp0);
b6d96bed 10476 }
5a5012ec 10477 break;
bf4120ad 10478 case OPC_SUB_S:
b6d96bed 10479 {
a7812ae4
PB
10480 TCGv_i32 fp0 = tcg_temp_new_i32();
10481 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10482
7c979afd
LA
10483 gen_load_fpr32(ctx, fp0, fs);
10484 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10485 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10486 tcg_temp_free_i32(fp1);
7c979afd 10487 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10488 tcg_temp_free_i32(fp0);
b6d96bed 10489 }
5a5012ec 10490 break;
bf4120ad 10491 case OPC_MUL_S:
b6d96bed 10492 {
a7812ae4
PB
10493 TCGv_i32 fp0 = tcg_temp_new_i32();
10494 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10495
7c979afd
LA
10496 gen_load_fpr32(ctx, fp0, fs);
10497 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10498 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10499 tcg_temp_free_i32(fp1);
7c979afd 10500 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10501 tcg_temp_free_i32(fp0);
b6d96bed 10502 }
5a5012ec 10503 break;
bf4120ad 10504 case OPC_DIV_S:
b6d96bed 10505 {
a7812ae4
PB
10506 TCGv_i32 fp0 = tcg_temp_new_i32();
10507 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10508
7c979afd
LA
10509 gen_load_fpr32(ctx, fp0, fs);
10510 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10511 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10512 tcg_temp_free_i32(fp1);
7c979afd 10513 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10514 tcg_temp_free_i32(fp0);
b6d96bed 10515 }
5a5012ec 10516 break;
bf4120ad 10517 case OPC_SQRT_S:
b6d96bed 10518 {
a7812ae4 10519 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10520
7c979afd 10521 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10522 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 10523 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10524 tcg_temp_free_i32(fp0);
b6d96bed 10525 }
5a5012ec 10526 break;
bf4120ad 10527 case OPC_ABS_S:
b6d96bed 10528 {
a7812ae4 10529 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10530
7c979afd 10531 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10532 if (ctx->abs2008) {
10533 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10534 } else {
10535 gen_helper_float_abs_s(fp0, fp0);
10536 }
7c979afd 10537 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10538 tcg_temp_free_i32(fp0);
b6d96bed 10539 }
5a5012ec 10540 break;
bf4120ad 10541 case OPC_MOV_S:
b6d96bed 10542 {
a7812ae4 10543 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10544
7c979afd
LA
10545 gen_load_fpr32(ctx, fp0, fs);
10546 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10547 tcg_temp_free_i32(fp0);
b6d96bed 10548 }
5a5012ec 10549 break;
bf4120ad 10550 case OPC_NEG_S:
b6d96bed 10551 {
a7812ae4 10552 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10553
7c979afd 10554 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10555 if (ctx->abs2008) {
10556 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10557 } else {
10558 gen_helper_float_chs_s(fp0, fp0);
10559 }
7c979afd 10560 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10561 tcg_temp_free_i32(fp0);
b6d96bed 10562 }
5a5012ec 10563 break;
bf4120ad 10564 case OPC_ROUND_L_S:
5e755519 10565 check_cp1_64bitmode(ctx);
b6d96bed 10566 {
a7812ae4
PB
10567 TCGv_i32 fp32 = tcg_temp_new_i32();
10568 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10569
7c979afd 10570 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10571 if (ctx->nan2008) {
10572 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10573 } else {
10574 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10575 }
a7812ae4 10576 tcg_temp_free_i32(fp32);
b6d96bed 10577 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10578 tcg_temp_free_i64(fp64);
b6d96bed 10579 }
5a5012ec 10580 break;
bf4120ad 10581 case OPC_TRUNC_L_S:
5e755519 10582 check_cp1_64bitmode(ctx);
b6d96bed 10583 {
a7812ae4
PB
10584 TCGv_i32 fp32 = tcg_temp_new_i32();
10585 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10586
7c979afd 10587 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10588 if (ctx->nan2008) {
10589 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10590 } else {
10591 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10592 }
a7812ae4 10593 tcg_temp_free_i32(fp32);
b6d96bed 10594 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10595 tcg_temp_free_i64(fp64);
b6d96bed 10596 }
5a5012ec 10597 break;
bf4120ad 10598 case OPC_CEIL_L_S:
5e755519 10599 check_cp1_64bitmode(ctx);
b6d96bed 10600 {
a7812ae4
PB
10601 TCGv_i32 fp32 = tcg_temp_new_i32();
10602 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10603
7c979afd 10604 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10605 if (ctx->nan2008) {
10606 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10607 } else {
10608 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10609 }
a7812ae4 10610 tcg_temp_free_i32(fp32);
b6d96bed 10611 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10612 tcg_temp_free_i64(fp64);
b6d96bed 10613 }
5a5012ec 10614 break;
bf4120ad 10615 case OPC_FLOOR_L_S:
5e755519 10616 check_cp1_64bitmode(ctx);
b6d96bed 10617 {
a7812ae4
PB
10618 TCGv_i32 fp32 = tcg_temp_new_i32();
10619 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10620
7c979afd 10621 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10622 if (ctx->nan2008) {
10623 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10624 } else {
10625 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10626 }
a7812ae4 10627 tcg_temp_free_i32(fp32);
b6d96bed 10628 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10629 tcg_temp_free_i64(fp64);
b6d96bed 10630 }
5a5012ec 10631 break;
bf4120ad 10632 case OPC_ROUND_W_S:
b6d96bed 10633 {
a7812ae4 10634 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10635
7c979afd 10636 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10637 if (ctx->nan2008) {
10638 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10639 } else {
10640 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10641 }
7c979afd 10642 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10643 tcg_temp_free_i32(fp0);
b6d96bed 10644 }
5a5012ec 10645 break;
bf4120ad 10646 case OPC_TRUNC_W_S:
b6d96bed 10647 {
a7812ae4 10648 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10649
7c979afd 10650 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10651 if (ctx->nan2008) {
10652 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10653 } else {
10654 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10655 }
7c979afd 10656 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10657 tcg_temp_free_i32(fp0);
b6d96bed 10658 }
5a5012ec 10659 break;
bf4120ad 10660 case OPC_CEIL_W_S:
b6d96bed 10661 {
a7812ae4 10662 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10663
7c979afd 10664 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10665 if (ctx->nan2008) {
10666 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10667 } else {
10668 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10669 }
7c979afd 10670 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10671 tcg_temp_free_i32(fp0);
b6d96bed 10672 }
5a5012ec 10673 break;
bf4120ad 10674 case OPC_FLOOR_W_S:
b6d96bed 10675 {
a7812ae4 10676 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10677
7c979afd 10678 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10679 if (ctx->nan2008) {
10680 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10681 } else {
10682 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10683 }
7c979afd 10684 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10685 tcg_temp_free_i32(fp0);
b6d96bed 10686 }
5a5012ec 10687 break;
e7f16abb
LA
10688 case OPC_SEL_S:
10689 check_insn(ctx, ISA_MIPS32R6);
10690 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10691 break;
10692 case OPC_SELEQZ_S:
10693 check_insn(ctx, ISA_MIPS32R6);
10694 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10695 break;
10696 case OPC_SELNEZ_S:
10697 check_insn(ctx, ISA_MIPS32R6);
10698 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 10699 break;
bf4120ad 10700 case OPC_MOVCF_S:
fecd2646 10701 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 10702 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10703 break;
bf4120ad 10704 case OPC_MOVZ_S:
fecd2646 10705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10706 {
42a268c2 10707 TCGLabel *l1 = gen_new_label();
c9297f4d 10708 TCGv_i32 fp0;
a16336e4 10709
c9297f4d
AJ
10710 if (ft != 0) {
10711 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10712 }
10713 fp0 = tcg_temp_new_i32();
7c979afd
LA
10714 gen_load_fpr32(ctx, fp0, fs);
10715 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10716 tcg_temp_free_i32(fp0);
a16336e4
TS
10717 gen_set_label(l1);
10718 }
5a5012ec 10719 break;
bf4120ad 10720 case OPC_MOVN_S:
fecd2646 10721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10722 {
42a268c2 10723 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10724 TCGv_i32 fp0;
10725
10726 if (ft != 0) {
10727 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10728 fp0 = tcg_temp_new_i32();
7c979afd
LA
10729 gen_load_fpr32(ctx, fp0, fs);
10730 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
10731 tcg_temp_free_i32(fp0);
10732 gen_set_label(l1);
10733 }
a16336e4 10734 }
5a5012ec 10735 break;
bf4120ad 10736 case OPC_RECIP_S:
b6d96bed 10737 {
a7812ae4 10738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10739
7c979afd 10740 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10741 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 10742 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10743 tcg_temp_free_i32(fp0);
b6d96bed 10744 }
57fa1fb3 10745 break;
bf4120ad 10746 case OPC_RSQRT_S:
b6d96bed 10747 {
a7812ae4 10748 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10749
7c979afd 10750 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10751 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 10752 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10753 tcg_temp_free_i32(fp0);
b6d96bed 10754 }
57fa1fb3 10755 break;
e7f16abb
LA
10756 case OPC_MADDF_S:
10757 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10758 {
a7812ae4
PB
10759 TCGv_i32 fp0 = tcg_temp_new_i32();
10760 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10761 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10762 gen_load_fpr32(ctx, fp0, fs);
10763 gen_load_fpr32(ctx, fp1, ft);
10764 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10765 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10766 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 10767 tcg_temp_free_i32(fp2);
a7812ae4 10768 tcg_temp_free_i32(fp1);
a7812ae4 10769 tcg_temp_free_i32(fp0);
b6d96bed 10770 }
57fa1fb3 10771 break;
e7f16abb
LA
10772 case OPC_MSUBF_S:
10773 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10774 {
a7812ae4 10775 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
10776 TCGv_i32 fp1 = tcg_temp_new_i32();
10777 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10778 gen_load_fpr32(ctx, fp0, fs);
10779 gen_load_fpr32(ctx, fp1, ft);
10780 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10781 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10782 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10783 tcg_temp_free_i32(fp2);
10784 tcg_temp_free_i32(fp1);
a7812ae4 10785 tcg_temp_free_i32(fp0);
b6d96bed 10786 }
57fa1fb3 10787 break;
e7f16abb
LA
10788 case OPC_RINT_S:
10789 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10790 {
a7812ae4 10791 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10792 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10793 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 10794 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10795 tcg_temp_free_i32(fp0);
b6d96bed 10796 }
57fa1fb3 10797 break;
e7f16abb
LA
10798 case OPC_CLASS_S:
10799 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10800 {
e7f16abb 10801 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10802 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 10803 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 10804 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 10805 tcg_temp_free_i32(fp0);
e7f16abb
LA
10806 }
10807 break;
10808 case OPC_MIN_S: /* OPC_RECIP2_S */
10809 if (ctx->insn_flags & ISA_MIPS32R6) {
10810 /* OPC_MIN_S */
a7812ae4
PB
10811 TCGv_i32 fp0 = tcg_temp_new_i32();
10812 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10813 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10814 gen_load_fpr32(ctx, fp0, fs);
10815 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10816 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 10817 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10818 tcg_temp_free_i32(fp2);
10819 tcg_temp_free_i32(fp1);
10820 tcg_temp_free_i32(fp0);
e7f16abb
LA
10821 } else {
10822 /* OPC_RECIP2_S */
10823 check_cp1_64bitmode(ctx);
10824 {
10825 TCGv_i32 fp0 = tcg_temp_new_i32();
10826 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10827
7c979afd
LA
10828 gen_load_fpr32(ctx, fp0, fs);
10829 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10830 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10831 tcg_temp_free_i32(fp1);
7c979afd 10832 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10833 tcg_temp_free_i32(fp0);
10834 }
e7f16abb
LA
10835 }
10836 break;
10837 case OPC_MINA_S: /* OPC_RECIP1_S */
10838 if (ctx->insn_flags & ISA_MIPS32R6) {
10839 /* OPC_MINA_S */
10840 TCGv_i32 fp0 = tcg_temp_new_i32();
10841 TCGv_i32 fp1 = tcg_temp_new_i32();
10842 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10843 gen_load_fpr32(ctx, fp0, fs);
10844 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10845 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 10846 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10847 tcg_temp_free_i32(fp2);
10848 tcg_temp_free_i32(fp1);
10849 tcg_temp_free_i32(fp0);
e7f16abb
LA
10850 } else {
10851 /* OPC_RECIP1_S */
10852 check_cp1_64bitmode(ctx);
10853 {
10854 TCGv_i32 fp0 = tcg_temp_new_i32();
10855
7c979afd 10856 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10857 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 10858 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10859 tcg_temp_free_i32(fp0);
10860 }
e7f16abb
LA
10861 }
10862 break;
10863 case OPC_MAX_S: /* OPC_RSQRT1_S */
10864 if (ctx->insn_flags & ISA_MIPS32R6) {
10865 /* OPC_MAX_S */
10866 TCGv_i32 fp0 = tcg_temp_new_i32();
10867 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10868 gen_load_fpr32(ctx, fp0, fs);
10869 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10870 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 10871 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
10872 tcg_temp_free_i32(fp1);
10873 tcg_temp_free_i32(fp0);
e7f16abb
LA
10874 } else {
10875 /* OPC_RSQRT1_S */
10876 check_cp1_64bitmode(ctx);
10877 {
10878 TCGv_i32 fp0 = tcg_temp_new_i32();
10879
7c979afd 10880 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10881 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 10882 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10883 tcg_temp_free_i32(fp0);
10884 }
e7f16abb
LA
10885 }
10886 break;
10887 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10888 if (ctx->insn_flags & ISA_MIPS32R6) {
10889 /* OPC_MAXA_S */
10890 TCGv_i32 fp0 = tcg_temp_new_i32();
10891 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10892 gen_load_fpr32(ctx, fp0, fs);
10893 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10894 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 10895 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 10896 tcg_temp_free_i32(fp1);
a7812ae4 10897 tcg_temp_free_i32(fp0);
e7f16abb
LA
10898 } else {
10899 /* OPC_RSQRT2_S */
10900 check_cp1_64bitmode(ctx);
10901 {
10902 TCGv_i32 fp0 = tcg_temp_new_i32();
10903 TCGv_i32 fp1 = tcg_temp_new_i32();
10904
7c979afd
LA
10905 gen_load_fpr32(ctx, fp0, fs);
10906 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10907 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10908 tcg_temp_free_i32(fp1);
7c979afd 10909 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10910 tcg_temp_free_i32(fp0);
10911 }
b6d96bed 10912 }
57fa1fb3 10913 break;
bf4120ad 10914 case OPC_CVT_D_S:
5e755519 10915 check_cp1_registers(ctx, fd);
b6d96bed 10916 {
a7812ae4
PB
10917 TCGv_i32 fp32 = tcg_temp_new_i32();
10918 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10919
7c979afd 10920 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10921 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 10922 tcg_temp_free_i32(fp32);
b6d96bed 10923 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10924 tcg_temp_free_i64(fp64);
b6d96bed 10925 }
5a5012ec 10926 break;
bf4120ad 10927 case OPC_CVT_W_S:
b6d96bed 10928 {
a7812ae4 10929 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10930
7c979afd 10931 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10932 if (ctx->nan2008) {
10933 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10934 } else {
10935 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10936 }
7c979afd 10937 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10938 tcg_temp_free_i32(fp0);
b6d96bed 10939 }
5a5012ec 10940 break;
bf4120ad 10941 case OPC_CVT_L_S:
5e755519 10942 check_cp1_64bitmode(ctx);
b6d96bed 10943 {
a7812ae4
PB
10944 TCGv_i32 fp32 = tcg_temp_new_i32();
10945 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10946
7c979afd 10947 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10948 if (ctx->nan2008) {
10949 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10950 } else {
10951 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10952 }
a7812ae4 10953 tcg_temp_free_i32(fp32);
b6d96bed 10954 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10955 tcg_temp_free_i64(fp64);
b6d96bed 10956 }
5a5012ec 10957 break;
bf4120ad 10958 case OPC_CVT_PS_S:
e29c9628 10959 check_ps(ctx);
b6d96bed 10960 {
a7812ae4
PB
10961 TCGv_i64 fp64 = tcg_temp_new_i64();
10962 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10963 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 10964
7c979afd
LA
10965 gen_load_fpr32(ctx, fp32_0, fs);
10966 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 10967 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
10968 tcg_temp_free_i32(fp32_1);
10969 tcg_temp_free_i32(fp32_0);
36aa55dc 10970 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10971 tcg_temp_free_i64(fp64);
b6d96bed 10972 }
5a5012ec 10973 break;
bf4120ad
NF
10974 case OPC_CMP_F_S:
10975 case OPC_CMP_UN_S:
10976 case OPC_CMP_EQ_S:
10977 case OPC_CMP_UEQ_S:
10978 case OPC_CMP_OLT_S:
10979 case OPC_CMP_ULT_S:
10980 case OPC_CMP_OLE_S:
10981 case OPC_CMP_ULE_S:
10982 case OPC_CMP_SF_S:
10983 case OPC_CMP_NGLE_S:
10984 case OPC_CMP_SEQ_S:
10985 case OPC_CMP_NGL_S:
10986 case OPC_CMP_LT_S:
10987 case OPC_CMP_NGE_S:
10988 case OPC_CMP_LE_S:
10989 case OPC_CMP_NGT_S:
fecd2646 10990 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10991 if (ctx->opcode & (1 << 6)) {
10992 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
10993 } else {
10994 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 10995 }
5a5012ec 10996 break;
bf4120ad 10997 case OPC_ADD_D:
5e755519 10998 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10999 {
a7812ae4
PB
11000 TCGv_i64 fp0 = tcg_temp_new_i64();
11001 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11002
11003 gen_load_fpr64(ctx, fp0, fs);
11004 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11005 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11006 tcg_temp_free_i64(fp1);
b6d96bed 11007 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11008 tcg_temp_free_i64(fp0);
b6d96bed 11009 }
6ea83fed 11010 break;
bf4120ad 11011 case OPC_SUB_D:
5e755519 11012 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11013 {
a7812ae4
PB
11014 TCGv_i64 fp0 = tcg_temp_new_i64();
11015 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11016
11017 gen_load_fpr64(ctx, fp0, fs);
11018 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11019 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11020 tcg_temp_free_i64(fp1);
b6d96bed 11021 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11022 tcg_temp_free_i64(fp0);
b6d96bed 11023 }
6ea83fed 11024 break;
bf4120ad 11025 case OPC_MUL_D:
5e755519 11026 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11027 {
a7812ae4
PB
11028 TCGv_i64 fp0 = tcg_temp_new_i64();
11029 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11030
11031 gen_load_fpr64(ctx, fp0, fs);
11032 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11033 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11034 tcg_temp_free_i64(fp1);
b6d96bed 11035 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11036 tcg_temp_free_i64(fp0);
b6d96bed 11037 }
6ea83fed 11038 break;
bf4120ad 11039 case OPC_DIV_D:
5e755519 11040 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11041 {
a7812ae4
PB
11042 TCGv_i64 fp0 = tcg_temp_new_i64();
11043 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11044
11045 gen_load_fpr64(ctx, fp0, fs);
11046 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11047 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11048 tcg_temp_free_i64(fp1);
b6d96bed 11049 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11050 tcg_temp_free_i64(fp0);
b6d96bed 11051 }
6ea83fed 11052 break;
bf4120ad 11053 case OPC_SQRT_D:
5e755519 11054 check_cp1_registers(ctx, fs | fd);
b6d96bed 11055 {
a7812ae4 11056 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11057
11058 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11059 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 11060 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11061 tcg_temp_free_i64(fp0);
b6d96bed 11062 }
6ea83fed 11063 break;
bf4120ad 11064 case OPC_ABS_D:
5e755519 11065 check_cp1_registers(ctx, fs | fd);
b6d96bed 11066 {
a7812ae4 11067 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11068
11069 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11070 if (ctx->abs2008) {
11071 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11072 } else {
11073 gen_helper_float_abs_d(fp0, fp0);
11074 }
b6d96bed 11075 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11076 tcg_temp_free_i64(fp0);
b6d96bed 11077 }
6ea83fed 11078 break;
bf4120ad 11079 case OPC_MOV_D:
5e755519 11080 check_cp1_registers(ctx, fs | fd);
b6d96bed 11081 {
a7812ae4 11082 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11083
11084 gen_load_fpr64(ctx, fp0, fs);
11085 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11086 tcg_temp_free_i64(fp0);
b6d96bed 11087 }
6ea83fed 11088 break;
bf4120ad 11089 case OPC_NEG_D:
5e755519 11090 check_cp1_registers(ctx, fs | fd);
b6d96bed 11091 {
a7812ae4 11092 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11093
11094 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11095 if (ctx->abs2008) {
11096 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11097 } else {
11098 gen_helper_float_chs_d(fp0, fp0);
11099 }
b6d96bed 11100 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11101 tcg_temp_free_i64(fp0);
b6d96bed 11102 }
6ea83fed 11103 break;
bf4120ad 11104 case OPC_ROUND_L_D:
5e755519 11105 check_cp1_64bitmode(ctx);
b6d96bed 11106 {
a7812ae4 11107 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11108
11109 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11110 if (ctx->nan2008) {
11111 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11112 } else {
11113 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11114 }
b6d96bed 11115 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11116 tcg_temp_free_i64(fp0);
b6d96bed 11117 }
5a5012ec 11118 break;
bf4120ad 11119 case OPC_TRUNC_L_D:
5e755519 11120 check_cp1_64bitmode(ctx);
b6d96bed 11121 {
a7812ae4 11122 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11123
11124 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11125 if (ctx->nan2008) {
11126 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11127 } else {
11128 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11129 }
b6d96bed 11130 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11131 tcg_temp_free_i64(fp0);
b6d96bed 11132 }
5a5012ec 11133 break;
bf4120ad 11134 case OPC_CEIL_L_D:
5e755519 11135 check_cp1_64bitmode(ctx);
b6d96bed 11136 {
a7812ae4 11137 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11138
11139 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11140 if (ctx->nan2008) {
11141 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11142 } else {
11143 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11144 }
b6d96bed 11145 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11146 tcg_temp_free_i64(fp0);
b6d96bed 11147 }
5a5012ec 11148 break;
bf4120ad 11149 case OPC_FLOOR_L_D:
5e755519 11150 check_cp1_64bitmode(ctx);
b6d96bed 11151 {
a7812ae4 11152 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11153
11154 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11155 if (ctx->nan2008) {
11156 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11157 } else {
11158 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11159 }
b6d96bed 11160 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11161 tcg_temp_free_i64(fp0);
b6d96bed 11162 }
5a5012ec 11163 break;
bf4120ad 11164 case OPC_ROUND_W_D:
5e755519 11165 check_cp1_registers(ctx, fs);
b6d96bed 11166 {
a7812ae4
PB
11167 TCGv_i32 fp32 = tcg_temp_new_i32();
11168 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11169
11170 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11171 if (ctx->nan2008) {
11172 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11173 } else {
11174 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11175 }
a7812ae4 11176 tcg_temp_free_i64(fp64);
7c979afd 11177 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11178 tcg_temp_free_i32(fp32);
b6d96bed 11179 }
6ea83fed 11180 break;
bf4120ad 11181 case OPC_TRUNC_W_D:
5e755519 11182 check_cp1_registers(ctx, fs);
b6d96bed 11183 {
a7812ae4
PB
11184 TCGv_i32 fp32 = tcg_temp_new_i32();
11185 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11186
11187 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11188 if (ctx->nan2008) {
11189 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11190 } else {
11191 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11192 }
a7812ae4 11193 tcg_temp_free_i64(fp64);
7c979afd 11194 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11195 tcg_temp_free_i32(fp32);
b6d96bed 11196 }
6ea83fed 11197 break;
bf4120ad 11198 case OPC_CEIL_W_D:
5e755519 11199 check_cp1_registers(ctx, fs);
b6d96bed 11200 {
a7812ae4
PB
11201 TCGv_i32 fp32 = tcg_temp_new_i32();
11202 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11203
11204 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11205 if (ctx->nan2008) {
11206 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11207 } else {
11208 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11209 }
a7812ae4 11210 tcg_temp_free_i64(fp64);
7c979afd 11211 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11212 tcg_temp_free_i32(fp32);
b6d96bed 11213 }
6ea83fed 11214 break;
bf4120ad 11215 case OPC_FLOOR_W_D:
5e755519 11216 check_cp1_registers(ctx, fs);
b6d96bed 11217 {
a7812ae4
PB
11218 TCGv_i32 fp32 = tcg_temp_new_i32();
11219 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11220
11221 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11222 if (ctx->nan2008) {
11223 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11224 } else {
11225 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11226 }
a7812ae4 11227 tcg_temp_free_i64(fp64);
7c979afd 11228 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11229 tcg_temp_free_i32(fp32);
b6d96bed 11230 }
6ea83fed 11231 break;
e7f16abb
LA
11232 case OPC_SEL_D:
11233 check_insn(ctx, ISA_MIPS32R6);
11234 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11235 break;
11236 case OPC_SELEQZ_D:
11237 check_insn(ctx, ISA_MIPS32R6);
11238 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11239 break;
11240 case OPC_SELNEZ_D:
11241 check_insn(ctx, ISA_MIPS32R6);
11242 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 11243 break;
bf4120ad 11244 case OPC_MOVCF_D:
fecd2646 11245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 11246 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 11247 break;
bf4120ad 11248 case OPC_MOVZ_D:
fecd2646 11249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11250 {
42a268c2 11251 TCGLabel *l1 = gen_new_label();
c9297f4d 11252 TCGv_i64 fp0;
a16336e4 11253
c9297f4d
AJ
11254 if (ft != 0) {
11255 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11256 }
11257 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11258 gen_load_fpr64(ctx, fp0, fs);
11259 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11260 tcg_temp_free_i64(fp0);
a16336e4
TS
11261 gen_set_label(l1);
11262 }
5a5012ec 11263 break;
bf4120ad 11264 case OPC_MOVN_D:
fecd2646 11265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11266 {
42a268c2 11267 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11268 TCGv_i64 fp0;
11269
11270 if (ft != 0) {
11271 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11272 fp0 = tcg_temp_new_i64();
11273 gen_load_fpr64(ctx, fp0, fs);
11274 gen_store_fpr64(ctx, fp0, fd);
11275 tcg_temp_free_i64(fp0);
11276 gen_set_label(l1);
11277 }
a16336e4 11278 }
6ea83fed 11279 break;
bf4120ad 11280 case OPC_RECIP_D:
ca6c7803 11281 check_cp1_registers(ctx, fs | fd);
b6d96bed 11282 {
a7812ae4 11283 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11284
11285 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11286 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 11287 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11288 tcg_temp_free_i64(fp0);
b6d96bed 11289 }
57fa1fb3 11290 break;
bf4120ad 11291 case OPC_RSQRT_D:
ca6c7803 11292 check_cp1_registers(ctx, fs | fd);
b6d96bed 11293 {
a7812ae4 11294 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11295
11296 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11297 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 11298 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11299 tcg_temp_free_i64(fp0);
b6d96bed 11300 }
57fa1fb3 11301 break;
e7f16abb
LA
11302 case OPC_MADDF_D:
11303 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11304 {
a7812ae4
PB
11305 TCGv_i64 fp0 = tcg_temp_new_i64();
11306 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 11307 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11308 gen_load_fpr64(ctx, fp0, fs);
11309 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11310 gen_load_fpr64(ctx, fp2, fd);
11311 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11312 gen_store_fpr64(ctx, fp2, fd);
11313 tcg_temp_free_i64(fp2);
a7812ae4 11314 tcg_temp_free_i64(fp1);
a7812ae4 11315 tcg_temp_free_i64(fp0);
b6d96bed 11316 }
57fa1fb3 11317 break;
e7f16abb
LA
11318 case OPC_MSUBF_D:
11319 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11320 {
a7812ae4 11321 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
11322 TCGv_i64 fp1 = tcg_temp_new_i64();
11323 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 11324 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
11325 gen_load_fpr64(ctx, fp1, ft);
11326 gen_load_fpr64(ctx, fp2, fd);
11327 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11328 gen_store_fpr64(ctx, fp2, fd);
11329 tcg_temp_free_i64(fp2);
11330 tcg_temp_free_i64(fp1);
a7812ae4 11331 tcg_temp_free_i64(fp0);
b6d96bed 11332 }
57fa1fb3 11333 break;
e7f16abb
LA
11334 case OPC_RINT_D:
11335 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11336 {
a7812ae4 11337 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11338 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 11339 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 11340 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11341 tcg_temp_free_i64(fp0);
b6d96bed 11342 }
57fa1fb3 11343 break;
e7f16abb
LA
11344 case OPC_CLASS_D:
11345 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11346 {
e7f16abb
LA
11347 TCGv_i64 fp0 = tcg_temp_new_i64();
11348 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 11349 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
11350 gen_store_fpr64(ctx, fp0, fd);
11351 tcg_temp_free_i64(fp0);
e7f16abb
LA
11352 }
11353 break;
11354 case OPC_MIN_D: /* OPC_RECIP2_D */
11355 if (ctx->insn_flags & ISA_MIPS32R6) {
11356 /* OPC_MIN_D */
a7812ae4
PB
11357 TCGv_i64 fp0 = tcg_temp_new_i64();
11358 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
11359 gen_load_fpr64(ctx, fp0, fs);
11360 gen_load_fpr64(ctx, fp1, ft);
11361 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11362 gen_store_fpr64(ctx, fp1, fd);
11363 tcg_temp_free_i64(fp1);
11364 tcg_temp_free_i64(fp0);
e7f16abb
LA
11365 } else {
11366 /* OPC_RECIP2_D */
11367 check_cp1_64bitmode(ctx);
11368 {
11369 TCGv_i64 fp0 = tcg_temp_new_i64();
11370 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 11371
e7f16abb
LA
11372 gen_load_fpr64(ctx, fp0, fs);
11373 gen_load_fpr64(ctx, fp1, ft);
11374 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11375 tcg_temp_free_i64(fp1);
11376 gen_store_fpr64(ctx, fp0, fd);
11377 tcg_temp_free_i64(fp0);
11378 }
e7f16abb
LA
11379 }
11380 break;
11381 case OPC_MINA_D: /* OPC_RECIP1_D */
11382 if (ctx->insn_flags & ISA_MIPS32R6) {
11383 /* OPC_MINA_D */
11384 TCGv_i64 fp0 = tcg_temp_new_i64();
11385 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11386 gen_load_fpr64(ctx, fp0, fs);
11387 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11388 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11389 gen_store_fpr64(ctx, fp1, fd);
11390 tcg_temp_free_i64(fp1);
11391 tcg_temp_free_i64(fp0);
e7f16abb
LA
11392 } else {
11393 /* OPC_RECIP1_D */
11394 check_cp1_64bitmode(ctx);
11395 {
11396 TCGv_i64 fp0 = tcg_temp_new_i64();
11397
11398 gen_load_fpr64(ctx, fp0, fs);
11399 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11400 gen_store_fpr64(ctx, fp0, fd);
11401 tcg_temp_free_i64(fp0);
11402 }
e7f16abb
LA
11403 }
11404 break;
11405 case OPC_MAX_D: /* OPC_RSQRT1_D */
11406 if (ctx->insn_flags & ISA_MIPS32R6) {
11407 /* OPC_MAX_D */
11408 TCGv_i64 fp0 = tcg_temp_new_i64();
11409 TCGv_i64 fp1 = tcg_temp_new_i64();
11410 gen_load_fpr64(ctx, fp0, fs);
11411 gen_load_fpr64(ctx, fp1, ft);
11412 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11413 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 11414 tcg_temp_free_i64(fp1);
a7812ae4 11415 tcg_temp_free_i64(fp0);
e7f16abb
LA
11416 } else {
11417 /* OPC_RSQRT1_D */
11418 check_cp1_64bitmode(ctx);
11419 {
11420 TCGv_i64 fp0 = tcg_temp_new_i64();
11421
11422 gen_load_fpr64(ctx, fp0, fs);
11423 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11424 gen_store_fpr64(ctx, fp0, fd);
11425 tcg_temp_free_i64(fp0);
11426 }
e7f16abb
LA
11427 }
11428 break;
11429 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11430 if (ctx->insn_flags & ISA_MIPS32R6) {
11431 /* OPC_MAXA_D */
11432 TCGv_i64 fp0 = tcg_temp_new_i64();
11433 TCGv_i64 fp1 = tcg_temp_new_i64();
11434 gen_load_fpr64(ctx, fp0, fs);
11435 gen_load_fpr64(ctx, fp1, ft);
11436 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11437 gen_store_fpr64(ctx, fp1, fd);
11438 tcg_temp_free_i64(fp1);
11439 tcg_temp_free_i64(fp0);
e7f16abb
LA
11440 } else {
11441 /* OPC_RSQRT2_D */
11442 check_cp1_64bitmode(ctx);
11443 {
11444 TCGv_i64 fp0 = tcg_temp_new_i64();
11445 TCGv_i64 fp1 = tcg_temp_new_i64();
11446
11447 gen_load_fpr64(ctx, fp0, fs);
11448 gen_load_fpr64(ctx, fp1, ft);
11449 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11450 tcg_temp_free_i64(fp1);
11451 gen_store_fpr64(ctx, fp0, fd);
11452 tcg_temp_free_i64(fp0);
11453 }
b6d96bed 11454 }
57fa1fb3 11455 break;
bf4120ad
NF
11456 case OPC_CMP_F_D:
11457 case OPC_CMP_UN_D:
11458 case OPC_CMP_EQ_D:
11459 case OPC_CMP_UEQ_D:
11460 case OPC_CMP_OLT_D:
11461 case OPC_CMP_ULT_D:
11462 case OPC_CMP_OLE_D:
11463 case OPC_CMP_ULE_D:
11464 case OPC_CMP_SF_D:
11465 case OPC_CMP_NGLE_D:
11466 case OPC_CMP_SEQ_D:
11467 case OPC_CMP_NGL_D:
11468 case OPC_CMP_LT_D:
11469 case OPC_CMP_NGE_D:
11470 case OPC_CMP_LE_D:
11471 case OPC_CMP_NGT_D:
fecd2646 11472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11473 if (ctx->opcode & (1 << 6)) {
11474 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
11475 } else {
11476 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 11477 }
6ea83fed 11478 break;
bf4120ad 11479 case OPC_CVT_S_D:
5e755519 11480 check_cp1_registers(ctx, fs);
b6d96bed 11481 {
a7812ae4
PB
11482 TCGv_i32 fp32 = tcg_temp_new_i32();
11483 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11484
11485 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11486 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 11487 tcg_temp_free_i64(fp64);
7c979afd 11488 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11489 tcg_temp_free_i32(fp32);
b6d96bed 11490 }
5a5012ec 11491 break;
bf4120ad 11492 case OPC_CVT_W_D:
5e755519 11493 check_cp1_registers(ctx, fs);
b6d96bed 11494 {
a7812ae4
PB
11495 TCGv_i32 fp32 = tcg_temp_new_i32();
11496 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11497
11498 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11499 if (ctx->nan2008) {
11500 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11501 } else {
11502 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11503 }
a7812ae4 11504 tcg_temp_free_i64(fp64);
7c979afd 11505 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11506 tcg_temp_free_i32(fp32);
b6d96bed 11507 }
5a5012ec 11508 break;
bf4120ad 11509 case OPC_CVT_L_D:
5e755519 11510 check_cp1_64bitmode(ctx);
b6d96bed 11511 {
a7812ae4 11512 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11513
11514 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11515 if (ctx->nan2008) {
11516 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11517 } else {
11518 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11519 }
b6d96bed 11520 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11521 tcg_temp_free_i64(fp0);
b6d96bed 11522 }
5a5012ec 11523 break;
bf4120ad 11524 case OPC_CVT_S_W:
b6d96bed 11525 {
a7812ae4 11526 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11527
7c979afd 11528 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11529 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 11530 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11531 tcg_temp_free_i32(fp0);
b6d96bed 11532 }
6ea83fed 11533 break;
bf4120ad 11534 case OPC_CVT_D_W:
5e755519 11535 check_cp1_registers(ctx, fd);
b6d96bed 11536 {
a7812ae4
PB
11537 TCGv_i32 fp32 = tcg_temp_new_i32();
11538 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11539
7c979afd 11540 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11541 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11542 tcg_temp_free_i32(fp32);
b6d96bed 11543 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11544 tcg_temp_free_i64(fp64);
b6d96bed 11545 }
5a5012ec 11546 break;
bf4120ad 11547 case OPC_CVT_S_L:
5e755519 11548 check_cp1_64bitmode(ctx);
b6d96bed 11549 {
a7812ae4
PB
11550 TCGv_i32 fp32 = tcg_temp_new_i32();
11551 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11552
11553 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11554 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11555 tcg_temp_free_i64(fp64);
7c979afd 11556 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11557 tcg_temp_free_i32(fp32);
b6d96bed 11558 }
5a5012ec 11559 break;
bf4120ad 11560 case OPC_CVT_D_L:
5e755519 11561 check_cp1_64bitmode(ctx);
b6d96bed 11562 {
a7812ae4 11563 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11564
11565 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11566 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11567 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11568 tcg_temp_free_i64(fp0);
b6d96bed 11569 }
5a5012ec 11570 break;
bf4120ad 11571 case OPC_CVT_PS_PW:
e29c9628 11572 check_ps(ctx);
b6d96bed 11573 {
a7812ae4 11574 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11575
11576 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11577 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11578 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11579 tcg_temp_free_i64(fp0);
b6d96bed 11580 }
5a5012ec 11581 break;
bf4120ad 11582 case OPC_ADD_PS:
e29c9628 11583 check_ps(ctx);
b6d96bed 11584 {
a7812ae4
PB
11585 TCGv_i64 fp0 = tcg_temp_new_i64();
11586 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11587
11588 gen_load_fpr64(ctx, fp0, fs);
11589 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11590 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11591 tcg_temp_free_i64(fp1);
b6d96bed 11592 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11593 tcg_temp_free_i64(fp0);
b6d96bed 11594 }
6ea83fed 11595 break;
bf4120ad 11596 case OPC_SUB_PS:
e29c9628 11597 check_ps(ctx);
b6d96bed 11598 {
a7812ae4
PB
11599 TCGv_i64 fp0 = tcg_temp_new_i64();
11600 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11601
11602 gen_load_fpr64(ctx, fp0, fs);
11603 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11604 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11605 tcg_temp_free_i64(fp1);
b6d96bed 11606 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11607 tcg_temp_free_i64(fp0);
b6d96bed 11608 }
6ea83fed 11609 break;
bf4120ad 11610 case OPC_MUL_PS:
e29c9628 11611 check_ps(ctx);
b6d96bed 11612 {
a7812ae4
PB
11613 TCGv_i64 fp0 = tcg_temp_new_i64();
11614 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11615
11616 gen_load_fpr64(ctx, fp0, fs);
11617 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11618 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11619 tcg_temp_free_i64(fp1);
b6d96bed 11620 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11621 tcg_temp_free_i64(fp0);
b6d96bed 11622 }
6ea83fed 11623 break;
bf4120ad 11624 case OPC_ABS_PS:
e29c9628 11625 check_ps(ctx);
b6d96bed 11626 {
a7812ae4 11627 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11628
11629 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11630 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11631 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11632 tcg_temp_free_i64(fp0);
b6d96bed 11633 }
6ea83fed 11634 break;
bf4120ad 11635 case OPC_MOV_PS:
e29c9628 11636 check_ps(ctx);
b6d96bed 11637 {
a7812ae4 11638 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11639
11640 gen_load_fpr64(ctx, fp0, fs);
11641 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11642 tcg_temp_free_i64(fp0);
b6d96bed 11643 }
6ea83fed 11644 break;
bf4120ad 11645 case OPC_NEG_PS:
e29c9628 11646 check_ps(ctx);
b6d96bed 11647 {
a7812ae4 11648 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11649
11650 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11651 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11652 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11653 tcg_temp_free_i64(fp0);
b6d96bed 11654 }
6ea83fed 11655 break;
bf4120ad 11656 case OPC_MOVCF_PS:
e29c9628 11657 check_ps(ctx);
7f6613ce 11658 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11659 break;
bf4120ad 11660 case OPC_MOVZ_PS:
e29c9628 11661 check_ps(ctx);
a16336e4 11662 {
42a268c2 11663 TCGLabel *l1 = gen_new_label();
30a3848b 11664 TCGv_i64 fp0;
a16336e4 11665
c9297f4d
AJ
11666 if (ft != 0)
11667 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11668 fp0 = tcg_temp_new_i64();
11669 gen_load_fpr64(ctx, fp0, fs);
11670 gen_store_fpr64(ctx, fp0, fd);
11671 tcg_temp_free_i64(fp0);
a16336e4
TS
11672 gen_set_label(l1);
11673 }
6ea83fed 11674 break;
bf4120ad 11675 case OPC_MOVN_PS:
e29c9628 11676 check_ps(ctx);
a16336e4 11677 {
42a268c2 11678 TCGLabel *l1 = gen_new_label();
30a3848b 11679 TCGv_i64 fp0;
c9297f4d
AJ
11680
11681 if (ft != 0) {
11682 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11683 fp0 = tcg_temp_new_i64();
11684 gen_load_fpr64(ctx, fp0, fs);
11685 gen_store_fpr64(ctx, fp0, fd);
11686 tcg_temp_free_i64(fp0);
11687 gen_set_label(l1);
11688 }
a16336e4 11689 }
6ea83fed 11690 break;
bf4120ad 11691 case OPC_ADDR_PS:
e29c9628 11692 check_ps(ctx);
b6d96bed 11693 {
a7812ae4
PB
11694 TCGv_i64 fp0 = tcg_temp_new_i64();
11695 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11696
11697 gen_load_fpr64(ctx, fp0, ft);
11698 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11699 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11700 tcg_temp_free_i64(fp1);
b6d96bed 11701 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11702 tcg_temp_free_i64(fp0);
b6d96bed 11703 }
fbcc6828 11704 break;
bf4120ad 11705 case OPC_MULR_PS:
e29c9628 11706 check_ps(ctx);
b6d96bed 11707 {
a7812ae4
PB
11708 TCGv_i64 fp0 = tcg_temp_new_i64();
11709 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11710
11711 gen_load_fpr64(ctx, fp0, ft);
11712 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11713 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11714 tcg_temp_free_i64(fp1);
b6d96bed 11715 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11716 tcg_temp_free_i64(fp0);
b6d96bed 11717 }
57fa1fb3 11718 break;
bf4120ad 11719 case OPC_RECIP2_PS:
e29c9628 11720 check_ps(ctx);
b6d96bed 11721 {
a7812ae4
PB
11722 TCGv_i64 fp0 = tcg_temp_new_i64();
11723 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11724
11725 gen_load_fpr64(ctx, fp0, fs);
d22d7289 11726 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11727 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11728 tcg_temp_free_i64(fp1);
b6d96bed 11729 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11730 tcg_temp_free_i64(fp0);
b6d96bed 11731 }
57fa1fb3 11732 break;
bf4120ad 11733 case OPC_RECIP1_PS:
e29c9628 11734 check_ps(ctx);
b6d96bed 11735 {
a7812ae4 11736 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11737
11738 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11739 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 11740 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11741 tcg_temp_free_i64(fp0);
b6d96bed 11742 }
57fa1fb3 11743 break;
bf4120ad 11744 case OPC_RSQRT1_PS:
e29c9628 11745 check_ps(ctx);
b6d96bed 11746 {
a7812ae4 11747 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11748
11749 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11750 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 11751 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11752 tcg_temp_free_i64(fp0);
b6d96bed 11753 }
57fa1fb3 11754 break;
bf4120ad 11755 case OPC_RSQRT2_PS:
e29c9628 11756 check_ps(ctx);
b6d96bed 11757 {
a7812ae4
PB
11758 TCGv_i64 fp0 = tcg_temp_new_i64();
11759 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11760
11761 gen_load_fpr64(ctx, fp0, fs);
11762 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11763 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11764 tcg_temp_free_i64(fp1);
b6d96bed 11765 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11766 tcg_temp_free_i64(fp0);
b6d96bed 11767 }
57fa1fb3 11768 break;
bf4120ad 11769 case OPC_CVT_S_PU:
5e755519 11770 check_cp1_64bitmode(ctx);
b6d96bed 11771 {
a7812ae4 11772 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11773
7f6613ce 11774 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 11775 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 11776 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11777 tcg_temp_free_i32(fp0);
b6d96bed 11778 }
dd016883 11779 break;
bf4120ad 11780 case OPC_CVT_PW_PS:
e29c9628 11781 check_ps(ctx);
b6d96bed 11782 {
a7812ae4 11783 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11784
11785 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11786 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 11787 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11788 tcg_temp_free_i64(fp0);
b6d96bed 11789 }
6ea83fed 11790 break;
bf4120ad 11791 case OPC_CVT_S_PL:
5e755519 11792 check_cp1_64bitmode(ctx);
b6d96bed 11793 {
a7812ae4 11794 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11795
7c979afd 11796 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11797 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 11798 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11799 tcg_temp_free_i32(fp0);
b6d96bed 11800 }
6ea83fed 11801 break;
bf4120ad 11802 case OPC_PLL_PS:
e29c9628 11803 check_ps(ctx);
b6d96bed 11804 {
a7812ae4
PB
11805 TCGv_i32 fp0 = tcg_temp_new_i32();
11806 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11807
7c979afd
LA
11808 gen_load_fpr32(ctx, fp0, fs);
11809 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 11810 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 11811 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
11812 tcg_temp_free_i32(fp0);
11813 tcg_temp_free_i32(fp1);
b6d96bed 11814 }
6ea83fed 11815 break;
bf4120ad 11816 case OPC_PLU_PS:
e29c9628 11817 check_ps(ctx);
b6d96bed 11818 {
a7812ae4
PB
11819 TCGv_i32 fp0 = tcg_temp_new_i32();
11820 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11821
7c979afd 11822 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 11823 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11824 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11825 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11826 tcg_temp_free_i32(fp0);
11827 tcg_temp_free_i32(fp1);
b6d96bed 11828 }
5a5012ec 11829 break;
bf4120ad 11830 case OPC_PUL_PS:
e29c9628 11831 check_ps(ctx);
b6d96bed 11832 {
a7812ae4
PB
11833 TCGv_i32 fp0 = tcg_temp_new_i32();
11834 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11835
7f6613ce 11836 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
11837 gen_load_fpr32(ctx, fp1, ft);
11838 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11839 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11840 tcg_temp_free_i32(fp0);
11841 tcg_temp_free_i32(fp1);
b6d96bed 11842 }
5a5012ec 11843 break;
bf4120ad 11844 case OPC_PUU_PS:
e29c9628 11845 check_ps(ctx);
b6d96bed 11846 {
a7812ae4
PB
11847 TCGv_i32 fp0 = tcg_temp_new_i32();
11848 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11849
7f6613ce
PJ
11850 gen_load_fpr32h(ctx, fp0, fs);
11851 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11852 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11853 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11854 tcg_temp_free_i32(fp0);
11855 tcg_temp_free_i32(fp1);
b6d96bed 11856 }
5a5012ec 11857 break;
bf4120ad
NF
11858 case OPC_CMP_F_PS:
11859 case OPC_CMP_UN_PS:
11860 case OPC_CMP_EQ_PS:
11861 case OPC_CMP_UEQ_PS:
11862 case OPC_CMP_OLT_PS:
11863 case OPC_CMP_ULT_PS:
11864 case OPC_CMP_OLE_PS:
11865 case OPC_CMP_ULE_PS:
11866 case OPC_CMP_SF_PS:
11867 case OPC_CMP_NGLE_PS:
11868 case OPC_CMP_SEQ_PS:
11869 case OPC_CMP_NGL_PS:
11870 case OPC_CMP_LT_PS:
11871 case OPC_CMP_NGE_PS:
11872 case OPC_CMP_LE_PS:
11873 case OPC_CMP_NGT_PS:
8153667c
NF
11874 if (ctx->opcode & (1 << 6)) {
11875 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
11876 } else {
11877 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 11878 }
6ea83fed 11879 break;
5a5012ec 11880 default:
9d68ac14 11881 MIPS_INVAL("farith");
9c708c7f 11882 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
11883 return;
11884 }
6ea83fed 11885}
6af0bf9c 11886
5a5012ec 11887/* Coprocessor 3 (FPU) */
5e755519
TS
11888static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11889 int fd, int fs, int base, int index)
7a387fff 11890{
4e2474d6 11891 TCGv t0 = tcg_temp_new();
7a387fff 11892
93b12ccc 11893 if (base == 0) {
6c5c1e20 11894 gen_load_gpr(t0, index);
93b12ccc 11895 } else if (index == 0) {
6c5c1e20 11896 gen_load_gpr(t0, base);
93b12ccc 11897 } else {
05168674 11898 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 11899 }
5a5012ec 11900 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 11901 memory access. */
5a5012ec
TS
11902 switch (opc) {
11903 case OPC_LWXC1:
8c0ab41f 11904 check_cop1x(ctx);
b6d96bed 11905 {
a7812ae4 11906 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11907
5f68f5ae 11908 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 11909 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 11910 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11911 tcg_temp_free_i32(fp0);
b6d96bed 11912 }
5a5012ec
TS
11913 break;
11914 case OPC_LDXC1:
8c0ab41f
AJ
11915 check_cop1x(ctx);
11916 check_cp1_registers(ctx, fd);
b6d96bed 11917 {
a7812ae4 11918 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 11919 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11920 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11921 tcg_temp_free_i64(fp0);
b6d96bed 11922 }
5a5012ec
TS
11923 break;
11924 case OPC_LUXC1:
8c0ab41f 11925 check_cp1_64bitmode(ctx);
6c5c1e20 11926 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11927 {
a7812ae4 11928 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11929
5f68f5ae 11930 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11931 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11932 tcg_temp_free_i64(fp0);
b6d96bed 11933 }
5a5012ec
TS
11934 break;
11935 case OPC_SWXC1:
8c0ab41f 11936 check_cop1x(ctx);
b6d96bed 11937 {
a7812ae4 11938 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11939 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 11940 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 11941 tcg_temp_free_i32(fp0);
b6d96bed 11942 }
5a5012ec
TS
11943 break;
11944 case OPC_SDXC1:
8c0ab41f
AJ
11945 check_cop1x(ctx);
11946 check_cp1_registers(ctx, fs);
b6d96bed 11947 {
a7812ae4 11948 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11949 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11950 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11951 tcg_temp_free_i64(fp0);
b6d96bed 11952 }
5a5012ec
TS
11953 break;
11954 case OPC_SUXC1:
8c0ab41f 11955 check_cp1_64bitmode(ctx);
6c5c1e20 11956 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11957 {
a7812ae4 11958 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11959 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11960 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11961 tcg_temp_free_i64(fp0);
b6d96bed 11962 }
5a5012ec 11963 break;
5a5012ec 11964 }
6c5c1e20 11965 tcg_temp_free(t0);
5a5012ec
TS
11966}
11967
5e755519
TS
11968static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11969 int fd, int fr, int fs, int ft)
5a5012ec 11970{
5a5012ec
TS
11971 switch (opc) {
11972 case OPC_ALNV_PS:
e29c9628 11973 check_ps(ctx);
a16336e4 11974 {
a7812ae4 11975 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
11976 TCGv_i32 fp = tcg_temp_new_i32();
11977 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
11978 TCGLabel *l1 = gen_new_label();
11979 TCGLabel *l2 = gen_new_label();
a16336e4 11980
6c5c1e20
TS
11981 gen_load_gpr(t0, fr);
11982 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
11983
11984 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 11985 gen_load_fpr32(ctx, fp, fs);
7f6613ce 11986 gen_load_fpr32h(ctx, fph, fs);
7c979afd 11987 gen_store_fpr32(ctx, fp, fd);
7f6613ce 11988 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
11989 tcg_gen_br(l2);
11990 gen_set_label(l1);
6c5c1e20
TS
11991 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11992 tcg_temp_free(t0);
a16336e4 11993#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 11994 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
11995 gen_load_fpr32h(ctx, fph, ft);
11996 gen_store_fpr32h(ctx, fp, fd);
7c979afd 11997 gen_store_fpr32(ctx, fph, fd);
a16336e4 11998#else
7f6613ce 11999 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
12000 gen_load_fpr32(ctx, fp, ft);
12001 gen_store_fpr32(ctx, fph, fd);
7f6613ce 12002 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
12003#endif
12004 gen_set_label(l2);
c905fdac
AJ
12005 tcg_temp_free_i32(fp);
12006 tcg_temp_free_i32(fph);
a16336e4 12007 }
5a5012ec
TS
12008 break;
12009 case OPC_MADD_S:
b8aa4598 12010 check_cop1x(ctx);
b6d96bed 12011 {
a7812ae4
PB
12012 TCGv_i32 fp0 = tcg_temp_new_i32();
12013 TCGv_i32 fp1 = tcg_temp_new_i32();
12014 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12015
7c979afd
LA
12016 gen_load_fpr32(ctx, fp0, fs);
12017 gen_load_fpr32(ctx, fp1, ft);
12018 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12019 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12020 tcg_temp_free_i32(fp0);
12021 tcg_temp_free_i32(fp1);
7c979afd 12022 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12023 tcg_temp_free_i32(fp2);
b6d96bed 12024 }
5a5012ec
TS
12025 break;
12026 case OPC_MADD_D:
b8aa4598
TS
12027 check_cop1x(ctx);
12028 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12029 {
a7812ae4
PB
12030 TCGv_i64 fp0 = tcg_temp_new_i64();
12031 TCGv_i64 fp1 = tcg_temp_new_i64();
12032 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12033
12034 gen_load_fpr64(ctx, fp0, fs);
12035 gen_load_fpr64(ctx, fp1, ft);
12036 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12037 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12038 tcg_temp_free_i64(fp0);
12039 tcg_temp_free_i64(fp1);
b6d96bed 12040 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12041 tcg_temp_free_i64(fp2);
b6d96bed 12042 }
5a5012ec
TS
12043 break;
12044 case OPC_MADD_PS:
e29c9628 12045 check_ps(ctx);
b6d96bed 12046 {
a7812ae4
PB
12047 TCGv_i64 fp0 = tcg_temp_new_i64();
12048 TCGv_i64 fp1 = tcg_temp_new_i64();
12049 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12050
12051 gen_load_fpr64(ctx, fp0, fs);
12052 gen_load_fpr64(ctx, fp1, ft);
12053 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12054 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12055 tcg_temp_free_i64(fp0);
12056 tcg_temp_free_i64(fp1);
b6d96bed 12057 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12058 tcg_temp_free_i64(fp2);
b6d96bed 12059 }
5a5012ec
TS
12060 break;
12061 case OPC_MSUB_S:
b8aa4598 12062 check_cop1x(ctx);
b6d96bed 12063 {
a7812ae4
PB
12064 TCGv_i32 fp0 = tcg_temp_new_i32();
12065 TCGv_i32 fp1 = tcg_temp_new_i32();
12066 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12067
7c979afd
LA
12068 gen_load_fpr32(ctx, fp0, fs);
12069 gen_load_fpr32(ctx, fp1, ft);
12070 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12071 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12072 tcg_temp_free_i32(fp0);
12073 tcg_temp_free_i32(fp1);
7c979afd 12074 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12075 tcg_temp_free_i32(fp2);
b6d96bed 12076 }
5a5012ec
TS
12077 break;
12078 case OPC_MSUB_D:
b8aa4598
TS
12079 check_cop1x(ctx);
12080 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12081 {
a7812ae4
PB
12082 TCGv_i64 fp0 = tcg_temp_new_i64();
12083 TCGv_i64 fp1 = tcg_temp_new_i64();
12084 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12085
12086 gen_load_fpr64(ctx, fp0, fs);
12087 gen_load_fpr64(ctx, fp1, ft);
12088 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12089 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12090 tcg_temp_free_i64(fp0);
12091 tcg_temp_free_i64(fp1);
b6d96bed 12092 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12093 tcg_temp_free_i64(fp2);
b6d96bed 12094 }
5a5012ec
TS
12095 break;
12096 case OPC_MSUB_PS:
e29c9628 12097 check_ps(ctx);
b6d96bed 12098 {
a7812ae4
PB
12099 TCGv_i64 fp0 = tcg_temp_new_i64();
12100 TCGv_i64 fp1 = tcg_temp_new_i64();
12101 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12102
12103 gen_load_fpr64(ctx, fp0, fs);
12104 gen_load_fpr64(ctx, fp1, ft);
12105 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12106 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12107 tcg_temp_free_i64(fp0);
12108 tcg_temp_free_i64(fp1);
b6d96bed 12109 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12110 tcg_temp_free_i64(fp2);
b6d96bed 12111 }
5a5012ec
TS
12112 break;
12113 case OPC_NMADD_S:
b8aa4598 12114 check_cop1x(ctx);
b6d96bed 12115 {
a7812ae4
PB
12116 TCGv_i32 fp0 = tcg_temp_new_i32();
12117 TCGv_i32 fp1 = tcg_temp_new_i32();
12118 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12119
7c979afd
LA
12120 gen_load_fpr32(ctx, fp0, fs);
12121 gen_load_fpr32(ctx, fp1, ft);
12122 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12123 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12124 tcg_temp_free_i32(fp0);
12125 tcg_temp_free_i32(fp1);
7c979afd 12126 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12127 tcg_temp_free_i32(fp2);
b6d96bed 12128 }
5a5012ec
TS
12129 break;
12130 case OPC_NMADD_D:
b8aa4598
TS
12131 check_cop1x(ctx);
12132 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12133 {
a7812ae4
PB
12134 TCGv_i64 fp0 = tcg_temp_new_i64();
12135 TCGv_i64 fp1 = tcg_temp_new_i64();
12136 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12137
12138 gen_load_fpr64(ctx, fp0, fs);
12139 gen_load_fpr64(ctx, fp1, ft);
12140 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12141 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12142 tcg_temp_free_i64(fp0);
12143 tcg_temp_free_i64(fp1);
b6d96bed 12144 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12145 tcg_temp_free_i64(fp2);
b6d96bed 12146 }
5a5012ec
TS
12147 break;
12148 case OPC_NMADD_PS:
e29c9628 12149 check_ps(ctx);
b6d96bed 12150 {
a7812ae4
PB
12151 TCGv_i64 fp0 = tcg_temp_new_i64();
12152 TCGv_i64 fp1 = tcg_temp_new_i64();
12153 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12154
12155 gen_load_fpr64(ctx, fp0, fs);
12156 gen_load_fpr64(ctx, fp1, ft);
12157 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12158 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12159 tcg_temp_free_i64(fp0);
12160 tcg_temp_free_i64(fp1);
b6d96bed 12161 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12162 tcg_temp_free_i64(fp2);
b6d96bed 12163 }
5a5012ec
TS
12164 break;
12165 case OPC_NMSUB_S:
b8aa4598 12166 check_cop1x(ctx);
b6d96bed 12167 {
a7812ae4
PB
12168 TCGv_i32 fp0 = tcg_temp_new_i32();
12169 TCGv_i32 fp1 = tcg_temp_new_i32();
12170 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12171
7c979afd
LA
12172 gen_load_fpr32(ctx, fp0, fs);
12173 gen_load_fpr32(ctx, fp1, ft);
12174 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12175 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12176 tcg_temp_free_i32(fp0);
12177 tcg_temp_free_i32(fp1);
7c979afd 12178 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12179 tcg_temp_free_i32(fp2);
b6d96bed 12180 }
5a5012ec
TS
12181 break;
12182 case OPC_NMSUB_D:
b8aa4598
TS
12183 check_cop1x(ctx);
12184 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12185 {
a7812ae4
PB
12186 TCGv_i64 fp0 = tcg_temp_new_i64();
12187 TCGv_i64 fp1 = tcg_temp_new_i64();
12188 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12189
12190 gen_load_fpr64(ctx, fp0, fs);
12191 gen_load_fpr64(ctx, fp1, ft);
12192 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12193 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12194 tcg_temp_free_i64(fp0);
12195 tcg_temp_free_i64(fp1);
b6d96bed 12196 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12197 tcg_temp_free_i64(fp2);
b6d96bed 12198 }
5a5012ec
TS
12199 break;
12200 case OPC_NMSUB_PS:
e29c9628 12201 check_ps(ctx);
b6d96bed 12202 {
a7812ae4
PB
12203 TCGv_i64 fp0 = tcg_temp_new_i64();
12204 TCGv_i64 fp1 = tcg_temp_new_i64();
12205 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12206
12207 gen_load_fpr64(ctx, fp0, fs);
12208 gen_load_fpr64(ctx, fp1, ft);
12209 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12210 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12211 tcg_temp_free_i64(fp0);
12212 tcg_temp_free_i64(fp1);
b6d96bed 12213 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12214 tcg_temp_free_i64(fp2);
b6d96bed 12215 }
5a5012ec 12216 break;
923617a3 12217 default:
9d68ac14 12218 MIPS_INVAL("flt3_arith");
9c708c7f 12219 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
12220 return;
12221 }
7a387fff
TS
12222}
12223
b00c7218 12224static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
12225{
12226 TCGv t0;
12227
b3167288
RH
12228#if !defined(CONFIG_USER_ONLY)
12229 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12230 Therefore only check the ISA in system mode. */
d75c135e 12231 check_insn(ctx, ISA_MIPS32R2);
b3167288 12232#endif
26ebe468
NF
12233 t0 = tcg_temp_new();
12234
12235 switch (rd) {
12236 case 0:
895c2d04 12237 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
12238 gen_store_gpr(t0, rt);
12239 break;
12240 case 1:
895c2d04 12241 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
12242 gen_store_gpr(t0, rt);
12243 break;
12244 case 2:
eeb3bba8 12245 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12246 gen_io_start();
12247 }
895c2d04 12248 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 12249 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12250 gen_io_end();
12251 }
26ebe468 12252 gen_store_gpr(t0, rt);
d673a68d 12253 /* Break the TB to be able to take timer interrupts immediately
b28425ba 12254 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 12255 we break completely out of translated code. */
eeb3bba8
EC
12256 gen_save_pc(ctx->base.pc_next + 4);
12257 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
12258 break;
12259 case 3:
895c2d04 12260 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
12261 gen_store_gpr(t0, rt);
12262 break;
b00c7218
YK
12263 case 4:
12264 check_insn(ctx, ISA_MIPS32R6);
12265 if (sel != 0) {
12266 /* Performance counter registers are not implemented other than
12267 * control register 0.
12268 */
12269 generate_exception(ctx, EXCP_RI);
12270 }
12271 gen_helper_rdhwr_performance(t0, cpu_env);
12272 gen_store_gpr(t0, rt);
12273 break;
12274 case 5:
12275 check_insn(ctx, ISA_MIPS32R6);
12276 gen_helper_rdhwr_xnp(t0, cpu_env);
12277 gen_store_gpr(t0, rt);
12278 break;
26ebe468
NF
12279 case 29:
12280#if defined(CONFIG_USER_ONLY)
d279279e
PJ
12281 tcg_gen_ld_tl(t0, cpu_env,
12282 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
12283 gen_store_gpr(t0, rt);
12284 break;
12285#else
d279279e
PJ
12286 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12287 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12288 tcg_gen_ld_tl(t0, cpu_env,
12289 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12290 gen_store_gpr(t0, rt);
12291 } else {
9c708c7f 12292 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
12293 }
12294 break;
26ebe468
NF
12295#endif
12296 default: /* Invalid */
12297 MIPS_INVAL("rdhwr");
9c708c7f 12298 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
12299 break;
12300 }
12301 tcg_temp_free(t0);
12302}
12303
a5f53390
LA
12304static inline void clear_branch_hflags(DisasContext *ctx)
12305{
12306 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 12307 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
12308 save_cpu_state(ctx, 0);
12309 } else {
12310 /* it is not safe to save ctx->hflags as hflags may be changed
12311 in execution time by the instruction in delay / forbidden slot. */
12312 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12313 }
12314}
12315
31837be3 12316static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
12317{
12318 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 12319 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 12320 /* Branches completion */
a5f53390 12321 clear_branch_hflags(ctx);
eeb3bba8 12322 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 12323 /* FIXME: Need to clear can_do_io. */
364d4831 12324 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 12325 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 12326 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 12327 break;
c9602061
NF
12328 case MIPS_HFLAG_B:
12329 /* unconditional branch */
364d4831
NF
12330 if (proc_hflags & MIPS_HFLAG_BX) {
12331 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12332 }
c9602061
NF
12333 gen_goto_tb(ctx, 0, ctx->btarget);
12334 break;
12335 case MIPS_HFLAG_BL:
12336 /* blikely taken case */
c9602061
NF
12337 gen_goto_tb(ctx, 0, ctx->btarget);
12338 break;
12339 case MIPS_HFLAG_BC:
12340 /* Conditional branch */
c9602061 12341 {
42a268c2 12342 TCGLabel *l1 = gen_new_label();
c9602061
NF
12343
12344 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 12345 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
12346 gen_set_label(l1);
12347 gen_goto_tb(ctx, 0, ctx->btarget);
12348 }
12349 break;
12350 case MIPS_HFLAG_BR:
12351 /* unconditional branch to register */
d75c135e 12352 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
12353 TCGv t0 = tcg_temp_new();
12354 TCGv_i32 t1 = tcg_temp_new_i32();
12355
12356 tcg_gen_andi_tl(t0, btarget, 0x1);
12357 tcg_gen_trunc_tl_i32(t1, t0);
12358 tcg_temp_free(t0);
12359 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12360 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12361 tcg_gen_or_i32(hflags, hflags, t1);
12362 tcg_temp_free_i32(t1);
12363
12364 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12365 } else {
12366 tcg_gen_mov_tl(cpu_PC, btarget);
12367 }
eeb3bba8 12368 if (ctx->base.singlestep_enabled) {
c9602061 12369 save_cpu_state(ctx, 0);
9c708c7f 12370 gen_helper_raise_exception_debug(cpu_env);
c9602061 12371 }
7f11636d 12372 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
12373 break;
12374 default:
a5f53390
LA
12375 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12376 abort();
c9602061
NF
12377 }
12378 }
12379}
12380
6893f074
YK
12381/* Compact Branches */
12382static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12383 int rs, int rt, int32_t offset)
12384{
12385 int bcond_compute = 0;
12386 TCGv t0 = tcg_temp_new();
12387 TCGv t1 = tcg_temp_new();
65935f07 12388 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
12389
12390 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12391#ifdef MIPS_DEBUG_DISAS
12392 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 12393 "\n", ctx->base.pc_next);
6893f074 12394#endif
9c708c7f 12395 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12396 goto out;
12397 }
12398
12399 /* Load needed operands and calculate btarget */
12400 switch (opc) {
12401 /* compact branch */
12402 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12403 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12404 gen_load_gpr(t0, rs);
12405 gen_load_gpr(t1, rt);
12406 bcond_compute = 1;
eeb3bba8 12407 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12408 if (rs <= rt && rs == 0) {
12409 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 12410 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12411 }
12412 break;
12413 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12414 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12415 gen_load_gpr(t0, rs);
12416 gen_load_gpr(t1, rt);
12417 bcond_compute = 1;
eeb3bba8 12418 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12419 break;
12420 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12421 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12422 if (rs == 0 || rs == rt) {
12423 /* OPC_BLEZALC, OPC_BGEZALC */
12424 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 12425 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12426 }
12427 gen_load_gpr(t0, rs);
12428 gen_load_gpr(t1, rt);
12429 bcond_compute = 1;
eeb3bba8 12430 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12431 break;
12432 case OPC_BC:
12433 case OPC_BALC:
eeb3bba8 12434 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12435 break;
12436 case OPC_BEQZC:
12437 case OPC_BNEZC:
12438 if (rs != 0) {
12439 /* OPC_BEQZC, OPC_BNEZC */
12440 gen_load_gpr(t0, rs);
12441 bcond_compute = 1;
eeb3bba8 12442 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12443 } else {
12444 /* OPC_JIC, OPC_JIALC */
12445 TCGv tbase = tcg_temp_new();
12446 TCGv toffset = tcg_temp_new();
12447
12448 gen_load_gpr(tbase, rt);
12449 tcg_gen_movi_tl(toffset, offset);
12450 gen_op_addr_add(ctx, btarget, tbase, toffset);
12451 tcg_temp_free(tbase);
12452 tcg_temp_free(toffset);
12453 }
12454 break;
12455 default:
12456 MIPS_INVAL("Compact branch/jump");
9c708c7f 12457 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12458 goto out;
12459 }
12460
12461 if (bcond_compute == 0) {
12462 /* Uncoditional compact branch */
12463 switch (opc) {
12464 case OPC_JIALC:
eeb3bba8 12465 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12466 /* Fallthrough */
12467 case OPC_JIC:
12468 ctx->hflags |= MIPS_HFLAG_BR;
12469 break;
12470 case OPC_BALC:
eeb3bba8 12471 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12472 /* Fallthrough */
12473 case OPC_BC:
12474 ctx->hflags |= MIPS_HFLAG_B;
12475 break;
12476 default:
12477 MIPS_INVAL("Compact branch/jump");
9c708c7f 12478 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12479 goto out;
12480 }
12481
12482 /* Generating branch here as compact branches don't have delay slot */
12483 gen_branch(ctx, 4);
12484 } else {
12485 /* Conditional compact branch */
12486 TCGLabel *fs = gen_new_label();
12487 save_cpu_state(ctx, 0);
12488
12489 switch (opc) {
12490 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12491 if (rs == 0 && rt != 0) {
12492 /* OPC_BLEZALC */
12493 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12494 } else if (rs != 0 && rt != 0 && rs == rt) {
12495 /* OPC_BGEZALC */
12496 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12497 } else {
12498 /* OPC_BGEUC */
12499 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12500 }
12501 break;
12502 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12503 if (rs == 0 && rt != 0) {
12504 /* OPC_BGTZALC */
12505 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12506 } else if (rs != 0 && rt != 0 && rs == rt) {
12507 /* OPC_BLTZALC */
12508 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12509 } else {
12510 /* OPC_BLTUC */
12511 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12512 }
12513 break;
12514 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12515 if (rs == 0 && rt != 0) {
12516 /* OPC_BLEZC */
12517 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12518 } else if (rs != 0 && rt != 0 && rs == rt) {
12519 /* OPC_BGEZC */
12520 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12521 } else {
12522 /* OPC_BGEC */
12523 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12524 }
12525 break;
12526 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12527 if (rs == 0 && rt != 0) {
12528 /* OPC_BGTZC */
12529 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12530 } else if (rs != 0 && rt != 0 && rs == rt) {
12531 /* OPC_BLTZC */
12532 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12533 } else {
12534 /* OPC_BLTC */
12535 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12536 }
12537 break;
12538 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12539 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12540 if (rs >= rt) {
12541 /* OPC_BOVC, OPC_BNVC */
12542 TCGv t2 = tcg_temp_new();
12543 TCGv t3 = tcg_temp_new();
12544 TCGv t4 = tcg_temp_new();
12545 TCGv input_overflow = tcg_temp_new();
12546
12547 gen_load_gpr(t0, rs);
12548 gen_load_gpr(t1, rt);
12549 tcg_gen_ext32s_tl(t2, t0);
12550 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12551 tcg_gen_ext32s_tl(t3, t1);
12552 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12553 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12554
12555 tcg_gen_add_tl(t4, t2, t3);
12556 tcg_gen_ext32s_tl(t4, t4);
12557 tcg_gen_xor_tl(t2, t2, t3);
12558 tcg_gen_xor_tl(t3, t4, t3);
12559 tcg_gen_andc_tl(t2, t3, t2);
12560 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12561 tcg_gen_or_tl(t4, t4, input_overflow);
12562 if (opc == OPC_BOVC) {
12563 /* OPC_BOVC */
12564 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12565 } else {
12566 /* OPC_BNVC */
12567 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12568 }
12569 tcg_temp_free(input_overflow);
12570 tcg_temp_free(t4);
12571 tcg_temp_free(t3);
12572 tcg_temp_free(t2);
12573 } else if (rs < rt && rs == 0) {
12574 /* OPC_BEQZALC, OPC_BNEZALC */
12575 if (opc == OPC_BEQZALC) {
12576 /* OPC_BEQZALC */
12577 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12578 } else {
12579 /* OPC_BNEZALC */
12580 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12581 }
12582 } else {
12583 /* OPC_BEQC, OPC_BNEC */
12584 if (opc == OPC_BEQC) {
12585 /* OPC_BEQC */
12586 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12587 } else {
12588 /* OPC_BNEC */
12589 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12590 }
12591 }
12592 break;
12593 case OPC_BEQZC:
12594 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12595 break;
12596 case OPC_BNEZC:
12597 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12598 break;
12599 default:
12600 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 12601 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12602 goto out;
12603 }
12604
12605 /* Generating branch here as compact branches don't have delay slot */
12606 gen_goto_tb(ctx, 1, ctx->btarget);
12607 gen_set_label(fs);
12608
12609 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12610 }
12611
12612out:
12613 tcg_temp_free(t0);
12614 tcg_temp_free(t1);
12615}
12616
7a387fff 12617/* ISA extensions (ASEs) */
6af0bf9c 12618/* MIPS16 extension to MIPS32 */
6ea219d0
NF
12619
12620/* MIPS16 major opcodes */
12621enum {
12622 M16_OPC_ADDIUSP = 0x00,
12623 M16_OPC_ADDIUPC = 0x01,
12624 M16_OPC_B = 0x02,
12625 M16_OPC_JAL = 0x03,
12626 M16_OPC_BEQZ = 0x04,
12627 M16_OPC_BNEQZ = 0x05,
12628 M16_OPC_SHIFT = 0x06,
12629 M16_OPC_LD = 0x07,
12630 M16_OPC_RRIA = 0x08,
12631 M16_OPC_ADDIU8 = 0x09,
12632 M16_OPC_SLTI = 0x0a,
12633 M16_OPC_SLTIU = 0x0b,
12634 M16_OPC_I8 = 0x0c,
12635 M16_OPC_LI = 0x0d,
12636 M16_OPC_CMPI = 0x0e,
12637 M16_OPC_SD = 0x0f,
12638 M16_OPC_LB = 0x10,
12639 M16_OPC_LH = 0x11,
12640 M16_OPC_LWSP = 0x12,
12641 M16_OPC_LW = 0x13,
12642 M16_OPC_LBU = 0x14,
12643 M16_OPC_LHU = 0x15,
12644 M16_OPC_LWPC = 0x16,
12645 M16_OPC_LWU = 0x17,
12646 M16_OPC_SB = 0x18,
12647 M16_OPC_SH = 0x19,
12648 M16_OPC_SWSP = 0x1a,
12649 M16_OPC_SW = 0x1b,
12650 M16_OPC_RRR = 0x1c,
12651 M16_OPC_RR = 0x1d,
12652 M16_OPC_EXTEND = 0x1e,
12653 M16_OPC_I64 = 0x1f
12654};
12655
12656/* I8 funct field */
12657enum {
12658 I8_BTEQZ = 0x0,
12659 I8_BTNEZ = 0x1,
12660 I8_SWRASP = 0x2,
12661 I8_ADJSP = 0x3,
12662 I8_SVRS = 0x4,
12663 I8_MOV32R = 0x5,
12664 I8_MOVR32 = 0x7
12665};
12666
12667/* RRR f field */
12668enum {
12669 RRR_DADDU = 0x0,
12670 RRR_ADDU = 0x1,
12671 RRR_DSUBU = 0x2,
12672 RRR_SUBU = 0x3
12673};
12674
12675/* RR funct field */
12676enum {
12677 RR_JR = 0x00,
12678 RR_SDBBP = 0x01,
12679 RR_SLT = 0x02,
12680 RR_SLTU = 0x03,
12681 RR_SLLV = 0x04,
12682 RR_BREAK = 0x05,
12683 RR_SRLV = 0x06,
12684 RR_SRAV = 0x07,
12685 RR_DSRL = 0x08,
12686 RR_CMP = 0x0a,
12687 RR_NEG = 0x0b,
12688 RR_AND = 0x0c,
12689 RR_OR = 0x0d,
12690 RR_XOR = 0x0e,
12691 RR_NOT = 0x0f,
12692 RR_MFHI = 0x10,
12693 RR_CNVT = 0x11,
12694 RR_MFLO = 0x12,
12695 RR_DSRA = 0x13,
12696 RR_DSLLV = 0x14,
12697 RR_DSRLV = 0x16,
12698 RR_DSRAV = 0x17,
12699 RR_MULT = 0x18,
12700 RR_MULTU = 0x19,
12701 RR_DIV = 0x1a,
12702 RR_DIVU = 0x1b,
12703 RR_DMULT = 0x1c,
12704 RR_DMULTU = 0x1d,
12705 RR_DDIV = 0x1e,
12706 RR_DDIVU = 0x1f
12707};
12708
12709/* I64 funct field */
12710enum {
12711 I64_LDSP = 0x0,
12712 I64_SDSP = 0x1,
12713 I64_SDRASP = 0x2,
12714 I64_DADJSP = 0x3,
12715 I64_LDPC = 0x4,
364d4831 12716 I64_DADDIU5 = 0x5,
6ea219d0
NF
12717 I64_DADDIUPC = 0x6,
12718 I64_DADDIUSP = 0x7
12719};
12720
12721/* RR ry field for CNVT */
12722enum {
12723 RR_RY_CNVT_ZEB = 0x0,
12724 RR_RY_CNVT_ZEH = 0x1,
12725 RR_RY_CNVT_ZEW = 0x2,
12726 RR_RY_CNVT_SEB = 0x4,
12727 RR_RY_CNVT_SEH = 0x5,
12728 RR_RY_CNVT_SEW = 0x6,
12729};
12730
364d4831
NF
12731static int xlat (int r)
12732{
12733 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12734
12735 return map[r];
12736}
12737
12738static void gen_mips16_save (DisasContext *ctx,
12739 int xsregs, int aregs,
12740 int do_ra, int do_s0, int do_s1,
12741 int framesize)
12742{
12743 TCGv t0 = tcg_temp_new();
12744 TCGv t1 = tcg_temp_new();
c48245f0 12745 TCGv t2 = tcg_temp_new();
364d4831
NF
12746 int args, astatic;
12747
12748 switch (aregs) {
12749 case 0:
12750 case 1:
12751 case 2:
12752 case 3:
12753 case 11:
12754 args = 0;
12755 break;
12756 case 4:
12757 case 5:
12758 case 6:
12759 case 7:
12760 args = 1;
12761 break;
12762 case 8:
12763 case 9:
12764 case 10:
12765 args = 2;
12766 break;
12767 case 12:
12768 case 13:
12769 args = 3;
12770 break;
12771 case 14:
12772 args = 4;
12773 break;
12774 default:
9c708c7f 12775 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12776 return;
12777 }
12778
12779 switch (args) {
12780 case 4:
12781 gen_base_offset_addr(ctx, t0, 29, 12);
12782 gen_load_gpr(t1, 7);
5f68f5ae 12783 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12784 /* Fall through */
12785 case 3:
12786 gen_base_offset_addr(ctx, t0, 29, 8);
12787 gen_load_gpr(t1, 6);
5f68f5ae 12788 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12789 /* Fall through */
12790 case 2:
12791 gen_base_offset_addr(ctx, t0, 29, 4);
12792 gen_load_gpr(t1, 5);
5f68f5ae 12793 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12794 /* Fall through */
12795 case 1:
12796 gen_base_offset_addr(ctx, t0, 29, 0);
12797 gen_load_gpr(t1, 4);
5f68f5ae 12798 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12799 }
12800
12801 gen_load_gpr(t0, 29);
12802
5f68f5ae 12803#define DECR_AND_STORE(reg) do { \
c48245f0
MR
12804 tcg_gen_movi_tl(t2, -4); \
12805 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
12806 gen_load_gpr(t1, reg); \
12807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
12808 } while (0)
12809
12810 if (do_ra) {
12811 DECR_AND_STORE(31);
12812 }
12813
12814 switch (xsregs) {
12815 case 7:
12816 DECR_AND_STORE(30);
12817 /* Fall through */
12818 case 6:
12819 DECR_AND_STORE(23);
12820 /* Fall through */
12821 case 5:
12822 DECR_AND_STORE(22);
12823 /* Fall through */
12824 case 4:
12825 DECR_AND_STORE(21);
12826 /* Fall through */
12827 case 3:
12828 DECR_AND_STORE(20);
12829 /* Fall through */
12830 case 2:
12831 DECR_AND_STORE(19);
12832 /* Fall through */
12833 case 1:
12834 DECR_AND_STORE(18);
12835 }
12836
12837 if (do_s1) {
12838 DECR_AND_STORE(17);
12839 }
12840 if (do_s0) {
12841 DECR_AND_STORE(16);
12842 }
12843
12844 switch (aregs) {
12845 case 0:
12846 case 4:
12847 case 8:
12848 case 12:
12849 case 14:
12850 astatic = 0;
12851 break;
12852 case 1:
12853 case 5:
12854 case 9:
12855 case 13:
12856 astatic = 1;
12857 break;
12858 case 2:
12859 case 6:
12860 case 10:
12861 astatic = 2;
12862 break;
12863 case 3:
12864 case 7:
12865 astatic = 3;
12866 break;
12867 case 11:
12868 astatic = 4;
12869 break;
12870 default:
9c708c7f 12871 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12872 return;
12873 }
12874
12875 if (astatic > 0) {
12876 DECR_AND_STORE(7);
12877 if (astatic > 1) {
12878 DECR_AND_STORE(6);
12879 if (astatic > 2) {
12880 DECR_AND_STORE(5);
12881 if (astatic > 3) {
12882 DECR_AND_STORE(4);
12883 }
12884 }
12885 }
12886 }
12887#undef DECR_AND_STORE
12888
c48245f0
MR
12889 tcg_gen_movi_tl(t2, -framesize);
12890 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
12891 tcg_temp_free(t0);
12892 tcg_temp_free(t1);
c48245f0 12893 tcg_temp_free(t2);
364d4831
NF
12894}
12895
12896static void gen_mips16_restore (DisasContext *ctx,
12897 int xsregs, int aregs,
12898 int do_ra, int do_s0, int do_s1,
12899 int framesize)
12900{
12901 int astatic;
12902 TCGv t0 = tcg_temp_new();
12903 TCGv t1 = tcg_temp_new();
c48245f0 12904 TCGv t2 = tcg_temp_new();
364d4831 12905
c48245f0
MR
12906 tcg_gen_movi_tl(t2, framesize);
12907 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 12908
5f68f5ae 12909#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
12910 tcg_gen_movi_tl(t2, -4); \
12911 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
12912 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12913 gen_store_gpr(t1, reg); \
364d4831
NF
12914 } while (0)
12915
12916 if (do_ra) {
12917 DECR_AND_LOAD(31);
12918 }
12919
12920 switch (xsregs) {
12921 case 7:
12922 DECR_AND_LOAD(30);
12923 /* Fall through */
12924 case 6:
12925 DECR_AND_LOAD(23);
12926 /* Fall through */
12927 case 5:
12928 DECR_AND_LOAD(22);
12929 /* Fall through */
12930 case 4:
12931 DECR_AND_LOAD(21);
12932 /* Fall through */
12933 case 3:
12934 DECR_AND_LOAD(20);
12935 /* Fall through */
12936 case 2:
12937 DECR_AND_LOAD(19);
12938 /* Fall through */
12939 case 1:
12940 DECR_AND_LOAD(18);
12941 }
12942
12943 if (do_s1) {
12944 DECR_AND_LOAD(17);
12945 }
12946 if (do_s0) {
12947 DECR_AND_LOAD(16);
12948 }
12949
12950 switch (aregs) {
12951 case 0:
12952 case 4:
12953 case 8:
12954 case 12:
12955 case 14:
12956 astatic = 0;
12957 break;
12958 case 1:
12959 case 5:
12960 case 9:
12961 case 13:
12962 astatic = 1;
12963 break;
12964 case 2:
12965 case 6:
12966 case 10:
12967 astatic = 2;
12968 break;
12969 case 3:
12970 case 7:
12971 astatic = 3;
12972 break;
12973 case 11:
12974 astatic = 4;
12975 break;
12976 default:
9c708c7f 12977 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12978 return;
12979 }
12980
12981 if (astatic > 0) {
12982 DECR_AND_LOAD(7);
12983 if (astatic > 1) {
12984 DECR_AND_LOAD(6);
12985 if (astatic > 2) {
12986 DECR_AND_LOAD(5);
12987 if (astatic > 3) {
12988 DECR_AND_LOAD(4);
12989 }
12990 }
12991 }
12992 }
12993#undef DECR_AND_LOAD
12994
c48245f0
MR
12995 tcg_gen_movi_tl(t2, framesize);
12996 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
12997 tcg_temp_free(t0);
12998 tcg_temp_free(t1);
c48245f0 12999 tcg_temp_free(t2);
364d4831
NF
13000}
13001
13002static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13003 int is_64_bit, int extended)
13004{
13005 TCGv t0;
13006
13007 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13008 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13009 return;
13010 }
13011
13012 t0 = tcg_temp_new();
13013
13014 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13015 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13016 if (!is_64_bit) {
13017 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13018 }
13019
13020 tcg_temp_free(t0);
13021}
13022
0d74a222
LA
13023static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13024 int16_t offset)
13025{
13026 TCGv_i32 t0 = tcg_const_i32(op);
13027 TCGv t1 = tcg_temp_new();
13028 gen_base_offset_addr(ctx, t1, base, offset);
13029 gen_helper_cache(cpu_env, t1, t0);
13030}
13031
364d4831 13032#if defined(TARGET_MIPS64)
d75c135e 13033static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
13034 int ry, int funct, int16_t offset,
13035 int extended)
13036{
13037 switch (funct) {
13038 case I64_LDSP:
d9224450 13039 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13040 check_mips_64(ctx);
13041 offset = extended ? offset : offset << 3;
d75c135e 13042 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
13043 break;
13044 case I64_SDSP:
d9224450 13045 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13046 check_mips_64(ctx);
13047 offset = extended ? offset : offset << 3;
5c13fdfd 13048 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
13049 break;
13050 case I64_SDRASP:
d9224450 13051 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13052 check_mips_64(ctx);
13053 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 13054 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
13055 break;
13056 case I64_DADJSP:
d9224450 13057 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13058 check_mips_64(ctx);
13059 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 13060 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
13061 break;
13062 case I64_LDPC:
d9224450
MR
13063 check_insn(ctx, ISA_MIPS3);
13064 check_mips_64(ctx);
364d4831 13065 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13066 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13067 } else {
13068 offset = extended ? offset : offset << 3;
d75c135e 13069 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
13070 }
13071 break;
13072 case I64_DADDIU5:
d9224450 13073 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13074 check_mips_64(ctx);
13075 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 13076 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
13077 break;
13078 case I64_DADDIUPC:
d9224450 13079 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13080 check_mips_64(ctx);
13081 offset = extended ? offset : offset << 2;
13082 gen_addiupc(ctx, ry, offset, 1, extended);
13083 break;
13084 case I64_DADDIUSP:
d9224450 13085 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13086 check_mips_64(ctx);
13087 offset = extended ? offset : offset << 2;
d75c135e 13088 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
13089 break;
13090 }
13091}
13092#endif
13093
240ce26a 13094static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 13095{
eeb3bba8 13096 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13097 int op, rx, ry, funct, sa;
13098 int16_t imm, offset;
13099
13100 ctx->opcode = (ctx->opcode << 16) | extend;
13101 op = (ctx->opcode >> 11) & 0x1f;
13102 sa = (ctx->opcode >> 22) & 0x1f;
13103 funct = (ctx->opcode >> 8) & 0x7;
13104 rx = xlat((ctx->opcode >> 8) & 0x7);
13105 ry = xlat((ctx->opcode >> 5) & 0x7);
13106 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13107 | ((ctx->opcode >> 21) & 0x3f) << 5
13108 | (ctx->opcode & 0x1f));
13109
13110 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13111 counterparts. */
13112 switch (op) {
13113 case M16_OPC_ADDIUSP:
d75c135e 13114 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13115 break;
13116 case M16_OPC_ADDIUPC:
13117 gen_addiupc(ctx, rx, imm, 0, 1);
13118 break;
13119 case M16_OPC_B:
b231c103 13120 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
13121 /* No delay slot, so just process as a normal instruction */
13122 break;
13123 case M16_OPC_BEQZ:
b231c103 13124 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
13125 /* No delay slot, so just process as a normal instruction */
13126 break;
13127 case M16_OPC_BNEQZ:
b231c103 13128 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
13129 /* No delay slot, so just process as a normal instruction */
13130 break;
13131 case M16_OPC_SHIFT:
13132 switch (ctx->opcode & 0x3) {
13133 case 0x0:
d75c135e 13134 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13135 break;
13136 case 0x1:
13137#if defined(TARGET_MIPS64)
13138 check_mips_64(ctx);
d75c135e 13139 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13140#else
9c708c7f 13141 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13142#endif
13143 break;
13144 case 0x2:
d75c135e 13145 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13146 break;
13147 case 0x3:
d75c135e 13148 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13149 break;
13150 }
13151 break;
13152#if defined(TARGET_MIPS64)
13153 case M16_OPC_LD:
d9224450 13154 check_insn(ctx, ISA_MIPS3);
d75de749 13155 check_mips_64(ctx);
d75c135e 13156 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
13157 break;
13158#endif
13159 case M16_OPC_RRIA:
13160 imm = ctx->opcode & 0xf;
13161 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13162 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13163 imm = (int16_t) (imm << 1) >> 1;
13164 if ((ctx->opcode >> 4) & 0x1) {
13165#if defined(TARGET_MIPS64)
13166 check_mips_64(ctx);
d75c135e 13167 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13168#else
9c708c7f 13169 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13170#endif
13171 } else {
d75c135e 13172 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13173 }
13174 break;
13175 case M16_OPC_ADDIU8:
d75c135e 13176 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13177 break;
13178 case M16_OPC_SLTI:
d75c135e 13179 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13180 break;
13181 case M16_OPC_SLTIU:
d75c135e 13182 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13183 break;
13184 case M16_OPC_I8:
13185 switch (funct) {
13186 case I8_BTEQZ:
b231c103 13187 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
13188 break;
13189 case I8_BTNEZ:
b231c103 13190 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
13191 break;
13192 case I8_SWRASP:
5c13fdfd 13193 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
13194 break;
13195 case I8_ADJSP:
d75c135e 13196 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
13197 break;
13198 case I8_SVRS:
d9224450 13199 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13200 {
13201 int xsregs = (ctx->opcode >> 24) & 0x7;
13202 int aregs = (ctx->opcode >> 16) & 0xf;
13203 int do_ra = (ctx->opcode >> 6) & 0x1;
13204 int do_s0 = (ctx->opcode >> 5) & 0x1;
13205 int do_s1 = (ctx->opcode >> 4) & 0x1;
13206 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13207 | (ctx->opcode & 0xf)) << 3;
13208
13209 if (ctx->opcode & (1 << 7)) {
13210 gen_mips16_save(ctx, xsregs, aregs,
13211 do_ra, do_s0, do_s1,
13212 framesize);
13213 } else {
13214 gen_mips16_restore(ctx, xsregs, aregs,
13215 do_ra, do_s0, do_s1,
13216 framesize);
13217 }
13218 }
13219 break;
13220 default:
9c708c7f 13221 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13222 break;
13223 }
13224 break;
13225 case M16_OPC_LI:
13226 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13227 break;
13228 case M16_OPC_CMPI:
13229 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13230 break;
13231#if defined(TARGET_MIPS64)
13232 case M16_OPC_SD:
d9224450
MR
13233 check_insn(ctx, ISA_MIPS3);
13234 check_mips_64(ctx);
5c13fdfd 13235 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
13236 break;
13237#endif
13238 case M16_OPC_LB:
d75c135e 13239 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13240 break;
13241 case M16_OPC_LH:
d75c135e 13242 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
13243 break;
13244 case M16_OPC_LWSP:
d75c135e 13245 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
13246 break;
13247 case M16_OPC_LW:
d75c135e 13248 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
13249 break;
13250 case M16_OPC_LBU:
d75c135e 13251 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13252 break;
13253 case M16_OPC_LHU:
d75c135e 13254 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
13255 break;
13256 case M16_OPC_LWPC:
d75c135e 13257 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
13258 break;
13259#if defined(TARGET_MIPS64)
13260 case M16_OPC_LWU:
d9224450
MR
13261 check_insn(ctx, ISA_MIPS3);
13262 check_mips_64(ctx);
d75c135e 13263 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
13264 break;
13265#endif
13266 case M16_OPC_SB:
5c13fdfd 13267 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13268 break;
13269 case M16_OPC_SH:
5c13fdfd 13270 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
13271 break;
13272 case M16_OPC_SWSP:
5c13fdfd 13273 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
13274 break;
13275 case M16_OPC_SW:
5c13fdfd 13276 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
13277 break;
13278#if defined(TARGET_MIPS64)
13279 case M16_OPC_I64:
d75c135e 13280 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
13281 break;
13282#endif
13283 default:
9c708c7f 13284 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13285 break;
13286 }
13287
13288 return 4;
13289}
13290
3b3c1694
LA
13291static inline bool is_uhi(int sdbbp_code)
13292{
13293#ifdef CONFIG_USER_ONLY
13294 return false;
13295#else
13296 return semihosting_enabled() && sdbbp_code == 1;
13297#endif
13298}
13299
240ce26a 13300static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
13301{
13302 int rx, ry;
13303 int sa;
13304 int op, cnvt_op, op1, offset;
13305 int funct;
13306 int n_bytes;
13307
13308 op = (ctx->opcode >> 11) & 0x1f;
13309 sa = (ctx->opcode >> 2) & 0x7;
13310 sa = sa == 0 ? 8 : sa;
13311 rx = xlat((ctx->opcode >> 8) & 0x7);
13312 cnvt_op = (ctx->opcode >> 5) & 0x7;
13313 ry = xlat((ctx->opcode >> 5) & 0x7);
13314 op1 = offset = ctx->opcode & 0x1f;
13315
13316 n_bytes = 2;
13317
13318 switch (op) {
13319 case M16_OPC_ADDIUSP:
13320 {
13321 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13322
d75c135e 13323 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13324 }
13325 break;
13326 case M16_OPC_ADDIUPC:
13327 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13328 break;
13329 case M16_OPC_B:
13330 offset = (ctx->opcode & 0x7ff) << 1;
13331 offset = (int16_t)(offset << 4) >> 4;
b231c103 13332 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
13333 /* No delay slot, so just process as a normal instruction */
13334 break;
13335 case M16_OPC_JAL:
eeb3bba8 13336 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13337 offset = (((ctx->opcode & 0x1f) << 21)
13338 | ((ctx->opcode >> 5) & 0x1f) << 16
13339 | offset) << 2;
b231c103
YK
13340 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13341 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 13342 n_bytes = 4;
364d4831
NF
13343 break;
13344 case M16_OPC_BEQZ:
b231c103
YK
13345 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13346 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13347 /* No delay slot, so just process as a normal instruction */
13348 break;
13349 case M16_OPC_BNEQZ:
b231c103
YK
13350 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13351 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13352 /* No delay slot, so just process as a normal instruction */
13353 break;
13354 case M16_OPC_SHIFT:
13355 switch (ctx->opcode & 0x3) {
13356 case 0x0:
d75c135e 13357 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13358 break;
13359 case 0x1:
13360#if defined(TARGET_MIPS64)
d9224450 13361 check_insn(ctx, ISA_MIPS3);
364d4831 13362 check_mips_64(ctx);
d75c135e 13363 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13364#else
9c708c7f 13365 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13366#endif
13367 break;
13368 case 0x2:
d75c135e 13369 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13370 break;
13371 case 0x3:
d75c135e 13372 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13373 break;
13374 }
13375 break;
13376#if defined(TARGET_MIPS64)
13377 case M16_OPC_LD:
d9224450 13378 check_insn(ctx, ISA_MIPS3);
364d4831 13379 check_mips_64(ctx);
d75c135e 13380 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
13381 break;
13382#endif
13383 case M16_OPC_RRIA:
13384 {
13385 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13386
13387 if ((ctx->opcode >> 4) & 1) {
13388#if defined(TARGET_MIPS64)
d9224450 13389 check_insn(ctx, ISA_MIPS3);
364d4831 13390 check_mips_64(ctx);
d75c135e 13391 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13392#else
9c708c7f 13393 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13394#endif
13395 } else {
d75c135e 13396 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13397 }
13398 }
13399 break;
13400 case M16_OPC_ADDIU8:
13401 {
13402 int16_t imm = (int8_t) ctx->opcode;
13403
d75c135e 13404 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13405 }
13406 break;
13407 case M16_OPC_SLTI:
13408 {
13409 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13410 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13411 }
13412 break;
13413 case M16_OPC_SLTIU:
13414 {
13415 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13416 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13417 }
13418 break;
13419 case M16_OPC_I8:
13420 {
13421 int reg32;
13422
13423 funct = (ctx->opcode >> 8) & 0x7;
13424 switch (funct) {
13425 case I8_BTEQZ:
13426 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 13427 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13428 break;
13429 case I8_BTNEZ:
13430 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 13431 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13432 break;
13433 case I8_SWRASP:
5c13fdfd 13434 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
13435 break;
13436 case I8_ADJSP:
d75c135e 13437 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
13438 ((int8_t)ctx->opcode) << 3);
13439 break;
13440 case I8_SVRS:
d9224450 13441 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13442 {
13443 int do_ra = ctx->opcode & (1 << 6);
13444 int do_s0 = ctx->opcode & (1 << 5);
13445 int do_s1 = ctx->opcode & (1 << 4);
13446 int framesize = ctx->opcode & 0xf;
13447
13448 if (framesize == 0) {
13449 framesize = 128;
13450 } else {
13451 framesize = framesize << 3;
13452 }
13453
13454 if (ctx->opcode & (1 << 7)) {
13455 gen_mips16_save(ctx, 0, 0,
13456 do_ra, do_s0, do_s1, framesize);
13457 } else {
13458 gen_mips16_restore(ctx, 0, 0,
13459 do_ra, do_s0, do_s1, framesize);
13460 }
13461 }
13462 break;
13463 case I8_MOV32R:
13464 {
13465 int rz = xlat(ctx->opcode & 0x7);
13466
13467 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13468 ((ctx->opcode >> 5) & 0x7);
d75c135e 13469 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
13470 }
13471 break;
13472 case I8_MOVR32:
13473 reg32 = ctx->opcode & 0x1f;
d75c135e 13474 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
13475 break;
13476 default:
9c708c7f 13477 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13478 break;
13479 }
13480 }
13481 break;
13482 case M16_OPC_LI:
13483 {
13484 int16_t imm = (uint8_t) ctx->opcode;
13485
d75c135e 13486 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
13487 }
13488 break;
13489 case M16_OPC_CMPI:
13490 {
13491 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13492 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
13493 }
13494 break;
13495#if defined(TARGET_MIPS64)
13496 case M16_OPC_SD:
d9224450 13497 check_insn(ctx, ISA_MIPS3);
364d4831 13498 check_mips_64(ctx);
5c13fdfd 13499 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
13500 break;
13501#endif
13502 case M16_OPC_LB:
d75c135e 13503 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13504 break;
13505 case M16_OPC_LH:
d75c135e 13506 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
13507 break;
13508 case M16_OPC_LWSP:
d75c135e 13509 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13510 break;
13511 case M16_OPC_LW:
d75c135e 13512 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
13513 break;
13514 case M16_OPC_LBU:
d75c135e 13515 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13516 break;
13517 case M16_OPC_LHU:
d75c135e 13518 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
13519 break;
13520 case M16_OPC_LWPC:
d75c135e 13521 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13522 break;
13523#if defined (TARGET_MIPS64)
13524 case M16_OPC_LWU:
d9224450 13525 check_insn(ctx, ISA_MIPS3);
364d4831 13526 check_mips_64(ctx);
d75c135e 13527 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
13528 break;
13529#endif
13530 case M16_OPC_SB:
5c13fdfd 13531 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13532 break;
13533 case M16_OPC_SH:
5c13fdfd 13534 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
13535 break;
13536 case M16_OPC_SWSP:
5c13fdfd 13537 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13538 break;
13539 case M16_OPC_SW:
5c13fdfd 13540 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
13541 break;
13542 case M16_OPC_RRR:
13543 {
13544 int rz = xlat((ctx->opcode >> 2) & 0x7);
13545 int mips32_op;
13546
13547 switch (ctx->opcode & 0x3) {
13548 case RRR_ADDU:
13549 mips32_op = OPC_ADDU;
13550 break;
13551 case RRR_SUBU:
13552 mips32_op = OPC_SUBU;
13553 break;
13554#if defined(TARGET_MIPS64)
13555 case RRR_DADDU:
13556 mips32_op = OPC_DADDU;
d9224450 13557 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13558 check_mips_64(ctx);
13559 break;
13560 case RRR_DSUBU:
13561 mips32_op = OPC_DSUBU;
d9224450 13562 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13563 check_mips_64(ctx);
13564 break;
13565#endif
13566 default:
9c708c7f 13567 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13568 goto done;
13569 }
13570
d75c135e 13571 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
13572 done:
13573 ;
13574 }
13575 break;
13576 case M16_OPC_RR:
13577 switch (op1) {
13578 case RR_JR:
13579 {
13580 int nd = (ctx->opcode >> 7) & 0x1;
13581 int link = (ctx->opcode >> 6) & 0x1;
13582 int ra = (ctx->opcode >> 5) & 0x1;
13583
d9224450
MR
13584 if (nd) {
13585 check_insn(ctx, ISA_MIPS32);
13586 }
13587
364d4831 13588 if (link) {
b231c103 13589 op = OPC_JALR;
364d4831
NF
13590 } else {
13591 op = OPC_JR;
13592 }
13593
b231c103
YK
13594 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13595 (nd ? 0 : 2));
364d4831
NF
13596 }
13597 break;
13598 case RR_SDBBP:
3b3c1694
LA
13599 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13600 gen_helper_do_semihosting(cpu_env);
13601 } else {
13602 /* XXX: not clear which exception should be raised
13603 * when in debug mode...
13604 */
13605 check_insn(ctx, ISA_MIPS32);
9c708c7f 13606 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13607 }
364d4831
NF
13608 break;
13609 case RR_SLT:
d75c135e 13610 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
13611 break;
13612 case RR_SLTU:
d75c135e 13613 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
13614 break;
13615 case RR_BREAK:
9c708c7f 13616 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
13617 break;
13618 case RR_SLLV:
d75c135e 13619 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
13620 break;
13621 case RR_SRLV:
d75c135e 13622 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
13623 break;
13624 case RR_SRAV:
d75c135e 13625 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
13626 break;
13627#if defined (TARGET_MIPS64)
13628 case RR_DSRL:
d9224450 13629 check_insn(ctx, ISA_MIPS3);
364d4831 13630 check_mips_64(ctx);
d75c135e 13631 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
13632 break;
13633#endif
13634 case RR_CMP:
d75c135e 13635 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
13636 break;
13637 case RR_NEG:
d75c135e 13638 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
13639 break;
13640 case RR_AND:
d75c135e 13641 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
13642 break;
13643 case RR_OR:
d75c135e 13644 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
13645 break;
13646 case RR_XOR:
d75c135e 13647 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
13648 break;
13649 case RR_NOT:
d75c135e 13650 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
13651 break;
13652 case RR_MFHI:
26135ead 13653 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
13654 break;
13655 case RR_CNVT:
d9224450 13656 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13657 switch (cnvt_op) {
13658 case RR_RY_CNVT_ZEB:
13659 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13660 break;
13661 case RR_RY_CNVT_ZEH:
13662 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13663 break;
13664 case RR_RY_CNVT_SEB:
13665 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13666 break;
13667 case RR_RY_CNVT_SEH:
13668 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13669 break;
13670#if defined (TARGET_MIPS64)
13671 case RR_RY_CNVT_ZEW:
d9224450 13672 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13673 check_mips_64(ctx);
13674 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13675 break;
13676 case RR_RY_CNVT_SEW:
d9224450 13677 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13678 check_mips_64(ctx);
13679 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13680 break;
13681#endif
13682 default:
9c708c7f 13683 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13684 break;
13685 }
13686 break;
13687 case RR_MFLO:
26135ead 13688 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
13689 break;
13690#if defined (TARGET_MIPS64)
13691 case RR_DSRA:
d9224450 13692 check_insn(ctx, ISA_MIPS3);
364d4831 13693 check_mips_64(ctx);
d75c135e 13694 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
13695 break;
13696 case RR_DSLLV:
d9224450 13697 check_insn(ctx, ISA_MIPS3);
364d4831 13698 check_mips_64(ctx);
d75c135e 13699 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
13700 break;
13701 case RR_DSRLV:
d9224450 13702 check_insn(ctx, ISA_MIPS3);
364d4831 13703 check_mips_64(ctx);
d75c135e 13704 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
13705 break;
13706 case RR_DSRAV:
d9224450 13707 check_insn(ctx, ISA_MIPS3);
364d4831 13708 check_mips_64(ctx);
d75c135e 13709 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
13710 break;
13711#endif
13712 case RR_MULT:
26135ead 13713 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
13714 break;
13715 case RR_MULTU:
26135ead 13716 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
13717 break;
13718 case RR_DIV:
26135ead 13719 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
13720 break;
13721 case RR_DIVU:
26135ead 13722 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
13723 break;
13724#if defined (TARGET_MIPS64)
13725 case RR_DMULT:
d9224450 13726 check_insn(ctx, ISA_MIPS3);
364d4831 13727 check_mips_64(ctx);
26135ead 13728 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
13729 break;
13730 case RR_DMULTU:
d9224450 13731 check_insn(ctx, ISA_MIPS3);
364d4831 13732 check_mips_64(ctx);
26135ead 13733 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
13734 break;
13735 case RR_DDIV:
d9224450 13736 check_insn(ctx, ISA_MIPS3);
364d4831 13737 check_mips_64(ctx);
26135ead 13738 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
13739 break;
13740 case RR_DDIVU:
d9224450 13741 check_insn(ctx, ISA_MIPS3);
364d4831 13742 check_mips_64(ctx);
26135ead 13743 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
13744 break;
13745#endif
13746 default:
9c708c7f 13747 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13748 break;
13749 }
13750 break;
13751 case M16_OPC_EXTEND:
240ce26a 13752 decode_extended_mips16_opc(env, ctx);
364d4831
NF
13753 n_bytes = 4;
13754 break;
13755#if defined(TARGET_MIPS64)
13756 case M16_OPC_I64:
13757 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 13758 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
13759 break;
13760#endif
13761 default:
9c708c7f 13762 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13763 break;
13764 }
13765
13766 return n_bytes;
13767}
13768
211da992 13769/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 13770
211da992
CWR
13771/*
13772 * microMIPS32/microMIPS64 major opcodes
13773 *
13774 * 1. MIPS Architecture for Programmers Volume II-B:
13775 * The microMIPS32 Instruction Set (Revision 3.05)
13776 *
13777 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13778 *
13779 * 2. MIPS Architecture For Programmers Volume II-A:
13780 * The MIPS64 Instruction Set (Revision 3.51)
13781 */
6af0bf9c 13782
3c824109
NF
13783enum {
13784 POOL32A = 0x00,
13785 POOL16A = 0x01,
13786 LBU16 = 0x02,
13787 MOVE16 = 0x03,
13788 ADDI32 = 0x04,
3a1f4268
YK
13789 R6_LUI = 0x04,
13790 AUI = 0x04,
3c824109
NF
13791 LBU32 = 0x05,
13792 SB32 = 0x06,
13793 LB32 = 0x07,
13794
13795 POOL32B = 0x08,
13796 POOL16B = 0x09,
13797 LHU16 = 0x0a,
13798 ANDI16 = 0x0b,
13799 ADDIU32 = 0x0c,
13800 LHU32 = 0x0d,
13801 SH32 = 0x0e,
13802 LH32 = 0x0f,
13803
13804 POOL32I = 0x10,
13805 POOL16C = 0x11,
13806 LWSP16 = 0x12,
13807 POOL16D = 0x13,
13808 ORI32 = 0x14,
13809 POOL32F = 0x15,
211da992
CWR
13810 POOL32S = 0x16, /* MIPS64 */
13811 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
13812
13813 POOL32C = 0x18,
13814 LWGP16 = 0x19,
13815 LW16 = 0x1a,
13816 POOL16E = 0x1b,
13817 XORI32 = 0x1c,
13818 JALS32 = 0x1d,
3a1f4268
YK
13819 BOVC = 0x1d,
13820 BEQC = 0x1d,
13821 BEQZALC = 0x1d,
3c824109 13822 ADDIUPC = 0x1e,
3a1f4268
YK
13823 PCREL = 0x1e,
13824 BNVC = 0x1f,
13825 BNEC = 0x1f,
13826 BNEZALC = 0x1f,
3c824109 13827
3a1f4268
YK
13828 R6_BEQZC = 0x20,
13829 JIC = 0x20,
3c824109
NF
13830 POOL16F = 0x21,
13831 SB16 = 0x22,
13832 BEQZ16 = 0x23,
3a1f4268 13833 BEQZC16 = 0x23,
3c824109
NF
13834 SLTI32 = 0x24,
13835 BEQ32 = 0x25,
3a1f4268 13836 BC = 0x25,
3c824109
NF
13837 SWC132 = 0x26,
13838 LWC132 = 0x27,
13839
3a1f4268 13840 /* 0x29 is reserved */
3c824109 13841 RES_29 = 0x29,
3a1f4268
YK
13842 R6_BNEZC = 0x28,
13843 JIALC = 0x28,
3c824109
NF
13844 SH16 = 0x2a,
13845 BNEZ16 = 0x2b,
3a1f4268 13846 BNEZC16 = 0x2b,
3c824109
NF
13847 SLTIU32 = 0x2c,
13848 BNE32 = 0x2d,
3a1f4268 13849 BALC = 0x2d,
3c824109
NF
13850 SDC132 = 0x2e,
13851 LDC132 = 0x2f,
13852
3a1f4268 13853 /* 0x31 is reserved */
3c824109 13854 RES_31 = 0x31,
3a1f4268
YK
13855 BLEZALC = 0x30,
13856 BGEZALC = 0x30,
13857 BGEUC = 0x30,
3c824109
NF
13858 SWSP16 = 0x32,
13859 B16 = 0x33,
3a1f4268 13860 BC16 = 0x33,
3c824109
NF
13861 ANDI32 = 0x34,
13862 J32 = 0x35,
3a1f4268
YK
13863 BGTZC = 0x35,
13864 BLTZC = 0x35,
13865 BLTC = 0x35,
211da992
CWR
13866 SD32 = 0x36, /* MIPS64 */
13867 LD32 = 0x37, /* MIPS64 */
3c824109 13868
3a1f4268 13869 /* 0x39 is reserved */
3c824109 13870 RES_39 = 0x39,
3a1f4268
YK
13871 BGTZALC = 0x38,
13872 BLTZALC = 0x38,
13873 BLTUC = 0x38,
3c824109
NF
13874 SW16 = 0x3a,
13875 LI16 = 0x3b,
13876 JALX32 = 0x3c,
13877 JAL32 = 0x3d,
3a1f4268
YK
13878 BLEZC = 0x3d,
13879 BGEZC = 0x3d,
13880 BGEC = 0x3d,
3c824109
NF
13881 SW32 = 0x3e,
13882 LW32 = 0x3f
13883};
13884
3a1f4268
YK
13885/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13886enum {
13887 ADDIUPC_00 = 0x00,
c38a1d52
AR
13888 ADDIUPC_01 = 0x01,
13889 ADDIUPC_02 = 0x02,
13890 ADDIUPC_03 = 0x03,
13891 ADDIUPC_04 = 0x04,
13892 ADDIUPC_05 = 0x05,
13893 ADDIUPC_06 = 0x06,
3a1f4268
YK
13894 ADDIUPC_07 = 0x07,
13895 AUIPC = 0x1e,
13896 ALUIPC = 0x1f,
13897 LWPC_08 = 0x08,
c38a1d52
AR
13898 LWPC_09 = 0x09,
13899 LWPC_0A = 0x0A,
13900 LWPC_0B = 0x0B,
13901 LWPC_0C = 0x0C,
13902 LWPC_0D = 0x0D,
13903 LWPC_0E = 0x0E,
3a1f4268
YK
13904 LWPC_0F = 0x0F,
13905};
13906
3c824109
NF
13907/* POOL32A encoding of minor opcode field */
13908
13909enum {
13910 /* These opcodes are distinguished only by bits 9..6; those bits are
13911 * what are recorded below. */
13912 SLL32 = 0x0,
13913 SRL32 = 0x1,
13914 SRA = 0x2,
13915 ROTR = 0x3,
3a1f4268
YK
13916 SELEQZ = 0x5,
13917 SELNEZ = 0x6,
b00c7218 13918 R6_RDHWR = 0x7,
3c824109
NF
13919
13920 SLLV = 0x0,
13921 SRLV = 0x1,
13922 SRAV = 0x2,
13923 ROTRV = 0x3,
13924 ADD = 0x4,
13925 ADDU32 = 0x5,
13926 SUB = 0x6,
13927 SUBU32 = 0x7,
13928 MUL = 0x8,
13929 AND = 0x9,
13930 OR32 = 0xa,
13931 NOR = 0xb,
13932 XOR32 = 0xc,
13933 SLT = 0xd,
13934 SLTU = 0xe,
13935
13936 MOVN = 0x0,
3a1f4268 13937 R6_MUL = 0x0,
3c824109 13938 MOVZ = 0x1,
3a1f4268
YK
13939 MUH = 0x1,
13940 MULU = 0x2,
13941 MUHU = 0x3,
3c824109 13942 LWXS = 0x4,
3a1f4268
YK
13943 R6_DIV = 0x4,
13944 MOD = 0x5,
13945 R6_DIVU = 0x6,
13946 MODU = 0x7,
3c824109
NF
13947
13948 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 13949 BREAK32 = 0x07,
3c824109 13950 INS = 0x0c,
3a1f4268
YK
13951 LSA = 0x0f,
13952 ALIGN = 0x1f,
3c824109 13953 EXT = 0x2c,
bb238210
YK
13954 POOL32AXF = 0x3c,
13955 SIGRIE = 0x3f
3c824109
NF
13956};
13957
13958/* POOL32AXF encoding of minor opcode field extension */
13959
d132c79f
CWR
13960/*
13961 * 1. MIPS Architecture for Programmers Volume II-B:
13962 * The microMIPS32 Instruction Set (Revision 3.05)
13963 *
13964 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13965 *
13966 * 2. MIPS Architecture for Programmers VolumeIV-e:
13967 * The MIPS DSP Application-Specific Extension
13968 * to the microMIPS32 Architecture (Revision 2.34)
13969 *
13970 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13971 */
13972
3c824109
NF
13973enum {
13974 /* bits 11..6 */
13975 TEQ = 0x00,
13976 TGE = 0x08,
13977 TGEU = 0x10,
13978 TLT = 0x20,
13979 TLTU = 0x28,
13980 TNE = 0x30,
13981
13982 MFC0 = 0x03,
13983 MTC0 = 0x0b,
13984
d132c79f
CWR
13985 /* begin of microMIPS32 DSP */
13986
3c824109
NF
13987 /* bits 13..12 for 0x01 */
13988 MFHI_ACC = 0x0,
13989 MFLO_ACC = 0x1,
13990 MTHI_ACC = 0x2,
13991 MTLO_ACC = 0x3,
13992
13993 /* bits 13..12 for 0x2a */
13994 MADD_ACC = 0x0,
13995 MADDU_ACC = 0x1,
13996 MSUB_ACC = 0x2,
13997 MSUBU_ACC = 0x3,
13998
13999 /* bits 13..12 for 0x32 */
14000 MULT_ACC = 0x0,
6801038b 14001 MULTU_ACC = 0x1,
3c824109 14002
d132c79f
CWR
14003 /* end of microMIPS32 DSP */
14004
3c824109 14005 /* bits 15..12 for 0x2c */
3a1f4268 14006 BITSWAP = 0x0,
3c824109
NF
14007 SEB = 0x2,
14008 SEH = 0x3,
14009 CLO = 0x4,
14010 CLZ = 0x5,
14011 RDHWR = 0x6,
14012 WSBH = 0x7,
14013 MULT = 0x8,
14014 MULTU = 0x9,
14015 DIV = 0xa,
14016 DIVU = 0xb,
14017 MADD = 0xc,
14018 MADDU = 0xd,
14019 MSUB = 0xe,
14020 MSUBU = 0xf,
14021
14022 /* bits 15..12 for 0x34 */
14023 MFC2 = 0x4,
14024 MTC2 = 0x5,
14025 MFHC2 = 0x8,
14026 MTHC2 = 0x9,
14027 CFC2 = 0xc,
14028 CTC2 = 0xd,
14029
14030 /* bits 15..12 for 0x3c */
14031 JALR = 0x0,
14032 JR = 0x0, /* alias */
3a1f4268
YK
14033 JALRC = 0x0,
14034 JRC = 0x0,
3c824109 14035 JALR_HB = 0x1,
3a1f4268 14036 JALRC_HB = 0x1,
3c824109
NF
14037 JALRS = 0x4,
14038 JALRS_HB = 0x5,
14039
14040 /* bits 15..12 for 0x05 */
14041 RDPGPR = 0xe,
14042 WRPGPR = 0xf,
14043
14044 /* bits 15..12 for 0x0d */
14045 TLBP = 0x0,
14046 TLBR = 0x1,
14047 TLBWI = 0x2,
14048 TLBWR = 0x3,
e60ec063
YK
14049 TLBINV = 0x4,
14050 TLBINVF = 0x5,
3c824109
NF
14051 WAIT = 0x9,
14052 IRET = 0xd,
14053 DERET = 0xe,
14054 ERET = 0xf,
14055
14056 /* bits 15..12 for 0x15 */
14057 DMT = 0x0,
14058 DVPE = 0x1,
14059 EMT = 0x2,
14060 EVPE = 0x3,
14061
14062 /* bits 15..12 for 0x1d */
14063 DI = 0x4,
14064 EI = 0x5,
14065
14066 /* bits 15..12 for 0x2d */
14067 SYNC = 0x6,
14068 SYSCALL = 0x8,
14069 SDBBP = 0xd,
14070
14071 /* bits 15..12 for 0x35 */
14072 MFHI32 = 0x0,
14073 MFLO32 = 0x1,
14074 MTHI32 = 0x2,
14075 MTLO32 = 0x3,
14076};
14077
14078/* POOL32B encoding of minor opcode field (bits 15..12) */
14079
14080enum {
14081 LWC2 = 0x0,
14082 LWP = 0x1,
14083 LDP = 0x4,
14084 LWM32 = 0x5,
14085 CACHE = 0x6,
14086 LDM = 0x7,
14087 SWC2 = 0x8,
14088 SWP = 0x9,
14089 SDP = 0xc,
14090 SWM32 = 0xd,
14091 SDM = 0xf
14092};
14093
14094/* POOL32C encoding of minor opcode field (bits 15..12) */
14095
14096enum {
14097 LWL = 0x0,
14098 SWL = 0x8,
14099 LWR = 0x1,
14100 SWR = 0x9,
14101 PREF = 0x2,
8fffc646 14102 ST_EVA = 0xa,
3c824109
NF
14103 LL = 0x3,
14104 SC = 0xb,
14105 LDL = 0x4,
14106 SDL = 0xc,
14107 LDR = 0x5,
14108 SDR = 0xd,
8fffc646 14109 LD_EVA = 0x6,
3c824109
NF
14110 LWU = 0xe,
14111 LLD = 0x7,
14112 SCD = 0xf
14113};
14114
8fffc646
JH
14115/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14116
14117enum {
14118 LBUE = 0x0,
14119 LHUE = 0x1,
14120 LWLE = 0x2,
14121 LWRE = 0x3,
14122 LBE = 0x4,
14123 LHE = 0x5,
14124 LLE = 0x6,
14125 LWE = 0x7,
14126};
14127
14128/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14129
14130enum {
14131 SWLE = 0x0,
14132 SWRE = 0x1,
14133 PREFE = 0x2,
14134 CACHEE = 0x3,
14135 SBE = 0x4,
14136 SHE = 0x5,
14137 SCE = 0x6,
14138 SWE = 0x7,
14139};
14140
3c824109
NF
14141/* POOL32F encoding of minor opcode field (bits 5..0) */
14142
14143enum {
14144 /* These are the bit 7..6 values */
14145 ADD_FMT = 0x0,
3c824109
NF
14146
14147 SUB_FMT = 0x1,
3c824109
NF
14148
14149 MUL_FMT = 0x2,
14150
14151 DIV_FMT = 0x3,
14152
14153 /* These are the bit 8..6 values */
3a1f4268 14154 MOVN_FMT = 0x0,
3c824109
NF
14155 RSQRT2_FMT = 0x0,
14156 MOVF_FMT = 0x0,
3a1f4268
YK
14157 RINT_FMT = 0x0,
14158 SELNEZ_FMT = 0x0,
3c824109 14159
3a1f4268 14160 MOVZ_FMT = 0x1,
3c824109
NF
14161 LWXC1 = 0x1,
14162 MOVT_FMT = 0x1,
3a1f4268
YK
14163 CLASS_FMT = 0x1,
14164 SELEQZ_FMT = 0x1,
3c824109
NF
14165
14166 PLL_PS = 0x2,
14167 SWXC1 = 0x2,
3a1f4268 14168 SEL_FMT = 0x2,
3c824109
NF
14169
14170 PLU_PS = 0x3,
14171 LDXC1 = 0x3,
14172
3a1f4268 14173 MOVN_FMT_04 = 0x4,
3c824109
NF
14174 PUL_PS = 0x4,
14175 SDXC1 = 0x4,
14176 RECIP2_FMT = 0x4,
14177
3a1f4268 14178 MOVZ_FMT_05 = 0x05,
3c824109
NF
14179 PUU_PS = 0x5,
14180 LUXC1 = 0x5,
14181
14182 CVT_PS_S = 0x6,
14183 SUXC1 = 0x6,
14184 ADDR_PS = 0x6,
14185 PREFX = 0x6,
3a1f4268 14186 MADDF_FMT = 0x6,
3c824109
NF
14187
14188 MULR_PS = 0x7,
3a1f4268 14189 MSUBF_FMT = 0x7,
3c824109
NF
14190
14191 MADD_S = 0x01,
14192 MADD_D = 0x09,
14193 MADD_PS = 0x11,
14194 ALNV_PS = 0x19,
14195 MSUB_S = 0x21,
14196 MSUB_D = 0x29,
14197 MSUB_PS = 0x31,
14198
14199 NMADD_S = 0x02,
14200 NMADD_D = 0x0a,
14201 NMADD_PS = 0x12,
14202 NMSUB_S = 0x22,
14203 NMSUB_D = 0x2a,
14204 NMSUB_PS = 0x32,
14205
3a1f4268
YK
14206 MIN_FMT = 0x3,
14207 MAX_FMT = 0xb,
14208 MINA_FMT = 0x23,
14209 MAXA_FMT = 0x2b,
3c824109
NF
14210 POOL32FXF = 0x3b,
14211
14212 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
14213 C_COND_FMT = 0x3c,
14214
14215 CMP_CONDN_S = 0x5,
14216 CMP_CONDN_D = 0x15
3c824109
NF
14217};
14218
14219/* POOL32Fxf encoding of minor opcode extension field */
14220
14221enum {
14222 CVT_L = 0x04,
14223 RSQRT_FMT = 0x08,
14224 FLOOR_L = 0x0c,
14225 CVT_PW_PS = 0x1c,
14226 CVT_W = 0x24,
14227 SQRT_FMT = 0x28,
14228 FLOOR_W = 0x2c,
14229 CVT_PS_PW = 0x3c,
14230 CFC1 = 0x40,
14231 RECIP_FMT = 0x48,
14232 CEIL_L = 0x4c,
14233 CTC1 = 0x60,
14234 CEIL_W = 0x6c,
14235 MFC1 = 0x80,
14236 CVT_S_PL = 0x84,
14237 TRUNC_L = 0x8c,
14238 MTC1 = 0xa0,
14239 CVT_S_PU = 0xa4,
14240 TRUNC_W = 0xac,
14241 MFHC1 = 0xc0,
14242 ROUND_L = 0xcc,
14243 MTHC1 = 0xe0,
14244 ROUND_W = 0xec,
14245
14246 MOV_FMT = 0x01,
14247 MOVF = 0x05,
14248 ABS_FMT = 0x0d,
14249 RSQRT1_FMT = 0x1d,
14250 MOVT = 0x25,
14251 NEG_FMT = 0x2d,
14252 CVT_D = 0x4d,
14253 RECIP1_FMT = 0x5d,
14254 CVT_S = 0x6d
14255};
14256
14257/* POOL32I encoding of minor opcode field (bits 25..21) */
14258
14259enum {
14260 BLTZ = 0x00,
14261 BLTZAL = 0x01,
14262 BGEZ = 0x02,
14263 BGEZAL = 0x03,
14264 BLEZ = 0x04,
14265 BNEZC = 0x05,
14266 BGTZ = 0x06,
14267 BEQZC = 0x07,
14268 TLTI = 0x08,
3a1f4268 14269 BC1EQZC = 0x08,
3c824109 14270 TGEI = 0x09,
3a1f4268 14271 BC1NEZC = 0x09,
3c824109 14272 TLTIU = 0x0a,
3a1f4268 14273 BC2EQZC = 0x0a,
3c824109 14274 TGEIU = 0x0b,
3a1f4268 14275 BC2NEZC = 0x0a,
3c824109 14276 TNEI = 0x0c,
3a1f4268 14277 R6_SYNCI = 0x0c,
3c824109
NF
14278 LUI = 0x0d,
14279 TEQI = 0x0e,
14280 SYNCI = 0x10,
14281 BLTZALS = 0x11,
14282 BGEZALS = 0x13,
14283 BC2F = 0x14,
14284 BC2T = 0x15,
14285 BPOSGE64 = 0x1a,
14286 BPOSGE32 = 0x1b,
14287 /* These overlap and are distinguished by bit16 of the instruction */
14288 BC1F = 0x1c,
14289 BC1T = 0x1d,
14290 BC1ANY2F = 0x1c,
14291 BC1ANY2T = 0x1d,
14292 BC1ANY4F = 0x1e,
14293 BC1ANY4T = 0x1f
14294};
14295
14296/* POOL16A encoding of minor opcode field */
14297
14298enum {
14299 ADDU16 = 0x0,
14300 SUBU16 = 0x1
14301};
14302
14303/* POOL16B encoding of minor opcode field */
14304
14305enum {
14306 SLL16 = 0x0,
14307 SRL16 = 0x1
14308};
14309
14310/* POOL16C encoding of minor opcode field */
14311
14312enum {
14313 NOT16 = 0x00,
14314 XOR16 = 0x04,
14315 AND16 = 0x08,
14316 OR16 = 0x0c,
14317 LWM16 = 0x10,
14318 SWM16 = 0x14,
14319 JR16 = 0x18,
14320 JRC16 = 0x1a,
14321 JALR16 = 0x1c,
14322 JALR16S = 0x1e,
14323 MFHI16 = 0x20,
14324 MFLO16 = 0x24,
14325 BREAK16 = 0x28,
14326 SDBBP16 = 0x2c,
14327 JRADDIUSP = 0x30
14328};
14329
3a1f4268
YK
14330/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14331
14332enum {
14333 R6_NOT16 = 0x00,
14334 R6_AND16 = 0x01,
14335 R6_LWM16 = 0x02,
14336 R6_JRC16 = 0x03,
14337 MOVEP = 0x04,
c38a1d52
AR
14338 MOVEP_05 = 0x05,
14339 MOVEP_06 = 0x06,
3a1f4268
YK
14340 MOVEP_07 = 0x07,
14341 R6_XOR16 = 0x08,
14342 R6_OR16 = 0x09,
14343 R6_SWM16 = 0x0a,
14344 JALRC16 = 0x0b,
14345 MOVEP_0C = 0x0c,
c38a1d52
AR
14346 MOVEP_0D = 0x0d,
14347 MOVEP_0E = 0x0e,
3a1f4268
YK
14348 MOVEP_0F = 0x0f,
14349 JRCADDIUSP = 0x13,
14350 R6_BREAK16 = 0x1b,
14351 R6_SDBBP16 = 0x3b
14352};
14353
3c824109
NF
14354/* POOL16D encoding of minor opcode field */
14355
14356enum {
14357 ADDIUS5 = 0x0,
14358 ADDIUSP = 0x1
14359};
14360
14361/* POOL16E encoding of minor opcode field */
14362
14363enum {
14364 ADDIUR2 = 0x0,
14365 ADDIUR1SP = 0x1
14366};
14367
14368static int mmreg (int r)
14369{
14370 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14371
14372 return map[r];
14373}
14374
14375/* Used for 16-bit store instructions. */
14376static int mmreg2 (int r)
14377{
14378 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14379
14380 return map[r];
14381}
14382
14383#define uMIPS_RD(op) ((op >> 7) & 0x7)
14384#define uMIPS_RS(op) ((op >> 4) & 0x7)
14385#define uMIPS_RS2(op) uMIPS_RS(op)
14386#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14387#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14388#define uMIPS_RS5(op) (op & 0x1f)
14389
14390/* Signed immediate */
14391#define SIMM(op, start, width) \
14392 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14393 << (32-width)) \
14394 >> (32-width))
14395/* Zero-extended immediate */
14396#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14397
d75c135e 14398static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
14399{
14400 int rd = mmreg(uMIPS_RD(ctx->opcode));
14401
d75c135e 14402 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
14403}
14404
d75c135e 14405static void gen_addiur2(DisasContext *ctx)
3c824109
NF
14406{
14407 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14408 int rd = mmreg(uMIPS_RD(ctx->opcode));
14409 int rs = mmreg(uMIPS_RS(ctx->opcode));
14410
d75c135e 14411 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
14412}
14413
d75c135e 14414static void gen_addiusp(DisasContext *ctx)
3c824109
NF
14415{
14416 int encoded = ZIMM(ctx->opcode, 1, 9);
14417 int decoded;
14418
14419 if (encoded <= 1) {
14420 decoded = 256 + encoded;
14421 } else if (encoded <= 255) {
14422 decoded = encoded;
14423 } else if (encoded <= 509) {
14424 decoded = encoded - 512;
14425 } else {
14426 decoded = encoded - 768;
14427 }
14428
d75c135e 14429 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
14430}
14431
d75c135e 14432static void gen_addius5(DisasContext *ctx)
3c824109
NF
14433{
14434 int imm = SIMM(ctx->opcode, 1, 4);
14435 int rd = (ctx->opcode >> 5) & 0x1f;
14436
d75c135e 14437 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
14438}
14439
d75c135e 14440static void gen_andi16(DisasContext *ctx)
3c824109
NF
14441{
14442 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14443 31, 32, 63, 64, 255, 32768, 65535 };
14444 int rd = mmreg(uMIPS_RD(ctx->opcode));
14445 int rs = mmreg(uMIPS_RS(ctx->opcode));
14446 int encoded = ZIMM(ctx->opcode, 0, 4);
14447
d75c135e 14448 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
14449}
14450
14451static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14452 int base, int16_t offset)
14453{
14454 TCGv t0, t1;
14455 TCGv_i32 t2;
14456
14457 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 14458 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14459 return;
14460 }
14461
14462 t0 = tcg_temp_new();
14463
14464 gen_base_offset_addr(ctx, t0, base, offset);
14465
14466 t1 = tcg_const_tl(reglist);
14467 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 14468
3c824109
NF
14469 save_cpu_state(ctx, 1);
14470 switch (opc) {
14471 case LWM32:
895c2d04 14472 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
14473 break;
14474 case SWM32:
895c2d04 14475 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
14476 break;
14477#ifdef TARGET_MIPS64
14478 case LDM:
895c2d04 14479 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
14480 break;
14481 case SDM:
895c2d04 14482 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 14483 break;
6af0bf9c 14484#endif
3c824109 14485 }
3c824109 14486 tcg_temp_free(t0);
33087598 14487 tcg_temp_free(t1);
3c824109
NF
14488 tcg_temp_free_i32(t2);
14489}
6af0bf9c 14490
3c824109 14491
240ce26a 14492static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 14493{
3c824109
NF
14494 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14495 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 14496
3c824109
NF
14497 switch (((ctx->opcode) >> 4) & 0x3f) {
14498 case NOT16 + 0:
14499 case NOT16 + 1:
14500 case NOT16 + 2:
14501 case NOT16 + 3:
d75c135e 14502 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
14503 break;
14504 case XOR16 + 0:
14505 case XOR16 + 1:
14506 case XOR16 + 2:
14507 case XOR16 + 3:
d75c135e 14508 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
14509 break;
14510 case AND16 + 0:
14511 case AND16 + 1:
14512 case AND16 + 2:
14513 case AND16 + 3:
d75c135e 14514 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
14515 break;
14516 case OR16 + 0:
14517 case OR16 + 1:
14518 case OR16 + 2:
14519 case OR16 + 3:
d75c135e 14520 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
14521 break;
14522 case LWM16 + 0:
14523 case LWM16 + 1:
14524 case LWM16 + 2:
14525 case LWM16 + 3:
14526 {
14527 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14528 int offset = ZIMM(ctx->opcode, 0, 4);
14529
14530 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14531 29, offset << 2);
14532 }
14533 break;
14534 case SWM16 + 0:
14535 case SWM16 + 1:
14536 case SWM16 + 2:
14537 case SWM16 + 3:
14538 {
14539 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14540 int offset = ZIMM(ctx->opcode, 0, 4);
14541
14542 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14543 29, offset << 2);
14544 }
14545 break;
14546 case JR16 + 0:
14547 case JR16 + 1:
14548 {
14549 int reg = ctx->opcode & 0x1f;
14550
b231c103 14551 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 14552 }
3c824109
NF
14553 break;
14554 case JRC16 + 0:
14555 case JRC16 + 1:
14556 {
14557 int reg = ctx->opcode & 0x1f;
b231c103 14558 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
14559 /* Let normal delay slot handling in our caller take us
14560 to the branch target. */
14561 }
14562 break;
14563 case JALR16 + 0:
14564 case JALR16 + 1:
b231c103
YK
14565 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14566 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14567 break;
3c824109
NF
14568 case JALR16S + 0:
14569 case JALR16S + 1:
b231c103
YK
14570 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14571 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14572 break;
14573 case MFHI16 + 0:
14574 case MFHI16 + 1:
26135ead 14575 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14576 break;
14577 case MFLO16 + 0:
14578 case MFLO16 + 1:
26135ead 14579 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14580 break;
14581 case BREAK16:
9c708c7f 14582 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
14583 break;
14584 case SDBBP16:
3b3c1694
LA
14585 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14586 gen_helper_do_semihosting(cpu_env);
14587 } else {
14588 /* XXX: not clear which exception should be raised
14589 * when in debug mode...
14590 */
14591 check_insn(ctx, ISA_MIPS32);
9c708c7f 14592 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14593 }
3c824109
NF
14594 break;
14595 case JRADDIUSP + 0:
14596 case JRADDIUSP + 1:
14597 {
14598 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 14599 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 14600 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
14601 /* Let normal delay slot handling in our caller take us
14602 to the branch target. */
14603 }
14604 break;
14605 default:
9c708c7f 14606 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14607 break;
14608 }
14609}
14610
ed7ce6c0
YK
14611static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14612 int enc_rs)
14613{
14614 int rd, rs, re, rt;
14615 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14616 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14617 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14618 rd = rd_enc[enc_dest];
14619 re = re_enc[enc_dest];
14620 rs = rs_rt_enc[enc_rs];
14621 rt = rs_rt_enc[enc_rt];
14622 if (rs) {
14623 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14624 } else {
14625 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14626 }
14627 if (rt) {
14628 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14629 } else {
14630 tcg_gen_movi_tl(cpu_gpr[re], 0);
14631 }
14632}
14633
14634static void gen_pool16c_r6_insn(DisasContext *ctx)
14635{
14636 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14637 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14638
14639 switch (ctx->opcode & 0xf) {
14640 case R6_NOT16:
14641 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14642 break;
14643 case R6_AND16:
14644 gen_logic(ctx, OPC_AND, rt, rt, rs);
14645 break;
14646 case R6_LWM16:
14647 {
14648 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14649 int offset = extract32(ctx->opcode, 4, 4);
14650 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14651 }
14652 break;
14653 case R6_JRC16: /* JRCADDIUSP */
14654 if ((ctx->opcode >> 4) & 1) {
14655 /* JRCADDIUSP */
14656 int imm = extract32(ctx->opcode, 5, 5);
14657 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14658 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14659 } else {
14660 /* JRC16 */
e1555d7d 14661 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
14662 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14663 }
14664 break;
c38a1d52
AR
14665 case MOVEP:
14666 case MOVEP_05:
14667 case MOVEP_06:
14668 case MOVEP_07:
14669 case MOVEP_0C:
14670 case MOVEP_0D:
14671 case MOVEP_0E:
14672 case MOVEP_0F:
ed7ce6c0
YK
14673 {
14674 int enc_dest = uMIPS_RD(ctx->opcode);
14675 int enc_rt = uMIPS_RS2(ctx->opcode);
14676 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14677 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14678 }
14679 break;
14680 case R6_XOR16:
14681 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14682 break;
14683 case R6_OR16:
14684 gen_logic(ctx, OPC_OR, rt, rt, rs);
14685 break;
14686 case R6_SWM16:
14687 {
14688 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14689 int offset = extract32(ctx->opcode, 4, 4);
14690 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14691 }
14692 break;
14693 case JALRC16: /* BREAK16, SDBBP16 */
14694 switch (ctx->opcode & 0x3f) {
14695 case JALRC16:
14696 case JALRC16 + 0x20:
14697 /* JALRC16 */
14698 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14699 31, 0, 0);
14700 break;
14701 case R6_BREAK16:
14702 /* BREAK16 */
14703 generate_exception(ctx, EXCP_BREAK);
14704 break;
14705 case R6_SDBBP16:
14706 /* SDBBP16 */
060ebfef
LA
14707 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14708 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 14709 } else {
060ebfef
LA
14710 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14711 generate_exception(ctx, EXCP_RI);
14712 } else {
14713 generate_exception(ctx, EXCP_DBp);
14714 }
ed7ce6c0
YK
14715 }
14716 break;
14717 }
14718 break;
14719 default:
14720 generate_exception(ctx, EXCP_RI);
14721 break;
14722 }
14723}
14724
3c824109
NF
14725static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14726{
14727 TCGv t0 = tcg_temp_new();
14728 TCGv t1 = tcg_temp_new();
14729
14730 gen_load_gpr(t0, base);
14731
14732 if (index != 0) {
14733 gen_load_gpr(t1, index);
14734 tcg_gen_shli_tl(t1, t1, 2);
14735 gen_op_addr_add(ctx, t0, t1, t0);
14736 }
14737
5f68f5ae 14738 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14739 gen_store_gpr(t1, rd);
14740
14741 tcg_temp_free(t0);
14742 tcg_temp_free(t1);
14743}
14744
14745static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14746 int base, int16_t offset)
14747{
3c824109
NF
14748 TCGv t0, t1;
14749
36c6711b 14750 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 14751 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
14752 return;
14753 }
14754
3c824109
NF
14755 t0 = tcg_temp_new();
14756 t1 = tcg_temp_new();
8e9ade68 14757
3c824109
NF
14758 gen_base_offset_addr(ctx, t0, base, offset);
14759
14760 switch (opc) {
14761 case LWP:
36c6711b 14762 if (rd == base) {
9c708c7f 14763 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14764 return;
14765 }
5f68f5ae 14766 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14767 gen_store_gpr(t1, rd);
14768 tcg_gen_movi_tl(t1, 4);
14769 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14770 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 14771 gen_store_gpr(t1, rd+1);
3c824109
NF
14772 break;
14773 case SWP:
3c824109 14774 gen_load_gpr(t1, rd);
5f68f5ae 14775 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14776 tcg_gen_movi_tl(t1, 4);
14777 gen_op_addr_add(ctx, t0, t0, t1);
14778 gen_load_gpr(t1, rd+1);
5f68f5ae 14779 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14780 break;
14781#ifdef TARGET_MIPS64
14782 case LDP:
36c6711b 14783 if (rd == base) {
9c708c7f 14784 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14785 return;
14786 }
5f68f5ae 14787 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14788 gen_store_gpr(t1, rd);
14789 tcg_gen_movi_tl(t1, 8);
14790 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14791 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 14792 gen_store_gpr(t1, rd+1);
3c824109
NF
14793 break;
14794 case SDP:
3c824109 14795 gen_load_gpr(t1, rd);
5f68f5ae 14796 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14797 tcg_gen_movi_tl(t1, 8);
14798 gen_op_addr_add(ctx, t0, t0, t1);
14799 gen_load_gpr(t1, rd+1);
5f68f5ae 14800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14801 break;
14802#endif
6af0bf9c 14803 }
3c824109
NF
14804 tcg_temp_free(t0);
14805 tcg_temp_free(t1);
14806}
618b0fe9 14807
d208ac0c
LA
14808static void gen_sync(int stype)
14809{
14810 TCGBar tcg_mo = TCG_BAR_SC;
14811
14812 switch (stype) {
14813 case 0x4: /* SYNC_WMB */
14814 tcg_mo |= TCG_MO_ST_ST;
14815 break;
14816 case 0x10: /* SYNC_MB */
14817 tcg_mo |= TCG_MO_ALL;
14818 break;
14819 case 0x11: /* SYNC_ACQUIRE */
14820 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14821 break;
14822 case 0x12: /* SYNC_RELEASE */
14823 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14824 break;
14825 case 0x13: /* SYNC_RMB */
14826 tcg_mo |= TCG_MO_LD_LD;
14827 break;
14828 default:
14829 tcg_mo |= TCG_MO_ALL;
14830 break;
14831 }
14832
14833 tcg_gen_mb(tcg_mo);
14834}
14835
240ce26a 14836static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
14837{
14838 int extension = (ctx->opcode >> 6) & 0x3f;
14839 int minor = (ctx->opcode >> 12) & 0xf;
14840 uint32_t mips32_op;
14841
14842 switch (extension) {
14843 case TEQ:
14844 mips32_op = OPC_TEQ;
14845 goto do_trap;
14846 case TGE:
14847 mips32_op = OPC_TGE;
14848 goto do_trap;
14849 case TGEU:
14850 mips32_op = OPC_TGEU;
14851 goto do_trap;
14852 case TLT:
14853 mips32_op = OPC_TLT;
14854 goto do_trap;
14855 case TLTU:
14856 mips32_op = OPC_TLTU;
14857 goto do_trap;
14858 case TNE:
14859 mips32_op = OPC_TNE;
14860 do_trap:
14861 gen_trap(ctx, mips32_op, rs, rt, -1);
14862 break;
14863#ifndef CONFIG_USER_ONLY
14864 case MFC0:
14865 case MFC0 + 32:
2e15497c 14866 check_cp0_enabled(ctx);
3c824109
NF
14867 if (rt == 0) {
14868 /* Treat as NOP. */
14869 break;
14870 }
d75c135e 14871 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
14872 break;
14873 case MTC0:
14874 case MTC0 + 32:
2e15497c 14875 check_cp0_enabled(ctx);
3c824109
NF
14876 {
14877 TCGv t0 = tcg_temp_new();
618b0fe9 14878
3c824109 14879 gen_load_gpr(t0, rt);
d75c135e 14880 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
14881 tcg_temp_free(t0);
14882 }
14883 break;
14884#endif
a1fc6246
LA
14885 case 0x2a:
14886 switch (minor & 3) {
14887 case MADD_ACC:
14888 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14889 break;
14890 case MADDU_ACC:
14891 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14892 break;
14893 case MSUB_ACC:
14894 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14895 break;
14896 case MSUBU_ACC:
14897 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14898 break;
14899 default:
14900 goto pool32axf_invalid;
14901 }
14902 break;
14903 case 0x32:
14904 switch (minor & 3) {
14905 case MULT_ACC:
14906 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14907 break;
14908 case MULTU_ACC:
14909 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14910 break;
14911 default:
14912 goto pool32axf_invalid;
14913 }
14914 break;
3c824109
NF
14915 case 0x2c:
14916 switch (minor) {
e0332095
YK
14917 case BITSWAP:
14918 check_insn(ctx, ISA_MIPS32R6);
14919 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14920 break;
3c824109
NF
14921 case SEB:
14922 gen_bshfl(ctx, OPC_SEB, rs, rt);
14923 break;
14924 case SEH:
14925 gen_bshfl(ctx, OPC_SEH, rs, rt);
14926 break;
14927 case CLO:
14928 mips32_op = OPC_CLO;
14929 goto do_cl;
14930 case CLZ:
14931 mips32_op = OPC_CLZ;
14932 do_cl:
d75c135e 14933 check_insn(ctx, ISA_MIPS32);
3c824109
NF
14934 gen_cl(ctx, mips32_op, rt, rs);
14935 break;
14936 case RDHWR:
b00c7218
YK
14937 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14938 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
14939 break;
14940 case WSBH:
14941 gen_bshfl(ctx, OPC_WSBH, rs, rt);
14942 break;
14943 case MULT:
9e8f441a 14944 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14945 mips32_op = OPC_MULT;
26135ead 14946 goto do_mul;
3c824109 14947 case MULTU:
9e8f441a 14948 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14949 mips32_op = OPC_MULTU;
26135ead 14950 goto do_mul;
3c824109 14951 case DIV:
9e8f441a 14952 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14953 mips32_op = OPC_DIV;
26135ead 14954 goto do_div;
3c824109 14955 case DIVU:
9e8f441a 14956 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14957 mips32_op = OPC_DIVU;
26135ead
RS
14958 goto do_div;
14959 do_div:
14960 check_insn(ctx, ISA_MIPS32);
14961 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14962 break;
3c824109 14963 case MADD:
9e8f441a 14964 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14965 mips32_op = OPC_MADD;
26135ead 14966 goto do_mul;
3c824109 14967 case MADDU:
9e8f441a 14968 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14969 mips32_op = OPC_MADDU;
26135ead 14970 goto do_mul;
3c824109 14971 case MSUB:
9e8f441a 14972 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14973 mips32_op = OPC_MSUB;
26135ead 14974 goto do_mul;
3c824109 14975 case MSUBU:
9e8f441a 14976 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14977 mips32_op = OPC_MSUBU;
26135ead 14978 do_mul:
d75c135e 14979 check_insn(ctx, ISA_MIPS32);
a1fc6246 14980 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
14981 break;
14982 default:
14983 goto pool32axf_invalid;
14984 }
14985 break;
14986 case 0x34:
14987 switch (minor) {
14988 case MFC2:
14989 case MTC2:
14990 case MFHC2:
14991 case MTHC2:
14992 case CFC2:
14993 case CTC2:
14994 generate_exception_err(ctx, EXCP_CpU, 2);
14995 break;
14996 default:
14997 goto pool32axf_invalid;
14998 }
14999 break;
15000 case 0x3c:
15001 switch (minor) {
65935f07
YK
15002 case JALR: /* JALRC */
15003 case JALR_HB: /* JALRC_HB */
15004 if (ctx->insn_flags & ISA_MIPS32R6) {
15005 /* JALRC, JALRC_HB */
15006 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15007 } else {
15008 /* JALR, JALR_HB */
15009 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15010 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15011 }
3c824109
NF
15012 break;
15013 case JALRS:
15014 case JALRS_HB:
9e8f441a 15015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15016 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15017 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15018 break;
15019 default:
15020 goto pool32axf_invalid;
15021 }
15022 break;
15023 case 0x05:
15024 switch (minor) {
15025 case RDPGPR:
2e15497c 15026 check_cp0_enabled(ctx);
d75c135e 15027 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15028 gen_load_srsgpr(rs, rt);
3c824109
NF
15029 break;
15030 case WRPGPR:
2e15497c 15031 check_cp0_enabled(ctx);
d75c135e 15032 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15033 gen_store_srsgpr(rs, rt);
3c824109
NF
15034 break;
15035 default:
15036 goto pool32axf_invalid;
15037 }
15038 break;
15039#ifndef CONFIG_USER_ONLY
15040 case 0x0d:
15041 switch (minor) {
15042 case TLBP:
15043 mips32_op = OPC_TLBP;
15044 goto do_cp0;
15045 case TLBR:
15046 mips32_op = OPC_TLBR;
15047 goto do_cp0;
15048 case TLBWI:
15049 mips32_op = OPC_TLBWI;
15050 goto do_cp0;
15051 case TLBWR:
15052 mips32_op = OPC_TLBWR;
15053 goto do_cp0;
e60ec063
YK
15054 case TLBINV:
15055 mips32_op = OPC_TLBINV;
15056 goto do_cp0;
15057 case TLBINVF:
15058 mips32_op = OPC_TLBINVF;
15059 goto do_cp0;
3c824109
NF
15060 case WAIT:
15061 mips32_op = OPC_WAIT;
15062 goto do_cp0;
15063 case DERET:
15064 mips32_op = OPC_DERET;
15065 goto do_cp0;
15066 case ERET:
15067 mips32_op = OPC_ERET;
15068 do_cp0:
15069 gen_cp0(env, ctx, mips32_op, rt, rs);
15070 break;
15071 default:
15072 goto pool32axf_invalid;
15073 }
15074 break;
15075 case 0x1d:
15076 switch (minor) {
15077 case DI:
2e15497c 15078 check_cp0_enabled(ctx);
3c824109
NF
15079 {
15080 TCGv t0 = tcg_temp_new();
15081
15082 save_cpu_state(ctx, 1);
895c2d04 15083 gen_helper_di(t0, cpu_env);
3c824109
NF
15084 gen_store_gpr(t0, rs);
15085 /* Stop translation as we may have switched the execution mode */
eeb3bba8 15086 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15087 tcg_temp_free(t0);
15088 }
15089 break;
15090 case EI:
2e15497c 15091 check_cp0_enabled(ctx);
3c824109
NF
15092 {
15093 TCGv t0 = tcg_temp_new();
15094
15095 save_cpu_state(ctx, 1);
895c2d04 15096 gen_helper_ei(t0, cpu_env);
3c824109 15097 gen_store_gpr(t0, rs);
b28425ba 15098 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 15099 of translated code to check for pending interrupts. */
eeb3bba8
EC
15100 gen_save_pc(ctx->base.pc_next + 4);
15101 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
15102 tcg_temp_free(t0);
15103 }
15104 break;
15105 default:
15106 goto pool32axf_invalid;
15107 }
15108 break;
15109#endif
15110 case 0x2d:
15111 switch (minor) {
15112 case SYNC:
d208ac0c 15113 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
15114 break;
15115 case SYSCALL:
9c708c7f 15116 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
15117 break;
15118 case SDBBP:
3b3c1694
LA
15119 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15120 gen_helper_do_semihosting(cpu_env);
15121 } else {
15122 check_insn(ctx, ISA_MIPS32);
e0332095 15123 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 15124 generate_exception_end(ctx, EXCP_RI);
e0332095 15125 } else {
9c708c7f 15126 generate_exception_end(ctx, EXCP_DBp);
e0332095 15127 }
3b3c1694 15128 }
3c824109
NF
15129 break;
15130 default:
15131 goto pool32axf_invalid;
15132 }
15133 break;
a1fc6246 15134 case 0x01:
26135ead 15135 switch (minor & 3) {
a1fc6246 15136 case MFHI_ACC:
26135ead 15137 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 15138 break;
a1fc6246 15139 case MFLO_ACC:
26135ead 15140 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 15141 break;
a1fc6246 15142 case MTHI_ACC:
26135ead 15143 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 15144 break;
a1fc6246 15145 case MTLO_ACC:
26135ead 15146 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
15147 break;
15148 default:
15149 goto pool32axf_invalid;
15150 }
15151 break;
a1fc6246 15152 case 0x35:
9e8f441a 15153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
15154 switch (minor) {
15155 case MFHI32:
15156 gen_HILO(ctx, OPC_MFHI, 0, rs);
15157 break;
15158 case MFLO32:
15159 gen_HILO(ctx, OPC_MFLO, 0, rs);
15160 break;
15161 case MTHI32:
15162 gen_HILO(ctx, OPC_MTHI, 0, rs);
15163 break;
15164 case MTLO32:
15165 gen_HILO(ctx, OPC_MTLO, 0, rs);
15166 break;
15167 default:
15168 goto pool32axf_invalid;
15169 }
15170 break;
3c824109
NF
15171 default:
15172 pool32axf_invalid:
15173 MIPS_INVAL("pool32axf");
9c708c7f 15174 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15175 break;
15176 }
15177}
15178
15179/* Values for microMIPS fmt field. Variable-width, depending on which
15180 formats the instruction supports. */
15181
15182enum {
15183 FMT_SD_S = 0,
15184 FMT_SD_D = 1,
15185
15186 FMT_SDPS_S = 0,
15187 FMT_SDPS_D = 1,
15188 FMT_SDPS_PS = 2,
15189
15190 FMT_SWL_S = 0,
15191 FMT_SWL_W = 1,
15192 FMT_SWL_L = 2,
15193
15194 FMT_DWL_D = 0,
15195 FMT_DWL_W = 1,
15196 FMT_DWL_L = 2
15197};
15198
d75c135e 15199static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
15200{
15201 int extension = (ctx->opcode >> 6) & 0x3ff;
15202 uint32_t mips32_op;
15203
15204#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15205#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15206#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15207
15208 switch (extension) {
15209 case FLOAT_1BIT_FMT(CFC1, 0):
15210 mips32_op = OPC_CFC1;
15211 goto do_cp1;
15212 case FLOAT_1BIT_FMT(CTC1, 0):
15213 mips32_op = OPC_CTC1;
15214 goto do_cp1;
15215 case FLOAT_1BIT_FMT(MFC1, 0):
15216 mips32_op = OPC_MFC1;
15217 goto do_cp1;
15218 case FLOAT_1BIT_FMT(MTC1, 0):
15219 mips32_op = OPC_MTC1;
15220 goto do_cp1;
15221 case FLOAT_1BIT_FMT(MFHC1, 0):
15222 mips32_op = OPC_MFHC1;
15223 goto do_cp1;
15224 case FLOAT_1BIT_FMT(MTHC1, 0):
15225 mips32_op = OPC_MTHC1;
15226 do_cp1:
15227 gen_cp1(ctx, mips32_op, rt, rs);
15228 break;
15229
15230 /* Reciprocal square root */
15231 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15232 mips32_op = OPC_RSQRT_S;
15233 goto do_unaryfp;
15234 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15235 mips32_op = OPC_RSQRT_D;
15236 goto do_unaryfp;
15237
15238 /* Square root */
15239 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15240 mips32_op = OPC_SQRT_S;
15241 goto do_unaryfp;
15242 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15243 mips32_op = OPC_SQRT_D;
15244 goto do_unaryfp;
15245
15246 /* Reciprocal */
15247 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15248 mips32_op = OPC_RECIP_S;
15249 goto do_unaryfp;
15250 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15251 mips32_op = OPC_RECIP_D;
15252 goto do_unaryfp;
15253
15254 /* Floor */
15255 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15256 mips32_op = OPC_FLOOR_L_S;
15257 goto do_unaryfp;
15258 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15259 mips32_op = OPC_FLOOR_L_D;
15260 goto do_unaryfp;
15261 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15262 mips32_op = OPC_FLOOR_W_S;
15263 goto do_unaryfp;
15264 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15265 mips32_op = OPC_FLOOR_W_D;
15266 goto do_unaryfp;
15267
15268 /* Ceiling */
15269 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15270 mips32_op = OPC_CEIL_L_S;
15271 goto do_unaryfp;
15272 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15273 mips32_op = OPC_CEIL_L_D;
15274 goto do_unaryfp;
15275 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15276 mips32_op = OPC_CEIL_W_S;
15277 goto do_unaryfp;
15278 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15279 mips32_op = OPC_CEIL_W_D;
15280 goto do_unaryfp;
15281
15282 /* Truncation */
15283 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15284 mips32_op = OPC_TRUNC_L_S;
15285 goto do_unaryfp;
15286 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15287 mips32_op = OPC_TRUNC_L_D;
15288 goto do_unaryfp;
15289 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15290 mips32_op = OPC_TRUNC_W_S;
15291 goto do_unaryfp;
15292 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15293 mips32_op = OPC_TRUNC_W_D;
15294 goto do_unaryfp;
15295
15296 /* Round */
15297 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15298 mips32_op = OPC_ROUND_L_S;
15299 goto do_unaryfp;
15300 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15301 mips32_op = OPC_ROUND_L_D;
15302 goto do_unaryfp;
15303 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15304 mips32_op = OPC_ROUND_W_S;
15305 goto do_unaryfp;
15306 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15307 mips32_op = OPC_ROUND_W_D;
15308 goto do_unaryfp;
15309
15310 /* Integer to floating-point conversion */
15311 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15312 mips32_op = OPC_CVT_L_S;
15313 goto do_unaryfp;
15314 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15315 mips32_op = OPC_CVT_L_D;
15316 goto do_unaryfp;
15317 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15318 mips32_op = OPC_CVT_W_S;
15319 goto do_unaryfp;
15320 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15321 mips32_op = OPC_CVT_W_D;
15322 goto do_unaryfp;
15323
15324 /* Paired-foo conversions */
15325 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15326 mips32_op = OPC_CVT_S_PL;
15327 goto do_unaryfp;
15328 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15329 mips32_op = OPC_CVT_S_PU;
15330 goto do_unaryfp;
15331 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15332 mips32_op = OPC_CVT_PW_PS;
15333 goto do_unaryfp;
15334 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15335 mips32_op = OPC_CVT_PS_PW;
15336 goto do_unaryfp;
15337
15338 /* Floating-point moves */
15339 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15340 mips32_op = OPC_MOV_S;
15341 goto do_unaryfp;
15342 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15343 mips32_op = OPC_MOV_D;
15344 goto do_unaryfp;
15345 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15346 mips32_op = OPC_MOV_PS;
15347 goto do_unaryfp;
15348
15349 /* Absolute value */
15350 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15351 mips32_op = OPC_ABS_S;
15352 goto do_unaryfp;
15353 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15354 mips32_op = OPC_ABS_D;
15355 goto do_unaryfp;
15356 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15357 mips32_op = OPC_ABS_PS;
15358 goto do_unaryfp;
15359
15360 /* Negation */
15361 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15362 mips32_op = OPC_NEG_S;
15363 goto do_unaryfp;
15364 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15365 mips32_op = OPC_NEG_D;
15366 goto do_unaryfp;
15367 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15368 mips32_op = OPC_NEG_PS;
15369 goto do_unaryfp;
15370
15371 /* Reciprocal square root step */
15372 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15373 mips32_op = OPC_RSQRT1_S;
15374 goto do_unaryfp;
15375 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15376 mips32_op = OPC_RSQRT1_D;
15377 goto do_unaryfp;
15378 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15379 mips32_op = OPC_RSQRT1_PS;
15380 goto do_unaryfp;
15381
15382 /* Reciprocal step */
15383 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15384 mips32_op = OPC_RECIP1_S;
15385 goto do_unaryfp;
15386 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15387 mips32_op = OPC_RECIP1_S;
15388 goto do_unaryfp;
15389 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15390 mips32_op = OPC_RECIP1_PS;
15391 goto do_unaryfp;
15392
15393 /* Conversions from double */
15394 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15395 mips32_op = OPC_CVT_D_S;
15396 goto do_unaryfp;
15397 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15398 mips32_op = OPC_CVT_D_W;
15399 goto do_unaryfp;
15400 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15401 mips32_op = OPC_CVT_D_L;
15402 goto do_unaryfp;
15403
15404 /* Conversions from single */
15405 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15406 mips32_op = OPC_CVT_S_D;
15407 goto do_unaryfp;
15408 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15409 mips32_op = OPC_CVT_S_W;
15410 goto do_unaryfp;
15411 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15412 mips32_op = OPC_CVT_S_L;
15413 do_unaryfp:
15414 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15415 break;
15416
15417 /* Conditional moves on floating-point codes */
15418 case COND_FLOAT_MOV(MOVT, 0):
15419 case COND_FLOAT_MOV(MOVT, 1):
15420 case COND_FLOAT_MOV(MOVT, 2):
15421 case COND_FLOAT_MOV(MOVT, 3):
15422 case COND_FLOAT_MOV(MOVT, 4):
15423 case COND_FLOAT_MOV(MOVT, 5):
15424 case COND_FLOAT_MOV(MOVT, 6):
15425 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 15426 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15427 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15428 break;
15429 case COND_FLOAT_MOV(MOVF, 0):
15430 case COND_FLOAT_MOV(MOVF, 1):
15431 case COND_FLOAT_MOV(MOVF, 2):
15432 case COND_FLOAT_MOV(MOVF, 3):
15433 case COND_FLOAT_MOV(MOVF, 4):
15434 case COND_FLOAT_MOV(MOVF, 5):
15435 case COND_FLOAT_MOV(MOVF, 6):
15436 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 15437 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15438 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15439 break;
15440 default:
15441 MIPS_INVAL("pool32fxf");
9c708c7f 15442 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15443 break;
15444 }
15445}
15446
f60eeb0c 15447static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15448{
15449 int32_t offset;
15450 uint16_t insn;
15451 int rt, rs, rd, rr;
15452 int16_t imm;
8fffc646 15453 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
15454 uint32_t cond, fmt, cc;
15455
eeb3bba8 15456 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
15457 ctx->opcode = (ctx->opcode << 16) | insn;
15458
15459 rt = (ctx->opcode >> 21) & 0x1f;
15460 rs = (ctx->opcode >> 16) & 0x1f;
15461 rd = (ctx->opcode >> 11) & 0x1f;
15462 rr = (ctx->opcode >> 6) & 0x1f;
15463 imm = (int16_t) ctx->opcode;
15464
15465 op = (ctx->opcode >> 26) & 0x3f;
15466 switch (op) {
15467 case POOL32A:
15468 minor = ctx->opcode & 0x3f;
15469 switch (minor) {
15470 case 0x00:
15471 minor = (ctx->opcode >> 6) & 0xf;
15472 switch (minor) {
15473 case SLL32:
15474 mips32_op = OPC_SLL;
15475 goto do_shifti;
15476 case SRA:
15477 mips32_op = OPC_SRA;
15478 goto do_shifti;
15479 case SRL32:
15480 mips32_op = OPC_SRL;
15481 goto do_shifti;
15482 case ROTR:
15483 mips32_op = OPC_ROTR;
15484 do_shifti:
d75c135e 15485 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 15486 break;
e0332095
YK
15487 case SELEQZ:
15488 check_insn(ctx, ISA_MIPS32R6);
15489 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15490 break;
15491 case SELNEZ:
15492 check_insn(ctx, ISA_MIPS32R6);
15493 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15494 break;
b00c7218
YK
15495 case R6_RDHWR:
15496 check_insn(ctx, ISA_MIPS32R6);
15497 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15498 break;
3c824109
NF
15499 default:
15500 goto pool32a_invalid;
15501 }
15502 break;
15503 case 0x10:
15504 minor = (ctx->opcode >> 6) & 0xf;
15505 switch (minor) {
15506 /* Arithmetic */
15507 case ADD:
15508 mips32_op = OPC_ADD;
15509 goto do_arith;
15510 case ADDU32:
15511 mips32_op = OPC_ADDU;
15512 goto do_arith;
15513 case SUB:
15514 mips32_op = OPC_SUB;
15515 goto do_arith;
15516 case SUBU32:
15517 mips32_op = OPC_SUBU;
15518 goto do_arith;
15519 case MUL:
9e8f441a 15520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15521 mips32_op = OPC_MUL;
15522 do_arith:
d75c135e 15523 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15524 break;
15525 /* Shifts */
15526 case SLLV:
15527 mips32_op = OPC_SLLV;
15528 goto do_shift;
15529 case SRLV:
15530 mips32_op = OPC_SRLV;
15531 goto do_shift;
15532 case SRAV:
15533 mips32_op = OPC_SRAV;
15534 goto do_shift;
15535 case ROTRV:
15536 mips32_op = OPC_ROTRV;
15537 do_shift:
d75c135e 15538 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15539 break;
15540 /* Logical operations */
15541 case AND:
15542 mips32_op = OPC_AND;
15543 goto do_logic;
15544 case OR32:
15545 mips32_op = OPC_OR;
15546 goto do_logic;
15547 case NOR:
15548 mips32_op = OPC_NOR;
15549 goto do_logic;
15550 case XOR32:
15551 mips32_op = OPC_XOR;
15552 do_logic:
d75c135e 15553 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15554 break;
15555 /* Set less than */
15556 case SLT:
15557 mips32_op = OPC_SLT;
15558 goto do_slt;
15559 case SLTU:
15560 mips32_op = OPC_SLTU;
15561 do_slt:
d75c135e 15562 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15563 break;
15564 default:
15565 goto pool32a_invalid;
15566 }
15567 break;
15568 case 0x18:
15569 minor = (ctx->opcode >> 6) & 0xf;
15570 switch (minor) {
15571 /* Conditional moves */
e0332095
YK
15572 case MOVN: /* MUL */
15573 if (ctx->insn_flags & ISA_MIPS32R6) {
15574 /* MUL */
15575 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15576 } else {
15577 /* MOVN */
15578 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15579 }
15580 break;
15581 case MOVZ: /* MUH */
15582 if (ctx->insn_flags & ISA_MIPS32R6) {
15583 /* MUH */
15584 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15585 } else {
15586 /* MOVZ */
15587 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15588 }
15589 break;
15590 case MULU:
15591 check_insn(ctx, ISA_MIPS32R6);
15592 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15593 break;
15594 case MUHU:
15595 check_insn(ctx, ISA_MIPS32R6);
15596 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15597 break;
15598 case LWXS: /* DIV */
15599 if (ctx->insn_flags & ISA_MIPS32R6) {
15600 /* DIV */
15601 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15602 } else {
15603 /* LWXS */
15604 gen_ldxs(ctx, rs, rt, rd);
15605 }
15606 break;
15607 case MOD:
15608 check_insn(ctx, ISA_MIPS32R6);
15609 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15610 break;
15611 case R6_DIVU:
15612 check_insn(ctx, ISA_MIPS32R6);
15613 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 15614 break;
e0332095
YK
15615 case MODU:
15616 check_insn(ctx, ISA_MIPS32R6);
15617 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
15618 break;
15619 default:
15620 goto pool32a_invalid;
15621 }
15622 break;
15623 case INS:
15624 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15625 return;
e0332095
YK
15626 case LSA:
15627 check_insn(ctx, ISA_MIPS32R6);
15628 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15629 extract32(ctx->opcode, 9, 2));
15630 break;
15631 case ALIGN:
15632 check_insn(ctx, ISA_MIPS32R6);
821f2008 15633 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 15634 break;
3c824109
NF
15635 case EXT:
15636 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15637 return;
15638 case POOL32AXF:
240ce26a 15639 gen_pool32axf(env, ctx, rt, rs);
3c824109 15640 break;
dbd8af98 15641 case BREAK32:
9c708c7f 15642 generate_exception_end(ctx, EXCP_BREAK);
3c824109 15643 break;
bb238210
YK
15644 case SIGRIE:
15645 check_insn(ctx, ISA_MIPS32R6);
15646 generate_exception_end(ctx, EXCP_RI);
15647 break;
3c824109
NF
15648 default:
15649 pool32a_invalid:
15650 MIPS_INVAL("pool32a");
9c708c7f 15651 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15652 break;
15653 }
15654 break;
15655 case POOL32B:
15656 minor = (ctx->opcode >> 12) & 0xf;
15657 switch (minor) {
15658 case CACHE:
2e15497c 15659 check_cp0_enabled(ctx);
0d74a222
LA
15660 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15661 gen_cache_operation(ctx, rt, rs, imm);
15662 }
3c824109
NF
15663 break;
15664 case LWC2:
15665 case SWC2:
15666 /* COP2: Not implemented. */
15667 generate_exception_err(ctx, EXCP_CpU, 2);
15668 break;
3c824109
NF
15669#ifdef TARGET_MIPS64
15670 case LDP:
15671 case SDP:
d9224450
MR
15672 check_insn(ctx, ISA_MIPS3);
15673 check_mips_64(ctx);
3c824109 15674#endif
146dd620 15675 /* fall through */
d9224450
MR
15676 case LWP:
15677 case SWP:
3c824109
NF
15678 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15679 break;
3c824109
NF
15680#ifdef TARGET_MIPS64
15681 case LDM:
15682 case SDM:
d9224450
MR
15683 check_insn(ctx, ISA_MIPS3);
15684 check_mips_64(ctx);
3c824109 15685#endif
146dd620 15686 /* fall through */
d9224450
MR
15687 case LWM32:
15688 case SWM32:
3c824109
NF
15689 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15690 break;
15691 default:
15692 MIPS_INVAL("pool32b");
9c708c7f 15693 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15694 break;
15695 }
15696 break;
15697 case POOL32F:
5ab5c041 15698 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
15699 minor = ctx->opcode & 0x3f;
15700 check_cp1_enabled(ctx);
15701 switch (minor) {
15702 case ALNV_PS:
9e8f441a 15703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15704 mips32_op = OPC_ALNV_PS;
15705 goto do_madd;
15706 case MADD_S:
9e8f441a 15707 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15708 mips32_op = OPC_MADD_S;
15709 goto do_madd;
15710 case MADD_D:
9e8f441a 15711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15712 mips32_op = OPC_MADD_D;
15713 goto do_madd;
15714 case MADD_PS:
9e8f441a 15715 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15716 mips32_op = OPC_MADD_PS;
15717 goto do_madd;
15718 case MSUB_S:
9e8f441a 15719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15720 mips32_op = OPC_MSUB_S;
15721 goto do_madd;
15722 case MSUB_D:
9e8f441a 15723 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15724 mips32_op = OPC_MSUB_D;
15725 goto do_madd;
15726 case MSUB_PS:
9e8f441a 15727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15728 mips32_op = OPC_MSUB_PS;
15729 goto do_madd;
15730 case NMADD_S:
9e8f441a 15731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15732 mips32_op = OPC_NMADD_S;
15733 goto do_madd;
15734 case NMADD_D:
9e8f441a 15735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15736 mips32_op = OPC_NMADD_D;
15737 goto do_madd;
15738 case NMADD_PS:
9e8f441a 15739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15740 mips32_op = OPC_NMADD_PS;
15741 goto do_madd;
15742 case NMSUB_S:
9e8f441a 15743 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15744 mips32_op = OPC_NMSUB_S;
15745 goto do_madd;
15746 case NMSUB_D:
9e8f441a 15747 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15748 mips32_op = OPC_NMSUB_D;
15749 goto do_madd;
15750 case NMSUB_PS:
9e8f441a 15751 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15752 mips32_op = OPC_NMSUB_PS;
15753 do_madd:
15754 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15755 break;
15756 case CABS_COND_FMT:
9e8f441a 15757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15758 cond = (ctx->opcode >> 6) & 0xf;
15759 cc = (ctx->opcode >> 13) & 0x7;
15760 fmt = (ctx->opcode >> 10) & 0x3;
15761 switch (fmt) {
15762 case 0x0:
15763 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15764 break;
15765 case 0x1:
15766 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15767 break;
15768 case 0x2:
15769 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15770 break;
15771 default:
15772 goto pool32f_invalid;
15773 }
15774 break;
15775 case C_COND_FMT:
9e8f441a 15776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15777 cond = (ctx->opcode >> 6) & 0xf;
15778 cc = (ctx->opcode >> 13) & 0x7;
15779 fmt = (ctx->opcode >> 10) & 0x3;
15780 switch (fmt) {
15781 case 0x0:
15782 gen_cmp_s(ctx, cond, rt, rs, cc);
15783 break;
15784 case 0x1:
15785 gen_cmp_d(ctx, cond, rt, rs, cc);
15786 break;
15787 case 0x2:
15788 gen_cmp_ps(ctx, cond, rt, rs, cc);
15789 break;
15790 default:
15791 goto pool32f_invalid;
15792 }
15793 break;
2a24a7ba
YK
15794 case CMP_CONDN_S:
15795 check_insn(ctx, ISA_MIPS32R6);
15796 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15797 break;
15798 case CMP_CONDN_D:
15799 check_insn(ctx, ISA_MIPS32R6);
15800 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15801 break;
3c824109 15802 case POOL32FXF:
d75c135e 15803 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
15804 break;
15805 case 0x00:
15806 /* PLL foo */
15807 switch ((ctx->opcode >> 6) & 0x7) {
15808 case PLL_PS:
15809 mips32_op = OPC_PLL_PS;
15810 goto do_ps;
15811 case PLU_PS:
15812 mips32_op = OPC_PLU_PS;
15813 goto do_ps;
15814 case PUL_PS:
15815 mips32_op = OPC_PUL_PS;
15816 goto do_ps;
15817 case PUU_PS:
15818 mips32_op = OPC_PUU_PS;
15819 goto do_ps;
15820 case CVT_PS_S:
9e8f441a 15821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15822 mips32_op = OPC_CVT_PS_S;
15823 do_ps:
15824 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15825 break;
15826 default:
15827 goto pool32f_invalid;
15828 }
15829 break;
2a24a7ba
YK
15830 case MIN_FMT:
15831 check_insn(ctx, ISA_MIPS32R6);
15832 switch ((ctx->opcode >> 9) & 0x3) {
15833 case FMT_SDPS_S:
15834 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15835 break;
15836 case FMT_SDPS_D:
15837 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15838 break;
15839 default:
15840 goto pool32f_invalid;
15841 }
15842 break;
3c824109
NF
15843 case 0x08:
15844 /* [LS][WDU]XC1 */
15845 switch ((ctx->opcode >> 6) & 0x7) {
15846 case LWXC1:
9e8f441a 15847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15848 mips32_op = OPC_LWXC1;
15849 goto do_ldst_cp1;
15850 case SWXC1:
9e8f441a 15851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15852 mips32_op = OPC_SWXC1;
15853 goto do_ldst_cp1;
15854 case LDXC1:
9e8f441a 15855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15856 mips32_op = OPC_LDXC1;
15857 goto do_ldst_cp1;
15858 case SDXC1:
9e8f441a 15859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15860 mips32_op = OPC_SDXC1;
15861 goto do_ldst_cp1;
15862 case LUXC1:
9e8f441a 15863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15864 mips32_op = OPC_LUXC1;
15865 goto do_ldst_cp1;
15866 case SUXC1:
9e8f441a 15867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15868 mips32_op = OPC_SUXC1;
15869 do_ldst_cp1:
15870 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15871 break;
15872 default:
15873 goto pool32f_invalid;
15874 }
15875 break;
2a24a7ba
YK
15876 case MAX_FMT:
15877 check_insn(ctx, ISA_MIPS32R6);
15878 switch ((ctx->opcode >> 9) & 0x3) {
15879 case FMT_SDPS_S:
15880 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15881 break;
15882 case FMT_SDPS_D:
15883 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15884 break;
15885 default:
15886 goto pool32f_invalid;
15887 }
15888 break;
3c824109
NF
15889 case 0x18:
15890 /* 3D insns */
9e8f441a 15891 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15892 fmt = (ctx->opcode >> 9) & 0x3;
15893 switch ((ctx->opcode >> 6) & 0x7) {
15894 case RSQRT2_FMT:
15895 switch (fmt) {
15896 case FMT_SDPS_S:
15897 mips32_op = OPC_RSQRT2_S;
15898 goto do_3d;
15899 case FMT_SDPS_D:
15900 mips32_op = OPC_RSQRT2_D;
15901 goto do_3d;
15902 case FMT_SDPS_PS:
15903 mips32_op = OPC_RSQRT2_PS;
15904 goto do_3d;
15905 default:
15906 goto pool32f_invalid;
15907 }
15908 break;
15909 case RECIP2_FMT:
15910 switch (fmt) {
15911 case FMT_SDPS_S:
15912 mips32_op = OPC_RECIP2_S;
15913 goto do_3d;
15914 case FMT_SDPS_D:
15915 mips32_op = OPC_RECIP2_D;
15916 goto do_3d;
15917 case FMT_SDPS_PS:
15918 mips32_op = OPC_RECIP2_PS;
15919 goto do_3d;
15920 default:
15921 goto pool32f_invalid;
15922 }
15923 break;
15924 case ADDR_PS:
15925 mips32_op = OPC_ADDR_PS;
15926 goto do_3d;
15927 case MULR_PS:
15928 mips32_op = OPC_MULR_PS;
15929 do_3d:
15930 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15931 break;
15932 default:
15933 goto pool32f_invalid;
15934 }
15935 break;
15936 case 0x20:
2a24a7ba 15937 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
15938 cc = (ctx->opcode >> 13) & 0x7;
15939 fmt = (ctx->opcode >> 9) & 0x3;
15940 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
15941 case MOVF_FMT: /* RINT_FMT */
15942 if (ctx->insn_flags & ISA_MIPS32R6) {
15943 /* RINT_FMT */
15944 switch (fmt) {
15945 case FMT_SDPS_S:
15946 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15947 break;
15948 case FMT_SDPS_D:
15949 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15950 break;
15951 default:
15952 goto pool32f_invalid;
15953 }
15954 } else {
15955 /* MOVF_FMT */
15956 switch (fmt) {
15957 case FMT_SDPS_S:
15958 gen_movcf_s(ctx, rs, rt, cc, 0);
15959 break;
15960 case FMT_SDPS_D:
15961 gen_movcf_d(ctx, rs, rt, cc, 0);
15962 break;
15963 case FMT_SDPS_PS:
15964 check_ps(ctx);
15965 gen_movcf_ps(ctx, rs, rt, cc, 0);
15966 break;
15967 default:
15968 goto pool32f_invalid;
15969 }
3c824109
NF
15970 }
15971 break;
2a24a7ba
YK
15972 case MOVT_FMT: /* CLASS_FMT */
15973 if (ctx->insn_flags & ISA_MIPS32R6) {
15974 /* CLASS_FMT */
15975 switch (fmt) {
15976 case FMT_SDPS_S:
15977 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15978 break;
15979 case FMT_SDPS_D:
15980 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15981 break;
15982 default:
15983 goto pool32f_invalid;
15984 }
15985 } else {
15986 /* MOVT_FMT */
15987 switch (fmt) {
15988 case FMT_SDPS_S:
15989 gen_movcf_s(ctx, rs, rt, cc, 1);
15990 break;
15991 case FMT_SDPS_D:
15992 gen_movcf_d(ctx, rs, rt, cc, 1);
15993 break;
15994 case FMT_SDPS_PS:
15995 check_ps(ctx);
15996 gen_movcf_ps(ctx, rs, rt, cc, 1);
15997 break;
15998 default:
15999 goto pool32f_invalid;
16000 }
3c824109
NF
16001 }
16002 break;
16003 case PREFX:
9e8f441a 16004 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16005 break;
16006 default:
16007 goto pool32f_invalid;
16008 }
16009 break;
16010#define FINSN_3ARG_SDPS(prfx) \
16011 switch ((ctx->opcode >> 8) & 0x3) { \
16012 case FMT_SDPS_S: \
16013 mips32_op = OPC_##prfx##_S; \
16014 goto do_fpop; \
16015 case FMT_SDPS_D: \
16016 mips32_op = OPC_##prfx##_D; \
16017 goto do_fpop; \
16018 case FMT_SDPS_PS: \
e29c9628 16019 check_ps(ctx); \
3c824109
NF
16020 mips32_op = OPC_##prfx##_PS; \
16021 goto do_fpop; \
16022 default: \
16023 goto pool32f_invalid; \
16024 }
2a24a7ba
YK
16025 case MINA_FMT:
16026 check_insn(ctx, ISA_MIPS32R6);
16027 switch ((ctx->opcode >> 9) & 0x3) {
16028 case FMT_SDPS_S:
16029 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16030 break;
16031 case FMT_SDPS_D:
16032 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16033 break;
16034 default:
16035 goto pool32f_invalid;
16036 }
16037 break;
16038 case MAXA_FMT:
16039 check_insn(ctx, ISA_MIPS32R6);
16040 switch ((ctx->opcode >> 9) & 0x3) {
16041 case FMT_SDPS_S:
16042 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16043 break;
16044 case FMT_SDPS_D:
16045 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16046 break;
16047 default:
16048 goto pool32f_invalid;
16049 }
16050 break;
3c824109
NF
16051 case 0x30:
16052 /* regular FP ops */
16053 switch ((ctx->opcode >> 6) & 0x3) {
16054 case ADD_FMT:
16055 FINSN_3ARG_SDPS(ADD);
16056 break;
16057 case SUB_FMT:
16058 FINSN_3ARG_SDPS(SUB);
16059 break;
16060 case MUL_FMT:
16061 FINSN_3ARG_SDPS(MUL);
16062 break;
16063 case DIV_FMT:
16064 fmt = (ctx->opcode >> 8) & 0x3;
16065 if (fmt == 1) {
16066 mips32_op = OPC_DIV_D;
16067 } else if (fmt == 0) {
16068 mips32_op = OPC_DIV_S;
16069 } else {
16070 goto pool32f_invalid;
16071 }
16072 goto do_fpop;
16073 default:
16074 goto pool32f_invalid;
16075 }
16076 break;
16077 case 0x38:
16078 /* cmovs */
2a24a7ba 16079 switch ((ctx->opcode >> 6) & 0x7) {
fdac60cd 16080 case MOVN_FMT: /* SELEQZ_FMT */
2a24a7ba 16081 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16082 /* SELEQZ_FMT */
2a24a7ba
YK
16083 switch ((ctx->opcode >> 9) & 0x3) {
16084 case FMT_SDPS_S:
fdac60cd 16085 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2a24a7ba
YK
16086 break;
16087 case FMT_SDPS_D:
fdac60cd 16088 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2a24a7ba
YK
16089 break;
16090 default:
16091 goto pool32f_invalid;
16092 }
16093 } else {
16094 /* MOVN_FMT */
16095 FINSN_3ARG_SDPS(MOVN);
16096 }
16097 break;
16098 case MOVN_FMT_04:
16099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16100 FINSN_3ARG_SDPS(MOVN);
16101 break;
fdac60cd 16102 case MOVZ_FMT: /* SELNEZ_FMT */
2a24a7ba 16103 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16104 /* SELNEZ_FMT */
2a24a7ba
YK
16105 switch ((ctx->opcode >> 9) & 0x3) {
16106 case FMT_SDPS_S:
fdac60cd 16107 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2a24a7ba
YK
16108 break;
16109 case FMT_SDPS_D:
fdac60cd 16110 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2a24a7ba
YK
16111 break;
16112 default:
16113 goto pool32f_invalid;
16114 }
16115 } else {
16116 /* MOVZ_FMT */
16117 FINSN_3ARG_SDPS(MOVZ);
16118 }
16119 break;
16120 case MOVZ_FMT_05:
16121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16122 FINSN_3ARG_SDPS(MOVZ);
16123 break;
2a24a7ba
YK
16124 case SEL_FMT:
16125 check_insn(ctx, ISA_MIPS32R6);
16126 switch ((ctx->opcode >> 9) & 0x3) {
16127 case FMT_SDPS_S:
16128 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16129 break;
16130 case FMT_SDPS_D:
16131 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16132 break;
16133 default:
16134 goto pool32f_invalid;
16135 }
16136 break;
16137 case MADDF_FMT:
16138 check_insn(ctx, ISA_MIPS32R6);
16139 switch ((ctx->opcode >> 9) & 0x3) {
16140 case FMT_SDPS_S:
16141 mips32_op = OPC_MADDF_S;
16142 goto do_fpop;
16143 case FMT_SDPS_D:
16144 mips32_op = OPC_MADDF_D;
16145 goto do_fpop;
16146 default:
16147 goto pool32f_invalid;
16148 }
16149 break;
16150 case MSUBF_FMT:
16151 check_insn(ctx, ISA_MIPS32R6);
16152 switch ((ctx->opcode >> 9) & 0x3) {
16153 case FMT_SDPS_S:
16154 mips32_op = OPC_MSUBF_S;
16155 goto do_fpop;
16156 case FMT_SDPS_D:
16157 mips32_op = OPC_MSUBF_D;
16158 goto do_fpop;
16159 default:
16160 goto pool32f_invalid;
16161 }
16162 break;
3c824109
NF
16163 default:
16164 goto pool32f_invalid;
16165 }
16166 break;
16167 do_fpop:
16168 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16169 break;
16170 default:
16171 pool32f_invalid:
16172 MIPS_INVAL("pool32f");
9c708c7f 16173 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16174 break;
16175 }
16176 } else {
16177 generate_exception_err(ctx, EXCP_CpU, 1);
16178 }
16179 break;
16180 case POOL32I:
16181 minor = (ctx->opcode >> 21) & 0x1f;
16182 switch (minor) {
16183 case BLTZ:
9e8f441a 16184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16185 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16186 break;
3c824109 16187 case BLTZAL:
9e8f441a 16188 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16189 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16190 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16191 break;
3c824109 16192 case BLTZALS:
9e8f441a 16193 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16194 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16195 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16196 break;
3c824109 16197 case BGEZ:
9e8f441a 16198 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16199 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16200 break;
3c824109 16201 case BGEZAL:
9e8f441a 16202 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16203 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16204 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16205 break;
3c824109 16206 case BGEZALS:
9e8f441a 16207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16208 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16209 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16210 break;
3c824109 16211 case BLEZ:
9e8f441a 16212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16213 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16214 break;
3c824109 16215 case BGTZ:
9e8f441a 16216 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 16217 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
16218 break;
16219
16220 /* Traps */
65935f07
YK
16221 case TLTI: /* BC1EQZC */
16222 if (ctx->insn_flags & ISA_MIPS32R6) {
16223 /* BC1EQZC */
16224 check_cp1_enabled(ctx);
16225 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16226 } else {
16227 /* TLTI */
16228 mips32_op = OPC_TLTI;
16229 goto do_trapi;
16230 }
16231 break;
16232 case TGEI: /* BC1NEZC */
16233 if (ctx->insn_flags & ISA_MIPS32R6) {
16234 /* BC1NEZC */
16235 check_cp1_enabled(ctx);
16236 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16237 } else {
16238 /* TGEI */
16239 mips32_op = OPC_TGEI;
16240 goto do_trapi;
16241 }
16242 break;
3c824109 16243 case TLTIU:
9e8f441a 16244 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16245 mips32_op = OPC_TLTIU;
16246 goto do_trapi;
16247 case TGEIU:
9e8f441a 16248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16249 mips32_op = OPC_TGEIU;
16250 goto do_trapi;
3b4a5489
YK
16251 case TNEI: /* SYNCI */
16252 if (ctx->insn_flags & ISA_MIPS32R6) {
16253 /* SYNCI */
16254 /* Break the TB to be able to sync copied instructions
16255 immediately */
eeb3bba8 16256 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
16257 } else {
16258 /* TNEI */
16259 mips32_op = OPC_TNEI;
16260 goto do_trapi;
16261 }
16262 break;
3c824109 16263 case TEQI:
9e8f441a 16264 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16265 mips32_op = OPC_TEQI;
16266 do_trapi:
16267 gen_trap(ctx, mips32_op, rs, -1, imm);
16268 break;
16269
16270 case BNEZC:
16271 case BEQZC:
9e8f441a 16272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16273 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 16274 4, rs, 0, imm << 1, 0);
3c824109
NF
16275 /* Compact branches don't have a delay slot, so just let
16276 the normal delay slot handling take us to the branch
16277 target. */
16278 break;
16279 case LUI:
9e8f441a 16280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 16281 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
16282 break;
16283 case SYNCI:
9e8f441a 16284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
16285 /* Break the TB to be able to sync copied instructions
16286 immediately */
eeb3bba8 16287 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
16288 break;
16289 case BC2F:
16290 case BC2T:
9e8f441a 16291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16292 /* COP2: Not implemented. */
16293 generate_exception_err(ctx, EXCP_CpU, 2);
16294 break;
16295 case BC1F:
9e8f441a 16296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16297 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16298 goto do_cp1branch;
16299 case BC1T:
9e8f441a 16300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16301 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16302 goto do_cp1branch;
16303 case BC1ANY4F:
9e8f441a 16304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16305 mips32_op = OPC_BC1FANY4;
16306 goto do_cp1mips3d;
16307 case BC1ANY4T:
9e8f441a 16308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16309 mips32_op = OPC_BC1TANY4;
16310 do_cp1mips3d:
16311 check_cop1x(ctx);
d75c135e 16312 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
16313 /* Fall through */
16314 do_cp1branch:
272f458d
MR
16315 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16316 check_cp1_enabled(ctx);
16317 gen_compute_branch1(ctx, mips32_op,
16318 (ctx->opcode >> 18) & 0x7, imm << 1);
16319 } else {
16320 generate_exception_err(ctx, EXCP_CpU, 1);
16321 }
3c824109
NF
16322 break;
16323 case BPOSGE64:
16324 case BPOSGE32:
16325 /* MIPS DSP: not implemented */
16326 /* Fall through */
16327 default:
16328 MIPS_INVAL("pool32i");
9c708c7f 16329 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16330 break;
16331 }
16332 break;
16333 case POOL32C:
16334 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
16335 offset = sextract32(ctx->opcode, 0,
16336 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
16337 switch (minor) {
16338 case LWL:
9e8f441a 16339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16340 mips32_op = OPC_LWL;
5c13fdfd 16341 goto do_ld_lr;
3c824109 16342 case SWL:
9e8f441a 16343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16344 mips32_op = OPC_SWL;
5c13fdfd 16345 goto do_st_lr;
3c824109 16346 case LWR:
9e8f441a 16347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16348 mips32_op = OPC_LWR;
5c13fdfd 16349 goto do_ld_lr;
3c824109 16350 case SWR:
9e8f441a 16351 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16352 mips32_op = OPC_SWR;
5c13fdfd 16353 goto do_st_lr;
3c824109
NF
16354#if defined(TARGET_MIPS64)
16355 case LDL:
d9224450
MR
16356 check_insn(ctx, ISA_MIPS3);
16357 check_mips_64(ctx);
9e8f441a 16358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16359 mips32_op = OPC_LDL;
5c13fdfd 16360 goto do_ld_lr;
3c824109 16361 case SDL:
d9224450
MR
16362 check_insn(ctx, ISA_MIPS3);
16363 check_mips_64(ctx);
9e8f441a 16364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16365 mips32_op = OPC_SDL;
5c13fdfd 16366 goto do_st_lr;
3c824109 16367 case LDR:
d9224450
MR
16368 check_insn(ctx, ISA_MIPS3);
16369 check_mips_64(ctx);
9e8f441a 16370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16371 mips32_op = OPC_LDR;
5c13fdfd 16372 goto do_ld_lr;
3c824109 16373 case SDR:
d9224450
MR
16374 check_insn(ctx, ISA_MIPS3);
16375 check_mips_64(ctx);
9e8f441a 16376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16377 mips32_op = OPC_SDR;
5c13fdfd 16378 goto do_st_lr;
3c824109 16379 case LWU:
d9224450
MR
16380 check_insn(ctx, ISA_MIPS3);
16381 check_mips_64(ctx);
3c824109 16382 mips32_op = OPC_LWU;
5c13fdfd 16383 goto do_ld_lr;
3c824109 16384 case LLD:
d9224450
MR
16385 check_insn(ctx, ISA_MIPS3);
16386 check_mips_64(ctx);
3c824109 16387 mips32_op = OPC_LLD;
5c13fdfd 16388 goto do_ld_lr;
3c824109
NF
16389#endif
16390 case LL:
16391 mips32_op = OPC_LL;
5c13fdfd
AJ
16392 goto do_ld_lr;
16393 do_ld_lr:
3b4a5489 16394 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
16395 break;
16396 do_st_lr:
8fffc646 16397 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
16398 break;
16399 case SC:
3b4a5489 16400 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
16401 break;
16402#if defined(TARGET_MIPS64)
16403 case SCD:
d9224450
MR
16404 check_insn(ctx, ISA_MIPS3);
16405 check_mips_64(ctx);
3b4a5489 16406 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
16407 break;
16408#endif
8fffc646
JH
16409 case LD_EVA:
16410 if (!ctx->eva) {
16411 MIPS_INVAL("pool32c ld-eva");
16412 generate_exception_end(ctx, EXCP_RI);
16413 break;
16414 }
16415 check_cp0_enabled(ctx);
16416
16417 minor2 = (ctx->opcode >> 9) & 0x7;
16418 offset = sextract32(ctx->opcode, 0, 9);
16419 switch (minor2) {
16420 case LBUE:
16421 mips32_op = OPC_LBUE;
16422 goto do_ld_lr;
16423 case LHUE:
16424 mips32_op = OPC_LHUE;
16425 goto do_ld_lr;
16426 case LWLE:
16427 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16428 mips32_op = OPC_LWLE;
16429 goto do_ld_lr;
16430 case LWRE:
16431 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16432 mips32_op = OPC_LWRE;
16433 goto do_ld_lr;
16434 case LBE:
16435 mips32_op = OPC_LBE;
16436 goto do_ld_lr;
16437 case LHE:
16438 mips32_op = OPC_LHE;
16439 goto do_ld_lr;
16440 case LLE:
16441 mips32_op = OPC_LLE;
16442 goto do_ld_lr;
16443 case LWE:
16444 mips32_op = OPC_LWE;
16445 goto do_ld_lr;
16446 };
16447 break;
16448 case ST_EVA:
16449 if (!ctx->eva) {
16450 MIPS_INVAL("pool32c st-eva");
16451 generate_exception_end(ctx, EXCP_RI);
16452 break;
16453 }
16454 check_cp0_enabled(ctx);
16455
16456 minor2 = (ctx->opcode >> 9) & 0x7;
16457 offset = sextract32(ctx->opcode, 0, 9);
16458 switch (minor2) {
16459 case SWLE:
16460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16461 mips32_op = OPC_SWLE;
16462 goto do_st_lr;
16463 case SWRE:
16464 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16465 mips32_op = OPC_SWRE;
16466 goto do_st_lr;
16467 case PREFE:
16468 /* Treat as no-op */
16469 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16470 /* hint codes 24-31 are reserved and signal RI */
16471 generate_exception(ctx, EXCP_RI);
16472 }
16473 break;
16474 case CACHEE:
16475 /* Treat as no-op */
16476 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16477 gen_cache_operation(ctx, rt, rs, offset);
16478 }
16479 break;
16480 case SBE:
16481 mips32_op = OPC_SBE;
16482 goto do_st_lr;
16483 case SHE:
16484 mips32_op = OPC_SHE;
16485 goto do_st_lr;
16486 case SCE:
16487 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16488 break;
16489 case SWE:
16490 mips32_op = OPC_SWE;
16491 goto do_st_lr;
16492 };
16493 break;
3c824109
NF
16494 case PREF:
16495 /* Treat as no-op */
3b4a5489
YK
16496 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16497 /* hint codes 24-31 are reserved and signal RI */
16498 generate_exception(ctx, EXCP_RI);
16499 }
3c824109
NF
16500 break;
16501 default:
16502 MIPS_INVAL("pool32c");
9c708c7f 16503 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16504 break;
16505 }
16506 break;
ab39ee45
YK
16507 case ADDI32: /* AUI, LUI */
16508 if (ctx->insn_flags & ISA_MIPS32R6) {
16509 /* AUI, LUI */
16510 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16511 } else {
16512 /* ADDI32 */
16513 mips32_op = OPC_ADDI;
16514 goto do_addi;
16515 }
16516 break;
3c824109
NF
16517 case ADDIU32:
16518 mips32_op = OPC_ADDIU;
16519 do_addi:
d75c135e 16520 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16521 break;
16522
16523 /* Logical operations */
16524 case ORI32:
16525 mips32_op = OPC_ORI;
16526 goto do_logici;
16527 case XORI32:
16528 mips32_op = OPC_XORI;
16529 goto do_logici;
16530 case ANDI32:
16531 mips32_op = OPC_ANDI;
16532 do_logici:
d75c135e 16533 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16534 break;
16535
16536 /* Set less than immediate */
16537 case SLTI32:
16538 mips32_op = OPC_SLTI;
16539 goto do_slti;
16540 case SLTIU32:
16541 mips32_op = OPC_SLTIU;
16542 do_slti:
d75c135e 16543 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16544 break;
16545 case JALX32:
9e8f441a 16546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16547 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
16548 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16549 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 16550 break;
65935f07
YK
16551 case JALS32: /* BOVC, BEQC, BEQZALC */
16552 if (ctx->insn_flags & ISA_MIPS32R6) {
16553 if (rs >= rt) {
16554 /* BOVC */
16555 mips32_op = OPC_BOVC;
16556 } else if (rs < rt && rs == 0) {
16557 /* BEQZALC */
16558 mips32_op = OPC_BEQZALC;
16559 } else {
16560 /* BEQC */
16561 mips32_op = OPC_BEQC;
16562 }
16563 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16564 } else {
16565 /* JALS32 */
16566 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16567 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16568 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16569 }
3c824109 16570 break;
65935f07
YK
16571 case BEQ32: /* BC */
16572 if (ctx->insn_flags & ISA_MIPS32R6) {
16573 /* BC */
16574 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16575 sextract32(ctx->opcode << 1, 0, 27));
16576 } else {
16577 /* BEQ32 */
16578 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16579 }
3c824109 16580 break;
65935f07
YK
16581 case BNE32: /* BALC */
16582 if (ctx->insn_flags & ISA_MIPS32R6) {
16583 /* BALC */
16584 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16585 sextract32(ctx->opcode << 1, 0, 27));
16586 } else {
16587 /* BNE32 */
16588 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16589 }
3c824109 16590 break;
65935f07
YK
16591 case J32: /* BGTZC, BLTZC, BLTC */
16592 if (ctx->insn_flags & ISA_MIPS32R6) {
16593 if (rs == 0 && rt != 0) {
16594 /* BGTZC */
16595 mips32_op = OPC_BGTZC;
16596 } else if (rs != 0 && rt != 0 && rs == rt) {
16597 /* BLTZC */
16598 mips32_op = OPC_BLTZC;
16599 } else {
16600 /* BLTC */
16601 mips32_op = OPC_BLTC;
16602 }
16603 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16604 } else {
16605 /* J32 */
16606 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16607 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16608 }
3c824109 16609 break;
65935f07
YK
16610 case JAL32: /* BLEZC, BGEZC, BGEC */
16611 if (ctx->insn_flags & ISA_MIPS32R6) {
16612 if (rs == 0 && rt != 0) {
16613 /* BLEZC */
16614 mips32_op = OPC_BLEZC;
16615 } else if (rs != 0 && rt != 0 && rs == rt) {
16616 /* BGEZC */
16617 mips32_op = OPC_BGEZC;
16618 } else {
16619 /* BGEC */
16620 mips32_op = OPC_BGEC;
16621 }
16622 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16623 } else {
16624 /* JAL32 */
16625 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16626 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16627 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16628 }
3c824109
NF
16629 break;
16630 /* Floating point (COP1) */
16631 case LWC132:
16632 mips32_op = OPC_LWC1;
16633 goto do_cop1;
16634 case LDC132:
16635 mips32_op = OPC_LDC1;
16636 goto do_cop1;
16637 case SWC132:
16638 mips32_op = OPC_SWC1;
16639 goto do_cop1;
16640 case SDC132:
16641 mips32_op = OPC_SDC1;
16642 do_cop1:
5ab5c041 16643 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 16644 break;
ab39ee45
YK
16645 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16646 if (ctx->insn_flags & ISA_MIPS32R6) {
16647 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16648 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
16649 case ADDIUPC_00:
16650 case ADDIUPC_01:
16651 case ADDIUPC_02:
16652 case ADDIUPC_03:
16653 case ADDIUPC_04:
16654 case ADDIUPC_05:
16655 case ADDIUPC_06:
16656 case ADDIUPC_07:
eeb3bba8 16657 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16658 break;
16659 case AUIPC:
eeb3bba8 16660 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
16661 break;
16662 case ALUIPC:
eeb3bba8 16663 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 16664 break;
c38a1d52
AR
16665 case LWPC_08:
16666 case LWPC_09:
16667 case LWPC_0A:
16668 case LWPC_0B:
16669 case LWPC_0C:
16670 case LWPC_0D:
16671 case LWPC_0E:
16672 case LWPC_0F:
eeb3bba8 16673 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16674 break;
16675 default:
16676 generate_exception(ctx, EXCP_RI);
16677 break;
16678 }
16679 } else {
16680 /* ADDIUPC */
3c824109 16681 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 16682 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
16683
16684 gen_addiupc(ctx, reg, offset, 0, 0);
16685 }
16686 break;
65935f07
YK
16687 case BNVC: /* BNEC, BNEZALC */
16688 check_insn(ctx, ISA_MIPS32R6);
16689 if (rs >= rt) {
16690 /* BNVC */
16691 mips32_op = OPC_BNVC;
16692 } else if (rs < rt && rs == 0) {
16693 /* BNEZALC */
16694 mips32_op = OPC_BNEZALC;
16695 } else {
16696 /* BNEC */
16697 mips32_op = OPC_BNEC;
16698 }
16699 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16700 break;
16701 case R6_BNEZC: /* JIALC */
16702 check_insn(ctx, ISA_MIPS32R6);
16703 if (rt != 0) {
16704 /* BNEZC */
16705 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16706 sextract32(ctx->opcode << 1, 0, 22));
16707 } else {
16708 /* JIALC */
16709 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16710 }
16711 break;
16712 case R6_BEQZC: /* JIC */
16713 check_insn(ctx, ISA_MIPS32R6);
16714 if (rt != 0) {
16715 /* BEQZC */
16716 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16717 sextract32(ctx->opcode << 1, 0, 22));
16718 } else {
16719 /* JIC */
16720 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16721 }
16722 break;
16723 case BLEZALC: /* BGEZALC, BGEUC */
16724 check_insn(ctx, ISA_MIPS32R6);
16725 if (rs == 0 && rt != 0) {
16726 /* BLEZALC */
16727 mips32_op = OPC_BLEZALC;
16728 } else if (rs != 0 && rt != 0 && rs == rt) {
16729 /* BGEZALC */
16730 mips32_op = OPC_BGEZALC;
16731 } else {
16732 /* BGEUC */
16733 mips32_op = OPC_BGEUC;
16734 }
16735 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16736 break;
16737 case BGTZALC: /* BLTZALC, BLTUC */
16738 check_insn(ctx, ISA_MIPS32R6);
16739 if (rs == 0 && rt != 0) {
16740 /* BGTZALC */
16741 mips32_op = OPC_BGTZALC;
16742 } else if (rs != 0 && rt != 0 && rs == rt) {
16743 /* BLTZALC */
16744 mips32_op = OPC_BLTZALC;
16745 } else {
16746 /* BLTUC */
16747 mips32_op = OPC_BLTUC;
16748 }
16749 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16750 break;
3c824109
NF
16751 /* Loads and stores */
16752 case LB32:
16753 mips32_op = OPC_LB;
5c13fdfd 16754 goto do_ld;
3c824109
NF
16755 case LBU32:
16756 mips32_op = OPC_LBU;
5c13fdfd 16757 goto do_ld;
3c824109
NF
16758 case LH32:
16759 mips32_op = OPC_LH;
5c13fdfd 16760 goto do_ld;
3c824109
NF
16761 case LHU32:
16762 mips32_op = OPC_LHU;
5c13fdfd 16763 goto do_ld;
3c824109
NF
16764 case LW32:
16765 mips32_op = OPC_LW;
5c13fdfd 16766 goto do_ld;
3c824109
NF
16767#ifdef TARGET_MIPS64
16768 case LD32:
d9224450
MR
16769 check_insn(ctx, ISA_MIPS3);
16770 check_mips_64(ctx);
3c824109 16771 mips32_op = OPC_LD;
5c13fdfd 16772 goto do_ld;
3c824109 16773 case SD32:
d9224450
MR
16774 check_insn(ctx, ISA_MIPS3);
16775 check_mips_64(ctx);
3c824109 16776 mips32_op = OPC_SD;
5c13fdfd 16777 goto do_st;
3c824109
NF
16778#endif
16779 case SB32:
16780 mips32_op = OPC_SB;
5c13fdfd 16781 goto do_st;
3c824109
NF
16782 case SH32:
16783 mips32_op = OPC_SH;
5c13fdfd 16784 goto do_st;
3c824109
NF
16785 case SW32:
16786 mips32_op = OPC_SW;
5c13fdfd
AJ
16787 goto do_st;
16788 do_ld:
d75c135e 16789 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
16790 break;
16791 do_st:
16792 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16793 break;
16794 default:
9c708c7f 16795 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16796 break;
16797 }
16798}
16799
240ce26a 16800static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
16801{
16802 uint32_t op;
16803
16804 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
16805 if (ctx->base.pc_next & 0x1) {
16806 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 16807 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
16808 return 2;
16809 }
16810
16811 op = (ctx->opcode >> 10) & 0x3f;
16812 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
16813 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16814 switch (op & 0x7) { /* MSB-3..MSB-5 */
16815 case 0:
16816 /* POOL32A, POOL32B, POOL32I, POOL32C */
16817 case 4:
16818 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16819 case 5:
16820 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16821 case 6:
16822 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16823 case 7:
16824 /* LB32, LH32, LWC132, LDC132, LW32 */
16825 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 16826 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16827 return 2;
16828 }
16829 break;
b231c103
YK
16830 case 1:
16831 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16832 case 2:
16833 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16834 case 3:
16835 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16836 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 16837 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16838 return 2;
16839 }
16840 break;
3c824109
NF
16841 }
16842 }
b231c103 16843
3c824109
NF
16844 switch (op) {
16845 case POOL16A:
16846 {
16847 int rd = mmreg(uMIPS_RD(ctx->opcode));
16848 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16849 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16850 uint32_t opc = 0;
16851
16852 switch (ctx->opcode & 0x1) {
16853 case ADDU16:
16854 opc = OPC_ADDU;
16855 break;
16856 case SUBU16:
16857 opc = OPC_SUBU;
16858 break;
16859 }
ed7ce6c0
YK
16860 if (ctx->insn_flags & ISA_MIPS32R6) {
16861 /* In the Release 6 the register number location in
16862 * the instruction encoding has changed.
16863 */
16864 gen_arith(ctx, opc, rs1, rd, rs2);
16865 } else {
16866 gen_arith(ctx, opc, rd, rs1, rs2);
16867 }
3c824109
NF
16868 }
16869 break;
16870 case POOL16B:
16871 {
16872 int rd = mmreg(uMIPS_RD(ctx->opcode));
16873 int rs = mmreg(uMIPS_RS(ctx->opcode));
16874 int amount = (ctx->opcode >> 1) & 0x7;
16875 uint32_t opc = 0;
16876 amount = amount == 0 ? 8 : amount;
16877
16878 switch (ctx->opcode & 0x1) {
16879 case SLL16:
16880 opc = OPC_SLL;
16881 break;
16882 case SRL16:
16883 opc = OPC_SRL;
16884 break;
16885 }
16886
d75c135e 16887 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
16888 }
16889 break;
16890 case POOL16C:
ed7ce6c0
YK
16891 if (ctx->insn_flags & ISA_MIPS32R6) {
16892 gen_pool16c_r6_insn(ctx);
16893 } else {
16894 gen_pool16c_insn(ctx);
16895 }
3c824109
NF
16896 break;
16897 case LWGP16:
16898 {
16899 int rd = mmreg(uMIPS_RD(ctx->opcode));
16900 int rb = 28; /* GP */
16901 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16902
d75c135e 16903 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16904 }
16905 break;
16906 case POOL16F:
9e8f441a 16907 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16908 if (ctx->opcode & 1) {
9c708c7f 16909 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16910 } else {
16911 /* MOVEP */
16912 int enc_dest = uMIPS_RD(ctx->opcode);
16913 int enc_rt = uMIPS_RS2(ctx->opcode);
16914 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 16915 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
16916 }
16917 break;
16918 case LBU16:
16919 {
16920 int rd = mmreg(uMIPS_RD(ctx->opcode));
16921 int rb = mmreg(uMIPS_RS(ctx->opcode));
16922 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16923 offset = (offset == 0xf ? -1 : offset);
16924
d75c135e 16925 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
16926 }
16927 break;
16928 case LHU16:
16929 {
16930 int rd = mmreg(uMIPS_RD(ctx->opcode));
16931 int rb = mmreg(uMIPS_RS(ctx->opcode));
16932 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16933
d75c135e 16934 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
16935 }
16936 break;
16937 case LWSP16:
16938 {
16939 int rd = (ctx->opcode >> 5) & 0x1f;
16940 int rb = 29; /* SP */
16941 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16942
d75c135e 16943 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16944 }
16945 break;
16946 case LW16:
16947 {
16948 int rd = mmreg(uMIPS_RD(ctx->opcode));
16949 int rb = mmreg(uMIPS_RS(ctx->opcode));
16950 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16951
d75c135e 16952 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16953 }
16954 break;
16955 case SB16:
16956 {
16957 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16958 int rb = mmreg(uMIPS_RS(ctx->opcode));
16959 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16960
5c13fdfd 16961 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
16962 }
16963 break;
16964 case SH16:
16965 {
16966 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16967 int rb = mmreg(uMIPS_RS(ctx->opcode));
16968 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16969
5c13fdfd 16970 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
16971 }
16972 break;
16973 case SWSP16:
16974 {
16975 int rd = (ctx->opcode >> 5) & 0x1f;
16976 int rb = 29; /* SP */
16977 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16978
5c13fdfd 16979 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
16980 }
16981 break;
16982 case SW16:
16983 {
16984 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16985 int rb = mmreg(uMIPS_RS(ctx->opcode));
16986 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16987
5c13fdfd 16988 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
16989 }
16990 break;
16991 case MOVE16:
16992 {
16993 int rd = uMIPS_RD5(ctx->opcode);
16994 int rs = uMIPS_RS5(ctx->opcode);
16995
7215d7e7 16996 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
16997 }
16998 break;
16999 case ANDI16:
d75c135e 17000 gen_andi16(ctx);
3c824109
NF
17001 break;
17002 case POOL16D:
17003 switch (ctx->opcode & 0x1) {
17004 case ADDIUS5:
d75c135e 17005 gen_addius5(ctx);
3c824109
NF
17006 break;
17007 case ADDIUSP:
d75c135e 17008 gen_addiusp(ctx);
3c824109
NF
17009 break;
17010 }
17011 break;
17012 case POOL16E:
17013 switch (ctx->opcode & 0x1) {
17014 case ADDIUR2:
d75c135e 17015 gen_addiur2(ctx);
3c824109
NF
17016 break;
17017 case ADDIUR1SP:
d75c135e 17018 gen_addiur1sp(ctx);
3c824109
NF
17019 break;
17020 }
17021 break;
65935f07 17022 case B16: /* BC16 */
3c824109 17023 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
17024 sextract32(ctx->opcode, 0, 10) << 1,
17025 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 17026 break;
65935f07
YK
17027 case BNEZ16: /* BNEZC16 */
17028 case BEQZ16: /* BEQZC16 */
3c824109
NF
17029 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17030 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
17031 0, sextract32(ctx->opcode, 0, 7) << 1,
17032 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17033
3c824109
NF
17034 break;
17035 case LI16:
17036 {
17037 int reg = mmreg(uMIPS_RD(ctx->opcode));
17038 int imm = ZIMM(ctx->opcode, 0, 7);
17039
17040 imm = (imm == 0x7f ? -1 : imm);
17041 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17042 }
17043 break;
3c824109 17044 case RES_29:
3c824109 17045 case RES_31:
3c824109 17046 case RES_39:
9c708c7f 17047 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17048 break;
17049 default:
f60eeb0c 17050 decode_micromips32_opc(env, ctx);
3c824109
NF
17051 return 4;
17052 }
17053
17054 return 2;
17055}
17056
261c95a0
YK
17057/*
17058 *
17059 * nanoMIPS opcodes
17060 *
17061 */
17062
17063/* MAJOR, P16, and P32 pools opcodes */
17064enum {
17065 NM_P_ADDIU = 0x00,
17066 NM_ADDIUPC = 0x01,
17067 NM_MOVE_BALC = 0x02,
17068 NM_P16_MV = 0x04,
17069 NM_LW16 = 0x05,
17070 NM_BC16 = 0x06,
17071 NM_P16_SR = 0x07,
17072
17073 NM_POOL32A = 0x08,
17074 NM_P_BAL = 0x0a,
17075 NM_P16_SHIFT = 0x0c,
17076 NM_LWSP16 = 0x0d,
17077 NM_BALC16 = 0x0e,
17078 NM_P16_4X4 = 0x0f,
17079
17080 NM_P_GP_W = 0x10,
17081 NM_P_GP_BH = 0x11,
17082 NM_P_J = 0x12,
17083 NM_P16C = 0x14,
17084 NM_LWGP16 = 0x15,
17085 NM_P16_LB = 0x17,
17086
17087 NM_P48I = 0x18,
17088 NM_P16_A1 = 0x1c,
17089 NM_LW4X4 = 0x1d,
17090 NM_P16_LH = 0x1f,
17091
17092 NM_P_U12 = 0x20,
17093 NM_P_LS_U12 = 0x21,
17094 NM_P_BR1 = 0x22,
17095 NM_P16_A2 = 0x24,
17096 NM_SW16 = 0x25,
17097 NM_BEQZC16 = 0x26,
17098
17099 NM_POOL32F = 0x28,
17100 NM_P_LS_S9 = 0x29,
17101 NM_P_BR2 = 0x2a,
17102
17103 NM_P16_ADDU = 0x2c,
17104 NM_SWSP16 = 0x2d,
17105 NM_BNEZC16 = 0x2e,
17106 NM_MOVEP = 0x2f,
17107
17108 NM_POOL32S = 0x30,
17109 NM_P_BRI = 0x32,
17110 NM_LI16 = 0x34,
17111 NM_SWGP16 = 0x35,
17112 NM_P16_BR = 0x36,
17113
17114 NM_P_LUI = 0x38,
17115 NM_ANDI16 = 0x3c,
17116 NM_SW4X4 = 0x3d,
17117 NM_MOVEPREV = 0x3f,
17118};
17119
17120/* POOL32A instruction pool */
17121enum {
17122 NM_POOL32A0 = 0x00,
17123 NM_SPECIAL2 = 0x01,
17124 NM_COP2_1 = 0x02,
17125 NM_UDI = 0x03,
17126 NM_POOL32A5 = 0x05,
17127 NM_POOL32A7 = 0x07,
17128};
17129
17130/* P.GP.W instruction pool */
17131enum {
17132 NM_ADDIUGP_W = 0x00,
17133 NM_LWGP = 0x02,
17134 NM_SWGP = 0x03,
17135};
17136
17137/* P48I instruction pool */
17138enum {
17139 NM_LI48 = 0x00,
17140 NM_ADDIU48 = 0x01,
17141 NM_ADDIUGP48 = 0x02,
17142 NM_ADDIUPC48 = 0x03,
17143 NM_LWPC48 = 0x0b,
17144 NM_SWPC48 = 0x0f,
17145};
17146
17147/* P.U12 instruction pool */
17148enum {
17149 NM_ORI = 0x00,
17150 NM_XORI = 0x01,
17151 NM_ANDI = 0x02,
17152 NM_P_SR = 0x03,
17153 NM_SLTI = 0x04,
17154 NM_SLTIU = 0x05,
17155 NM_SEQI = 0x06,
17156 NM_ADDIUNEG = 0x08,
17157 NM_P_SHIFT = 0x0c,
17158 NM_P_ROTX = 0x0d,
17159 NM_P_INS = 0x0e,
17160 NM_P_EXT = 0x0f,
17161};
17162
17163/* POOL32F instruction pool */
17164enum {
17165 NM_POOL32F_0 = 0x00,
17166 NM_POOL32F_3 = 0x03,
17167 NM_POOL32F_5 = 0x05,
17168};
17169
17170/* POOL32S instruction pool */
17171enum {
17172 NM_POOL32S_0 = 0x00,
17173 NM_POOL32S_4 = 0x04,
17174};
17175
17176/* P.LUI instruction pool */
17177enum {
17178 NM_LUI = 0x00,
17179 NM_ALUIPC = 0x01,
17180};
17181
17182/* P.GP.BH instruction pool */
17183enum {
17184 NM_LBGP = 0x00,
17185 NM_SBGP = 0x01,
17186 NM_LBUGP = 0x02,
17187 NM_ADDIUGP_B = 0x03,
17188 NM_P_GP_LH = 0x04,
17189 NM_P_GP_SH = 0x05,
17190 NM_P_GP_CP1 = 0x06,
17191};
17192
17193/* P.LS.U12 instruction pool */
17194enum {
17195 NM_LB = 0x00,
17196 NM_SB = 0x01,
17197 NM_LBU = 0x02,
17198 NM_P_PREFU12 = 0x03,
17199 NM_LH = 0x04,
17200 NM_SH = 0x05,
17201 NM_LHU = 0x06,
17202 NM_LWU = 0x07,
17203 NM_LW = 0x08,
17204 NM_SW = 0x09,
17205 NM_LWC1 = 0x0a,
17206 NM_SWC1 = 0x0b,
17207 NM_LDC1 = 0x0e,
17208 NM_SDC1 = 0x0f,
17209};
17210
17211/* P.LS.S9 instruction pool */
17212enum {
17213 NM_P_LS_S0 = 0x00,
17214 NM_P_LS_S1 = 0x01,
17215 NM_P_LS_E0 = 0x02,
17216 NM_P_LS_WM = 0x04,
17217 NM_P_LS_UAWM = 0x05,
17218};
17219
17220/* P.BAL instruction pool */
17221enum {
17222 NM_BC = 0x00,
17223 NM_BALC = 0x01,
17224};
17225
17226/* P.J instruction pool */
17227enum {
17228 NM_JALRC = 0x00,
17229 NM_JALRC_HB = 0x01,
17230 NM_P_BALRSC = 0x08,
17231};
17232
17233/* P.BR1 instruction pool */
17234enum {
17235 NM_BEQC = 0x00,
17236 NM_P_BR3A = 0x01,
17237 NM_BGEC = 0x02,
17238 NM_BGEUC = 0x03,
17239};
17240
17241/* P.BR2 instruction pool */
17242enum {
17243 NM_BNEC = 0x00,
17244 NM_BLTC = 0x02,
17245 NM_BLTUC = 0x03,
17246};
17247
17248/* P.BRI instruction pool */
17249enum {
17250 NM_BEQIC = 0x00,
17251 NM_BBEQZC = 0x01,
17252 NM_BGEIC = 0x02,
17253 NM_BGEIUC = 0x03,
17254 NM_BNEIC = 0x04,
17255 NM_BBNEZC = 0x05,
17256 NM_BLTIC = 0x06,
17257 NM_BLTIUC = 0x07,
17258};
17259
17260/* P16.SHIFT instruction pool */
17261enum {
17262 NM_SLL16 = 0x00,
17263 NM_SRL16 = 0x01,
17264};
17265
17266/* POOL16C instruction pool */
17267enum {
17268 NM_POOL16C_0 = 0x00,
17269 NM_LWXS16 = 0x01,
17270};
17271
17272/* P16.A1 instruction pool */
17273enum {
17274 NM_ADDIUR1SP = 0x01,
17275};
17276
17277/* P16.A2 instruction pool */
17278enum {
17279 NM_ADDIUR2 = 0x00,
17280 NM_P_ADDIURS5 = 0x01,
17281};
17282
17283/* P16.ADDU instruction pool */
17284enum {
17285 NM_ADDU16 = 0x00,
17286 NM_SUBU16 = 0x01,
17287};
17288
17289/* P16.SR instruction pool */
17290enum {
17291 NM_SAVE16 = 0x00,
17292 NM_RESTORE_JRC16 = 0x01,
17293};
17294
17295/* P16.4X4 instruction pool */
17296enum {
17297 NM_ADDU4X4 = 0x00,
17298 NM_MUL4X4 = 0x01,
17299};
17300
17301/* P16.LB instruction pool */
17302enum {
17303 NM_LB16 = 0x00,
17304 NM_SB16 = 0x01,
17305 NM_LBU16 = 0x02,
17306};
17307
17308/* P16.LH instruction pool */
17309enum {
17310 NM_LH16 = 0x00,
17311 NM_SH16 = 0x01,
17312 NM_LHU16 = 0x02,
17313};
17314
17315/* P.RI instruction pool */
17316enum {
17317 NM_SIGRIE = 0x00,
17318 NM_P_SYSCALL = 0x01,
17319 NM_BREAK = 0x02,
17320 NM_SDBBP = 0x03,
17321};
17322
17323/* POOL32A0 instruction pool */
17324enum {
17325 NM_P_TRAP = 0x00,
17326 NM_SEB = 0x01,
17327 NM_SLLV = 0x02,
17328 NM_MUL = 0x03,
17329 NM_MFC0 = 0x06,
17330 NM_MFHC0 = 0x07,
17331 NM_SEH = 0x09,
17332 NM_SRLV = 0x0a,
17333 NM_MUH = 0x0b,
17334 NM_MTC0 = 0x0e,
17335 NM_MTHC0 = 0x0f,
17336 NM_SRAV = 0x12,
17337 NM_MULU = 0x13,
17338 NM_ROTRV = 0x1a,
17339 NM_MUHU = 0x1b,
17340 NM_ADD = 0x22,
17341 NM_DIV = 0x23,
17342 NM_ADDU = 0x2a,
17343 NM_MOD = 0x2b,
17344 NM_SUB = 0x32,
17345 NM_DIVU = 0x33,
17346 NM_RDHWR = 0x38,
17347 NM_SUBU = 0x3a,
17348 NM_MODU = 0x3b,
17349 NM_P_CMOVE = 0x42,
17350 NM_FORK = 0x45,
17351 NM_MFTR = 0x46,
17352 NM_MFHTR = 0x47,
17353 NM_AND = 0x4a,
17354 NM_YIELD = 0x4d,
17355 NM_MTTR = 0x4e,
17356 NM_MTHTR = 0x4f,
17357 NM_OR = 0x52,
17358 NM_D_E_MT_VPE = 0x56,
17359 NM_NOR = 0x5a,
17360 NM_XOR = 0x62,
17361 NM_SLT = 0x6a,
17362 NM_P_SLTU = 0x72,
17363 NM_SOV = 0x7a,
17364};
17365
b3979b6f
SM
17366/* POOL32A5 instruction pool */
17367enum {
17368 NM_CMP_EQ_PH = 0x00,
17369 NM_CMP_LT_PH = 0x08,
17370 NM_CMP_LE_PH = 0x10,
17371 NM_CMPGU_EQ_QB = 0x18,
17372 NM_CMPGU_LT_QB = 0x20,
17373 NM_CMPGU_LE_QB = 0x28,
17374 NM_CMPGDU_EQ_QB = 0x30,
17375 NM_CMPGDU_LT_QB = 0x38,
17376 NM_CMPGDU_LE_QB = 0x40,
17377 NM_CMPU_EQ_QB = 0x48,
17378 NM_CMPU_LT_QB = 0x50,
17379 NM_CMPU_LE_QB = 0x58,
17380 NM_ADDQ_S_W = 0x60,
17381 NM_SUBQ_S_W = 0x68,
17382 NM_ADDSC = 0x70,
17383 NM_ADDWC = 0x78,
17384
17385 NM_ADDQ_S_PH = 0x01,
17386 NM_ADDQH_R_PH = 0x09,
17387 NM_ADDQH_R_W = 0x11,
17388 NM_ADDU_S_QB = 0x19,
17389 NM_ADDU_S_PH = 0x21,
17390 NM_ADDUH_R_QB = 0x29,
17391 NM_SHRAV_R_PH = 0x31,
17392 NM_SHRAV_R_QB = 0x39,
17393 NM_SUBQ_S_PH = 0x41,
17394 NM_SUBQH_R_PH = 0x49,
17395 NM_SUBQH_R_W = 0x51,
17396 NM_SUBU_S_QB = 0x59,
17397 NM_SUBU_S_PH = 0x61,
17398 NM_SUBUH_R_QB = 0x69,
17399 NM_SHLLV_S_PH = 0x71,
17400 NM_PRECR_SRA_R_PH_W = 0x79,
17401
17402 NM_MULEU_S_PH_QBL = 0x12,
17403 NM_MULEU_S_PH_QBR = 0x1a,
17404 NM_MULQ_RS_PH = 0x22,
17405 NM_MULQ_S_PH = 0x2a,
17406 NM_MULQ_RS_W = 0x32,
17407 NM_MULQ_S_W = 0x3a,
17408 NM_APPEND = 0x42,
17409 NM_MODSUB = 0x52,
17410 NM_SHRAV_R_W = 0x5a,
17411 NM_SHRLV_PH = 0x62,
17412 NM_SHRLV_QB = 0x6a,
17413 NM_SHLLV_QB = 0x72,
17414 NM_SHLLV_S_W = 0x7a,
17415
17416 NM_SHILO = 0x03,
17417
17418 NM_MULEQ_S_W_PHL = 0x04,
17419 NM_MULEQ_S_W_PHR = 0x0c,
17420
17421 NM_MUL_S_PH = 0x05,
17422 NM_PRECR_QB_PH = 0x0d,
17423 NM_PRECRQ_QB_PH = 0x15,
17424 NM_PRECRQ_PH_W = 0x1d,
17425 NM_PRECRQ_RS_PH_W = 0x25,
17426 NM_PRECRQU_S_QB_PH = 0x2d,
17427 NM_PACKRL_PH = 0x35,
17428 NM_PICK_QB = 0x3d,
17429 NM_PICK_PH = 0x45,
17430
17431 NM_SHRA_R_W = 0x5e,
17432 NM_SHRA_R_PH = 0x66,
17433 NM_SHLL_S_PH = 0x76,
17434 NM_SHLL_S_W = 0x7e,
17435
17436 NM_REPL_PH = 0x07
17437};
17438
261c95a0
YK
17439/* POOL32A7 instruction pool */
17440enum {
17441 NM_P_LSX = 0x00,
17442 NM_LSA = 0x01,
17443 NM_EXTW = 0x03,
17444 NM_POOL32AXF = 0x07,
17445};
17446
17447/* P.SR instruction pool */
17448enum {
17449 NM_PP_SR = 0x00,
17450 NM_P_SR_F = 0x01,
17451};
17452
17453/* P.SHIFT instruction pool */
17454enum {
17455 NM_P_SLL = 0x00,
17456 NM_SRL = 0x02,
17457 NM_SRA = 0x04,
17458 NM_ROTR = 0x06,
17459};
17460
17461/* P.ROTX instruction pool */
17462enum {
17463 NM_ROTX = 0x00,
17464};
17465
17466/* P.INS instruction pool */
17467enum {
17468 NM_INS = 0x00,
17469};
17470
17471/* P.EXT instruction pool */
17472enum {
17473 NM_EXT = 0x00,
17474};
17475
17476/* POOL32F_0 (fmt) instruction pool */
17477enum {
17478 NM_RINT_S = 0x04,
17479 NM_RINT_D = 0x44,
17480 NM_ADD_S = 0x06,
17481 NM_SELEQZ_S = 0x07,
17482 NM_SELEQZ_D = 0x47,
17483 NM_CLASS_S = 0x0c,
17484 NM_CLASS_D = 0x4c,
17485 NM_SUB_S = 0x0e,
17486 NM_SELNEZ_S = 0x0f,
17487 NM_SELNEZ_D = 0x4f,
17488 NM_MUL_S = 0x16,
17489 NM_SEL_S = 0x17,
17490 NM_SEL_D = 0x57,
17491 NM_DIV_S = 0x1e,
17492 NM_ADD_D = 0x26,
17493 NM_SUB_D = 0x2e,
17494 NM_MUL_D = 0x36,
17495 NM_MADDF_S = 0x37,
17496 NM_MADDF_D = 0x77,
17497 NM_DIV_D = 0x3e,
17498 NM_MSUBF_S = 0x3f,
17499 NM_MSUBF_D = 0x7f,
17500};
17501
17502/* POOL32F_3 instruction pool */
17503enum {
17504 NM_MIN_FMT = 0x00,
17505 NM_MAX_FMT = 0x01,
17506 NM_MINA_FMT = 0x04,
17507 NM_MAXA_FMT = 0x05,
17508 NM_POOL32FXF = 0x07,
17509};
17510
17511/* POOL32F_5 instruction pool */
17512enum {
17513 NM_CMP_CONDN_S = 0x00,
17514 NM_CMP_CONDN_D = 0x02,
17515};
17516
17517/* P.GP.LH instruction pool */
17518enum {
17519 NM_LHGP = 0x00,
17520 NM_LHUGP = 0x01,
17521};
17522
17523/* P.GP.SH instruction pool */
17524enum {
17525 NM_SHGP = 0x00,
17526};
17527
17528/* P.GP.CP1 instruction pool */
17529enum {
17530 NM_LWC1GP = 0x00,
17531 NM_SWC1GP = 0x01,
17532 NM_LDC1GP = 0x02,
17533 NM_SDC1GP = 0x03,
17534};
17535
17536/* P.LS.S0 instruction pool */
17537enum {
17538 NM_LBS9 = 0x00,
17539 NM_LHS9 = 0x04,
17540 NM_LWS9 = 0x08,
17541 NM_LDS9 = 0x0c,
17542
17543 NM_SBS9 = 0x01,
17544 NM_SHS9 = 0x05,
17545 NM_SWS9 = 0x09,
17546 NM_SDS9 = 0x0d,
17547
17548 NM_LBUS9 = 0x02,
17549 NM_LHUS9 = 0x06,
17550 NM_LWC1S9 = 0x0a,
17551 NM_LDC1S9 = 0x0e,
17552
17553 NM_P_PREFS9 = 0x03,
17554 NM_LWUS9 = 0x07,
17555 NM_SWC1S9 = 0x0b,
17556 NM_SDC1S9 = 0x0f,
17557};
17558
17559/* P.LS.S1 instruction pool */
17560enum {
17561 NM_ASET_ACLR = 0x02,
17562 NM_UALH = 0x04,
17563 NM_UASH = 0x05,
17564 NM_CACHE = 0x07,
17565 NM_P_LL = 0x0a,
17566 NM_P_SC = 0x0b,
17567};
17568
0d30b3bb
DN
17569/* P.LS.E0 instruction pool */
17570enum {
17571 NM_LBE = 0x00,
17572 NM_SBE = 0x01,
17573 NM_LBUE = 0x02,
17574 NM_P_PREFE = 0x03,
17575 NM_LHE = 0x04,
17576 NM_SHE = 0x05,
17577 NM_LHUE = 0x06,
17578 NM_CACHEE = 0x07,
17579 NM_LWE = 0x08,
17580 NM_SWE = 0x09,
17581 NM_P_LLE = 0x0a,
17582 NM_P_SCE = 0x0b,
17583};
17584
17585/* P.PREFE instruction pool */
17586enum {
17587 NM_SYNCIE = 0x00,
17588 NM_PREFE = 0x01,
17589};
17590
17591/* P.LLE instruction pool */
17592enum {
17593 NM_LLE = 0x00,
17594 NM_LLWPE = 0x01,
17595};
17596
17597/* P.SCE instruction pool */
17598enum {
17599 NM_SCE = 0x00,
17600 NM_SCWPE = 0x01,
17601};
17602
261c95a0
YK
17603/* P.LS.WM instruction pool */
17604enum {
17605 NM_LWM = 0x00,
17606 NM_SWM = 0x01,
17607};
17608
17609/* P.LS.UAWM instruction pool */
17610enum {
17611 NM_UALWM = 0x00,
17612 NM_UASWM = 0x01,
17613};
17614
17615/* P.BR3A instruction pool */
17616enum {
17617 NM_BC1EQZC = 0x00,
17618 NM_BC1NEZC = 0x01,
17619 NM_BC2EQZC = 0x02,
17620 NM_BC2NEZC = 0x03,
17621 NM_BPOSGE32C = 0x04,
17622};
17623
17624/* P16.RI instruction pool */
17625enum {
17626 NM_P16_SYSCALL = 0x01,
17627 NM_BREAK16 = 0x02,
17628 NM_SDBBP16 = 0x03,
17629};
17630
17631/* POOL16C_0 instruction pool */
17632enum {
17633 NM_POOL16C_00 = 0x00,
17634};
17635
17636/* P16.JRC instruction pool */
17637enum {
17638 NM_JRC = 0x00,
17639 NM_JALRC16 = 0x01,
17640};
17641
17642/* P.SYSCALL instruction pool */
17643enum {
17644 NM_SYSCALL = 0x00,
17645 NM_HYPCALL = 0x01,
17646};
17647
17648/* P.TRAP instruction pool */
17649enum {
17650 NM_TEQ = 0x00,
17651 NM_TNE = 0x01,
17652};
17653
17654/* P.CMOVE instruction pool */
17655enum {
17656 NM_MOVZ = 0x00,
17657 NM_MOVN = 0x01,
17658};
17659
17660/* POOL32Axf instruction pool */
17661enum {
b3979b6f
SM
17662 NM_POOL32AXF_1 = 0x01,
17663 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
17664 NM_POOL32AXF_4 = 0x04,
17665 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
17666 NM_POOL32AXF_7 = 0x07,
17667};
17668
17669/* POOL32Axf_1 instruction pool */
17670enum {
17671 NM_POOL32AXF_1_0 = 0x00,
17672 NM_POOL32AXF_1_1 = 0x01,
17673 NM_POOL32AXF_1_3 = 0x03,
17674 NM_POOL32AXF_1_4 = 0x04,
17675 NM_POOL32AXF_1_5 = 0x05,
17676 NM_POOL32AXF_1_7 = 0x07,
17677};
17678
17679/* POOL32Axf_2 instruction pool */
17680enum {
17681 NM_POOL32AXF_2_0_7 = 0x00,
17682 NM_POOL32AXF_2_8_15 = 0x01,
17683 NM_POOL32AXF_2_16_23 = 0x02,
17684 NM_POOL32AXF_2_24_31 = 0x03,
17685};
17686
17687/* POOL32Axf_7 instruction pool */
17688enum {
17689 NM_SHRA_R_QB = 0x0,
17690 NM_SHRL_PH = 0x1,
17691 NM_REPL_QB = 0x2,
17692};
17693
17694/* POOL32Axf_1_0 instruction pool */
17695enum {
17696 NM_MFHI = 0x0,
17697 NM_MFLO = 0x1,
17698 NM_MTHI = 0x2,
17699 NM_MTLO = 0x3,
17700};
17701
17702/* POOL32Axf_1_1 instruction pool */
17703enum {
17704 NM_MTHLIP = 0x0,
17705 NM_SHILOV = 0x1,
17706};
17707
17708/* POOL32Axf_1_3 instruction pool */
17709enum {
17710 NM_RDDSP = 0x0,
17711 NM_WRDSP = 0x1,
17712 NM_EXTP = 0x2,
17713 NM_EXTPDP = 0x3,
17714};
17715
17716/* POOL32Axf_1_4 instruction pool */
17717enum {
17718 NM_SHLL_QB = 0x0,
17719 NM_SHRL_QB = 0x1,
17720};
17721
17722/* POOL32Axf_1_5 instruction pool */
17723enum {
17724 NM_MAQ_S_W_PHR = 0x0,
17725 NM_MAQ_S_W_PHL = 0x1,
17726 NM_MAQ_SA_W_PHR = 0x2,
17727 NM_MAQ_SA_W_PHL = 0x3,
17728};
17729
17730/* POOL32Axf_1_7 instruction pool */
17731enum {
17732 NM_EXTR_W = 0x0,
17733 NM_EXTR_R_W = 0x1,
17734 NM_EXTR_RS_W = 0x2,
17735 NM_EXTR_S_H = 0x3,
17736};
17737
17738/* POOL32Axf_2_0_7 instruction pool */
17739enum {
17740 NM_DPA_W_PH = 0x0,
17741 NM_DPAQ_S_W_PH = 0x1,
17742 NM_DPS_W_PH = 0x2,
17743 NM_DPSQ_S_W_PH = 0x3,
17744 NM_BALIGN = 0x4,
17745 NM_MADD = 0x5,
17746 NM_MULT = 0x6,
17747 NM_EXTRV_W = 0x7,
17748};
17749
17750/* POOL32Axf_2_8_15 instruction pool */
17751enum {
17752 NM_DPAX_W_PH = 0x0,
17753 NM_DPAQ_SA_L_W = 0x1,
17754 NM_DPSX_W_PH = 0x2,
17755 NM_DPSQ_SA_L_W = 0x3,
17756 NM_MADDU = 0x5,
17757 NM_MULTU = 0x6,
17758 NM_EXTRV_R_W = 0x7,
17759};
17760
17761/* POOL32Axf_2_16_23 instruction pool */
17762enum {
17763 NM_DPAU_H_QBL = 0x0,
17764 NM_DPAQX_S_W_PH = 0x1,
17765 NM_DPSU_H_QBL = 0x2,
17766 NM_DPSQX_S_W_PH = 0x3,
17767 NM_EXTPV = 0x4,
17768 NM_MSUB = 0x5,
17769 NM_MULSA_W_PH = 0x6,
17770 NM_EXTRV_RS_W = 0x7,
17771};
17772
17773/* POOL32Axf_2_24_31 instruction pool */
17774enum {
17775 NM_DPAU_H_QBR = 0x0,
17776 NM_DPAQX_SA_W_PH = 0x1,
17777 NM_DPSU_H_QBR = 0x2,
17778 NM_DPSQX_SA_W_PH = 0x3,
17779 NM_EXTPDPV = 0x4,
17780 NM_MSUBU = 0x5,
17781 NM_MULSAQ_S_W_PH = 0x6,
17782 NM_EXTRV_S_H = 0x7,
261c95a0
YK
17783};
17784
17785/* POOL32Axf_{4, 5} instruction pool */
17786enum {
17787 NM_CLO = 0x25,
17788 NM_CLZ = 0x2d,
17789
17790 NM_TLBP = 0x01,
17791 NM_TLBR = 0x09,
17792 NM_TLBWI = 0x11,
17793 NM_TLBWR = 0x19,
17794 NM_TLBINV = 0x03,
17795 NM_TLBINVF = 0x0b,
17796 NM_DI = 0x23,
17797 NM_EI = 0x2b,
17798 NM_RDPGPR = 0x70,
17799 NM_WRPGPR = 0x78,
17800 NM_WAIT = 0x61,
17801 NM_DERET = 0x71,
17802 NM_ERETX = 0x79,
b3979b6f
SM
17803
17804 /* nanoMIPS DSP instructions */
17805 NM_ABSQ_S_QB = 0x00,
17806 NM_ABSQ_S_PH = 0x08,
17807 NM_ABSQ_S_W = 0x10,
17808 NM_PRECEQ_W_PHL = 0x28,
17809 NM_PRECEQ_W_PHR = 0x30,
17810 NM_PRECEQU_PH_QBL = 0x38,
17811 NM_PRECEQU_PH_QBR = 0x48,
17812 NM_PRECEU_PH_QBL = 0x58,
17813 NM_PRECEU_PH_QBR = 0x68,
17814 NM_PRECEQU_PH_QBLA = 0x39,
17815 NM_PRECEQU_PH_QBRA = 0x49,
17816 NM_PRECEU_PH_QBLA = 0x59,
17817 NM_PRECEU_PH_QBRA = 0x69,
17818 NM_REPLV_PH = 0x01,
17819 NM_REPLV_QB = 0x09,
17820 NM_BITREV = 0x18,
17821 NM_INSV = 0x20,
17822 NM_RADDU_W_QB = 0x78,
17823
17824 NM_BITSWAP = 0x05,
17825 NM_WSBH = 0x3d,
261c95a0
YK
17826};
17827
17828/* PP.SR instruction pool */
17829enum {
17830 NM_SAVE = 0x00,
17831 NM_RESTORE = 0x02,
17832 NM_RESTORE_JRC = 0x03,
17833};
17834
17835/* P.SR.F instruction pool */
17836enum {
17837 NM_SAVEF = 0x00,
17838 NM_RESTOREF = 0x01,
17839};
17840
17841/* P16.SYSCALL instruction pool */
17842enum {
17843 NM_SYSCALL16 = 0x00,
17844 NM_HYPCALL16 = 0x01,
17845};
17846
17847/* POOL16C_00 instruction pool */
17848enum {
17849 NM_NOT16 = 0x00,
17850 NM_XOR16 = 0x01,
17851 NM_AND16 = 0x02,
17852 NM_OR16 = 0x03,
17853};
17854
17855/* PP.LSX and PP.LSXS instruction pool */
17856enum {
17857 NM_LBX = 0x00,
17858 NM_LHX = 0x04,
17859 NM_LWX = 0x08,
17860 NM_LDX = 0x0c,
17861
17862 NM_SBX = 0x01,
17863 NM_SHX = 0x05,
17864 NM_SWX = 0x09,
17865 NM_SDX = 0x0d,
17866
17867 NM_LBUX = 0x02,
17868 NM_LHUX = 0x06,
17869 NM_LWC1X = 0x0a,
17870 NM_LDC1X = 0x0e,
17871
17872 NM_LWUX = 0x07,
17873 NM_SWC1X = 0x0b,
17874 NM_SDC1X = 0x0f,
17875
17876 NM_LHXS = 0x04,
17877 NM_LWXS = 0x08,
17878 NM_LDXS = 0x0c,
17879
17880 NM_SHXS = 0x05,
17881 NM_SWXS = 0x09,
17882 NM_SDXS = 0x0d,
17883
17884 NM_LHUXS = 0x06,
17885 NM_LWC1XS = 0x0a,
17886 NM_LDC1XS = 0x0e,
17887
17888 NM_LWUXS = 0x07,
17889 NM_SWC1XS = 0x0b,
17890 NM_SDC1XS = 0x0f,
17891};
17892
17893/* ERETx instruction pool */
17894enum {
17895 NM_ERET = 0x00,
17896 NM_ERETNC = 0x01,
17897};
17898
17899/* POOL32FxF_{0, 1} insturction pool */
17900enum {
17901 NM_CFC1 = 0x40,
17902 NM_CTC1 = 0x60,
17903 NM_MFC1 = 0x80,
17904 NM_MTC1 = 0xa0,
17905 NM_MFHC1 = 0xc0,
17906 NM_MTHC1 = 0xe0,
17907
17908 NM_CVT_S_PL = 0x84,
17909 NM_CVT_S_PU = 0xa4,
17910
17911 NM_CVT_L_S = 0x004,
17912 NM_CVT_L_D = 0x104,
17913 NM_CVT_W_S = 0x024,
17914 NM_CVT_W_D = 0x124,
17915
17916 NM_RSQRT_S = 0x008,
17917 NM_RSQRT_D = 0x108,
17918
17919 NM_SQRT_S = 0x028,
17920 NM_SQRT_D = 0x128,
17921
17922 NM_RECIP_S = 0x048,
17923 NM_RECIP_D = 0x148,
17924
17925 NM_FLOOR_L_S = 0x00c,
17926 NM_FLOOR_L_D = 0x10c,
17927
17928 NM_FLOOR_W_S = 0x02c,
17929 NM_FLOOR_W_D = 0x12c,
17930
17931 NM_CEIL_L_S = 0x04c,
17932 NM_CEIL_L_D = 0x14c,
17933 NM_CEIL_W_S = 0x06c,
17934 NM_CEIL_W_D = 0x16c,
17935 NM_TRUNC_L_S = 0x08c,
17936 NM_TRUNC_L_D = 0x18c,
17937 NM_TRUNC_W_S = 0x0ac,
17938 NM_TRUNC_W_D = 0x1ac,
17939 NM_ROUND_L_S = 0x0cc,
17940 NM_ROUND_L_D = 0x1cc,
17941 NM_ROUND_W_S = 0x0ec,
17942 NM_ROUND_W_D = 0x1ec,
17943
17944 NM_MOV_S = 0x01,
17945 NM_MOV_D = 0x81,
17946 NM_ABS_S = 0x0d,
17947 NM_ABS_D = 0x8d,
17948 NM_NEG_S = 0x2d,
17949 NM_NEG_D = 0xad,
17950 NM_CVT_D_S = 0x04d,
17951 NM_CVT_D_W = 0x0cd,
17952 NM_CVT_D_L = 0x14d,
17953 NM_CVT_S_D = 0x06d,
17954 NM_CVT_S_W = 0x0ed,
17955 NM_CVT_S_L = 0x16d,
17956};
17957
17958/* P.LL instruction pool */
17959enum {
17960 NM_LL = 0x00,
17961 NM_LLWP = 0x01,
17962};
17963
17964/* P.SC instruction pool */
17965enum {
17966 NM_SC = 0x00,
17967 NM_SCWP = 0x01,
17968};
17969
17970/* P.DVP instruction pool */
17971enum {
17972 NM_DVP = 0x00,
17973 NM_EVP = 0x01,
17974};
17975
c533c0f4
AM
17976
17977/*
17978 *
17979 * nanoMIPS decoding engine
17980 *
17981 */
17982
6bfa9f4c
AM
17983
17984/* extraction utilities */
17985
17986#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17987#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17988#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17989#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17990#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17991#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17992
ea4ca3c2
YK
17993/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17994static inline int decode_gpr_gpr3(int r)
17995{
17996 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17997
17998 return map[r & 0x7];
17999}
18000
8bdb7029
YK
18001/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18002static inline int decode_gpr_gpr3_src_store(int r)
18003{
18004 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18005
18006 return map[r & 0x7];
18007}
18008
ea4ca3c2
YK
18009/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18010static inline int decode_gpr_gpr4(int r)
18011{
18012 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18013 16, 17, 18, 19, 20, 21, 22, 23 };
18014
18015 return map[r & 0xf];
18016}
18017
8bdb7029
YK
18018/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18019static inline int decode_gpr_gpr4_zero(int r)
18020{
18021 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18022 16, 17, 18, 19, 20, 21, 22, 23 };
18023
18024 return map[r & 0xf];
18025}
18026
6bfa9f4c 18027
80845edf
YK
18028/* extraction utilities */
18029
18030#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18031#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18032#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18033#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18034#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18035#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18036
18037
bf0718c5
SM
18038static void gen_adjust_sp(DisasContext *ctx, int u)
18039{
18040 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18041}
18042
18043static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18044 uint8_t gp, uint16_t u)
18045{
18046 int counter = 0;
18047 TCGv va = tcg_temp_new();
18048 TCGv t0 = tcg_temp_new();
18049
18050 while (counter != count) {
18051 bool use_gp = gp && (counter == count - 1);
18052 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18053 int this_offset = -((counter + 1) << 2);
18054 gen_base_offset_addr(ctx, va, 29, this_offset);
18055 gen_load_gpr(t0, this_rt);
18056 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18057 (MO_TEUL | ctx->default_tcg_memop_mask));
18058 counter++;
18059 }
18060
18061 /* adjust stack pointer */
18062 gen_adjust_sp(ctx, -u);
18063
18064 tcg_temp_free(t0);
18065 tcg_temp_free(va);
18066}
18067
18068static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18069 uint8_t gp, uint16_t u)
18070{
18071 int counter = 0;
18072 TCGv va = tcg_temp_new();
18073 TCGv t0 = tcg_temp_new();
18074
18075 while (counter != count) {
18076 bool use_gp = gp && (counter == count - 1);
18077 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18078 int this_offset = u - ((counter + 1) << 2);
18079 gen_base_offset_addr(ctx, va, 29, this_offset);
18080 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18081 ctx->default_tcg_memop_mask);
18082 tcg_gen_ext32s_tl(t0, t0);
18083 gen_store_gpr(t0, this_rt);
18084 counter++;
18085 }
18086
18087 /* adjust stack pointer */
18088 gen_adjust_sp(ctx, u);
18089
18090 tcg_temp_free(t0);
18091 tcg_temp_free(va);
18092}
18093
80845edf
YK
18094static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18095{
18096 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18097 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18098
18099 switch (extract32(ctx->opcode, 2, 2)) {
18100 case NM_NOT16:
18101 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18102 break;
18103 case NM_AND16:
18104 gen_logic(ctx, OPC_AND, rt, rt, rs);
18105 break;
18106 case NM_XOR16:
18107 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18108 break;
18109 case NM_OR16:
18110 gen_logic(ctx, OPC_OR, rt, rt, rs);
18111 break;
18112 }
18113}
18114
0a1a6ed7 18115static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
18116{
18117 int rt = extract32(ctx->opcode, 21, 5);
18118 int rs = extract32(ctx->opcode, 16, 5);
18119 int rd = extract32(ctx->opcode, 11, 5);
18120
18121 switch (extract32(ctx->opcode, 3, 7)) {
18122 case NM_P_TRAP:
18123 switch (extract32(ctx->opcode, 10, 1)) {
18124 case NM_TEQ:
fb32f8c8 18125 check_nms(ctx);
e0cf0e65
YK
18126 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18127 break;
18128 case NM_TNE:
fb32f8c8 18129 check_nms(ctx);
e0cf0e65
YK
18130 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18131 break;
18132 }
18133 break;
18134 case NM_RDHWR:
fb32f8c8 18135 check_nms(ctx);
e0cf0e65
YK
18136 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18137 break;
18138 case NM_SEB:
fb32f8c8 18139 check_nms(ctx);
e0cf0e65
YK
18140 gen_bshfl(ctx, OPC_SEB, rs, rt);
18141 break;
18142 case NM_SEH:
18143 gen_bshfl(ctx, OPC_SEH, rs, rt);
18144 break;
18145 case NM_SLLV:
18146 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18147 break;
18148 case NM_SRLV:
18149 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18150 break;
18151 case NM_SRAV:
18152 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18153 break;
18154 case NM_ROTRV:
18155 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18156 break;
18157 case NM_ADD:
18158 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18159 break;
18160 case NM_ADDU:
18161 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18162 break;
18163 case NM_SUB:
fb32f8c8 18164 check_nms(ctx);
e0cf0e65
YK
18165 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18166 break;
18167 case NM_SUBU:
18168 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18169 break;
18170 case NM_P_CMOVE:
18171 switch (extract32(ctx->opcode, 10, 1)) {
18172 case NM_MOVZ:
18173 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18174 break;
18175 case NM_MOVN:
18176 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18177 break;
18178 }
18179 break;
18180 case NM_AND:
18181 gen_logic(ctx, OPC_AND, rd, rs, rt);
18182 break;
18183 case NM_OR:
18184 gen_logic(ctx, OPC_OR, rd, rs, rt);
18185 break;
18186 case NM_NOR:
18187 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18188 break;
18189 case NM_XOR:
18190 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18191 break;
18192 case NM_SLT:
18193 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18194 break;
18195 case NM_P_SLTU:
18196 if (rd == 0) {
18197 /* P_DVP */
18198#ifndef CONFIG_USER_ONLY
18199 TCGv t0 = tcg_temp_new();
18200 switch (extract32(ctx->opcode, 10, 1)) {
18201 case NM_DVP:
18202 if (ctx->vp) {
18203 check_cp0_enabled(ctx);
18204 gen_helper_dvp(t0, cpu_env);
18205 gen_store_gpr(t0, rt);
18206 }
18207 break;
18208 case NM_EVP:
18209 if (ctx->vp) {
18210 check_cp0_enabled(ctx);
18211 gen_helper_evp(t0, cpu_env);
18212 gen_store_gpr(t0, rt);
18213 }
18214 break;
18215 }
18216 tcg_temp_free(t0);
18217#endif
18218 } else {
18219 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18220 }
18221 break;
18222 case NM_SOV:
18223 {
18224 TCGv t0 = tcg_temp_new();
18225 TCGv t1 = tcg_temp_new();
18226 TCGv t2 = tcg_temp_new();
18227
18228 gen_load_gpr(t1, rs);
18229 gen_load_gpr(t2, rt);
18230 tcg_gen_add_tl(t0, t1, t2);
18231 tcg_gen_ext32s_tl(t0, t0);
18232 tcg_gen_xor_tl(t1, t1, t2);
18233 tcg_gen_xor_tl(t2, t0, t2);
18234 tcg_gen_andc_tl(t1, t2, t1);
18235
18236 /* operands of same sign, result different sign */
18237 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18238 gen_store_gpr(t0, rd);
18239
18240 tcg_temp_free(t0);
18241 tcg_temp_free(t1);
18242 tcg_temp_free(t2);
18243 }
18244 break;
18245 case NM_MUL:
18246 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18247 break;
18248 case NM_MUH:
18249 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18250 break;
18251 case NM_MULU:
18252 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18253 break;
18254 case NM_MUHU:
18255 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18256 break;
18257 case NM_DIV:
18258 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18259 break;
18260 case NM_MOD:
18261 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18262 break;
18263 case NM_DIVU:
18264 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18265 break;
18266 case NM_MODU:
18267 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18268 break;
18269#ifndef CONFIG_USER_ONLY
18270 case NM_MFC0:
18271 check_cp0_enabled(ctx);
18272 if (rt == 0) {
18273 /* Treat as NOP. */
18274 break;
18275 }
18276 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18277 break;
18278 case NM_MTC0:
18279 check_cp0_enabled(ctx);
18280 {
18281 TCGv t0 = tcg_temp_new();
18282
18283 gen_load_gpr(t0, rt);
18284 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18285 tcg_temp_free(t0);
18286 }
18287 break;
0a1a6ed7
SM
18288 case NM_D_E_MT_VPE:
18289 {
18290 uint8_t sc = extract32(ctx->opcode, 10, 1);
18291 TCGv t0 = tcg_temp_new();
18292
18293 switch (sc) {
18294 case 0:
18295 if (rs == 1) {
18296 /* DMT */
18297 check_cp0_mt(ctx);
18298 gen_helper_dmt(t0);
18299 gen_store_gpr(t0, rt);
18300 } else if (rs == 0) {
18301 /* DVPE */
18302 check_cp0_mt(ctx);
18303 gen_helper_dvpe(t0, cpu_env);
18304 gen_store_gpr(t0, rt);
18305 } else {
18306 generate_exception_end(ctx, EXCP_RI);
18307 }
18308 break;
18309 case 1:
18310 if (rs == 1) {
18311 /* EMT */
18312 check_cp0_mt(ctx);
18313 gen_helper_emt(t0);
18314 gen_store_gpr(t0, rt);
18315 } else if (rs == 0) {
18316 /* EVPE */
18317 check_cp0_mt(ctx);
18318 gen_helper_evpe(t0, cpu_env);
18319 gen_store_gpr(t0, rt);
18320 } else {
18321 generate_exception_end(ctx, EXCP_RI);
18322 }
18323 break;
18324 }
18325
18326 tcg_temp_free(t0);
18327 }
18328 break;
18329 case NM_FORK:
18330 check_mt(ctx);
18331 {
18332 TCGv t0 = tcg_temp_new();
18333 TCGv t1 = tcg_temp_new();
18334
18335 gen_load_gpr(t0, rt);
18336 gen_load_gpr(t1, rs);
18337 gen_helper_fork(t0, t1);
18338 tcg_temp_free(t0);
18339 tcg_temp_free(t1);
18340 }
18341 break;
18342 case NM_MFTR:
18343 case NM_MFHTR:
18344 check_cp0_enabled(ctx);
18345 if (rd == 0) {
18346 /* Treat as NOP. */
18347 return;
18348 }
18349 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18350 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18351 break;
18352 case NM_MTTR:
18353 case NM_MTHTR:
18354 check_cp0_enabled(ctx);
18355 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18356 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18357 break;
18358 case NM_YIELD:
18359 check_mt(ctx);
18360 {
18361 TCGv t0 = tcg_temp_new();
18362
18363 gen_load_gpr(t0, rs);
18364 gen_helper_yield(t0, cpu_env, t0);
18365 gen_store_gpr(t0, rt);
18366 tcg_temp_free(t0);
18367 }
18368 break;
e0cf0e65
YK
18369#endif
18370 default:
18371 generate_exception_end(ctx, EXCP_RI);
18372 break;
18373 }
18374}
18375
2ed42efa
SM
18376/* dsp */
18377static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18378 int ret, int v1, int v2)
18379{
18380 TCGv_i32 t0;
18381 TCGv v0_t;
18382 TCGv v1_t;
18383
18384 t0 = tcg_temp_new_i32();
18385
18386 v0_t = tcg_temp_new();
18387 v1_t = tcg_temp_new();
18388
18389 tcg_gen_movi_i32(t0, v2 >> 3);
18390
18391 gen_load_gpr(v0_t, ret);
18392 gen_load_gpr(v1_t, v1);
18393
18394 switch (opc) {
18395 case NM_MAQ_S_W_PHR:
18396 check_dsp(ctx);
18397 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18398 break;
18399 case NM_MAQ_S_W_PHL:
18400 check_dsp(ctx);
18401 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18402 break;
18403 case NM_MAQ_SA_W_PHR:
18404 check_dsp(ctx);
18405 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18406 break;
18407 case NM_MAQ_SA_W_PHL:
18408 check_dsp(ctx);
18409 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18410 break;
18411 default:
18412 generate_exception_end(ctx, EXCP_RI);
18413 break;
18414 }
18415
18416 tcg_temp_free_i32(t0);
18417
18418 tcg_temp_free(v0_t);
18419 tcg_temp_free(v1_t);
18420}
18421
18422
18423static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18424 int ret, int v1, int v2)
18425{
18426 int16_t imm;
18427 TCGv t0 = tcg_temp_new();
18428 TCGv t1 = tcg_temp_new();
18429 TCGv v0_t = tcg_temp_new();
18430
18431 gen_load_gpr(v0_t, v1);
18432
18433 switch (opc) {
18434 case NM_POOL32AXF_1_0:
18435 check_dsp(ctx);
18436 switch (extract32(ctx->opcode, 12, 2)) {
18437 case NM_MFHI:
18438 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18439 break;
18440 case NM_MFLO:
18441 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18442 break;
18443 case NM_MTHI:
18444 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18445 break;
18446 case NM_MTLO:
18447 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18448 break;
18449 }
18450 break;
18451 case NM_POOL32AXF_1_1:
18452 check_dsp(ctx);
18453 switch (extract32(ctx->opcode, 12, 2)) {
18454 case NM_MTHLIP:
18455 tcg_gen_movi_tl(t0, v2);
18456 gen_helper_mthlip(t0, v0_t, cpu_env);
18457 break;
18458 case NM_SHILOV:
18459 tcg_gen_movi_tl(t0, v2 >> 3);
18460 gen_helper_shilo(t0, v0_t, cpu_env);
18461 break;
18462 default:
18463 generate_exception_end(ctx, EXCP_RI);
18464 break;
18465 }
18466 break;
18467 case NM_POOL32AXF_1_3:
18468 check_dsp(ctx);
18469 imm = extract32(ctx->opcode, 14, 7);
18470 switch (extract32(ctx->opcode, 12, 2)) {
18471 case NM_RDDSP:
18472 tcg_gen_movi_tl(t0, imm);
18473 gen_helper_rddsp(t0, t0, cpu_env);
18474 gen_store_gpr(t0, ret);
18475 break;
18476 case NM_WRDSP:
18477 gen_load_gpr(t0, ret);
18478 tcg_gen_movi_tl(t1, imm);
18479 gen_helper_wrdsp(t0, t1, cpu_env);
18480 break;
18481 case NM_EXTP:
18482 tcg_gen_movi_tl(t0, v2 >> 3);
18483 tcg_gen_movi_tl(t1, v1);
18484 gen_helper_extp(t0, t0, t1, cpu_env);
18485 gen_store_gpr(t0, ret);
18486 break;
18487 case NM_EXTPDP:
18488 tcg_gen_movi_tl(t0, v2 >> 3);
18489 tcg_gen_movi_tl(t1, v1);
18490 gen_helper_extpdp(t0, t0, t1, cpu_env);
18491 gen_store_gpr(t0, ret);
18492 break;
18493 }
18494 break;
18495 case NM_POOL32AXF_1_4:
18496 check_dsp(ctx);
18497 tcg_gen_movi_tl(t0, v2 >> 2);
18498 switch (extract32(ctx->opcode, 12, 1)) {
18499 case NM_SHLL_QB:
18500 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18501 gen_store_gpr(t0, ret);
18502 break;
18503 case NM_SHRL_QB:
18504 gen_helper_shrl_qb(t0, t0, v0_t);
18505 gen_store_gpr(t0, ret);
18506 break;
18507 }
18508 break;
18509 case NM_POOL32AXF_1_5:
18510 opc = extract32(ctx->opcode, 12, 2);
18511 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18512 break;
18513 case NM_POOL32AXF_1_7:
18514 check_dsp(ctx);
18515 tcg_gen_movi_tl(t0, v2 >> 3);
18516 tcg_gen_movi_tl(t1, v1);
18517 switch (extract32(ctx->opcode, 12, 2)) {
18518 case NM_EXTR_W:
18519 gen_helper_extr_w(t0, t0, t1, cpu_env);
18520 gen_store_gpr(t0, ret);
18521 break;
18522 case NM_EXTR_R_W:
18523 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18524 gen_store_gpr(t0, ret);
18525 break;
18526 case NM_EXTR_RS_W:
18527 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18528 gen_store_gpr(t0, ret);
18529 break;
18530 case NM_EXTR_S_H:
18531 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18532 gen_store_gpr(t0, ret);
18533 break;
18534 }
18535 break;
18536 default:
18537 generate_exception_end(ctx, EXCP_RI);
18538 break;
18539 }
18540
18541 tcg_temp_free(t0);
18542 tcg_temp_free(t1);
18543 tcg_temp_free(v0_t);
18544}
18545
8b3698b2
SM
18546static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18547 TCGv v0, TCGv v1, int rd)
18548{
18549 TCGv_i32 t0;
18550
18551 t0 = tcg_temp_new_i32();
18552
18553 tcg_gen_movi_i32(t0, rd >> 3);
18554
18555 switch (opc) {
18556 case NM_POOL32AXF_2_0_7:
18557 switch (extract32(ctx->opcode, 9, 3)) {
18558 case NM_DPA_W_PH:
908f6be1 18559 check_dsp_r2(ctx);
8b3698b2
SM
18560 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18561 break;
18562 case NM_DPAQ_S_W_PH:
18563 check_dsp(ctx);
18564 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18565 break;
18566 case NM_DPS_W_PH:
908f6be1 18567 check_dsp_r2(ctx);
8b3698b2
SM
18568 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18569 break;
18570 case NM_DPSQ_S_W_PH:
18571 check_dsp(ctx);
18572 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18573 break;
18574 default:
18575 generate_exception_end(ctx, EXCP_RI);
18576 break;
18577 }
18578 break;
18579 case NM_POOL32AXF_2_8_15:
18580 switch (extract32(ctx->opcode, 9, 3)) {
18581 case NM_DPAX_W_PH:
908f6be1 18582 check_dsp_r2(ctx);
8b3698b2
SM
18583 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18584 break;
18585 case NM_DPAQ_SA_L_W:
18586 check_dsp(ctx);
18587 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18588 break;
18589 case NM_DPSX_W_PH:
908f6be1 18590 check_dsp_r2(ctx);
8b3698b2
SM
18591 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18592 break;
18593 case NM_DPSQ_SA_L_W:
18594 check_dsp(ctx);
18595 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18596 break;
18597 default:
18598 generate_exception_end(ctx, EXCP_RI);
18599 break;
18600 }
18601 break;
18602 case NM_POOL32AXF_2_16_23:
18603 switch (extract32(ctx->opcode, 9, 3)) {
18604 case NM_DPAU_H_QBL:
18605 check_dsp(ctx);
18606 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18607 break;
18608 case NM_DPAQX_S_W_PH:
908f6be1 18609 check_dsp_r2(ctx);
8b3698b2
SM
18610 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18611 break;
18612 case NM_DPSU_H_QBL:
18613 check_dsp(ctx);
18614 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18615 break;
18616 case NM_DPSQX_S_W_PH:
908f6be1 18617 check_dsp_r2(ctx);
8b3698b2
SM
18618 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18619 break;
18620 case NM_MULSA_W_PH:
908f6be1 18621 check_dsp_r2(ctx);
8b3698b2
SM
18622 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18623 break;
18624 default:
18625 generate_exception_end(ctx, EXCP_RI);
18626 break;
18627 }
18628 break;
18629 case NM_POOL32AXF_2_24_31:
18630 switch (extract32(ctx->opcode, 9, 3)) {
18631 case NM_DPAU_H_QBR:
18632 check_dsp(ctx);
18633 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18634 break;
18635 case NM_DPAQX_SA_W_PH:
908f6be1 18636 check_dsp_r2(ctx);
8b3698b2
SM
18637 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18638 break;
18639 case NM_DPSU_H_QBR:
18640 check_dsp(ctx);
18641 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18642 break;
18643 case NM_DPSQX_SA_W_PH:
908f6be1 18644 check_dsp_r2(ctx);
8b3698b2
SM
18645 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18646 break;
18647 case NM_MULSAQ_S_W_PH:
18648 check_dsp(ctx);
18649 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18650 break;
18651 default:
18652 generate_exception_end(ctx, EXCP_RI);
18653 break;
18654 }
18655 break;
18656 default:
18657 generate_exception_end(ctx, EXCP_RI);
18658 break;
18659 }
18660
18661 tcg_temp_free_i32(t0);
18662}
18663
18664static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18665 int rt, int rs, int rd)
18666{
18667 int ret = rt;
18668 TCGv t0 = tcg_temp_new();
18669 TCGv t1 = tcg_temp_new();
18670 TCGv v0_t = tcg_temp_new();
18671 TCGv v1_t = tcg_temp_new();
18672
18673 gen_load_gpr(v0_t, rt);
18674 gen_load_gpr(v1_t, rs);
18675
18676 switch (opc) {
18677 case NM_POOL32AXF_2_0_7:
18678 switch (extract32(ctx->opcode, 9, 3)) {
18679 case NM_DPA_W_PH:
18680 case NM_DPAQ_S_W_PH:
18681 case NM_DPS_W_PH:
18682 case NM_DPSQ_S_W_PH:
18683 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18684 break;
18685 case NM_BALIGN:
908f6be1 18686 check_dsp_r2(ctx);
8b3698b2
SM
18687 if (rt != 0) {
18688 gen_load_gpr(t0, rs);
18689 rd &= 3;
18690 if (rd != 0 && rd != 2) {
18691 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18692 tcg_gen_ext32u_tl(t0, t0);
18693 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18694 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18695 }
18696 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18697 }
18698 break;
18699 case NM_MADD:
18700 check_dsp(ctx);
18701 {
18702 int acc = extract32(ctx->opcode, 14, 2);
18703 TCGv_i64 t2 = tcg_temp_new_i64();
18704 TCGv_i64 t3 = tcg_temp_new_i64();
18705
18706 gen_load_gpr(t0, rt);
18707 gen_load_gpr(t1, rs);
18708 tcg_gen_ext_tl_i64(t2, t0);
18709 tcg_gen_ext_tl_i64(t3, t1);
18710 tcg_gen_mul_i64(t2, t2, t3);
18711 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18712 tcg_gen_add_i64(t2, t2, t3);
18713 tcg_temp_free_i64(t3);
18714 gen_move_low32(cpu_LO[acc], t2);
18715 gen_move_high32(cpu_HI[acc], t2);
18716 tcg_temp_free_i64(t2);
18717 }
18718 break;
18719 case NM_MULT:
18720 check_dsp(ctx);
18721 {
18722 int acc = extract32(ctx->opcode, 14, 2);
18723 TCGv_i32 t2 = tcg_temp_new_i32();
18724 TCGv_i32 t3 = tcg_temp_new_i32();
18725
18726 gen_load_gpr(t0, rs);
18727 gen_load_gpr(t1, rt);
18728 tcg_gen_trunc_tl_i32(t2, t0);
18729 tcg_gen_trunc_tl_i32(t3, t1);
18730 tcg_gen_muls2_i32(t2, t3, t2, t3);
18731 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18732 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18733 tcg_temp_free_i32(t2);
18734 tcg_temp_free_i32(t3);
18735 }
18736 break;
18737 case NM_EXTRV_W:
18738 check_dsp(ctx);
18739 gen_load_gpr(v1_t, rs);
18740 tcg_gen_movi_tl(t0, rd >> 3);
18741 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18742 gen_store_gpr(t0, ret);
18743 break;
18744 }
18745 break;
18746 case NM_POOL32AXF_2_8_15:
18747 switch (extract32(ctx->opcode, 9, 3)) {
18748 case NM_DPAX_W_PH:
18749 case NM_DPAQ_SA_L_W:
18750 case NM_DPSX_W_PH:
18751 case NM_DPSQ_SA_L_W:
18752 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18753 break;
18754 case NM_MADDU:
18755 check_dsp(ctx);
18756 {
18757 int acc = extract32(ctx->opcode, 14, 2);
18758 TCGv_i64 t2 = tcg_temp_new_i64();
18759 TCGv_i64 t3 = tcg_temp_new_i64();
18760
18761 gen_load_gpr(t0, rs);
18762 gen_load_gpr(t1, rt);
18763 tcg_gen_ext32u_tl(t0, t0);
18764 tcg_gen_ext32u_tl(t1, t1);
18765 tcg_gen_extu_tl_i64(t2, t0);
18766 tcg_gen_extu_tl_i64(t3, t1);
18767 tcg_gen_mul_i64(t2, t2, t3);
18768 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18769 tcg_gen_add_i64(t2, t2, t3);
18770 tcg_temp_free_i64(t3);
18771 gen_move_low32(cpu_LO[acc], t2);
18772 gen_move_high32(cpu_HI[acc], t2);
18773 tcg_temp_free_i64(t2);
18774 }
18775 break;
18776 case NM_MULTU:
18777 check_dsp(ctx);
18778 {
18779 int acc = extract32(ctx->opcode, 14, 2);
18780 TCGv_i32 t2 = tcg_temp_new_i32();
18781 TCGv_i32 t3 = tcg_temp_new_i32();
18782
18783 gen_load_gpr(t0, rs);
18784 gen_load_gpr(t1, rt);
18785 tcg_gen_trunc_tl_i32(t2, t0);
18786 tcg_gen_trunc_tl_i32(t3, t1);
18787 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18788 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18789 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18790 tcg_temp_free_i32(t2);
18791 tcg_temp_free_i32(t3);
18792 }
18793 break;
18794 case NM_EXTRV_R_W:
18795 check_dsp(ctx);
18796 tcg_gen_movi_tl(t0, rd >> 3);
18797 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18798 gen_store_gpr(t0, ret);
18799 break;
18800 default:
18801 generate_exception_end(ctx, EXCP_RI);
18802 break;
18803 }
18804 break;
18805 case NM_POOL32AXF_2_16_23:
18806 switch (extract32(ctx->opcode, 9, 3)) {
18807 case NM_DPAU_H_QBL:
18808 case NM_DPAQX_S_W_PH:
18809 case NM_DPSU_H_QBL:
18810 case NM_DPSQX_S_W_PH:
18811 case NM_MULSA_W_PH:
18812 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18813 break;
18814 case NM_EXTPV:
18815 check_dsp(ctx);
18816 tcg_gen_movi_tl(t0, rd >> 3);
18817 gen_helper_extp(t0, t0, v1_t, cpu_env);
18818 gen_store_gpr(t0, ret);
18819 break;
18820 case NM_MSUB:
18821 check_dsp(ctx);
18822 {
18823 int acc = extract32(ctx->opcode, 14, 2);
18824 TCGv_i64 t2 = tcg_temp_new_i64();
18825 TCGv_i64 t3 = tcg_temp_new_i64();
18826
18827 gen_load_gpr(t0, rs);
18828 gen_load_gpr(t1, rt);
18829 tcg_gen_ext_tl_i64(t2, t0);
18830 tcg_gen_ext_tl_i64(t3, t1);
18831 tcg_gen_mul_i64(t2, t2, t3);
18832 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18833 tcg_gen_sub_i64(t2, t3, t2);
18834 tcg_temp_free_i64(t3);
18835 gen_move_low32(cpu_LO[acc], t2);
18836 gen_move_high32(cpu_HI[acc], t2);
18837 tcg_temp_free_i64(t2);
18838 }
18839 break;
18840 case NM_EXTRV_RS_W:
18841 check_dsp(ctx);
18842 tcg_gen_movi_tl(t0, rd >> 3);
18843 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18844 gen_store_gpr(t0, ret);
18845 break;
18846 }
18847 break;
18848 case NM_POOL32AXF_2_24_31:
18849 switch (extract32(ctx->opcode, 9, 3)) {
18850 case NM_DPAU_H_QBR:
18851 case NM_DPAQX_SA_W_PH:
18852 case NM_DPSU_H_QBR:
18853 case NM_DPSQX_SA_W_PH:
18854 case NM_MULSAQ_S_W_PH:
18855 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18856 break;
18857 case NM_EXTPDPV:
18858 check_dsp(ctx);
18859 tcg_gen_movi_tl(t0, rd >> 3);
18860 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18861 gen_store_gpr(t0, ret);
18862 break;
18863 case NM_MSUBU:
18864 check_dsp(ctx);
18865 {
18866 int acc = extract32(ctx->opcode, 14, 2);
18867 TCGv_i64 t2 = tcg_temp_new_i64();
18868 TCGv_i64 t3 = tcg_temp_new_i64();
18869
18870 gen_load_gpr(t0, rs);
18871 gen_load_gpr(t1, rt);
18872 tcg_gen_ext32u_tl(t0, t0);
18873 tcg_gen_ext32u_tl(t1, t1);
18874 tcg_gen_extu_tl_i64(t2, t0);
18875 tcg_gen_extu_tl_i64(t3, t1);
18876 tcg_gen_mul_i64(t2, t2, t3);
18877 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18878 tcg_gen_sub_i64(t2, t3, t2);
18879 tcg_temp_free_i64(t3);
18880 gen_move_low32(cpu_LO[acc], t2);
18881 gen_move_high32(cpu_HI[acc], t2);
18882 tcg_temp_free_i64(t2);
18883 }
18884 break;
18885 case NM_EXTRV_S_H:
18886 check_dsp(ctx);
18887 tcg_gen_movi_tl(t0, rd >> 3);
18888 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18889 gen_store_gpr(t0, ret);
18890 break;
18891 }
18892 break;
18893 default:
18894 generate_exception_end(ctx, EXCP_RI);
18895 break;
18896 }
18897
18898 tcg_temp_free(t0);
18899 tcg_temp_free(t1);
18900
18901 tcg_temp_free(v0_t);
18902 tcg_temp_free(v1_t);
18903}
18904
4c75c985
SM
18905static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18906 int rt, int rs)
18907{
18908 int ret = rt;
18909 TCGv t0 = tcg_temp_new();
18910 TCGv v0_t = tcg_temp_new();
18911
18912 gen_load_gpr(v0_t, rs);
18913
18914 switch (opc) {
18915 case NM_ABSQ_S_QB:
908f6be1 18916 check_dsp_r2(ctx);
4c75c985
SM
18917 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18918 gen_store_gpr(v0_t, ret);
18919 break;
18920 case NM_ABSQ_S_PH:
18921 check_dsp(ctx);
18922 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18923 gen_store_gpr(v0_t, ret);
18924 break;
18925 case NM_ABSQ_S_W:
18926 check_dsp(ctx);
18927 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18928 gen_store_gpr(v0_t, ret);
18929 break;
18930 case NM_PRECEQ_W_PHL:
18931 check_dsp(ctx);
18932 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18933 tcg_gen_ext32s_tl(v0_t, v0_t);
18934 gen_store_gpr(v0_t, ret);
18935 break;
18936 case NM_PRECEQ_W_PHR:
18937 check_dsp(ctx);
18938 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18939 tcg_gen_shli_tl(v0_t, v0_t, 16);
18940 tcg_gen_ext32s_tl(v0_t, v0_t);
18941 gen_store_gpr(v0_t, ret);
18942 break;
18943 case NM_PRECEQU_PH_QBL:
18944 check_dsp(ctx);
18945 gen_helper_precequ_ph_qbl(v0_t, v0_t);
18946 gen_store_gpr(v0_t, ret);
18947 break;
18948 case NM_PRECEQU_PH_QBR:
18949 check_dsp(ctx);
18950 gen_helper_precequ_ph_qbr(v0_t, v0_t);
18951 gen_store_gpr(v0_t, ret);
18952 break;
18953 case NM_PRECEQU_PH_QBLA:
18954 check_dsp(ctx);
18955 gen_helper_precequ_ph_qbla(v0_t, v0_t);
18956 gen_store_gpr(v0_t, ret);
18957 break;
18958 case NM_PRECEQU_PH_QBRA:
18959 check_dsp(ctx);
18960 gen_helper_precequ_ph_qbra(v0_t, v0_t);
18961 gen_store_gpr(v0_t, ret);
18962 break;
18963 case NM_PRECEU_PH_QBL:
18964 check_dsp(ctx);
18965 gen_helper_preceu_ph_qbl(v0_t, v0_t);
18966 gen_store_gpr(v0_t, ret);
18967 break;
18968 case NM_PRECEU_PH_QBR:
18969 check_dsp(ctx);
18970 gen_helper_preceu_ph_qbr(v0_t, v0_t);
18971 gen_store_gpr(v0_t, ret);
18972 break;
18973 case NM_PRECEU_PH_QBLA:
18974 check_dsp(ctx);
18975 gen_helper_preceu_ph_qbla(v0_t, v0_t);
18976 gen_store_gpr(v0_t, ret);
18977 break;
18978 case NM_PRECEU_PH_QBRA:
18979 check_dsp(ctx);
18980 gen_helper_preceu_ph_qbra(v0_t, v0_t);
18981 gen_store_gpr(v0_t, ret);
18982 break;
18983 case NM_REPLV_PH:
18984 check_dsp(ctx);
18985 tcg_gen_ext16u_tl(v0_t, v0_t);
18986 tcg_gen_shli_tl(t0, v0_t, 16);
18987 tcg_gen_or_tl(v0_t, v0_t, t0);
18988 tcg_gen_ext32s_tl(v0_t, v0_t);
18989 gen_store_gpr(v0_t, ret);
18990 break;
18991 case NM_REPLV_QB:
18992 check_dsp(ctx);
18993 tcg_gen_ext8u_tl(v0_t, v0_t);
18994 tcg_gen_shli_tl(t0, v0_t, 8);
18995 tcg_gen_or_tl(v0_t, v0_t, t0);
18996 tcg_gen_shli_tl(t0, v0_t, 16);
18997 tcg_gen_or_tl(v0_t, v0_t, t0);
18998 tcg_gen_ext32s_tl(v0_t, v0_t);
18999 gen_store_gpr(v0_t, ret);
19000 break;
19001 case NM_BITREV:
19002 check_dsp(ctx);
19003 gen_helper_bitrev(v0_t, v0_t);
19004 gen_store_gpr(v0_t, ret);
19005 break;
19006 case NM_INSV:
19007 check_dsp(ctx);
19008 {
19009 TCGv tv0 = tcg_temp_new();
19010
19011 gen_load_gpr(tv0, rt);
19012 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19013 gen_store_gpr(v0_t, ret);
19014 tcg_temp_free(tv0);
19015 }
19016 break;
19017 case NM_RADDU_W_QB:
19018 check_dsp(ctx);
19019 gen_helper_raddu_w_qb(v0_t, v0_t);
19020 gen_store_gpr(v0_t, ret);
19021 break;
19022 case NM_BITSWAP:
19023 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19024 break;
19025 case NM_CLO:
fb32f8c8 19026 check_nms(ctx);
4c75c985
SM
19027 gen_cl(ctx, OPC_CLO, ret, rs);
19028 break;
19029 case NM_CLZ:
fb32f8c8 19030 check_nms(ctx);
4c75c985
SM
19031 gen_cl(ctx, OPC_CLZ, ret, rs);
19032 break;
19033 case NM_WSBH:
19034 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19035 break;
19036 default:
19037 generate_exception_end(ctx, EXCP_RI);
19038 break;
19039 }
19040
19041 tcg_temp_free(v0_t);
19042 tcg_temp_free(t0);
19043}
19044
0b591184
SM
19045static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19046 int rt, int rs, int rd)
19047{
19048 TCGv t0 = tcg_temp_new();
19049 TCGv rs_t = tcg_temp_new();
19050
19051 gen_load_gpr(rs_t, rs);
19052
19053 switch (opc) {
19054 case NM_SHRA_R_QB:
908f6be1 19055 check_dsp_r2(ctx);
0b591184
SM
19056 tcg_gen_movi_tl(t0, rd >> 2);
19057 switch (extract32(ctx->opcode, 12, 1)) {
19058 case 0:
19059 /* NM_SHRA_QB */
19060 gen_helper_shra_qb(t0, t0, rs_t);
19061 gen_store_gpr(t0, rt);
19062 break;
19063 case 1:
19064 /* NM_SHRA_R_QB */
19065 gen_helper_shra_r_qb(t0, t0, rs_t);
19066 gen_store_gpr(t0, rt);
19067 break;
19068 }
19069 break;
19070 case NM_SHRL_PH:
908f6be1 19071 check_dsp_r2(ctx);
0b591184
SM
19072 tcg_gen_movi_tl(t0, rd >> 1);
19073 gen_helper_shrl_ph(t0, t0, rs_t);
19074 gen_store_gpr(t0, rt);
19075 break;
19076 case NM_REPL_QB:
19077 check_dsp(ctx);
19078 {
19079 int16_t imm;
19080 target_long result;
19081 imm = extract32(ctx->opcode, 13, 8);
19082 result = (uint32_t)imm << 24 |
19083 (uint32_t)imm << 16 |
19084 (uint32_t)imm << 8 |
19085 (uint32_t)imm;
19086 result = (int32_t)result;
19087 tcg_gen_movi_tl(t0, result);
19088 gen_store_gpr(t0, rt);
19089 }
19090 break;
19091 default:
19092 generate_exception_end(ctx, EXCP_RI);
19093 break;
19094 }
19095 tcg_temp_free(t0);
19096 tcg_temp_free(rs_t);
19097}
19098
2ed42efa 19099
64224187
YK
19100static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19101{
64224187
YK
19102 int rt = extract32(ctx->opcode, 21, 5);
19103 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 19104 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
19105
19106 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
19107 case NM_POOL32AXF_1:
19108 {
19109 int32_t op1 = extract32(ctx->opcode, 9, 3);
19110 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19111 }
19112 break;
19113 case NM_POOL32AXF_2:
8b3698b2
SM
19114 {
19115 int32_t op1 = extract32(ctx->opcode, 12, 2);
19116 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19117 }
2ed42efa 19118 break;
64224187 19119 case NM_POOL32AXF_4:
4c75c985
SM
19120 {
19121 int32_t op1 = extract32(ctx->opcode, 9, 7);
19122 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19123 }
2ed42efa 19124 break;
64224187
YK
19125 case NM_POOL32AXF_5:
19126 switch (extract32(ctx->opcode, 9, 7)) {
19127#ifndef CONFIG_USER_ONLY
19128 case NM_TLBP:
19129 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19130 break;
19131 case NM_TLBR:
19132 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19133 break;
19134 case NM_TLBWI:
19135 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19136 break;
19137 case NM_TLBWR:
19138 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19139 break;
19140 case NM_TLBINV:
19141 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19142 break;
19143 case NM_TLBINVF:
19144 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19145 break;
19146 case NM_DI:
19147 check_cp0_enabled(ctx);
19148 {
19149 TCGv t0 = tcg_temp_new();
19150
19151 save_cpu_state(ctx, 1);
19152 gen_helper_di(t0, cpu_env);
19153 gen_store_gpr(t0, rt);
19154 /* Stop translation as we may have switched the execution mode */
19155 ctx->base.is_jmp = DISAS_STOP;
19156 tcg_temp_free(t0);
19157 }
19158 break;
19159 case NM_EI:
19160 check_cp0_enabled(ctx);
19161 {
19162 TCGv t0 = tcg_temp_new();
19163
19164 save_cpu_state(ctx, 1);
19165 gen_helper_ei(t0, cpu_env);
19166 gen_store_gpr(t0, rt);
19167 /* Stop translation as we may have switched the execution mode */
19168 ctx->base.is_jmp = DISAS_STOP;
19169 tcg_temp_free(t0);
19170 }
19171 break;
19172 case NM_RDPGPR:
19173 gen_load_srsgpr(rs, rt);
19174 break;
19175 case NM_WRPGPR:
19176 gen_store_srsgpr(rs, rt);
19177 break;
19178 case NM_WAIT:
19179 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19180 break;
19181 case NM_DERET:
19182 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19183 break;
19184 case NM_ERETX:
19185 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19186 break;
19187#endif
19188 default:
19189 generate_exception_end(ctx, EXCP_RI);
19190 break;
19191 }
19192 break;
2ed42efa 19193 case NM_POOL32AXF_7:
0b591184
SM
19194 {
19195 int32_t op1 = extract32(ctx->opcode, 9, 3);
19196 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19197 }
2ed42efa 19198 break;
64224187
YK
19199 default:
19200 generate_exception_end(ctx, EXCP_RI);
19201 break;
19202 }
19203}
19204
11d0fc10
SM
19205/* Immediate Value Compact Branches */
19206static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19207 int rt, int32_t imm, int32_t offset)
19208{
19209 TCGCond cond;
19210 int bcond_compute = 0;
19211 TCGv t0 = tcg_temp_new();
19212 TCGv t1 = tcg_temp_new();
19213
19214 gen_load_gpr(t0, rt);
19215 tcg_gen_movi_tl(t1, imm);
19216 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19217
19218 /* Load needed operands and calculate btarget */
19219 switch (opc) {
19220 case NM_BEQIC:
19221 if (rt == 0 && imm == 0) {
19222 /* Unconditional branch */
19223 } else if (rt == 0 && imm != 0) {
19224 /* Treat as NOP */
19225 goto out;
19226 } else {
19227 bcond_compute = 1;
19228 cond = TCG_COND_EQ;
19229 }
19230 break;
19231 case NM_BBEQZC:
19232 case NM_BBNEZC:
fb32f8c8 19233 check_nms(ctx);
11d0fc10
SM
19234 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19235 generate_exception_end(ctx, EXCP_RI);
19236 goto out;
19237 } else if (rt == 0 && opc == NM_BBEQZC) {
19238 /* Unconditional branch */
19239 } else if (rt == 0 && opc == NM_BBNEZC) {
19240 /* Treat as NOP */
19241 goto out;
19242 } else {
19243 tcg_gen_shri_tl(t0, t0, imm);
19244 tcg_gen_andi_tl(t0, t0, 1);
19245 tcg_gen_movi_tl(t1, 0);
19246 bcond_compute = 1;
19247 if (opc == NM_BBEQZC) {
19248 cond = TCG_COND_EQ;
19249 } else {
19250 cond = TCG_COND_NE;
19251 }
19252 }
19253 break;
19254 case NM_BNEIC:
19255 if (rt == 0 && imm == 0) {
19256 /* Treat as NOP */
19257 goto out;
19258 } else if (rt == 0 && imm != 0) {
19259 /* Unconditional branch */
19260 } else {
19261 bcond_compute = 1;
19262 cond = TCG_COND_NE;
19263 }
19264 break;
19265 case NM_BGEIC:
19266 if (rt == 0 && imm == 0) {
19267 /* Unconditional branch */
19268 } else {
19269 bcond_compute = 1;
19270 cond = TCG_COND_GE;
19271 }
19272 break;
19273 case NM_BLTIC:
19274 bcond_compute = 1;
19275 cond = TCG_COND_LT;
19276 break;
19277 case NM_BGEIUC:
19278 if (rt == 0 && imm == 0) {
19279 /* Unconditional branch */
19280 } else {
19281 bcond_compute = 1;
19282 cond = TCG_COND_GEU;
19283 }
19284 break;
19285 case NM_BLTIUC:
19286 bcond_compute = 1;
19287 cond = TCG_COND_LTU;
19288 break;
19289 default:
19290 MIPS_INVAL("Immediate Value Compact branch");
19291 generate_exception_end(ctx, EXCP_RI);
19292 goto out;
19293 }
19294
19295 if (bcond_compute == 0) {
19296 /* Uncoditional compact branch */
19297 gen_goto_tb(ctx, 0, ctx->btarget);
19298 } else {
19299 /* Conditional compact branch */
19300 TCGLabel *fs = gen_new_label();
19301
19302 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19303
19304 gen_goto_tb(ctx, 1, ctx->btarget);
19305 gen_set_label(fs);
19306
19307 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19308 }
19309
19310out:
19311 tcg_temp_free(t0);
19312 tcg_temp_free(t1);
19313}
19314
19315/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19316static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19317 int rt)
19318{
19319 TCGv t0 = tcg_temp_new();
19320 TCGv t1 = tcg_temp_new();
19321
19322 /* load rs */
19323 gen_load_gpr(t0, rs);
19324
19325 /* link */
19326 if (rt != 0) {
19327 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19328 }
19329
19330 /* calculate btarget */
19331 tcg_gen_shli_tl(t0, t0, 1);
19332 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19333 gen_op_addr_add(ctx, btarget, t1, t0);
19334
19335 /* unconditional branch to register */
19336 tcg_gen_mov_tl(cpu_PC, btarget);
19337 tcg_gen_lookup_and_goto_ptr();
19338
19339 tcg_temp_free(t0);
19340 tcg_temp_free(t1);
19341}
19342
19343/* nanoMIPS Branches */
19344static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19345 int rs, int rt, int32_t offset)
19346{
19347 int bcond_compute = 0;
19348 TCGv t0 = tcg_temp_new();
19349 TCGv t1 = tcg_temp_new();
19350
19351 /* Load needed operands and calculate btarget */
19352 switch (opc) {
19353 /* compact branch */
19354 case OPC_BGEC:
19355 case OPC_BLTC:
19356 gen_load_gpr(t0, rs);
19357 gen_load_gpr(t1, rt);
19358 bcond_compute = 1;
19359 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19360 break;
19361 case OPC_BGEUC:
19362 case OPC_BLTUC:
19363 if (rs == 0 || rs == rt) {
19364 /* OPC_BLEZALC, OPC_BGEZALC */
19365 /* OPC_BGTZALC, OPC_BLTZALC */
19366 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19367 }
19368 gen_load_gpr(t0, rs);
19369 gen_load_gpr(t1, rt);
19370 bcond_compute = 1;
19371 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19372 break;
19373 case OPC_BC:
19374 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19375 break;
19376 case OPC_BEQZC:
19377 if (rs != 0) {
19378 /* OPC_BEQZC, OPC_BNEZC */
19379 gen_load_gpr(t0, rs);
19380 bcond_compute = 1;
19381 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19382 } else {
19383 /* OPC_JIC, OPC_JIALC */
19384 TCGv tbase = tcg_temp_new();
19385 TCGv toffset = tcg_temp_new();
19386
19387 gen_load_gpr(tbase, rt);
19388 tcg_gen_movi_tl(toffset, offset);
19389 gen_op_addr_add(ctx, btarget, tbase, toffset);
19390 tcg_temp_free(tbase);
19391 tcg_temp_free(toffset);
19392 }
19393 break;
19394 default:
19395 MIPS_INVAL("Compact branch/jump");
19396 generate_exception_end(ctx, EXCP_RI);
19397 goto out;
19398 }
19399
19400 if (bcond_compute == 0) {
19401 /* Uncoditional compact branch */
19402 switch (opc) {
19403 case OPC_BC:
19404 gen_goto_tb(ctx, 0, ctx->btarget);
19405 break;
19406 default:
19407 MIPS_INVAL("Compact branch/jump");
19408 generate_exception_end(ctx, EXCP_RI);
19409 goto out;
19410 }
19411 } else {
19412 /* Conditional compact branch */
19413 TCGLabel *fs = gen_new_label();
19414
19415 switch (opc) {
19416 case OPC_BGEUC:
19417 if (rs == 0 && rt != 0) {
19418 /* OPC_BLEZALC */
19419 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19420 } else if (rs != 0 && rt != 0 && rs == rt) {
19421 /* OPC_BGEZALC */
19422 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19423 } else {
19424 /* OPC_BGEUC */
19425 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19426 }
19427 break;
19428 case OPC_BLTUC:
19429 if (rs == 0 && rt != 0) {
19430 /* OPC_BGTZALC */
19431 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19432 } else if (rs != 0 && rt != 0 && rs == rt) {
19433 /* OPC_BLTZALC */
19434 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19435 } else {
19436 /* OPC_BLTUC */
19437 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19438 }
19439 break;
19440 case OPC_BGEC:
19441 if (rs == 0 && rt != 0) {
19442 /* OPC_BLEZC */
19443 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19444 } else if (rs != 0 && rt != 0 && rs == rt) {
19445 /* OPC_BGEZC */
19446 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19447 } else {
19448 /* OPC_BGEC */
19449 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19450 }
19451 break;
19452 case OPC_BLTC:
19453 if (rs == 0 && rt != 0) {
19454 /* OPC_BGTZC */
19455 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19456 } else if (rs != 0 && rt != 0 && rs == rt) {
19457 /* OPC_BLTZC */
19458 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19459 } else {
19460 /* OPC_BLTC */
19461 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19462 }
19463 break;
19464 case OPC_BEQZC:
19465 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19466 break;
19467 default:
19468 MIPS_INVAL("Compact conditional branch/jump");
19469 generate_exception_end(ctx, EXCP_RI);
19470 goto out;
19471 }
19472
19473 /* Generating branch here as compact branches don't have delay slot */
19474 gen_goto_tb(ctx, 1, ctx->btarget);
19475 gen_set_label(fs);
19476
19477 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19478 }
19479
19480out:
19481 tcg_temp_free(t0);
19482 tcg_temp_free(t1);
19483}
19484
19485
19486/* nanoMIPS CP1 Branches */
19487static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19488 int32_t ft, int32_t offset)
19489{
19490 target_ulong btarget;
19491 TCGv_i64 t0 = tcg_temp_new_i64();
19492
19493 gen_load_fpr64(ctx, t0, ft);
19494 tcg_gen_andi_i64(t0, t0, 1);
19495
19496 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19497
19498 switch (op) {
19499 case NM_BC1EQZC:
19500 tcg_gen_xori_i64(t0, t0, 1);
19501 ctx->hflags |= MIPS_HFLAG_BC;
19502 break;
19503 case NM_BC1NEZC:
19504 /* t0 already set */
19505 ctx->hflags |= MIPS_HFLAG_BC;
19506 break;
19507 default:
19508 MIPS_INVAL("cp1 cond branch");
19509 generate_exception_end(ctx, EXCP_RI);
19510 goto out;
19511 }
19512
19513 tcg_gen_trunc_i64_tl(bcond, t0);
19514
19515 ctx->btarget = btarget;
19516
19517out:
19518 tcg_temp_free_i64(t0);
19519}
19520
eac52664
YK
19521
19522static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19523{
19524 TCGv t0, t1;
19525 t0 = tcg_temp_new();
19526 t1 = tcg_temp_new();
19527
19528 gen_load_gpr(t0, rs);
19529 gen_load_gpr(t1, rt);
19530
19531 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19532 /* PP.LSXS instructions require shifting */
19533 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 19534 case NM_SHXS:
fb32f8c8
DN
19535 check_nms(ctx);
19536 case NM_LHXS:
eac52664
YK
19537 case NM_LHUXS:
19538 tcg_gen_shli_tl(t0, t0, 1);
19539 break;
eac52664 19540 case NM_SWXS:
fb32f8c8
DN
19541 check_nms(ctx);
19542 case NM_LWXS:
eac52664
YK
19543 case NM_LWC1XS:
19544 case NM_SWC1XS:
19545 tcg_gen_shli_tl(t0, t0, 2);
19546 break;
19547 case NM_LDC1XS:
19548 case NM_SDC1XS:
19549 tcg_gen_shli_tl(t0, t0, 3);
19550 break;
19551 }
19552 }
19553 gen_op_addr_add(ctx, t0, t0, t1);
19554
19555 switch (extract32(ctx->opcode, 7, 4)) {
19556 case NM_LBX:
19557 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19558 MO_SB);
19559 gen_store_gpr(t0, rd);
19560 break;
19561 case NM_LHX:
19562 /*case NM_LHXS:*/
19563 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19564 MO_TESW);
19565 gen_store_gpr(t0, rd);
19566 break;
19567 case NM_LWX:
19568 /*case NM_LWXS:*/
19569 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19570 MO_TESL);
19571 gen_store_gpr(t0, rd);
19572 break;
19573 case NM_LBUX:
19574 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19575 MO_UB);
19576 gen_store_gpr(t0, rd);
19577 break;
19578 case NM_LHUX:
19579 /*case NM_LHUXS:*/
19580 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19581 MO_TEUW);
19582 gen_store_gpr(t0, rd);
19583 break;
19584 case NM_SBX:
fb32f8c8 19585 check_nms(ctx);
eac52664
YK
19586 gen_load_gpr(t1, rd);
19587 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19588 MO_8);
19589 break;
19590 case NM_SHX:
19591 /*case NM_SHXS:*/
fb32f8c8 19592 check_nms(ctx);
eac52664
YK
19593 gen_load_gpr(t1, rd);
19594 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19595 MO_TEUW);
19596 break;
19597 case NM_SWX:
19598 /*case NM_SWXS:*/
fb32f8c8 19599 check_nms(ctx);
eac52664
YK
19600 gen_load_gpr(t1, rd);
19601 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19602 MO_TEUL);
19603 break;
19604 case NM_LWC1X:
19605 /*case NM_LWC1XS:*/
19606 case NM_LDC1X:
19607 /*case NM_LDC1XS:*/
19608 case NM_SWC1X:
19609 /*case NM_SWC1XS:*/
19610 case NM_SDC1X:
19611 /*case NM_SDC1XS:*/
19612 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19613 check_cp1_enabled(ctx);
19614 switch (extract32(ctx->opcode, 7, 4)) {
19615 case NM_LWC1X:
19616 /*case NM_LWC1XS:*/
19617 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19618 break;
19619 case NM_LDC1X:
19620 /*case NM_LDC1XS:*/
19621 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19622 break;
19623 case NM_SWC1X:
19624 /*case NM_SWC1XS:*/
19625 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19626 break;
19627 case NM_SDC1X:
19628 /*case NM_SDC1XS:*/
19629 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19630 break;
19631 }
19632 } else {
19633 generate_exception_err(ctx, EXCP_CpU, 1);
19634 }
19635 break;
19636 default:
19637 generate_exception_end(ctx, EXCP_RI);
19638 break;
19639 }
19640
19641 tcg_temp_free(t0);
19642 tcg_temp_free(t1);
19643}
19644
579b8ea9
YK
19645static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19646{
19647 int rt, rs, rd;
19648
19649 rt = extract32(ctx->opcode, 21, 5);
19650 rs = extract32(ctx->opcode, 16, 5);
19651 rd = extract32(ctx->opcode, 11, 5);
19652
19653 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19654 generate_exception_end(ctx, EXCP_RI);
19655 return;
19656 }
19657 check_cp1_enabled(ctx);
19658 switch (extract32(ctx->opcode, 0, 3)) {
19659 case NM_POOL32F_0:
19660 switch (extract32(ctx->opcode, 3, 7)) {
19661 case NM_RINT_S:
19662 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19663 break;
19664 case NM_RINT_D:
19665 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19666 break;
19667 case NM_CLASS_S:
19668 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19669 break;
19670 case NM_CLASS_D:
19671 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19672 break;
19673 case NM_ADD_S:
19674 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19675 break;
19676 case NM_ADD_D:
19677 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19678 break;
19679 case NM_SUB_S:
19680 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19681 break;
19682 case NM_SUB_D:
19683 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19684 break;
19685 case NM_MUL_S:
19686 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19687 break;
19688 case NM_MUL_D:
19689 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19690 break;
19691 case NM_DIV_S:
19692 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19693 break;
19694 case NM_DIV_D:
19695 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19696 break;
19697 case NM_SELEQZ_S:
19698 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19699 break;
19700 case NM_SELEQZ_D:
19701 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19702 break;
19703 case NM_SELNEZ_S:
19704 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19705 break;
19706 case NM_SELNEZ_D:
19707 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19708 break;
19709 case NM_SEL_S:
19710 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19711 break;
19712 case NM_SEL_D:
19713 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19714 break;
19715 case NM_MADDF_S:
19716 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19717 break;
19718 case NM_MADDF_D:
19719 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19720 break;
19721 case NM_MSUBF_S:
19722 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19723 break;
19724 case NM_MSUBF_D:
19725 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19726 break;
19727 default:
19728 generate_exception_end(ctx, EXCP_RI);
19729 break;
19730 }
19731 break;
19732 case NM_POOL32F_3:
19733 switch (extract32(ctx->opcode, 3, 3)) {
19734 case NM_MIN_FMT:
19735 switch (extract32(ctx->opcode, 9, 1)) {
19736 case FMT_SDPS_S:
19737 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19738 break;
19739 case FMT_SDPS_D:
19740 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19741 break;
19742 }
19743 break;
19744 case NM_MAX_FMT:
19745 switch (extract32(ctx->opcode, 9, 1)) {
19746 case FMT_SDPS_S:
19747 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19748 break;
19749 case FMT_SDPS_D:
19750 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19751 break;
19752 }
19753 break;
19754 case NM_MINA_FMT:
19755 switch (extract32(ctx->opcode, 9, 1)) {
19756 case FMT_SDPS_S:
19757 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19758 break;
19759 case FMT_SDPS_D:
19760 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19761 break;
19762 }
19763 break;
19764 case NM_MAXA_FMT:
19765 switch (extract32(ctx->opcode, 9, 1)) {
19766 case FMT_SDPS_S:
19767 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19768 break;
19769 case FMT_SDPS_D:
19770 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19771 break;
19772 }
19773 break;
19774 case NM_POOL32FXF:
19775 switch (extract32(ctx->opcode, 6, 8)) {
19776 case NM_CFC1:
19777 gen_cp1(ctx, OPC_CFC1, rt, rs);
19778 break;
19779 case NM_CTC1:
19780 gen_cp1(ctx, OPC_CTC1, rt, rs);
19781 break;
19782 case NM_MFC1:
19783 gen_cp1(ctx, OPC_MFC1, rt, rs);
19784 break;
19785 case NM_MTC1:
19786 gen_cp1(ctx, OPC_MTC1, rt, rs);
19787 break;
19788 case NM_MFHC1:
19789 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19790 break;
19791 case NM_MTHC1:
19792 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19793 break;
19794 case NM_CVT_S_PL:
19795 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19796 break;
19797 case NM_CVT_S_PU:
19798 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19799 break;
19800 default:
19801 switch (extract32(ctx->opcode, 6, 9)) {
19802 case NM_CVT_L_S:
19803 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19804 break;
19805 case NM_CVT_L_D:
19806 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19807 break;
19808 case NM_CVT_W_S:
19809 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19810 break;
19811 case NM_CVT_W_D:
19812 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19813 break;
19814 case NM_RSQRT_S:
19815 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19816 break;
19817 case NM_RSQRT_D:
19818 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19819 break;
19820 case NM_SQRT_S:
19821 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19822 break;
19823 case NM_SQRT_D:
19824 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19825 break;
19826 case NM_RECIP_S:
19827 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19828 break;
19829 case NM_RECIP_D:
19830 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19831 break;
19832 case NM_FLOOR_L_S:
19833 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19834 break;
19835 case NM_FLOOR_L_D:
19836 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19837 break;
19838 case NM_FLOOR_W_S:
19839 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19840 break;
19841 case NM_FLOOR_W_D:
19842 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19843 break;
19844 case NM_CEIL_L_S:
19845 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19846 break;
19847 case NM_CEIL_L_D:
19848 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19849 break;
19850 case NM_CEIL_W_S:
19851 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19852 break;
19853 case NM_CEIL_W_D:
19854 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19855 break;
19856 case NM_TRUNC_L_S:
19857 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19858 break;
19859 case NM_TRUNC_L_D:
19860 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19861 break;
19862 case NM_TRUNC_W_S:
19863 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19864 break;
19865 case NM_TRUNC_W_D:
19866 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19867 break;
19868 case NM_ROUND_L_S:
19869 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19870 break;
19871 case NM_ROUND_L_D:
19872 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19873 break;
19874 case NM_ROUND_W_S:
19875 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19876 break;
19877 case NM_ROUND_W_D:
19878 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19879 break;
19880 case NM_MOV_S:
19881 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19882 break;
19883 case NM_MOV_D:
19884 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19885 break;
19886 case NM_ABS_S:
19887 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19888 break;
19889 case NM_ABS_D:
19890 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19891 break;
19892 case NM_NEG_S:
19893 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19894 break;
19895 case NM_NEG_D:
19896 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19897 break;
19898 case NM_CVT_D_S:
19899 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19900 break;
19901 case NM_CVT_D_W:
19902 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19903 break;
19904 case NM_CVT_D_L:
19905 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19906 break;
19907 case NM_CVT_S_D:
19908 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19909 break;
19910 case NM_CVT_S_W:
19911 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19912 break;
19913 case NM_CVT_S_L:
19914 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19915 break;
19916 default:
19917 generate_exception_end(ctx, EXCP_RI);
19918 break;
19919 }
19920 break;
19921 }
19922 break;
19923 }
19924 break;
19925 case NM_POOL32F_5:
19926 switch (extract32(ctx->opcode, 3, 3)) {
19927 case NM_CMP_CONDN_S:
19928 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19929 break;
19930 case NM_CMP_CONDN_D:
19931 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19932 break;
19933 default:
19934 generate_exception_end(ctx, EXCP_RI);
19935 break;
19936 }
19937 break;
19938 default:
19939 generate_exception_end(ctx, EXCP_RI);
19940 break;
19941 }
19942}
19943
3285a3e4
SM
19944static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19945 int rd, int rs, int rt)
19946{
19947 int ret = rd;
19948 TCGv t0 = tcg_temp_new();
19949 TCGv v1_t = tcg_temp_new();
19950 TCGv v2_t = tcg_temp_new();
19951
19952 gen_load_gpr(v1_t, rs);
19953 gen_load_gpr(v2_t, rt);
19954
19955 switch (opc) {
19956 case NM_CMP_EQ_PH:
19957 check_dsp(ctx);
19958 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19959 break;
19960 case NM_CMP_LT_PH:
19961 check_dsp(ctx);
19962 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19963 break;
19964 case NM_CMP_LE_PH:
19965 check_dsp(ctx);
19966 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19967 break;
19968 case NM_CMPU_EQ_QB:
19969 check_dsp(ctx);
19970 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19971 break;
19972 case NM_CMPU_LT_QB:
19973 check_dsp(ctx);
19974 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19975 break;
19976 case NM_CMPU_LE_QB:
19977 check_dsp(ctx);
19978 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19979 break;
19980 case NM_CMPGU_EQ_QB:
19981 check_dsp(ctx);
19982 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19983 gen_store_gpr(v1_t, ret);
19984 break;
19985 case NM_CMPGU_LT_QB:
19986 check_dsp(ctx);
19987 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19988 gen_store_gpr(v1_t, ret);
19989 break;
19990 case NM_CMPGU_LE_QB:
19991 check_dsp(ctx);
19992 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19993 gen_store_gpr(v1_t, ret);
19994 break;
19995 case NM_CMPGDU_EQ_QB:
908f6be1 19996 check_dsp_r2(ctx);
3285a3e4
SM
19997 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19998 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19999 gen_store_gpr(v1_t, ret);
20000 break;
20001 case NM_CMPGDU_LT_QB:
908f6be1 20002 check_dsp_r2(ctx);
3285a3e4
SM
20003 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20004 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20005 gen_store_gpr(v1_t, ret);
20006 break;
20007 case NM_CMPGDU_LE_QB:
908f6be1 20008 check_dsp_r2(ctx);
3285a3e4
SM
20009 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20010 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20011 gen_store_gpr(v1_t, ret);
20012 break;
20013 case NM_PACKRL_PH:
20014 check_dsp(ctx);
20015 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20016 gen_store_gpr(v1_t, ret);
20017 break;
20018 case NM_PICK_QB:
20019 check_dsp(ctx);
20020 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20021 gen_store_gpr(v1_t, ret);
20022 break;
20023 case NM_PICK_PH:
20024 check_dsp(ctx);
20025 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20026 gen_store_gpr(v1_t, ret);
20027 break;
20028 case NM_ADDQ_S_W:
20029 check_dsp(ctx);
20030 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20031 gen_store_gpr(v1_t, ret);
20032 break;
20033 case NM_SUBQ_S_W:
20034 check_dsp(ctx);
20035 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20036 gen_store_gpr(v1_t, ret);
20037 break;
20038 case NM_ADDSC:
20039 check_dsp(ctx);
20040 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20041 gen_store_gpr(v1_t, ret);
20042 break;
20043 case NM_ADDWC:
20044 check_dsp(ctx);
20045 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20046 gen_store_gpr(v1_t, ret);
20047 break;
20048 case NM_ADDQ_S_PH:
20049 check_dsp(ctx);
20050 switch (extract32(ctx->opcode, 10, 1)) {
20051 case 0:
20052 /* ADDQ_PH */
20053 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20054 gen_store_gpr(v1_t, ret);
20055 break;
20056 case 1:
20057 /* ADDQ_S_PH */
20058 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20059 gen_store_gpr(v1_t, ret);
20060 break;
20061 }
20062 break;
20063 case NM_ADDQH_R_PH:
908f6be1 20064 check_dsp_r2(ctx);
3285a3e4
SM
20065 switch (extract32(ctx->opcode, 10, 1)) {
20066 case 0:
20067 /* ADDQH_PH */
20068 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20069 gen_store_gpr(v1_t, ret);
20070 break;
20071 case 1:
20072 /* ADDQH_R_PH */
20073 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20074 gen_store_gpr(v1_t, ret);
20075 break;
20076 }
20077 break;
20078 case NM_ADDQH_R_W:
908f6be1 20079 check_dsp_r2(ctx);
3285a3e4
SM
20080 switch (extract32(ctx->opcode, 10, 1)) {
20081 case 0:
20082 /* ADDQH_W */
20083 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20084 gen_store_gpr(v1_t, ret);
20085 break;
20086 case 1:
20087 /* ADDQH_R_W */
20088 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20089 gen_store_gpr(v1_t, ret);
20090 break;
20091 }
20092 break;
20093 case NM_ADDU_S_QB:
20094 check_dsp(ctx);
20095 switch (extract32(ctx->opcode, 10, 1)) {
20096 case 0:
20097 /* ADDU_QB */
20098 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20099 gen_store_gpr(v1_t, ret);
20100 break;
20101 case 1:
20102 /* ADDU_S_QB */
20103 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20104 gen_store_gpr(v1_t, ret);
20105 break;
20106 }
20107 break;
20108 case NM_ADDU_S_PH:
908f6be1 20109 check_dsp_r2(ctx);
3285a3e4
SM
20110 switch (extract32(ctx->opcode, 10, 1)) {
20111 case 0:
20112 /* ADDU_PH */
20113 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20114 gen_store_gpr(v1_t, ret);
20115 break;
20116 case 1:
20117 /* ADDU_S_PH */
20118 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20119 gen_store_gpr(v1_t, ret);
20120 break;
20121 }
20122 break;
20123 case NM_ADDUH_R_QB:
908f6be1 20124 check_dsp_r2(ctx);
3285a3e4
SM
20125 switch (extract32(ctx->opcode, 10, 1)) {
20126 case 0:
20127 /* ADDUH_QB */
20128 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20129 gen_store_gpr(v1_t, ret);
20130 break;
20131 case 1:
20132 /* ADDUH_R_QB */
20133 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20134 gen_store_gpr(v1_t, ret);
20135 break;
20136 }
20137 break;
20138 case NM_SHRAV_R_PH:
20139 check_dsp(ctx);
20140 switch (extract32(ctx->opcode, 10, 1)) {
20141 case 0:
20142 /* SHRAV_PH */
20143 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20144 gen_store_gpr(v1_t, ret);
20145 break;
20146 case 1:
20147 /* SHRAV_R_PH */
20148 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20149 gen_store_gpr(v1_t, ret);
20150 break;
20151 }
20152 break;
20153 case NM_SHRAV_R_QB:
908f6be1 20154 check_dsp_r2(ctx);
3285a3e4
SM
20155 switch (extract32(ctx->opcode, 10, 1)) {
20156 case 0:
20157 /* SHRAV_QB */
20158 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20159 gen_store_gpr(v1_t, ret);
20160 break;
20161 case 1:
20162 /* SHRAV_R_QB */
20163 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20164 gen_store_gpr(v1_t, ret);
20165 break;
20166 }
20167 break;
20168 case NM_SUBQ_S_PH:
20169 check_dsp(ctx);
20170 switch (extract32(ctx->opcode, 10, 1)) {
20171 case 0:
20172 /* SUBQ_PH */
20173 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20174 gen_store_gpr(v1_t, ret);
20175 break;
20176 case 1:
20177 /* SUBQ_S_PH */
20178 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20179 gen_store_gpr(v1_t, ret);
20180 break;
20181 }
20182 break;
20183 case NM_SUBQH_R_PH:
908f6be1 20184 check_dsp_r2(ctx);
3285a3e4
SM
20185 switch (extract32(ctx->opcode, 10, 1)) {
20186 case 0:
20187 /* SUBQH_PH */
20188 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20189 gen_store_gpr(v1_t, ret);
20190 break;
20191 case 1:
20192 /* SUBQH_R_PH */
20193 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20194 gen_store_gpr(v1_t, ret);
20195 break;
20196 }
20197 break;
20198 case NM_SUBQH_R_W:
908f6be1 20199 check_dsp_r2(ctx);
3285a3e4
SM
20200 switch (extract32(ctx->opcode, 10, 1)) {
20201 case 0:
20202 /* SUBQH_W */
20203 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20204 gen_store_gpr(v1_t, ret);
20205 break;
20206 case 1:
20207 /* SUBQH_R_W */
20208 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20209 gen_store_gpr(v1_t, ret);
20210 break;
20211 }
20212 break;
20213 case NM_SUBU_S_QB:
20214 check_dsp(ctx);
20215 switch (extract32(ctx->opcode, 10, 1)) {
20216 case 0:
20217 /* SUBU_QB */
20218 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20219 gen_store_gpr(v1_t, ret);
20220 break;
20221 case 1:
20222 /* SUBU_S_QB */
20223 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20224 gen_store_gpr(v1_t, ret);
20225 break;
20226 }
20227 break;
20228 case NM_SUBU_S_PH:
908f6be1 20229 check_dsp_r2(ctx);
3285a3e4
SM
20230 switch (extract32(ctx->opcode, 10, 1)) {
20231 case 0:
20232 /* SUBU_PH */
20233 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20234 gen_store_gpr(v1_t, ret);
20235 break;
20236 case 1:
20237 /* SUBU_S_PH */
20238 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20239 gen_store_gpr(v1_t, ret);
20240 break;
20241 }
20242 break;
20243 case NM_SUBUH_R_QB:
908f6be1 20244 check_dsp_r2(ctx);
3285a3e4
SM
20245 switch (extract32(ctx->opcode, 10, 1)) {
20246 case 0:
20247 /* SUBUH_QB */
20248 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20249 gen_store_gpr(v1_t, ret);
20250 break;
20251 case 1:
20252 /* SUBUH_R_QB */
20253 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20254 gen_store_gpr(v1_t, ret);
20255 break;
20256 }
20257 break;
20258 case NM_SHLLV_S_PH:
20259 check_dsp(ctx);
20260 switch (extract32(ctx->opcode, 10, 1)) {
20261 case 0:
20262 /* SHLLV_PH */
20263 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20264 gen_store_gpr(v1_t, ret);
20265 break;
20266 case 1:
20267 /* SHLLV_S_PH */
20268 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20269 gen_store_gpr(v1_t, ret);
20270 break;
20271 }
20272 break;
20273 case NM_PRECR_SRA_R_PH_W:
908f6be1 20274 check_dsp_r2(ctx);
3285a3e4
SM
20275 switch (extract32(ctx->opcode, 10, 1)) {
20276 case 0:
20277 /* PRECR_SRA_PH_W */
20278 {
20279 TCGv_i32 sa_t = tcg_const_i32(rd);
20280 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20281 cpu_gpr[rt]);
20282 gen_store_gpr(v1_t, rt);
20283 tcg_temp_free_i32(sa_t);
20284 }
20285 break;
20286 case 1:
20287 /* PRECR_SRA_R_PH_W */
20288 {
20289 TCGv_i32 sa_t = tcg_const_i32(rd);
20290 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20291 cpu_gpr[rt]);
20292 gen_store_gpr(v1_t, rt);
20293 tcg_temp_free_i32(sa_t);
20294 }
20295 break;
20296 }
20297 break;
20298 case NM_MULEU_S_PH_QBL:
20299 check_dsp(ctx);
20300 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20301 gen_store_gpr(v1_t, ret);
20302 break;
20303 case NM_MULEU_S_PH_QBR:
20304 check_dsp(ctx);
20305 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20306 gen_store_gpr(v1_t, ret);
20307 break;
20308 case NM_MULQ_RS_PH:
20309 check_dsp(ctx);
20310 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20311 gen_store_gpr(v1_t, ret);
20312 break;
20313 case NM_MULQ_S_PH:
908f6be1 20314 check_dsp_r2(ctx);
3285a3e4
SM
20315 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20316 gen_store_gpr(v1_t, ret);
20317 break;
20318 case NM_MULQ_RS_W:
908f6be1 20319 check_dsp_r2(ctx);
3285a3e4
SM
20320 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20321 gen_store_gpr(v1_t, ret);
20322 break;
20323 case NM_MULQ_S_W:
908f6be1 20324 check_dsp_r2(ctx);
3285a3e4
SM
20325 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20326 gen_store_gpr(v1_t, ret);
20327 break;
20328 case NM_APPEND:
908f6be1 20329 check_dsp_r2(ctx);
3285a3e4
SM
20330 gen_load_gpr(t0, rs);
20331 if (rd != 0) {
20332 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20333 }
20334 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20335 break;
20336 case NM_MODSUB:
20337 check_dsp(ctx);
20338 gen_helper_modsub(v1_t, v1_t, v2_t);
20339 gen_store_gpr(v1_t, ret);
20340 break;
20341 case NM_SHRAV_R_W:
20342 check_dsp(ctx);
20343 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20344 gen_store_gpr(v1_t, ret);
20345 break;
20346 case NM_SHRLV_PH:
908f6be1 20347 check_dsp_r2(ctx);
3285a3e4
SM
20348 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20349 gen_store_gpr(v1_t, ret);
20350 break;
20351 case NM_SHRLV_QB:
20352 check_dsp(ctx);
20353 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20354 gen_store_gpr(v1_t, ret);
20355 break;
20356 case NM_SHLLV_QB:
20357 check_dsp(ctx);
20358 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20359 gen_store_gpr(v1_t, ret);
20360 break;
20361 case NM_SHLLV_S_W:
20362 check_dsp(ctx);
20363 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20364 gen_store_gpr(v1_t, ret);
20365 break;
20366 case NM_SHILO:
20367 check_dsp(ctx);
20368 {
20369 TCGv tv0 = tcg_temp_new();
20370 TCGv tv1 = tcg_temp_new();
20371 int16_t imm = extract32(ctx->opcode, 16, 7);
20372
20373 tcg_gen_movi_tl(tv0, rd >> 3);
20374 tcg_gen_movi_tl(tv1, imm);
20375 gen_helper_shilo(tv0, tv1, cpu_env);
20376 }
20377 break;
20378 case NM_MULEQ_S_W_PHL:
20379 check_dsp(ctx);
20380 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20381 gen_store_gpr(v1_t, ret);
20382 break;
20383 case NM_MULEQ_S_W_PHR:
20384 check_dsp(ctx);
20385 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20386 gen_store_gpr(v1_t, ret);
20387 break;
20388 case NM_MUL_S_PH:
908f6be1 20389 check_dsp_r2(ctx);
3285a3e4
SM
20390 switch (extract32(ctx->opcode, 10, 1)) {
20391 case 0:
20392 /* MUL_PH */
20393 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20394 gen_store_gpr(v1_t, ret);
20395 break;
20396 case 1:
20397 /* MUL_S_PH */
20398 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20399 gen_store_gpr(v1_t, ret);
20400 break;
20401 }
20402 break;
20403 case NM_PRECR_QB_PH:
908f6be1 20404 check_dsp_r2(ctx);
3285a3e4
SM
20405 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20406 gen_store_gpr(v1_t, ret);
20407 break;
20408 case NM_PRECRQ_QB_PH:
20409 check_dsp(ctx);
20410 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20411 gen_store_gpr(v1_t, ret);
20412 break;
20413 case NM_PRECRQ_PH_W:
20414 check_dsp(ctx);
20415 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20416 gen_store_gpr(v1_t, ret);
20417 break;
20418 case NM_PRECRQ_RS_PH_W:
20419 check_dsp(ctx);
20420 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20421 gen_store_gpr(v1_t, ret);
20422 break;
20423 case NM_PRECRQU_S_QB_PH:
20424 check_dsp(ctx);
20425 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20426 gen_store_gpr(v1_t, ret);
20427 break;
20428 case NM_SHRA_R_W:
20429 check_dsp(ctx);
20430 tcg_gen_movi_tl(t0, rd);
20431 gen_helper_shra_r_w(v1_t, t0, v1_t);
20432 gen_store_gpr(v1_t, rt);
20433 break;
20434 case NM_SHRA_R_PH:
20435 check_dsp(ctx);
20436 tcg_gen_movi_tl(t0, rd >> 1);
20437 switch (extract32(ctx->opcode, 10, 1)) {
20438 case 0:
20439 /* SHRA_PH */
20440 gen_helper_shra_ph(v1_t, t0, v1_t);
3285a3e4 20441 gen_store_gpr(v1_t, rt);
d5ebcbaf 20442 break;
3285a3e4
SM
20443 case 1:
20444 /* SHRA_R_PH */
20445 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20446 gen_store_gpr(v1_t, rt);
20447 break;
20448 }
20449 break;
20450 case NM_SHLL_S_PH:
20451 check_dsp(ctx);
20452 tcg_gen_movi_tl(t0, rd >> 1);
20453 switch (extract32(ctx->opcode, 10, 2)) {
20454 case 0:
20455 /* SHLL_PH */
20456 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20457 gen_store_gpr(v1_t, rt);
20458 break;
20459 case 2:
20460 /* SHLL_S_PH */
20461 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20462 gen_store_gpr(v1_t, rt);
20463 break;
20464 default:
20465 generate_exception_end(ctx, EXCP_RI);
20466 break;
20467 }
20468 break;
20469 case NM_SHLL_S_W:
20470 check_dsp(ctx);
20471 tcg_gen_movi_tl(t0, rd);
20472 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20473 gen_store_gpr(v1_t, rt);
20474 break;
20475 case NM_REPL_PH:
20476 check_dsp(ctx);
20477 {
20478 int16_t imm;
20479 imm = sextract32(ctx->opcode, 11, 11);
20480 imm = (int16_t)(imm << 6) >> 6;
20481 if (rt != 0) {
20482 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20483 }
20484 }
20485 break;
20486 default:
20487 generate_exception_end(ctx, EXCP_RI);
20488 break;
20489 }
20490}
20491
c0280983
YK
20492static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20493{
20494 uint16_t insn;
20495 uint32_t op;
eac52664 20496 int rt, rs, rd;
c0280983
YK
20497 int offset;
20498 int imm;
20499
20500 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20501 ctx->opcode = (ctx->opcode << 16) | insn;
20502
20503 rt = extract32(ctx->opcode, 21, 5);
20504 rs = extract32(ctx->opcode, 16, 5);
eac52664 20505 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
20506
20507 op = extract32(ctx->opcode, 26, 6);
20508 switch (op) {
20509 case NM_P_ADDIU:
20510 if (rt == 0) {
20511 /* P.RI */
20512 switch (extract32(ctx->opcode, 19, 2)) {
20513 case NM_SIGRIE:
20514 default:
20515 generate_exception_end(ctx, EXCP_RI);
20516 break;
20517 case NM_P_SYSCALL:
20518 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20519 generate_exception_end(ctx, EXCP_SYSCALL);
20520 } else {
20521 generate_exception_end(ctx, EXCP_RI);
20522 }
20523 break;
20524 case NM_BREAK:
20525 generate_exception_end(ctx, EXCP_BREAK);
20526 break;
20527 case NM_SDBBP:
20528 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20529 gen_helper_do_semihosting(cpu_env);
20530 } else {
20531 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20532 generate_exception_end(ctx, EXCP_RI);
20533 } else {
20534 generate_exception_end(ctx, EXCP_DBp);
20535 }
20536 }
20537 break;
20538 }
20539 } else {
20540 /* NM_ADDIU */
20541 imm = extract32(ctx->opcode, 0, 16);
20542 if (rs != 0) {
20543 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20544 } else {
20545 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20546 }
20547 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20548 }
20549 break;
20550 case NM_ADDIUPC:
20551 if (rt != 0) {
20552 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20553 extract32(ctx->opcode, 1, 20) << 1;
20554 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20555 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20556 }
20557 break;
20558 case NM_POOL32A:
e0cf0e65
YK
20559 switch (ctx->opcode & 0x07) {
20560 case NM_POOL32A0:
0a1a6ed7 20561 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 20562 break;
3285a3e4
SM
20563 case NM_POOL32A5:
20564 {
20565 int32_t op1 = extract32(ctx->opcode, 3, 7);
20566 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20567 }
20568 break;
e0cf0e65 20569 case NM_POOL32A7:
64224187 20570 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
20571 case NM_P_LSX:
20572 gen_p_lsx(ctx, rd, rs, rt);
20573 break;
20574 case NM_LSA:
20575 /* In nanoMIPS, the shift field directly encodes the shift
20576 * amount, meaning that the supported shift values are in
20577 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20578 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20579 extract32(ctx->opcode, 9, 2) - 1);
20580 break;
821f2008
JH
20581 case NM_EXTW:
20582 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20583 break;
64224187
YK
20584 case NM_POOL32AXF:
20585 gen_pool32axf_nanomips_insn(env, ctx);
20586 break;
20587 default:
20588 generate_exception_end(ctx, EXCP_RI);
20589 break;
20590 }
e0cf0e65
YK
20591 break;
20592 default:
20593 generate_exception_end(ctx, EXCP_RI);
20594 break;
20595 }
c0280983
YK
20596 break;
20597 case NM_P_GP_W:
20598 switch (ctx->opcode & 0x03) {
20599 case NM_ADDIUGP_W:
20600 if (rt != 0) {
20601 offset = extract32(ctx->opcode, 0, 21);
20602 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20603 }
20604 break;
20605 case NM_LWGP:
20606 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20607 break;
20608 case NM_SWGP:
20609 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20610 break;
20611 default:
20612 generate_exception_end(ctx, EXCP_RI);
20613 break;
20614 }
20615 break;
20616 case NM_P48I:
7ef009b2
YK
20617 {
20618 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20619 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20620 switch (extract32(ctx->opcode, 16, 5)) {
20621 case NM_LI48:
fb32f8c8 20622 check_nms(ctx);
7ef009b2
YK
20623 if (rt != 0) {
20624 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20625 }
20626 break;
20627 case NM_ADDIU48:
fb32f8c8 20628 check_nms(ctx);
7ef009b2
YK
20629 if (rt != 0) {
20630 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20631 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20632 }
20633 break;
20634 case NM_ADDIUGP48:
fb32f8c8 20635 check_nms(ctx);
7ef009b2
YK
20636 if (rt != 0) {
20637 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20638 }
20639 break;
20640 case NM_ADDIUPC48:
fb32f8c8 20641 check_nms(ctx);
7ef009b2
YK
20642 if (rt != 0) {
20643 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20644 addr_off);
20645
20646 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20647 }
20648 break;
20649 case NM_LWPC48:
fb32f8c8 20650 check_nms(ctx);
7ef009b2
YK
20651 if (rt != 0) {
20652 TCGv t0;
20653 t0 = tcg_temp_new();
20654
20655 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20656 addr_off);
20657
20658 tcg_gen_movi_tl(t0, addr);
20659 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20660 tcg_temp_free(t0);
20661 }
20662 break;
20663 case NM_SWPC48:
fb32f8c8 20664 check_nms(ctx);
7ef009b2
YK
20665 {
20666 TCGv t0, t1;
20667 t0 = tcg_temp_new();
20668 t1 = tcg_temp_new();
20669
20670 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20671 addr_off);
20672
20673 tcg_gen_movi_tl(t0, addr);
20674 gen_load_gpr(t1, rt);
20675
20676 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20677
20678 tcg_temp_free(t0);
20679 tcg_temp_free(t1);
20680 }
20681 break;
20682 default:
20683 generate_exception_end(ctx, EXCP_RI);
20684 break;
20685 }
20686 return 6;
20687 }
c0280983
YK
20688 case NM_P_U12:
20689 switch (extract32(ctx->opcode, 12, 4)) {
20690 case NM_ORI:
20691 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20692 break;
20693 case NM_XORI:
20694 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20695 break;
20696 case NM_ANDI:
20697 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20698 break;
20699 case NM_P_SR:
20700 switch (extract32(ctx->opcode, 20, 1)) {
20701 case NM_PP_SR:
20702 switch (ctx->opcode & 3) {
20703 case NM_SAVE:
20704 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20705 extract32(ctx->opcode, 2, 1),
20706 extract32(ctx->opcode, 3, 9) << 3);
20707 break;
20708 case NM_RESTORE:
20709 case NM_RESTORE_JRC:
20710 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20711 extract32(ctx->opcode, 2, 1),
20712 extract32(ctx->opcode, 3, 9) << 3);
20713 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20714 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20715 }
20716 break;
20717 default:
20718 generate_exception_end(ctx, EXCP_RI);
20719 break;
20720 }
20721 break;
20722 case NM_P_SR_F:
20723 generate_exception_end(ctx, EXCP_RI);
20724 break;
20725 }
20726 break;
20727 case NM_SLTI:
20728 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20729 break;
20730 case NM_SLTIU:
20731 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20732 break;
20733 case NM_SEQI:
20734 {
20735 TCGv t0 = tcg_temp_new();
20736
20737 imm = extract32(ctx->opcode, 0, 12);
20738 gen_load_gpr(t0, rs);
20739 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20740 gen_store_gpr(t0, rt);
20741
20742 tcg_temp_free(t0);
20743 }
20744 break;
20745 case NM_ADDIUNEG:
20746 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20747 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20748 break;
20749 case NM_P_SHIFT:
20750 {
20751 int shift = extract32(ctx->opcode, 0, 5);
20752 switch (extract32(ctx->opcode, 5, 4)) {
20753 case NM_P_SLL:
20754 if (rt == 0 && shift == 0) {
20755 /* NOP */
20756 } else if (rt == 0 && shift == 3) {
20757 /* EHB - treat as NOP */
20758 } else if (rt == 0 && shift == 5) {
20759 /* PAUSE - treat as NOP */
20760 } else if (rt == 0 && shift == 6) {
20761 /* SYNC */
20762 gen_sync(extract32(ctx->opcode, 16, 5));
20763 } else {
20764 /* SLL */
20765 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20766 extract32(ctx->opcode, 0, 5));
20767 }
20768 break;
20769 case NM_SRL:
20770 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20771 extract32(ctx->opcode, 0, 5));
20772 break;
20773 case NM_SRA:
20774 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20775 extract32(ctx->opcode, 0, 5));
20776 break;
20777 case NM_ROTR:
20778 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20779 extract32(ctx->opcode, 0, 5));
20780 break;
20781 }
20782 }
20783 break;
20784 case NM_P_ROTX:
fb32f8c8 20785 check_nms(ctx);
e222f506
MF
20786 if (rt != 0) {
20787 TCGv t0 = tcg_temp_new();
20788 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20789 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20790 << 1);
20791 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20792
20793 gen_load_gpr(t0, rs);
20794 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20795 tcg_temp_free(t0);
20796
20797 tcg_temp_free_i32(shift);
20798 tcg_temp_free_i32(shiftx);
20799 tcg_temp_free_i32(stripe);
20800 }
c0280983
YK
20801 break;
20802 case NM_P_INS:
20803 switch (((ctx->opcode >> 10) & 2) |
20804 (extract32(ctx->opcode, 5, 1))) {
20805 case NM_INS:
fb32f8c8 20806 check_nms(ctx);
c0280983
YK
20807 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20808 extract32(ctx->opcode, 6, 5));
20809 break;
20810 default:
20811 generate_exception_end(ctx, EXCP_RI);
20812 break;
20813 }
20814 break;
20815 case NM_P_EXT:
20816 switch (((ctx->opcode >> 10) & 2) |
20817 (extract32(ctx->opcode, 5, 1))) {
20818 case NM_EXT:
fb32f8c8 20819 check_nms(ctx);
c0280983
YK
20820 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20821 extract32(ctx->opcode, 6, 5));
20822 break;
20823 default:
20824 generate_exception_end(ctx, EXCP_RI);
20825 break;
20826 }
20827 break;
20828 default:
20829 generate_exception_end(ctx, EXCP_RI);
20830 break;
20831 }
20832 break;
20833 case NM_POOL32F:
579b8ea9 20834 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
20835 break;
20836 case NM_POOL32S:
20837 break;
20838 case NM_P_LUI:
20839 switch (extract32(ctx->opcode, 1, 1)) {
20840 case NM_LUI:
20841 if (rt != 0) {
20842 tcg_gen_movi_tl(cpu_gpr[rt],
20843 sextract32(ctx->opcode, 0, 1) << 31 |
20844 extract32(ctx->opcode, 2, 10) << 21 |
20845 extract32(ctx->opcode, 12, 9) << 12);
20846 }
20847 break;
20848 case NM_ALUIPC:
20849 if (rt != 0) {
20850 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20851 extract32(ctx->opcode, 2, 10) << 21 |
20852 extract32(ctx->opcode, 12, 9) << 12;
20853 target_long addr;
20854 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20855 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20856 }
20857 break;
20858 }
20859 break;
20860 case NM_P_GP_BH:
8f1d9b6d
YK
20861 {
20862 uint32_t u = extract32(ctx->opcode, 0, 18);
20863
20864 switch (extract32(ctx->opcode, 18, 3)) {
20865 case NM_LBGP:
20866 gen_ld(ctx, OPC_LB, rt, 28, u);
20867 break;
20868 case NM_SBGP:
20869 gen_st(ctx, OPC_SB, rt, 28, u);
20870 break;
20871 case NM_LBUGP:
20872 gen_ld(ctx, OPC_LBU, rt, 28, u);
20873 break;
20874 case NM_ADDIUGP_B:
20875 if (rt != 0) {
20876 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20877 }
20878 break;
20879 case NM_P_GP_LH:
20880 u &= ~1;
20881 switch (ctx->opcode & 1) {
20882 case NM_LHGP:
20883 gen_ld(ctx, OPC_LH, rt, 28, u);
20884 break;
20885 case NM_LHUGP:
20886 gen_ld(ctx, OPC_LHU, rt, 28, u);
20887 break;
20888 }
20889 break;
20890 case NM_P_GP_SH:
20891 u &= ~1;
20892 switch (ctx->opcode & 1) {
20893 case NM_SHGP:
20894 gen_st(ctx, OPC_SH, rt, 28, u);
20895 break;
20896 default:
20897 generate_exception_end(ctx, EXCP_RI);
20898 break;
20899 }
20900 break;
20901 case NM_P_GP_CP1:
20902 u &= ~0x3;
20903 switch (ctx->opcode & 0x3) {
20904 case NM_LWC1GP:
20905 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20906 break;
20907 case NM_LDC1GP:
20908 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20909 break;
20910 case NM_SWC1GP:
20911 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20912 break;
20913 case NM_SDC1GP:
20914 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20915 break;
20916 }
20917 break;
20918 default:
20919 generate_exception_end(ctx, EXCP_RI);
20920 break;
20921 }
20922 }
c0280983
YK
20923 break;
20924 case NM_P_LS_U12:
8f1d9b6d
YK
20925 {
20926 uint32_t u = extract32(ctx->opcode, 0, 12);
20927
20928 switch (extract32(ctx->opcode, 12, 4)) {
20929 case NM_P_PREFU12:
20930 if (rt == 31) {
20931 /* SYNCI */
20932 /* Break the TB to be able to sync copied instructions
20933 immediately */
20934 ctx->base.is_jmp = DISAS_STOP;
20935 } else {
20936 /* PREF */
20937 /* Treat as NOP. */
20938 }
20939 break;
20940 case NM_LB:
20941 gen_ld(ctx, OPC_LB, rt, rs, u);
20942 break;
20943 case NM_LH:
20944 gen_ld(ctx, OPC_LH, rt, rs, u);
20945 break;
20946 case NM_LW:
20947 gen_ld(ctx, OPC_LW, rt, rs, u);
20948 break;
20949 case NM_LBU:
20950 gen_ld(ctx, OPC_LBU, rt, rs, u);
20951 break;
20952 case NM_LHU:
20953 gen_ld(ctx, OPC_LHU, rt, rs, u);
20954 break;
20955 case NM_SB:
20956 gen_st(ctx, OPC_SB, rt, rs, u);
20957 break;
20958 case NM_SH:
20959 gen_st(ctx, OPC_SH, rt, rs, u);
20960 break;
20961 case NM_SW:
20962 gen_st(ctx, OPC_SW, rt, rs, u);
20963 break;
20964 case NM_LWC1:
20965 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20966 break;
20967 case NM_LDC1:
20968 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20969 break;
20970 case NM_SWC1:
20971 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20972 break;
20973 case NM_SDC1:
20974 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20975 break;
20976 default:
20977 generate_exception_end(ctx, EXCP_RI);
20978 break;
20979 }
20980 }
c0280983
YK
20981 break;
20982 case NM_P_LS_S9:
8f1d9b6d
YK
20983 {
20984 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20985 extract32(ctx->opcode, 0, 8);
20986
20987 switch (extract32(ctx->opcode, 8, 3)) {
20988 case NM_P_LS_S0:
20989 switch (extract32(ctx->opcode, 11, 4)) {
20990 case NM_LBS9:
20991 gen_ld(ctx, OPC_LB, rt, rs, s);
20992 break;
20993 case NM_LHS9:
20994 gen_ld(ctx, OPC_LH, rt, rs, s);
20995 break;
20996 case NM_LWS9:
20997 gen_ld(ctx, OPC_LW, rt, rs, s);
20998 break;
20999 case NM_LBUS9:
21000 gen_ld(ctx, OPC_LBU, rt, rs, s);
21001 break;
21002 case NM_LHUS9:
21003 gen_ld(ctx, OPC_LHU, rt, rs, s);
21004 break;
21005 case NM_SBS9:
21006 gen_st(ctx, OPC_SB, rt, rs, s);
21007 break;
21008 case NM_SHS9:
21009 gen_st(ctx, OPC_SH, rt, rs, s);
21010 break;
21011 case NM_SWS9:
21012 gen_st(ctx, OPC_SW, rt, rs, s);
21013 break;
21014 case NM_LWC1S9:
21015 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21016 break;
21017 case NM_LDC1S9:
21018 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21019 break;
21020 case NM_SWC1S9:
21021 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21022 break;
21023 case NM_SDC1S9:
21024 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21025 break;
21026 case NM_P_PREFS9:
21027 if (rt == 31) {
21028 /* SYNCI */
21029 /* Break the TB to be able to sync copied instructions
21030 immediately */
21031 ctx->base.is_jmp = DISAS_STOP;
21032 } else {
21033 /* PREF */
21034 /* Treat as NOP. */
21035 }
21036 break;
21037 default:
21038 generate_exception_end(ctx, EXCP_RI);
21039 break;
21040 }
21041 break;
21042 case NM_P_LS_S1:
21043 switch (extract32(ctx->opcode, 11, 4)) {
21044 case NM_UALH:
21045 case NM_UASH:
fb32f8c8 21046 check_nms(ctx);
8f1d9b6d
YK
21047 {
21048 TCGv t0 = tcg_temp_new();
21049 TCGv t1 = tcg_temp_new();
21050
21051 gen_base_offset_addr(ctx, t0, rs, s);
21052
21053 switch (extract32(ctx->opcode, 11, 4)) {
21054 case NM_UALH:
21055 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21056 MO_UNALN);
21057 gen_store_gpr(t0, rt);
21058 break;
21059 case NM_UASH:
21060 gen_load_gpr(t1, rt);
21061 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21062 MO_UNALN);
21063 break;
21064 }
21065 tcg_temp_free(t0);
21066 tcg_temp_free(t1);
21067 }
21068 break;
21069 case NM_P_LL:
21070 switch (ctx->opcode & 0x03) {
21071 case NM_LL:
21072 gen_ld(ctx, OPC_LL, rt, rs, s);
21073 break;
21074 case NM_LLWP:
0b16dcd1
AR
21075 check_xnp(ctx);
21076 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21077 break;
21078 }
21079 break;
21080 case NM_P_SC:
21081 switch (ctx->opcode & 0x03) {
21082 case NM_SC:
21083 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21084 break;
21085 case NM_SCWP:
0b16dcd1
AR
21086 check_xnp(ctx);
21087 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21088 break;
21089 }
21090 break;
21091 case NM_CACHE:
21092 check_cp0_enabled(ctx);
21093 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21094 gen_cache_operation(ctx, rt, rs, s);
21095 }
21096 break;
21097 }
21098 break;
21099 case NM_P_LS_WM:
21100 case NM_P_LS_UAWM:
fb32f8c8 21101 check_nms(ctx);
8f1d9b6d
YK
21102 {
21103 int count = extract32(ctx->opcode, 12, 3);
21104 int counter = 0;
21105
21106 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21107 extract32(ctx->opcode, 0, 8);
21108 TCGv va = tcg_temp_new();
21109 TCGv t1 = tcg_temp_new();
21110 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21111 NM_P_LS_UAWM ? MO_UNALN : 0;
21112
21113 count = (count == 0) ? 8 : count;
21114 while (counter != count) {
21115 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21116 int this_offset = offset + (counter << 2);
21117
21118 gen_base_offset_addr(ctx, va, rs, this_offset);
21119
21120 switch (extract32(ctx->opcode, 11, 1)) {
21121 case NM_LWM:
21122 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21123 memop | MO_TESL);
21124 gen_store_gpr(t1, this_rt);
21125 if ((this_rt == rs) &&
21126 (counter != (count - 1))) {
21127 /* UNPREDICTABLE */
21128 }
21129 break;
21130 case NM_SWM:
21131 this_rt = (rt == 0) ? 0 : this_rt;
21132 gen_load_gpr(t1, this_rt);
21133 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21134 memop | MO_TEUL);
21135 break;
21136 }
21137 counter++;
21138 }
21139 tcg_temp_free(va);
21140 tcg_temp_free(t1);
21141 }
21142 break;
21143 default:
21144 generate_exception_end(ctx, EXCP_RI);
21145 break;
21146 }
21147 }
c0280983
YK
21148 break;
21149 case NM_MOVE_BALC:
fb32f8c8 21150 check_nms(ctx);
11d0fc10
SM
21151 {
21152 TCGv t0 = tcg_temp_new();
21153 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21154 extract32(ctx->opcode, 1, 20) << 1;
21155 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21156 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21157 extract32(ctx->opcode, 21, 3));
21158 gen_load_gpr(t0, rt);
21159 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21160 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21161 tcg_temp_free(t0);
21162 }
c0280983
YK
21163 break;
21164 case NM_P_BAL:
11d0fc10
SM
21165 {
21166 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21167 extract32(ctx->opcode, 1, 24) << 1;
21168
21169 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21170 /* BC */
21171 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21172 } else {
21173 /* BALC */
21174 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21175 }
21176 }
c0280983
YK
21177 break;
21178 case NM_P_J:
11d0fc10
SM
21179 switch (extract32(ctx->opcode, 12, 4)) {
21180 case NM_JALRC:
21181 case NM_JALRC_HB:
21182 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21183 break;
21184 case NM_P_BALRSC:
21185 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21186 break;
21187 default:
21188 generate_exception_end(ctx, EXCP_RI);
21189 break;
21190 }
c0280983
YK
21191 break;
21192 case NM_P_BR1:
11d0fc10
SM
21193 {
21194 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21195 extract32(ctx->opcode, 1, 13) << 1;
21196 switch (extract32(ctx->opcode, 14, 2)) {
21197 case NM_BEQC:
fb32f8c8 21198 check_nms(ctx);
11d0fc10
SM
21199 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21200 break;
21201 case NM_P_BR3A:
21202 s = sextract32(ctx->opcode, 0, 1) << 14 |
21203 extract32(ctx->opcode, 1, 13) << 1;
21204 check_cp1_enabled(ctx);
21205 switch (extract32(ctx->opcode, 16, 5)) {
21206 case NM_BC1EQZC:
21207 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21208 break;
21209 case NM_BC1NEZC:
21210 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21211 break;
6d033ca7 21212 case NM_BPOSGE32C:
908f6be1 21213 check_dsp_r3(ctx);
6d033ca7
SM
21214 {
21215 int32_t imm = extract32(ctx->opcode, 1, 13) |
21216 extract32(ctx->opcode, 0, 1) << 13;
21217
21218 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21219 imm);
21220 }
21221 break;
11d0fc10
SM
21222 default:
21223 generate_exception_end(ctx, EXCP_RI);
21224 break;
21225 }
21226 break;
21227 case NM_BGEC:
21228 if (rs == rt) {
21229 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21230 } else {
21231 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21232 }
21233 break;
21234 case NM_BGEUC:
21235 if (rs == rt || rt == 0) {
21236 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21237 } else if (rs == 0) {
21238 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21239 } else {
21240 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21241 }
21242 break;
21243 }
21244 }
c0280983
YK
21245 break;
21246 case NM_P_BR2:
11d0fc10
SM
21247 {
21248 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21249 extract32(ctx->opcode, 1, 13) << 1;
21250 switch (extract32(ctx->opcode, 14, 2)) {
21251 case NM_BNEC:
fb32f8c8 21252 check_nms(ctx);
11d0fc10
SM
21253 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21254 break;
21255 case NM_BLTC:
21256 if (rs != 0 && rt != 0 && rs == rt) {
21257 /* NOP */
21258 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21259 } else {
21260 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21261 }
21262 break;
21263 case NM_BLTUC:
21264 if (rs == 0 || rs == rt) {
21265 /* NOP */
21266 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21267 } else {
21268 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21269 }
21270 break;
21271 default:
21272 generate_exception_end(ctx, EXCP_RI);
21273 break;
21274 }
21275 }
c0280983
YK
21276 break;
21277 case NM_P_BRI:
11d0fc10
SM
21278 {
21279 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21280 extract32(ctx->opcode, 1, 10) << 1;
21281 uint32_t u = extract32(ctx->opcode, 11, 7);
21282
21283 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21284 rt, u, s);
21285 }
c0280983
YK
21286 break;
21287 default:
21288 generate_exception_end(ctx, EXCP_RI);
21289 break;
21290 }
21291 return 4;
21292}
21293
c533c0f4
AM
21294static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21295{
ea4ca3c2
YK
21296 uint32_t op;
21297 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21298 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21299 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
8bdb7029 21300 int offset;
ea4ca3c2
YK
21301 int imm;
21302
21303 /* make sure instructions are on a halfword boundary */
21304 if (ctx->base.pc_next & 0x1) {
21305 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21306 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21307 tcg_temp_free(tmp);
21308 generate_exception_end(ctx, EXCP_AdEL);
21309 return 2;
21310 }
21311
21312 op = extract32(ctx->opcode, 10, 6);
21313 switch (op) {
21314 case NM_P16_MV:
8869ad02
YK
21315 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21316 if (rt != 0) {
21317 /* MOVE */
21318 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21319 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21320 } else {
21321 /* P16.RI */
21322 switch (extract32(ctx->opcode, 3, 2)) {
21323 case NM_P16_SYSCALL:
21324 if (extract32(ctx->opcode, 2, 1) == 0) {
21325 generate_exception_end(ctx, EXCP_SYSCALL);
21326 } else {
21327 generate_exception_end(ctx, EXCP_RI);
21328 }
21329 break;
21330 case NM_BREAK16:
21331 generate_exception_end(ctx, EXCP_BREAK);
21332 break;
21333 case NM_SDBBP16:
21334 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21335 gen_helper_do_semihosting(cpu_env);
21336 } else {
21337 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21338 generate_exception_end(ctx, EXCP_RI);
21339 } else {
21340 generate_exception_end(ctx, EXCP_DBp);
21341 }
21342 }
21343 break;
21344 default:
21345 generate_exception_end(ctx, EXCP_RI);
21346 break;
21347 }
21348 }
ea4ca3c2
YK
21349 break;
21350 case NM_P16_SHIFT:
c46562fb
YK
21351 {
21352 int shift = extract32(ctx->opcode, 0, 3);
21353 uint32_t opc = 0;
21354 shift = (shift == 0) ? 8 : shift;
21355
21356 switch (extract32(ctx->opcode, 3, 1)) {
21357 case NM_SLL16:
21358 opc = OPC_SLL;
21359 break;
21360 case NM_SRL16:
21361 opc = OPC_SRL;
21362 break;
21363 }
21364 gen_shift_imm(ctx, opc, rt, rs, shift);
21365 }
ea4ca3c2
YK
21366 break;
21367 case NM_P16C:
8bdb7029
YK
21368 switch (ctx->opcode & 1) {
21369 case NM_POOL16C_0:
80845edf 21370 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
21371 break;
21372 case NM_LWXS16:
21373 gen_ldxs(ctx, rt, rs, rd);
21374 break;
21375 }
ea4ca3c2
YK
21376 break;
21377 case NM_P16_A1:
21378 switch (extract32(ctx->opcode, 6, 1)) {
21379 case NM_ADDIUR1SP:
21380 imm = extract32(ctx->opcode, 0, 6) << 2;
21381 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21382 break;
21383 default:
21384 generate_exception_end(ctx, EXCP_RI);
21385 break;
21386 }
21387 break;
21388 case NM_P16_A2:
21389 switch (extract32(ctx->opcode, 3, 1)) {
21390 case NM_ADDIUR2:
21391 imm = extract32(ctx->opcode, 0, 3) << 2;
21392 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21393 break;
21394 case NM_P_ADDIURS5:
21395 rt = extract32(ctx->opcode, 5, 5);
21396 if (rt != 0) {
21397 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21398 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21399 (extract32(ctx->opcode, 0, 3));
21400 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21401 }
21402 break;
21403 }
21404 break;
21405 case NM_P16_ADDU:
21406 switch (ctx->opcode & 0x1) {
21407 case NM_ADDU16:
21408 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21409 break;
21410 case NM_SUBU16:
21411 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21412 break;
21413 }
21414 break;
21415 case NM_P16_4X4:
21416 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21417 extract32(ctx->opcode, 5, 3);
21418 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21419 extract32(ctx->opcode, 0, 3);
21420 rt = decode_gpr_gpr4(rt);
21421 rs = decode_gpr_gpr4(rs);
21422 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21423 (extract32(ctx->opcode, 3, 1))) {
21424 case NM_ADDU4X4:
fb32f8c8 21425 check_nms(ctx);
ea4ca3c2
YK
21426 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21427 break;
21428 case NM_MUL4X4:
fb32f8c8 21429 check_nms(ctx);
ea4ca3c2
YK
21430 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21431 break;
21432 default:
21433 generate_exception_end(ctx, EXCP_RI);
21434 break;
21435 }
21436 break;
21437 case NM_LI16:
8869ad02
YK
21438 {
21439 int imm = extract32(ctx->opcode, 0, 7);
21440 imm = (imm == 0x7f ? -1 : imm);
21441 if (rt != 0) {
21442 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21443 }
21444 }
ea4ca3c2
YK
21445 break;
21446 case NM_ANDI16:
80845edf
YK
21447 {
21448 uint32_t u = extract32(ctx->opcode, 0, 4);
21449 u = (u == 12) ? 0xff :
21450 (u == 13) ? 0xffff : u;
21451 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21452 }
ea4ca3c2
YK
21453 break;
21454 case NM_P16_LB:
8bdb7029
YK
21455 offset = extract32(ctx->opcode, 0, 2);
21456 switch (extract32(ctx->opcode, 2, 2)) {
21457 case NM_LB16:
21458 gen_ld(ctx, OPC_LB, rt, rs, offset);
21459 break;
21460 case NM_SB16:
21461 rt = decode_gpr_gpr3_src_store(
21462 NANOMIPS_EXTRACT_RD(ctx->opcode));
21463 gen_st(ctx, OPC_SB, rt, rs, offset);
21464 break;
21465 case NM_LBU16:
21466 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21467 break;
21468 default:
21469 generate_exception_end(ctx, EXCP_RI);
21470 break;
21471 }
ea4ca3c2
YK
21472 break;
21473 case NM_P16_LH:
8bdb7029
YK
21474 offset = extract32(ctx->opcode, 1, 2) << 1;
21475 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21476 case NM_LH16:
21477 gen_ld(ctx, OPC_LH, rt, rs, offset);
21478 break;
21479 case NM_SH16:
21480 rt = decode_gpr_gpr3_src_store(
21481 NANOMIPS_EXTRACT_RD(ctx->opcode));
21482 gen_st(ctx, OPC_SH, rt, rs, offset);
21483 break;
21484 case NM_LHU16:
21485 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21486 break;
21487 default:
21488 generate_exception_end(ctx, EXCP_RI);
21489 break;
21490 }
ea4ca3c2
YK
21491 break;
21492 case NM_LW16:
8bdb7029
YK
21493 offset = extract32(ctx->opcode, 0, 4) << 2;
21494 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21495 break;
21496 case NM_LWSP16:
8bdb7029
YK
21497 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21498 offset = extract32(ctx->opcode, 0, 5) << 2;
21499 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
21500 break;
21501 case NM_LW4X4:
fb32f8c8 21502 check_nms(ctx);
8bdb7029
YK
21503 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21504 extract32(ctx->opcode, 5, 3);
21505 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21506 extract32(ctx->opcode, 0, 3);
21507 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21508 (extract32(ctx->opcode, 8, 1) << 2);
21509 rt = decode_gpr_gpr4(rt);
21510 rs = decode_gpr_gpr4(rs);
21511 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21512 break;
21513 case NM_SW4X4:
fb32f8c8 21514 check_nms(ctx);
8bdb7029
YK
21515 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21516 extract32(ctx->opcode, 5, 3);
21517 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21518 extract32(ctx->opcode, 0, 3);
21519 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21520 (extract32(ctx->opcode, 8, 1) << 2);
21521 rt = decode_gpr_gpr4_zero(rt);
21522 rs = decode_gpr_gpr4(rs);
21523 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21524 break;
21525 case NM_LWGP16:
8bdb7029
YK
21526 offset = extract32(ctx->opcode, 0, 7) << 2;
21527 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
21528 break;
21529 case NM_SWSP16:
8bdb7029
YK
21530 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21531 offset = extract32(ctx->opcode, 0, 5) << 2;
21532 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
21533 break;
21534 case NM_SW16:
8bdb7029
YK
21535 rt = decode_gpr_gpr3_src_store(
21536 NANOMIPS_EXTRACT_RD(ctx->opcode));
21537 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21538 offset = extract32(ctx->opcode, 0, 4) << 2;
21539 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21540 break;
21541 case NM_SWGP16:
8bdb7029
YK
21542 rt = decode_gpr_gpr3_src_store(
21543 NANOMIPS_EXTRACT_RD(ctx->opcode));
21544 offset = extract32(ctx->opcode, 0, 7) << 2;
21545 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
21546 break;
21547 case NM_BC16:
764371d2
SM
21548 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21549 (sextract32(ctx->opcode, 0, 1) << 10) |
21550 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21551 break;
21552 case NM_BALC16:
764371d2
SM
21553 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21554 (sextract32(ctx->opcode, 0, 1) << 10) |
21555 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21556 break;
21557 case NM_BEQZC16:
764371d2
SM
21558 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21559 (sextract32(ctx->opcode, 0, 1) << 7) |
21560 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21561 break;
21562 case NM_BNEZC16:
764371d2
SM
21563 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21564 (sextract32(ctx->opcode, 0, 1) << 7) |
21565 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21566 break;
21567 case NM_P16_BR:
764371d2
SM
21568 switch (ctx->opcode & 0xf) {
21569 case 0:
21570 /* P16.JRC */
21571 switch (extract32(ctx->opcode, 4, 1)) {
21572 case NM_JRC:
21573 gen_compute_branch_nm(ctx, OPC_JR, 2,
21574 extract32(ctx->opcode, 5, 5), 0, 0);
21575 break;
21576 case NM_JALRC16:
21577 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21578 extract32(ctx->opcode, 5, 5), 31, 0);
21579 break;
21580 }
21581 break;
21582 default:
21583 {
21584 /* P16.BRI */
21585 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21586 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21587 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21588 extract32(ctx->opcode, 0, 4) << 1);
21589 }
21590 break;
21591 }
ea4ca3c2
YK
21592 break;
21593 case NM_P16_SR:
bf0718c5
SM
21594 {
21595 int count = extract32(ctx->opcode, 0, 4);
21596 int u = extract32(ctx->opcode, 4, 4) << 4;
21597
21598 rt = 30 + extract32(ctx->opcode, 9, 1);
21599 switch (extract32(ctx->opcode, 8, 1)) {
21600 case NM_SAVE16:
21601 gen_save(ctx, rt, count, 0, u);
21602 break;
21603 case NM_RESTORE_JRC16:
21604 gen_restore(ctx, rt, count, 0, u);
21605 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21606 break;
21607 }
21608 }
ea4ca3c2
YK
21609 break;
21610 case NM_MOVEP:
ea4ca3c2 21611 case NM_MOVEPREV:
fb32f8c8 21612 check_nms(ctx);
4d18232c
YK
21613 {
21614 static const int gpr2reg1[] = {4, 5, 6, 7};
21615 static const int gpr2reg2[] = {5, 6, 7, 8};
21616 int re;
21617 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21618 extract32(ctx->opcode, 8, 1);
21619 int r1 = gpr2reg1[rd2];
21620 int r2 = gpr2reg2[rd2];
21621 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21622 extract32(ctx->opcode, 0, 3);
21623 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21624 extract32(ctx->opcode, 5, 3);
21625 TCGv t0 = tcg_temp_new();
21626 TCGv t1 = tcg_temp_new();
21627 if (op == NM_MOVEP) {
21628 rd = r1;
21629 re = r2;
21630 rs = decode_gpr_gpr4_zero(r3);
21631 rt = decode_gpr_gpr4_zero(r4);
21632 } else {
21633 rd = decode_gpr_gpr4(r3);
21634 re = decode_gpr_gpr4(r4);
21635 rs = r1;
21636 rt = r2;
21637 }
21638 gen_load_gpr(t0, rs);
21639 gen_load_gpr(t1, rt);
21640 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21641 tcg_gen_mov_tl(cpu_gpr[re], t1);
21642 tcg_temp_free(t0);
21643 tcg_temp_free(t1);
21644 }
ea4ca3c2
YK
21645 break;
21646 default:
c0280983 21647 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
21648 }
21649
c533c0f4
AM
21650 return 2;
21651}
21652
21653
3c824109
NF
21654/* SmartMIPS extension to MIPS32 */
21655
21656#if defined(TARGET_MIPS64)
21657
21658/* MDMX extension to MIPS64 */
21659
21660#endif
21661
9b1a1d68 21662/* MIPSDSP functions. */
d75c135e 21663static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
21664 int rd, int base, int offset)
21665{
9b1a1d68
JL
21666 TCGv t0;
21667
9b1a1d68
JL
21668 check_dsp(ctx);
21669 t0 = tcg_temp_new();
21670
21671 if (base == 0) {
21672 gen_load_gpr(t0, offset);
21673 } else if (offset == 0) {
21674 gen_load_gpr(t0, base);
21675 } else {
21676 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21677 }
21678
9b1a1d68
JL
21679 switch (opc) {
21680 case OPC_LBUX:
5f68f5ae 21681 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 21682 gen_store_gpr(t0, rd);
9b1a1d68
JL
21683 break;
21684 case OPC_LHX:
5f68f5ae 21685 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 21686 gen_store_gpr(t0, rd);
9b1a1d68
JL
21687 break;
21688 case OPC_LWX:
5f68f5ae 21689 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 21690 gen_store_gpr(t0, rd);
9b1a1d68
JL
21691 break;
21692#if defined(TARGET_MIPS64)
21693 case OPC_LDX:
5f68f5ae 21694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 21695 gen_store_gpr(t0, rd);
9b1a1d68
JL
21696 break;
21697#endif
21698 }
9b1a1d68
JL
21699 tcg_temp_free(t0);
21700}
21701
461c08df
JL
21702static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21703 int ret, int v1, int v2)
21704{
461c08df
JL
21705 TCGv v1_t;
21706 TCGv v2_t;
21707
21708 if (ret == 0) {
21709 /* Treat as NOP. */
461c08df
JL
21710 return;
21711 }
21712
21713 v1_t = tcg_temp_new();
21714 v2_t = tcg_temp_new();
21715
21716 gen_load_gpr(v1_t, v1);
21717 gen_load_gpr(v2_t, v2);
21718
21719 switch (op1) {
21720 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21721 case OPC_MULT_G_2E:
908f6be1 21722 check_dsp_r2(ctx);
461c08df
JL
21723 switch (op2) {
21724 case OPC_ADDUH_QB:
21725 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21726 break;
21727 case OPC_ADDUH_R_QB:
21728 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21729 break;
21730 case OPC_ADDQH_PH:
21731 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21732 break;
21733 case OPC_ADDQH_R_PH:
21734 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21735 break;
21736 case OPC_ADDQH_W:
21737 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21738 break;
21739 case OPC_ADDQH_R_W:
21740 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21741 break;
21742 case OPC_SUBUH_QB:
21743 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21744 break;
21745 case OPC_SUBUH_R_QB:
21746 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21747 break;
21748 case OPC_SUBQH_PH:
21749 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21750 break;
21751 case OPC_SUBQH_R_PH:
21752 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21753 break;
21754 case OPC_SUBQH_W:
21755 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21756 break;
21757 case OPC_SUBQH_R_W:
21758 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21759 break;
21760 }
21761 break;
21762 case OPC_ABSQ_S_PH_DSP:
21763 switch (op2) {
21764 case OPC_ABSQ_S_QB:
908f6be1 21765 check_dsp_r2(ctx);
461c08df
JL
21766 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21767 break;
21768 case OPC_ABSQ_S_PH:
21769 check_dsp(ctx);
21770 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21771 break;
21772 case OPC_ABSQ_S_W:
21773 check_dsp(ctx);
21774 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21775 break;
21776 case OPC_PRECEQ_W_PHL:
21777 check_dsp(ctx);
21778 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21779 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21780 break;
21781 case OPC_PRECEQ_W_PHR:
21782 check_dsp(ctx);
21783 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21784 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21786 break;
21787 case OPC_PRECEQU_PH_QBL:
21788 check_dsp(ctx);
21789 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21790 break;
21791 case OPC_PRECEQU_PH_QBR:
21792 check_dsp(ctx);
21793 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21794 break;
21795 case OPC_PRECEQU_PH_QBLA:
21796 check_dsp(ctx);
21797 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21798 break;
21799 case OPC_PRECEQU_PH_QBRA:
21800 check_dsp(ctx);
21801 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21802 break;
21803 case OPC_PRECEU_PH_QBL:
21804 check_dsp(ctx);
21805 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21806 break;
21807 case OPC_PRECEU_PH_QBR:
21808 check_dsp(ctx);
21809 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21810 break;
21811 case OPC_PRECEU_PH_QBLA:
21812 check_dsp(ctx);
21813 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21814 break;
21815 case OPC_PRECEU_PH_QBRA:
21816 check_dsp(ctx);
21817 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21818 break;
21819 }
21820 break;
21821 case OPC_ADDU_QB_DSP:
21822 switch (op2) {
21823 case OPC_ADDQ_PH:
21824 check_dsp(ctx);
21825 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21826 break;
21827 case OPC_ADDQ_S_PH:
21828 check_dsp(ctx);
21829 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21830 break;
21831 case OPC_ADDQ_S_W:
21832 check_dsp(ctx);
21833 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21834 break;
21835 case OPC_ADDU_QB:
21836 check_dsp(ctx);
21837 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21838 break;
21839 case OPC_ADDU_S_QB:
21840 check_dsp(ctx);
21841 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21842 break;
21843 case OPC_ADDU_PH:
908f6be1 21844 check_dsp_r2(ctx);
461c08df
JL
21845 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21846 break;
21847 case OPC_ADDU_S_PH:
908f6be1 21848 check_dsp_r2(ctx);
461c08df
JL
21849 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21850 break;
21851 case OPC_SUBQ_PH:
21852 check_dsp(ctx);
21853 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21854 break;
21855 case OPC_SUBQ_S_PH:
21856 check_dsp(ctx);
21857 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21858 break;
21859 case OPC_SUBQ_S_W:
21860 check_dsp(ctx);
21861 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21862 break;
21863 case OPC_SUBU_QB:
21864 check_dsp(ctx);
21865 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21866 break;
21867 case OPC_SUBU_S_QB:
21868 check_dsp(ctx);
21869 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21870 break;
21871 case OPC_SUBU_PH:
908f6be1 21872 check_dsp_r2(ctx);
461c08df
JL
21873 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21874 break;
21875 case OPC_SUBU_S_PH:
908f6be1 21876 check_dsp_r2(ctx);
461c08df
JL
21877 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21878 break;
21879 case OPC_ADDSC:
21880 check_dsp(ctx);
21881 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21882 break;
21883 case OPC_ADDWC:
21884 check_dsp(ctx);
21885 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21886 break;
21887 case OPC_MODSUB:
21888 check_dsp(ctx);
21889 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21890 break;
21891 case OPC_RADDU_W_QB:
21892 check_dsp(ctx);
21893 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21894 break;
21895 }
21896 break;
21897 case OPC_CMPU_EQ_QB_DSP:
21898 switch (op2) {
21899 case OPC_PRECR_QB_PH:
908f6be1 21900 check_dsp_r2(ctx);
461c08df
JL
21901 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21902 break;
21903 case OPC_PRECRQ_QB_PH:
21904 check_dsp(ctx);
21905 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21906 break;
21907 case OPC_PRECR_SRA_PH_W:
908f6be1 21908 check_dsp_r2(ctx);
461c08df
JL
21909 {
21910 TCGv_i32 sa_t = tcg_const_i32(v2);
21911 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21912 cpu_gpr[ret]);
21913 tcg_temp_free_i32(sa_t);
21914 break;
21915 }
21916 case OPC_PRECR_SRA_R_PH_W:
908f6be1 21917 check_dsp_r2(ctx);
461c08df
JL
21918 {
21919 TCGv_i32 sa_t = tcg_const_i32(v2);
21920 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21921 cpu_gpr[ret]);
21922 tcg_temp_free_i32(sa_t);
21923 break;
21924 }
21925 case OPC_PRECRQ_PH_W:
21926 check_dsp(ctx);
21927 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21928 break;
21929 case OPC_PRECRQ_RS_PH_W:
21930 check_dsp(ctx);
21931 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21932 break;
21933 case OPC_PRECRQU_S_QB_PH:
21934 check_dsp(ctx);
21935 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21936 break;
21937 }
21938 break;
21939#ifdef TARGET_MIPS64
21940 case OPC_ABSQ_S_QH_DSP:
21941 switch (op2) {
21942 case OPC_PRECEQ_L_PWL:
21943 check_dsp(ctx);
21944 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21945 break;
21946 case OPC_PRECEQ_L_PWR:
21947 check_dsp(ctx);
21948 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21949 break;
21950 case OPC_PRECEQ_PW_QHL:
21951 check_dsp(ctx);
21952 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21953 break;
21954 case OPC_PRECEQ_PW_QHR:
21955 check_dsp(ctx);
21956 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21957 break;
21958 case OPC_PRECEQ_PW_QHLA:
21959 check_dsp(ctx);
21960 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21961 break;
21962 case OPC_PRECEQ_PW_QHRA:
21963 check_dsp(ctx);
21964 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21965 break;
21966 case OPC_PRECEQU_QH_OBL:
21967 check_dsp(ctx);
21968 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21969 break;
21970 case OPC_PRECEQU_QH_OBR:
21971 check_dsp(ctx);
21972 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21973 break;
21974 case OPC_PRECEQU_QH_OBLA:
21975 check_dsp(ctx);
21976 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21977 break;
21978 case OPC_PRECEQU_QH_OBRA:
21979 check_dsp(ctx);
21980 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21981 break;
21982 case OPC_PRECEU_QH_OBL:
21983 check_dsp(ctx);
21984 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21985 break;
21986 case OPC_PRECEU_QH_OBR:
21987 check_dsp(ctx);
21988 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21989 break;
21990 case OPC_PRECEU_QH_OBLA:
21991 check_dsp(ctx);
21992 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21993 break;
21994 case OPC_PRECEU_QH_OBRA:
21995 check_dsp(ctx);
21996 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21997 break;
21998 case OPC_ABSQ_S_OB:
908f6be1 21999 check_dsp_r2(ctx);
461c08df
JL
22000 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22001 break;
22002 case OPC_ABSQ_S_PW:
22003 check_dsp(ctx);
22004 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22005 break;
22006 case OPC_ABSQ_S_QH:
22007 check_dsp(ctx);
22008 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22009 break;
22010 }
22011 break;
22012 case OPC_ADDU_OB_DSP:
22013 switch (op2) {
22014 case OPC_RADDU_L_OB:
22015 check_dsp(ctx);
22016 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22017 break;
22018 case OPC_SUBQ_PW:
22019 check_dsp(ctx);
22020 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22021 break;
22022 case OPC_SUBQ_S_PW:
22023 check_dsp(ctx);
22024 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22025 break;
22026 case OPC_SUBQ_QH:
22027 check_dsp(ctx);
22028 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22029 break;
22030 case OPC_SUBQ_S_QH:
22031 check_dsp(ctx);
22032 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22033 break;
22034 case OPC_SUBU_OB:
22035 check_dsp(ctx);
22036 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22037 break;
22038 case OPC_SUBU_S_OB:
22039 check_dsp(ctx);
22040 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22041 break;
22042 case OPC_SUBU_QH:
908f6be1 22043 check_dsp_r2(ctx);
461c08df
JL
22044 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22045 break;
22046 case OPC_SUBU_S_QH:
908f6be1 22047 check_dsp_r2(ctx);
461c08df
JL
22048 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22049 break;
22050 case OPC_SUBUH_OB:
908f6be1 22051 check_dsp_r2(ctx);
461c08df
JL
22052 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22053 break;
22054 case OPC_SUBUH_R_OB:
908f6be1 22055 check_dsp_r2(ctx);
461c08df
JL
22056 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22057 break;
22058 case OPC_ADDQ_PW:
22059 check_dsp(ctx);
22060 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22061 break;
22062 case OPC_ADDQ_S_PW:
22063 check_dsp(ctx);
22064 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22065 break;
22066 case OPC_ADDQ_QH:
22067 check_dsp(ctx);
22068 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22069 break;
22070 case OPC_ADDQ_S_QH:
22071 check_dsp(ctx);
22072 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22073 break;
22074 case OPC_ADDU_OB:
22075 check_dsp(ctx);
22076 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22077 break;
22078 case OPC_ADDU_S_OB:
22079 check_dsp(ctx);
22080 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22081 break;
22082 case OPC_ADDU_QH:
908f6be1 22083 check_dsp_r2(ctx);
461c08df
JL
22084 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22085 break;
22086 case OPC_ADDU_S_QH:
908f6be1 22087 check_dsp_r2(ctx);
461c08df
JL
22088 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22089 break;
22090 case OPC_ADDUH_OB:
908f6be1 22091 check_dsp_r2(ctx);
461c08df
JL
22092 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22093 break;
22094 case OPC_ADDUH_R_OB:
908f6be1 22095 check_dsp_r2(ctx);
461c08df
JL
22096 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22097 break;
22098 }
22099 break;
22100 case OPC_CMPU_EQ_OB_DSP:
22101 switch (op2) {
22102 case OPC_PRECR_OB_QH:
908f6be1 22103 check_dsp_r2(ctx);
461c08df
JL
22104 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22105 break;
22106 case OPC_PRECR_SRA_QH_PW:
908f6be1 22107 check_dsp_r2(ctx);
461c08df
JL
22108 {
22109 TCGv_i32 ret_t = tcg_const_i32(ret);
22110 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22111 tcg_temp_free_i32(ret_t);
22112 break;
22113 }
22114 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 22115 check_dsp_r2(ctx);
461c08df
JL
22116 {
22117 TCGv_i32 sa_v = tcg_const_i32(ret);
22118 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22119 tcg_temp_free_i32(sa_v);
22120 break;
22121 }
22122 case OPC_PRECRQ_OB_QH:
22123 check_dsp(ctx);
22124 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22125 break;
22126 case OPC_PRECRQ_PW_L:
22127 check_dsp(ctx);
22128 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22129 break;
22130 case OPC_PRECRQ_QH_PW:
22131 check_dsp(ctx);
22132 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22133 break;
22134 case OPC_PRECRQ_RS_QH_PW:
22135 check_dsp(ctx);
22136 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22137 break;
22138 case OPC_PRECRQU_S_OB_QH:
22139 check_dsp(ctx);
22140 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22141 break;
22142 }
22143 break;
22144#endif
22145 }
22146
22147 tcg_temp_free(v1_t);
22148 tcg_temp_free(v2_t);
461c08df 22149}
9b1a1d68 22150
77c5fa8b
JL
22151static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22152 int ret, int v1, int v2)
22153{
22154 uint32_t op2;
77c5fa8b
JL
22155 TCGv t0;
22156 TCGv v1_t;
22157 TCGv v2_t;
22158
22159 if (ret == 0) {
22160 /* Treat as NOP. */
77c5fa8b
JL
22161 return;
22162 }
22163
22164 t0 = tcg_temp_new();
22165 v1_t = tcg_temp_new();
22166 v2_t = tcg_temp_new();
22167
22168 tcg_gen_movi_tl(t0, v1);
22169 gen_load_gpr(v1_t, v1);
22170 gen_load_gpr(v2_t, v2);
22171
22172 switch (opc) {
22173 case OPC_SHLL_QB_DSP:
22174 {
22175 op2 = MASK_SHLL_QB(ctx->opcode);
22176 switch (op2) {
22177 case OPC_SHLL_QB:
22178 check_dsp(ctx);
22179 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22180 break;
22181 case OPC_SHLLV_QB:
22182 check_dsp(ctx);
22183 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22184 break;
22185 case OPC_SHLL_PH:
22186 check_dsp(ctx);
22187 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22188 break;
22189 case OPC_SHLLV_PH:
22190 check_dsp(ctx);
22191 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22192 break;
22193 case OPC_SHLL_S_PH:
22194 check_dsp(ctx);
22195 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22196 break;
22197 case OPC_SHLLV_S_PH:
22198 check_dsp(ctx);
22199 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22200 break;
22201 case OPC_SHLL_S_W:
22202 check_dsp(ctx);
22203 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22204 break;
22205 case OPC_SHLLV_S_W:
22206 check_dsp(ctx);
22207 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22208 break;
22209 case OPC_SHRL_QB:
22210 check_dsp(ctx);
22211 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22212 break;
22213 case OPC_SHRLV_QB:
22214 check_dsp(ctx);
22215 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22216 break;
22217 case OPC_SHRL_PH:
908f6be1 22218 check_dsp_r2(ctx);
77c5fa8b
JL
22219 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22220 break;
22221 case OPC_SHRLV_PH:
908f6be1 22222 check_dsp_r2(ctx);
77c5fa8b
JL
22223 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22224 break;
22225 case OPC_SHRA_QB:
908f6be1 22226 check_dsp_r2(ctx);
77c5fa8b
JL
22227 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22228 break;
22229 case OPC_SHRA_R_QB:
908f6be1 22230 check_dsp_r2(ctx);
77c5fa8b
JL
22231 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22232 break;
22233 case OPC_SHRAV_QB:
908f6be1 22234 check_dsp_r2(ctx);
77c5fa8b
JL
22235 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22236 break;
22237 case OPC_SHRAV_R_QB:
908f6be1 22238 check_dsp_r2(ctx);
77c5fa8b
JL
22239 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22240 break;
22241 case OPC_SHRA_PH:
22242 check_dsp(ctx);
22243 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22244 break;
22245 case OPC_SHRA_R_PH:
22246 check_dsp(ctx);
22247 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22248 break;
22249 case OPC_SHRAV_PH:
22250 check_dsp(ctx);
22251 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22252 break;
22253 case OPC_SHRAV_R_PH:
22254 check_dsp(ctx);
22255 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22256 break;
22257 case OPC_SHRA_R_W:
22258 check_dsp(ctx);
22259 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22260 break;
22261 case OPC_SHRAV_R_W:
22262 check_dsp(ctx);
22263 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22264 break;
22265 default: /* Invalid */
22266 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 22267 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22268 break;
22269 }
22270 break;
22271 }
22272#ifdef TARGET_MIPS64
22273 case OPC_SHLL_OB_DSP:
22274 op2 = MASK_SHLL_OB(ctx->opcode);
22275 switch (op2) {
22276 case OPC_SHLL_PW:
22277 check_dsp(ctx);
22278 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22279 break;
22280 case OPC_SHLLV_PW:
22281 check_dsp(ctx);
22282 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22283 break;
22284 case OPC_SHLL_S_PW:
22285 check_dsp(ctx);
22286 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22287 break;
22288 case OPC_SHLLV_S_PW:
22289 check_dsp(ctx);
22290 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22291 break;
22292 case OPC_SHLL_OB:
22293 check_dsp(ctx);
22294 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22295 break;
22296 case OPC_SHLLV_OB:
22297 check_dsp(ctx);
22298 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22299 break;
22300 case OPC_SHLL_QH:
22301 check_dsp(ctx);
22302 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22303 break;
22304 case OPC_SHLLV_QH:
22305 check_dsp(ctx);
22306 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22307 break;
22308 case OPC_SHLL_S_QH:
22309 check_dsp(ctx);
22310 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22311 break;
22312 case OPC_SHLLV_S_QH:
22313 check_dsp(ctx);
22314 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22315 break;
22316 case OPC_SHRA_OB:
908f6be1 22317 check_dsp_r2(ctx);
77c5fa8b
JL
22318 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22319 break;
22320 case OPC_SHRAV_OB:
908f6be1 22321 check_dsp_r2(ctx);
77c5fa8b
JL
22322 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22323 break;
22324 case OPC_SHRA_R_OB:
908f6be1 22325 check_dsp_r2(ctx);
77c5fa8b
JL
22326 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22327 break;
22328 case OPC_SHRAV_R_OB:
908f6be1 22329 check_dsp_r2(ctx);
77c5fa8b
JL
22330 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22331 break;
22332 case OPC_SHRA_PW:
22333 check_dsp(ctx);
22334 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22335 break;
22336 case OPC_SHRAV_PW:
22337 check_dsp(ctx);
22338 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22339 break;
22340 case OPC_SHRA_R_PW:
22341 check_dsp(ctx);
22342 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22343 break;
22344 case OPC_SHRAV_R_PW:
22345 check_dsp(ctx);
22346 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22347 break;
22348 case OPC_SHRA_QH:
22349 check_dsp(ctx);
22350 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22351 break;
22352 case OPC_SHRAV_QH:
22353 check_dsp(ctx);
22354 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22355 break;
22356 case OPC_SHRA_R_QH:
22357 check_dsp(ctx);
22358 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22359 break;
22360 case OPC_SHRAV_R_QH:
22361 check_dsp(ctx);
22362 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22363 break;
22364 case OPC_SHRL_OB:
22365 check_dsp(ctx);
22366 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22367 break;
22368 case OPC_SHRLV_OB:
22369 check_dsp(ctx);
22370 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22371 break;
22372 case OPC_SHRL_QH:
908f6be1 22373 check_dsp_r2(ctx);
77c5fa8b
JL
22374 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22375 break;
22376 case OPC_SHRLV_QH:
908f6be1 22377 check_dsp_r2(ctx);
77c5fa8b
JL
22378 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22379 break;
22380 default: /* Invalid */
22381 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 22382 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22383 break;
22384 }
22385 break;
22386#endif
22387 }
22388
22389 tcg_temp_free(t0);
22390 tcg_temp_free(v1_t);
22391 tcg_temp_free(v2_t);
77c5fa8b
JL
22392}
22393
a22260ae
JL
22394static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22395 int ret, int v1, int v2, int check_ret)
22396{
a22260ae
JL
22397 TCGv_i32 t0;
22398 TCGv v1_t;
22399 TCGv v2_t;
22400
22401 if ((ret == 0) && (check_ret == 1)) {
22402 /* Treat as NOP. */
a22260ae
JL
22403 return;
22404 }
22405
22406 t0 = tcg_temp_new_i32();
22407 v1_t = tcg_temp_new();
22408 v2_t = tcg_temp_new();
22409
22410 tcg_gen_movi_i32(t0, ret);
22411 gen_load_gpr(v1_t, v1);
22412 gen_load_gpr(v2_t, v2);
22413
22414 switch (op1) {
22415 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22416 * the same mask and op1. */
22417 case OPC_MULT_G_2E:
908f6be1 22418 check_dsp_r2(ctx);
a22260ae
JL
22419 switch (op2) {
22420 case OPC_MUL_PH:
22421 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22422 break;
22423 case OPC_MUL_S_PH:
22424 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22425 break;
22426 case OPC_MULQ_S_W:
22427 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22428 break;
22429 case OPC_MULQ_RS_W:
22430 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22431 break;
22432 }
22433 break;
22434 case OPC_DPA_W_PH_DSP:
22435 switch (op2) {
22436 case OPC_DPAU_H_QBL:
22437 check_dsp(ctx);
22438 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22439 break;
22440 case OPC_DPAU_H_QBR:
22441 check_dsp(ctx);
22442 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22443 break;
22444 case OPC_DPSU_H_QBL:
22445 check_dsp(ctx);
22446 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22447 break;
22448 case OPC_DPSU_H_QBR:
22449 check_dsp(ctx);
22450 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22451 break;
22452 case OPC_DPA_W_PH:
908f6be1 22453 check_dsp_r2(ctx);
a22260ae
JL
22454 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22455 break;
22456 case OPC_DPAX_W_PH:
908f6be1 22457 check_dsp_r2(ctx);
a22260ae
JL
22458 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22459 break;
22460 case OPC_DPAQ_S_W_PH:
22461 check_dsp(ctx);
22462 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22463 break;
22464 case OPC_DPAQX_S_W_PH:
908f6be1 22465 check_dsp_r2(ctx);
a22260ae
JL
22466 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22467 break;
22468 case OPC_DPAQX_SA_W_PH:
908f6be1 22469 check_dsp_r2(ctx);
a22260ae
JL
22470 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22471 break;
22472 case OPC_DPS_W_PH:
908f6be1 22473 check_dsp_r2(ctx);
a22260ae
JL
22474 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22475 break;
22476 case OPC_DPSX_W_PH:
908f6be1 22477 check_dsp_r2(ctx);
a22260ae
JL
22478 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22479 break;
22480 case OPC_DPSQ_S_W_PH:
22481 check_dsp(ctx);
22482 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22483 break;
22484 case OPC_DPSQX_S_W_PH:
908f6be1 22485 check_dsp_r2(ctx);
a22260ae
JL
22486 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22487 break;
22488 case OPC_DPSQX_SA_W_PH:
908f6be1 22489 check_dsp_r2(ctx);
a22260ae
JL
22490 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22491 break;
22492 case OPC_MULSAQ_S_W_PH:
22493 check_dsp(ctx);
22494 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22495 break;
22496 case OPC_DPAQ_SA_L_W:
22497 check_dsp(ctx);
22498 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22499 break;
22500 case OPC_DPSQ_SA_L_W:
22501 check_dsp(ctx);
22502 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22503 break;
22504 case OPC_MAQ_S_W_PHL:
22505 check_dsp(ctx);
22506 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22507 break;
22508 case OPC_MAQ_S_W_PHR:
22509 check_dsp(ctx);
22510 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22511 break;
22512 case OPC_MAQ_SA_W_PHL:
22513 check_dsp(ctx);
22514 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22515 break;
22516 case OPC_MAQ_SA_W_PHR:
22517 check_dsp(ctx);
22518 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22519 break;
22520 case OPC_MULSA_W_PH:
908f6be1 22521 check_dsp_r2(ctx);
a22260ae
JL
22522 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22523 break;
22524 }
22525 break;
22526#ifdef TARGET_MIPS64
22527 case OPC_DPAQ_W_QH_DSP:
22528 {
22529 int ac = ret & 0x03;
22530 tcg_gen_movi_i32(t0, ac);
22531
22532 switch (op2) {
22533 case OPC_DMADD:
22534 check_dsp(ctx);
22535 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22536 break;
22537 case OPC_DMADDU:
22538 check_dsp(ctx);
22539 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22540 break;
22541 case OPC_DMSUB:
22542 check_dsp(ctx);
22543 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22544 break;
22545 case OPC_DMSUBU:
22546 check_dsp(ctx);
22547 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22548 break;
22549 case OPC_DPA_W_QH:
908f6be1 22550 check_dsp_r2(ctx);
a22260ae
JL
22551 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22552 break;
22553 case OPC_DPAQ_S_W_QH:
22554 check_dsp(ctx);
22555 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22556 break;
22557 case OPC_DPAQ_SA_L_PW:
22558 check_dsp(ctx);
22559 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22560 break;
22561 case OPC_DPAU_H_OBL:
22562 check_dsp(ctx);
22563 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22564 break;
22565 case OPC_DPAU_H_OBR:
22566 check_dsp(ctx);
22567 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22568 break;
22569 case OPC_DPS_W_QH:
908f6be1 22570 check_dsp_r2(ctx);
a22260ae
JL
22571 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22572 break;
22573 case OPC_DPSQ_S_W_QH:
22574 check_dsp(ctx);
22575 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22576 break;
22577 case OPC_DPSQ_SA_L_PW:
22578 check_dsp(ctx);
22579 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22580 break;
22581 case OPC_DPSU_H_OBL:
22582 check_dsp(ctx);
22583 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22584 break;
22585 case OPC_DPSU_H_OBR:
22586 check_dsp(ctx);
22587 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22588 break;
22589 case OPC_MAQ_S_L_PWL:
22590 check_dsp(ctx);
22591 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22592 break;
22593 case OPC_MAQ_S_L_PWR:
22594 check_dsp(ctx);
22595 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22596 break;
22597 case OPC_MAQ_S_W_QHLL:
22598 check_dsp(ctx);
22599 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22600 break;
22601 case OPC_MAQ_SA_W_QHLL:
22602 check_dsp(ctx);
22603 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22604 break;
22605 case OPC_MAQ_S_W_QHLR:
22606 check_dsp(ctx);
22607 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22608 break;
22609 case OPC_MAQ_SA_W_QHLR:
22610 check_dsp(ctx);
22611 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22612 break;
22613 case OPC_MAQ_S_W_QHRL:
22614 check_dsp(ctx);
22615 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22616 break;
22617 case OPC_MAQ_SA_W_QHRL:
22618 check_dsp(ctx);
22619 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22620 break;
22621 case OPC_MAQ_S_W_QHRR:
22622 check_dsp(ctx);
22623 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22624 break;
22625 case OPC_MAQ_SA_W_QHRR:
22626 check_dsp(ctx);
22627 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22628 break;
22629 case OPC_MULSAQ_S_L_PW:
22630 check_dsp(ctx);
22631 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22632 break;
22633 case OPC_MULSAQ_S_W_QH:
22634 check_dsp(ctx);
22635 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22636 break;
22637 }
22638 }
22639 break;
22640#endif
22641 case OPC_ADDU_QB_DSP:
22642 switch (op2) {
22643 case OPC_MULEU_S_PH_QBL:
22644 check_dsp(ctx);
22645 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22646 break;
22647 case OPC_MULEU_S_PH_QBR:
22648 check_dsp(ctx);
22649 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22650 break;
22651 case OPC_MULQ_RS_PH:
22652 check_dsp(ctx);
22653 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22654 break;
22655 case OPC_MULEQ_S_W_PHL:
22656 check_dsp(ctx);
22657 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22658 break;
22659 case OPC_MULEQ_S_W_PHR:
22660 check_dsp(ctx);
22661 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22662 break;
22663 case OPC_MULQ_S_PH:
908f6be1 22664 check_dsp_r2(ctx);
a22260ae
JL
22665 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22666 break;
22667 }
22668 break;
22669#ifdef TARGET_MIPS64
22670 case OPC_ADDU_OB_DSP:
22671 switch (op2) {
22672 case OPC_MULEQ_S_PW_QHL:
22673 check_dsp(ctx);
22674 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22675 break;
22676 case OPC_MULEQ_S_PW_QHR:
22677 check_dsp(ctx);
22678 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22679 break;
22680 case OPC_MULEU_S_QH_OBL:
22681 check_dsp(ctx);
22682 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22683 break;
22684 case OPC_MULEU_S_QH_OBR:
22685 check_dsp(ctx);
22686 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22687 break;
22688 case OPC_MULQ_RS_QH:
22689 check_dsp(ctx);
22690 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22691 break;
22692 }
22693 break;
22694#endif
22695 }
22696
22697 tcg_temp_free_i32(t0);
22698 tcg_temp_free(v1_t);
22699 tcg_temp_free(v2_t);
a22260ae
JL
22700}
22701
d75c135e 22702static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
22703 int ret, int val)
22704{
1cb6686c
JL
22705 int16_t imm;
22706 TCGv t0;
22707 TCGv val_t;
22708
22709 if (ret == 0) {
22710 /* Treat as NOP. */
1cb6686c
JL
22711 return;
22712 }
22713
22714 t0 = tcg_temp_new();
22715 val_t = tcg_temp_new();
22716 gen_load_gpr(val_t, val);
22717
22718 switch (op1) {
22719 case OPC_ABSQ_S_PH_DSP:
22720 switch (op2) {
22721 case OPC_BITREV:
22722 check_dsp(ctx);
22723 gen_helper_bitrev(cpu_gpr[ret], val_t);
22724 break;
22725 case OPC_REPL_QB:
22726 check_dsp(ctx);
22727 {
22728 target_long result;
22729 imm = (ctx->opcode >> 16) & 0xFF;
22730 result = (uint32_t)imm << 24 |
22731 (uint32_t)imm << 16 |
22732 (uint32_t)imm << 8 |
22733 (uint32_t)imm;
22734 result = (int32_t)result;
22735 tcg_gen_movi_tl(cpu_gpr[ret], result);
22736 }
22737 break;
22738 case OPC_REPLV_QB:
22739 check_dsp(ctx);
22740 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22741 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22742 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22743 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22744 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22746 break;
22747 case OPC_REPL_PH:
22748 check_dsp(ctx);
22749 {
22750 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 22751 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
22752 tcg_gen_movi_tl(cpu_gpr[ret], \
22753 (target_long)((int32_t)imm << 16 | \
c4aaba92 22754 (uint16_t)imm));
1cb6686c
JL
22755 }
22756 break;
22757 case OPC_REPLV_PH:
22758 check_dsp(ctx);
22759 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22760 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22761 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22762 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22763 break;
22764 }
22765 break;
22766#ifdef TARGET_MIPS64
22767 case OPC_ABSQ_S_QH_DSP:
22768 switch (op2) {
22769 case OPC_REPL_OB:
22770 check_dsp(ctx);
22771 {
22772 target_long temp;
22773
22774 imm = (ctx->opcode >> 16) & 0xFF;
22775 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22776 temp = (temp << 16) | temp;
22777 temp = (temp << 32) | temp;
22778 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22779 break;
22780 }
22781 case OPC_REPL_PW:
22782 check_dsp(ctx);
22783 {
22784 target_long temp;
22785
22786 imm = (ctx->opcode >> 16) & 0x03FF;
22787 imm = (int16_t)(imm << 6) >> 6;
22788 temp = ((target_long)imm << 32) \
22789 | ((target_long)imm & 0xFFFFFFFF);
22790 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22791 break;
22792 }
22793 case OPC_REPL_QH:
22794 check_dsp(ctx);
22795 {
22796 target_long temp;
22797
22798 imm = (ctx->opcode >> 16) & 0x03FF;
22799 imm = (int16_t)(imm << 6) >> 6;
22800
22801 temp = ((uint64_t)(uint16_t)imm << 48) |
22802 ((uint64_t)(uint16_t)imm << 32) |
22803 ((uint64_t)(uint16_t)imm << 16) |
22804 (uint64_t)(uint16_t)imm;
22805 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22806 break;
22807 }
22808 case OPC_REPLV_OB:
22809 check_dsp(ctx);
22810 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22811 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22812 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22813 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22814 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22815 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22816 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22817 break;
22818 case OPC_REPLV_PW:
22819 check_dsp(ctx);
22820 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22821 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22822 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22823 break;
22824 case OPC_REPLV_QH:
22825 check_dsp(ctx);
22826 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22827 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22828 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22831 break;
22832 }
22833 break;
22834#endif
22835 }
22836 tcg_temp_free(t0);
22837 tcg_temp_free(val_t);
1cb6686c
JL
22838}
22839
26690560
JL
22840static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22841 uint32_t op1, uint32_t op2,
22842 int ret, int v1, int v2, int check_ret)
22843{
26690560
JL
22844 TCGv t1;
22845 TCGv v1_t;
22846 TCGv v2_t;
22847
22848 if ((ret == 0) && (check_ret == 1)) {
22849 /* Treat as NOP. */
26690560
JL
22850 return;
22851 }
22852
26690560
JL
22853 t1 = tcg_temp_new();
22854 v1_t = tcg_temp_new();
22855 v2_t = tcg_temp_new();
22856
22857 gen_load_gpr(v1_t, v1);
22858 gen_load_gpr(v2_t, v2);
22859
22860 switch (op1) {
26690560
JL
22861 case OPC_CMPU_EQ_QB_DSP:
22862 switch (op2) {
22863 case OPC_CMPU_EQ_QB:
22864 check_dsp(ctx);
22865 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22866 break;
22867 case OPC_CMPU_LT_QB:
22868 check_dsp(ctx);
22869 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22870 break;
22871 case OPC_CMPU_LE_QB:
22872 check_dsp(ctx);
22873 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22874 break;
22875 case OPC_CMPGU_EQ_QB:
22876 check_dsp(ctx);
22877 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22878 break;
22879 case OPC_CMPGU_LT_QB:
22880 check_dsp(ctx);
22881 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22882 break;
22883 case OPC_CMPGU_LE_QB:
22884 check_dsp(ctx);
22885 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22886 break;
22887 case OPC_CMPGDU_EQ_QB:
908f6be1 22888 check_dsp_r2(ctx);
26690560
JL
22889 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22890 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22891 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22892 tcg_gen_shli_tl(t1, t1, 24);
22893 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22894 break;
22895 case OPC_CMPGDU_LT_QB:
908f6be1 22896 check_dsp_r2(ctx);
26690560
JL
22897 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22898 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22899 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22900 tcg_gen_shli_tl(t1, t1, 24);
22901 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22902 break;
22903 case OPC_CMPGDU_LE_QB:
908f6be1 22904 check_dsp_r2(ctx);
26690560
JL
22905 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22906 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22907 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22908 tcg_gen_shli_tl(t1, t1, 24);
22909 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22910 break;
22911 case OPC_CMP_EQ_PH:
22912 check_dsp(ctx);
22913 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22914 break;
22915 case OPC_CMP_LT_PH:
22916 check_dsp(ctx);
22917 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22918 break;
22919 case OPC_CMP_LE_PH:
22920 check_dsp(ctx);
22921 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22922 break;
22923 case OPC_PICK_QB:
22924 check_dsp(ctx);
22925 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22926 break;
22927 case OPC_PICK_PH:
22928 check_dsp(ctx);
22929 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22930 break;
22931 case OPC_PACKRL_PH:
22932 check_dsp(ctx);
22933 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22934 break;
22935 }
22936 break;
22937#ifdef TARGET_MIPS64
22938 case OPC_CMPU_EQ_OB_DSP:
22939 switch (op2) {
22940 case OPC_CMP_EQ_PW:
22941 check_dsp(ctx);
22942 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22943 break;
22944 case OPC_CMP_LT_PW:
22945 check_dsp(ctx);
22946 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22947 break;
22948 case OPC_CMP_LE_PW:
22949 check_dsp(ctx);
22950 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22951 break;
22952 case OPC_CMP_EQ_QH:
22953 check_dsp(ctx);
22954 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22955 break;
22956 case OPC_CMP_LT_QH:
22957 check_dsp(ctx);
22958 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22959 break;
22960 case OPC_CMP_LE_QH:
22961 check_dsp(ctx);
22962 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22963 break;
22964 case OPC_CMPGDU_EQ_OB:
908f6be1 22965 check_dsp_r2(ctx);
26690560
JL
22966 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22967 break;
22968 case OPC_CMPGDU_LT_OB:
908f6be1 22969 check_dsp_r2(ctx);
26690560
JL
22970 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22971 break;
22972 case OPC_CMPGDU_LE_OB:
908f6be1 22973 check_dsp_r2(ctx);
26690560
JL
22974 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22975 break;
22976 case OPC_CMPGU_EQ_OB:
22977 check_dsp(ctx);
22978 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22979 break;
22980 case OPC_CMPGU_LT_OB:
22981 check_dsp(ctx);
22982 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22983 break;
22984 case OPC_CMPGU_LE_OB:
22985 check_dsp(ctx);
22986 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22987 break;
22988 case OPC_CMPU_EQ_OB:
22989 check_dsp(ctx);
22990 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22991 break;
22992 case OPC_CMPU_LT_OB:
22993 check_dsp(ctx);
22994 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22995 break;
22996 case OPC_CMPU_LE_OB:
22997 check_dsp(ctx);
22998 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22999 break;
23000 case OPC_PACKRL_PW:
23001 check_dsp(ctx);
23002 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23003 break;
23004 case OPC_PICK_OB:
23005 check_dsp(ctx);
23006 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23007 break;
23008 case OPC_PICK_PW:
23009 check_dsp(ctx);
23010 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23011 break;
23012 case OPC_PICK_QH:
23013 check_dsp(ctx);
23014 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23015 break;
23016 }
23017 break;
df6126a7
AJ
23018#endif
23019 }
23020
23021 tcg_temp_free(t1);
23022 tcg_temp_free(v1_t);
23023 tcg_temp_free(v2_t);
df6126a7
AJ
23024}
23025
23026static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23027 uint32_t op1, int rt, int rs, int sa)
23028{
df6126a7
AJ
23029 TCGv t0;
23030
908f6be1 23031 check_dsp_r2(ctx);
df6126a7
AJ
23032
23033 if (rt == 0) {
23034 /* Treat as NOP. */
df6126a7
AJ
23035 return;
23036 }
23037
23038 t0 = tcg_temp_new();
23039 gen_load_gpr(t0, rs);
23040
23041 switch (op1) {
23042 case OPC_APPEND_DSP:
23043 switch (MASK_APPEND(ctx->opcode)) {
23044 case OPC_APPEND:
23045 if (sa != 0) {
23046 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23047 }
23048 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23049 break;
23050 case OPC_PREPEND:
23051 if (sa != 0) {
23052 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23053 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23054 tcg_gen_shli_tl(t0, t0, 32 - sa);
23055 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23056 }
23057 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23058 break;
23059 case OPC_BALIGN:
23060 sa &= 3;
23061 if (sa != 0 && sa != 2) {
23062 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23063 tcg_gen_ext32u_tl(t0, t0);
23064 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23065 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23066 }
23067 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23068 break;
23069 default: /* Invalid */
23070 MIPS_INVAL("MASK APPEND");
9c708c7f 23071 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
23072 break;
23073 }
23074 break;
23075#ifdef TARGET_MIPS64
26690560 23076 case OPC_DAPPEND_DSP:
df6126a7 23077 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 23078 case OPC_DAPPEND:
df6126a7
AJ
23079 if (sa != 0) {
23080 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23081 }
26690560
JL
23082 break;
23083 case OPC_PREPENDD:
df6126a7
AJ
23084 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23085 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23086 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
23087 break;
23088 case OPC_PREPENDW:
df6126a7
AJ
23089 if (sa != 0) {
23090 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23091 tcg_gen_shli_tl(t0, t0, 64 - sa);
23092 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23093 }
26690560
JL
23094 break;
23095 case OPC_DBALIGN:
df6126a7
AJ
23096 sa &= 7;
23097 if (sa != 0 && sa != 2 && sa != 4) {
23098 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23099 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23100 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23101 }
26690560
JL
23102 break;
23103 default: /* Invalid */
23104 MIPS_INVAL("MASK DAPPEND");
9c708c7f 23105 generate_exception_end(ctx, EXCP_RI);
26690560
JL
23106 break;
23107 }
23108 break;
23109#endif
23110 }
df6126a7 23111 tcg_temp_free(t0);
26690560
JL
23112}
23113
b53371ed
JL
23114static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23115 int ret, int v1, int v2, int check_ret)
23116
23117{
b53371ed
JL
23118 TCGv t0;
23119 TCGv t1;
23120 TCGv v1_t;
23121 TCGv v2_t;
23122 int16_t imm;
23123
23124 if ((ret == 0) && (check_ret == 1)) {
23125 /* Treat as NOP. */
b53371ed
JL
23126 return;
23127 }
23128
23129 t0 = tcg_temp_new();
23130 t1 = tcg_temp_new();
23131 v1_t = tcg_temp_new();
23132 v2_t = tcg_temp_new();
23133
23134 gen_load_gpr(v1_t, v1);
23135 gen_load_gpr(v2_t, v2);
23136
23137 switch (op1) {
23138 case OPC_EXTR_W_DSP:
23139 check_dsp(ctx);
23140 switch (op2) {
23141 case OPC_EXTR_W:
23142 tcg_gen_movi_tl(t0, v2);
23143 tcg_gen_movi_tl(t1, v1);
23144 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23145 break;
23146 case OPC_EXTR_R_W:
23147 tcg_gen_movi_tl(t0, v2);
23148 tcg_gen_movi_tl(t1, v1);
23149 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23150 break;
23151 case OPC_EXTR_RS_W:
23152 tcg_gen_movi_tl(t0, v2);
23153 tcg_gen_movi_tl(t1, v1);
23154 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23155 break;
23156 case OPC_EXTR_S_H:
23157 tcg_gen_movi_tl(t0, v2);
23158 tcg_gen_movi_tl(t1, v1);
23159 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23160 break;
23161 case OPC_EXTRV_S_H:
23162 tcg_gen_movi_tl(t0, v2);
23163 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23164 break;
23165 case OPC_EXTRV_W:
23166 tcg_gen_movi_tl(t0, v2);
23167 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23168 break;
23169 case OPC_EXTRV_R_W:
23170 tcg_gen_movi_tl(t0, v2);
23171 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23172 break;
23173 case OPC_EXTRV_RS_W:
23174 tcg_gen_movi_tl(t0, v2);
23175 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23176 break;
23177 case OPC_EXTP:
23178 tcg_gen_movi_tl(t0, v2);
23179 tcg_gen_movi_tl(t1, v1);
23180 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23181 break;
23182 case OPC_EXTPV:
23183 tcg_gen_movi_tl(t0, v2);
23184 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23185 break;
23186 case OPC_EXTPDP:
23187 tcg_gen_movi_tl(t0, v2);
23188 tcg_gen_movi_tl(t1, v1);
23189 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23190 break;
23191 case OPC_EXTPDPV:
23192 tcg_gen_movi_tl(t0, v2);
23193 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23194 break;
23195 case OPC_SHILO:
23196 imm = (ctx->opcode >> 20) & 0x3F;
23197 tcg_gen_movi_tl(t0, ret);
23198 tcg_gen_movi_tl(t1, imm);
23199 gen_helper_shilo(t0, t1, cpu_env);
23200 break;
23201 case OPC_SHILOV:
23202 tcg_gen_movi_tl(t0, ret);
23203 gen_helper_shilo(t0, v1_t, cpu_env);
23204 break;
23205 case OPC_MTHLIP:
23206 tcg_gen_movi_tl(t0, ret);
23207 gen_helper_mthlip(t0, v1_t, cpu_env);
23208 break;
23209 case OPC_WRDSP:
23210 imm = (ctx->opcode >> 11) & 0x3FF;
23211 tcg_gen_movi_tl(t0, imm);
23212 gen_helper_wrdsp(v1_t, t0, cpu_env);
23213 break;
23214 case OPC_RDDSP:
23215 imm = (ctx->opcode >> 16) & 0x03FF;
23216 tcg_gen_movi_tl(t0, imm);
23217 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23218 break;
23219 }
23220 break;
23221#ifdef TARGET_MIPS64
23222 case OPC_DEXTR_W_DSP:
23223 check_dsp(ctx);
23224 switch (op2) {
23225 case OPC_DMTHLIP:
23226 tcg_gen_movi_tl(t0, ret);
23227 gen_helper_dmthlip(v1_t, t0, cpu_env);
23228 break;
23229 case OPC_DSHILO:
23230 {
23231 int shift = (ctx->opcode >> 19) & 0x7F;
23232 int ac = (ctx->opcode >> 11) & 0x03;
23233 tcg_gen_movi_tl(t0, shift);
23234 tcg_gen_movi_tl(t1, ac);
23235 gen_helper_dshilo(t0, t1, cpu_env);
23236 break;
23237 }
23238 case OPC_DSHILOV:
23239 {
23240 int ac = (ctx->opcode >> 11) & 0x03;
23241 tcg_gen_movi_tl(t0, ac);
23242 gen_helper_dshilo(v1_t, t0, cpu_env);
23243 break;
23244 }
23245 case OPC_DEXTP:
23246 tcg_gen_movi_tl(t0, v2);
23247 tcg_gen_movi_tl(t1, v1);
23248
23249 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23250 break;
23251 case OPC_DEXTPV:
23252 tcg_gen_movi_tl(t0, v2);
23253 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23254 break;
23255 case OPC_DEXTPDP:
23256 tcg_gen_movi_tl(t0, v2);
23257 tcg_gen_movi_tl(t1, v1);
23258 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23259 break;
23260 case OPC_DEXTPDPV:
23261 tcg_gen_movi_tl(t0, v2);
23262 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23263 break;
23264 case OPC_DEXTR_L:
23265 tcg_gen_movi_tl(t0, v2);
23266 tcg_gen_movi_tl(t1, v1);
23267 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23268 break;
23269 case OPC_DEXTR_R_L:
23270 tcg_gen_movi_tl(t0, v2);
23271 tcg_gen_movi_tl(t1, v1);
23272 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23273 break;
23274 case OPC_DEXTR_RS_L:
23275 tcg_gen_movi_tl(t0, v2);
23276 tcg_gen_movi_tl(t1, v1);
23277 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23278 break;
23279 case OPC_DEXTR_W:
23280 tcg_gen_movi_tl(t0, v2);
23281 tcg_gen_movi_tl(t1, v1);
23282 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23283 break;
23284 case OPC_DEXTR_R_W:
23285 tcg_gen_movi_tl(t0, v2);
23286 tcg_gen_movi_tl(t1, v1);
23287 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23288 break;
23289 case OPC_DEXTR_RS_W:
23290 tcg_gen_movi_tl(t0, v2);
23291 tcg_gen_movi_tl(t1, v1);
23292 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23293 break;
23294 case OPC_DEXTR_S_H:
23295 tcg_gen_movi_tl(t0, v2);
23296 tcg_gen_movi_tl(t1, v1);
23297 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23298 break;
23299 case OPC_DEXTRV_S_H:
23300 tcg_gen_movi_tl(t0, v2);
23301 tcg_gen_movi_tl(t1, v1);
23302 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23303 break;
23304 case OPC_DEXTRV_L:
23305 tcg_gen_movi_tl(t0, v2);
23306 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23307 break;
23308 case OPC_DEXTRV_R_L:
23309 tcg_gen_movi_tl(t0, v2);
23310 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23311 break;
23312 case OPC_DEXTRV_RS_L:
23313 tcg_gen_movi_tl(t0, v2);
23314 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23315 break;
23316 case OPC_DEXTRV_W:
23317 tcg_gen_movi_tl(t0, v2);
23318 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23319 break;
23320 case OPC_DEXTRV_R_W:
23321 tcg_gen_movi_tl(t0, v2);
23322 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23323 break;
23324 case OPC_DEXTRV_RS_W:
23325 tcg_gen_movi_tl(t0, v2);
23326 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23327 break;
23328 }
23329 break;
23330#endif
23331 }
23332
23333 tcg_temp_free(t0);
23334 tcg_temp_free(t1);
23335 tcg_temp_free(v1_t);
23336 tcg_temp_free(v2_t);
b53371ed
JL
23337}
23338
9b1a1d68
JL
23339/* End MIPSDSP functions. */
23340
10dc65db
LA
23341static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23342{
4267d3e6 23343 int rs, rt, rd, sa;
b42ee5e1 23344 uint32_t op1, op2;
10dc65db
LA
23345
23346 rs = (ctx->opcode >> 21) & 0x1f;
23347 rt = (ctx->opcode >> 16) & 0x1f;
23348 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 23349 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23350
23351 op1 = MASK_SPECIAL(ctx->opcode);
23352 switch (op1) {
d4ea6acd 23353 case OPC_LSA:
1f1b4c00 23354 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23355 break;
c2e19f3c
AM
23356 case OPC_MULT:
23357 case OPC_MULTU:
23358 case OPC_DIV:
23359 case OPC_DIVU:
b42ee5e1
LA
23360 op2 = MASK_R6_MULDIV(ctx->opcode);
23361 switch (op2) {
23362 case R6_OPC_MUL:
23363 case R6_OPC_MUH:
23364 case R6_OPC_MULU:
23365 case R6_OPC_MUHU:
23366 case R6_OPC_DIV:
23367 case R6_OPC_MOD:
23368 case R6_OPC_DIVU:
23369 case R6_OPC_MODU:
23370 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23371 break;
23372 default:
23373 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23374 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23375 break;
23376 }
23377 break;
10dc65db
LA
23378 case OPC_SELEQZ:
23379 case OPC_SELNEZ:
23380 gen_cond_move(ctx, op1, rd, rs, rt);
23381 break;
4267d3e6
LA
23382 case R6_OPC_CLO:
23383 case R6_OPC_CLZ:
23384 if (rt == 0 && sa == 1) {
23385 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23386 We need additionally to check other fields */
23387 gen_cl(ctx, op1, rd, rs);
23388 } else {
9c708c7f 23389 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23390 }
23391 break;
23392 case R6_OPC_SDBBP:
3b3c1694
LA
23393 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23394 gen_helper_do_semihosting(cpu_env);
faf1f68b 23395 } else {
3b3c1694 23396 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 23397 generate_exception_end(ctx, EXCP_RI);
3b3c1694 23398 } else {
9c708c7f 23399 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23400 }
faf1f68b 23401 }
4267d3e6 23402 break;
b42ee5e1 23403#if defined(TARGET_MIPS64)
d4ea6acd
LA
23404 case OPC_DLSA:
23405 check_mips_64(ctx);
1f1b4c00 23406 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23407 break;
4267d3e6
LA
23408 case R6_OPC_DCLO:
23409 case R6_OPC_DCLZ:
23410 if (rt == 0 && sa == 1) {
23411 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23412 We need additionally to check other fields */
23413 check_mips_64(ctx);
23414 gen_cl(ctx, op1, rd, rs);
23415 } else {
9c708c7f 23416 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23417 }
23418 break;
c2e19f3c
AM
23419 case OPC_DMULT:
23420 case OPC_DMULTU:
23421 case OPC_DDIV:
23422 case OPC_DDIVU:
23423
b42ee5e1
LA
23424 op2 = MASK_R6_MULDIV(ctx->opcode);
23425 switch (op2) {
23426 case R6_OPC_DMUL:
23427 case R6_OPC_DMUH:
23428 case R6_OPC_DMULU:
23429 case R6_OPC_DMUHU:
23430 case R6_OPC_DDIV:
23431 case R6_OPC_DMOD:
23432 case R6_OPC_DDIVU:
23433 case R6_OPC_DMODU:
23434 check_mips_64(ctx);
23435 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23436 break;
23437 default:
23438 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23439 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23440 break;
23441 }
23442 break;
23443#endif
10dc65db
LA
23444 default: /* Invalid */
23445 MIPS_INVAL("special_r6");
9c708c7f 23446 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23447 break;
23448 }
23449}
23450
23451static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23452{
b42ee5e1 23453 int rs, rt, rd, sa;
10dc65db
LA
23454 uint32_t op1;
23455
23456 rs = (ctx->opcode >> 21) & 0x1f;
23457 rt = (ctx->opcode >> 16) & 0x1f;
23458 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 23459 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23460
23461 op1 = MASK_SPECIAL(ctx->opcode);
23462 switch (op1) {
23463 case OPC_MOVN: /* Conditional move */
23464 case OPC_MOVZ:
23465 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23466 INSN_LOONGSON2E | INSN_LOONGSON2F);
23467 gen_cond_move(ctx, op1, rd, rs, rt);
23468 break;
23469 case OPC_MFHI: /* Move from HI/LO */
23470 case OPC_MFLO:
23471 gen_HILO(ctx, op1, rs & 3, rd);
23472 break;
23473 case OPC_MTHI:
23474 case OPC_MTLO: /* Move to HI/LO */
23475 gen_HILO(ctx, op1, rd & 3, rs);
23476 break;
23477 case OPC_MOVCI:
23478 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23479 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23480 check_cp1_enabled(ctx);
23481 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23482 (ctx->opcode >> 16) & 1);
23483 } else {
23484 generate_exception_err(ctx, EXCP_CpU, 1);
23485 }
23486 break;
b42ee5e1
LA
23487 case OPC_MULT:
23488 case OPC_MULTU:
23489 if (sa) {
23490 check_insn(ctx, INSN_VR54XX);
23491 op1 = MASK_MUL_VR54XX(ctx->opcode);
23492 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23493 } else {
23494 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23495 }
23496 break;
23497 case OPC_DIV:
23498 case OPC_DIVU:
23499 gen_muldiv(ctx, op1, 0, rs, rt);
23500 break;
23501#if defined(TARGET_MIPS64)
c2e19f3c
AM
23502 case OPC_DMULT:
23503 case OPC_DMULTU:
23504 case OPC_DDIV:
23505 case OPC_DDIVU:
b42ee5e1
LA
23506 check_insn(ctx, ISA_MIPS3);
23507 check_mips_64(ctx);
23508 gen_muldiv(ctx, op1, 0, rs, rt);
23509 break;
23510#endif
0aefa333 23511 case OPC_JR:
b231c103 23512 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 23513 break;
4267d3e6
LA
23514 case OPC_SPIM:
23515#ifdef MIPS_STRICT_STANDARD
23516 MIPS_INVAL("SPIM");
9c708c7f 23517 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23518#else
23519 /* Implemented as RI exception for now. */
23520 MIPS_INVAL("spim (unofficial)");
9c708c7f 23521 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23522#endif
23523 break;
10dc65db
LA
23524 default: /* Invalid */
23525 MIPS_INVAL("special_legacy");
9c708c7f 23526 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23527 break;
23528 }
23529}
23530
099e5b4d 23531static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 23532{
3c824109 23533 int rs, rt, rd, sa;
099e5b4d 23534 uint32_t op1;
3c824109 23535
3c824109
NF
23536 rs = (ctx->opcode >> 21) & 0x1f;
23537 rt = (ctx->opcode >> 16) & 0x1f;
23538 rd = (ctx->opcode >> 11) & 0x1f;
23539 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
23540
23541 op1 = MASK_SPECIAL(ctx->opcode);
23542 switch (op1) {
23543 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
23544 if (sa == 5 && rd == 0 &&
23545 rs == 0 && rt == 0) { /* PAUSE */
23546 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23547 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 23548 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
23549 break;
23550 }
23551 }
23552 /* Fallthrough */
099e5b4d
LA
23553 case OPC_SRA:
23554 gen_shift_imm(ctx, op1, rd, rt, sa);
23555 break;
23556 case OPC_SRL:
23557 switch ((ctx->opcode >> 21) & 0x1f) {
23558 case 1:
23559 /* rotr is decoded as srl on non-R2 CPUs */
23560 if (ctx->insn_flags & ISA_MIPS32R2) {
23561 op1 = OPC_ROTR;
ea63e2c3 23562 }
099e5b4d
LA
23563 /* Fallthrough */
23564 case 0:
23565 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 23566 break;
099e5b4d 23567 default:
9c708c7f 23568 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 23569 break;
099e5b4d
LA
23570 }
23571 break;
c2e19f3c
AM
23572 case OPC_ADD:
23573 case OPC_ADDU:
23574 case OPC_SUB:
23575 case OPC_SUBU:
099e5b4d
LA
23576 gen_arith(ctx, op1, rd, rs, rt);
23577 break;
23578 case OPC_SLLV: /* Shifts */
23579 case OPC_SRAV:
23580 gen_shift(ctx, op1, rd, rs, rt);
23581 break;
23582 case OPC_SRLV:
23583 switch ((ctx->opcode >> 6) & 0x1f) {
23584 case 1:
23585 /* rotrv is decoded as srlv on non-R2 CPUs */
23586 if (ctx->insn_flags & ISA_MIPS32R2) {
23587 op1 = OPC_ROTRV;
26135ead 23588 }
099e5b4d
LA
23589 /* Fallthrough */
23590 case 0:
23591 gen_shift(ctx, op1, rd, rs, rt);
26135ead 23592 break;
099e5b4d 23593 default:
9c708c7f 23594 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 23595 break;
099e5b4d
LA
23596 }
23597 break;
23598 case OPC_SLT: /* Set on less than */
23599 case OPC_SLTU:
23600 gen_slt(ctx, op1, rd, rs, rt);
23601 break;
23602 case OPC_AND: /* Logic*/
23603 case OPC_OR:
23604 case OPC_NOR:
23605 case OPC_XOR:
23606 gen_logic(ctx, op1, rd, rs, rt);
23607 break;
0aefa333 23608 case OPC_JALR:
b231c103 23609 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 23610 break;
c2e19f3c
AM
23611 case OPC_TGE: /* Traps */
23612 case OPC_TGEU:
23613 case OPC_TLT:
23614 case OPC_TLTU:
23615 case OPC_TEQ:
099e5b4d 23616 case OPC_TNE:
d9224450 23617 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
23618 gen_trap(ctx, op1, rs, rt, -1);
23619 break;
d4ea6acd 23620 case OPC_LSA: /* OPC_PMON */
f7685877
YK
23621 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23622 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
23623 decode_opc_special_r6(env, ctx);
23624 } else {
23625 /* Pmon entry point, also R4010 selsl */
b48cfdff 23626#ifdef MIPS_STRICT_STANDARD
d4ea6acd 23627 MIPS_INVAL("PMON / selsl");
9c708c7f 23628 generate_exception_end(ctx, EXCP_RI);
b48cfdff 23629#else
d4ea6acd 23630 gen_helper_0e0i(pmon, sa);
b48cfdff 23631#endif
d4ea6acd 23632 }
099e5b4d
LA
23633 break;
23634 case OPC_SYSCALL:
9c708c7f 23635 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
23636 break;
23637 case OPC_BREAK:
9c708c7f 23638 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 23639 break;
099e5b4d 23640 case OPC_SYNC:
d9224450 23641 check_insn(ctx, ISA_MIPS2);
d208ac0c 23642 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 23643 break;
4ad40f36 23644
d26bc211 23645#if defined(TARGET_MIPS64)
099e5b4d
LA
23646 /* MIPS64 specific opcodes */
23647 case OPC_DSLL:
23648 case OPC_DSRA:
23649 case OPC_DSLL32:
23650 case OPC_DSRA32:
23651 check_insn(ctx, ISA_MIPS3);
23652 check_mips_64(ctx);
23653 gen_shift_imm(ctx, op1, rd, rt, sa);
23654 break;
23655 case OPC_DSRL:
23656 switch ((ctx->opcode >> 21) & 0x1f) {
23657 case 1:
23658 /* drotr is decoded as dsrl on non-R2 CPUs */
23659 if (ctx->insn_flags & ISA_MIPS32R2) {
23660 op1 = OPC_DROTR;
ea63e2c3 23661 }
099e5b4d
LA
23662 /* Fallthrough */
23663 case 0:
d75c135e 23664 check_insn(ctx, ISA_MIPS3);
e189e748 23665 check_mips_64(ctx);
099e5b4d 23666 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23667 break;
099e5b4d 23668 default:
9c708c7f 23669 generate_exception_end(ctx, EXCP_RI);
460f00c4 23670 break;
099e5b4d
LA
23671 }
23672 break;
23673 case OPC_DSRL32:
23674 switch ((ctx->opcode >> 21) & 0x1f) {
23675 case 1:
23676 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23677 if (ctx->insn_flags & ISA_MIPS32R2) {
23678 op1 = OPC_DROTR32;
ea63e2c3 23679 }
099e5b4d
LA
23680 /* Fallthrough */
23681 case 0:
d75c135e 23682 check_insn(ctx, ISA_MIPS3);
e189e748 23683 check_mips_64(ctx);
099e5b4d 23684 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23685 break;
099e5b4d 23686 default:
9c708c7f 23687 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23688 break;
23689 }
23690 break;
c2e19f3c
AM
23691 case OPC_DADD:
23692 case OPC_DADDU:
23693 case OPC_DSUB:
23694 case OPC_DSUBU:
099e5b4d
LA
23695 check_insn(ctx, ISA_MIPS3);
23696 check_mips_64(ctx);
23697 gen_arith(ctx, op1, rd, rs, rt);
23698 break;
23699 case OPC_DSLLV:
23700 case OPC_DSRAV:
23701 check_insn(ctx, ISA_MIPS3);
23702 check_mips_64(ctx);
23703 gen_shift(ctx, op1, rd, rs, rt);
23704 break;
23705 case OPC_DSRLV:
23706 switch ((ctx->opcode >> 6) & 0x1f) {
23707 case 1:
23708 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23709 if (ctx->insn_flags & ISA_MIPS32R2) {
23710 op1 = OPC_DROTRV;
6af0bf9c 23711 }
099e5b4d
LA
23712 /* Fallthrough */
23713 case 0:
23714 check_insn(ctx, ISA_MIPS3);
e189e748 23715 check_mips_64(ctx);
099e5b4d 23716 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 23717 break;
099e5b4d 23718 default:
9c708c7f 23719 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23720 break;
23721 }
23722 break;
f7685877
YK
23723 case OPC_DLSA:
23724 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23725 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23726 decode_opc_special_r6(env, ctx);
23727 }
23728 break;
099e5b4d 23729#endif
10dc65db
LA
23730 default:
23731 if (ctx->insn_flags & ISA_MIPS32R6) {
23732 decode_opc_special_r6(env, ctx);
23733 } else {
23734 decode_opc_special_legacy(env, ctx);
23735 }
23736 }
23737}
23738
10dc65db 23739static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
23740{
23741 int rs, rt, rd;
23742 uint32_t op1;
6c5c1e20 23743
4267d3e6
LA
23744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23745
099e5b4d
LA
23746 rs = (ctx->opcode >> 21) & 0x1f;
23747 rt = (ctx->opcode >> 16) & 0x1f;
23748 rd = (ctx->opcode >> 11) & 0x1f;
23749
23750 op1 = MASK_SPECIAL2(ctx->opcode);
23751 switch (op1) {
c2e19f3c
AM
23752 case OPC_MADD: /* Multiply and add/sub */
23753 case OPC_MADDU:
23754 case OPC_MSUB:
23755 case OPC_MSUBU:
099e5b4d
LA
23756 check_insn(ctx, ISA_MIPS32);
23757 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23758 break;
23759 case OPC_MUL:
099e5b4d
LA
23760 gen_arith(ctx, op1, rd, rs, rt);
23761 break;
fac5a073
LA
23762 case OPC_DIV_G_2F:
23763 case OPC_DIVU_G_2F:
23764 case OPC_MULT_G_2F:
23765 case OPC_MULTU_G_2F:
23766 case OPC_MOD_G_2F:
23767 case OPC_MODU_G_2F:
23768 check_insn(ctx, INSN_LOONGSON2F);
23769 gen_loongson_integer(ctx, op1, rd, rs, rt);
23770 break;
099e5b4d
LA
23771 case OPC_CLO:
23772 case OPC_CLZ:
23773 check_insn(ctx, ISA_MIPS32);
23774 gen_cl(ctx, op1, rd, rs);
23775 break;
23776 case OPC_SDBBP:
3b3c1694
LA
23777 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23778 gen_helper_do_semihosting(cpu_env);
23779 } else {
23780 /* XXX: not clear which exception should be raised
23781 * when in debug mode...
23782 */
23783 check_insn(ctx, ISA_MIPS32);
9c708c7f 23784 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23785 }
099e5b4d 23786 break;
9b1a1d68 23787#if defined(TARGET_MIPS64)
099e5b4d
LA
23788 case OPC_DCLO:
23789 case OPC_DCLZ:
23790 check_insn(ctx, ISA_MIPS64);
23791 check_mips_64(ctx);
23792 gen_cl(ctx, op1, rd, rs);
23793 break;
4267d3e6
LA
23794 case OPC_DMULT_G_2F:
23795 case OPC_DMULTU_G_2F:
23796 case OPC_DDIV_G_2F:
23797 case OPC_DDIVU_G_2F:
23798 case OPC_DMOD_G_2F:
23799 case OPC_DMODU_G_2F:
23800 check_insn(ctx, INSN_LOONGSON2F);
23801 gen_loongson_integer(ctx, op1, rd, rs, rt);
23802 break;
10dc65db 23803#endif
4267d3e6
LA
23804 default: /* Invalid */
23805 MIPS_INVAL("special2_legacy");
9c708c7f 23806 generate_exception_end(ctx, EXCP_RI);
4267d3e6 23807 break;
10dc65db
LA
23808 }
23809}
23810
23811static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23812{
15eacb9b
YK
23813 int rs, rt, rd, sa;
23814 uint32_t op1, op2;
10dc65db
LA
23815 int16_t imm;
23816
23817 rs = (ctx->opcode >> 21) & 0x1f;
23818 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
23819 rd = (ctx->opcode >> 11) & 0x1f;
23820 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23821 imm = (int16_t)ctx->opcode >> 7;
23822
23823 op1 = MASK_SPECIAL3(ctx->opcode);
23824 switch (op1) {
bf7910c6
LA
23825 case R6_OPC_PREF:
23826 if (rt >= 24) {
23827 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 23828 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
23829 }
23830 /* Treat as NOP. */
23831 break;
23832 case R6_OPC_CACHE:
40d48212 23833 check_cp0_enabled(ctx);
0d74a222
LA
23834 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23835 gen_cache_operation(ctx, rt, rs, imm);
23836 }
bf7910c6 23837 break;
10dc65db
LA
23838 case R6_OPC_SC:
23839 gen_st_cond(ctx, op1, rt, rs, imm);
23840 break;
23841 case R6_OPC_LL:
23842 gen_ld(ctx, op1, rt, rs, imm);
23843 break;
15eacb9b
YK
23844 case OPC_BSHFL:
23845 {
23846 if (rd == 0) {
23847 /* Treat as NOP. */
23848 break;
23849 }
15eacb9b
YK
23850 op2 = MASK_BSHFL(ctx->opcode);
23851 switch (op2) {
c2e19f3c
AM
23852 case OPC_ALIGN:
23853 case OPC_ALIGN_END:
821f2008 23854 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
23855 break;
23856 case OPC_BITSWAP:
1f1b4c00 23857 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
23858 break;
23859 }
15eacb9b
YK
23860 }
23861 break;
bf7910c6
LA
23862#if defined(TARGET_MIPS64)
23863 case R6_OPC_SCD:
23864 gen_st_cond(ctx, op1, rt, rs, imm);
23865 break;
23866 case R6_OPC_LLD:
23867 gen_ld(ctx, op1, rt, rs, imm);
23868 break;
15eacb9b
YK
23869 case OPC_DBSHFL:
23870 check_mips_64(ctx);
23871 {
23872 if (rd == 0) {
23873 /* Treat as NOP. */
23874 break;
23875 }
15eacb9b
YK
23876 op2 = MASK_DBSHFL(ctx->opcode);
23877 switch (op2) {
c2e19f3c
AM
23878 case OPC_DALIGN:
23879 case OPC_DALIGN_END:
821f2008 23880 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
23881 break;
23882 case OPC_DBITSWAP:
1f1b4c00 23883 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
23884 break;
23885 }
1f1b4c00 23886
15eacb9b
YK
23887 }
23888 break;
bf7910c6 23889#endif
10dc65db
LA
23890 default: /* Invalid */
23891 MIPS_INVAL("special3_r6");
9c708c7f 23892 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23893 break;
23894 }
23895}
23896
23897static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23898{
fac5a073 23899 int rs, rt, rd;
099e5b4d 23900 uint32_t op1, op2;
099e5b4d
LA
23901
23902 rs = (ctx->opcode >> 21) & 0x1f;
23903 rt = (ctx->opcode >> 16) & 0x1f;
23904 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
23905
23906 op1 = MASK_SPECIAL3(ctx->opcode);
23907 switch (op1) {
c2e19f3c
AM
23908 case OPC_DIV_G_2E:
23909 case OPC_DIVU_G_2E:
23910 case OPC_MOD_G_2E:
23911 case OPC_MODU_G_2E:
23912 case OPC_MULT_G_2E:
23913 case OPC_MULTU_G_2E:
099e5b4d
LA
23914 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23915 * the same mask and op1. */
908f6be1 23916 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 23917 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 23918 switch (op2) {
099e5b4d
LA
23919 case OPC_ADDUH_QB:
23920 case OPC_ADDUH_R_QB:
23921 case OPC_ADDQH_PH:
23922 case OPC_ADDQH_R_PH:
23923 case OPC_ADDQH_W:
23924 case OPC_ADDQH_R_W:
23925 case OPC_SUBUH_QB:
23926 case OPC_SUBUH_R_QB:
23927 case OPC_SUBQH_PH:
23928 case OPC_SUBQH_R_PH:
23929 case OPC_SUBQH_W:
23930 case OPC_SUBQH_R_W:
461c08df
JL
23931 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23932 break;
099e5b4d
LA
23933 case OPC_MUL_PH:
23934 case OPC_MUL_S_PH:
23935 case OPC_MULQ_S_W:
23936 case OPC_MULQ_RS_W:
23937 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 23938 break;
461c08df 23939 default:
099e5b4d 23940 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 23941 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
23942 break;
23943 }
099e5b4d
LA
23944 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23945 gen_loongson_integer(ctx, op1, rd, rs, rt);
23946 } else {
9c708c7f 23947 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23948 }
23949 break;
23950 case OPC_LX_DSP:
23951 op2 = MASK_LX(ctx->opcode);
23952 switch (op2) {
23953#if defined(TARGET_MIPS64)
23954 case OPC_LDX:
23955#endif
23956 case OPC_LBUX:
23957 case OPC_LHX:
23958 case OPC_LWX:
23959 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23960 break;
23961 default: /* Invalid */
23962 MIPS_INVAL("MASK LX");
9c708c7f 23963 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23964 break;
23965 }
23966 break;
23967 case OPC_ABSQ_S_PH_DSP:
23968 op2 = MASK_ABSQ_S_PH(ctx->opcode);
23969 switch (op2) {
23970 case OPC_ABSQ_S_QB:
23971 case OPC_ABSQ_S_PH:
23972 case OPC_ABSQ_S_W:
23973 case OPC_PRECEQ_W_PHL:
23974 case OPC_PRECEQ_W_PHR:
23975 case OPC_PRECEQU_PH_QBL:
23976 case OPC_PRECEQU_PH_QBR:
23977 case OPC_PRECEQU_PH_QBLA:
23978 case OPC_PRECEQU_PH_QBRA:
23979 case OPC_PRECEU_PH_QBL:
23980 case OPC_PRECEU_PH_QBR:
23981 case OPC_PRECEU_PH_QBLA:
23982 case OPC_PRECEU_PH_QBRA:
23983 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23984 break;
23985 case OPC_BITREV:
23986 case OPC_REPL_QB:
23987 case OPC_REPLV_QB:
23988 case OPC_REPL_PH:
23989 case OPC_REPLV_PH:
23990 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23991 break;
23992 default:
23993 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 23994 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23995 break;
23996 }
23997 break;
23998 case OPC_ADDU_QB_DSP:
23999 op2 = MASK_ADDU_QB(ctx->opcode);
24000 switch (op2) {
24001 case OPC_ADDQ_PH:
24002 case OPC_ADDQ_S_PH:
24003 case OPC_ADDQ_S_W:
24004 case OPC_ADDU_QB:
24005 case OPC_ADDU_S_QB:
24006 case OPC_ADDU_PH:
24007 case OPC_ADDU_S_PH:
24008 case OPC_SUBQ_PH:
24009 case OPC_SUBQ_S_PH:
24010 case OPC_SUBQ_S_W:
24011 case OPC_SUBU_QB:
24012 case OPC_SUBU_S_QB:
24013 case OPC_SUBU_PH:
24014 case OPC_SUBU_S_PH:
24015 case OPC_ADDSC:
24016 case OPC_ADDWC:
24017 case OPC_MODSUB:
24018 case OPC_RADDU_W_QB:
24019 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24020 break;
24021 case OPC_MULEU_S_PH_QBL:
24022 case OPC_MULEU_S_PH_QBR:
24023 case OPC_MULQ_RS_PH:
24024 case OPC_MULEQ_S_W_PHL:
24025 case OPC_MULEQ_S_W_PHR:
24026 case OPC_MULQ_S_PH:
24027 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24028 break;
24029 default: /* Invalid */
24030 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 24031 generate_exception_end(ctx, EXCP_RI);
461c08df 24032 break;
461c08df 24033
099e5b4d
LA
24034 }
24035 break;
24036 case OPC_CMPU_EQ_QB_DSP:
24037 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
24038 switch (op2) {
24039 case OPC_PRECR_SRA_PH_W:
24040 case OPC_PRECR_SRA_R_PH_W:
24041 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 24042 break;
099e5b4d
LA
24043 case OPC_PRECR_QB_PH:
24044 case OPC_PRECRQ_QB_PH:
24045 case OPC_PRECRQ_PH_W:
24046 case OPC_PRECRQ_RS_PH_W:
24047 case OPC_PRECRQU_S_QB_PH:
24048 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 24049 break;
099e5b4d
LA
24050 case OPC_CMPU_EQ_QB:
24051 case OPC_CMPU_LT_QB:
24052 case OPC_CMPU_LE_QB:
24053 case OPC_CMP_EQ_PH:
24054 case OPC_CMP_LT_PH:
24055 case OPC_CMP_LE_PH:
24056 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 24057 break;
099e5b4d
LA
24058 case OPC_CMPGU_EQ_QB:
24059 case OPC_CMPGU_LT_QB:
24060 case OPC_CMPGU_LE_QB:
24061 case OPC_CMPGDU_EQ_QB:
24062 case OPC_CMPGDU_LT_QB:
24063 case OPC_CMPGDU_LE_QB:
24064 case OPC_PICK_QB:
24065 case OPC_PICK_PH:
24066 case OPC_PACKRL_PH:
24067 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24068 break;
24069 default: /* Invalid */
24070 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 24071 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
24072 break;
24073 }
24074 break;
24075 case OPC_SHLL_QB_DSP:
24076 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24077 break;
24078 case OPC_DPA_W_PH_DSP:
24079 op2 = MASK_DPA_W_PH(ctx->opcode);
24080 switch (op2) {
24081 case OPC_DPAU_H_QBL:
24082 case OPC_DPAU_H_QBR:
24083 case OPC_DPSU_H_QBL:
24084 case OPC_DPSU_H_QBR:
24085 case OPC_DPA_W_PH:
24086 case OPC_DPAX_W_PH:
24087 case OPC_DPAQ_S_W_PH:
24088 case OPC_DPAQX_S_W_PH:
24089 case OPC_DPAQX_SA_W_PH:
24090 case OPC_DPS_W_PH:
24091 case OPC_DPSX_W_PH:
24092 case OPC_DPSQ_S_W_PH:
24093 case OPC_DPSQX_S_W_PH:
24094 case OPC_DPSQX_SA_W_PH:
24095 case OPC_MULSAQ_S_W_PH:
24096 case OPC_DPAQ_SA_L_W:
24097 case OPC_DPSQ_SA_L_W:
24098 case OPC_MAQ_S_W_PHL:
24099 case OPC_MAQ_S_W_PHR:
24100 case OPC_MAQ_SA_W_PHL:
24101 case OPC_MAQ_SA_W_PHR:
24102 case OPC_MULSA_W_PH:
24103 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24104 break;
24105 default: /* Invalid */
24106 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 24107 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
24108 break;
24109 }
24110 break;
24111 case OPC_INSV_DSP:
24112 op2 = MASK_INSV(ctx->opcode);
24113 switch (op2) {
24114 case OPC_INSV:
24115 check_dsp(ctx);
24116 {
24117 TCGv t0, t1;
24118
24119 if (rt == 0) {
099e5b4d
LA
24120 break;
24121 }
24122
24123 t0 = tcg_temp_new();
24124 t1 = tcg_temp_new();
24125
24126 gen_load_gpr(t0, rt);
24127 gen_load_gpr(t1, rs);
24128
24129 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
24130
24131 tcg_temp_free(t0);
24132 tcg_temp_free(t1);
a22260ae
JL
24133 break;
24134 }
099e5b4d
LA
24135 default: /* Invalid */
24136 MIPS_INVAL("MASK INSV");
9c708c7f 24137 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
24138 break;
24139 }
24140 break;
24141 case OPC_APPEND_DSP:
24142 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24143 break;
24144 case OPC_EXTR_W_DSP:
24145 op2 = MASK_EXTR_W(ctx->opcode);
24146 switch (op2) {
24147 case OPC_EXTR_W:
24148 case OPC_EXTR_R_W:
24149 case OPC_EXTR_RS_W:
24150 case OPC_EXTR_S_H:
24151 case OPC_EXTRV_S_H:
24152 case OPC_EXTRV_W:
24153 case OPC_EXTRV_R_W:
24154 case OPC_EXTRV_RS_W:
24155 case OPC_EXTP:
24156 case OPC_EXTPV:
24157 case OPC_EXTPDP:
24158 case OPC_EXTPDPV:
24159 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24160 break;
24161 case OPC_RDDSP:
24162 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
24163 break;
24164 case OPC_SHILO:
24165 case OPC_SHILOV:
24166 case OPC_MTHLIP:
24167 case OPC_WRDSP:
24168 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24169 break;
24170 default: /* Invalid */
24171 MIPS_INVAL("MASK EXTR.W");
9c708c7f 24172 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
24173 break;
24174 }
24175 break;
099e5b4d 24176#if defined(TARGET_MIPS64)
c2e19f3c
AM
24177 case OPC_DDIV_G_2E:
24178 case OPC_DDIVU_G_2E:
24179 case OPC_DMULT_G_2E:
24180 case OPC_DMULTU_G_2E:
24181 case OPC_DMOD_G_2E:
24182 case OPC_DMODU_G_2E:
fac5a073
LA
24183 check_insn(ctx, INSN_LOONGSON2E);
24184 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 24185 break;
099e5b4d
LA
24186 case OPC_ABSQ_S_QH_DSP:
24187 op2 = MASK_ABSQ_S_QH(ctx->opcode);
24188 switch (op2) {
24189 case OPC_PRECEQ_L_PWL:
24190 case OPC_PRECEQ_L_PWR:
24191 case OPC_PRECEQ_PW_QHL:
24192 case OPC_PRECEQ_PW_QHR:
24193 case OPC_PRECEQ_PW_QHLA:
24194 case OPC_PRECEQ_PW_QHRA:
24195 case OPC_PRECEQU_QH_OBL:
24196 case OPC_PRECEQU_QH_OBR:
24197 case OPC_PRECEQU_QH_OBLA:
24198 case OPC_PRECEQU_QH_OBRA:
24199 case OPC_PRECEU_QH_OBL:
24200 case OPC_PRECEU_QH_OBR:
24201 case OPC_PRECEU_QH_OBLA:
24202 case OPC_PRECEU_QH_OBRA:
24203 case OPC_ABSQ_S_OB:
24204 case OPC_ABSQ_S_PW:
24205 case OPC_ABSQ_S_QH:
24206 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24207 break;
24208 case OPC_REPL_OB:
24209 case OPC_REPL_PW:
24210 case OPC_REPL_QH:
24211 case OPC_REPLV_OB:
24212 case OPC_REPLV_PW:
24213 case OPC_REPLV_QH:
24214 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
24215 break;
24216 default: /* Invalid */
24217 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 24218 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
24219 break;
24220 }
24221 break;
24222 case OPC_ADDU_OB_DSP:
24223 op2 = MASK_ADDU_OB(ctx->opcode);
24224 switch (op2) {
24225 case OPC_RADDU_L_OB:
24226 case OPC_SUBQ_PW:
24227 case OPC_SUBQ_S_PW:
24228 case OPC_SUBQ_QH:
24229 case OPC_SUBQ_S_QH:
24230 case OPC_SUBU_OB:
24231 case OPC_SUBU_S_OB:
24232 case OPC_SUBU_QH:
24233 case OPC_SUBU_S_QH:
24234 case OPC_SUBUH_OB:
24235 case OPC_SUBUH_R_OB:
24236 case OPC_ADDQ_PW:
24237 case OPC_ADDQ_S_PW:
24238 case OPC_ADDQ_QH:
24239 case OPC_ADDQ_S_QH:
24240 case OPC_ADDU_OB:
24241 case OPC_ADDU_S_OB:
24242 case OPC_ADDU_QH:
24243 case OPC_ADDU_S_QH:
24244 case OPC_ADDUH_OB:
24245 case OPC_ADDUH_R_OB:
24246 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 24247 break;
099e5b4d
LA
24248 case OPC_MULEQ_S_PW_QHL:
24249 case OPC_MULEQ_S_PW_QHR:
24250 case OPC_MULEU_S_QH_OBL:
24251 case OPC_MULEU_S_QH_OBR:
24252 case OPC_MULQ_RS_QH:
24253 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 24254 break;
099e5b4d
LA
24255 default: /* Invalid */
24256 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 24257 generate_exception_end(ctx, EXCP_RI);
26690560 24258 break;
099e5b4d
LA
24259 }
24260 break;
24261 case OPC_CMPU_EQ_OB_DSP:
24262 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
24263 switch (op2) {
24264 case OPC_PRECR_SRA_QH_PW:
24265 case OPC_PRECR_SRA_R_QH_PW:
24266 /* Return value is rt. */
24267 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 24268 break;
099e5b4d
LA
24269 case OPC_PRECR_OB_QH:
24270 case OPC_PRECRQ_OB_QH:
24271 case OPC_PRECRQ_PW_L:
24272 case OPC_PRECRQ_QH_PW:
24273 case OPC_PRECRQ_RS_QH_PW:
24274 case OPC_PRECRQU_S_OB_QH:
24275 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 24276 break;
099e5b4d
LA
24277 case OPC_CMPU_EQ_OB:
24278 case OPC_CMPU_LT_OB:
24279 case OPC_CMPU_LE_OB:
24280 case OPC_CMP_EQ_QH:
24281 case OPC_CMP_LT_QH:
24282 case OPC_CMP_LE_QH:
24283 case OPC_CMP_EQ_PW:
24284 case OPC_CMP_LT_PW:
24285 case OPC_CMP_LE_PW:
24286 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 24287 break;
099e5b4d
LA
24288 case OPC_CMPGDU_EQ_OB:
24289 case OPC_CMPGDU_LT_OB:
24290 case OPC_CMPGDU_LE_OB:
24291 case OPC_CMPGU_EQ_OB:
24292 case OPC_CMPGU_LT_OB:
24293 case OPC_CMPGU_LE_OB:
24294 case OPC_PACKRL_PW:
24295 case OPC_PICK_OB:
24296 case OPC_PICK_PW:
24297 case OPC_PICK_QH:
24298 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 24299 break;
099e5b4d
LA
24300 default: /* Invalid */
24301 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 24302 generate_exception_end(ctx, EXCP_RI);
161f85e6 24303 break;
099e5b4d
LA
24304 }
24305 break;
24306 case OPC_DAPPEND_DSP:
24307 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24308 break;
24309 case OPC_DEXTR_W_DSP:
24310 op2 = MASK_DEXTR_W(ctx->opcode);
24311 switch (op2) {
24312 case OPC_DEXTP:
24313 case OPC_DEXTPDP:
24314 case OPC_DEXTPDPV:
24315 case OPC_DEXTPV:
24316 case OPC_DEXTR_L:
24317 case OPC_DEXTR_R_L:
24318 case OPC_DEXTR_RS_L:
24319 case OPC_DEXTR_W:
24320 case OPC_DEXTR_R_W:
24321 case OPC_DEXTR_RS_W:
24322 case OPC_DEXTR_S_H:
24323 case OPC_DEXTRV_L:
24324 case OPC_DEXTRV_R_L:
24325 case OPC_DEXTRV_RS_L:
24326 case OPC_DEXTRV_S_H:
24327 case OPC_DEXTRV_W:
24328 case OPC_DEXTRV_R_W:
24329 case OPC_DEXTRV_RS_W:
24330 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 24331 break;
099e5b4d
LA
24332 case OPC_DMTHLIP:
24333 case OPC_DSHILO:
24334 case OPC_DSHILOV:
24335 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 24336 break;
099e5b4d
LA
24337 default: /* Invalid */
24338 MIPS_INVAL("MASK EXTR.W");
9c708c7f 24339 generate_exception_end(ctx, EXCP_RI);
461c08df 24340 break;
099e5b4d
LA
24341 }
24342 break;
24343 case OPC_DPAQ_W_QH_DSP:
24344 op2 = MASK_DPAQ_W_QH(ctx->opcode);
24345 switch (op2) {
24346 case OPC_DPAU_H_OBL:
24347 case OPC_DPAU_H_OBR:
24348 case OPC_DPSU_H_OBL:
24349 case OPC_DPSU_H_OBR:
24350 case OPC_DPA_W_QH:
24351 case OPC_DPAQ_S_W_QH:
24352 case OPC_DPS_W_QH:
24353 case OPC_DPSQ_S_W_QH:
24354 case OPC_MULSAQ_S_W_QH:
24355 case OPC_DPAQ_SA_L_PW:
24356 case OPC_DPSQ_SA_L_PW:
24357 case OPC_MULSAQ_S_L_PW:
24358 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24359 break;
24360 case OPC_MAQ_S_W_QHLL:
24361 case OPC_MAQ_S_W_QHLR:
24362 case OPC_MAQ_S_W_QHRL:
24363 case OPC_MAQ_S_W_QHRR:
24364 case OPC_MAQ_SA_W_QHLL:
24365 case OPC_MAQ_SA_W_QHLR:
24366 case OPC_MAQ_SA_W_QHRL:
24367 case OPC_MAQ_SA_W_QHRR:
24368 case OPC_MAQ_S_L_PWL:
24369 case OPC_MAQ_S_L_PWR:
24370 case OPC_DMADD:
24371 case OPC_DMADDU:
24372 case OPC_DMSUB:
24373 case OPC_DMSUBU:
24374 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 24375 break;
099e5b4d
LA
24376 default: /* Invalid */
24377 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 24378 generate_exception_end(ctx, EXCP_RI);
b53371ed 24379 break;
099e5b4d
LA
24380 }
24381 break;
24382 case OPC_DINSV_DSP:
24383 op2 = MASK_INSV(ctx->opcode);
24384 switch (op2) {
24385 case OPC_DINSV:
24386 {
24387 TCGv t0, t1;
24388
24389 if (rt == 0) {
a22260ae
JL
24390 break;
24391 }
099e5b4d 24392 check_dsp(ctx);
1cb6686c 24393
099e5b4d
LA
24394 t0 = tcg_temp_new();
24395 t1 = tcg_temp_new();
1cb6686c 24396
099e5b4d
LA
24397 gen_load_gpr(t0, rt);
24398 gen_load_gpr(t1, rs);
1cb6686c 24399
099e5b4d 24400 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 24401
099e5b4d
LA
24402 tcg_temp_free(t0);
24403 tcg_temp_free(t1);
77c5fa8b 24404 break;
099e5b4d 24405 }
7a387fff 24406 default: /* Invalid */
099e5b4d 24407 MIPS_INVAL("MASK DINSV");
9c708c7f 24408 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
24409 break;
24410 }
24411 break;
099e5b4d
LA
24412 case OPC_SHLL_OB_DSP:
24413 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24414 break;
24415#endif
fac5a073
LA
24416 default: /* Invalid */
24417 MIPS_INVAL("special3_legacy");
9c708c7f 24418 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
24419 break;
24420 }
24421}
24422
24423static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
24424{
24425 int rs, rt, rd, sa;
24426 uint32_t op1, op2;
76964147 24427 int16_t imm;
fac5a073
LA
24428
24429 rs = (ctx->opcode >> 21) & 0x1f;
24430 rt = (ctx->opcode >> 16) & 0x1f;
24431 rd = (ctx->opcode >> 11) & 0x1f;
24432 sa = (ctx->opcode >> 6) & 0x1f;
76964147 24433 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
24434
24435 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
24436
24437 /*
24438 * EVA loads and stores overlap Loongson 2E instructions decoded by
24439 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24440 * EVA is absent.
24441 */
24442 if (ctx->eva) {
24443 switch (op1) {
c2e19f3c
AM
24444 case OPC_LWLE:
24445 case OPC_LWRE:
76964147
JH
24446 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24447 /* fall through */
c2e19f3c
AM
24448 case OPC_LBUE:
24449 case OPC_LHUE:
24450 case OPC_LBE:
24451 case OPC_LHE:
24452 case OPC_LLE:
24453 case OPC_LWE:
76964147
JH
24454 check_cp0_enabled(ctx);
24455 gen_ld(ctx, op1, rt, rs, imm);
24456 return;
c2e19f3c
AM
24457 case OPC_SWLE:
24458 case OPC_SWRE:
76964147
JH
24459 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24460 /* fall through */
c2e19f3c
AM
24461 case OPC_SBE:
24462 case OPC_SHE:
76964147
JH
24463 case OPC_SWE:
24464 check_cp0_enabled(ctx);
24465 gen_st(ctx, op1, rt, rs, imm);
24466 return;
24467 case OPC_SCE:
24468 check_cp0_enabled(ctx);
24469 gen_st_cond(ctx, op1, rt, rs, imm);
24470 return;
24471 case OPC_CACHEE:
24472 check_cp0_enabled(ctx);
24473 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24474 gen_cache_operation(ctx, rt, rs, imm);
24475 }
24476 /* Treat as NOP. */
24477 return;
24478 case OPC_PREFE:
24479 check_cp0_enabled(ctx);
24480 /* Treat as NOP. */
24481 return;
24482 }
24483 }
24484
fac5a073
LA
24485 switch (op1) {
24486 case OPC_EXT:
24487 case OPC_INS:
24488 check_insn(ctx, ISA_MIPS32R2);
24489 gen_bitops(ctx, op1, rt, rs, sa, rd);
24490 break;
24491 case OPC_BSHFL:
fac5a073 24492 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 24493 switch (op2) {
c2e19f3c
AM
24494 case OPC_ALIGN:
24495 case OPC_ALIGN_END:
15eacb9b
YK
24496 case OPC_BITSWAP:
24497 check_insn(ctx, ISA_MIPS32R6);
24498 decode_opc_special3_r6(env, ctx);
24499 break;
24500 default:
24501 check_insn(ctx, ISA_MIPS32R2);
24502 gen_bshfl(ctx, op2, rt, rd);
24503 break;
24504 }
fac5a073
LA
24505 break;
24506#if defined(TARGET_MIPS64)
c2e19f3c
AM
24507 case OPC_DEXTM:
24508 case OPC_DEXTU:
24509 case OPC_DEXT:
24510 case OPC_DINSM:
24511 case OPC_DINSU:
24512 case OPC_DINS:
fac5a073
LA
24513 check_insn(ctx, ISA_MIPS64R2);
24514 check_mips_64(ctx);
24515 gen_bitops(ctx, op1, rt, rs, sa, rd);
24516 break;
24517 case OPC_DBSHFL:
fac5a073 24518 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 24519 switch (op2) {
c2e19f3c
AM
24520 case OPC_DALIGN:
24521 case OPC_DALIGN_END:
15eacb9b
YK
24522 case OPC_DBITSWAP:
24523 check_insn(ctx, ISA_MIPS32R6);
24524 decode_opc_special3_r6(env, ctx);
24525 break;
24526 default:
24527 check_insn(ctx, ISA_MIPS64R2);
24528 check_mips_64(ctx);
24529 op2 = MASK_DBSHFL(ctx->opcode);
24530 gen_bshfl(ctx, op2, rt, rd);
24531 break;
24532 }
fac5a073
LA
24533 break;
24534#endif
24535 case OPC_RDHWR:
b00c7218 24536 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
24537 break;
24538 case OPC_FORK:
9affc1c5 24539 check_mt(ctx);
fac5a073
LA
24540 {
24541 TCGv t0 = tcg_temp_new();
24542 TCGv t1 = tcg_temp_new();
24543
24544 gen_load_gpr(t0, rt);
24545 gen_load_gpr(t1, rs);
24546 gen_helper_fork(t0, t1);
24547 tcg_temp_free(t0);
24548 tcg_temp_free(t1);
24549 }
24550 break;
24551 case OPC_YIELD:
9affc1c5 24552 check_mt(ctx);
fac5a073
LA
24553 {
24554 TCGv t0 = tcg_temp_new();
24555
fac5a073
LA
24556 gen_load_gpr(t0, rs);
24557 gen_helper_yield(t0, cpu_env, t0);
24558 gen_store_gpr(t0, rd);
24559 tcg_temp_free(t0);
24560 }
24561 break;
10dc65db
LA
24562 default:
24563 if (ctx->insn_flags & ISA_MIPS32R6) {
24564 decode_opc_special3_r6(env, ctx);
24565 } else {
24566 decode_opc_special3_legacy(env, ctx);
24567 }
099e5b4d
LA
24568 }
24569}
24570
863f264d
YK
24571/* MIPS SIMD Architecture (MSA) */
24572static inline int check_msa_access(DisasContext *ctx)
24573{
24574 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24575 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 24576 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
24577 return 0;
24578 }
24579
24580 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24581 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 24582 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
24583 return 0;
24584 } else {
9c708c7f 24585 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
24586 return 0;
24587 }
24588 }
24589 return 1;
24590}
24591
5692c6e1
YK
24592static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24593{
24594 /* generates tcg ops to check if any element is 0 */
24595 /* Note this function only works with MSA_WRLEN = 128 */
24596 uint64_t eval_zero_or_big = 0;
24597 uint64_t eval_big = 0;
24598 TCGv_i64 t0 = tcg_temp_new_i64();
24599 TCGv_i64 t1 = tcg_temp_new_i64();
24600 switch (df) {
24601 case DF_BYTE:
24602 eval_zero_or_big = 0x0101010101010101ULL;
24603 eval_big = 0x8080808080808080ULL;
24604 break;
24605 case DF_HALF:
24606 eval_zero_or_big = 0x0001000100010001ULL;
24607 eval_big = 0x8000800080008000ULL;
24608 break;
24609 case DF_WORD:
24610 eval_zero_or_big = 0x0000000100000001ULL;
24611 eval_big = 0x8000000080000000ULL;
24612 break;
24613 case DF_DOUBLE:
24614 eval_zero_or_big = 0x0000000000000001ULL;
24615 eval_big = 0x8000000000000000ULL;
24616 break;
24617 }
24618 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24619 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24620 tcg_gen_andi_i64(t0, t0, eval_big);
24621 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24622 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24623 tcg_gen_andi_i64(t1, t1, eval_big);
24624 tcg_gen_or_i64(t0, t0, t1);
24625 /* if all bits are zero then all elements are not zero */
24626 /* if some bit is non-zero then some element is zero */
24627 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24628 tcg_gen_trunc_i64_tl(tresult, t0);
24629 tcg_temp_free_i64(t0);
24630 tcg_temp_free_i64(t1);
24631}
24632
24633static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24634{
24635 uint8_t df = (ctx->opcode >> 21) & 0x3;
24636 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24637 int64_t s16 = (int16_t)ctx->opcode;
24638
24639 check_msa_access(ctx);
24640
075a1fe7 24641 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 24642 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
24643 return;
24644 }
24645 switch (op1) {
24646 case OPC_BZ_V:
24647 case OPC_BNZ_V:
24648 {
24649 TCGv_i64 t0 = tcg_temp_new_i64();
24650 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24651 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24652 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24653 tcg_gen_trunc_i64_tl(bcond, t0);
24654 tcg_temp_free_i64(t0);
24655 }
24656 break;
24657 case OPC_BZ_B:
24658 case OPC_BZ_H:
24659 case OPC_BZ_W:
24660 case OPC_BZ_D:
24661 gen_check_zero_element(bcond, df, wt);
24662 break;
24663 case OPC_BNZ_B:
24664 case OPC_BNZ_H:
24665 case OPC_BNZ_W:
24666 case OPC_BNZ_D:
24667 gen_check_zero_element(bcond, df, wt);
24668 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24669 break;
24670 }
24671
eeb3bba8 24672 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
24673
24674 ctx->hflags |= MIPS_HFLAG_BC;
24675 ctx->hflags |= MIPS_HFLAG_BDS32;
24676}
24677
4c789546
YK
24678static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24679{
24680#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24681 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24682 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24683 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24684
24685 TCGv_i32 twd = tcg_const_i32(wd);
24686 TCGv_i32 tws = tcg_const_i32(ws);
24687 TCGv_i32 ti8 = tcg_const_i32(i8);
24688
24689 switch (MASK_MSA_I8(ctx->opcode)) {
24690 case OPC_ANDI_B:
24691 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24692 break;
24693 case OPC_ORI_B:
24694 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24695 break;
24696 case OPC_NORI_B:
24697 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24698 break;
24699 case OPC_XORI_B:
24700 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24701 break;
24702 case OPC_BMNZI_B:
24703 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24704 break;
24705 case OPC_BMZI_B:
24706 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24707 break;
24708 case OPC_BSELI_B:
24709 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24710 break;
24711 case OPC_SHF_B:
24712 case OPC_SHF_H:
24713 case OPC_SHF_W:
24714 {
24715 uint8_t df = (ctx->opcode >> 24) & 0x3;
24716 if (df == DF_DOUBLE) {
9c708c7f 24717 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
24718 } else {
24719 TCGv_i32 tdf = tcg_const_i32(df);
24720 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24721 tcg_temp_free_i32(tdf);
24722 }
24723 }
24724 break;
24725 default:
24726 MIPS_INVAL("MSA instruction");
9c708c7f 24727 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
24728 break;
24729 }
24730
24731 tcg_temp_free_i32(twd);
24732 tcg_temp_free_i32(tws);
24733 tcg_temp_free_i32(ti8);
24734}
24735
80e71591
YK
24736static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24737{
24738#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24739 uint8_t df = (ctx->opcode >> 21) & 0x3;
24740 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24741 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24742 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24743 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24744
24745 TCGv_i32 tdf = tcg_const_i32(df);
24746 TCGv_i32 twd = tcg_const_i32(wd);
24747 TCGv_i32 tws = tcg_const_i32(ws);
24748 TCGv_i32 timm = tcg_temp_new_i32();
24749 tcg_gen_movi_i32(timm, u5);
24750
24751 switch (MASK_MSA_I5(ctx->opcode)) {
24752 case OPC_ADDVI_df:
24753 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24754 break;
24755 case OPC_SUBVI_df:
24756 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24757 break;
24758 case OPC_MAXI_S_df:
24759 tcg_gen_movi_i32(timm, s5);
24760 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24761 break;
24762 case OPC_MAXI_U_df:
24763 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24764 break;
24765 case OPC_MINI_S_df:
24766 tcg_gen_movi_i32(timm, s5);
24767 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24768 break;
24769 case OPC_MINI_U_df:
24770 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24771 break;
24772 case OPC_CEQI_df:
24773 tcg_gen_movi_i32(timm, s5);
24774 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24775 break;
24776 case OPC_CLTI_S_df:
24777 tcg_gen_movi_i32(timm, s5);
24778 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24779 break;
24780 case OPC_CLTI_U_df:
24781 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24782 break;
24783 case OPC_CLEI_S_df:
24784 tcg_gen_movi_i32(timm, s5);
24785 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24786 break;
24787 case OPC_CLEI_U_df:
24788 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24789 break;
24790 case OPC_LDI_df:
24791 {
24792 int32_t s10 = sextract32(ctx->opcode, 11, 10);
24793 tcg_gen_movi_i32(timm, s10);
24794 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24795 }
24796 break;
24797 default:
24798 MIPS_INVAL("MSA instruction");
9c708c7f 24799 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
24800 break;
24801 }
24802
24803 tcg_temp_free_i32(tdf);
24804 tcg_temp_free_i32(twd);
24805 tcg_temp_free_i32(tws);
24806 tcg_temp_free_i32(timm);
24807}
24808
d4cf28de
YK
24809static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24810{
24811#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24812 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24813 uint32_t df = 0, m = 0;
24814 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24815 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24816
24817 TCGv_i32 tdf;
24818 TCGv_i32 tm;
24819 TCGv_i32 twd;
24820 TCGv_i32 tws;
24821
24822 if ((dfm & 0x40) == 0x00) {
24823 m = dfm & 0x3f;
24824 df = DF_DOUBLE;
24825 } else if ((dfm & 0x60) == 0x40) {
24826 m = dfm & 0x1f;
24827 df = DF_WORD;
24828 } else if ((dfm & 0x70) == 0x60) {
24829 m = dfm & 0x0f;
24830 df = DF_HALF;
24831 } else if ((dfm & 0x78) == 0x70) {
24832 m = dfm & 0x7;
24833 df = DF_BYTE;
24834 } else {
9c708c7f 24835 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
24836 return;
24837 }
24838
24839 tdf = tcg_const_i32(df);
24840 tm = tcg_const_i32(m);
24841 twd = tcg_const_i32(wd);
24842 tws = tcg_const_i32(ws);
24843
24844 switch (MASK_MSA_BIT(ctx->opcode)) {
24845 case OPC_SLLI_df:
24846 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24847 break;
24848 case OPC_SRAI_df:
24849 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24850 break;
24851 case OPC_SRLI_df:
24852 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24853 break;
24854 case OPC_BCLRI_df:
24855 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24856 break;
24857 case OPC_BSETI_df:
24858 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24859 break;
24860 case OPC_BNEGI_df:
24861 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24862 break;
24863 case OPC_BINSLI_df:
24864 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24865 break;
24866 case OPC_BINSRI_df:
24867 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24868 break;
24869 case OPC_SAT_S_df:
24870 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24871 break;
24872 case OPC_SAT_U_df:
24873 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24874 break;
24875 case OPC_SRARI_df:
24876 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24877 break;
24878 case OPC_SRLRI_df:
24879 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24880 break;
24881 default:
24882 MIPS_INVAL("MSA instruction");
9c708c7f 24883 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
24884 break;
24885 }
24886
24887 tcg_temp_free_i32(tdf);
24888 tcg_temp_free_i32(tm);
24889 tcg_temp_free_i32(twd);
24890 tcg_temp_free_i32(tws);
24891}
24892
28f99f08
YK
24893static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24894{
24895#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24896 uint8_t df = (ctx->opcode >> 21) & 0x3;
24897 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24898 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24899 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24900
24901 TCGv_i32 tdf = tcg_const_i32(df);
24902 TCGv_i32 twd = tcg_const_i32(wd);
24903 TCGv_i32 tws = tcg_const_i32(ws);
24904 TCGv_i32 twt = tcg_const_i32(wt);
24905
24906 switch (MASK_MSA_3R(ctx->opcode)) {
24907 case OPC_SLL_df:
24908 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24909 break;
24910 case OPC_ADDV_df:
24911 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24912 break;
24913 case OPC_CEQ_df:
24914 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24915 break;
24916 case OPC_ADD_A_df:
24917 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24918 break;
24919 case OPC_SUBS_S_df:
24920 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24921 break;
24922 case OPC_MULV_df:
24923 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24924 break;
24925 case OPC_SLD_df:
24926 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24927 break;
24928 case OPC_VSHF_df:
24929 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24930 break;
24931 case OPC_SRA_df:
24932 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24933 break;
24934 case OPC_SUBV_df:
24935 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24936 break;
24937 case OPC_ADDS_A_df:
24938 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24939 break;
24940 case OPC_SUBS_U_df:
24941 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24942 break;
24943 case OPC_MADDV_df:
24944 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24945 break;
24946 case OPC_SPLAT_df:
24947 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24948 break;
24949 case OPC_SRAR_df:
24950 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24951 break;
24952 case OPC_SRL_df:
24953 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24954 break;
24955 case OPC_MAX_S_df:
24956 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24957 break;
24958 case OPC_CLT_S_df:
24959 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24960 break;
24961 case OPC_ADDS_S_df:
24962 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24963 break;
24964 case OPC_SUBSUS_U_df:
24965 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24966 break;
24967 case OPC_MSUBV_df:
24968 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24969 break;
24970 case OPC_PCKEV_df:
24971 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24972 break;
24973 case OPC_SRLR_df:
24974 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24975 break;
24976 case OPC_BCLR_df:
24977 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24978 break;
24979 case OPC_MAX_U_df:
24980 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24981 break;
24982 case OPC_CLT_U_df:
24983 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24984 break;
24985 case OPC_ADDS_U_df:
24986 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24987 break;
24988 case OPC_SUBSUU_S_df:
24989 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24990 break;
24991 case OPC_PCKOD_df:
24992 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24993 break;
24994 case OPC_BSET_df:
24995 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24996 break;
24997 case OPC_MIN_S_df:
24998 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24999 break;
25000 case OPC_CLE_S_df:
25001 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
25002 break;
25003 case OPC_AVE_S_df:
25004 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
25005 break;
25006 case OPC_ASUB_S_df:
25007 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
25008 break;
25009 case OPC_DIV_S_df:
25010 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
25011 break;
25012 case OPC_ILVL_df:
25013 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
25014 break;
25015 case OPC_BNEG_df:
25016 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
25017 break;
25018 case OPC_MIN_U_df:
25019 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
25020 break;
25021 case OPC_CLE_U_df:
25022 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
25023 break;
25024 case OPC_AVE_U_df:
25025 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
25026 break;
25027 case OPC_ASUB_U_df:
25028 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
25029 break;
25030 case OPC_DIV_U_df:
25031 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
25032 break;
25033 case OPC_ILVR_df:
25034 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
25035 break;
25036 case OPC_BINSL_df:
25037 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
25038 break;
25039 case OPC_MAX_A_df:
25040 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
25041 break;
25042 case OPC_AVER_S_df:
25043 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
25044 break;
25045 case OPC_MOD_S_df:
25046 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
25047 break;
25048 case OPC_ILVEV_df:
25049 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
25050 break;
25051 case OPC_BINSR_df:
25052 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
25053 break;
25054 case OPC_MIN_A_df:
25055 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
25056 break;
25057 case OPC_AVER_U_df:
25058 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
25059 break;
25060 case OPC_MOD_U_df:
25061 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
25062 break;
25063 case OPC_ILVOD_df:
25064 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
25065 break;
25066
25067 case OPC_DOTP_S_df:
25068 case OPC_DOTP_U_df:
25069 case OPC_DPADD_S_df:
25070 case OPC_DPADD_U_df:
25071 case OPC_DPSUB_S_df:
25072 case OPC_HADD_S_df:
25073 case OPC_DPSUB_U_df:
25074 case OPC_HADD_U_df:
25075 case OPC_HSUB_S_df:
25076 case OPC_HSUB_U_df:
25077 if (df == DF_BYTE) {
9c708c7f
PD
25078 generate_exception_end(ctx, EXCP_RI);
25079 break;
28f99f08
YK
25080 }
25081 switch (MASK_MSA_3R(ctx->opcode)) {
25082 case OPC_DOTP_S_df:
25083 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
25084 break;
25085 case OPC_DOTP_U_df:
25086 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
25087 break;
25088 case OPC_DPADD_S_df:
25089 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
25090 break;
25091 case OPC_DPADD_U_df:
25092 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
25093 break;
25094 case OPC_DPSUB_S_df:
25095 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
25096 break;
25097 case OPC_HADD_S_df:
25098 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
25099 break;
25100 case OPC_DPSUB_U_df:
25101 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
25102 break;
25103 case OPC_HADD_U_df:
25104 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
25105 break;
25106 case OPC_HSUB_S_df:
25107 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
25108 break;
25109 case OPC_HSUB_U_df:
25110 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
25111 break;
25112 }
25113 break;
25114 default:
25115 MIPS_INVAL("MSA instruction");
9c708c7f 25116 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
25117 break;
25118 }
25119 tcg_temp_free_i32(twd);
25120 tcg_temp_free_i32(tws);
25121 tcg_temp_free_i32(twt);
25122 tcg_temp_free_i32(tdf);
25123}
25124
1e608ec1
YK
25125static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
25126{
25127#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
25128 uint8_t source = (ctx->opcode >> 11) & 0x1f;
25129 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
25130 TCGv telm = tcg_temp_new();
25131 TCGv_i32 tsr = tcg_const_i32(source);
25132 TCGv_i32 tdt = tcg_const_i32(dest);
25133
25134 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
25135 case OPC_CTCMSA:
25136 gen_load_gpr(telm, source);
25137 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
25138 break;
25139 case OPC_CFCMSA:
25140 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
25141 gen_store_gpr(telm, dest);
25142 break;
25143 case OPC_MOVE_V:
25144 gen_helper_msa_move_v(cpu_env, tdt, tsr);
25145 break;
25146 default:
25147 MIPS_INVAL("MSA instruction");
9c708c7f 25148 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
25149 break;
25150 }
25151
25152 tcg_temp_free(telm);
25153 tcg_temp_free_i32(tdt);
25154 tcg_temp_free_i32(tsr);
25155}
25156
25157static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
25158 uint32_t n)
25159{
25160#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25161 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25162 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25163
25164 TCGv_i32 tws = tcg_const_i32(ws);
25165 TCGv_i32 twd = tcg_const_i32(wd);
25166 TCGv_i32 tn = tcg_const_i32(n);
25167 TCGv_i32 tdf = tcg_const_i32(df);
25168
25169 switch (MASK_MSA_ELM(ctx->opcode)) {
25170 case OPC_SLDI_df:
25171 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
25172 break;
25173 case OPC_SPLATI_df:
25174 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
25175 break;
25176 case OPC_INSVE_df:
25177 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
25178 break;
25179 case OPC_COPY_S_df:
25180 case OPC_COPY_U_df:
25181 case OPC_INSERT_df:
25182#if !defined(TARGET_MIPS64)
25183 /* Double format valid only for MIPS64 */
25184 if (df == DF_DOUBLE) {
9c708c7f 25185 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
25186 break;
25187 }
25188#endif
25189 switch (MASK_MSA_ELM(ctx->opcode)) {
25190 case OPC_COPY_S_df:
cab48881
MD
25191 if (likely(wd != 0)) {
25192 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
25193 }
1e608ec1
YK
25194 break;
25195 case OPC_COPY_U_df:
cab48881
MD
25196 if (likely(wd != 0)) {
25197 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
25198 }
1e608ec1
YK
25199 break;
25200 case OPC_INSERT_df:
25201 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
25202 break;
25203 }
25204 break;
25205 default:
25206 MIPS_INVAL("MSA instruction");
9c708c7f 25207 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
25208 }
25209 tcg_temp_free_i32(twd);
25210 tcg_temp_free_i32(tws);
25211 tcg_temp_free_i32(tn);
25212 tcg_temp_free_i32(tdf);
25213}
25214
25215static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
25216{
25217 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
25218 uint32_t df = 0, n = 0;
25219
25220 if ((dfn & 0x30) == 0x00) {
25221 n = dfn & 0x0f;
25222 df = DF_BYTE;
25223 } else if ((dfn & 0x38) == 0x20) {
25224 n = dfn & 0x07;
25225 df = DF_HALF;
25226 } else if ((dfn & 0x3c) == 0x30) {
25227 n = dfn & 0x03;
25228 df = DF_WORD;
25229 } else if ((dfn & 0x3e) == 0x38) {
25230 n = dfn & 0x01;
25231 df = DF_DOUBLE;
25232 } else if (dfn == 0x3E) {
25233 /* CTCMSA, CFCMSA, MOVE.V */
25234 gen_msa_elm_3e(env, ctx);
25235 return;
25236 } else {
9c708c7f 25237 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
25238 return;
25239 }
25240
25241 gen_msa_elm_df(env, ctx, df, n);
25242}
25243
7d05b9c8
YK
25244static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
25245{
25246#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25247 uint8_t df = (ctx->opcode >> 21) & 0x1;
25248 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25249 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25250 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25251
25252 TCGv_i32 twd = tcg_const_i32(wd);
25253 TCGv_i32 tws = tcg_const_i32(ws);
25254 TCGv_i32 twt = tcg_const_i32(wt);
25255 TCGv_i32 tdf = tcg_temp_new_i32();
25256
25257 /* adjust df value for floating-point instruction */
25258 tcg_gen_movi_i32(tdf, df + 2);
25259
25260 switch (MASK_MSA_3RF(ctx->opcode)) {
25261 case OPC_FCAF_df:
25262 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
25263 break;
25264 case OPC_FADD_df:
25265 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
25266 break;
25267 case OPC_FCUN_df:
25268 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
25269 break;
25270 case OPC_FSUB_df:
25271 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
25272 break;
25273 case OPC_FCOR_df:
25274 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
25275 break;
25276 case OPC_FCEQ_df:
25277 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
25278 break;
25279 case OPC_FMUL_df:
25280 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
25281 break;
25282 case OPC_FCUNE_df:
25283 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
25284 break;
25285 case OPC_FCUEQ_df:
25286 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
25287 break;
25288 case OPC_FDIV_df:
25289 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
25290 break;
25291 case OPC_FCNE_df:
25292 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
25293 break;
25294 case OPC_FCLT_df:
25295 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
25296 break;
25297 case OPC_FMADD_df:
25298 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
25299 break;
25300 case OPC_MUL_Q_df:
25301 tcg_gen_movi_i32(tdf, df + 1);
25302 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
25303 break;
25304 case OPC_FCULT_df:
25305 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
25306 break;
25307 case OPC_FMSUB_df:
25308 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
25309 break;
25310 case OPC_MADD_Q_df:
25311 tcg_gen_movi_i32(tdf, df + 1);
25312 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
25313 break;
25314 case OPC_FCLE_df:
25315 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
25316 break;
25317 case OPC_MSUB_Q_df:
25318 tcg_gen_movi_i32(tdf, df + 1);
25319 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
25320 break;
25321 case OPC_FCULE_df:
25322 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
25323 break;
25324 case OPC_FEXP2_df:
25325 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
25326 break;
25327 case OPC_FSAF_df:
25328 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
25329 break;
25330 case OPC_FEXDO_df:
25331 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
25332 break;
25333 case OPC_FSUN_df:
25334 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
25335 break;
25336 case OPC_FSOR_df:
25337 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
25338 break;
25339 case OPC_FSEQ_df:
25340 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
25341 break;
25342 case OPC_FTQ_df:
25343 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
25344 break;
25345 case OPC_FSUNE_df:
25346 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
25347 break;
25348 case OPC_FSUEQ_df:
25349 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
25350 break;
25351 case OPC_FSNE_df:
25352 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
25353 break;
25354 case OPC_FSLT_df:
25355 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
25356 break;
25357 case OPC_FMIN_df:
25358 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
25359 break;
25360 case OPC_MULR_Q_df:
25361 tcg_gen_movi_i32(tdf, df + 1);
25362 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
25363 break;
25364 case OPC_FSULT_df:
25365 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
25366 break;
25367 case OPC_FMIN_A_df:
25368 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
25369 break;
25370 case OPC_MADDR_Q_df:
25371 tcg_gen_movi_i32(tdf, df + 1);
25372 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
25373 break;
25374 case OPC_FSLE_df:
25375 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
25376 break;
25377 case OPC_FMAX_df:
25378 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
25379 break;
25380 case OPC_MSUBR_Q_df:
25381 tcg_gen_movi_i32(tdf, df + 1);
25382 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
25383 break;
25384 case OPC_FSULE_df:
25385 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
25386 break;
25387 case OPC_FMAX_A_df:
25388 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
25389 break;
25390 default:
25391 MIPS_INVAL("MSA instruction");
9c708c7f 25392 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
25393 break;
25394 }
25395
25396 tcg_temp_free_i32(twd);
25397 tcg_temp_free_i32(tws);
25398 tcg_temp_free_i32(twt);
25399 tcg_temp_free_i32(tdf);
25400}
25401
cbe50b9a
YK
25402static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
25403{
25404#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25405 (op & (0x7 << 18)))
25406 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25407 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25408 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25409 uint8_t df = (ctx->opcode >> 16) & 0x3;
25410 TCGv_i32 twd = tcg_const_i32(wd);
25411 TCGv_i32 tws = tcg_const_i32(ws);
25412 TCGv_i32 twt = tcg_const_i32(wt);
25413 TCGv_i32 tdf = tcg_const_i32(df);
25414
25415 switch (MASK_MSA_2R(ctx->opcode)) {
25416 case OPC_FILL_df:
25417#if !defined(TARGET_MIPS64)
25418 /* Double format valid only for MIPS64 */
25419 if (df == DF_DOUBLE) {
9c708c7f 25420 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
25421 break;
25422 }
25423#endif
25424 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
25425 break;
25426 case OPC_PCNT_df:
25427 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
25428 break;
25429 case OPC_NLOC_df:
25430 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
25431 break;
25432 case OPC_NLZC_df:
25433 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
25434 break;
25435 default:
25436 MIPS_INVAL("MSA instruction");
9c708c7f 25437 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
25438 break;
25439 }
25440
25441 tcg_temp_free_i32(twd);
25442 tcg_temp_free_i32(tws);
25443 tcg_temp_free_i32(twt);
25444 tcg_temp_free_i32(tdf);
25445}
25446
3bdeb688
YK
25447static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
25448{
25449#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25450 (op & (0xf << 17)))
25451 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25452 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25453 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25454 uint8_t df = (ctx->opcode >> 16) & 0x1;
25455 TCGv_i32 twd = tcg_const_i32(wd);
25456 TCGv_i32 tws = tcg_const_i32(ws);
25457 TCGv_i32 twt = tcg_const_i32(wt);
25458 /* adjust df value for floating-point instruction */
25459 TCGv_i32 tdf = tcg_const_i32(df + 2);
25460
25461 switch (MASK_MSA_2RF(ctx->opcode)) {
25462 case OPC_FCLASS_df:
25463 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
25464 break;
25465 case OPC_FTRUNC_S_df:
25466 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
25467 break;
25468 case OPC_FTRUNC_U_df:
25469 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25470 break;
25471 case OPC_FSQRT_df:
25472 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25473 break;
25474 case OPC_FRSQRT_df:
25475 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25476 break;
25477 case OPC_FRCP_df:
25478 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25479 break;
25480 case OPC_FRINT_df:
25481 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25482 break;
25483 case OPC_FLOG2_df:
25484 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25485 break;
25486 case OPC_FEXUPL_df:
25487 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
25488 break;
25489 case OPC_FEXUPR_df:
25490 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
25491 break;
25492 case OPC_FFQL_df:
25493 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
25494 break;
25495 case OPC_FFQR_df:
25496 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
25497 break;
25498 case OPC_FTINT_S_df:
25499 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
25500 break;
25501 case OPC_FTINT_U_df:
25502 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
25503 break;
25504 case OPC_FFINT_S_df:
25505 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
25506 break;
25507 case OPC_FFINT_U_df:
25508 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
25509 break;
25510 }
25511
25512 tcg_temp_free_i32(twd);
25513 tcg_temp_free_i32(tws);
25514 tcg_temp_free_i32(twt);
25515 tcg_temp_free_i32(tdf);
25516}
25517
cbe50b9a
YK
25518static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
25519{
25520#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
25521 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25522 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25523 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25524 TCGv_i32 twd = tcg_const_i32(wd);
25525 TCGv_i32 tws = tcg_const_i32(ws);
25526 TCGv_i32 twt = tcg_const_i32(wt);
25527
25528 switch (MASK_MSA_VEC(ctx->opcode)) {
25529 case OPC_AND_V:
25530 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
25531 break;
25532 case OPC_OR_V:
25533 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
25534 break;
25535 case OPC_NOR_V:
25536 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
25537 break;
25538 case OPC_XOR_V:
25539 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
25540 break;
25541 case OPC_BMNZ_V:
25542 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
25543 break;
25544 case OPC_BMZ_V:
25545 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
25546 break;
25547 case OPC_BSEL_V:
25548 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
25549 break;
25550 default:
25551 MIPS_INVAL("MSA instruction");
9c708c7f 25552 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
25553 break;
25554 }
25555
25556 tcg_temp_free_i32(twd);
25557 tcg_temp_free_i32(tws);
25558 tcg_temp_free_i32(twt);
25559}
25560
25561static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25562{
25563 switch (MASK_MSA_VEC(ctx->opcode)) {
25564 case OPC_AND_V:
25565 case OPC_OR_V:
25566 case OPC_NOR_V:
25567 case OPC_XOR_V:
25568 case OPC_BMNZ_V:
25569 case OPC_BMZ_V:
25570 case OPC_BSEL_V:
25571 gen_msa_vec_v(env, ctx);
25572 break;
25573 case OPC_MSA_2R:
25574 gen_msa_2r(env, ctx);
25575 break;
3bdeb688
YK
25576 case OPC_MSA_2RF:
25577 gen_msa_2rf(env, ctx);
25578 break;
cbe50b9a
YK
25579 default:
25580 MIPS_INVAL("MSA instruction");
9c708c7f 25581 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
25582 break;
25583 }
25584}
25585
4c789546
YK
25586static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25587{
25588 uint32_t opcode = ctx->opcode;
25589 check_insn(ctx, ASE_MSA);
25590 check_msa_access(ctx);
25591
25592 switch (MASK_MSA_MINOR(opcode)) {
25593 case OPC_MSA_I8_00:
25594 case OPC_MSA_I8_01:
25595 case OPC_MSA_I8_02:
25596 gen_msa_i8(env, ctx);
25597 break;
80e71591
YK
25598 case OPC_MSA_I5_06:
25599 case OPC_MSA_I5_07:
25600 gen_msa_i5(env, ctx);
25601 break;
d4cf28de
YK
25602 case OPC_MSA_BIT_09:
25603 case OPC_MSA_BIT_0A:
25604 gen_msa_bit(env, ctx);
25605 break;
28f99f08
YK
25606 case OPC_MSA_3R_0D:
25607 case OPC_MSA_3R_0E:
25608 case OPC_MSA_3R_0F:
25609 case OPC_MSA_3R_10:
25610 case OPC_MSA_3R_11:
25611 case OPC_MSA_3R_12:
25612 case OPC_MSA_3R_13:
25613 case OPC_MSA_3R_14:
25614 case OPC_MSA_3R_15:
25615 gen_msa_3r(env, ctx);
25616 break;
1e608ec1
YK
25617 case OPC_MSA_ELM:
25618 gen_msa_elm(env, ctx);
25619 break;
7d05b9c8
YK
25620 case OPC_MSA_3RF_1A:
25621 case OPC_MSA_3RF_1B:
25622 case OPC_MSA_3RF_1C:
25623 gen_msa_3rf(env, ctx);
25624 break;
cbe50b9a
YK
25625 case OPC_MSA_VEC:
25626 gen_msa_vec(env, ctx);
25627 break;
f7685877
YK
25628 case OPC_LD_B:
25629 case OPC_LD_H:
25630 case OPC_LD_W:
25631 case OPC_LD_D:
25632 case OPC_ST_B:
25633 case OPC_ST_H:
25634 case OPC_ST_W:
25635 case OPC_ST_D:
25636 {
25637 int32_t s10 = sextract32(ctx->opcode, 16, 10);
25638 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25639 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25640 uint8_t df = (ctx->opcode >> 0) & 0x3;
25641
f7685877 25642 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
25643 TCGv taddr = tcg_temp_new();
25644 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
25645
25646 switch (MASK_MSA_MINOR(opcode)) {
25647 case OPC_LD_B:
adc370a4
YK
25648 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25649 break;
f7685877 25650 case OPC_LD_H:
adc370a4
YK
25651 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25652 break;
f7685877 25653 case OPC_LD_W:
adc370a4
YK
25654 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25655 break;
f7685877 25656 case OPC_LD_D:
adc370a4 25657 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
25658 break;
25659 case OPC_ST_B:
adc370a4
YK
25660 gen_helper_msa_st_b(cpu_env, twd, taddr);
25661 break;
f7685877 25662 case OPC_ST_H:
adc370a4
YK
25663 gen_helper_msa_st_h(cpu_env, twd, taddr);
25664 break;
f7685877 25665 case OPC_ST_W:
adc370a4
YK
25666 gen_helper_msa_st_w(cpu_env, twd, taddr);
25667 break;
f7685877 25668 case OPC_ST_D:
adc370a4 25669 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
25670 break;
25671 }
25672
25673 tcg_temp_free_i32(twd);
adc370a4 25674 tcg_temp_free(taddr);
f7685877
YK
25675 }
25676 break;
4c789546
YK
25677 default:
25678 MIPS_INVAL("MSA instruction");
9c708c7f 25679 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
25680 break;
25681 }
25682
25683}
25684
d2bfa6e6 25685static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
25686{
25687 int32_t offset;
25688 int rs, rt, rd, sa;
25689 uint32_t op, op1;
25690 int16_t imm;
25691
25692 /* make sure instructions are on a word boundary */
eeb3bba8
EC
25693 if (ctx->base.pc_next & 0x3) {
25694 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 25695 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
25696 return;
25697 }
25698
25699 /* Handle blikely not taken case */
25700 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 25701 TCGLabel *l1 = gen_new_label();
099e5b4d 25702
099e5b4d
LA
25703 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25704 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 25705 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
25706 gen_set_label(l1);
25707 }
25708
099e5b4d
LA
25709 op = MASK_OP_MAJOR(ctx->opcode);
25710 rs = (ctx->opcode >> 21) & 0x1f;
25711 rt = (ctx->opcode >> 16) & 0x1f;
25712 rd = (ctx->opcode >> 11) & 0x1f;
25713 sa = (ctx->opcode >> 6) & 0x1f;
25714 imm = (int16_t)ctx->opcode;
25715 switch (op) {
25716 case OPC_SPECIAL:
25717 decode_opc_special(env, ctx);
25718 break;
25719 case OPC_SPECIAL2:
4267d3e6 25720 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
25721 break;
25722 case OPC_SPECIAL3:
25723 decode_opc_special3(env, ctx);
25724 break;
7a387fff
TS
25725 case OPC_REGIMM:
25726 op1 = MASK_REGIMM(ctx->opcode);
25727 switch (op1) {
fecd2646
LA
25728 case OPC_BLTZL: /* REGIMM branches */
25729 case OPC_BGEZL:
25730 case OPC_BLTZALL:
25731 case OPC_BGEZALL:
d9224450 25732 check_insn(ctx, ISA_MIPS2);
fecd2646 25733 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 25734 /* Fallthrough */
fecd2646
LA
25735 case OPC_BLTZ:
25736 case OPC_BGEZ:
b231c103 25737 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 25738 break;
fecd2646
LA
25739 case OPC_BLTZAL:
25740 case OPC_BGEZAL:
0aefa333
YK
25741 if (ctx->insn_flags & ISA_MIPS32R6) {
25742 if (rs == 0) {
25743 /* OPC_NAL, OPC_BAL */
b231c103 25744 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 25745 } else {
9c708c7f 25746 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
25747 }
25748 } else {
b231c103 25749 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 25750 }
c9602061 25751 break;
c2e19f3c
AM
25752 case OPC_TGEI: /* REGIMM traps */
25753 case OPC_TGEIU:
25754 case OPC_TLTI:
25755 case OPC_TLTIU:
25756 case OPC_TEQI:
25757
7a387fff 25758 case OPC_TNEI:
d9224450 25759 check_insn(ctx, ISA_MIPS2);
fecd2646 25760 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
25761 gen_trap(ctx, op1, rs, -1, imm);
25762 break;
bb238210
YK
25763 case OPC_SIGRIE:
25764 check_insn(ctx, ISA_MIPS32R6);
25765 generate_exception_end(ctx, EXCP_RI);
25766 break;
7a387fff 25767 case OPC_SYNCI:
d75c135e 25768 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
25769 /* Break the TB to be able to sync copied instructions
25770 immediately */
eeb3bba8 25771 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 25772 break;
e45a93e2
JL
25773 case OPC_BPOSGE32: /* MIPS DSP branch */
25774#if defined(TARGET_MIPS64)
25775 case OPC_BPOSGE64:
25776#endif
25777 check_dsp(ctx);
b231c103 25778 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 25779 break;
d4ea6acd
LA
25780#if defined(TARGET_MIPS64)
25781 case OPC_DAHI:
25782 check_insn(ctx, ISA_MIPS32R6);
25783 check_mips_64(ctx);
25784 if (rs != 0) {
25785 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25786 }
d4ea6acd
LA
25787 break;
25788 case OPC_DATI:
25789 check_insn(ctx, ISA_MIPS32R6);
25790 check_mips_64(ctx);
25791 if (rs != 0) {
25792 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25793 }
d4ea6acd
LA
25794 break;
25795#endif
6af0bf9c 25796 default: /* Invalid */
923617a3 25797 MIPS_INVAL("regimm");
9c708c7f 25798 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
25799 break;
25800 }
25801 break;
7a387fff 25802 case OPC_CP0:
387a8fe5 25803 check_cp0_enabled(ctx);
7a387fff 25804 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 25805 switch (op1) {
7a387fff
TS
25806 case OPC_MFC0:
25807 case OPC_MTC0:
ead9360e
TS
25808 case OPC_MFTR:
25809 case OPC_MTTR:
5204ea79
LA
25810 case OPC_MFHC0:
25811 case OPC_MTHC0:
d26bc211 25812#if defined(TARGET_MIPS64)
7a387fff
TS
25813 case OPC_DMFC0:
25814 case OPC_DMTC0:
25815#endif
f1aa6320 25816#ifndef CONFIG_USER_ONLY
932e71cd 25817 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 25818#endif /* !CONFIG_USER_ONLY */
7a387fff 25819 break;
c38a1d52
AR
25820 case OPC_C0:
25821 case OPC_C0_1:
25822 case OPC_C0_2:
25823 case OPC_C0_3:
25824 case OPC_C0_4:
25825 case OPC_C0_5:
25826 case OPC_C0_6:
25827 case OPC_C0_7:
25828 case OPC_C0_8:
25829 case OPC_C0_9:
25830 case OPC_C0_A:
25831 case OPC_C0_B:
25832 case OPC_C0_C:
25833 case OPC_C0_D:
25834 case OPC_C0_E:
25835 case OPC_C0_F:
f1aa6320 25836#ifndef CONFIG_USER_ONLY
932e71cd 25837 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 25838#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
25839 break;
25840 case OPC_MFMC0:
8706c382 25841#ifndef CONFIG_USER_ONLY
932e71cd 25842 {
099e5b4d 25843 uint32_t op2;
35fbce2c 25844 TCGv t0 = tcg_temp_new();
6c5c1e20 25845
0eaef5aa 25846 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
25847 switch (op2) {
25848 case OPC_DMT:
9affc1c5 25849 check_cp0_mt(ctx);
9ed5726c 25850 gen_helper_dmt(t0);
35fbce2c 25851 gen_store_gpr(t0, rt);
6c5c1e20
TS
25852 break;
25853 case OPC_EMT:
9affc1c5 25854 check_cp0_mt(ctx);
9ed5726c 25855 gen_helper_emt(t0);
35fbce2c 25856 gen_store_gpr(t0, rt);
da80682b 25857 break;
6c5c1e20 25858 case OPC_DVPE:
9affc1c5 25859 check_cp0_mt(ctx);
895c2d04 25860 gen_helper_dvpe(t0, cpu_env);
35fbce2c 25861 gen_store_gpr(t0, rt);
6c5c1e20
TS
25862 break;
25863 case OPC_EVPE:
9affc1c5 25864 check_cp0_mt(ctx);
895c2d04 25865 gen_helper_evpe(t0, cpu_env);
35fbce2c 25866 gen_store_gpr(t0, rt);
6c5c1e20 25867 break;
01bc435b
YK
25868 case OPC_DVP:
25869 check_insn(ctx, ISA_MIPS32R6);
25870 if (ctx->vp) {
25871 gen_helper_dvp(t0, cpu_env);
25872 gen_store_gpr(t0, rt);
25873 }
25874 break;
25875 case OPC_EVP:
25876 check_insn(ctx, ISA_MIPS32R6);
25877 if (ctx->vp) {
25878 gen_helper_evp(t0, cpu_env);
25879 gen_store_gpr(t0, rt);
25880 }
25881 break;
6c5c1e20 25882 case OPC_DI:
d75c135e 25883 check_insn(ctx, ISA_MIPS32R2);
867abc7e 25884 save_cpu_state(ctx, 1);
895c2d04 25885 gen_helper_di(t0, cpu_env);
35fbce2c 25886 gen_store_gpr(t0, rt);
d2bfa6e6
MR
25887 /* Stop translation as we may have switched
25888 the execution mode. */
eeb3bba8 25889 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
25890 break;
25891 case OPC_EI:
d75c135e 25892 check_insn(ctx, ISA_MIPS32R2);
867abc7e 25893 save_cpu_state(ctx, 1);
895c2d04 25894 gen_helper_ei(t0, cpu_env);
35fbce2c 25895 gen_store_gpr(t0, rt);
b28425ba
EC
25896 /* DISAS_STOP isn't sufficient, we need to ensure we break
25897 out of translated code to check for pending interrupts */
eeb3bba8
EC
25898 gen_save_pc(ctx->base.pc_next + 4);
25899 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
25900 break;
25901 default: /* Invalid */
25902 MIPS_INVAL("mfmc0");
9c708c7f 25903 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
25904 break;
25905 }
6c5c1e20 25906 tcg_temp_free(t0);
7a387fff 25907 }
0eaef5aa 25908#endif /* !CONFIG_USER_ONLY */
6af0bf9c 25909 break;
7a387fff 25910 case OPC_RDPGPR:
d75c135e 25911 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 25912 gen_load_srsgpr(rt, rd);
ead9360e 25913 break;
7a387fff 25914 case OPC_WRPGPR:
d75c135e 25915 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 25916 gen_store_srsgpr(rt, rd);
38121543 25917 break;
6af0bf9c 25918 default:
923617a3 25919 MIPS_INVAL("cp0");
9c708c7f 25920 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
25921 break;
25922 }
25923 break;
31837be3
YK
25924 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25925 if (ctx->insn_flags & ISA_MIPS32R6) {
25926 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25927 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25928 } else {
25929 /* OPC_ADDI */
25930 /* Arithmetic with immediate opcode */
25931 gen_arith_imm(ctx, op, rt, rs, imm);
25932 }
25933 break;
324d9e32 25934 case OPC_ADDIU:
d75c135e 25935 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 25936 break;
324d9e32
AJ
25937 case OPC_SLTI: /* Set on less than with immediate opcode */
25938 case OPC_SLTIU:
d75c135e 25939 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
25940 break;
25941 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 25942 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
25943 case OPC_ORI:
25944 case OPC_XORI:
d75c135e 25945 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 25946 break;
c2e19f3c
AM
25947 case OPC_J: /* Jump */
25948 case OPC_JAL:
7a387fff 25949 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 25950 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 25951 break;
31837be3
YK
25952 /* Branch */
25953 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25954 if (ctx->insn_flags & ISA_MIPS32R6) {
25955 if (rt == 0) {
9c708c7f 25956 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
25957 break;
25958 }
25959 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25960 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25961 } else {
25962 /* OPC_BLEZL */
b231c103 25963 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25964 }
25965 break;
25966 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25967 if (ctx->insn_flags & ISA_MIPS32R6) {
25968 if (rt == 0) {
9c708c7f 25969 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
25970 break;
25971 }
25972 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25973 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25974 } else {
25975 /* OPC_BGTZL */
b231c103 25976 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25977 }
25978 break;
25979 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25980 if (rt == 0) {
25981 /* OPC_BLEZ */
b231c103 25982 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25983 } else {
25984 check_insn(ctx, ISA_MIPS32R6);
25985 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25986 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25987 }
25988 break;
25989 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25990 if (rt == 0) {
25991 /* OPC_BGTZ */
b231c103 25992 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25993 } else {
25994 check_insn(ctx, ISA_MIPS32R6);
25995 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25996 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25997 }
25998 break;
25999 case OPC_BEQL:
26000 case OPC_BNEL:
d9224450 26001 check_insn(ctx, ISA_MIPS2);
fecd2646 26002 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 26003 /* Fallthrough */
31837be3
YK
26004 case OPC_BEQ:
26005 case OPC_BNE:
b231c103 26006 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 26007 break;
d9224450
MR
26008 case OPC_LL: /* Load and stores */
26009 check_insn(ctx, ISA_MIPS2);
26010 /* Fallthrough */
26011 case OPC_LWL:
fecd2646
LA
26012 case OPC_LWR:
26013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 26014 /* Fallthrough */
c2e19f3c
AM
26015 case OPC_LB:
26016 case OPC_LH:
26017 case OPC_LW:
26018 case OPC_LWPC:
26019 case OPC_LBU:
26020 case OPC_LHU:
d75c135e 26021 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 26022 break;
fecd2646 26023 case OPC_SWL:
7a387fff 26024 case OPC_SWR:
fecd2646 26025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 26026 /* fall through */
c2e19f3c
AM
26027 case OPC_SB:
26028 case OPC_SH:
fecd2646 26029 case OPC_SW:
5c13fdfd 26030 gen_st(ctx, op, rt, rs, imm);
7a387fff 26031 break;
d66c7132 26032 case OPC_SC:
d9224450 26033 check_insn(ctx, ISA_MIPS2);
4368b29a 26034 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
26035 gen_st_cond(ctx, op, rt, rs, imm);
26036 break;
7a387fff 26037 case OPC_CACHE:
bf7910c6 26038 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 26039 check_cp0_enabled(ctx);
d75c135e 26040 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
26041 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26042 gen_cache_operation(ctx, rt, rs, imm);
26043 }
ead9360e 26044 /* Treat as NOP. */
34ae7b51 26045 break;
7a387fff 26046 case OPC_PREF:
bf7910c6 26047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 26048 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 26049 /* Treat as NOP. */
6af0bf9c 26050 break;
4ad40f36 26051
923617a3 26052 /* Floating point (COP1). */
7a387fff
TS
26053 case OPC_LWC1:
26054 case OPC_LDC1:
26055 case OPC_SWC1:
26056 case OPC_SDC1:
5ab5c041 26057 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
26058 break;
26059
7a387fff 26060 case OPC_CP1:
5692c6e1
YK
26061 op1 = MASK_CP1(ctx->opcode);
26062
26063 switch (op1) {
26064 case OPC_MFHC1:
26065 case OPC_MTHC1:
5e755519 26066 check_cp1_enabled(ctx);
5692c6e1 26067 check_insn(ctx, ISA_MIPS32R2);
146dd620 26068 /* fall through */
5692c6e1
YK
26069 case OPC_MFC1:
26070 case OPC_CFC1:
26071 case OPC_MTC1:
26072 case OPC_CTC1:
26073 check_cp1_enabled(ctx);
26074 gen_cp1(ctx, op1, rt, rd);
26075 break;
d26bc211 26076#if defined(TARGET_MIPS64)
5692c6e1
YK
26077 case OPC_DMFC1:
26078 case OPC_DMTC1:
26079 check_cp1_enabled(ctx);
26080 check_insn(ctx, ISA_MIPS3);
d9224450 26081 check_mips_64(ctx);
5692c6e1
YK
26082 gen_cp1(ctx, op1, rt, rd);
26083 break;
e189e748 26084#endif
5692c6e1
YK
26085 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
26086 check_cp1_enabled(ctx);
26087 if (ctx->insn_flags & ISA_MIPS32R6) {
26088 /* OPC_BC1EQZ */
31837be3 26089 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 26090 rt, imm << 2, 4);
5692c6e1
YK
26091 } else {
26092 /* OPC_BC1ANY2 */
b8aa4598 26093 check_cop1x(ctx);
d75c135e 26094 check_insn(ctx, ASE_MIPS3D);
d75c135e 26095 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 26096 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
26097 }
26098 break;
26099 case OPC_BC1NEZ:
26100 check_cp1_enabled(ctx);
26101 check_insn(ctx, ISA_MIPS32R6);
26102 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 26103 rt, imm << 2, 4);
5692c6e1
YK
26104 break;
26105 case OPC_BC1ANY4:
26106 check_cp1_enabled(ctx);
26107 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26108 check_cop1x(ctx);
26109 check_insn(ctx, ASE_MIPS3D);
26110 /* fall through */
26111 case OPC_BC1:
26112 check_cp1_enabled(ctx);
26113 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26114 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
26115 (rt >> 2) & 0x7, imm << 2);
26116 break;
26117 case OPC_PS_FMT:
e29c9628 26118 check_ps(ctx);
b6f3b233 26119 /* fall through */
5692c6e1
YK
26120 case OPC_S_FMT:
26121 case OPC_D_FMT:
26122 check_cp1_enabled(ctx);
26123 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26124 (imm >> 8) & 0x7);
26125 break;
26126 case OPC_W_FMT:
26127 case OPC_L_FMT:
26128 {
26129 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
26130 check_cp1_enabled(ctx);
26131 if (ctx->insn_flags & ISA_MIPS32R6) {
26132 switch (r6_op) {
26133 case R6_OPC_CMP_AF_S:
26134 case R6_OPC_CMP_UN_S:
26135 case R6_OPC_CMP_EQ_S:
26136 case R6_OPC_CMP_UEQ_S:
26137 case R6_OPC_CMP_LT_S:
26138 case R6_OPC_CMP_ULT_S:
26139 case R6_OPC_CMP_LE_S:
26140 case R6_OPC_CMP_ULE_S:
26141 case R6_OPC_CMP_SAF_S:
26142 case R6_OPC_CMP_SUN_S:
26143 case R6_OPC_CMP_SEQ_S:
26144 case R6_OPC_CMP_SEUQ_S:
26145 case R6_OPC_CMP_SLT_S:
26146 case R6_OPC_CMP_SULT_S:
26147 case R6_OPC_CMP_SLE_S:
26148 case R6_OPC_CMP_SULE_S:
26149 case R6_OPC_CMP_OR_S:
26150 case R6_OPC_CMP_UNE_S:
26151 case R6_OPC_CMP_NE_S:
26152 case R6_OPC_CMP_SOR_S:
26153 case R6_OPC_CMP_SUNE_S:
26154 case R6_OPC_CMP_SNE_S:
26155 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26156 break;
26157 case R6_OPC_CMP_AF_D:
26158 case R6_OPC_CMP_UN_D:
26159 case R6_OPC_CMP_EQ_D:
26160 case R6_OPC_CMP_UEQ_D:
26161 case R6_OPC_CMP_LT_D:
26162 case R6_OPC_CMP_ULT_D:
26163 case R6_OPC_CMP_LE_D:
26164 case R6_OPC_CMP_ULE_D:
26165 case R6_OPC_CMP_SAF_D:
26166 case R6_OPC_CMP_SUN_D:
26167 case R6_OPC_CMP_SEQ_D:
26168 case R6_OPC_CMP_SEUQ_D:
26169 case R6_OPC_CMP_SLT_D:
26170 case R6_OPC_CMP_SULT_D:
26171 case R6_OPC_CMP_SLE_D:
26172 case R6_OPC_CMP_SULE_D:
26173 case R6_OPC_CMP_OR_D:
26174 case R6_OPC_CMP_UNE_D:
26175 case R6_OPC_CMP_NE_D:
26176 case R6_OPC_CMP_SOR_D:
26177 case R6_OPC_CMP_SUNE_D:
26178 case R6_OPC_CMP_SNE_D:
26179 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26180 break;
26181 default:
d2bfa6e6
MR
26182 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
26183 rt, rd, sa, (imm >> 8) & 0x7);
26184
5692c6e1 26185 break;
3f493883 26186 }
5692c6e1
YK
26187 } else {
26188 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26189 (imm >> 8) & 0x7);
36d23958 26190 }
5692c6e1
YK
26191 break;
26192 }
26193 case OPC_BZ_V:
26194 case OPC_BNZ_V:
26195 case OPC_BZ_B:
26196 case OPC_BZ_H:
26197 case OPC_BZ_W:
26198 case OPC_BZ_D:
26199 case OPC_BNZ_B:
26200 case OPC_BNZ_H:
26201 case OPC_BNZ_W:
26202 case OPC_BNZ_D:
26203 check_insn(ctx, ASE_MSA);
26204 gen_msa_branch(env, ctx, op1);
26205 break;
26206 default:
26207 MIPS_INVAL("cp1");
9c708c7f 26208 generate_exception_end(ctx, EXCP_RI);
5692c6e1 26209 break;
6ea83fed 26210 }
4ad40f36
FB
26211 break;
26212
31837be3
YK
26213 /* Compact branches [R6] and COP2 [non-R6] */
26214 case OPC_BC: /* OPC_LWC2 */
26215 case OPC_BALC: /* OPC_SWC2 */
26216 if (ctx->insn_flags & ISA_MIPS32R6) {
26217 /* OPC_BC, OPC_BALC */
26218 gen_compute_compact_branch(ctx, op, 0, 0,
26219 sextract32(ctx->opcode << 2, 0, 28));
26220 } else {
26221 /* OPC_LWC2, OPC_SWC2 */
26222 /* COP2: Not implemented. */
26223 generate_exception_err(ctx, EXCP_CpU, 2);
26224 }
26225 break;
26226 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
26227 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
26228 if (ctx->insn_flags & ISA_MIPS32R6) {
26229 if (rs != 0) {
26230 /* OPC_BEQZC, OPC_BNEZC */
26231 gen_compute_compact_branch(ctx, op, rs, 0,
26232 sextract32(ctx->opcode << 2, 0, 23));
26233 } else {
26234 /* OPC_JIC, OPC_JIALC */
26235 gen_compute_compact_branch(ctx, op, 0, rt, imm);
26236 }
26237 } else {
26238 /* OPC_LWC2, OPC_SWC2 */
26239 /* COP2: Not implemented. */
26240 generate_exception_err(ctx, EXCP_CpU, 2);
26241 }
4ad40f36 26242 break;
bd277fa1 26243 case OPC_CP2:
d75c135e 26244 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
26245 /* Note that these instructions use different fields. */
26246 gen_loongson_multimedia(ctx, sa, rd, rt);
26247 break;
4ad40f36 26248
7a387fff 26249 case OPC_CP3:
fecd2646 26250 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 26251 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 26252 check_cp1_enabled(ctx);
36d23958
TS
26253 op1 = MASK_CP3(ctx->opcode);
26254 switch (op1) {
d9224450
MR
26255 case OPC_LUXC1:
26256 case OPC_SUXC1:
26257 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26258 /* Fallthrough */
5a5012ec
TS
26259 case OPC_LWXC1:
26260 case OPC_LDXC1:
5a5012ec
TS
26261 case OPC_SWXC1:
26262 case OPC_SDXC1:
d9224450 26263 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 26264 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 26265 break;
e0c84da7 26266 case OPC_PREFX:
d9224450 26267 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 26268 /* Treat as NOP. */
e0c84da7 26269 break;
5a5012ec 26270 case OPC_ALNV_PS:
d9224450
MR
26271 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26272 /* Fallthrough */
5a5012ec
TS
26273 case OPC_MADD_S:
26274 case OPC_MADD_D:
26275 case OPC_MADD_PS:
26276 case OPC_MSUB_S:
26277 case OPC_MSUB_D:
26278 case OPC_MSUB_PS:
26279 case OPC_NMADD_S:
26280 case OPC_NMADD_D:
26281 case OPC_NMADD_PS:
26282 case OPC_NMSUB_S:
26283 case OPC_NMSUB_D:
26284 case OPC_NMSUB_PS:
d9224450 26285 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
26286 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
26287 break;
36d23958 26288 default:
923617a3 26289 MIPS_INVAL("cp3");
9c708c7f 26290 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
26291 break;
26292 }
26293 } else {
e397ee33 26294 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 26295 }
4ad40f36
FB
26296 break;
26297
d26bc211 26298#if defined(TARGET_MIPS64)
7a387fff 26299 /* MIPS64 opcodes */
c2e19f3c
AM
26300 case OPC_LDL:
26301 case OPC_LDR:
bf7910c6 26302 case OPC_LLD:
fecd2646 26303 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 26304 /* fall through */
fecd2646 26305 case OPC_LWU:
7a387fff 26306 case OPC_LD:
d75c135e 26307 check_insn(ctx, ISA_MIPS3);
5c13fdfd 26308 check_mips_64(ctx);
d75c135e 26309 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 26310 break;
c2e19f3c
AM
26311 case OPC_SDL:
26312 case OPC_SDR:
fecd2646 26313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 26314 /* fall through */
7a387fff 26315 case OPC_SD:
d75c135e 26316 check_insn(ctx, ISA_MIPS3);
e189e748 26317 check_mips_64(ctx);
5c13fdfd 26318 gen_st(ctx, op, rt, rs, imm);
7a387fff 26319 break;
d66c7132 26320 case OPC_SCD:
bf7910c6 26321 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 26322 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
26323 check_mips_64(ctx);
26324 gen_st_cond(ctx, op, rt, rs, imm);
26325 break;
31837be3
YK
26326 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
26327 if (ctx->insn_flags & ISA_MIPS32R6) {
26328 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
26329 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26330 } else {
26331 /* OPC_DADDI */
26332 check_insn(ctx, ISA_MIPS3);
26333 check_mips_64(ctx);
26334 gen_arith_imm(ctx, op, rt, rs, imm);
26335 }
26336 break;
324d9e32 26337 case OPC_DADDIU:
d75c135e 26338 check_insn(ctx, ISA_MIPS3);
e189e748 26339 check_mips_64(ctx);
d75c135e 26340 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 26341 break;
31837be3
YK
26342#else
26343 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
26344 if (ctx->insn_flags & ISA_MIPS32R6) {
26345 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26346 } else {
26347 MIPS_INVAL("major opcode");
9c708c7f 26348 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
26349 }
26350 break;
6af0bf9c 26351#endif
d4ea6acd
LA
26352 case OPC_DAUI: /* OPC_JALX */
26353 if (ctx->insn_flags & ISA_MIPS32R6) {
26354#if defined(TARGET_MIPS64)
26355 /* OPC_DAUI */
26356 check_mips_64(ctx);
db77d852
LA
26357 if (rs == 0) {
26358 generate_exception(ctx, EXCP_RI);
26359 } else if (rt != 0) {
d4ea6acd
LA
26360 TCGv t0 = tcg_temp_new();
26361 gen_load_gpr(t0, rs);
26362 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
26363 tcg_temp_free(t0);
26364 }
d4ea6acd 26365#else
9c708c7f 26366 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
26367 MIPS_INVAL("major opcode");
26368#endif
26369 } else {
26370 /* OPC_JALX */
26371 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
26372 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 26373 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 26374 }
364d4831 26375 break;
4c789546 26376 case OPC_MSA: /* OPC_MDMX */
7a387fff 26377 /* MDMX: Not implemented. */
4c789546 26378 gen_msa(env, ctx);
d4ea6acd
LA
26379 break;
26380 case OPC_PCREL:
26381 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 26382 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 26383 break;
6af0bf9c 26384 default: /* Invalid */
923617a3 26385 MIPS_INVAL("major opcode");
9c708c7f 26386 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
26387 break;
26388 }
6af0bf9c
FB
26389}
26390
18f440ed 26391static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 26392{
18f440ed 26393 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 26394 CPUMIPSState *env = cs->env_ptr;
12be9258 26395
18f440ed 26396 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
26397 ctx->saved_pc = -1;
26398 ctx->insn_flags = env->insn_flags;
26399 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 26400 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
26401 ctx->CP0_Config3 = env->CP0_Config3;
26402 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
26403 ctx->btarget = 0;
26404 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
26405 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
26406 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
26407 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
26408 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
26409 ctx->PAMask = env->PAMask;
26410 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
26411 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
26412 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
26413 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
26414 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 26415 /* Restore delay slot state from the tb context. */
12be9258
EC
26416 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
26417 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
26418 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 26419 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
26420 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
26421 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
26422 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
26423 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
26424 restore_cpu_state(env, ctx);
932e71cd 26425#ifdef CONFIG_USER_ONLY
12be9258 26426 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 26427#else
12be9258 26428 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 26429#endif
12be9258
EC
26430 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
26431 MO_UNALN : MO_ALIGN;
190ce7fb 26432
18f440ed
EC
26433 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
26434 ctx->hflags);
26435}
12be9258 26436
18f440ed
EC
26437static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
26438{
26439}
b933066a 26440
18f440ed
EC
26441static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
26442{
26443 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 26444
18f440ed
EC
26445 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
26446 ctx->btarget);
26447}
31837be3 26448
18f440ed
EC
26449static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
26450 const CPUBreakpoint *bp)
26451{
26452 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 26453
18f440ed
EC
26454 save_cpu_state(ctx, 1);
26455 ctx->base.is_jmp = DISAS_NORETURN;
26456 gen_helper_raise_exception_debug(cpu_env);
26457 /* The address covered by the breakpoint must be included in
26458 [tb->pc, tb->pc + tb->size) in order to for it to be
26459 properly cleared -- thus we increment the PC here so that
26460 the logic setting tb->size below does the right thing. */
26461 ctx->base.pc_next += 4;
26462 return true;
26463}
4ad40f36 26464
18f440ed
EC
26465static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
26466{
26467 CPUMIPSState *env = cs->env_ptr;
26468 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26469 int insn_bytes;
26470 int is_slot;
4ad40f36 26471
18f440ed 26472 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
26473 if (ctx->insn_flags & ISA_NANOMIPS32) {
26474 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26475 insn_bytes = decode_nanomips_opc(env, ctx);
26476 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
26477 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
26478 insn_bytes = 4;
26479 decode_opc(env, ctx);
26480 } else if (ctx->insn_flags & ASE_MICROMIPS) {
26481 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26482 insn_bytes = decode_micromips_opc(env, ctx);
26483 } else if (ctx->insn_flags & ASE_MIPS16) {
26484 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26485 insn_bytes = decode_mips16_opc(env, ctx);
26486 } else {
26487 generate_exception_end(ctx, EXCP_RI);
26488 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
26489 return;
26490 }
faf7aaa9 26491
18f440ed
EC
26492 if (ctx->hflags & MIPS_HFLAG_BMASK) {
26493 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
26494 MIPS_HFLAG_FBNSLOT))) {
26495 /* force to generate branch as there is neither delay nor
26496 forbidden slot */
26497 is_slot = 1;
26498 }
26499 if ((ctx->hflags & MIPS_HFLAG_M16) &&
26500 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
26501 /* Force to generate branch as microMIPS R6 doesn't restrict
26502 branches in the forbidden slot. */
26503 is_slot = 1;
eeb3bba8 26504 }
18f440ed
EC
26505 }
26506 if (is_slot) {
26507 gen_branch(ctx, insn_bytes);
26508 }
26509 ctx->base.pc_next += insn_bytes;
1b530a6d 26510
18f440ed
EC
26511 if (ctx->base.is_jmp != DISAS_NEXT) {
26512 return;
6af0bf9c 26513 }
18f440ed
EC
26514 /* Execute a branch and its delay slot as a single instruction.
26515 This is what GDB expects and is consistent with what the
26516 hardware does (e.g. if a delay slot instruction faults, the
26517 reported PC is the PC of the branch). */
26518 if (ctx->base.singlestep_enabled &&
26519 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
26520 ctx->base.is_jmp = DISAS_TOO_MANY;
26521 }
26522 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
26523 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 26524 }
18f440ed
EC
26525}
26526
26527static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
26528{
26529 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26530
12be9258
EC
26531 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
26532 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 26533 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 26534 } else {
12be9258 26535 switch (ctx->base.is_jmp) {
b28425ba 26536 case DISAS_STOP:
12be9258 26537 gen_save_pc(ctx->base.pc_next);
cd314a7d 26538 tcg_gen_lookup_and_goto_ptr();
df1561e2 26539 break;
b28425ba 26540 case DISAS_NEXT:
18f440ed 26541 case DISAS_TOO_MANY:
12be9258
EC
26542 save_cpu_state(ctx, 0);
26543 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 26544 break;
b28425ba 26545 case DISAS_EXIT:
07ea28b4 26546 tcg_gen_exit_tb(NULL, 0);
16c00cb2 26547 break;
b28425ba 26548 case DISAS_NORETURN:
5a5012ec 26549 break;
18f440ed
EC
26550 default:
26551 g_assert_not_reached();
6958549d 26552 }
6af0bf9c 26553 }
18f440ed
EC
26554}
26555
26556static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
26557{
26558 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
26559 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26560}
26561
26562static const TranslatorOps mips_tr_ops = {
26563 .init_disas_context = mips_tr_init_disas_context,
26564 .tb_start = mips_tr_tb_start,
26565 .insn_start = mips_tr_insn_start,
26566 .breakpoint_check = mips_tr_breakpoint_check,
26567 .translate_insn = mips_tr_translate_insn,
26568 .tb_stop = mips_tr_tb_stop,
26569 .disas_log = mips_tr_disas_log,
26570};
26571
26572void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26573{
26574 DisasContext ctx;
26575
26576 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
26577}
26578
7db13fae 26579static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 26580 int flags)
6ea83fed
FB
26581{
26582 int i;
5e755519 26583 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 26584
2a5612e6
SW
26585#define printfpr(fp) \
26586 do { \
26587 if (is_fpu64) \
26588 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26589 " fd:%13g fs:%13g psu: %13g\n", \
26590 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26591 (double)(fp)->fd, \
26592 (double)(fp)->fs[FP_ENDIAN_IDX], \
26593 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26594 else { \
26595 fpr_t tmp; \
26596 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26597 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26598 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26599 " fd:%13g fs:%13g psu:%13g\n", \
26600 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26601 (double)tmp.fd, \
26602 (double)tmp.fs[FP_ENDIAN_IDX], \
26603 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26604 } \
6ea83fed
FB
26605 } while(0)
26606
5a5012ec 26607
9a78eead
SW
26608 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26609 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 26610 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
26611 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26612 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 26613 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
26614 }
26615
26616#undef printfpr
26617}
26618
878096ee
AF
26619void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26620 int flags)
6af0bf9c 26621{
878096ee
AF
26622 MIPSCPU *cpu = MIPS_CPU(cs);
26623 CPUMIPSState *env = &cpu->env;
6af0bf9c 26624 int i;
3b46e624 26625
a7200c9f
SW
26626 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26627 " LO=0x" TARGET_FMT_lx " ds %04x "
26628 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
26629 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26630 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
26631 for (i = 0; i < 32; i++) {
26632 if ((i & 3) == 0)
26633 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 26634 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
26635 if ((i & 3) == 3)
26636 cpu_fprintf(f, "\n");
26637 }
568b600d 26638
3594c774 26639 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 26640 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
26641 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26642 PRIx64 "\n",
5499b6ff 26643 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
26644 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
26645 env->CP0_Config2, env->CP0_Config3);
26646 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
26647 env->CP0_Config4, env->CP0_Config5);
1cc5af69 26648 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 26649 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 26650 }
6af0bf9c
FB
26651}
26652
78ce64f4 26653void mips_tcg_init(void)
39454628 26654{
f01be154 26655 int i;
39454628 26656
f764718d 26657 cpu_gpr[0] = NULL;
bb928dbe 26658 for (i = 1; i < 32; i++)
e1ccc054 26659 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 26660 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 26661 regnames[i]);
d73ee8a2 26662
863f264d
YK
26663 for (i = 0; i < 32; i++) {
26664 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26665 msa_wr_d[i * 2] =
e1ccc054 26666 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
26667 /* The scalar floating-point unit (FPU) registers are mapped on
26668 * the MSA vector registers. */
26669 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
26670 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26671 msa_wr_d[i * 2 + 1] =
e1ccc054 26672 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
26673 }
26674
e1ccc054 26675 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 26676 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 26677 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 26678 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 26679 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 26680 regnames_HI[i]);
e1ccc054 26681 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 26682 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 26683 regnames_LO[i]);
4b2eb8d2 26684 }
e1ccc054 26685 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 26686 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 26687 "DSPControl");
e1ccc054 26688 bcond = tcg_global_mem_new(cpu_env,
7db13fae 26689 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 26690 btarget = tcg_global_mem_new(cpu_env,
7db13fae 26691 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 26692 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 26693 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 26694
e1ccc054 26695 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 26696 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 26697 "fcr0");
e1ccc054 26698 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 26699 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 26700 "fcr31");
39454628
TS
26701}
26702
5b27a92d 26703#include "translate_init.inc.c"
aaed909a 26704
27e38392
PMD
26705void cpu_mips_realize_env(CPUMIPSState *env)
26706{
26707 env->exception_base = (int32_t)0xBFC00000;
26708
26709#ifndef CONFIG_USER_ONLY
26710 mmu_init(env, env->cpu_model);
26711#endif
26712 fpu_init(env, env->cpu_model);
26713 mvp_init(env, env->cpu_model);
26714}
26715
a7519f2b 26716bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 26717{
a7519f2b
IM
26718 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26719 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
26720}
26721
a7519f2b 26722bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 26723{
a7519f2b
IM
26724 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26725 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
26726}
26727
89777fd1
LA
26728void cpu_set_exception_base(int vp_index, target_ulong address)
26729{
26730 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26731 vp->env.exception_base = address;
26732}
26733
1bba0dc9 26734void cpu_state_reset(CPUMIPSState *env)
6ae81775 26735{
55e5c285
AF
26736 MIPSCPU *cpu = mips_env_get_cpu(env);
26737 CPUState *cs = CPU(cpu);
6ae81775 26738
51cc2e78
BS
26739 /* Reset registers to their default values */
26740 env->CP0_PRid = env->cpu_model->CP0_PRid;
26741 env->CP0_Config0 = env->cpu_model->CP0_Config0;
26742#ifdef TARGET_WORDS_BIGENDIAN
26743 env->CP0_Config0 |= (1 << CP0C0_BE);
26744#endif
26745 env->CP0_Config1 = env->cpu_model->CP0_Config1;
26746 env->CP0_Config2 = env->cpu_model->CP0_Config2;
26747 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
26748 env->CP0_Config4 = env->cpu_model->CP0_Config4;
26749 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
26750 env->CP0_Config5 = env->cpu_model->CP0_Config5;
26751 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
26752 env->CP0_Config6 = env->cpu_model->CP0_Config6;
26753 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
26754 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26755 << env->cpu_model->CP0_LLAddr_shift;
26756 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
26757 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26758 env->CCRes = env->cpu_model->CCRes;
26759 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26760 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26761 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26762 env->current_tc = 0;
26763 env->SEGBITS = env->cpu_model->SEGBITS;
26764 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26765#if defined(TARGET_MIPS64)
26766 if (env->cpu_model->insn_flags & ISA_MIPS3) {
26767 env->SEGMask |= 3ULL << 62;
26768 }
26769#endif
26770 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
26771 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26772 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26773 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26774 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26775 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26776 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26777 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26778 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26779 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26780 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
26781 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26782 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 26783 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 26784 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 26785 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 26786 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 26787 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
26788 env->insn_flags = env->cpu_model->insn_flags;
26789
0eaef5aa 26790#if defined(CONFIG_USER_ONLY)
03e6e501 26791 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
26792# ifdef TARGET_MIPS64
26793 /* Enable 64-bit register mode. */
26794 env->CP0_Status |= (1 << CP0St_PX);
26795# endif
26796# ifdef TARGET_ABI_MIPSN64
26797 /* Enable 64-bit address mode. */
26798 env->CP0_Status |= (1 << CP0St_UX);
26799# endif
94159135
MI
26800 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26801 hardware registers. */
26802 env->CP0_HWREna |= 0x0000000F;
91a75935 26803 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 26804 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 26805 }
6f0af304
PJ
26806 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26807 env->CP0_Status |= (1 << CP0St_MX);
853c3240 26808 }
4d66261f
PJ
26809# if defined(TARGET_MIPS64)
26810 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26811 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26812 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
26813 env->CP0_Status |= (1 << CP0St_FR);
26814 }
4d66261f 26815# endif
932e71cd
AJ
26816#else
26817 if (env->hflags & MIPS_HFLAG_BMASK) {
26818 /* If the exception was raised from a delay slot,
26819 come back to the jump. */
c3577479
MR
26820 env->CP0_ErrorEPC = (env->active_tc.PC
26821 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 26822 } else {
932e71cd
AJ
26823 env->CP0_ErrorEPC = env->active_tc.PC;
26824 }
89777fd1 26825 env->active_tc.PC = env->exception_base;
51cc2e78
BS
26826 env->CP0_Random = env->tlb->nb_tlb - 1;
26827 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 26828 env->CP0_Wired = 0;
01bc435b 26829 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 26830 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 26831 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
26832 env->CP0_EBase |= 0x40000000;
26833 } else {
74dbf824 26834 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 26835 }
c870e3f5
YK
26836 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26837 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26838 }
a0c80608
PB
26839 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26840 0x3ff : 0xff;
932e71cd
AJ
26841 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26842 /* vectored interrupts not implemented, timer on int 7,
26843 no performance counters. */
26844 env->CP0_IntCtl = 0xe0000000;
26845 {
26846 int i;
26847
26848 for (i = 0; i < 7; i++) {
26849 env->CP0_WatchLo[i] = 0;
26850 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 26851 }
932e71cd
AJ
26852 env->CP0_WatchLo[7] = 0;
26853 env->CP0_WatchHi[7] = 0;
fd88b6ab 26854 }
932e71cd
AJ
26855 /* Count register increments in debug mode, EJTAG version 1 */
26856 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 26857
4b69c7e2
JH
26858 cpu_mips_store_count(env, 1);
26859
9e56e756
EI
26860 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26861 int i;
26862
26863 /* Only TC0 on VPE 0 starts as active. */
26864 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 26865 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
26866 env->tcs[i].CP0_TCHalt = 1;
26867 }
26868 env->active_tc.CP0_TCHalt = 1;
259186a7 26869 cs->halted = 1;
9e56e756 26870
55e5c285 26871 if (cs->cpu_index == 0) {
9e56e756
EI
26872 /* VPE0 starts up enabled. */
26873 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26874 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26875
26876 /* TC0 starts up unhalted. */
259186a7 26877 cs->halted = 0;
9e56e756
EI
26878 env->active_tc.CP0_TCHalt = 0;
26879 env->tcs[0].CP0_TCHalt = 0;
26880 /* With thread 0 active. */
26881 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26882 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26883 }
26884 }
cec56a73
JH
26885
26886 /*
26887 * Configure default legacy segmentation control. We use this regardless of
26888 * whether segmentation control is presented to the guest.
26889 */
26890 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26891 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
26892 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26893 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26894 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26895 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26896 (2 << CP0SC_C);
26897 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26898 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26899 (3 << CP0SC_C)) << 16;
26900 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26901 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26902 (1 << CP0SC_EU) | (2 << CP0SC_C);
26903 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26904 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26905 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26906 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26907 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 26908#endif
ddc584bd
LA
26909 if ((env->insn_flags & ISA_MIPS32R6) &&
26910 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26911 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26912 env->CP0_Status |= (1 << CP0St_FR);
26913 }
26914
63010795
YK
26915 if (env->insn_flags & ISA_MIPS32R6) {
26916 /* PTW = 1 */
26917 env->CP0_PWSize = 0x40;
26918 /* GDI = 12 */
26919 /* UDI = 12 */
26920 /* MDI = 12 */
26921 /* PRI = 12 */
26922 /* PTEI = 2 */
26923 env->CP0_PWField = 0x0C30C302;
26924 } else {
26925 /* GDI = 0 */
26926 /* UDI = 0 */
26927 /* MDI = 0 */
26928 /* PRI = 0 */
26929 /* PTEI = 2 */
26930 env->CP0_PWField = 0x02;
26931 }
26932
0bbc0396
SM
26933 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26934 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
26935 env->hflags |= MIPS_HFLAG_M16;
26936 }
26937
863f264d
YK
26938 /* MSA */
26939 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26940 msa_reset(env);
26941 }
26942
03e6e501 26943 compute_hflags(env);
599bc5e8 26944 restore_fp_status(env);
e117f526 26945 restore_pamask(env);
27103424 26946 cs->exception_index = EXCP_NONE;
3b3c1694
LA
26947
26948 if (semihosting_get_argc()) {
26949 /* UHI interface can be used to obtain argc and argv */
26950 env->active_tc.gpr[4] = -1;
26951 }
6af0bf9c 26952}
d2856f1a 26953
bad729e2
RH
26954void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26955 target_ulong *data)
d2856f1a 26956{
bad729e2 26957 env->active_tc.PC = data[0];
d2856f1a 26958 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 26959 env->hflags |= data[1];
4636401d
AJ
26960 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26961 case MIPS_HFLAG_BR:
26962 break;
26963 case MIPS_HFLAG_BC:
26964 case MIPS_HFLAG_BL:
26965 case MIPS_HFLAG_B:
bad729e2 26966 env->btarget = data[2];
4636401d
AJ
26967 break;
26968 }
d2856f1a 26969}