]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes
[mirror_qemu.git] / target / mips / translate.c
CommitLineData
6af0bf9c 1/*
ab99e0e4 2 * MIPS 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)
96e5b4c7 9 * Copyright (c) 2020 Philippe Mathieu-Daudé
6af0bf9c
FB
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
89975214 14 * version 2.1 of the License, or (at your option) any later version.
6af0bf9c
FB
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
8167ee88 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
23 */
24
c684822a 25#include "qemu/osdep.h"
6af0bf9c 26#include "cpu.h"
26aa3d9a 27#include "internal.h"
dcb32f1d 28#include "tcg/tcg-op.h"
f08b6170 29#include "exec/cpu_ldst.h"
2ef6175a
RH
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
f1672e6f 32#include "hw/semihosting/semihost.h"
a7812ae4 33
b44a7fb1 34#include "target/mips/trace.h"
a7e30d84 35#include "trace-tcg.h"
b28425ba 36#include "exec/translator.h"
508127e2 37#include "exec/log.h"
0442428a 38#include "qemu/qemu-print.h"
81ddae7c 39#include "fpu_helper.h"
e3130936 40#include "translate.h"
a7e30d84 41
e37e863f
FB
42enum {
43 /* indirect opcode tables */
7a387fff
TS
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
7a387fff
TS
47 OPC_CP2 = (0x12 << 26),
48 OPC_CP3 = (0x13 << 26),
49 OPC_SPECIAL2 = (0x1C << 26),
50 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 51 /* arithmetic with immediate */
7a387fff
TS
52 OPC_ADDI = (0x08 << 26),
53 OPC_ADDIU = (0x09 << 26),
54 OPC_SLTI = (0x0A << 26),
55 OPC_SLTIU = (0x0B << 26),
324d9e32 56 /* logic with immediate */
7a387fff
TS
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
324d9e32 61 /* arithmetic with immediate */
7a387fff
TS
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
e37e863f 64 /* Jump and branches */
7a387fff
TS
65 OPC_J = (0x02 << 26),
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
b231c103 75 OPC_JALX = (0x1D << 26),
d4ea6acd 76 OPC_DAUI = (0x1D << 26),
e37e863f 77 /* Load and stores */
7a387fff
TS
78 OPC_LDL = (0x1A << 26),
79 OPC_LDR = (0x1B << 26),
80 OPC_LB = (0x20 << 26),
81 OPC_LH = (0x21 << 26),
82 OPC_LWL = (0x22 << 26),
83 OPC_LW = (0x23 << 26),
364d4831 84 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
85 OPC_LBU = (0x24 << 26),
86 OPC_LHU = (0x25 << 26),
87 OPC_LWR = (0x26 << 26),
88 OPC_LWU = (0x27 << 26),
89 OPC_SB = (0x28 << 26),
90 OPC_SH = (0x29 << 26),
91 OPC_SWL = (0x2A << 26),
92 OPC_SW = (0x2B << 26),
93 OPC_SDL = (0x2C << 26),
94 OPC_SDR = (0x2D << 26),
95 OPC_SWR = (0x2E << 26),
96 OPC_LL = (0x30 << 26),
97 OPC_LLD = (0x34 << 26),
98 OPC_LD = (0x37 << 26),
364d4831 99 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
e37e863f 103 /* Floating point load/store */
7a387fff
TS
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
31837be3
YK
112 /* Compact Branches */
113 OPC_BLEZALC = (0x06 << 26),
114 OPC_BGEZALC = (0x06 << 26),
115 OPC_BGEUC = (0x06 << 26),
116 OPC_BGTZALC = (0x07 << 26),
117 OPC_BLTZALC = (0x07 << 26),
118 OPC_BLTUC = (0x07 << 26),
119 OPC_BOVC = (0x08 << 26),
120 OPC_BEQZALC = (0x08 << 26),
121 OPC_BEQC = (0x08 << 26),
122 OPC_BLEZC = (0x16 << 26),
123 OPC_BGEZC = (0x16 << 26),
124 OPC_BGEC = (0x16 << 26),
125 OPC_BGTZC = (0x17 << 26),
126 OPC_BLTZC = (0x17 << 26),
127 OPC_BLTC = (0x17 << 26),
128 OPC_BNVC = (0x18 << 26),
129 OPC_BNEZALC = (0x18 << 26),
130 OPC_BNEC = (0x18 << 26),
131 OPC_BC = (0x32 << 26),
132 OPC_BEQZC = (0x36 << 26),
133 OPC_JIC = (0x36 << 26),
134 OPC_BALC = (0x3A << 26),
135 OPC_BNEZC = (0x3E << 26),
136 OPC_JIALC = (0x3E << 26),
7a387fff
TS
137 /* MDMX ASE specific */
138 OPC_MDMX = (0x1E << 26),
e37e863f 139 /* Cache and prefetch */
7a387fff
TS
140 OPC_CACHE = (0x2F << 26),
141 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
142 /* PC-relative address computation / loads */
143 OPC_PCREL = (0x3B << 26),
144};
145
146/* PC-relative address computation / loads */
71375b59
AM
147#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
d4ea6acd
LA
149enum {
150 /* Instructions determined by bits 19 and 20 */
151 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
152 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
153 OPC_LWUPC = OPC_PCREL | (2 << 19),
154
155 /* Instructions determined by bits 16 ... 20 */
156 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
157 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
158
159 /* Other */
160 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
161};
162
163/* MIPS special opcodes */
71375b59 164#define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff 165
e37e863f
FB
166enum {
167 /* Shifts */
7a387fff 168 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
169 /* NOP is SLL r0, r0, 0 */
170 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
171 /* EHB is SLL r0, r0, 3 */
172 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 173 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
174 OPC_SRA = 0x03 | OPC_SPECIAL,
175 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 176 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 177 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
178 OPC_SRAV = 0x07 | OPC_SPECIAL,
179 OPC_DSLLV = 0x14 | OPC_SPECIAL,
180 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 181 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
182 OPC_DSRAV = 0x17 | OPC_SPECIAL,
183 OPC_DSLL = 0x38 | OPC_SPECIAL,
184 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 185 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
186 OPC_DSRA = 0x3B | OPC_SPECIAL,
187 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
188 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 189 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 190 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 191 /* Multiplication / division */
7a387fff
TS
192 OPC_MULT = 0x18 | OPC_SPECIAL,
193 OPC_MULTU = 0x19 | OPC_SPECIAL,
194 OPC_DIV = 0x1A | OPC_SPECIAL,
195 OPC_DIVU = 0x1B | OPC_SPECIAL,
196 OPC_DMULT = 0x1C | OPC_SPECIAL,
197 OPC_DMULTU = 0x1D | OPC_SPECIAL,
198 OPC_DDIV = 0x1E | OPC_SPECIAL,
199 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 200
e37e863f 201 /* 2 registers arithmetic / logic */
7a387fff
TS
202 OPC_ADD = 0x20 | OPC_SPECIAL,
203 OPC_ADDU = 0x21 | OPC_SPECIAL,
204 OPC_SUB = 0x22 | OPC_SPECIAL,
205 OPC_SUBU = 0x23 | OPC_SPECIAL,
206 OPC_AND = 0x24 | OPC_SPECIAL,
207 OPC_OR = 0x25 | OPC_SPECIAL,
208 OPC_XOR = 0x26 | OPC_SPECIAL,
209 OPC_NOR = 0x27 | OPC_SPECIAL,
210 OPC_SLT = 0x2A | OPC_SPECIAL,
211 OPC_SLTU = 0x2B | OPC_SPECIAL,
212 OPC_DADD = 0x2C | OPC_SPECIAL,
213 OPC_DADDU = 0x2D | OPC_SPECIAL,
214 OPC_DSUB = 0x2E | OPC_SPECIAL,
215 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 216 /* Jumps */
7a387fff
TS
217 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
218 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 219 /* Traps */
7a387fff
TS
220 OPC_TGE = 0x30 | OPC_SPECIAL,
221 OPC_TGEU = 0x31 | OPC_SPECIAL,
222 OPC_TLT = 0x32 | OPC_SPECIAL,
223 OPC_TLTU = 0x33 | OPC_SPECIAL,
224 OPC_TEQ = 0x34 | OPC_SPECIAL,
225 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 226 /* HI / LO registers load & stores */
7a387fff
TS
227 OPC_MFHI = 0x10 | OPC_SPECIAL,
228 OPC_MTHI = 0x11 | OPC_SPECIAL,
229 OPC_MFLO = 0x12 | OPC_SPECIAL,
230 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 231 /* Conditional moves */
7a387fff
TS
232 OPC_MOVZ = 0x0A | OPC_SPECIAL,
233 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 234
b691d9d2
LA
235 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
236 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
237
7a387fff 238 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
239
240 /* Special */
a0d700e4 241 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
242 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
243 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 244 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
245 OPC_SYNC = 0x0F | OPC_SPECIAL,
246
7a387fff
TS
247 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
248 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
249 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
250 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
251};
252
7480515f
AM
253/*
254 * R6 Multiply and Divide instructions have the same opcode
255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
256 */
71375b59 257#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
b42ee5e1
LA
258
259enum {
260 R6_OPC_MUL = OPC_MULT | (2 << 6),
261 R6_OPC_MUH = OPC_MULT | (3 << 6),
262 R6_OPC_MULU = OPC_MULTU | (2 << 6),
263 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
264 R6_OPC_DIV = OPC_DIV | (2 << 6),
265 R6_OPC_MOD = OPC_DIV | (3 << 6),
266 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
267 R6_OPC_MODU = OPC_DIVU | (3 << 6),
268
269 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
270 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
271 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
272 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
273 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
274 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
275 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
276 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
277
278 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
279 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
280 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
281 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
282 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
283
284 OPC_LSA = 0x05 | OPC_SPECIAL,
285 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
286};
287
e9c71dd1 288/* Multiplication variants of the vr54xx. */
71375b59 289#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
e9c71dd1
TS
290
291enum {
292 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
293 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
294 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
295 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
296 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
297 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
298 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
299 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
301 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
302 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
303 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
304 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
305 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
306};
307
7a387fff 308/* REGIMM (rt field) opcodes */
71375b59 309#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
7a387fff
TS
310
311enum {
312 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
313 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
314 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
315 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
316 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
317 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
318 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
319 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
320 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
321 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
322 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
323 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
324 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
325 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 326 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 327 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
328
329 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
330 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
331};
332
7a387fff 333/* Special2 opcodes */
71375b59 334#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff 335
e37e863f 336enum {
7a387fff
TS
337 /* Multiply & xxx operations */
338 OPC_MADD = 0x00 | OPC_SPECIAL2,
339 OPC_MADDU = 0x01 | OPC_SPECIAL2,
340 OPC_MUL = 0x02 | OPC_SPECIAL2,
341 OPC_MSUB = 0x04 | OPC_SPECIAL2,
342 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
343 /* Loongson 2F */
344 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
345 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
346 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
347 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
348 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
349 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
350 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
351 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
352 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
353 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
354 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
355 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 356 /* Misc */
7a387fff
TS
357 OPC_CLZ = 0x20 | OPC_SPECIAL2,
358 OPC_CLO = 0x21 | OPC_SPECIAL2,
359 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
360 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 361 /* Special */
7a387fff
TS
362 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
363};
364
365/* Special3 opcodes */
71375b59 366#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff
TS
367
368enum {
369 OPC_EXT = 0x00 | OPC_SPECIAL3,
370 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
371 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
372 OPC_DEXT = 0x03 | OPC_SPECIAL3,
373 OPC_INS = 0x04 | OPC_SPECIAL3,
374 OPC_DINSM = 0x05 | OPC_SPECIAL3,
375 OPC_DINSU = 0x06 | OPC_SPECIAL3,
376 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
377 OPC_FORK = 0x08 | OPC_SPECIAL3,
378 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
379 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
380 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
381 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
99029be1 382 OPC_GINV = 0x3D | OPC_SPECIAL3,
161f85e6
AJ
383
384 /* Loongson 2E */
385 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
386 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
387 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
388 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
389 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
390 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
391 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
392 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
393 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
394 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
395 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
396 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
397
398 /* MIPS DSP Load */
399 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
400 /* MIPS DSP Arithmetic */
401 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 402 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 403 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 404 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
405 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
406 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
407 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 408 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
409 /* MIPS DSP GPR-Based Shift Sub-class */
410 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 411 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
412 /* MIPS DSP Multiply Sub-class insns */
413 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
414 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
415 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 416 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
417 /* DSP Bit/Manipulation Sub-class */
418 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 419 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 420 /* MIPS DSP Append Sub-class */
26690560 421 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 422 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
423 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
424 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 425 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 426
76964147
JH
427 /* EVA */
428 OPC_LWLE = 0x19 | OPC_SPECIAL3,
429 OPC_LWRE = 0x1A | OPC_SPECIAL3,
430 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
431 OPC_SBE = 0x1C | OPC_SPECIAL3,
432 OPC_SHE = 0x1D | OPC_SPECIAL3,
433 OPC_SCE = 0x1E | OPC_SPECIAL3,
434 OPC_SWE = 0x1F | OPC_SPECIAL3,
435 OPC_SWLE = 0x21 | OPC_SPECIAL3,
436 OPC_SWRE = 0x22 | OPC_SPECIAL3,
437 OPC_PREFE = 0x23 | OPC_SPECIAL3,
438 OPC_LBUE = 0x28 | OPC_SPECIAL3,
439 OPC_LHUE = 0x29 | OPC_SPECIAL3,
440 OPC_LBE = 0x2C | OPC_SPECIAL3,
441 OPC_LHE = 0x2D | OPC_SPECIAL3,
442 OPC_LLE = 0x2E | OPC_SPECIAL3,
443 OPC_LWE = 0x2F | OPC_SPECIAL3,
444
4368b29a 445 /* R6 */
bf7910c6
LA
446 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
447 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
448 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
449 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
450 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
451 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
452};
453
e10a0ca1
JY
454/* Loongson EXT load/store quad word opcodes */
455#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
456enum {
457 OPC_GSLQ = 0x0020 | OPC_LWC2,
458 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
459 OPC_GSSHFL = OPC_LWC2,
460 OPC_GSSQ = 0x0020 | OPC_SWC2,
461 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
462 OPC_GSSHFS = OPC_SWC2,
463};
464
fd723105
JY
465/* Loongson EXT shifted load/store opcodes */
466#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
467enum {
468 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
469 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
470 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
471 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
472 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
473 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
474 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
475 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
476};
477
90e22a57
JY
478/* Loongson EXT LDC2/SDC2 opcodes */
479#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
480
481enum {
482 OPC_GSLBX = 0x0 | OPC_LDC2,
483 OPC_GSLHX = 0x1 | OPC_LDC2,
484 OPC_GSLWX = 0x2 | OPC_LDC2,
485 OPC_GSLDX = 0x3 | OPC_LDC2,
486 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
487 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
488 OPC_GSSBX = 0x0 | OPC_SDC2,
489 OPC_GSSHX = 0x1 | OPC_SDC2,
490 OPC_GSSWX = 0x2 | OPC_SDC2,
491 OPC_GSSDX = 0x3 | OPC_SDC2,
492 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
493 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
494};
495
7a387fff 496/* BSHFL opcodes */
71375b59 497#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
7a387fff 498
e37e863f 499enum {
15eacb9b
YK
500 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
501 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
502 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
373ecd38
AM
503 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
504 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
505 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
506 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
15eacb9b 507 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
508};
509
7a387fff 510/* DBSHFL opcodes */
71375b59 511#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
7a387fff 512
e37e863f 513enum {
15eacb9b
YK
514 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
515 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
373ecd38
AM
516 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
517 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
518 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
519 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
520 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
521 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
522 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
523 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
15eacb9b 524 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
525};
526
e45a93e2
JL
527/* MIPS DSP REGIMM opcodes */
528enum {
529 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 530 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
531};
532
71375b59 533#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
9b1a1d68
JL
534/* MIPS DSP Load */
535enum {
536 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
537 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
538 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 539 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
540};
541
71375b59 542#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
543enum {
544 /* MIPS DSP Arithmetic Sub-class */
545 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
546 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
547 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
549 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
550 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
551 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
552 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
553 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
554 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
555 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
556 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
557 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
558 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
559 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
560 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
561 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
562 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
563 /* MIPS DSP Multiply Sub-class insns */
564 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
565 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
566 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
567 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
568 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
569 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
570};
571
572#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
71375b59 573#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
574enum {
575 /* MIPS DSP Arithmetic Sub-class */
576 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
577 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
578 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
579 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
580 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
582 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
583 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
584 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
585 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
586 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
587 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
588 /* MIPS DSP Multiply Sub-class insns */
589 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
590 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
591 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
592 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
593};
594
71375b59 595#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
596enum {
597 /* MIPS DSP Arithmetic Sub-class */
598 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
600 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
601 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
606 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
607 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
608 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
609 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
610 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
611 /* DSP Bit/Manipulation Sub-class */
612 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
613 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
614 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
615 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
616 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
617};
618
71375b59 619#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
620enum {
621 /* MIPS DSP Arithmetic Sub-class */
622 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
629 /* DSP Compare-Pick Sub-class */
630 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
634 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
635 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
636 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
637 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
638 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
639 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
640 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
641 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
642 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
643 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
644 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 645};
a22260ae 646
71375b59 647#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
77c5fa8b
JL
648enum {
649 /* MIPS DSP GPR-Based Shift Sub-class */
650 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
661 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
662 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
663 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
664 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
665 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
666 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
667 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
668 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
669 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
670 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
671 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
672};
461c08df 673
71375b59 674#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
a22260ae
JL
675enum {
676 /* MIPS DSP Multiply Sub-class insns */
677 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
680 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
683 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
686 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
688 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
689 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
690 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
691 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
692 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
693 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
694 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
695 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
696 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
697 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
698 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
699};
700
71375b59 701#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
1cb6686c
JL
702enum {
703 /* DSP Bit/Manipulation Sub-class */
704 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
705};
706
71375b59 707#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
26690560 708enum {
df6126a7 709 /* MIPS DSP Append Sub-class */
26690560
JL
710 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
711 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
712 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
713};
714
71375b59 715#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
b53371ed
JL
716enum {
717 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
718 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
719 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
720 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
721 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
722 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
723 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
724 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
725 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
726 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
727 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
728 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
729 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
730 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
731 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
732 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
733 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
734 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
735};
736
71375b59 737#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
738enum {
739 /* MIPS DSP Arithmetic Sub-class */
740 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
746 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
747 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
753 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
754 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
755 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
756 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
757 /* DSP Bit/Manipulation Sub-class */
758 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
759 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
760 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
761 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
762 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
763 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 764};
461c08df 765
71375b59 766#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df 767enum {
a22260ae
JL
768 /* MIPS DSP Multiply Sub-class insns */
769 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
770 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
771 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
772 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
773 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
774 /* MIPS DSP Arithmetic Sub-class */
775 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
776 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
777 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
778 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
779 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
780 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
781 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
782 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
783 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
784 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
785 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
786 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
787 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
788 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
789 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
790 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
791 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
792 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
793 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
794 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
795 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
796};
461c08df 797
71375b59 798#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df 799enum {
26690560
JL
800 /* DSP Compare-Pick Sub-class */
801 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
809 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
810 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
818 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
819 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
820 /* MIPS DSP Arithmetic Sub-class */
821 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
822 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
823 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
824 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
825 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
826 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
827 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
828 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
829};
461c08df 830
71375b59 831#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
26690560 832enum {
df6126a7 833 /* DSP Append Sub-class */
26690560
JL
834 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
835 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
836 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
837 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
838};
26690560 839
71375b59 840#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
b53371ed
JL
841enum {
842 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
843 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
844 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
853 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
854 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
855 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
856 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
857 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
858 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
859 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
860 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
861 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
862 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
863 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
864};
865
71375b59 866#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
1cb6686c
JL
867enum {
868 /* DSP Bit/Manipulation Sub-class */
869 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
870};
1cb6686c 871
71375b59 872#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
a22260ae
JL
873enum {
874 /* MIPS DSP Multiply Sub-class insns */
875 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
890 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
891 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
892 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
893 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
894 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
895 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
896 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
897 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
898 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
899 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
900 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
901};
a22260ae 902
71375b59 903#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
77c5fa8b
JL
904enum {
905 /* MIPS DSP GPR-Based Shift Sub-class */
906 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
921 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
922 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
923 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
924 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
925 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
926 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
927 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
928 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
929 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
930 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
931 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
932};
77c5fa8b 933
7a387fff 934/* Coprocessor 0 (rs field) */
71375b59 935#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
7a387fff 936
6ea83fed 937enum {
7a387fff
TS
938 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
939 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 940 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
941 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
942 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 943 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 944 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
945 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
946 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 947 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
948 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
949 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
950 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
951 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
952 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
953 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
954 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
955 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
956 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
957 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
958 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
959 OPC_C0_A = (0x1A << 21) | OPC_CP0,
960 OPC_C0_B = (0x1B << 21) | OPC_CP0,
961 OPC_C0_C = (0x1C << 21) | OPC_CP0,
962 OPC_C0_D = (0x1D << 21) | OPC_CP0,
963 OPC_C0_E = (0x1E << 21) | OPC_CP0,
964 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 965};
7a387fff
TS
966
967/* MFMC0 opcodes */
71375b59 968#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
7a387fff
TS
969
970enum {
ead9360e
TS
971 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
972 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
973 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
974 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
975 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
976 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
977 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
978 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
979};
980
981/* Coprocessor 0 (with rs == C0) */
71375b59 982#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
7a387fff
TS
983
984enum {
985 OPC_TLBR = 0x01 | OPC_C0,
986 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
987 OPC_TLBINV = 0x03 | OPC_C0,
988 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
989 OPC_TLBWR = 0x06 | OPC_C0,
990 OPC_TLBP = 0x08 | OPC_C0,
991 OPC_RFE = 0x10 | OPC_C0,
992 OPC_ERET = 0x18 | OPC_C0,
993 OPC_DERET = 0x1F | OPC_C0,
994 OPC_WAIT = 0x20 | OPC_C0,
995};
996
71375b59 997#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
e0c84da7
TS
998
999enum {
1000 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1001 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1002 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1003 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1004 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1005 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1006 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1007 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1008 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1009 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1010 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1011};
1012
8e2d5831 1013#define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
bd277fa1
RH
1014
1015enum {
71375b59
AM
1016 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1017 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1018 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1019 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1020 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1021 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1022 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1023 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1024
1025 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1026 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1027 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1028 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1029 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1030 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1031 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1032 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1033
1034 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1035 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1036 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1037 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1038 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1039 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1040 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1041 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1042
1043 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1044 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1045 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1046 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1047 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1048 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1049 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1050 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1051
1052 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1053 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1054 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1055 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1056 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1057 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1058
1059 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1060 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1061 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1062 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1063 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1064 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1065
1066 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1067 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1068 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1069 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1070 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1071 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1072
1073 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1074 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1075 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1076 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1077 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1078 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1079
1080 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1081 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1082 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1083 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1084 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1085 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1086
1087 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1088 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1089 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1090 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1091 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1092 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1093
1094 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1095 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1096 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1097 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1098 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1099 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1100
1101 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1102 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1103 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1104 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1105 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1106 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
bd277fa1
RH
1107};
1108
1109
71375b59 1110#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
e0c84da7
TS
1111
1112enum {
71375b59
AM
1113 OPC_LWXC1 = 0x00 | OPC_CP3,
1114 OPC_LDXC1 = 0x01 | OPC_CP3,
1115 OPC_LUXC1 = 0x05 | OPC_CP3,
1116 OPC_SWXC1 = 0x08 | OPC_CP3,
1117 OPC_SDXC1 = 0x09 | OPC_CP3,
1118 OPC_SUXC1 = 0x0D | OPC_CP3,
1119 OPC_PREFX = 0x0F | OPC_CP3,
1120 OPC_ALNV_PS = 0x1E | OPC_CP3,
1121 OPC_MADD_S = 0x20 | OPC_CP3,
1122 OPC_MADD_D = 0x21 | OPC_CP3,
1123 OPC_MADD_PS = 0x26 | OPC_CP3,
1124 OPC_MSUB_S = 0x28 | OPC_CP3,
1125 OPC_MSUB_D = 0x29 | OPC_CP3,
1126 OPC_MSUB_PS = 0x2E | OPC_CP3,
1127 OPC_NMADD_S = 0x30 | OPC_CP3,
1128 OPC_NMADD_D = 0x31 | OPC_CP3,
1129 OPC_NMADD_PS = 0x36 | OPC_CP3,
1130 OPC_NMSUB_S = 0x38 | OPC_CP3,
1131 OPC_NMSUB_D = 0x39 | OPC_CP3,
1132 OPC_NMSUB_PS = 0x3E | OPC_CP3,
e0c84da7
TS
1133};
1134
b158d449 1135/*
b158d449 1136 *
84e2c895
AM
1137 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1138 * ============================================
1139 *
1140 *
1141 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
b158d449
AM
1142 * instructions set. It is designed to fit the needs of signal, graphical and
1143 * video processing applications. MXU instruction set is used in Xburst family
1144 * of microprocessors by Ingenic.
1145 *
1146 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1147 * the control register.
1148 *
093ade12 1149 *
84e2c895
AM
1150 * The notation used in MXU assembler mnemonics
1151 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1152 *
1153 * Register operands:
1d0e663c
AM
1154 *
1155 * XRa, XRb, XRc, XRd - MXU registers
1156 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
093ade12 1157 *
84e2c895 1158 * Non-register operands:
093ade12 1159 *
84e2c895
AM
1160 * aptn1 - 1-bit accumulate add/subtract pattern
1161 * aptn2 - 2-bit accumulate add/subtract pattern
1162 * eptn2 - 2-bit execute add/subtract pattern
1163 * optn2 - 2-bit operand pattern
1164 * optn3 - 3-bit operand pattern
1165 * sft4 - 4-bit shift amount
1166 * strd2 - 2-bit stride amount
093ade12
AM
1167 *
1168 * Prefixes:
1169 *
84e2c895
AM
1170 * Level of parallelism: Operand size:
1171 * S - single operation at a time 32 - word
1172 * D - two operations in parallel 16 - half word
1173 * Q - four operations in parallel 8 - byte
093ade12
AM
1174 *
1175 * Operations:
1176 *
1177 * ADD - Add or subtract
1178 * ADDC - Add with carry-in
1179 * ACC - Accumulate
1180 * ASUM - Sum together then accumulate (add or subtract)
1181 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1182 * AVG - Average between 2 operands
1183 * ABD - Absolute difference
1184 * ALN - Align data
1185 * AND - Logical bitwise 'and' operation
1186 * CPS - Copy sign
1187 * EXTR - Extract bits
1188 * I2M - Move from GPR register to MXU register
1189 * LDD - Load data from memory to XRF
1190 * LDI - Load data from memory to XRF (and increase the address base)
1191 * LUI - Load unsigned immediate
1192 * MUL - Multiply
1193 * MULU - Unsigned multiply
1194 * MADD - 64-bit operand add 32x32 product
1195 * MSUB - 64-bit operand subtract 32x32 product
1196 * MAC - Multiply and accumulate (add or subtract)
1197 * MAD - Multiply and add or subtract
1198 * MAX - Maximum between 2 operands
1199 * MIN - Minimum between 2 operands
1200 * M2I - Move from MXU register to GPR register
1201 * MOVZ - Move if zero
1202 * MOVN - Move if non-zero
1203 * NOR - Logical bitwise 'nor' operation
1204 * OR - Logical bitwise 'or' operation
1205 * STD - Store data from XRF to memory
1206 * SDI - Store data from XRF to memory (and increase the address base)
1207 * SLT - Set of less than comparison
1208 * SAD - Sum of absolute differences
1209 * SLL - Logical shift left
1210 * SLR - Logical shift right
1211 * SAR - Arithmetic shift right
1212 * SAT - Saturation
1213 * SFL - Shuffle
1214 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1215 * XOR - Logical bitwise 'exclusive or' operation
1d0e663c 1216 *
84e2c895
AM
1217 * Suffixes:
1218 *
1219 * E - Expand results
1220 * F - Fixed point multiplication
1221 * L - Low part result
1222 * R - Doing rounding
1223 * V - Variable instead of immediate
1224 * W - Combine above L and V
1225 *
1226 *
1227 * The list of MXU instructions grouped by functionality
1228 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1229 *
1d0e663c
AM
1230 * Load/Store instructions Multiplication instructions
1231 * ----------------------- ---------------------------
1232 *
1233 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1234 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
093ade12
AM
1235 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1236 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1d0e663c
AM
1237 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1238 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1239 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1240 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1241 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1242 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1243 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1244 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1245 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1246 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1247 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1248 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1249 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1250 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1251 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1252 * S16SDI XRa, Rb, s10, eptn2
1253 * S8LDD XRa, Rb, s8, eptn3
1254 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1255 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1256 * S8SDI XRa, Rb, s8, eptn3
1257 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1258 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1259 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1260 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1261 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1262 * S32CPS XRa, XRb, XRc
1263 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1264 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1265 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1266 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1267 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1268 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1269 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1270 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1271 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1272 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1273 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1274 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1275 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1276 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1277 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1278 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1279 * Q8SLT XRa, XRb, XRc
1280 * Q8SLTU XRa, XRb, XRc
1281 * Q8MOVZ XRa, XRb, XRc Shift instructions
1282 * Q8MOVN XRa, XRb, XRc ------------------
1283 *
1284 * D32SLL XRa, XRb, XRc, XRd, sft4
1285 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1286 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1287 * D32SARL XRa, XRb, XRc, sft4
1288 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1289 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1290 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1291 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1292 * Q16SLL XRa, XRb, XRc, XRd, sft4
1293 * Q16SLR XRa, XRb, XRc, XRd, sft4
eab0bdb0 1294 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1d0e663c
AM
1295 * ------------------------- Q16SLLV XRa, XRb, Rb
1296 * Q16SLRV XRa, XRb, Rb
1297 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1298 * S32ALN XRa, XRb, XRc, Rb
1299 * S32ALNI XRa, XRb, XRc, s3
1300 * S32LUI XRa, s8, optn3 Move instructions
1301 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1302 * S32EXTRV XRa, XRb, Rs, Rt
1303 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1304 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1305 *
9ef5bff9 1306 *
84e2c895
AM
1307 * The opcode organization of MXU instructions
1308 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1309 *
1310 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1311 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1312 * other bits up to the instruction level is as follows:
1313 *
9ef5bff9
AM
1314 * bits
1315 * 05..00
1316 *
1317 * ┌─ 000000 ─ OPC_MXU_S32MADD
1318 * ├─ 000001 ─ OPC_MXU_S32MADDU
eab0bdb0
AM
1319 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1320 * │
9ef5bff9
AM
1321 * │ 20..18
1322 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1323 * │ ├─ 001 ─ OPC_MXU_S32MIN
1324 * │ ├─ 010 ─ OPC_MXU_D16MAX
1325 * │ ├─ 011 ─ OPC_MXU_D16MIN
1326 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1327 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1328 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1329 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1330 * ├─ 000100 ─ OPC_MXU_S32MSUB
1331 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1332 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1333 * │ ├─ 001 ─ OPC_MXU_D16SLT
1334 * │ ├─ 010 ─ OPC_MXU_D16AVG
1335 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1336 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1337 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1338 * │ └─ 111 ─ OPC_MXU_Q8ADD
1339 * │
1340 * │ 20..18
1341 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1342 * │ ├─ 010 ─ OPC_MXU_D16CPS
1343 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1344 * │ └─ 110 ─ OPC_MXU_Q16SAT
1345 * ├─ 001000 ─ OPC_MXU_D16MUL
1346 * │ 25..24
1347 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1348 * │ └─ 01 ─ OPC_MXU_D16MULE
1349 * ├─ 001010 ─ OPC_MXU_D16MAC
1350 * ├─ 001011 ─ OPC_MXU_D16MACF
1351 * ├─ 001100 ─ OPC_MXU_D16MADL
eab0bdb0 1352 * ├─ 001101 ─ OPC_MXU_S16MAD
9ef5bff9 1353 * ├─ 001110 ─ OPC_MXU_Q16ADD
eab0bdb0
AM
1354 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1355 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1356 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
9ef5bff9
AM
1357 * │
1358 * │ 23
eab0bdb0 1359 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
9ef5bff9
AM
1360 * │ └─ 1 ─ OPC_MXU_S32STDR
1361 * │
1362 * │ 13..10
eab0bdb0 1363 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
9ef5bff9
AM
1364 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1365 * │
1366 * │ 13..10
eab0bdb0 1367 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
9ef5bff9
AM
1368 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1369 * │
1370 * │ 23
eab0bdb0 1371 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
9ef5bff9
AM
1372 * │ └─ 1 ─ OPC_MXU_S32LDIR
1373 * │
1374 * │ 23
eab0bdb0 1375 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
9ef5bff9
AM
1376 * │ └─ 1 ─ OPC_MXU_S32SDIR
1377 * │
1378 * │ 13..10
eab0bdb0 1379 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
9ef5bff9
AM
1380 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1381 * │
1382 * │ 13..10
eab0bdb0 1383 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
9ef5bff9
AM
1384 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1385 * ├─ 011000 ─ OPC_MXU_D32ADD
1386 * │ 23..22
eab0bdb0 1387 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
9ef5bff9
AM
1388 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1389 * │ └─ 10 ─ OPC_MXU_D32ASUM
1390 * ├─ 011010 ─ <not assigned>
1391 * │ 23..22
eab0bdb0 1392 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
9ef5bff9
AM
1393 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1394 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1395 * │
1396 * │ 23..22
eab0bdb0 1397 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
9ef5bff9
AM
1398 * │ ├─ 01 ─ OPC_MXU_D8SUM
1399 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1400 * ├─ 011110 ─ <not assigned>
1401 * ├─ 011111 ─ <not assigned>
eab0bdb0
AM
1402 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1403 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
9ef5bff9 1404 * ├─ 100010 ─ OPC_MXU_S8LDD
eab0bdb0
AM
1405 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1406 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1407 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
9ef5bff9 1408 * │ ├─ 00 ─ OPC_MXU_S32EXTR
eab0bdb0 1409 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
9ef5bff9
AM
1410 * │
1411 * │ 20..18
eab0bdb0 1412 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
9ef5bff9 1413 * │ ├─ 001 ─ OPC_MXU_S32ALN
c233bf07 1414 * │ ├─ 010 ─ OPC_MXU_S32ALNI
b621f018
AM
1415 * │ ├─ 011 ─ OPC_MXU_S32LUI
1416 * │ ├─ 100 ─ OPC_MXU_S32NOR
1417 * │ ├─ 101 ─ OPC_MXU_S32AND
1418 * │ ├─ 110 ─ OPC_MXU_S32OR
1419 * │ └─ 111 ─ OPC_MXU_S32XOR
c233bf07
AM
1420 * │
1421 * │ 7..5
1422 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1423 * │ ├─ 001 ─ OPC_MXU_LXH
1424 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1425 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1426 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1427 * ├─ 101100 ─ OPC_MXU_S16LDI
1428 * ├─ 101101 ─ OPC_MXU_S16SDI
9ef5bff9
AM
1429 * ├─ 101110 ─ OPC_MXU_S32M2I
1430 * ├─ 101111 ─ OPC_MXU_S32I2M
1431 * ├─ 110000 ─ OPC_MXU_D32SLL
eab0bdb0
AM
1432 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1433 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1434 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1435 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1436 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
9ef5bff9 1437 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
c233bf07 1438 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
eab0bdb0 1439 * │
9ef5bff9
AM
1440 * ├─ 110111 ─ OPC_MXU_Q16SAR
1441 * │ 23..22
c233bf07 1442 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
9ef5bff9
AM
1443 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1444 * │
1445 * │ 20..18
c233bf07 1446 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
9ef5bff9
AM
1447 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1448 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1449 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1450 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
84e2c895 1451 * │ └─ 101 ─ OPC_MXU_S32MOVN
9ef5bff9
AM
1452 * │
1453 * │ 23..22
c233bf07 1454 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
9ef5bff9
AM
1455 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1456 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1457 * ├─ 111100 ─ OPC_MXU_Q8MADL
1458 * ├─ 111101 ─ OPC_MXU_S32SFL
1459 * ├─ 111110 ─ OPC_MXU_Q8SAD
eab0bdb0 1460 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
9ef5bff9
AM
1461 *
1462 *
84e2c895 1463 * Compiled after:
b158d449
AM
1464 *
1465 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
84e2c895 1466 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
b158d449
AM
1467 */
1468
8bacd1ff
AM
1469enum {
1470 OPC_MXU_S32MADD = 0x00,
1471 OPC_MXU_S32MADDU = 0x01,
11d56f61 1472 OPC__MXU_MUL = 0x02,
8bacd1ff
AM
1473 OPC_MXU__POOL00 = 0x03,
1474 OPC_MXU_S32MSUB = 0x04,
1475 OPC_MXU_S32MSUBU = 0x05,
1476 OPC_MXU__POOL01 = 0x06,
1477 OPC_MXU__POOL02 = 0x07,
1478 OPC_MXU_D16MUL = 0x08,
1479 OPC_MXU__POOL03 = 0x09,
1480 OPC_MXU_D16MAC = 0x0A,
1481 OPC_MXU_D16MACF = 0x0B,
1482 OPC_MXU_D16MADL = 0x0C,
eab0bdb0 1483 OPC_MXU_S16MAD = 0x0D,
8bacd1ff
AM
1484 OPC_MXU_Q16ADD = 0x0E,
1485 OPC_MXU_D16MACE = 0x0F,
eab0bdb0
AM
1486 OPC_MXU__POOL04 = 0x10,
1487 OPC_MXU__POOL05 = 0x11,
1488 OPC_MXU__POOL06 = 0x12,
1489 OPC_MXU__POOL07 = 0x13,
1490 OPC_MXU__POOL08 = 0x14,
1491 OPC_MXU__POOL09 = 0x15,
1492 OPC_MXU__POOL10 = 0x16,
1493 OPC_MXU__POOL11 = 0x17,
8bacd1ff 1494 OPC_MXU_D32ADD = 0x18,
eab0bdb0 1495 OPC_MXU__POOL12 = 0x19,
8bacd1ff 1496 /* not assigned 0x1A */
eab0bdb0
AM
1497 OPC_MXU__POOL13 = 0x1B,
1498 OPC_MXU__POOL14 = 0x1C,
8bacd1ff
AM
1499 OPC_MXU_Q8ACCE = 0x1D,
1500 /* not assigned 0x1E */
1501 /* not assigned 0x1F */
1502 /* not assigned 0x20 */
1503 /* not assigned 0x21 */
1504 OPC_MXU_S8LDD = 0x22,
1505 OPC_MXU_S8STD = 0x23,
1506 OPC_MXU_S8LDI = 0x24,
1507 OPC_MXU_S8SDI = 0x25,
eab0bdb0
AM
1508 OPC_MXU__POOL15 = 0x26,
1509 OPC_MXU__POOL16 = 0x27,
c233bf07 1510 OPC_MXU__POOL17 = 0x28,
8bacd1ff
AM
1511 /* not assigned 0x29 */
1512 OPC_MXU_S16LDD = 0x2A,
1513 OPC_MXU_S16STD = 0x2B,
1514 OPC_MXU_S16LDI = 0x2C,
1515 OPC_MXU_S16SDI = 0x2D,
1516 OPC_MXU_S32M2I = 0x2E,
1517 OPC_MXU_S32I2M = 0x2F,
1518 OPC_MXU_D32SLL = 0x30,
1519 OPC_MXU_D32SLR = 0x31,
1520 OPC_MXU_D32SARL = 0x32,
1521 OPC_MXU_D32SAR = 0x33,
1522 OPC_MXU_Q16SLL = 0x34,
1523 OPC_MXU_Q16SLR = 0x35,
c233bf07 1524 OPC_MXU__POOL18 = 0x36,
8bacd1ff 1525 OPC_MXU_Q16SAR = 0x37,
c233bf07
AM
1526 OPC_MXU__POOL19 = 0x38,
1527 OPC_MXU__POOL20 = 0x39,
1528 OPC_MXU__POOL21 = 0x3A,
8bacd1ff
AM
1529 OPC_MXU_Q16SCOP = 0x3B,
1530 OPC_MXU_Q8MADL = 0x3C,
1531 OPC_MXU_S32SFL = 0x3D,
1532 OPC_MXU_Q8SAD = 0x3E,
1533 /* not assigned 0x3F */
1534};
1535
1536
1537/*
1538 * MXU pool 00
1539 */
1540enum {
1541 OPC_MXU_S32MAX = 0x00,
1542 OPC_MXU_S32MIN = 0x01,
1543 OPC_MXU_D16MAX = 0x02,
1544 OPC_MXU_D16MIN = 0x03,
1545 OPC_MXU_Q8MAX = 0x04,
1546 OPC_MXU_Q8MIN = 0x05,
1547 OPC_MXU_Q8SLT = 0x06,
1548 OPC_MXU_Q8SLTU = 0x07,
1549};
1550
1551/*
1552 * MXU pool 01
1553 */
1554enum {
1555 OPC_MXU_S32SLT = 0x00,
1556 OPC_MXU_D16SLT = 0x01,
1557 OPC_MXU_D16AVG = 0x02,
1558 OPC_MXU_D16AVGR = 0x03,
1559 OPC_MXU_Q8AVG = 0x04,
1560 OPC_MXU_Q8AVGR = 0x05,
1561 OPC_MXU_Q8ADD = 0x07,
1562};
1563
1564/*
1565 * MXU pool 02
1566 */
1567enum {
1568 OPC_MXU_S32CPS = 0x00,
1569 OPC_MXU_D16CPS = 0x02,
1570 OPC_MXU_Q8ABD = 0x04,
1571 OPC_MXU_Q16SAT = 0x06,
1572};
1573
1574/*
1575 * MXU pool 03
1576 */
1577enum {
1578 OPC_MXU_D16MULF = 0x00,
1579 OPC_MXU_D16MULE = 0x01,
1580};
1581
1582/*
1583 * MXU pool 04
1584 */
8bacd1ff
AM
1585enum {
1586 OPC_MXU_S32LDD = 0x00,
1587 OPC_MXU_S32LDDR = 0x01,
1588};
1589
1590/*
eab0bdb0 1591 * MXU pool 05
8bacd1ff
AM
1592 */
1593enum {
1594 OPC_MXU_S32STD = 0x00,
1595 OPC_MXU_S32STDR = 0x01,
1596};
1597
1598/*
eab0bdb0 1599 * MXU pool 06
8bacd1ff
AM
1600 */
1601enum {
1602 OPC_MXU_S32LDDV = 0x00,
1603 OPC_MXU_S32LDDVR = 0x01,
1604};
1605
1606/*
eab0bdb0 1607 * MXU pool 07
8bacd1ff
AM
1608 */
1609enum {
1610 OPC_MXU_S32STDV = 0x00,
1611 OPC_MXU_S32STDVR = 0x01,
1612};
1613
1614/*
eab0bdb0 1615 * MXU pool 08
8bacd1ff
AM
1616 */
1617enum {
1618 OPC_MXU_S32LDI = 0x00,
1619 OPC_MXU_S32LDIR = 0x01,
1620};
1621
1622/*
eab0bdb0 1623 * MXU pool 09
8bacd1ff
AM
1624 */
1625enum {
1626 OPC_MXU_S32SDI = 0x00,
1627 OPC_MXU_S32SDIR = 0x01,
1628};
1629
1630/*
eab0bdb0 1631 * MXU pool 10
8bacd1ff
AM
1632 */
1633enum {
1634 OPC_MXU_S32LDIV = 0x00,
1635 OPC_MXU_S32LDIVR = 0x01,
1636};
1637
1638/*
eab0bdb0 1639 * MXU pool 11
8bacd1ff
AM
1640 */
1641enum {
1642 OPC_MXU_S32SDIV = 0x00,
1643 OPC_MXU_S32SDIVR = 0x01,
1644};
1645
1646/*
eab0bdb0 1647 * MXU pool 12
8bacd1ff
AM
1648 */
1649enum {
1650 OPC_MXU_D32ACC = 0x00,
1651 OPC_MXU_D32ACCM = 0x01,
1652 OPC_MXU_D32ASUM = 0x02,
1653};
1654
1655/*
eab0bdb0 1656 * MXU pool 13
8bacd1ff
AM
1657 */
1658enum {
1659 OPC_MXU_Q16ACC = 0x00,
1660 OPC_MXU_Q16ACCM = 0x01,
1661 OPC_MXU_Q16ASUM = 0x02,
1662};
1663
1664/*
eab0bdb0 1665 * MXU pool 14
8bacd1ff
AM
1666 */
1667enum {
1668 OPC_MXU_Q8ADDE = 0x00,
1669 OPC_MXU_D8SUM = 0x01,
1670 OPC_MXU_D8SUMC = 0x02,
1671};
1672
1673/*
eab0bdb0 1674 * MXU pool 15
8bacd1ff
AM
1675 */
1676enum {
1677 OPC_MXU_S32MUL = 0x00,
1678 OPC_MXU_S32MULU = 0x01,
1679 OPC_MXU_S32EXTR = 0x02,
1680 OPC_MXU_S32EXTRV = 0x03,
1681};
1682
1683/*
eab0bdb0 1684 * MXU pool 16
8bacd1ff
AM
1685 */
1686enum {
1687 OPC_MXU_D32SARW = 0x00,
1688 OPC_MXU_S32ALN = 0x01,
1689 OPC_MXU_S32ALNI = 0x02,
b621f018
AM
1690 OPC_MXU_S32LUI = 0x03,
1691 OPC_MXU_S32NOR = 0x04,
1692 OPC_MXU_S32AND = 0x05,
1693 OPC_MXU_S32OR = 0x06,
1694 OPC_MXU_S32XOR = 0x07,
8bacd1ff
AM
1695};
1696
1697/*
eab0bdb0 1698 * MXU pool 17
8bacd1ff 1699 */
c233bf07
AM
1700enum {
1701 OPC_MXU_LXB = 0x00,
1702 OPC_MXU_LXH = 0x01,
1703 OPC_MXU_LXW = 0x03,
1704 OPC_MXU_LXBU = 0x04,
1705 OPC_MXU_LXHU = 0x05,
1706};
1707
1708/*
1709 * MXU pool 18
1710 */
8bacd1ff
AM
1711enum {
1712 OPC_MXU_D32SLLV = 0x00,
1713 OPC_MXU_D32SLRV = 0x01,
1714 OPC_MXU_D32SARV = 0x03,
1715 OPC_MXU_Q16SLLV = 0x04,
1716 OPC_MXU_Q16SLRV = 0x05,
1717 OPC_MXU_Q16SARV = 0x07,
1718};
1719
1720/*
c233bf07 1721 * MXU pool 19
8bacd1ff
AM
1722 */
1723enum {
1724 OPC_MXU_Q8MUL = 0x00,
1725 OPC_MXU_Q8MULSU = 0x01,
1726};
1727
1728/*
c233bf07 1729 * MXU pool 20
8bacd1ff
AM
1730 */
1731enum {
1732 OPC_MXU_Q8MOVZ = 0x00,
1733 OPC_MXU_Q8MOVN = 0x01,
1734 OPC_MXU_D16MOVZ = 0x02,
1735 OPC_MXU_D16MOVN = 0x03,
1736 OPC_MXU_S32MOVZ = 0x04,
1737 OPC_MXU_S32MOVN = 0x05,
1738};
1739
1740/*
c233bf07 1741 * MXU pool 21
8bacd1ff
AM
1742 */
1743enum {
1744 OPC_MXU_Q8MAC = 0x00,
1745 OPC_MXU_Q8MACSU = 0x01,
1746};
1747
497f072b
FN
1748/*
1749 * Overview of the TX79-specific instruction set
1750 * =============================================
1751 *
1752 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1753 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1754 * instructions and certain multimedia instructions (MMIs). These MMIs
1755 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1756 * or sixteen 8-bit paths.
1757 *
1758 * Reference:
1759 *
1760 * The Toshiba TX System RISC TX79 Core Architecture manual,
1761 * https://wiki.qemu.org/File:C790.pdf
1762 *
1763 * Three-Operand Multiply and Multiply-Add (4 instructions)
1764 * --------------------------------------------------------
1765 * MADD [rd,] rs, rt Multiply/Add
1766 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1767 * MULT [rd,] rs, rt Multiply (3-operand)
1768 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1769 *
1770 * Multiply Instructions for Pipeline 1 (10 instructions)
1771 * ------------------------------------------------------
1772 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1773 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1774 * DIV1 rs, rt Divide Pipeline 1
1775 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1776 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1777 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1778 * MFHI1 rd Move From HI1 Register
1779 * MFLO1 rd Move From LO1 Register
1780 * MTHI1 rs Move To HI1 Register
1781 * MTLO1 rs Move To LO1 Register
1782 *
1783 * Arithmetic (19 instructions)
1784 * ----------------------------
1785 * PADDB rd, rs, rt Parallel Add Byte
1786 * PSUBB rd, rs, rt Parallel Subtract Byte
1787 * PADDH rd, rs, rt Parallel Add Halfword
1788 * PSUBH rd, rs, rt Parallel Subtract Halfword
1789 * PADDW rd, rs, rt Parallel Add Word
1790 * PSUBW rd, rs, rt Parallel Subtract Word
1791 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1792 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1793 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1794 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1795 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1796 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1797 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1798 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1799 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1800 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1801 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1802 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1803 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1804 *
1805 * Min/Max (4 instructions)
1806 * ------------------------
1807 * PMAXH rd, rs, rt Parallel Maximum Halfword
1808 * PMINH rd, rs, rt Parallel Minimum Halfword
1809 * PMAXW rd, rs, rt Parallel Maximum Word
1810 * PMINW rd, rs, rt Parallel Minimum Word
1811 *
1812 * Absolute (2 instructions)
1813 * -------------------------
1814 * PABSH rd, rt Parallel Absolute Halfword
1815 * PABSW rd, rt Parallel Absolute Word
1816 *
1817 * Logical (4 instructions)
1818 * ------------------------
1819 * PAND rd, rs, rt Parallel AND
1820 * POR rd, rs, rt Parallel OR
1821 * PXOR rd, rs, rt Parallel XOR
1822 * PNOR rd, rs, rt Parallel NOR
1823 *
1824 * Shift (9 instructions)
1825 * ----------------------
1826 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1827 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1828 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1829 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1830 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1831 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1832 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1833 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1834 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1835 *
1836 * Compare (6 instructions)
1837 * ------------------------
1838 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1839 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1840 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1841 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1842 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1843 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1844 *
1845 * LZC (1 instruction)
1846 * -------------------
1847 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1848 *
1849 * Quadword Load and Store (2 instructions)
1850 * ----------------------------------------
1851 * LQ rt, offset(base) Load Quadword
1852 * SQ rt, offset(base) Store Quadword
1853 *
1854 * Multiply and Divide (19 instructions)
1855 * -------------------------------------
1856 * PMULTW rd, rs, rt Parallel Multiply Word
1857 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1858 * PDIVW rs, rt Parallel Divide Word
1859 * PDIVUW rs, rt Parallel Divide Unsigned Word
1860 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1861 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1862 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1863 * PMULTH rd, rs, rt Parallel Multiply Halfword
1864 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1865 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1866 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1867 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1868 * PDIVBW rs, rt Parallel Divide Broadcast Word
1869 * PMFHI rd Parallel Move From HI Register
1870 * PMFLO rd Parallel Move From LO Register
1871 * PMTHI rs Parallel Move To HI Register
1872 * PMTLO rs Parallel Move To LO Register
1873 * PMFHL rd Parallel Move From HI/LO Register
1874 * PMTHL rs Parallel Move To HI/LO Register
1875 *
1876 * Pack/Extend (11 instructions)
1877 * -----------------------------
1878 * PPAC5 rd, rt Parallel Pack to 5 bits
1879 * PPACB rd, rs, rt Parallel Pack to Byte
1880 * PPACH rd, rs, rt Parallel Pack to Halfword
1881 * PPACW rd, rs, rt Parallel Pack to Word
1882 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1883 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1884 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1885 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1886 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1887 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1888 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1889 *
1890 * Others (16 instructions)
1891 * ------------------------
1892 * PCPYH rd, rt Parallel Copy Halfword
1893 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1894 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1895 * PREVH rd, rt Parallel Reverse Halfword
1896 * PINTH rd, rs, rt Parallel Interleave Halfword
1897 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1898 * PEXEH rd, rt Parallel Exchange Even Halfword
1899 * PEXCH rd, rt Parallel Exchange Center Halfword
1900 * PEXEW rd, rt Parallel Exchange Even Word
1901 * PEXCW rd, rt Parallel Exchange Center Word
1902 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1903 * MFSA rd Move from Shift Amount Register
1904 * MTSA rs Move to Shift Amount Register
1905 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1906 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1907 * PROT3W rd, rt Parallel Rotate 3 Words
f99c0d6d 1908 *
baa609db
AM
1909 * MMI (MultiMedia Instruction) encodings
1910 * ======================================
f99c0d6d 1911 *
baa609db 1912 * MMI instructions encoding table keys:
f99c0d6d
FN
1913 *
1914 * * This code is reserved for future use. An attempt to execute it
1915 * causes a Reserved Instruction exception.
1916 * % This code indicates an instruction class. The instruction word
1917 * must be further decoded by examining additional tables that show
1918 * the values for other instruction fields.
1919 * # This code is reserved for the unsupported instructions DMULT,
1920 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1921 * to execute it causes a Reserved Instruction exception.
1922 *
baa609db 1923 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
f99c0d6d
FN
1924 *
1925 * 31 26 0
1926 * +--------+----------------------------------------+
1927 * | opcode | |
1928 * +--------+----------------------------------------+
1929 *
1930 * opcode bits 28..26
1931 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1932 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1933 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1934 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1935 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1936 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1937 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1938 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1939 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1940 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1941 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 1942 */
b158d449 1943
f99c0d6d 1944enum {
baa609db
AM
1945 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
1946 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
1947 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
f99c0d6d
FN
1948};
1949
d3297211 1950/*
baa609db 1951 * MMI instructions with opcode field = MMI:
d3297211
FN
1952 *
1953 * 31 26 5 0
1954 * +--------+-------------------------------+--------+
1955 * | MMI | |function|
1956 * +--------+-------------------------------+--------+
1957 *
1958 * function bits 2..0
1959 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1960 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1961 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1962 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1963 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1964 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1965 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1966 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1967 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1968 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1969 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1970 */
1971
c8341e00 1972#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
d3297211 1973enum {
baa609db
AM
1974 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1975 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1976 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
1977 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
1978 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
1979 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
1980 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
1981 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
1982 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
1983 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1984 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1985 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1986 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1987 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1988 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1989 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
1990 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
1991 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
1992 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
1993 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
1994 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
1995 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
1996 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
1997 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
1998 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
d3297211
FN
1999};
2000
3ef65697 2001/*
baa609db 2002 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
3ef65697
FN
2003 *
2004 * 31 26 10 6 5 0
2005 * +--------+----------------------+--------+--------+
2006 * | MMI | |function| MMI0 |
2007 * +--------+----------------------+--------+--------+
2008 *
2009 * function bits 7..6
2010 * bits | 0 | 1 | 2 | 3
2011 * 10..8 | 00 | 01 | 10 | 11
2012 * -------+-------+-------+-------+-------
2013 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2014 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2015 * 2 010 | PADDB | PSUBB | PCGTB | *
2016 * 3 011 | * | * | * | *
2017 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2018 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2019 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2020 * 7 111 | * | * | PEXT5 | PPAC5
2021 */
2022
c8341e00 2023#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
3ef65697 2024enum {
baa609db
AM
2025 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2026 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2027 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2028 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2029 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2030 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2031 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2032 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2033 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2034 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2035 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2036 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2037 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2038 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2039 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2040 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2041 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2042 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2043 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2044 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2045 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2046 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2047 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2048 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2049 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
3ef65697
FN
2050};
2051
77596541 2052/*
baa609db 2053 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
77596541
FN
2054 *
2055 * 31 26 10 6 5 0
2056 * +--------+----------------------+--------+--------+
2057 * | MMI | |function| MMI1 |
2058 * +--------+----------------------+--------+--------+
2059 *
2060 * function bits 7..6
2061 * bits | 0 | 1 | 2 | 3
2062 * 10..8 | 00 | 01 | 10 | 11
2063 * -------+-------+-------+-------+-------
2064 * 0 000 | * | PABSW | PCEQW | PMINW
2065 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2066 * 2 010 | * | * | PCEQB | *
2067 * 3 011 | * | * | * | *
2068 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2069 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2070 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2071 * 7 111 | * | * | * | *
2072 */
2073
c8341e00 2074#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
77596541 2075enum {
baa609db
AM
2076 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2077 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2078 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2079 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2080 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2081 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2082 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2083 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2084 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2085 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2086 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2087 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2088 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2089 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2090 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2091 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2092 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2093 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
77596541
FN
2094};
2095
6c03ef6a 2096/*
baa609db 2097 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
6c03ef6a
FN
2098 *
2099 * 31 26 10 6 5 0
2100 * +--------+----------------------+--------+--------+
2101 * | MMI | |function| MMI2 |
2102 * +--------+----------------------+--------+--------+
2103 *
2104 * function bits 7..6
2105 * bits | 0 | 1 | 2 | 3
2106 * 10..8 | 00 | 01 | 10 | 11
2107 * -------+-------+-------+-------+-------
2108 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2109 * 1 001 | PMSUBW| * | * | *
2110 * 2 010 | PMFHI | PMFLO | PINTH | *
2111 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2112 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2113 * 5 101 | PMSUBH| PHMSBH| * | *
2114 * 6 110 | * | * | PEXEH | PREVH
2115 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2116 */
2117
c8341e00 2118#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
6c03ef6a 2119enum {
baa609db
AM
2120 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2121 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2122 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2123 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2124 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2125 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2126 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2127 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2128 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2129 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2130 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2131 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2132 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2133 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2134 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2135 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2136 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2137 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2138 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2139 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2140 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2141 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
6c03ef6a
FN
2142};
2143
dd581bf9 2144/*
baa609db 2145 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
dd581bf9
FN
2146 *
2147 * 31 26 10 6 5 0
2148 * +--------+----------------------+--------+--------+
2149 * | MMI | |function| MMI3 |
2150 * +--------+----------------------+--------+--------+
2151 *
2152 * function bits 7..6
2153 * bits | 0 | 1 | 2 | 3
2154 * 10..8 | 00 | 01 | 10 | 11
2155 * -------+-------+-------+-------+-------
2156 * 0 000 |PMADDUW| * | * | PSRAVW
2157 * 1 001 | * | * | * | *
2158 * 2 010 | PMTHI | PMTLO | PINTEH| *
2159 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2160 * 4 100 | * | * | POR | PNOR
2161 * 5 101 | * | * | * | *
2162 * 6 110 | * | * | PEXCH | PCPYH
2163 * 7 111 | * | * | PEXCW | *
2164 */
2165
c8341e00 2166#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
dd581bf9 2167enum {
baa609db
AM
2168 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2169 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2170 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2171 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2172 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2173 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2174 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2175 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2176 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2177 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2178 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2179 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2180 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
dd581bf9
FN
2181};
2182
39454628 2183/* global register indices */
46c9e2b3 2184TCGv cpu_gpr[32], cpu_PC;
340fff72 2185static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
46c9e2b3
PMD
2186static TCGv cpu_dspctrl, btarget;
2187TCGv bcond;
33a07fa2 2188static TCGv cpu_lladdr, cpu_llval;
41db4607 2189static TCGv_i32 hflags;
8758d1b8
PMD
2190TCGv_i32 fpu_fcr0, fpu_fcr31;
2191TCGv_i64 fpu_f64[32];
aa0bf00b 2192
a168a796
FN
2193#if defined(TARGET_MIPS64)
2194/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2195static TCGv_i64 cpu_mmr[32];
2196#endif
2197
b621f018 2198#if !defined(TARGET_MIPS64)
eb5559f6
CJ
2199/* MXU registers */
2200static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2201static TCGv mxu_CR;
b621f018 2202#endif
eb5559f6 2203
022c62cb 2204#include "exec/gen-icount.h"
2e70f6ef 2205
895c2d04 2206#define gen_helper_0e0i(name, arg) do { \
a7812ae4 2207 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 2208 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4 2209 tcg_temp_free_i32(helper_tmp); \
71375b59 2210 } while (0)
be24bb4f 2211
895c2d04 2212#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 2213 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 2214 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4 2215 tcg_temp_free_i32(helper_tmp); \
71375b59 2216 } while (0)
be24bb4f 2217
895c2d04
BS
2218#define gen_helper_1e0i(name, ret, arg1) do { \
2219 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2220 gen_helper_##name(ret, cpu_env, helper_tmp); \
2221 tcg_temp_free_i32(helper_tmp); \
71375b59 2222 } while (0)
895c2d04
BS
2223
2224#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2225 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2226 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2227 tcg_temp_free_i32(helper_tmp); \
71375b59 2228 } while (0)
895c2d04
BS
2229
2230#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2231 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2232 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2233 tcg_temp_free_i32(helper_tmp); \
71375b59 2234 } while (0)
895c2d04
BS
2235
2236#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 2237 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 2238 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4 2239 tcg_temp_free_i32(helper_tmp); \
71375b59 2240 } while (0)
be24bb4f 2241
895c2d04 2242#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 2243 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 2244 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4 2245 tcg_temp_free_i32(helper_tmp); \
71375b59 2246 } while (0)
c239529e 2247
b28425ba
EC
2248#define DISAS_STOP DISAS_TARGET_0
2249#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2250
d73ee8a2
RH
2251static const char * const regnames[] = {
2252 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2253 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2254 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2255 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2256};
6af0bf9c 2257
d73ee8a2
RH
2258static const char * const regnames_HI[] = {
2259 "HI0", "HI1", "HI2", "HI3",
2260};
4b2eb8d2 2261
d73ee8a2
RH
2262static const char * const regnames_LO[] = {
2263 "LO0", "LO1", "LO2", "LO3",
2264};
4b2eb8d2 2265
d73ee8a2
RH
2266static const char * const fregnames[] = {
2267 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2268 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2269 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2270 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2271};
958fb4a9 2272
b621f018 2273#if !defined(TARGET_MIPS64)
eb5559f6
CJ
2274static const char * const mxuregnames[] = {
2275 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2276 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2277};
b621f018 2278#endif
eb5559f6 2279
8e9ade68 2280/* General purpose registers moves. */
46c9e2b3 2281void gen_load_gpr(TCGv t, int reg)
aaa9128a 2282{
1f8929d2 2283 if (reg == 0) {
8e9ade68 2284 tcg_gen_movi_tl(t, 0);
1f8929d2 2285 } else {
4b2eb8d2 2286 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1f8929d2 2287 }
aaa9128a
TS
2288}
2289
46c9e2b3 2290void gen_store_gpr(TCGv t, int reg)
aaa9128a 2291{
1f8929d2 2292 if (reg != 0) {
4b2eb8d2 2293 tcg_gen_mov_tl(cpu_gpr[reg], t);
1f8929d2 2294 }
aaa9128a
TS
2295}
2296
8e9ade68 2297/* Moves to/from shadow registers. */
235785e8 2298static inline void gen_load_srsgpr(int from, int to)
aaa9128a 2299{
d9bea114 2300 TCGv t0 = tcg_temp_new();
be24bb4f 2301
1f8929d2 2302 if (from == 0) {
d9bea114 2303 tcg_gen_movi_tl(t0, 0);
1f8929d2 2304 } else {
d9bea114 2305 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2306 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2307
7db13fae 2308 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2309 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2310 tcg_gen_andi_i32(t2, t2, 0xf);
2311 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2312 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2313 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2314
d9bea114 2315 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2316 tcg_temp_free_ptr(addr);
d9bea114 2317 tcg_temp_free_i32(t2);
8e9ade68 2318 }
d9bea114
AJ
2319 gen_store_gpr(t0, to);
2320 tcg_temp_free(t0);
aaa9128a
TS
2321}
2322
71375b59 2323static inline void gen_store_srsgpr(int from, int to)
aaa9128a 2324{
be24bb4f 2325 if (to != 0) {
d9bea114
AJ
2326 TCGv t0 = tcg_temp_new();
2327 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2328 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2329
d9bea114 2330 gen_load_gpr(t0, from);
7db13fae 2331 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2332 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2333 tcg_gen_andi_i32(t2, t2, 0xf);
2334 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2335 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2336 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2337
d9bea114 2338 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2339 tcg_temp_free_ptr(addr);
d9bea114
AJ
2340 tcg_temp_free_i32(t2);
2341 tcg_temp_free(t0);
8e9ade68 2342 }
aaa9128a
TS
2343}
2344
b621f018 2345#if !defined(TARGET_MIPS64)
96992d1a
CJ
2346/* MXU General purpose registers moves. */
2347static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2348{
2349 if (reg == 0) {
2350 tcg_gen_movi_tl(t, 0);
2351 } else if (reg <= 15) {
2352 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2353 }
2354}
2355
2356static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2357{
2358 if (reg > 0 && reg <= 15) {
2359 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2360 }
2361}
2362
2363/* MXU control register moves. */
2364static inline void gen_load_mxu_cr(TCGv t)
2365{
2366 tcg_gen_mov_tl(t, mxu_CR);
2367}
2368
2369static inline void gen_store_mxu_cr(TCGv t)
2370{
2371 /* TODO: Add handling of RW rules for MXU_CR. */
2372 tcg_gen_mov_tl(mxu_CR, t);
2373}
b621f018 2374#endif
96992d1a
CJ
2375
2376
eab9944c
LA
2377/* Tests */
2378static inline void gen_save_pc(target_ulong pc)
2379{
2380 tcg_gen_movi_tl(cpu_PC, pc);
2381}
2382
2383static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2384{
2385 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2386 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2387 gen_save_pc(ctx->base.pc_next);
2388 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2389 }
2390 if (ctx->hflags != ctx->saved_hflags) {
2391 tcg_gen_movi_i32(hflags, ctx->hflags);
2392 ctx->saved_hflags = ctx->hflags;
2393 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2394 case MIPS_HFLAG_BR:
2395 break;
2396 case MIPS_HFLAG_BC:
2397 case MIPS_HFLAG_BL:
2398 case MIPS_HFLAG_B:
2399 tcg_gen_movi_tl(btarget, ctx->btarget);
2400 break;
2401 }
2402 }
2403}
2404
2405static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2406{
2407 ctx->saved_hflags = ctx->hflags;
2408 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2409 case MIPS_HFLAG_BR:
2410 break;
2411 case MIPS_HFLAG_BC:
2412 case MIPS_HFLAG_BL:
2413 case MIPS_HFLAG_B:
2414 ctx->btarget = env->btarget;
2415 break;
2416 }
2417}
2418
46c9e2b3 2419void generate_exception_err(DisasContext *ctx, int excp, int err)
eab9944c
LA
2420{
2421 TCGv_i32 texcp = tcg_const_i32(excp);
2422 TCGv_i32 terr = tcg_const_i32(err);
2423 save_cpu_state(ctx, 1);
2424 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2425 tcg_temp_free_i32(terr);
2426 tcg_temp_free_i32(texcp);
eeb3bba8 2427 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2428}
2429
46c9e2b3 2430void generate_exception(DisasContext *ctx, int excp)
eab9944c 2431{
eab9944c
LA
2432 gen_helper_0e0i(raise_exception, excp);
2433}
2434
46c9e2b3 2435void generate_exception_end(DisasContext *ctx, int excp)
9c708c7f
PD
2436{
2437 generate_exception_err(ctx, excp, 0);
2438}
2439
3a4ef3b7
PMD
2440void gen_reserved_instruction(DisasContext *ctx)
2441{
2442 generate_exception_end(ctx, EXCP_RI);
2443}
2444
aaa9128a 2445/* Floating point register moves. */
8758d1b8 2446void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2447{
7c979afd
LA
2448 if (ctx->hflags & MIPS_HFLAG_FRE) {
2449 generate_exception(ctx, EXCP_RI);
2450 }
ecc7b3aa 2451 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2452}
2453
8758d1b8 2454void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2455{
7c979afd
LA
2456 TCGv_i64 t64;
2457 if (ctx->hflags & MIPS_HFLAG_FRE) {
2458 generate_exception(ctx, EXCP_RI);
2459 }
2460 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2461 tcg_gen_extu_i32_i64(t64, t);
2462 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2463 tcg_temp_free_i64(t64);
6d066274
AJ
2464}
2465
7f6613ce 2466static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2467{
7f6613ce 2468 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2469 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2470 } else {
7c979afd 2471 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2472 }
6d066274
AJ
2473}
2474
7f6613ce 2475static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2476{
7f6613ce
PJ
2477 if (ctx->hflags & MIPS_HFLAG_F64) {
2478 TCGv_i64 t64 = tcg_temp_new_i64();
2479 tcg_gen_extu_i32_i64(t64, t);
2480 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2481 tcg_temp_free_i64(t64);
2482 } else {
7c979afd 2483 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2484 }
aa0bf00b 2485}
6ea83fed 2486
8758d1b8 2487void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2488{
f364515c 2489 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2490 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2491 } else {
d73ee8a2 2492 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2493 }
2494}
6ea83fed 2495
8758d1b8 2496void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2497{
f364515c 2498 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2499 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2500 } else {
d73ee8a2
RH
2501 TCGv_i64 t0;
2502 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2503 t0 = tcg_temp_new_i64();
6d066274 2504 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2505 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2506 tcg_temp_free_i64(t0);
aa0bf00b
TS
2507 }
2508}
6ea83fed 2509
8758d1b8 2510int get_fp_bit(int cc)
a16336e4 2511{
1f8929d2 2512 if (cc) {
d94536f4 2513 return 24 + cc;
1f8929d2 2514 } else {
d94536f4 2515 return 23;
1f8929d2 2516 }
a16336e4
TS
2517}
2518
48d38ca5 2519/* Addresses computation */
46c9e2b3 2520void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2521{
941694d0 2522 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2523
2524#if defined(TARGET_MIPS64)
01f72885 2525 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2526 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2527 }
2528#endif
4ad40f36
FB
2529}
2530
bf0718c5
SM
2531static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2532 target_long ofs)
2533{
2534 tcg_gen_addi_tl(ret, base, ofs);
2535
2536#if defined(TARGET_MIPS64)
2537 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2538 tcg_gen_ext32s_i64(ret, ret);
2539 }
2540#endif
2541}
2542
31837be3
YK
2543/* Addresses computation (translation time) */
2544static target_long addr_add(DisasContext *ctx, target_long base,
2545 target_long offset)
2546{
2547 target_long sum = base + offset;
2548
2549#if defined(TARGET_MIPS64)
2550 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2551 sum = (int32_t)sum;
2552 }
2553#endif
2554 return sum;
2555}
2556
71f303cd 2557/* Sign-extract the low 32-bits to a target_long. */
46c9e2b3 2558void gen_move_low32(TCGv ret, TCGv_i64 arg)
1f1b4c00
YK
2559{
2560#if defined(TARGET_MIPS64)
71f303cd
RH
2561 tcg_gen_ext32s_i64(ret, arg);
2562#else
2563 tcg_gen_extrl_i64_i32(ret, arg);
2564#endif
2565}
2566
2567/* Sign-extract the high 32-bits to a target_long. */
46c9e2b3 2568void gen_move_high32(TCGv ret, TCGv_i64 arg)
71f303cd
RH
2569{
2570#if defined(TARGET_MIPS64)
2571 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2572#else
71f303cd 2573 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2574#endif
2575}
2576
8758d1b8 2577void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2578{
1f8929d2 2579 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 2580 generate_exception_end(ctx, EXCP_CpU);
1f8929d2 2581 }
387a8fe5
TS
2582}
2583
8758d1b8 2584void check_cp1_enabled(DisasContext *ctx)
5e755519 2585{
1f8929d2 2586 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
5e755519 2587 generate_exception_err(ctx, EXCP_CpU, 1);
1f8929d2 2588 }
5e755519
TS
2589}
2590
7480515f
AM
2591/*
2592 * Verify that the processor is running with COP1X instructions enabled.
2593 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2594 * opcode tables.
2595 */
8758d1b8 2596void check_cop1x(DisasContext *ctx)
b8aa4598 2597{
1f8929d2 2598 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
3a4ef3b7 2599 gen_reserved_instruction(ctx);
1f8929d2 2600 }
b8aa4598
TS
2601}
2602
7480515f
AM
2603/*
2604 * Verify that the processor is running with 64-bit floating-point
2605 * operations enabled.
2606 */
8758d1b8 2607void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2608{
1f8929d2 2609 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
3a4ef3b7 2610 gen_reserved_instruction(ctx);
1f8929d2 2611 }
5e755519
TS
2612}
2613
2614/*
2615 * Verify if floating point register is valid; an operation is not defined
2616 * if bit 0 of any register specification is set and the FR bit in the
2617 * Status register equals zero, since the register numbers specify an
2618 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2619 * in the Status register equals one, both even and odd register numbers
2620 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2621 *
2622 * Multiple 64 bit wide registers can be checked by calling
2623 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2624 */
8758d1b8 2625void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2626{
1f8929d2 2627 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
3a4ef3b7 2628 gen_reserved_instruction(ctx);
1f8929d2 2629 }
5e755519
TS
2630}
2631
7480515f
AM
2632/*
2633 * Verify that the processor is running with DSP instructions enabled.
2634 * This is enabled by CP0 Status register MX(24) bit.
853c3240 2635 */
853c3240
JL
2636static inline void check_dsp(DisasContext *ctx)
2637{
2638 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2639 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2640 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2641 } else {
3a4ef3b7 2642 gen_reserved_instruction(ctx);
ad153f15 2643 }
853c3240
JL
2644 }
2645}
2646
908f6be1 2647static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2648{
908f6be1 2649 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2650 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2651 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2652 } else {
3a4ef3b7 2653 gen_reserved_instruction(ctx);
ad153f15 2654 }
853c3240
JL
2655 }
2656}
2657
908f6be1 2658static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2659{
908f6be1 2660 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2661 if (ctx->insn_flags & ASE_DSP) {
2662 generate_exception_end(ctx, EXCP_DSPDIS);
2663 } else {
3a4ef3b7 2664 gen_reserved_instruction(ctx);
59e781fb
SM
2665 }
2666 }
2667}
2668
7480515f
AM
2669/*
2670 * This code generates a "reserved instruction" exception if the
2671 * CPU does not support the instruction set corresponding to flags.
2672 */
46c9e2b3 2673void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2674{
d75c135e 2675 if (unlikely(!(ctx->insn_flags & flags))) {
3a4ef3b7 2676 gen_reserved_instruction(ctx);
d75c135e 2677 }
3a95e3a7
TS
2678}
2679
7480515f
AM
2680/*
2681 * This code generates a "reserved instruction" exception if the
2682 * CPU has corresponding flag set which indicates that the instruction
2683 * has been removed.
2684 */
f9c9cd63 2685static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2686{
2687 if (unlikely(ctx->insn_flags & flags)) {
3a4ef3b7 2688 gen_reserved_instruction(ctx);
fecd2646
LA
2689 }
2690}
2691
96631327
FN
2692/*
2693 * The Linux kernel traps certain reserved instruction exceptions to
2694 * emulate the corresponding instructions. QEMU is the kernel in user
2695 * mode, so those traps are emulated by accepting the instructions.
2696 *
2697 * A reserved instruction exception is generated for flagged CPUs if
2698 * QEMU runs in system mode.
2699 */
2700static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2701{
2702#ifndef CONFIG_USER_ONLY
2703 check_insn_opc_removed(ctx, flags);
2704#endif
2705}
2706
7480515f
AM
2707/*
2708 * This code generates a "reserved instruction" exception if the
2709 * CPU does not support 64-bit paired-single (PS) floating point data type.
2710 */
e29c9628
YK
2711static inline void check_ps(DisasContext *ctx)
2712{
2713 if (unlikely(!ctx->ps)) {
2714 generate_exception(ctx, EXCP_RI);
2715 }
2716 check_cp1_64bitmode(ctx);
2717}
2718
7480515f 2719/*
d7efb693
PMD
2720 * This code generates a "reserved instruction" exception if cpu is not
2721 * 64-bit or 64-bit instructions are not enabled.
7480515f 2722 */
46c9e2b3 2723void check_mips_64(DisasContext *ctx)
e189e748 2724{
d7efb693 2725 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
3a4ef3b7 2726 gen_reserved_instruction(ctx);
1f8929d2 2727 }
e189e748
TS
2728}
2729
5204ea79
LA
2730#ifndef CONFIG_USER_ONLY
2731static inline void check_mvh(DisasContext *ctx)
2732{
2733 if (unlikely(!ctx->mvh)) {
2734 generate_exception(ctx, EXCP_RI);
2735 }
2736}
2737#endif
2738
0b16dcd1
AR
2739/*
2740 * This code generates a "reserved instruction" exception if the
2741 * Config5 XNP bit is set.
2742 */
2743static inline void check_xnp(DisasContext *ctx)
2744{
2745 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3a4ef3b7 2746 gen_reserved_instruction(ctx);
0b16dcd1
AR
2747 }
2748}
2749
5e31fdd5
YK
2750#ifndef CONFIG_USER_ONLY
2751/*
2752 * This code generates a "reserved instruction" exception if the
2753 * Config3 PW bit is NOT set.
2754 */
2755static inline void check_pw(DisasContext *ctx)
2756{
2757 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3a4ef3b7 2758 gen_reserved_instruction(ctx);
5e31fdd5
YK
2759 }
2760}
2761#endif
2762
9affc1c5
AR
2763/*
2764 * This code generates a "reserved instruction" exception if the
2765 * Config3 MT bit is NOT set.
2766 */
2767static inline void check_mt(DisasContext *ctx)
2768{
2769 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 2770 gen_reserved_instruction(ctx);
9affc1c5
AR
2771 }
2772}
2773
2774#ifndef CONFIG_USER_ONLY
2775/*
2776 * This code generates a "coprocessor unusable" exception if CP0 is not
2777 * available, and, if that is not the case, generates a "reserved instruction"
2778 * exception if the Config5 MT bit is NOT set. This is needed for availability
2779 * control of some of MT ASE instructions.
2780 */
2781static inline void check_cp0_mt(DisasContext *ctx)
2782{
2783 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 2784 generate_exception_end(ctx, EXCP_CpU);
9affc1c5
AR
2785 } else {
2786 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 2787 gen_reserved_instruction(ctx);
9affc1c5
AR
2788 }
2789 }
2790}
2791#endif
2792
fb32f8c8
DN
2793/*
2794 * This code generates a "reserved instruction" exception if the
2795 * Config5 NMS bit is set.
2796 */
2797static inline void check_nms(DisasContext *ctx)
2798{
2799 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3a4ef3b7 2800 gen_reserved_instruction(ctx);
fb32f8c8
DN
2801 }
2802}
2803
d046a9ea
DN
2804/*
2805 * This code generates a "reserved instruction" exception if the
2806 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2807 * Config2 TL, and Config5 L2C are unset.
2808 */
2809static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
2810{
1f8929d2
AM
2811 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
2812 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
2813 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
2814 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
2815 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
2816 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3a4ef3b7 2817 gen_reserved_instruction(ctx);
d046a9ea
DN
2818 }
2819}
2820
2821/*
2822 * This code generates a "reserved instruction" exception if the
2823 * Config5 EVA bit is NOT set.
2824 */
2825static inline void check_eva(DisasContext *ctx)
2826{
2827 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3a4ef3b7 2828 gen_reserved_instruction(ctx);
d046a9ea
DN
2829 }
2830}
2831
0b16dcd1 2832
7480515f
AM
2833/*
2834 * Define small wrappers for gen_load_fpr* so that we have a uniform
2835 * calling interface for 32 and 64-bit FPRs. No sense in changing
2836 * all callers for gen_load_fpr32 when we need the CTX parameter for
2837 * this one use.
2838 */
7c979afd 2839#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
2840#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2841#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2842static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2843 int ft, int fs, int cc) \
2844{ \
71375b59
AM
2845 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2846 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
8153667c
NF
2847 switch (ifmt) { \
2848 case FMT_PS: \
e29c9628 2849 check_ps(ctx); \
8153667c
NF
2850 break; \
2851 case FMT_D: \
2852 if (abs) { \
2853 check_cop1x(ctx); \
2854 } \
2855 check_cp1_registers(ctx, fs | ft); \
2856 break; \
2857 case FMT_S: \
2858 if (abs) { \
2859 check_cop1x(ctx); \
2860 } \
2861 break; \
2862 } \
71375b59
AM
2863 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2864 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
8153667c 2865 switch (n) { \
1f8929d2
AM
2866 case 0: \
2867 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2868 break; \
2869 case 1: \
2870 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2871 break; \
2872 case 2: \
2873 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2874 break; \
2875 case 3: \
2876 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2877 break; \
2878 case 4: \
2879 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2880 break; \
2881 case 5: \
2882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2883 break; \
2884 case 6: \
2885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2886 break; \
2887 case 7: \
2888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2889 break; \
2890 case 8: \
2891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2892 break; \
2893 case 9: \
2894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2895 break; \
2896 case 10: \
2897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2898 break; \
2899 case 11: \
2900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2901 break; \
2902 case 12: \
2903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2904 break; \
2905 case 13: \
2906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2907 break; \
2908 case 14: \
2909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2910 break; \
2911 case 15: \
2912 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2913 break; \
2914 default: \
2915 abort(); \
8153667c 2916 } \
71375b59
AM
2917 tcg_temp_free_i##bits(fp0); \
2918 tcg_temp_free_i##bits(fp1); \
8153667c
NF
2919}
2920
2921FOP_CONDS(, 0, d, FMT_D, 64)
2922FOP_CONDS(abs, 1, d, FMT_D, 64)
2923FOP_CONDS(, 0, s, FMT_S, 32)
2924FOP_CONDS(abs, 1, s, FMT_S, 32)
2925FOP_CONDS(, 0, ps, FMT_PS, 64)
2926FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2927#undef FOP_CONDS
3f493883
YK
2928
2929#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
71375b59 2930static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3f493883
YK
2931 int ft, int fs, int fd) \
2932{ \
2933 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2934 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 2935 if (ifmt == FMT_D) { \
3f493883 2936 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
2937 } \
2938 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2939 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2940 switch (n) { \
2941 case 0: \
2942 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2943 break; \
2944 case 1: \
2945 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2946 break; \
2947 case 2: \
2948 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2949 break; \
2950 case 3: \
2951 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2952 break; \
2953 case 4: \
2954 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2955 break; \
2956 case 5: \
2957 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2958 break; \
2959 case 6: \
2960 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2961 break; \
2962 case 7: \
2963 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2964 break; \
2965 case 8: \
2966 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2967 break; \
2968 case 9: \
2969 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2970 break; \
2971 case 10: \
2972 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2973 break; \
2974 case 11: \
2975 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2976 break; \
2977 case 12: \
2978 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2979 break; \
2980 case 13: \
2981 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2982 break; \
2983 case 14: \
2984 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2985 break; \
2986 case 15: \
2987 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2988 break; \
2989 case 17: \
2990 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2991 break; \
2992 case 18: \
2993 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2994 break; \
2995 case 19: \
2996 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2997 break; \
2998 case 25: \
2999 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3000 break; \
3001 case 26: \
3002 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3003 break; \
3004 case 27: \
3005 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3006 break; \
3007 default: \
3008 abort(); \
3009 } \
3010 STORE; \
71375b59
AM
3011 tcg_temp_free_i ## bits(fp0); \
3012 tcg_temp_free_i ## bits(fp1); \
3f493883
YK
3013}
3014
3015FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 3016FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 3017#undef FOP_CONDNS
8153667c
NF
3018#undef gen_ldcmp_fpr32
3019#undef gen_ldcmp_fpr64
3020
958fb4a9 3021/* load/store instructions. */
e7139c44 3022#ifdef CONFIG_USER_ONLY
71375b59 3023#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
3024static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3025 DisasContext *ctx) \
d9bea114
AJ
3026{ \
3027 TCGv t0 = tcg_temp_new(); \
3028 tcg_gen_mov_tl(t0, arg1); \
3029 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
71375b59
AM
3030 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3031 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 3032 tcg_temp_free(t0); \
aaa9128a 3033}
e7139c44 3034#else
71375b59 3035#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
3036static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3037 DisasContext *ctx) \
e7139c44 3038{ \
dd4096cd 3039 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
3040}
3041#endif
71375b59 3042OP_LD_ATOMIC(ll, ld32s);
aaa9128a 3043#if defined(TARGET_MIPS64)
71375b59 3044OP_LD_ATOMIC(lld, ld64);
aaa9128a
TS
3045#endif
3046#undef OP_LD_ATOMIC
3047
46c9e2b3 3048void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
662d7485
NF
3049{
3050 if (base == 0) {
3051 tcg_gen_movi_tl(addr, offset);
3052 } else if (offset == 0) {
3053 gen_load_gpr(addr, base);
3054 } else {
3055 tcg_gen_movi_tl(addr, offset);
3056 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3057 }
3058}
3059
235785e8 3060static target_ulong pc_relative_pc(DisasContext *ctx)
364d4831 3061{
eeb3bba8 3062 target_ulong pc = ctx->base.pc_next;
364d4831
NF
3063
3064 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3065 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3066
3067 pc -= branch_bytes;
3068 }
3069
3070 pc &= ~(target_ulong)3;
3071 return pc;
3072}
3073
5c13fdfd 3074/* Load */
d75c135e 3075static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 3076 int rt, int base, int offset)
6af0bf9c 3077{
fc40787a 3078 TCGv t0, t1, t2;
dd4096cd 3079 int mem_idx = ctx->mem_idx;
afa88c3a 3080
8e2d5831
JY
3081 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
3082 INSN_LOONGSON3A)) {
7480515f
AM
3083 /*
3084 * Loongson CPU uses a load to zero register for prefetch.
3085 * We emulate it as a NOP. On other CPU we must perform the
3086 * actual memory access.
3087 */
afa88c3a
AJ
3088 return;
3089 }
6af0bf9c 3090
afa88c3a 3091 t0 = tcg_temp_new();
662d7485 3092 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 3093
6af0bf9c 3094 switch (opc) {
d26bc211 3095#if defined(TARGET_MIPS64)
6e473128 3096 case OPC_LWU:
dd4096cd 3097 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 3098 ctx->default_tcg_memop_mask);
78723684 3099 gen_store_gpr(t0, rt);
6e473128 3100 break;
6af0bf9c 3101 case OPC_LD:
dd4096cd 3102 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 3103 ctx->default_tcg_memop_mask);
78723684 3104 gen_store_gpr(t0, rt);
6af0bf9c 3105 break;
7a387fff 3106 case OPC_LLD:
bf7910c6 3107 case R6_OPC_LLD:
dd4096cd 3108 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 3109 gen_store_gpr(t0, rt);
7a387fff 3110 break;
6af0bf9c 3111 case OPC_LDL:
3cee3050 3112 t1 = tcg_temp_new();
7480515f
AM
3113 /*
3114 * Do a byte access to possibly trigger a page
3115 * fault with the unaligned address.
3116 */
dd4096cd 3117 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3118 tcg_gen_andi_tl(t1, t0, 7);
3119#ifndef TARGET_WORDS_BIGENDIAN
3120 tcg_gen_xori_tl(t1, t1, 7);
3121#endif
3122 tcg_gen_shli_tl(t1, t1, 3);
3123 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3124 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 3125 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3126 t2 = tcg_const_tl(-1);
3127 tcg_gen_shl_tl(t2, t2, t1);
78723684 3128 gen_load_gpr(t1, rt);
eb02cc3f 3129 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3130 tcg_temp_free(t2);
3131 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3132 tcg_temp_free(t1);
fc40787a 3133 gen_store_gpr(t0, rt);
6af0bf9c 3134 break;
6af0bf9c 3135 case OPC_LDR:
3cee3050 3136 t1 = tcg_temp_new();
7480515f
AM
3137 /*
3138 * Do a byte access to possibly trigger a page
3139 * fault with the unaligned address.
3140 */
dd4096cd 3141 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3142 tcg_gen_andi_tl(t1, t0, 7);
3143#ifdef TARGET_WORDS_BIGENDIAN
3144 tcg_gen_xori_tl(t1, t1, 7);
3145#endif
3146 tcg_gen_shli_tl(t1, t1, 3);
3147 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3148 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
3149 tcg_gen_shr_tl(t0, t0, t1);
3150 tcg_gen_xori_tl(t1, t1, 63);
3151 t2 = tcg_const_tl(0xfffffffffffffffeull);
3152 tcg_gen_shl_tl(t2, t2, t1);
78723684 3153 gen_load_gpr(t1, rt);
fc40787a
AJ
3154 tcg_gen_and_tl(t1, t1, t2);
3155 tcg_temp_free(t2);
3156 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3157 tcg_temp_free(t1);
fc40787a 3158 gen_store_gpr(t0, rt);
6af0bf9c 3159 break;
364d4831 3160 case OPC_LDPC:
3cee3050 3161 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3162 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3163 tcg_temp_free(t1);
dd4096cd 3164 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
3165 gen_store_gpr(t0, rt);
3166 break;
6af0bf9c 3167#endif
364d4831 3168 case OPC_LWPC:
3cee3050 3169 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3170 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3171 tcg_temp_free(t1);
dd4096cd 3172 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
3173 gen_store_gpr(t0, rt);
3174 break;
76964147
JH
3175 case OPC_LWE:
3176 mem_idx = MIPS_HFLAG_UM;
3177 /* fall through */
6af0bf9c 3178 case OPC_LW:
dd4096cd 3179 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 3180 ctx->default_tcg_memop_mask);
78723684 3181 gen_store_gpr(t0, rt);
6af0bf9c 3182 break;
76964147
JH
3183 case OPC_LHE:
3184 mem_idx = MIPS_HFLAG_UM;
3185 /* fall through */
6af0bf9c 3186 case OPC_LH:
dd4096cd 3187 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 3188 ctx->default_tcg_memop_mask);
78723684 3189 gen_store_gpr(t0, rt);
6af0bf9c 3190 break;
76964147
JH
3191 case OPC_LHUE:
3192 mem_idx = MIPS_HFLAG_UM;
3193 /* fall through */
6af0bf9c 3194 case OPC_LHU:
dd4096cd 3195 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 3196 ctx->default_tcg_memop_mask);
78723684 3197 gen_store_gpr(t0, rt);
6af0bf9c 3198 break;
76964147
JH
3199 case OPC_LBE:
3200 mem_idx = MIPS_HFLAG_UM;
3201 /* fall through */
6af0bf9c 3202 case OPC_LB:
dd4096cd 3203 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 3204 gen_store_gpr(t0, rt);
6af0bf9c 3205 break;
76964147
JH
3206 case OPC_LBUE:
3207 mem_idx = MIPS_HFLAG_UM;
3208 /* fall through */
6af0bf9c 3209 case OPC_LBU:
dd4096cd 3210 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 3211 gen_store_gpr(t0, rt);
6af0bf9c 3212 break;
76964147
JH
3213 case OPC_LWLE:
3214 mem_idx = MIPS_HFLAG_UM;
3215 /* fall through */
6af0bf9c 3216 case OPC_LWL:
3cee3050 3217 t1 = tcg_temp_new();
7480515f
AM
3218 /*
3219 * Do a byte access to possibly trigger a page
3220 * fault with the unaligned address.
3221 */
dd4096cd 3222 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3223 tcg_gen_andi_tl(t1, t0, 3);
3224#ifndef TARGET_WORDS_BIGENDIAN
3225 tcg_gen_xori_tl(t1, t1, 3);
3226#endif
3227 tcg_gen_shli_tl(t1, t1, 3);
3228 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3229 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 3230 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3231 t2 = tcg_const_tl(-1);
3232 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3233 gen_load_gpr(t1, rt);
eb02cc3f 3234 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3235 tcg_temp_free(t2);
3236 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3237 tcg_temp_free(t1);
fc40787a
AJ
3238 tcg_gen_ext32s_tl(t0, t0);
3239 gen_store_gpr(t0, rt);
6af0bf9c 3240 break;
76964147
JH
3241 case OPC_LWRE:
3242 mem_idx = MIPS_HFLAG_UM;
3243 /* fall through */
6af0bf9c 3244 case OPC_LWR:
3cee3050 3245 t1 = tcg_temp_new();
7480515f
AM
3246 /*
3247 * Do a byte access to possibly trigger a page
3248 * fault with the unaligned address.
3249 */
dd4096cd 3250 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3251 tcg_gen_andi_tl(t1, t0, 3);
3252#ifdef TARGET_WORDS_BIGENDIAN
3253 tcg_gen_xori_tl(t1, t1, 3);
3254#endif
3255 tcg_gen_shli_tl(t1, t1, 3);
3256 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3257 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
3258 tcg_gen_shr_tl(t0, t0, t1);
3259 tcg_gen_xori_tl(t1, t1, 31);
3260 t2 = tcg_const_tl(0xfffffffeull);
3261 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3262 gen_load_gpr(t1, rt);
fc40787a
AJ
3263 tcg_gen_and_tl(t1, t1, t2);
3264 tcg_temp_free(t2);
3265 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3266 tcg_temp_free(t1);
c728154b 3267 tcg_gen_ext32s_tl(t0, t0);
fc40787a 3268 gen_store_gpr(t0, rt);
6af0bf9c 3269 break;
76964147
JH
3270 case OPC_LLE:
3271 mem_idx = MIPS_HFLAG_UM;
3272 /* fall through */
6af0bf9c 3273 case OPC_LL:
4368b29a 3274 case R6_OPC_LL:
dd4096cd 3275 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 3276 gen_store_gpr(t0, rt);
6af0bf9c 3277 break;
d66c7132 3278 }
d66c7132 3279 tcg_temp_free(t0);
d66c7132
AJ
3280}
3281
0b16dcd1
AR
3282static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3283 uint32_t reg1, uint32_t reg2)
3284{
3285 TCGv taddr = tcg_temp_new();
3286 TCGv_i64 tval = tcg_temp_new_i64();
3287 TCGv tmp1 = tcg_temp_new();
3288 TCGv tmp2 = tcg_temp_new();
3289
3290 gen_base_offset_addr(ctx, taddr, base, offset);
3291 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3292#ifdef TARGET_WORDS_BIGENDIAN
3293 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3294#else
3295 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3296#endif
3297 gen_store_gpr(tmp1, reg1);
3298 tcg_temp_free(tmp1);
3299 gen_store_gpr(tmp2, reg2);
3300 tcg_temp_free(tmp2);
3301 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3302 tcg_temp_free_i64(tval);
3303 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3304 tcg_temp_free(taddr);
3305}
3306
5c13fdfd 3307/* Store */
235785e8
AM
3308static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3309 int base, int offset)
5c13fdfd 3310{
5c13fdfd
AJ
3311 TCGv t0 = tcg_temp_new();
3312 TCGv t1 = tcg_temp_new();
dd4096cd 3313 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3314
3315 gen_base_offset_addr(ctx, t0, base, offset);
3316 gen_load_gpr(t1, rt);
3317 switch (opc) {
3318#if defined(TARGET_MIPS64)
3319 case OPC_SD:
dd4096cd 3320 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3321 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3322 break;
3323 case OPC_SDL:
dd4096cd 3324 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3325 break;
3326 case OPC_SDR:
dd4096cd 3327 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3328 break;
3329#endif
76964147
JH
3330 case OPC_SWE:
3331 mem_idx = MIPS_HFLAG_UM;
3332 /* fall through */
5c13fdfd 3333 case OPC_SW:
dd4096cd 3334 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3335 ctx->default_tcg_memop_mask);
5c13fdfd 3336 break;
76964147
JH
3337 case OPC_SHE:
3338 mem_idx = MIPS_HFLAG_UM;
3339 /* fall through */
5c13fdfd 3340 case OPC_SH:
dd4096cd 3341 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3342 ctx->default_tcg_memop_mask);
5c13fdfd 3343 break;
76964147
JH
3344 case OPC_SBE:
3345 mem_idx = MIPS_HFLAG_UM;
3346 /* fall through */
5c13fdfd 3347 case OPC_SB:
dd4096cd 3348 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3349 break;
76964147
JH
3350 case OPC_SWLE:
3351 mem_idx = MIPS_HFLAG_UM;
3352 /* fall through */
5c13fdfd 3353 case OPC_SWL:
dd4096cd 3354 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3355 break;
76964147
JH
3356 case OPC_SWRE:
3357 mem_idx = MIPS_HFLAG_UM;
3358 /* fall through */
5c13fdfd 3359 case OPC_SWR:
dd4096cd 3360 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3361 break;
3362 }
5c13fdfd
AJ
3363 tcg_temp_free(t0);
3364 tcg_temp_free(t1);
3365}
3366
3367
d66c7132 3368/* Store conditional */
33a07fa2 3369static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
14776ab5 3370 MemOp tcg_mo, bool eva)
d66c7132 3371{
33a07fa2
LA
3372 TCGv addr, t0, val;
3373 TCGLabel *l1 = gen_new_label();
3374 TCGLabel *done = gen_new_label();
d66c7132 3375
2d2826b9 3376 t0 = tcg_temp_new();
33a07fa2 3377 addr = tcg_temp_new();
8cdf8869 3378 /* compare the address against that of the preceding LL */
33a07fa2
LA
3379 gen_base_offset_addr(ctx, addr, base, offset);
3380 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3381 tcg_temp_free(addr);
3382 tcg_gen_movi_tl(t0, 0);
3383 gen_store_gpr(t0, rt);
3384 tcg_gen_br(done);
3385
3386 gen_set_label(l1);
3387 /* generate cmpxchg */
3388 val = tcg_temp_new();
3389 gen_load_gpr(val, rt);
3390 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3391 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3392 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3393 gen_store_gpr(t0, rt);
3394 tcg_temp_free(val);
3395
3396 gen_set_label(done);
d66c7132 3397 tcg_temp_free(t0);
6af0bf9c
FB
3398}
3399
33a07fa2 3400
0b16dcd1 3401static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
8d5388c1 3402 uint32_t reg1, uint32_t reg2, bool eva)
0b16dcd1
AR
3403{
3404 TCGv taddr = tcg_temp_local_new();
3405 TCGv lladdr = tcg_temp_local_new();
3406 TCGv_i64 tval = tcg_temp_new_i64();
3407 TCGv_i64 llval = tcg_temp_new_i64();
3408 TCGv_i64 val = tcg_temp_new_i64();
3409 TCGv tmp1 = tcg_temp_new();
3410 TCGv tmp2 = tcg_temp_new();
3411 TCGLabel *lab_fail = gen_new_label();
3412 TCGLabel *lab_done = gen_new_label();
3413
3414 gen_base_offset_addr(ctx, taddr, base, offset);
3415
3416 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3417 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3418
3419 gen_load_gpr(tmp1, reg1);
3420 gen_load_gpr(tmp2, reg2);
3421
3422#ifdef TARGET_WORDS_BIGENDIAN
3423 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3424#else
3425 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3426#endif
3427
3428 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3429 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
8d5388c1 3430 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
0b16dcd1
AR
3431 if (reg1 != 0) {
3432 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3433 }
3434 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3435
3436 gen_set_label(lab_fail);
3437
3438 if (reg1 != 0) {
3439 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3440 }
3441 gen_set_label(lab_done);
3442 tcg_gen_movi_tl(lladdr, -1);
3443 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3444}
3445
6ea83fed 3446/* Load and store */
235785e8
AM
3447static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3448 TCGv t0)
6ea83fed 3449{
7480515f
AM
3450 /*
3451 * Don't do NOP if destination is zero: we must perform the actual
3452 * memory access.
3453 */
6ea83fed
FB
3454 switch (opc) {
3455 case OPC_LWC1:
b6d96bed 3456 {
a7812ae4 3457 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3458 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3459 ctx->default_tcg_memop_mask);
7c979afd 3460 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3461 tcg_temp_free_i32(fp0);
b6d96bed 3462 }
6ea83fed
FB
3463 break;
3464 case OPC_SWC1:
b6d96bed 3465 {
a7812ae4 3466 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3467 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3468 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3469 ctx->default_tcg_memop_mask);
a7812ae4 3470 tcg_temp_free_i32(fp0);
b6d96bed 3471 }
6ea83fed
FB
3472 break;
3473 case OPC_LDC1:
b6d96bed 3474 {
a7812ae4 3475 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3476 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3477 ctx->default_tcg_memop_mask);
b6d96bed 3478 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3479 tcg_temp_free_i64(fp0);
b6d96bed 3480 }
6ea83fed
FB
3481 break;
3482 case OPC_SDC1:
b6d96bed 3483 {
a7812ae4 3484 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3485 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3486 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3487 ctx->default_tcg_memop_mask);
a7812ae4 3488 tcg_temp_free_i64(fp0);
b6d96bed 3489 }
6ea83fed
FB
3490 break;
3491 default:
9d68ac14 3492 MIPS_INVAL("flt_ldst");
3a4ef3b7 3493 gen_reserved_instruction(ctx);
b52d3bfa 3494 break;
6ea83fed 3495 }
6ea83fed 3496}
6ea83fed 3497
5ab5c041
AJ
3498static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3499 int rs, int16_t imm)
26ebe468 3500{
b52d3bfa
YK
3501 TCGv t0 = tcg_temp_new();
3502
5ab5c041 3503 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3504 check_cp1_enabled(ctx);
d9224450
MR
3505 switch (op) {
3506 case OPC_LDC1:
3507 case OPC_SDC1:
3508 check_insn(ctx, ISA_MIPS2);
3509 /* Fallthrough */
3510 default:
b52d3bfa
YK
3511 gen_base_offset_addr(ctx, t0, rs, imm);
3512 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3513 }
26ebe468
NF
3514 } else {
3515 generate_exception_err(ctx, EXCP_CpU, 1);
3516 }
b52d3bfa 3517 tcg_temp_free(t0);
26ebe468
NF
3518}
3519
6af0bf9c 3520/* Arithmetic with immediate operand */
d75c135e 3521static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3522 int rt, int rs, int imm)
6af0bf9c 3523{
324d9e32 3524 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3525
7a387fff 3526 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
7480515f
AM
3527 /*
3528 * If no destination, treat it as a NOP.
3529 * For addi, we must generate the overflow exception when needed.
3530 */
324d9e32 3531 return;
6af0bf9c
FB
3532 }
3533 switch (opc) {
3534 case OPC_ADDI:
48d38ca5 3535 {
324d9e32
AJ
3536 TCGv t0 = tcg_temp_local_new();
3537 TCGv t1 = tcg_temp_new();
3538 TCGv t2 = tcg_temp_new();
42a268c2 3539 TCGLabel *l1 = gen_new_label();
48d38ca5 3540
324d9e32
AJ
3541 gen_load_gpr(t1, rs);
3542 tcg_gen_addi_tl(t0, t1, uimm);
3543 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3544
324d9e32
AJ
3545 tcg_gen_xori_tl(t1, t1, ~uimm);
3546 tcg_gen_xori_tl(t2, t0, uimm);
3547 tcg_gen_and_tl(t1, t1, t2);
3548 tcg_temp_free(t2);
3549 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3550 tcg_temp_free(t1);
48d38ca5
TS
3551 /* operands of same sign, result different sign */
3552 generate_exception(ctx, EXCP_OVERFLOW);
3553 gen_set_label(l1);
78723684 3554 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3555 gen_store_gpr(t0, rt);
3556 tcg_temp_free(t0);
48d38ca5 3557 }
6af0bf9c
FB
3558 break;
3559 case OPC_ADDIU:
324d9e32
AJ
3560 if (rs != 0) {
3561 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3562 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3563 } else {
3564 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3565 }
6af0bf9c 3566 break;
d26bc211 3567#if defined(TARGET_MIPS64)
7a387fff 3568 case OPC_DADDI:
48d38ca5 3569 {
324d9e32
AJ
3570 TCGv t0 = tcg_temp_local_new();
3571 TCGv t1 = tcg_temp_new();
3572 TCGv t2 = tcg_temp_new();
42a268c2 3573 TCGLabel *l1 = gen_new_label();
48d38ca5 3574
324d9e32
AJ
3575 gen_load_gpr(t1, rs);
3576 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3577
324d9e32
AJ
3578 tcg_gen_xori_tl(t1, t1, ~uimm);
3579 tcg_gen_xori_tl(t2, t0, uimm);
3580 tcg_gen_and_tl(t1, t1, t2);
3581 tcg_temp_free(t2);
3582 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3583 tcg_temp_free(t1);
48d38ca5
TS
3584 /* operands of same sign, result different sign */
3585 generate_exception(ctx, EXCP_OVERFLOW);
3586 gen_set_label(l1);
324d9e32
AJ
3587 gen_store_gpr(t0, rt);
3588 tcg_temp_free(t0);
48d38ca5 3589 }
7a387fff
TS
3590 break;
3591 case OPC_DADDIU:
324d9e32
AJ
3592 if (rs != 0) {
3593 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3594 } else {
3595 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3596 }
7a387fff
TS
3597 break;
3598#endif
324d9e32 3599 }
324d9e32
AJ
3600}
3601
3602/* Logic with immediate operand */
d75c135e 3603static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3604 int rt, int rs, int16_t imm)
324d9e32
AJ
3605{
3606 target_ulong uimm;
324d9e32
AJ
3607
3608 if (rt == 0) {
3609 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3610 return;
3611 }
3612 uimm = (uint16_t)imm;
3613 switch (opc) {
6af0bf9c 3614 case OPC_ANDI:
1f8929d2 3615 if (likely(rs != 0)) {
324d9e32 3616 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 3617 } else {
324d9e32 3618 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1f8929d2 3619 }
6af0bf9c
FB
3620 break;
3621 case OPC_ORI:
1f8929d2 3622 if (rs != 0) {
324d9e32 3623 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 3624 } else {
324d9e32 3625 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 3626 }
6af0bf9c
FB
3627 break;
3628 case OPC_XORI:
1f8929d2 3629 if (likely(rs != 0)) {
324d9e32 3630 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 3631 } else {
324d9e32 3632 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 3633 }
6af0bf9c
FB
3634 break;
3635 case OPC_LUI:
2e211e0a 3636 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
d4ea6acd
LA
3637 /* OPC_AUI */
3638 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3639 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3640 } else {
3641 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3642 }
7c2c3ea3
EJ
3643 break;
3644
3645 default:
6af0bf9c 3646 break;
324d9e32 3647 }
324d9e32
AJ
3648}
3649
3650/* Set on less than with immediate operand */
d75c135e 3651static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3652 int rt, int rs, int16_t imm)
324d9e32
AJ
3653{
3654 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3655 TCGv t0;
3656
3657 if (rt == 0) {
3658 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3659 return;
3660 }
3661 t0 = tcg_temp_new();
3662 gen_load_gpr(t0, rs);
3663 switch (opc) {
3664 case OPC_SLTI:
e68dd28f 3665 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3666 break;
3667 case OPC_SLTIU:
e68dd28f 3668 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3669 break;
3670 }
324d9e32
AJ
3671 tcg_temp_free(t0);
3672}
3673
3674/* Shifts with immediate operand */
d75c135e 3675static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3676 int rt, int rs, int16_t imm)
3677{
3678 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3679 TCGv t0;
3680
3681 if (rt == 0) {
3682 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3683 return;
3684 }
3685
3686 t0 = tcg_temp_new();
3687 gen_load_gpr(t0, rs);
3688 switch (opc) {
6af0bf9c 3689 case OPC_SLL:
78723684 3690 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3691 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3692 break;
3693 case OPC_SRA:
324d9e32 3694 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3695 break;
3696 case OPC_SRL:
ea63e2c3
NF
3697 if (uimm != 0) {
3698 tcg_gen_ext32u_tl(t0, t0);
3699 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3700 } else {
3701 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 3702 }
ea63e2c3
NF
3703 break;
3704 case OPC_ROTR:
3705 if (uimm != 0) {
3706 TCGv_i32 t1 = tcg_temp_new_i32();
3707
3708 tcg_gen_trunc_tl_i32(t1, t0);
3709 tcg_gen_rotri_i32(t1, t1, uimm);
3710 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3711 tcg_temp_free_i32(t1);
3399e30f
NF
3712 } else {
3713 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 3714 }
7a387fff 3715 break;
d26bc211 3716#if defined(TARGET_MIPS64)
7a387fff 3717 case OPC_DSLL:
324d9e32 3718 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3719 break;
3720 case OPC_DSRA:
324d9e32 3721 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3722 break;
3723 case OPC_DSRL:
ea63e2c3 3724 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
3725 break;
3726 case OPC_DROTR:
3727 if (uimm != 0) {
3728 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
3729 } else {
3730 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 3731 }
7a387fff
TS
3732 break;
3733 case OPC_DSLL32:
324d9e32 3734 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3735 break;
3736 case OPC_DSRA32:
324d9e32 3737 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3738 break;
3739 case OPC_DSRL32:
ea63e2c3 3740 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
3741 break;
3742 case OPC_DROTR32:
3743 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 3744 break;
7a387fff 3745#endif
6af0bf9c 3746 }
78723684 3747 tcg_temp_free(t0);
6af0bf9c
FB
3748}
3749
3750/* Arithmetic */
d75c135e
AJ
3751static void gen_arith(DisasContext *ctx, uint32_t opc,
3752 int rd, int rs, int rt)
6af0bf9c 3753{
7a387fff
TS
3754 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3755 && opc != OPC_DADD && opc != OPC_DSUB) {
7480515f
AM
3756 /*
3757 * If no destination, treat it as a NOP.
3758 * For add & sub, we must generate the overflow exception when needed.
3759 */
460f00c4 3760 return;
185f0762 3761 }
460f00c4 3762
6af0bf9c
FB
3763 switch (opc) {
3764 case OPC_ADD:
48d38ca5 3765 {
460f00c4
AJ
3766 TCGv t0 = tcg_temp_local_new();
3767 TCGv t1 = tcg_temp_new();
3768 TCGv t2 = tcg_temp_new();
42a268c2 3769 TCGLabel *l1 = gen_new_label();
48d38ca5 3770
460f00c4
AJ
3771 gen_load_gpr(t1, rs);
3772 gen_load_gpr(t2, rt);
3773 tcg_gen_add_tl(t0, t1, t2);
3774 tcg_gen_ext32s_tl(t0, t0);
3775 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3776 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3777 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3778 tcg_temp_free(t2);
3779 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3780 tcg_temp_free(t1);
48d38ca5
TS
3781 /* operands of same sign, result different sign */
3782 generate_exception(ctx, EXCP_OVERFLOW);
3783 gen_set_label(l1);
460f00c4
AJ
3784 gen_store_gpr(t0, rd);
3785 tcg_temp_free(t0);
48d38ca5 3786 }
6af0bf9c
FB
3787 break;
3788 case OPC_ADDU:
460f00c4
AJ
3789 if (rs != 0 && rt != 0) {
3790 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3791 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3792 } else if (rs == 0 && rt != 0) {
3793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3794 } else if (rs != 0 && rt == 0) {
3795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3796 } else {
3797 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3798 }
6af0bf9c
FB
3799 break;
3800 case OPC_SUB:
48d38ca5 3801 {
460f00c4
AJ
3802 TCGv t0 = tcg_temp_local_new();
3803 TCGv t1 = tcg_temp_new();
3804 TCGv t2 = tcg_temp_new();
42a268c2 3805 TCGLabel *l1 = gen_new_label();
48d38ca5 3806
460f00c4
AJ
3807 gen_load_gpr(t1, rs);
3808 gen_load_gpr(t2, rt);
3809 tcg_gen_sub_tl(t0, t1, t2);
3810 tcg_gen_ext32s_tl(t0, t0);
3811 tcg_gen_xor_tl(t2, t1, t2);
3812 tcg_gen_xor_tl(t1, t0, t1);
3813 tcg_gen_and_tl(t1, t1, t2);
3814 tcg_temp_free(t2);
3815 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3816 tcg_temp_free(t1);
7480515f
AM
3817 /*
3818 * operands of different sign, first operand and the result
3819 * of different sign
3820 */
48d38ca5
TS
3821 generate_exception(ctx, EXCP_OVERFLOW);
3822 gen_set_label(l1);
460f00c4
AJ
3823 gen_store_gpr(t0, rd);
3824 tcg_temp_free(t0);
48d38ca5 3825 }
6af0bf9c
FB
3826 break;
3827 case OPC_SUBU:
460f00c4
AJ
3828 if (rs != 0 && rt != 0) {
3829 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3830 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3831 } else if (rs == 0 && rt != 0) {
3832 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 3833 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
3834 } else if (rs != 0 && rt == 0) {
3835 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3836 } else {
3837 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3838 }
6af0bf9c 3839 break;
d26bc211 3840#if defined(TARGET_MIPS64)
7a387fff 3841 case OPC_DADD:
48d38ca5 3842 {
460f00c4
AJ
3843 TCGv t0 = tcg_temp_local_new();
3844 TCGv t1 = tcg_temp_new();
3845 TCGv t2 = tcg_temp_new();
42a268c2 3846 TCGLabel *l1 = gen_new_label();
48d38ca5 3847
460f00c4
AJ
3848 gen_load_gpr(t1, rs);
3849 gen_load_gpr(t2, rt);
3850 tcg_gen_add_tl(t0, t1, t2);
3851 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3852 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3853 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3854 tcg_temp_free(t2);
3855 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3856 tcg_temp_free(t1);
48d38ca5
TS
3857 /* operands of same sign, result different sign */
3858 generate_exception(ctx, EXCP_OVERFLOW);
3859 gen_set_label(l1);
460f00c4
AJ
3860 gen_store_gpr(t0, rd);
3861 tcg_temp_free(t0);
48d38ca5 3862 }
7a387fff
TS
3863 break;
3864 case OPC_DADDU:
460f00c4
AJ
3865 if (rs != 0 && rt != 0) {
3866 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3867 } else if (rs == 0 && rt != 0) {
3868 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3869 } else if (rs != 0 && rt == 0) {
3870 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3871 } else {
3872 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3873 }
7a387fff
TS
3874 break;
3875 case OPC_DSUB:
48d38ca5 3876 {
460f00c4
AJ
3877 TCGv t0 = tcg_temp_local_new();
3878 TCGv t1 = tcg_temp_new();
3879 TCGv t2 = tcg_temp_new();
42a268c2 3880 TCGLabel *l1 = gen_new_label();
48d38ca5 3881
460f00c4
AJ
3882 gen_load_gpr(t1, rs);
3883 gen_load_gpr(t2, rt);
3884 tcg_gen_sub_tl(t0, t1, t2);
3885 tcg_gen_xor_tl(t2, t1, t2);
3886 tcg_gen_xor_tl(t1, t0, t1);
3887 tcg_gen_and_tl(t1, t1, t2);
3888 tcg_temp_free(t2);
3889 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3890 tcg_temp_free(t1);
71375b59
AM
3891 /*
3892 * Operands of different sign, first operand and result different
3893 * sign.
3894 */
48d38ca5
TS
3895 generate_exception(ctx, EXCP_OVERFLOW);
3896 gen_set_label(l1);
460f00c4
AJ
3897 gen_store_gpr(t0, rd);
3898 tcg_temp_free(t0);
48d38ca5 3899 }
7a387fff
TS
3900 break;
3901 case OPC_DSUBU:
460f00c4
AJ
3902 if (rs != 0 && rt != 0) {
3903 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3904 } else if (rs == 0 && rt != 0) {
3905 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3906 } else if (rs != 0 && rt == 0) {
3907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3908 } else {
3909 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3910 }
7a387fff
TS
3911 break;
3912#endif
460f00c4
AJ
3913 case OPC_MUL:
3914 if (likely(rs != 0 && rt != 0)) {
3915 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3916 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3917 } else {
3918 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3919 }
6af0bf9c 3920 break;
460f00c4 3921 }
460f00c4
AJ
3922}
3923
3924/* Conditional move */
d75c135e 3925static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 3926 int rd, int rs, int rt)
460f00c4 3927{
acf12465 3928 TCGv t0, t1, t2;
460f00c4
AJ
3929
3930 if (rd == 0) {
acf12465 3931 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3932 return;
3933 }
3934
acf12465
AJ
3935 t0 = tcg_temp_new();
3936 gen_load_gpr(t0, rt);
3937 t1 = tcg_const_tl(0);
3938 t2 = tcg_temp_new();
3939 gen_load_gpr(t2, rs);
460f00c4
AJ
3940 switch (opc) {
3941 case OPC_MOVN:
acf12465 3942 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 3943 break;
460f00c4 3944 case OPC_MOVZ:
acf12465 3945 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 3946 break;
b691d9d2
LA
3947 case OPC_SELNEZ:
3948 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
3949 break;
3950 case OPC_SELEQZ:
3951 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 3952 break;
460f00c4 3953 }
acf12465
AJ
3954 tcg_temp_free(t2);
3955 tcg_temp_free(t1);
3956 tcg_temp_free(t0);
460f00c4
AJ
3957}
3958
3959/* Logic */
d75c135e 3960static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 3961 int rd, int rs, int rt)
460f00c4 3962{
460f00c4
AJ
3963 if (rd == 0) {
3964 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3965 return;
3966 }
3967
3968 switch (opc) {
6af0bf9c 3969 case OPC_AND:
460f00c4
AJ
3970 if (likely(rs != 0 && rt != 0)) {
3971 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3972 } else {
3973 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3974 }
6af0bf9c
FB
3975 break;
3976 case OPC_NOR:
460f00c4
AJ
3977 if (rs != 0 && rt != 0) {
3978 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3979 } else if (rs == 0 && rt != 0) {
3980 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3981 } else if (rs != 0 && rt == 0) {
3982 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3983 } else {
3984 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3985 }
6af0bf9c
FB
3986 break;
3987 case OPC_OR:
460f00c4
AJ
3988 if (likely(rs != 0 && rt != 0)) {
3989 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3990 } else if (rs == 0 && rt != 0) {
3991 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3992 } else if (rs != 0 && rt == 0) {
3993 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3994 } else {
3995 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3996 }
6af0bf9c
FB
3997 break;
3998 case OPC_XOR:
460f00c4
AJ
3999 if (likely(rs != 0 && rt != 0)) {
4000 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4001 } else if (rs == 0 && rt != 0) {
4002 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4003 } else if (rs != 0 && rt == 0) {
4004 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4005 } else {
4006 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4007 }
6af0bf9c 4008 break;
460f00c4 4009 }
460f00c4
AJ
4010}
4011
4012/* Set on lower than */
d75c135e 4013static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 4014 int rd, int rs, int rt)
460f00c4 4015{
460f00c4
AJ
4016 TCGv t0, t1;
4017
4018 if (rd == 0) {
4019 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4020 return;
4021 }
4022
4023 t0 = tcg_temp_new();
4024 t1 = tcg_temp_new();
4025 gen_load_gpr(t0, rs);
4026 gen_load_gpr(t1, rt);
4027 switch (opc) {
4028 case OPC_SLT:
e68dd28f 4029 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 4030 break;
460f00c4 4031 case OPC_SLTU:
e68dd28f 4032 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
4033 break;
4034 }
460f00c4
AJ
4035 tcg_temp_free(t0);
4036 tcg_temp_free(t1);
4037}
20c4c97c 4038
460f00c4 4039/* Shifts */
d75c135e
AJ
4040static void gen_shift(DisasContext *ctx, uint32_t opc,
4041 int rd, int rs, int rt)
460f00c4 4042{
460f00c4 4043 TCGv t0, t1;
20c4c97c 4044
460f00c4 4045 if (rd == 0) {
7480515f
AM
4046 /*
4047 * If no destination, treat it as a NOP.
4048 * For add & sub, we must generate the overflow exception when needed.
4049 */
460f00c4
AJ
4050 return;
4051 }
4052
4053 t0 = tcg_temp_new();
4054 t1 = tcg_temp_new();
4055 gen_load_gpr(t0, rs);
4056 gen_load_gpr(t1, rt);
4057 switch (opc) {
6af0bf9c 4058 case OPC_SLLV:
78723684
TS
4059 tcg_gen_andi_tl(t0, t0, 0x1f);
4060 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 4061 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
4062 break;
4063 case OPC_SRAV:
78723684 4064 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 4065 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
4066 break;
4067 case OPC_SRLV:
ea63e2c3
NF
4068 tcg_gen_ext32u_tl(t1, t1);
4069 tcg_gen_andi_tl(t0, t0, 0x1f);
4070 tcg_gen_shr_tl(t0, t1, t0);
4071 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
4072 break;
4073 case OPC_ROTRV:
4074 {
4075 TCGv_i32 t2 = tcg_temp_new_i32();
4076 TCGv_i32 t3 = tcg_temp_new_i32();
4077
4078 tcg_gen_trunc_tl_i32(t2, t0);
4079 tcg_gen_trunc_tl_i32(t3, t1);
4080 tcg_gen_andi_i32(t2, t2, 0x1f);
4081 tcg_gen_rotr_i32(t2, t3, t2);
4082 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4083 tcg_temp_free_i32(t2);
4084 tcg_temp_free_i32(t3);
5a63bcb2 4085 }
7a387fff 4086 break;
d26bc211 4087#if defined(TARGET_MIPS64)
7a387fff 4088 case OPC_DSLLV:
78723684 4089 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4090 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4091 break;
4092 case OPC_DSRAV:
78723684 4093 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4094 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4095 break;
4096 case OPC_DSRLV:
ea63e2c3
NF
4097 tcg_gen_andi_tl(t0, t0, 0x3f);
4098 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
4099 break;
4100 case OPC_DROTRV:
4101 tcg_gen_andi_tl(t0, t0, 0x3f);
4102 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 4103 break;
7a387fff 4104#endif
6af0bf9c 4105 }
78723684
TS
4106 tcg_temp_free(t0);
4107 tcg_temp_free(t1);
6af0bf9c
FB
4108}
4109
37b9aae2 4110#if defined(TARGET_MIPS64)
86efbfb6
FN
4111/* Copy GPR to and from TX79 HI1/LO1 register. */
4112static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4113{
baa609db 4114 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
86efbfb6
FN
4115 /* Treat as NOP. */
4116 return;
4117 }
4118
4119 switch (opc) {
baa609db 4120 case MMI_OPC_MFHI1:
86efbfb6
FN
4121 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4122 break;
baa609db 4123 case MMI_OPC_MFLO1:
86efbfb6
FN
4124 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4125 break;
baa609db 4126 case MMI_OPC_MTHI1:
86efbfb6
FN
4127 if (reg != 0) {
4128 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4129 } else {
4130 tcg_gen_movi_tl(cpu_HI[1], 0);
4131 }
4132 break;
baa609db 4133 case MMI_OPC_MTLO1:
86efbfb6
FN
4134 if (reg != 0) {
4135 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4136 } else {
4137 tcg_gen_movi_tl(cpu_LO[1], 0);
4138 }
4139 break;
4140 default:
4141 MIPS_INVAL("mfthilo1 TX79");
3a4ef3b7 4142 gen_reserved_instruction(ctx);
86efbfb6
FN
4143 break;
4144 }
4145}
37b9aae2 4146#endif
86efbfb6 4147
6af0bf9c 4148/* Arithmetic on HI/LO registers */
26135ead 4149static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 4150{
86efbfb6 4151 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 4152 /* Treat as NOP. */
a1f6684d 4153 return;
6af0bf9c 4154 }
4133498f 4155
4133498f 4156 if (acc != 0) {
86efbfb6 4157 check_dsp(ctx);
4133498f
JL
4158 }
4159
6af0bf9c
FB
4160 switch (opc) {
4161 case OPC_MFHI:
4133498f
JL
4162#if defined(TARGET_MIPS64)
4163 if (acc != 0) {
4164 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4165 } else
4166#endif
4167 {
4168 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4169 }
6af0bf9c
FB
4170 break;
4171 case OPC_MFLO:
4133498f
JL
4172#if defined(TARGET_MIPS64)
4173 if (acc != 0) {
4174 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4175 } else
4176#endif
4177 {
4178 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4179 }
6af0bf9c
FB
4180 break;
4181 case OPC_MTHI:
4133498f
JL
4182 if (reg != 0) {
4183#if defined(TARGET_MIPS64)
4184 if (acc != 0) {
4185 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4186 } else
4187#endif
4188 {
4189 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4190 }
4191 } else {
4192 tcg_gen_movi_tl(cpu_HI[acc], 0);
4193 }
6af0bf9c
FB
4194 break;
4195 case OPC_MTLO:
4133498f
JL
4196 if (reg != 0) {
4197#if defined(TARGET_MIPS64)
4198 if (acc != 0) {
4199 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4200 } else
4201#endif
4202 {
4203 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4204 }
4205 } else {
4206 tcg_gen_movi_tl(cpu_LO[acc], 0);
4207 }
6af0bf9c 4208 break;
6af0bf9c 4209 }
6af0bf9c
FB
4210}
4211
d4ea6acd 4212static inline void gen_r6_ld(target_long addr, int reg, int memidx,
14776ab5 4213 MemOp memop)
d4ea6acd
LA
4214{
4215 TCGv t0 = tcg_const_tl(addr);
4216 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4217 gen_store_gpr(t0, reg);
4218 tcg_temp_free(t0);
4219}
4220
ab39ee45
YK
4221static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4222 int rs)
d4ea6acd
LA
4223{
4224 target_long offset;
4225 target_long addr;
4226
ab39ee45 4227 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
4228 case OPC_ADDIUPC:
4229 if (rs != 0) {
4230 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4231 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4232 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4233 }
4234 break;
4235 case R6_OPC_LWPC:
4236 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4237 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4238 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4239 break;
4240#if defined(TARGET_MIPS64)
4241 case OPC_LWUPC:
4242 check_mips_64(ctx);
4243 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4244 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4245 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4246 break;
4247#endif
4248 default:
ab39ee45 4249 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
4250 case OPC_AUIPC:
4251 if (rs != 0) {
ab39ee45
YK
4252 offset = sextract32(ctx->opcode, 0, 16) << 16;
4253 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4254 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4255 }
4256 break;
4257 case OPC_ALUIPC:
4258 if (rs != 0) {
ab39ee45
YK
4259 offset = sextract32(ctx->opcode, 0, 16) << 16;
4260 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
4261 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4262 }
4263 break;
4264#if defined(TARGET_MIPS64)
4265 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4266 case R6_OPC_LDPC + (1 << 16):
4267 case R6_OPC_LDPC + (2 << 16):
4268 case R6_OPC_LDPC + (3 << 16):
4269 check_mips_64(ctx);
4270 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 4271 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
4272 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4273 break;
4274#endif
4275 default:
4276 MIPS_INVAL("OPC_PCREL");
3a4ef3b7 4277 gen_reserved_instruction(ctx);
d4ea6acd
LA
4278 break;
4279 }
4280 break;
4281 }
4282}
4283
b42ee5e1
LA
4284static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4285{
b42ee5e1
LA
4286 TCGv t0, t1;
4287
4288 if (rd == 0) {
4289 /* Treat as NOP. */
b42ee5e1
LA
4290 return;
4291 }
4292
4293 t0 = tcg_temp_new();
4294 t1 = tcg_temp_new();
4295
4296 gen_load_gpr(t0, rs);
4297 gen_load_gpr(t1, rt);
4298
4299 switch (opc) {
4300 case R6_OPC_DIV:
4301 {
4302 TCGv t2 = tcg_temp_new();
4303 TCGv t3 = tcg_temp_new();
4304 tcg_gen_ext32s_tl(t0, t0);
4305 tcg_gen_ext32s_tl(t1, t1);
4306 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4307 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4308 tcg_gen_and_tl(t2, t2, t3);
4309 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4310 tcg_gen_or_tl(t2, t2, t3);
4311 tcg_gen_movi_tl(t3, 0);
4312 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4313 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4314 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4315 tcg_temp_free(t3);
4316 tcg_temp_free(t2);
4317 }
b42ee5e1
LA
4318 break;
4319 case R6_OPC_MOD:
4320 {
4321 TCGv t2 = tcg_temp_new();
4322 TCGv t3 = tcg_temp_new();
4323 tcg_gen_ext32s_tl(t0, t0);
4324 tcg_gen_ext32s_tl(t1, t1);
4325 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4326 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4327 tcg_gen_and_tl(t2, t2, t3);
4328 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4329 tcg_gen_or_tl(t2, t2, t3);
4330 tcg_gen_movi_tl(t3, 0);
4331 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4332 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4333 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4334 tcg_temp_free(t3);
4335 tcg_temp_free(t2);
4336 }
b42ee5e1
LA
4337 break;
4338 case R6_OPC_DIVU:
4339 {
4340 TCGv t2 = tcg_const_tl(0);
4341 TCGv t3 = tcg_const_tl(1);
4342 tcg_gen_ext32u_tl(t0, t0);
4343 tcg_gen_ext32u_tl(t1, t1);
4344 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4345 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4347 tcg_temp_free(t3);
4348 tcg_temp_free(t2);
4349 }
b42ee5e1
LA
4350 break;
4351 case R6_OPC_MODU:
4352 {
4353 TCGv t2 = tcg_const_tl(0);
4354 TCGv t3 = tcg_const_tl(1);
4355 tcg_gen_ext32u_tl(t0, t0);
4356 tcg_gen_ext32u_tl(t1, t1);
4357 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4358 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4359 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4360 tcg_temp_free(t3);
4361 tcg_temp_free(t2);
4362 }
b42ee5e1
LA
4363 break;
4364 case R6_OPC_MUL:
4365 {
4366 TCGv_i32 t2 = tcg_temp_new_i32();
4367 TCGv_i32 t3 = tcg_temp_new_i32();
4368 tcg_gen_trunc_tl_i32(t2, t0);
4369 tcg_gen_trunc_tl_i32(t3, t1);
4370 tcg_gen_mul_i32(t2, t2, t3);
4371 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4372 tcg_temp_free_i32(t2);
4373 tcg_temp_free_i32(t3);
4374 }
b42ee5e1
LA
4375 break;
4376 case R6_OPC_MUH:
4377 {
4378 TCGv_i32 t2 = tcg_temp_new_i32();
4379 TCGv_i32 t3 = tcg_temp_new_i32();
4380 tcg_gen_trunc_tl_i32(t2, t0);
4381 tcg_gen_trunc_tl_i32(t3, t1);
4382 tcg_gen_muls2_i32(t2, t3, t2, t3);
4383 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4384 tcg_temp_free_i32(t2);
4385 tcg_temp_free_i32(t3);
4386 }
b42ee5e1
LA
4387 break;
4388 case R6_OPC_MULU:
4389 {
4390 TCGv_i32 t2 = tcg_temp_new_i32();
4391 TCGv_i32 t3 = tcg_temp_new_i32();
4392 tcg_gen_trunc_tl_i32(t2, t0);
4393 tcg_gen_trunc_tl_i32(t3, t1);
4394 tcg_gen_mul_i32(t2, t2, t3);
4395 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4396 tcg_temp_free_i32(t2);
4397 tcg_temp_free_i32(t3);
4398 }
b42ee5e1
LA
4399 break;
4400 case R6_OPC_MUHU:
4401 {
4402 TCGv_i32 t2 = tcg_temp_new_i32();
4403 TCGv_i32 t3 = tcg_temp_new_i32();
4404 tcg_gen_trunc_tl_i32(t2, t0);
4405 tcg_gen_trunc_tl_i32(t3, t1);
4406 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4407 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4408 tcg_temp_free_i32(t2);
4409 tcg_temp_free_i32(t3);
4410 }
b42ee5e1
LA
4411 break;
4412#if defined(TARGET_MIPS64)
4413 case R6_OPC_DDIV:
4414 {
4415 TCGv t2 = tcg_temp_new();
4416 TCGv t3 = tcg_temp_new();
4417 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4418 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4419 tcg_gen_and_tl(t2, t2, t3);
4420 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4421 tcg_gen_or_tl(t2, t2, t3);
4422 tcg_gen_movi_tl(t3, 0);
4423 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4424 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4425 tcg_temp_free(t3);
4426 tcg_temp_free(t2);
4427 }
b42ee5e1
LA
4428 break;
4429 case R6_OPC_DMOD:
4430 {
4431 TCGv t2 = tcg_temp_new();
4432 TCGv t3 = tcg_temp_new();
4433 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4434 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4435 tcg_gen_and_tl(t2, t2, t3);
4436 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4437 tcg_gen_or_tl(t2, t2, t3);
4438 tcg_gen_movi_tl(t3, 0);
4439 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4440 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4441 tcg_temp_free(t3);
4442 tcg_temp_free(t2);
4443 }
b42ee5e1
LA
4444 break;
4445 case R6_OPC_DDIVU:
4446 {
4447 TCGv t2 = tcg_const_tl(0);
4448 TCGv t3 = tcg_const_tl(1);
4449 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4450 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4451 tcg_temp_free(t3);
4452 tcg_temp_free(t2);
4453 }
b42ee5e1
LA
4454 break;
4455 case R6_OPC_DMODU:
4456 {
4457 TCGv t2 = tcg_const_tl(0);
4458 TCGv t3 = tcg_const_tl(1);
4459 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4460 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4461 tcg_temp_free(t3);
4462 tcg_temp_free(t2);
4463 }
b42ee5e1
LA
4464 break;
4465 case R6_OPC_DMUL:
4466 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4467 break;
4468 case R6_OPC_DMUH:
4469 {
4470 TCGv t2 = tcg_temp_new();
4471 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4472 tcg_temp_free(t2);
4473 }
b42ee5e1
LA
4474 break;
4475 case R6_OPC_DMULU:
4476 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4477 break;
4478 case R6_OPC_DMUHU:
4479 {
4480 TCGv t2 = tcg_temp_new();
4481 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4482 tcg_temp_free(t2);
4483 }
b42ee5e1
LA
4484 break;
4485#endif
4486 default:
9d68ac14 4487 MIPS_INVAL("r6 mul/div");
3a4ef3b7 4488 gen_reserved_instruction(ctx);
b42ee5e1
LA
4489 goto out;
4490 }
b42ee5e1
LA
4491 out:
4492 tcg_temp_free(t0);
4493 tcg_temp_free(t1);
4494}
4495
37b9aae2 4496#if defined(TARGET_MIPS64)
c42171c3
FN
4497static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4498{
4499 TCGv t0, t1;
4500
4501 t0 = tcg_temp_new();
4502 t1 = tcg_temp_new();
4503
4504 gen_load_gpr(t0, rs);
4505 gen_load_gpr(t1, rt);
4506
4507 switch (opc) {
baa609db 4508 case MMI_OPC_DIV1:
c42171c3
FN
4509 {
4510 TCGv t2 = tcg_temp_new();
4511 TCGv t3 = tcg_temp_new();
4512 tcg_gen_ext32s_tl(t0, t0);
4513 tcg_gen_ext32s_tl(t1, t1);
4514 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4515 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
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_div_tl(cpu_LO[1], t0, t1);
4522 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4523 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4524 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4525 tcg_temp_free(t3);
4526 tcg_temp_free(t2);
4527 }
4528 break;
baa609db 4529 case MMI_OPC_DIVU1:
c42171c3
FN
4530 {
4531 TCGv t2 = tcg_const_tl(0);
4532 TCGv t3 = tcg_const_tl(1);
4533 tcg_gen_ext32u_tl(t0, t0);
4534 tcg_gen_ext32u_tl(t1, t1);
4535 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4536 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4537 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4538 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4539 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4540 tcg_temp_free(t3);
4541 tcg_temp_free(t2);
4542 }
4543 break;
4544 default:
4545 MIPS_INVAL("div1 TX79");
3a4ef3b7 4546 gen_reserved_instruction(ctx);
c42171c3
FN
4547 goto out;
4548 }
4549 out:
4550 tcg_temp_free(t0);
4551 tcg_temp_free(t1);
4552}
37b9aae2 4553#endif
c42171c3 4554
26135ead
RS
4555static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4556 int acc, int rs, int rt)
6af0bf9c 4557{
d45f89f4
AJ
4558 TCGv t0, t1;
4559
51127181
AJ
4560 t0 = tcg_temp_new();
4561 t1 = tcg_temp_new();
6af0bf9c 4562
78723684
TS
4563 gen_load_gpr(t0, rs);
4564 gen_load_gpr(t1, rt);
51127181 4565
26135ead 4566 if (acc != 0) {
c42171c3 4567 check_dsp(ctx);
26135ead
RS
4568 }
4569
6af0bf9c
FB
4570 switch (opc) {
4571 case OPC_DIV:
48d38ca5 4572 {
51127181
AJ
4573 TCGv t2 = tcg_temp_new();
4574 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4575 tcg_gen_ext32s_tl(t0, t0);
4576 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4577 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4578 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4579 tcg_gen_and_tl(t2, t2, t3);
4580 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4581 tcg_gen_or_tl(t2, t2, t3);
4582 tcg_gen_movi_tl(t3, 0);
4583 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4584 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4585 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4586 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4587 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4588 tcg_temp_free(t3);
4589 tcg_temp_free(t2);
48d38ca5 4590 }
6af0bf9c
FB
4591 break;
4592 case OPC_DIVU:
48d38ca5 4593 {
51127181
AJ
4594 TCGv t2 = tcg_const_tl(0);
4595 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4596 tcg_gen_ext32u_tl(t0, t0);
4597 tcg_gen_ext32u_tl(t1, t1);
51127181 4598 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4599 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4600 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4601 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4602 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4603 tcg_temp_free(t3);
4604 tcg_temp_free(t2);
48d38ca5 4605 }
6af0bf9c
FB
4606 break;
4607 case OPC_MULT:
214c465f 4608 {
ce1dd5d1
RH
4609 TCGv_i32 t2 = tcg_temp_new_i32();
4610 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4611 tcg_gen_trunc_tl_i32(t2, t0);
4612 tcg_gen_trunc_tl_i32(t3, t1);
4613 tcg_gen_muls2_i32(t2, t3, t2, t3);
4614 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4615 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4616 tcg_temp_free_i32(t2);
4617 tcg_temp_free_i32(t3);
214c465f 4618 }
6af0bf9c
FB
4619 break;
4620 case OPC_MULTU:
214c465f 4621 {
ce1dd5d1
RH
4622 TCGv_i32 t2 = tcg_temp_new_i32();
4623 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4624 tcg_gen_trunc_tl_i32(t2, t0);
4625 tcg_gen_trunc_tl_i32(t3, t1);
4626 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4627 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4628 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4629 tcg_temp_free_i32(t2);
4630 tcg_temp_free_i32(t3);
214c465f 4631 }
6af0bf9c 4632 break;
d26bc211 4633#if defined(TARGET_MIPS64)
7a387fff 4634 case OPC_DDIV:
48d38ca5 4635 {
51127181
AJ
4636 TCGv t2 = tcg_temp_new();
4637 TCGv t3 = tcg_temp_new();
4638 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4639 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4640 tcg_gen_and_tl(t2, t2, t3);
4641 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4642 tcg_gen_or_tl(t2, t2, t3);
4643 tcg_gen_movi_tl(t3, 0);
4644 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4645 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4646 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4647 tcg_temp_free(t3);
4648 tcg_temp_free(t2);
48d38ca5 4649 }
7a387fff
TS
4650 break;
4651 case OPC_DDIVU:
48d38ca5 4652 {
51127181
AJ
4653 TCGv t2 = tcg_const_tl(0);
4654 TCGv t3 = tcg_const_tl(1);
4655 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4656 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4657 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4658 tcg_temp_free(t3);
4659 tcg_temp_free(t2);
48d38ca5 4660 }
7a387fff
TS
4661 break;
4662 case OPC_DMULT:
26135ead 4663 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4664 break;
4665 case OPC_DMULTU:
26135ead 4666 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4667 break;
4668#endif
6af0bf9c 4669 case OPC_MADD:
214c465f 4670 {
d45f89f4
AJ
4671 TCGv_i64 t2 = tcg_temp_new_i64();
4672 TCGv_i64 t3 = tcg_temp_new_i64();
4673
4674 tcg_gen_ext_tl_i64(t2, t0);
4675 tcg_gen_ext_tl_i64(t3, t1);
4676 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4677 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4678 tcg_gen_add_i64(t2, t2, t3);
4679 tcg_temp_free_i64(t3);
71f303cd
RH
4680 gen_move_low32(cpu_LO[acc], t2);
4681 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4682 tcg_temp_free_i64(t2);
214c465f 4683 }
6af0bf9c
FB
4684 break;
4685 case OPC_MADDU:
4133498f 4686 {
d45f89f4
AJ
4687 TCGv_i64 t2 = tcg_temp_new_i64();
4688 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4689
78723684
TS
4690 tcg_gen_ext32u_tl(t0, t0);
4691 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4692 tcg_gen_extu_tl_i64(t2, t0);
4693 tcg_gen_extu_tl_i64(t3, t1);
4694 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4695 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4696 tcg_gen_add_i64(t2, t2, t3);
4697 tcg_temp_free_i64(t3);
71f303cd
RH
4698 gen_move_low32(cpu_LO[acc], t2);
4699 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4700 tcg_temp_free_i64(t2);
214c465f 4701 }
6af0bf9c
FB
4702 break;
4703 case OPC_MSUB:
214c465f 4704 {
d45f89f4
AJ
4705 TCGv_i64 t2 = tcg_temp_new_i64();
4706 TCGv_i64 t3 = tcg_temp_new_i64();
4707
4708 tcg_gen_ext_tl_i64(t2, t0);
4709 tcg_gen_ext_tl_i64(t3, t1);
4710 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4711 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4712 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4713 tcg_temp_free_i64(t3);
71f303cd
RH
4714 gen_move_low32(cpu_LO[acc], t2);
4715 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4716 tcg_temp_free_i64(t2);
214c465f 4717 }
6af0bf9c
FB
4718 break;
4719 case OPC_MSUBU:
214c465f 4720 {
d45f89f4
AJ
4721 TCGv_i64 t2 = tcg_temp_new_i64();
4722 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4723
78723684
TS
4724 tcg_gen_ext32u_tl(t0, t0);
4725 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4726 tcg_gen_extu_tl_i64(t2, t0);
4727 tcg_gen_extu_tl_i64(t3, t1);
4728 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4729 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4730 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4731 tcg_temp_free_i64(t3);
71f303cd
RH
4732 gen_move_low32(cpu_LO[acc], t2);
4733 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4734 tcg_temp_free_i64(t2);
214c465f 4735 }
6af0bf9c
FB
4736 break;
4737 default:
9d68ac14 4738 MIPS_INVAL("mul/div");
3a4ef3b7 4739 gen_reserved_instruction(ctx);
78723684 4740 goto out;
6af0bf9c 4741 }
78723684
TS
4742 out:
4743 tcg_temp_free(t0);
4744 tcg_temp_free(t1);
6af0bf9c
FB
4745}
4746
21e8e8b2 4747/*
3b948f05
PMD
4748 * These MULT[U] and MADD[U] instructions implemented in for example
4749 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
21e8e8b2
FN
4750 * architectures are special three-operand variants with the syntax
4751 *
06de726b 4752 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
4753 *
4754 * such that
4755 *
4756 * (rd, LO, HI) <- rs * rt
4757 *
3b948f05
PMD
4758 * and
4759 *
a95c4c26 4760 * MADD[U][1] rd, rs, rt
3b948f05
PMD
4761 *
4762 * such that
4763 *
4764 * (rd, LO, HI) <- (LO, HI) + rs * rt
4765 *
21e8e8b2
FN
4766 * where the low-order 32-bits of the result is placed into both the
4767 * GPR rd and the special register LO. The high-order 32-bits of the
4768 * result is placed into the special register HI.
4769 *
4770 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4771 * which is the zero register that always reads as 0.
4772 */
4773static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
4774 int rd, int rs, int rt)
4775{
4776 TCGv t0 = tcg_temp_new();
4777 TCGv t1 = tcg_temp_new();
4778 int acc = 0;
4779
4780 gen_load_gpr(t0, rs);
4781 gen_load_gpr(t1, rt);
4782
4783 switch (opc) {
baa609db 4784 case MMI_OPC_MULT1:
06de726b
FN
4785 acc = 1;
4786 /* Fall through */
21e8e8b2
FN
4787 case OPC_MULT:
4788 {
4789 TCGv_i32 t2 = tcg_temp_new_i32();
4790 TCGv_i32 t3 = tcg_temp_new_i32();
4791 tcg_gen_trunc_tl_i32(t2, t0);
4792 tcg_gen_trunc_tl_i32(t3, t1);
4793 tcg_gen_muls2_i32(t2, t3, t2, t3);
4794 if (rd) {
4795 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4796 }
4797 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4798 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4799 tcg_temp_free_i32(t2);
4800 tcg_temp_free_i32(t3);
4801 }
4802 break;
baa609db 4803 case MMI_OPC_MULTU1:
06de726b
FN
4804 acc = 1;
4805 /* Fall through */
21e8e8b2
FN
4806 case OPC_MULTU:
4807 {
4808 TCGv_i32 t2 = tcg_temp_new_i32();
4809 TCGv_i32 t3 = tcg_temp_new_i32();
4810 tcg_gen_trunc_tl_i32(t2, t0);
4811 tcg_gen_trunc_tl_i32(t3, t1);
4812 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4813 if (rd) {
4814 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4815 }
4816 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4817 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4818 tcg_temp_free_i32(t2);
4819 tcg_temp_free_i32(t3);
4820 }
4821 break;
a95c4c26
FN
4822 case MMI_OPC_MADD1:
4823 acc = 1;
4824 /* Fall through */
3b948f05
PMD
4825 case MMI_OPC_MADD:
4826 {
4827 TCGv_i64 t2 = tcg_temp_new_i64();
4828 TCGv_i64 t3 = tcg_temp_new_i64();
4829
4830 tcg_gen_ext_tl_i64(t2, t0);
4831 tcg_gen_ext_tl_i64(t3, t1);
4832 tcg_gen_mul_i64(t2, t2, t3);
4833 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4834 tcg_gen_add_i64(t2, t2, t3);
4835 tcg_temp_free_i64(t3);
4836 gen_move_low32(cpu_LO[acc], t2);
4837 gen_move_high32(cpu_HI[acc], t2);
4838 if (rd) {
4839 gen_move_low32(cpu_gpr[rd], t2);
4840 }
4841 tcg_temp_free_i64(t2);
4842 }
4843 break;
a95c4c26
FN
4844 case MMI_OPC_MADDU1:
4845 acc = 1;
4846 /* Fall through */
3b948f05
PMD
4847 case MMI_OPC_MADDU:
4848 {
4849 TCGv_i64 t2 = tcg_temp_new_i64();
4850 TCGv_i64 t3 = tcg_temp_new_i64();
4851
4852 tcg_gen_ext32u_tl(t0, t0);
4853 tcg_gen_ext32u_tl(t1, t1);
4854 tcg_gen_extu_tl_i64(t2, t0);
4855 tcg_gen_extu_tl_i64(t3, t1);
4856 tcg_gen_mul_i64(t2, t2, t3);
4857 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4858 tcg_gen_add_i64(t2, t2, t3);
4859 tcg_temp_free_i64(t3);
4860 gen_move_low32(cpu_LO[acc], t2);
4861 gen_move_high32(cpu_HI[acc], t2);
4862 if (rd) {
4863 gen_move_low32(cpu_gpr[rd], t2);
4864 }
4865 tcg_temp_free_i64(t2);
4866 }
4867 break;
21e8e8b2 4868 default:
3b948f05 4869 MIPS_INVAL("mul/madd TXx9");
3a4ef3b7 4870 gen_reserved_instruction(ctx);
21e8e8b2
FN
4871 goto out;
4872 }
4873
4874 out:
4875 tcg_temp_free(t0);
4876 tcg_temp_free(t1);
4877}
4878
235785e8
AM
4879static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
4880 int rd, int rs, int rt)
e9c71dd1 4881{
f157bfe1
AJ
4882 TCGv t0 = tcg_temp_new();
4883 TCGv t1 = tcg_temp_new();
e9c71dd1 4884
6c5c1e20
TS
4885 gen_load_gpr(t0, rs);
4886 gen_load_gpr(t1, rt);
e9c71dd1
TS
4887
4888 switch (opc) {
4889 case OPC_VR54XX_MULS:
895c2d04 4890 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 4891 break;
e9c71dd1 4892 case OPC_VR54XX_MULSU:
895c2d04 4893 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 4894 break;
e9c71dd1 4895 case OPC_VR54XX_MACC:
895c2d04 4896 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 4897 break;
e9c71dd1 4898 case OPC_VR54XX_MACCU:
895c2d04 4899 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 4900 break;
e9c71dd1 4901 case OPC_VR54XX_MSAC:
895c2d04 4902 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 4903 break;
e9c71dd1 4904 case OPC_VR54XX_MSACU:
895c2d04 4905 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 4906 break;
e9c71dd1 4907 case OPC_VR54XX_MULHI:
895c2d04 4908 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 4909 break;
e9c71dd1 4910 case OPC_VR54XX_MULHIU:
895c2d04 4911 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 4912 break;
e9c71dd1 4913 case OPC_VR54XX_MULSHI:
895c2d04 4914 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 4915 break;
e9c71dd1 4916 case OPC_VR54XX_MULSHIU:
895c2d04 4917 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 4918 break;
e9c71dd1 4919 case OPC_VR54XX_MACCHI:
895c2d04 4920 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 4921 break;
e9c71dd1 4922 case OPC_VR54XX_MACCHIU:
895c2d04 4923 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 4924 break;
e9c71dd1 4925 case OPC_VR54XX_MSACHI:
895c2d04 4926 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 4927 break;
e9c71dd1 4928 case OPC_VR54XX_MSACHIU:
895c2d04 4929 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 4930 break;
e9c71dd1
TS
4931 default:
4932 MIPS_INVAL("mul vr54xx");
3a4ef3b7 4933 gen_reserved_instruction(ctx);
6c5c1e20 4934 goto out;
e9c71dd1 4935 }
6c5c1e20 4936 gen_store_gpr(t0, rd);
6c5c1e20
TS
4937
4938 out:
4939 tcg_temp_free(t0);
4940 tcg_temp_free(t1);
e9c71dd1
TS
4941}
4942
235785e8
AM
4943static void gen_cl(DisasContext *ctx, uint32_t opc,
4944 int rd, int rs)
6af0bf9c 4945{
20e1fb52 4946 TCGv t0;
6c5c1e20 4947
6af0bf9c 4948 if (rd == 0) {
ead9360e 4949 /* Treat as NOP. */
20e1fb52 4950 return;
6af0bf9c 4951 }
1a0196c5 4952 t0 = cpu_gpr[rd];
6c5c1e20 4953 gen_load_gpr(t0, rs);
1a0196c5 4954
6af0bf9c
FB
4955 switch (opc) {
4956 case OPC_CLO:
4267d3e6 4957 case R6_OPC_CLO:
1a0196c5
RH
4958#if defined(TARGET_MIPS64)
4959 case OPC_DCLO:
4960 case R6_OPC_DCLO:
4961#endif
4962 tcg_gen_not_tl(t0, t0);
6af0bf9c 4963 break;
1a0196c5
RH
4964 }
4965
4966 switch (opc) {
4967 case OPC_CLO:
4968 case R6_OPC_CLO:
6af0bf9c 4969 case OPC_CLZ:
4267d3e6 4970 case R6_OPC_CLZ:
1a0196c5
RH
4971 tcg_gen_ext32u_tl(t0, t0);
4972 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4973 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 4974 break;
d26bc211 4975#if defined(TARGET_MIPS64)
7a387fff 4976 case OPC_DCLO:
4267d3e6 4977 case R6_OPC_DCLO:
7a387fff 4978 case OPC_DCLZ:
4267d3e6 4979 case R6_OPC_DCLZ:
1a0196c5 4980 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
4981 break;
4982#endif
6af0bf9c 4983 }
6af0bf9c
FB
4984}
4985
161f85e6 4986/* Godson integer instructions */
bd277fa1
RH
4987static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4988 int rd, int rs, int rt)
161f85e6 4989{
161f85e6
AJ
4990 TCGv t0, t1;
4991
4992 if (rd == 0) {
4993 /* Treat as NOP. */
161f85e6
AJ
4994 return;
4995 }
4996
4997 switch (opc) {
4998 case OPC_MULT_G_2E:
4999 case OPC_MULT_G_2F:
5000 case OPC_MULTU_G_2E:
5001 case OPC_MULTU_G_2F:
5002#if defined(TARGET_MIPS64)
5003 case OPC_DMULT_G_2E:
5004 case OPC_DMULT_G_2F:
5005 case OPC_DMULTU_G_2E:
5006 case OPC_DMULTU_G_2F:
5007#endif
5008 t0 = tcg_temp_new();
5009 t1 = tcg_temp_new();
5010 break;
5011 default:
5012 t0 = tcg_temp_local_new();
5013 t1 = tcg_temp_local_new();
5014 break;
5015 }
5016
5017 gen_load_gpr(t0, rs);
5018 gen_load_gpr(t1, rt);
5019
5020 switch (opc) {
5021 case OPC_MULT_G_2E:
5022 case OPC_MULT_G_2F:
5023 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5024 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5025 break;
5026 case OPC_MULTU_G_2E:
5027 case OPC_MULTU_G_2F:
5028 tcg_gen_ext32u_tl(t0, t0);
5029 tcg_gen_ext32u_tl(t1, t1);
5030 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5031 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5032 break;
5033 case OPC_DIV_G_2E:
5034 case OPC_DIV_G_2F:
5035 {
42a268c2
RH
5036 TCGLabel *l1 = gen_new_label();
5037 TCGLabel *l2 = gen_new_label();
5038 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5039 tcg_gen_ext32s_tl(t0, t0);
5040 tcg_gen_ext32s_tl(t1, t1);
5041 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5042 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5043 tcg_gen_br(l3);
5044 gen_set_label(l1);
5045 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5047 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5048 tcg_gen_br(l3);
5049 gen_set_label(l2);
5050 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5051 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5052 gen_set_label(l3);
5053 }
161f85e6
AJ
5054 break;
5055 case OPC_DIVU_G_2E:
5056 case OPC_DIVU_G_2F:
5057 {
42a268c2
RH
5058 TCGLabel *l1 = gen_new_label();
5059 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5060 tcg_gen_ext32u_tl(t0, t0);
5061 tcg_gen_ext32u_tl(t1, t1);
5062 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5063 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5064 tcg_gen_br(l2);
5065 gen_set_label(l1);
5066 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5067 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5068 gen_set_label(l2);
5069 }
161f85e6
AJ
5070 break;
5071 case OPC_MOD_G_2E:
5072 case OPC_MOD_G_2F:
5073 {
42a268c2
RH
5074 TCGLabel *l1 = gen_new_label();
5075 TCGLabel *l2 = gen_new_label();
5076 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5077 tcg_gen_ext32u_tl(t0, t0);
5078 tcg_gen_ext32u_tl(t1, t1);
5079 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5080 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5081 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5082 gen_set_label(l1);
5083 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5084 tcg_gen_br(l3);
5085 gen_set_label(l2);
5086 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5088 gen_set_label(l3);
5089 }
161f85e6
AJ
5090 break;
5091 case OPC_MODU_G_2E:
5092 case OPC_MODU_G_2F:
5093 {
42a268c2
RH
5094 TCGLabel *l1 = gen_new_label();
5095 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5096 tcg_gen_ext32u_tl(t0, t0);
5097 tcg_gen_ext32u_tl(t1, t1);
5098 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5099 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5100 tcg_gen_br(l2);
5101 gen_set_label(l1);
5102 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5103 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5104 gen_set_label(l2);
5105 }
161f85e6
AJ
5106 break;
5107#if defined(TARGET_MIPS64)
5108 case OPC_DMULT_G_2E:
5109 case OPC_DMULT_G_2F:
5110 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5111 break;
5112 case OPC_DMULTU_G_2E:
5113 case OPC_DMULTU_G_2F:
5114 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5115 break;
5116 case OPC_DDIV_G_2E:
5117 case OPC_DDIV_G_2F:
5118 {
42a268c2
RH
5119 TCGLabel *l1 = gen_new_label();
5120 TCGLabel *l2 = gen_new_label();
5121 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5122 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5123 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5124 tcg_gen_br(l3);
5125 gen_set_label(l1);
5126 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5127 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5128 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5129 tcg_gen_br(l3);
5130 gen_set_label(l2);
5131 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5132 gen_set_label(l3);
5133 }
161f85e6
AJ
5134 break;
5135 case OPC_DDIVU_G_2E:
5136 case OPC_DDIVU_G_2F:
5137 {
42a268c2
RH
5138 TCGLabel *l1 = gen_new_label();
5139 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5140 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5141 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5142 tcg_gen_br(l2);
5143 gen_set_label(l1);
5144 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5145 gen_set_label(l2);
5146 }
161f85e6
AJ
5147 break;
5148 case OPC_DMOD_G_2E:
5149 case OPC_DMOD_G_2F:
5150 {
42a268c2
RH
5151 TCGLabel *l1 = gen_new_label();
5152 TCGLabel *l2 = gen_new_label();
5153 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5154 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5155 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5156 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5157 gen_set_label(l1);
5158 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5159 tcg_gen_br(l3);
5160 gen_set_label(l2);
5161 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5162 gen_set_label(l3);
5163 }
161f85e6
AJ
5164 break;
5165 case OPC_DMODU_G_2E:
5166 case OPC_DMODU_G_2F:
5167 {
42a268c2
RH
5168 TCGLabel *l1 = gen_new_label();
5169 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5170 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5172 tcg_gen_br(l2);
5173 gen_set_label(l1);
5174 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5175 gen_set_label(l2);
5176 }
161f85e6
AJ
5177 break;
5178#endif
5179 }
5180
161f85e6
AJ
5181 tcg_temp_free(t0);
5182 tcg_temp_free(t1);
5183}
5184
bd277fa1
RH
5185/* Loongson multimedia instructions */
5186static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5187{
bd277fa1
RH
5188 uint32_t opc, shift_max;
5189 TCGv_i64 t0, t1;
84878f4c 5190 TCGCond cond;
bd277fa1 5191
8e2d5831 5192 opc = MASK_LMMI(ctx->opcode);
bd277fa1
RH
5193 switch (opc) {
5194 case OPC_ADD_CP2:
5195 case OPC_SUB_CP2:
5196 case OPC_DADD_CP2:
5197 case OPC_DSUB_CP2:
5198 t0 = tcg_temp_local_new_i64();
5199 t1 = tcg_temp_local_new_i64();
5200 break;
5201 default:
5202 t0 = tcg_temp_new_i64();
5203 t1 = tcg_temp_new_i64();
5204 break;
5205 }
5206
b5a587b6 5207 check_cp1_enabled(ctx);
bd277fa1
RH
5208 gen_load_fpr64(ctx, t0, rs);
5209 gen_load_fpr64(ctx, t1, rt);
5210
bd277fa1 5211 switch (opc) {
b1cf82f0
AM
5212 case OPC_PADDSH:
5213 gen_helper_paddsh(t0, t0, t1);
5214 break;
5215 case OPC_PADDUSH:
5216 gen_helper_paddush(t0, t0, t1);
5217 break;
5218 case OPC_PADDH:
5219 gen_helper_paddh(t0, t0, t1);
5220 break;
5221 case OPC_PADDW:
5222 gen_helper_paddw(t0, t0, t1);
5223 break;
5224 case OPC_PADDSB:
5225 gen_helper_paddsb(t0, t0, t1);
5226 break;
5227 case OPC_PADDUSB:
5228 gen_helper_paddusb(t0, t0, t1);
5229 break;
5230 case OPC_PADDB:
5231 gen_helper_paddb(t0, t0, t1);
5232 break;
5233
5234 case OPC_PSUBSH:
5235 gen_helper_psubsh(t0, t0, t1);
5236 break;
5237 case OPC_PSUBUSH:
5238 gen_helper_psubush(t0, t0, t1);
5239 break;
5240 case OPC_PSUBH:
5241 gen_helper_psubh(t0, t0, t1);
5242 break;
5243 case OPC_PSUBW:
5244 gen_helper_psubw(t0, t0, t1);
5245 break;
5246 case OPC_PSUBSB:
5247 gen_helper_psubsb(t0, t0, t1);
5248 break;
5249 case OPC_PSUBUSB:
5250 gen_helper_psubusb(t0, t0, t1);
5251 break;
5252 case OPC_PSUBB:
5253 gen_helper_psubb(t0, t0, t1);
5254 break;
5255
5256 case OPC_PSHUFH:
5257 gen_helper_pshufh(t0, t0, t1);
5258 break;
5259 case OPC_PACKSSWH:
5260 gen_helper_packsswh(t0, t0, t1);
5261 break;
5262 case OPC_PACKSSHB:
5263 gen_helper_packsshb(t0, t0, t1);
5264 break;
5265 case OPC_PACKUSHB:
5266 gen_helper_packushb(t0, t0, t1);
5267 break;
5268
5269 case OPC_PUNPCKLHW:
5270 gen_helper_punpcklhw(t0, t0, t1);
5271 break;
5272 case OPC_PUNPCKHHW:
5273 gen_helper_punpckhhw(t0, t0, t1);
5274 break;
5275 case OPC_PUNPCKLBH:
5276 gen_helper_punpcklbh(t0, t0, t1);
5277 break;
5278 case OPC_PUNPCKHBH:
5279 gen_helper_punpckhbh(t0, t0, t1);
5280 break;
5281 case OPC_PUNPCKLWD:
5282 gen_helper_punpcklwd(t0, t0, t1);
5283 break;
5284 case OPC_PUNPCKHWD:
5285 gen_helper_punpckhwd(t0, t0, t1);
5286 break;
5287
5288 case OPC_PAVGH:
5289 gen_helper_pavgh(t0, t0, t1);
5290 break;
5291 case OPC_PAVGB:
5292 gen_helper_pavgb(t0, t0, t1);
5293 break;
5294 case OPC_PMAXSH:
5295 gen_helper_pmaxsh(t0, t0, t1);
5296 break;
5297 case OPC_PMINSH:
5298 gen_helper_pminsh(t0, t0, t1);
5299 break;
5300 case OPC_PMAXUB:
5301 gen_helper_pmaxub(t0, t0, t1);
5302 break;
5303 case OPC_PMINUB:
5304 gen_helper_pminub(t0, t0, t1);
5305 break;
5306
5307 case OPC_PCMPEQW:
5308 gen_helper_pcmpeqw(t0, t0, t1);
5309 break;
5310 case OPC_PCMPGTW:
5311 gen_helper_pcmpgtw(t0, t0, t1);
5312 break;
5313 case OPC_PCMPEQH:
5314 gen_helper_pcmpeqh(t0, t0, t1);
5315 break;
5316 case OPC_PCMPGTH:
5317 gen_helper_pcmpgth(t0, t0, t1);
5318 break;
5319 case OPC_PCMPEQB:
5320 gen_helper_pcmpeqb(t0, t0, t1);
5321 break;
5322 case OPC_PCMPGTB:
5323 gen_helper_pcmpgtb(t0, t0, t1);
5324 break;
5325
5326 case OPC_PSLLW:
5327 gen_helper_psllw(t0, t0, t1);
5328 break;
5329 case OPC_PSLLH:
5330 gen_helper_psllh(t0, t0, t1);
5331 break;
5332 case OPC_PSRLW:
5333 gen_helper_psrlw(t0, t0, t1);
5334 break;
5335 case OPC_PSRLH:
5336 gen_helper_psrlh(t0, t0, t1);
5337 break;
5338 case OPC_PSRAW:
5339 gen_helper_psraw(t0, t0, t1);
5340 break;
5341 case OPC_PSRAH:
5342 gen_helper_psrah(t0, t0, t1);
5343 break;
5344
5345 case OPC_PMULLH:
5346 gen_helper_pmullh(t0, t0, t1);
5347 break;
5348 case OPC_PMULHH:
5349 gen_helper_pmulhh(t0, t0, t1);
5350 break;
5351 case OPC_PMULHUH:
5352 gen_helper_pmulhuh(t0, t0, t1);
5353 break;
5354 case OPC_PMADDHW:
5355 gen_helper_pmaddhw(t0, t0, t1);
5356 break;
5357
5358 case OPC_PASUBUB:
5359 gen_helper_pasubub(t0, t0, t1);
5360 break;
5361 case OPC_BIADD:
5362 gen_helper_biadd(t0, t0);
5363 break;
5364 case OPC_PMOVMSKB:
5365 gen_helper_pmovmskb(t0, t0);
5366 break;
5367
5368 case OPC_PADDD:
5369 tcg_gen_add_i64(t0, t0, t1);
5370 break;
5371 case OPC_PSUBD:
5372 tcg_gen_sub_i64(t0, t0, t1);
5373 break;
5374 case OPC_XOR_CP2:
5375 tcg_gen_xor_i64(t0, t0, t1);
5376 break;
5377 case OPC_NOR_CP2:
5378 tcg_gen_nor_i64(t0, t0, t1);
5379 break;
5380 case OPC_AND_CP2:
5381 tcg_gen_and_i64(t0, t0, t1);
5382 break;
5383 case OPC_OR_CP2:
5384 tcg_gen_or_i64(t0, t0, t1);
5385 break;
bd277fa1 5386
9099a36b
H
5387 case OPC_PANDN:
5388 tcg_gen_andc_i64(t0, t1, t0);
5389 break;
5390
bd277fa1
RH
5391 case OPC_PINSRH_0:
5392 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
5393 break;
5394 case OPC_PINSRH_1:
5395 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
5396 break;
5397 case OPC_PINSRH_2:
5398 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
5399 break;
5400 case OPC_PINSRH_3:
5401 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
5402 break;
5403
5404 case OPC_PEXTRH:
5405 tcg_gen_andi_i64(t1, t1, 3);
5406 tcg_gen_shli_i64(t1, t1, 4);
5407 tcg_gen_shr_i64(t0, t0, t1);
5408 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
5409 break;
5410
5411 case OPC_ADDU_CP2:
5412 tcg_gen_add_i64(t0, t0, t1);
5413 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5414 break;
5415 case OPC_SUBU_CP2:
5416 tcg_gen_sub_i64(t0, t0, t1);
5417 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5418 break;
5419
5420 case OPC_SLL_CP2:
bd277fa1
RH
5421 shift_max = 32;
5422 goto do_shift;
5423 case OPC_SRL_CP2:
bd277fa1
RH
5424 shift_max = 32;
5425 goto do_shift;
5426 case OPC_SRA_CP2:
bd277fa1
RH
5427 shift_max = 32;
5428 goto do_shift;
5429 case OPC_DSLL_CP2:
bd277fa1
RH
5430 shift_max = 64;
5431 goto do_shift;
5432 case OPC_DSRL_CP2:
bd277fa1
RH
5433 shift_max = 64;
5434 goto do_shift;
5435 case OPC_DSRA_CP2:
bd277fa1
RH
5436 shift_max = 64;
5437 goto do_shift;
5438 do_shift:
5439 /* Make sure shift count isn't TCG undefined behaviour. */
5440 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5441
5442 switch (opc) {
5443 case OPC_SLL_CP2:
5444 case OPC_DSLL_CP2:
5445 tcg_gen_shl_i64(t0, t0, t1);
5446 break;
5447 case OPC_SRA_CP2:
5448 case OPC_DSRA_CP2:
7480515f
AM
5449 /*
5450 * Since SRA is UndefinedResult without sign-extended inputs,
5451 * we can treat SRA and DSRA the same.
5452 */
bd277fa1
RH
5453 tcg_gen_sar_i64(t0, t0, t1);
5454 break;
5455 case OPC_SRL_CP2:
5456 /* We want to shift in zeros for SRL; zero-extend first. */
5457 tcg_gen_ext32u_i64(t0, t0);
5458 /* FALLTHRU */
5459 case OPC_DSRL_CP2:
5460 tcg_gen_shr_i64(t0, t0, t1);
5461 break;
5462 }
5463
5464 if (shift_max == 32) {
5465 tcg_gen_ext32s_i64(t0, t0);
5466 }
5467
5468 /* Shifts larger than MAX produce zero. */
5469 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5470 tcg_gen_neg_i64(t1, t1);
5471 tcg_gen_and_i64(t0, t0, t1);
5472 break;
5473
5474 case OPC_ADD_CP2:
5475 case OPC_DADD_CP2:
5476 {
5477 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5478 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5479
5480 tcg_gen_mov_i64(t2, t0);
5481 tcg_gen_add_i64(t0, t1, t2);
5482 if (opc == OPC_ADD_CP2) {
5483 tcg_gen_ext32s_i64(t0, t0);
5484 }
5485 tcg_gen_xor_i64(t1, t1, t2);
5486 tcg_gen_xor_i64(t2, t2, t0);
5487 tcg_gen_andc_i64(t1, t2, t1);
5488 tcg_temp_free_i64(t2);
5489 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5490 generate_exception(ctx, EXCP_OVERFLOW);
5491 gen_set_label(lab);
bd277fa1
RH
5492 break;
5493 }
5494
5495 case OPC_SUB_CP2:
5496 case OPC_DSUB_CP2:
5497 {
5498 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5499 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5500
5501 tcg_gen_mov_i64(t2, t0);
5502 tcg_gen_sub_i64(t0, t1, t2);
5503 if (opc == OPC_SUB_CP2) {
5504 tcg_gen_ext32s_i64(t0, t0);
5505 }
5506 tcg_gen_xor_i64(t1, t1, t2);
5507 tcg_gen_xor_i64(t2, t2, t0);
5508 tcg_gen_and_i64(t1, t1, t2);
5509 tcg_temp_free_i64(t2);
5510 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5511 generate_exception(ctx, EXCP_OVERFLOW);
5512 gen_set_label(lab);
bd277fa1
RH
5513 break;
5514 }
5515
5516 case OPC_PMULUW:
5517 tcg_gen_ext32u_i64(t0, t0);
5518 tcg_gen_ext32u_i64(t1, t1);
5519 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
5520 break;
5521
5522 case OPC_SEQU_CP2:
5523 case OPC_SEQ_CP2:
84878f4c
JY
5524 cond = TCG_COND_EQ;
5525 goto do_cc_cond;
5526 break;
bd277fa1 5527 case OPC_SLTU_CP2:
84878f4c
JY
5528 cond = TCG_COND_LTU;
5529 goto do_cc_cond;
5530 break;
bd277fa1 5531 case OPC_SLT_CP2:
84878f4c
JY
5532 cond = TCG_COND_LT;
5533 goto do_cc_cond;
5534 break;
bd277fa1 5535 case OPC_SLEU_CP2:
84878f4c
JY
5536 cond = TCG_COND_LEU;
5537 goto do_cc_cond;
5538 break;
bd277fa1 5539 case OPC_SLE_CP2:
84878f4c
JY
5540 cond = TCG_COND_LE;
5541 do_cc_cond:
5542 {
5543 int cc = (ctx->opcode >> 8) & 0x7;
5544 TCGv_i64 t64 = tcg_temp_new_i64();
5545 TCGv_i32 t32 = tcg_temp_new_i32();
5546
5547 tcg_gen_setcond_i64(cond, t64, t0, t1);
5548 tcg_gen_extrl_i64_i32(t32, t64);
5549 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
5550 get_fp_bit(cc), 1);
5551
5552 tcg_temp_free_i32(t32);
5553 tcg_temp_free_i64(t64);
5554 }
5555 goto no_rd;
5556 break;
bd277fa1 5557 default:
9d68ac14 5558 MIPS_INVAL("loongson_cp2");
3a4ef3b7 5559 gen_reserved_instruction(ctx);
bd277fa1
RH
5560 return;
5561 }
5562
bd277fa1
RH
5563 gen_store_fpr64(ctx, t0, rd);
5564
84878f4c 5565no_rd:
bd277fa1
RH
5566 tcg_temp_free_i64(t0);
5567 tcg_temp_free_i64(t1);
5568}
5569
e10a0ca1
JY
5570static void gen_loongson_lswc2(DisasContext *ctx, int rt,
5571 int rs, int rd)
5572{
fd723105
JY
5573 TCGv t0, t1, t2;
5574 TCGv_i32 fp0;
e10a0ca1 5575#if defined(TARGET_MIPS64)
e10a0ca1
JY
5576 int lsq_rt1 = ctx->opcode & 0x1f;
5577 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
5578#endif
fd723105 5579 int shf_offset = sextract32(ctx->opcode, 6, 8);
e10a0ca1
JY
5580
5581 t0 = tcg_temp_new();
5582
5583 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
5584#if defined(TARGET_MIPS64)
5585 case OPC_GSLQ:
5586 t1 = tcg_temp_new();
5587 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5588 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5589 ctx->default_tcg_memop_mask);
5590 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5591 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5592 ctx->default_tcg_memop_mask);
5593 gen_store_gpr(t1, rt);
5594 gen_store_gpr(t0, lsq_rt1);
5595 tcg_temp_free(t1);
5596 break;
5597 case OPC_GSLQC1:
5598 check_cp1_enabled(ctx);
5599 t1 = tcg_temp_new();
5600 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5601 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5602 ctx->default_tcg_memop_mask);
5603 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5604 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5605 ctx->default_tcg_memop_mask);
5606 gen_store_fpr64(ctx, t1, rt);
5607 gen_store_fpr64(ctx, t0, lsq_rt1);
5608 tcg_temp_free(t1);
5609 break;
5610 case OPC_GSSQ:
5611 t1 = tcg_temp_new();
5612 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5613 gen_load_gpr(t1, rt);
5614 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5615 ctx->default_tcg_memop_mask);
5616 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5617 gen_load_gpr(t1, lsq_rt1);
5618 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5619 ctx->default_tcg_memop_mask);
5620 tcg_temp_free(t1);
5621 break;
5622 case OPC_GSSQC1:
5623 check_cp1_enabled(ctx);
5624 t1 = tcg_temp_new();
5625 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
5626 gen_load_fpr64(ctx, t1, rt);
5627 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5628 ctx->default_tcg_memop_mask);
5629 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
5630 gen_load_fpr64(ctx, t1, lsq_rt1);
5631 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5632 ctx->default_tcg_memop_mask);
5633 tcg_temp_free(t1);
5634 break;
5635#endif
fd723105
JY
5636 case OPC_GSSHFL:
5637 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
5638 case OPC_GSLWLC1:
5639 check_cp1_enabled(ctx);
5640 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5641 t1 = tcg_temp_new();
5642 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
5643 tcg_gen_andi_tl(t1, t0, 3);
5644#ifndef TARGET_WORDS_BIGENDIAN
5645 tcg_gen_xori_tl(t1, t1, 3);
5646#endif
5647 tcg_gen_shli_tl(t1, t1, 3);
5648 tcg_gen_andi_tl(t0, t0, ~3);
5649 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
5650 tcg_gen_shl_tl(t0, t0, t1);
5651 t2 = tcg_const_tl(-1);
5652 tcg_gen_shl_tl(t2, t2, t1);
5653 fp0 = tcg_temp_new_i32();
5654 gen_load_fpr32(ctx, fp0, rt);
5655 tcg_gen_ext_i32_tl(t1, fp0);
5656 tcg_gen_andc_tl(t1, t1, t2);
5657 tcg_temp_free(t2);
5658 tcg_gen_or_tl(t0, t0, t1);
5659 tcg_temp_free(t1);
5660#if defined(TARGET_MIPS64)
5661 tcg_gen_extrl_i64_i32(fp0, t0);
5662#else
5663 tcg_gen_ext32s_tl(fp0, t0);
5664#endif
5665 gen_store_fpr32(ctx, fp0, rt);
5666 tcg_temp_free_i32(fp0);
5667 break;
5668 case OPC_GSLWRC1:
5669 check_cp1_enabled(ctx);
5670 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5671 t1 = tcg_temp_new();
5672 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
5673 tcg_gen_andi_tl(t1, t0, 3);
5674#ifdef TARGET_WORDS_BIGENDIAN
5675 tcg_gen_xori_tl(t1, t1, 3);
5676#endif
5677 tcg_gen_shli_tl(t1, t1, 3);
5678 tcg_gen_andi_tl(t0, t0, ~3);
5679 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
5680 tcg_gen_shr_tl(t0, t0, t1);
5681 tcg_gen_xori_tl(t1, t1, 31);
5682 t2 = tcg_const_tl(0xfffffffeull);
5683 tcg_gen_shl_tl(t2, t2, t1);
5684 fp0 = tcg_temp_new_i32();
5685 gen_load_fpr32(ctx, fp0, rt);
5686 tcg_gen_ext_i32_tl(t1, fp0);
5687 tcg_gen_and_tl(t1, t1, t2);
5688 tcg_temp_free(t2);
5689 tcg_gen_or_tl(t0, t0, t1);
5690 tcg_temp_free(t1);
5691#if defined(TARGET_MIPS64)
5692 tcg_gen_extrl_i64_i32(fp0, t0);
5693#else
5694 tcg_gen_ext32s_tl(fp0, t0);
5695#endif
5696 gen_store_fpr32(ctx, fp0, rt);
5697 tcg_temp_free_i32(fp0);
5698 break;
5699#if defined(TARGET_MIPS64)
5700 case OPC_GSLDLC1:
5701 check_cp1_enabled(ctx);
5702 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5703 t1 = tcg_temp_new();
5704 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
5705 tcg_gen_andi_tl(t1, t0, 7);
5706#ifndef TARGET_WORDS_BIGENDIAN
5707 tcg_gen_xori_tl(t1, t1, 7);
5708#endif
5709 tcg_gen_shli_tl(t1, t1, 3);
5710 tcg_gen_andi_tl(t0, t0, ~7);
5711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
5712 tcg_gen_shl_tl(t0, t0, t1);
5713 t2 = tcg_const_tl(-1);
5714 tcg_gen_shl_tl(t2, t2, t1);
5715 gen_load_fpr64(ctx, t1, rt);
5716 tcg_gen_andc_tl(t1, t1, t2);
5717 tcg_temp_free(t2);
5718 tcg_gen_or_tl(t0, t0, t1);
5719 tcg_temp_free(t1);
5720 gen_store_fpr64(ctx, t0, rt);
5721 break;
5722 case OPC_GSLDRC1:
5723 check_cp1_enabled(ctx);
5724 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5725 t1 = tcg_temp_new();
5726 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
5727 tcg_gen_andi_tl(t1, t0, 7);
5728#ifdef TARGET_WORDS_BIGENDIAN
5729 tcg_gen_xori_tl(t1, t1, 7);
5730#endif
5731 tcg_gen_shli_tl(t1, t1, 3);
5732 tcg_gen_andi_tl(t0, t0, ~7);
5733 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
5734 tcg_gen_shr_tl(t0, t0, t1);
5735 tcg_gen_xori_tl(t1, t1, 63);
5736 t2 = tcg_const_tl(0xfffffffffffffffeull);
5737 tcg_gen_shl_tl(t2, t2, t1);
5738 gen_load_fpr64(ctx, t1, rt);
5739 tcg_gen_and_tl(t1, t1, t2);
5740 tcg_temp_free(t2);
5741 tcg_gen_or_tl(t0, t0, t1);
5742 tcg_temp_free(t1);
5743 gen_store_fpr64(ctx, t0, rt);
5744 break;
5745#endif
5746 default:
5747 MIPS_INVAL("loongson_gsshfl");
3a4ef3b7 5748 gen_reserved_instruction(ctx);
fd723105
JY
5749 break;
5750 }
5751 break;
5752 case OPC_GSSHFS:
5753 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
5754 case OPC_GSSWLC1:
5755 check_cp1_enabled(ctx);
5756 t1 = tcg_temp_new();
5757 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5758 fp0 = tcg_temp_new_i32();
5759 gen_load_fpr32(ctx, fp0, rt);
5760 tcg_gen_ext_i32_tl(t1, fp0);
5761 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5762 tcg_temp_free_i32(fp0);
5763 tcg_temp_free(t1);
5764 break;
5765 case OPC_GSSWRC1:
5766 check_cp1_enabled(ctx);
5767 t1 = tcg_temp_new();
5768 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5769 fp0 = tcg_temp_new_i32();
5770 gen_load_fpr32(ctx, fp0, rt);
5771 tcg_gen_ext_i32_tl(t1, fp0);
5772 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5773 tcg_temp_free_i32(fp0);
5774 tcg_temp_free(t1);
5775 break;
5776#if defined(TARGET_MIPS64)
5777 case OPC_GSSDLC1:
5778 check_cp1_enabled(ctx);
5779 t1 = tcg_temp_new();
5780 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5781 gen_load_fpr64(ctx, t1, rt);
5782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5783 tcg_temp_free(t1);
5784 break;
5785 case OPC_GSSDRC1:
5786 check_cp1_enabled(ctx);
5787 t1 = tcg_temp_new();
5788 gen_base_offset_addr(ctx, t0, rs, shf_offset);
5789 gen_load_fpr64(ctx, t1, rt);
5790 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5791 tcg_temp_free(t1);
5792 break;
5793#endif
5794 default:
5795 MIPS_INVAL("loongson_gsshfs");
3a4ef3b7 5796 gen_reserved_instruction(ctx);
fd723105
JY
5797 break;
5798 }
5799 break;
e10a0ca1
JY
5800 default:
5801 MIPS_INVAL("loongson_gslsq");
3a4ef3b7 5802 gen_reserved_instruction(ctx);
e10a0ca1
JY
5803 break;
5804 }
5805 tcg_temp_free(t0);
5806}
5807
90e22a57
JY
5808/* Loongson EXT LDC2/SDC2 */
5809static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
5810 int rs, int rd)
5811{
5812 int offset = sextract32(ctx->opcode, 3, 8);
5813 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
5814 TCGv t0, t1;
5815 TCGv_i32 fp0;
5816
5817 /* Pre-conditions */
5818 switch (opc) {
5819 case OPC_GSLBX:
5820 case OPC_GSLHX:
5821 case OPC_GSLWX:
5822 case OPC_GSLDX:
5823 /* prefetch, implement as NOP */
5824 if (rt == 0) {
5825 return;
5826 }
5827 break;
5828 case OPC_GSSBX:
5829 case OPC_GSSHX:
5830 case OPC_GSSWX:
5831 case OPC_GSSDX:
5832 break;
5833 case OPC_GSLWXC1:
5834#if defined(TARGET_MIPS64)
5835 case OPC_GSLDXC1:
5836#endif
5837 check_cp1_enabled(ctx);
5838 /* prefetch, implement as NOP */
5839 if (rt == 0) {
5840 return;
5841 }
5842 break;
5843 case OPC_GSSWXC1:
5844#if defined(TARGET_MIPS64)
5845 case OPC_GSSDXC1:
5846#endif
5847 check_cp1_enabled(ctx);
5848 break;
5849 default:
5850 MIPS_INVAL("loongson_lsdc2");
3a4ef3b7 5851 gen_reserved_instruction(ctx);
90e22a57
JY
5852 return;
5853 break;
5854 }
5855
5856 t0 = tcg_temp_new();
5857
5858 gen_base_offset_addr(ctx, t0, rs, offset);
5859 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
5860
5861 switch (opc) {
5862 case OPC_GSLBX:
5863 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
5864 gen_store_gpr(t0, rt);
5865 break;
5866 case OPC_GSLHX:
5867 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
5868 ctx->default_tcg_memop_mask);
5869 gen_store_gpr(t0, rt);
5870 break;
5871 case OPC_GSLWX:
5872 gen_base_offset_addr(ctx, t0, rs, offset);
5873 if (rd) {
5874 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
5875 }
5876 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
5877 ctx->default_tcg_memop_mask);
5878 gen_store_gpr(t0, rt);
5879 break;
5880#if defined(TARGET_MIPS64)
5881 case OPC_GSLDX:
5882 gen_base_offset_addr(ctx, t0, rs, offset);
5883 if (rd) {
5884 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
5885 }
5886 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5887 ctx->default_tcg_memop_mask);
5888 gen_store_gpr(t0, rt);
5889 break;
5890#endif
5891 case OPC_GSLWXC1:
5892 check_cp1_enabled(ctx);
5893 gen_base_offset_addr(ctx, t0, rs, offset);
5894 if (rd) {
5895 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
5896 }
5897 fp0 = tcg_temp_new_i32();
5898 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
5899 ctx->default_tcg_memop_mask);
5900 gen_store_fpr32(ctx, fp0, rt);
5901 tcg_temp_free_i32(fp0);
5902 break;
5903#if defined(TARGET_MIPS64)
5904 case OPC_GSLDXC1:
5905 check_cp1_enabled(ctx);
5906 gen_base_offset_addr(ctx, t0, rs, offset);
5907 if (rd) {
5908 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
5909 }
5910 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
5911 ctx->default_tcg_memop_mask);
5912 gen_store_fpr64(ctx, t0, rt);
5913 break;
5914#endif
5915 case OPC_GSSBX:
5916 t1 = tcg_temp_new();
5917 gen_load_gpr(t1, rt);
5918 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
5919 tcg_temp_free(t1);
5920 break;
5921 case OPC_GSSHX:
5922 t1 = tcg_temp_new();
5923 gen_load_gpr(t1, rt);
5924 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
5925 ctx->default_tcg_memop_mask);
5926 tcg_temp_free(t1);
5927 break;
5928 case OPC_GSSWX:
5929 t1 = tcg_temp_new();
5930 gen_load_gpr(t1, rt);
5931 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
5932 ctx->default_tcg_memop_mask);
5933 tcg_temp_free(t1);
5934 break;
5935#if defined(TARGET_MIPS64)
5936 case OPC_GSSDX:
5937 t1 = tcg_temp_new();
5938 gen_load_gpr(t1, rt);
5939 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
5940 ctx->default_tcg_memop_mask);
5941 tcg_temp_free(t1);
5942 break;
5943#endif
5944 case OPC_GSSWXC1:
5945 fp0 = tcg_temp_new_i32();
5946 gen_load_fpr32(ctx, fp0, rt);
5947 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
5948 ctx->default_tcg_memop_mask);
5949 tcg_temp_free_i32(fp0);
5950 break;
5951#if defined(TARGET_MIPS64)
5952 case OPC_GSSDXC1:
5953 t1 = tcg_temp_new();
5954 gen_load_fpr64(ctx, t1, rt);
5955 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
5956 ctx->default_tcg_memop_mask);
5957 tcg_temp_free(t1);
5958 break;
5959#endif
5960 default:
5961 break;
5962 }
5963
5964 tcg_temp_free(t0);
5965}
5966
6af0bf9c 5967/* Traps */
71375b59
AM
5968static void gen_trap(DisasContext *ctx, uint32_t opc,
5969 int rs, int rt, int16_t imm)
6af0bf9c
FB
5970{
5971 int cond;
cdc0faa6 5972 TCGv t0 = tcg_temp_new();
1ba74fb8 5973 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
5974
5975 cond = 0;
5976 /* Load needed operands */
5977 switch (opc) {
5978 case OPC_TEQ:
5979 case OPC_TGE:
5980 case OPC_TGEU:
5981 case OPC_TLT:
5982 case OPC_TLTU:
5983 case OPC_TNE:
5984 /* Compare two registers */
5985 if (rs != rt) {
be24bb4f
TS
5986 gen_load_gpr(t0, rs);
5987 gen_load_gpr(t1, rt);
6af0bf9c
FB
5988 cond = 1;
5989 }
179e32bb 5990 break;
6af0bf9c
FB
5991 case OPC_TEQI:
5992 case OPC_TGEI:
5993 case OPC_TGEIU:
5994 case OPC_TLTI:
5995 case OPC_TLTIU:
5996 case OPC_TNEI:
5997 /* Compare register to immediate */
5998 if (rs != 0 || imm != 0) {
be24bb4f
TS
5999 gen_load_gpr(t0, rs);
6000 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
6001 cond = 1;
6002 }
6003 break;
6004 }
6005 if (cond == 0) {
6006 switch (opc) {
6007 case OPC_TEQ: /* rs == rs */
6008 case OPC_TEQI: /* r0 == 0 */
6009 case OPC_TGE: /* rs >= rs */
6010 case OPC_TGEI: /* r0 >= 0 */
6011 case OPC_TGEU: /* rs >= rs unsigned */
6012 case OPC_TGEIU: /* r0 >= 0 unsigned */
6013 /* Always trap */
9c708c7f 6014 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
6015 break;
6016 case OPC_TLT: /* rs < rs */
6017 case OPC_TLTI: /* r0 < 0 */
6018 case OPC_TLTU: /* rs < rs unsigned */
6019 case OPC_TLTIU: /* r0 < 0 unsigned */
6020 case OPC_TNE: /* rs != rs */
6021 case OPC_TNEI: /* r0 != 0 */
ead9360e 6022 /* Never trap: treat as NOP. */
cdc0faa6 6023 break;
6af0bf9c
FB
6024 }
6025 } else {
42a268c2 6026 TCGLabel *l1 = gen_new_label();
cdc0faa6 6027
6af0bf9c
FB
6028 switch (opc) {
6029 case OPC_TEQ:
6030 case OPC_TEQI:
cdc0faa6 6031 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
6032 break;
6033 case OPC_TGE:
6034 case OPC_TGEI:
cdc0faa6 6035 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
6036 break;
6037 case OPC_TGEU:
6038 case OPC_TGEIU:
cdc0faa6 6039 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
6040 break;
6041 case OPC_TLT:
6042 case OPC_TLTI:
cdc0faa6 6043 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
6044 break;
6045 case OPC_TLTU:
6046 case OPC_TLTIU:
cdc0faa6 6047 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
6048 break;
6049 case OPC_TNE:
6050 case OPC_TNEI:
cdc0faa6 6051 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 6052 break;
6af0bf9c 6053 }
cdc0faa6 6054 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
6055 gen_set_label(l1);
6056 }
be24bb4f
TS
6057 tcg_temp_free(t0);
6058 tcg_temp_free(t1);
6af0bf9c
FB
6059}
6060
90aa39a1
SF
6061static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
6062{
eeb3bba8 6063 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
6064 return false;
6065 }
6066
6067#ifndef CONFIG_USER_ONLY
eeb3bba8 6068 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
6069#else
6070 return true;
6071#endif
6072}
6073
356265ae 6074static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 6075{
90aa39a1 6076 if (use_goto_tb(ctx, dest)) {
57fec1fe 6077 tcg_gen_goto_tb(n);
9b9e4393 6078 gen_save_pc(dest);
07ea28b4 6079 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 6080 } else {
9b9e4393 6081 gen_save_pc(dest);
eeb3bba8 6082 if (ctx->base.singlestep_enabled) {
7b270ef2 6083 save_cpu_state(ctx, 0);
9c708c7f 6084 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 6085 }
7f11636d 6086 tcg_gen_lookup_and_goto_ptr();
6e256c93 6087 }
c53be334
FB
6088}
6089
6af0bf9c 6090/* Branches (before delay slot) */
71375b59
AM
6091static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
6092 int insn_bytes,
6093 int rs, int rt, int32_t offset,
6094 int delayslot_size)
6af0bf9c 6095{
d077b6f7 6096 target_ulong btgt = -1;
3ad4bb2d 6097 int blink = 0;
2fdbad25 6098 int bcond_compute = 0;
1ba74fb8
AJ
6099 TCGv t0 = tcg_temp_new();
6100 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
6101
6102 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 6103#ifdef MIPS_DEBUG_DISAS
339cd2a8 6104 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 6105 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 6106#endif
3a4ef3b7 6107 gen_reserved_instruction(ctx);
6c5c1e20 6108 goto out;
3ad4bb2d 6109 }
6af0bf9c 6110
6af0bf9c
FB
6111 /* Load needed operands */
6112 switch (opc) {
6113 case OPC_BEQ:
6114 case OPC_BEQL:
6115 case OPC_BNE:
6116 case OPC_BNEL:
6117 /* Compare two registers */
6118 if (rs != rt) {
6c5c1e20
TS
6119 gen_load_gpr(t0, rs);
6120 gen_load_gpr(t1, rt);
2fdbad25 6121 bcond_compute = 1;
6af0bf9c 6122 }
eeb3bba8 6123 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
6124 break;
6125 case OPC_BGEZ:
6126 case OPC_BGEZAL:
6127 case OPC_BGEZALL:
6128 case OPC_BGEZL:
6129 case OPC_BGTZ:
6130 case OPC_BGTZL:
6131 case OPC_BLEZ:
6132 case OPC_BLEZL:
6133 case OPC_BLTZ:
6134 case OPC_BLTZAL:
6135 case OPC_BLTZALL:
6136 case OPC_BLTZL:
6137 /* Compare to zero */
6138 if (rs != 0) {
6c5c1e20 6139 gen_load_gpr(t0, rs);
2fdbad25 6140 bcond_compute = 1;
6af0bf9c 6141 }
eeb3bba8 6142 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 6143 break;
e45a93e2
JL
6144 case OPC_BPOSGE32:
6145#if defined(TARGET_MIPS64)
6146 case OPC_BPOSGE64:
6147 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
6148#else
6149 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6150#endif
6151 bcond_compute = 1;
eeb3bba8 6152 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 6153 break;
6af0bf9c
FB
6154 case OPC_J:
6155 case OPC_JAL:
364d4831 6156 case OPC_JALX:
6af0bf9c 6157 /* Jump to immediate */
eeb3bba8
EC
6158 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
6159 (uint32_t)offset;
6af0bf9c
FB
6160 break;
6161 case OPC_JR:
6162 case OPC_JALR:
6163 /* Jump to register */
7a387fff 6164 if (offset != 0 && offset != 16) {
7480515f
AM
6165 /*
6166 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6167 * others are reserved.
6168 */
923617a3 6169 MIPS_INVAL("jump hint");
3a4ef3b7 6170 gen_reserved_instruction(ctx);
6c5c1e20 6171 goto out;
6af0bf9c 6172 }
d077b6f7 6173 gen_load_gpr(btarget, rs);
6af0bf9c
FB
6174 break;
6175 default:
6176 MIPS_INVAL("branch/jump");
3a4ef3b7 6177 gen_reserved_instruction(ctx);
6c5c1e20 6178 goto out;
6af0bf9c 6179 }
2fdbad25 6180 if (bcond_compute == 0) {
6af0bf9c
FB
6181 /* No condition to be computed */
6182 switch (opc) {
6183 case OPC_BEQ: /* rx == rx */
6184 case OPC_BEQL: /* rx == rx likely */
6185 case OPC_BGEZ: /* 0 >= 0 */
6186 case OPC_BGEZL: /* 0 >= 0 likely */
6187 case OPC_BLEZ: /* 0 <= 0 */
6188 case OPC_BLEZL: /* 0 <= 0 likely */
6189 /* Always take */
4ad40f36 6190 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
6191 break;
6192 case OPC_BGEZAL: /* 0 >= 0 */
6193 case OPC_BGEZALL: /* 0 >= 0 likely */
6194 /* Always take and link */
6195 blink = 31;
4ad40f36 6196 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
6197 break;
6198 case OPC_BNE: /* rx != rx */
6199 case OPC_BGTZ: /* 0 > 0 */
6200 case OPC_BLTZ: /* 0 < 0 */
ead9360e 6201 /* Treat as NOP. */
6c5c1e20 6202 goto out;
eeef26cd 6203 case OPC_BLTZAL: /* 0 < 0 */
7480515f
AM
6204 /*
6205 * Handle as an unconditional branch to get correct delay
6206 * slot checking.
6207 */
3c824109 6208 blink = 31;
eeb3bba8 6209 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 6210 ctx->hflags |= MIPS_HFLAG_B;
3c824109 6211 break;
eeef26cd 6212 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 6213 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 6214 /* Skip the instruction in the delay slot */
eeb3bba8 6215 ctx->base.pc_next += 4;
6c5c1e20 6216 goto out;
6af0bf9c
FB
6217 case OPC_BNEL: /* rx != rx likely */
6218 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
6219 case OPC_BLTZL: /* 0 < 0 likely */
6220 /* Skip the instruction in the delay slot */
eeb3bba8 6221 ctx->base.pc_next += 4;
6c5c1e20 6222 goto out;
6af0bf9c 6223 case OPC_J:
4ad40f36 6224 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 6225 break;
364d4831
NF
6226 case OPC_JALX:
6227 ctx->hflags |= MIPS_HFLAG_BX;
6228 /* Fallthrough */
6af0bf9c
FB
6229 case OPC_JAL:
6230 blink = 31;
4ad40f36 6231 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
6232 break;
6233 case OPC_JR:
4ad40f36 6234 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
6235 break;
6236 case OPC_JALR:
6237 blink = rt;
4ad40f36 6238 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
6239 break;
6240 default:
6241 MIPS_INVAL("branch/jump");
3a4ef3b7 6242 gen_reserved_instruction(ctx);
6c5c1e20 6243 goto out;
6af0bf9c
FB
6244 }
6245 } else {
6246 switch (opc) {
6247 case OPC_BEQ:
e68dd28f 6248 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
6249 goto not_likely;
6250 case OPC_BEQL:
e68dd28f 6251 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
6252 goto likely;
6253 case OPC_BNE:
e68dd28f 6254 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
6255 goto not_likely;
6256 case OPC_BNEL:
e68dd28f 6257 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
6258 goto likely;
6259 case OPC_BGEZ:
e68dd28f 6260 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6261 goto not_likely;
6262 case OPC_BGEZL:
e68dd28f 6263 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6264 goto likely;
6265 case OPC_BGEZAL:
e68dd28f 6266 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6267 blink = 31;
6268 goto not_likely;
6269 case OPC_BGEZALL:
e68dd28f 6270 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 6271 blink = 31;
6af0bf9c
FB
6272 goto likely;
6273 case OPC_BGTZ:
e68dd28f 6274 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
6275 goto not_likely;
6276 case OPC_BGTZL:
e68dd28f 6277 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
6278 goto likely;
6279 case OPC_BLEZ:
e68dd28f 6280 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
6281 goto not_likely;
6282 case OPC_BLEZL:
e68dd28f 6283 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
6284 goto likely;
6285 case OPC_BLTZ:
e68dd28f 6286 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
6287 goto not_likely;
6288 case OPC_BLTZL:
e68dd28f 6289 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6290 goto likely;
e45a93e2
JL
6291 case OPC_BPOSGE32:
6292 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
6293 goto not_likely;
6294#if defined(TARGET_MIPS64)
6295 case OPC_BPOSGE64:
6296 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
6297 goto not_likely;
6298#endif
6af0bf9c 6299 case OPC_BLTZAL:
e68dd28f 6300 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6301 blink = 31;
6af0bf9c 6302 not_likely:
4ad40f36 6303 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
6304 break;
6305 case OPC_BLTZALL:
e68dd28f 6306 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6307 blink = 31;
6af0bf9c 6308 likely:
4ad40f36 6309 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 6310 break;
c53f4a62
TS
6311 default:
6312 MIPS_INVAL("conditional branch/jump");
3a4ef3b7 6313 gen_reserved_instruction(ctx);
6c5c1e20 6314 goto out;
6af0bf9c 6315 }
6af0bf9c 6316 }
9b9e4393 6317
d077b6f7 6318 ctx->btarget = btgt;
b231c103
YK
6319
6320 switch (delayslot_size) {
6321 case 2:
6322 ctx->hflags |= MIPS_HFLAG_BDS16;
6323 break;
6324 case 4:
6325 ctx->hflags |= MIPS_HFLAG_BDS32;
6326 break;
6327 }
6328
6af0bf9c 6329 if (blink > 0) {
b231c103 6330 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
6331 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6332
eeb3bba8
EC
6333 tcg_gen_movi_tl(cpu_gpr[blink],
6334 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 6335 }
6c5c1e20
TS
6336
6337 out:
1f8929d2 6338 if (insn_bytes == 2) {
364d4831 6339 ctx->hflags |= MIPS_HFLAG_B16;
1f8929d2 6340 }
6c5c1e20
TS
6341 tcg_temp_free(t0);
6342 tcg_temp_free(t1);
6af0bf9c
FB
6343}
6344
764371d2
SM
6345
6346/* nanoMIPS Branches */
6347static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6348 int insn_bytes,
6349 int rs, int rt, int32_t offset)
6350{
6351 target_ulong btgt = -1;
6352 int bcond_compute = 0;
6353 TCGv t0 = tcg_temp_new();
6354 TCGv t1 = tcg_temp_new();
6355
6356 /* Load needed operands */
6357 switch (opc) {
6358 case OPC_BEQ:
6359 case OPC_BNE:
6360 /* Compare two registers */
6361 if (rs != rt) {
6362 gen_load_gpr(t0, rs);
6363 gen_load_gpr(t1, rt);
6364 bcond_compute = 1;
6365 }
6366 btgt = ctx->base.pc_next + insn_bytes + offset;
6367 break;
6368 case OPC_BGEZAL:
6369 /* Compare to zero */
6370 if (rs != 0) {
6371 gen_load_gpr(t0, rs);
6372 bcond_compute = 1;
6373 }
6374 btgt = ctx->base.pc_next + insn_bytes + offset;
6375 break;
6376 case OPC_BPOSGE32:
6377 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6378 bcond_compute = 1;
6379 btgt = ctx->base.pc_next + insn_bytes + offset;
6380 break;
6381 case OPC_JR:
6382 case OPC_JALR:
6383 /* Jump to register */
6384 if (offset != 0 && offset != 16) {
7480515f
AM
6385 /*
6386 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6387 * others are reserved.
6388 */
764371d2 6389 MIPS_INVAL("jump hint");
3a4ef3b7 6390 gen_reserved_instruction(ctx);
764371d2
SM
6391 goto out;
6392 }
6393 gen_load_gpr(btarget, rs);
6394 break;
6395 default:
6396 MIPS_INVAL("branch/jump");
3a4ef3b7 6397 gen_reserved_instruction(ctx);
764371d2
SM
6398 goto out;
6399 }
6400 if (bcond_compute == 0) {
6401 /* No condition to be computed */
6402 switch (opc) {
6403 case OPC_BEQ: /* rx == rx */
6404 /* Always take */
6405 ctx->hflags |= MIPS_HFLAG_B;
6406 break;
6407 case OPC_BGEZAL: /* 0 >= 0 */
6408 /* Always take and link */
6409 tcg_gen_movi_tl(cpu_gpr[31],
6410 ctx->base.pc_next + insn_bytes);
6411 ctx->hflags |= MIPS_HFLAG_B;
6412 break;
6413 case OPC_BNE: /* rx != rx */
6414 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6415 /* Skip the instruction in the delay slot */
6416 ctx->base.pc_next += 4;
6417 goto out;
6418 case OPC_JR:
6419 ctx->hflags |= MIPS_HFLAG_BR;
6420 break;
6421 case OPC_JALR:
6422 if (rt > 0) {
6423 tcg_gen_movi_tl(cpu_gpr[rt],
6424 ctx->base.pc_next + insn_bytes);
6425 }
6426 ctx->hflags |= MIPS_HFLAG_BR;
6427 break;
6428 default:
6429 MIPS_INVAL("branch/jump");
3a4ef3b7 6430 gen_reserved_instruction(ctx);
764371d2
SM
6431 goto out;
6432 }
6433 } else {
6434 switch (opc) {
6435 case OPC_BEQ:
6436 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6437 goto not_likely;
6438 case OPC_BNE:
6439 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6440 goto not_likely;
6441 case OPC_BGEZAL:
6442 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6443 tcg_gen_movi_tl(cpu_gpr[31],
6444 ctx->base.pc_next + insn_bytes);
6445 goto not_likely;
6446 case OPC_BPOSGE32:
6447 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6448 not_likely:
6449 ctx->hflags |= MIPS_HFLAG_BC;
6450 break;
6451 default:
6452 MIPS_INVAL("conditional branch/jump");
3a4ef3b7 6453 gen_reserved_instruction(ctx);
764371d2
SM
6454 goto out;
6455 }
6456 }
6457
6458 ctx->btarget = btgt;
6459
6460 out:
6461 if (insn_bytes == 2) {
6462 ctx->hflags |= MIPS_HFLAG_B16;
6463 }
6464 tcg_temp_free(t0);
6465 tcg_temp_free(t1);
6466}
6467
6468
7a387fff 6469/* special3 bitfield operations */
235785e8
AM
6470static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6471 int rs, int lsb, int msb)
7a387fff 6472{
a7812ae4
PB
6473 TCGv t0 = tcg_temp_new();
6474 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
6475
6476 gen_load_gpr(t1, rs);
7a387fff
TS
6477 switch (opc) {
6478 case OPC_EXT:
b7f26e52 6479 if (lsb + msb > 31) {
7a387fff 6480 goto fail;
b7f26e52 6481 }
505ad7c2 6482 if (msb != 31) {
6eebb7a4 6483 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 6484 } else {
7480515f
AM
6485 /*
6486 * The two checks together imply that lsb == 0,
6487 * so this is a simple sign-extension.
6488 */
6eebb7a4 6489 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 6490 }
7a387fff 6491 break;
c6d6dd7c 6492#if defined(TARGET_MIPS64)
7a387fff 6493 case OPC_DEXTU:
b7f26e52
RH
6494 lsb += 32;
6495 goto do_dext;
6496 case OPC_DEXTM:
6497 msb += 32;
6498 goto do_dext;
7a387fff 6499 case OPC_DEXT:
b7f26e52
RH
6500 do_dext:
6501 if (lsb + msb > 63) {
6502 goto fail;
6503 }
6eebb7a4 6504 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 6505 break;
c6d6dd7c 6506#endif
7a387fff 6507 case OPC_INS:
b7f26e52 6508 if (lsb > msb) {
7a387fff 6509 goto fail;
b7f26e52 6510 }
6c5c1e20 6511 gen_load_gpr(t0, rt);
e0d002f1 6512 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 6513 tcg_gen_ext32s_tl(t0, t0);
7a387fff 6514 break;
c6d6dd7c 6515#if defined(TARGET_MIPS64)
7a387fff 6516 case OPC_DINSU:
b7f26e52
RH
6517 lsb += 32;
6518 /* FALLTHRU */
6519 case OPC_DINSM:
6520 msb += 32;
6521 /* FALLTHRU */
7a387fff 6522 case OPC_DINS:
b7f26e52
RH
6523 if (lsb > msb) {
6524 goto fail;
6525 }
6c5c1e20 6526 gen_load_gpr(t0, rt);
e0d002f1 6527 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 6528 break;
c6d6dd7c 6529#endif
7a387fff
TS
6530 default:
6531fail:
6532 MIPS_INVAL("bitops");
3a4ef3b7 6533 gen_reserved_instruction(ctx);
6c5c1e20
TS
6534 tcg_temp_free(t0);
6535 tcg_temp_free(t1);
7a387fff
TS
6536 return;
6537 }
6c5c1e20
TS
6538 gen_store_gpr(t0, rt);
6539 tcg_temp_free(t0);
6540 tcg_temp_free(t1);
7a387fff
TS
6541}
6542
235785e8 6543static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
49bcf33c 6544{
3a55fa47 6545 TCGv t0;
49bcf33c 6546
3a55fa47
AJ
6547 if (rd == 0) {
6548 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
6549 return;
6550 }
6551
6552 t0 = tcg_temp_new();
6553 gen_load_gpr(t0, rt);
49bcf33c
AJ
6554 switch (op2) {
6555 case OPC_WSBH:
3a55fa47
AJ
6556 {
6557 TCGv t1 = tcg_temp_new();
06a57e5c 6558 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
6559
6560 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6561 tcg_gen_and_tl(t1, t1, t2);
6562 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6563 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6564 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 6565 tcg_temp_free(t2);
3a55fa47
AJ
6566 tcg_temp_free(t1);
6567 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6568 }
49bcf33c
AJ
6569 break;
6570 case OPC_SEB:
3a55fa47 6571 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6572 break;
6573 case OPC_SEH:
3a55fa47 6574 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6575 break;
6576#if defined(TARGET_MIPS64)
6577 case OPC_DSBH:
3a55fa47
AJ
6578 {
6579 TCGv t1 = tcg_temp_new();
06a57e5c 6580 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
6581
6582 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6583 tcg_gen_and_tl(t1, t1, t2);
6584 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6585 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6586 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6587 tcg_temp_free(t2);
3a55fa47
AJ
6588 tcg_temp_free(t1);
6589 }
49bcf33c
AJ
6590 break;
6591 case OPC_DSHD:
3a55fa47
AJ
6592 {
6593 TCGv t1 = tcg_temp_new();
06a57e5c 6594 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
6595
6596 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
6597 tcg_gen_and_tl(t1, t1, t2);
6598 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6599 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
6600 tcg_gen_or_tl(t0, t0, t1);
6601 tcg_gen_shri_tl(t1, t0, 32);
6602 tcg_gen_shli_tl(t0, t0, 32);
6603 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6604 tcg_temp_free(t2);
3a55fa47
AJ
6605 tcg_temp_free(t1);
6606 }
49bcf33c
AJ
6607 break;
6608#endif
6609 default:
6610 MIPS_INVAL("bsfhl");
3a4ef3b7 6611 gen_reserved_instruction(ctx);
49bcf33c 6612 tcg_temp_free(t0);
49bcf33c
AJ
6613 return;
6614 }
49bcf33c 6615 tcg_temp_free(t0);
49bcf33c
AJ
6616}
6617
821f2008
JH
6618static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6619 int rt, int bits)
284b731a 6620{
1f1b4c00
YK
6621 TCGv t0;
6622 if (rd == 0) {
6623 /* Treat as NOP. */
6624 return;
6625 }
6626 t0 = tcg_temp_new();
821f2008
JH
6627 if (bits == 0 || bits == wordsz) {
6628 if (bits == 0) {
6629 gen_load_gpr(t0, rt);
6630 } else {
6631 gen_load_gpr(t0, rs);
6632 }
6633 switch (wordsz) {
6634 case 32:
51243852
MD
6635 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6636 break;
6637#if defined(TARGET_MIPS64)
821f2008 6638 case 64:
51243852
MD
6639 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6640 break;
6641#endif
6642 }
1f1b4c00
YK
6643 } else {
6644 TCGv t1 = tcg_temp_new();
821f2008 6645 gen_load_gpr(t0, rt);
1f1b4c00 6646 gen_load_gpr(t1, rs);
821f2008
JH
6647 switch (wordsz) {
6648 case 32:
1f1b4c00
YK
6649 {
6650 TCGv_i64 t2 = tcg_temp_new_i64();
6651 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 6652 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
6653 gen_move_low32(cpu_gpr[rd], t2);
6654 tcg_temp_free_i64(t2);
6655 }
6656 break;
284b731a 6657#if defined(TARGET_MIPS64)
821f2008
JH
6658 case 64:
6659 tcg_gen_shli_tl(t0, t0, bits);
6660 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
6661 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6662 break;
284b731a 6663#endif
1f1b4c00
YK
6664 }
6665 tcg_temp_free(t1);
6666 }
6667
6668 tcg_temp_free(t0);
6669}
6670
821f2008
JH
6671static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6672 int bp)
6673{
6674 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6675}
6676
6677static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6678 int shift)
6679{
6680 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6681}
6682
1f1b4c00
YK
6683static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6684{
6685 TCGv t0;
6686 if (rd == 0) {
6687 /* Treat as NOP. */
6688 return;
6689 }
6690 t0 = tcg_temp_new();
6691 gen_load_gpr(t0, rt);
6692 switch (opc) {
6693 case OPC_BITSWAP:
6694 gen_helper_bitswap(cpu_gpr[rd], t0);
6695 break;
6696#if defined(TARGET_MIPS64)
6697 case OPC_DBITSWAP:
6698 gen_helper_dbitswap(cpu_gpr[rd], t0);
6699 break;
6700#endif
6701 }
6702 tcg_temp_free(t0);
284b731a
LA
6703}
6704
1f1b4c00
YK
6705#ifndef CONFIG_USER_ONLY
6706/* CP0 (MMU and control) */
5204ea79
LA
6707static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6708{
6709 TCGv_i64 t0 = tcg_temp_new_i64();
6710 TCGv_i64 t1 = tcg_temp_new_i64();
6711
6712 tcg_gen_ext_tl_i64(t0, arg);
6713 tcg_gen_ld_i64(t1, cpu_env, off);
6714#if defined(TARGET_MIPS64)
6715 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6716#else
6717 tcg_gen_concat32_i64(t1, t1, t0);
6718#endif
6719 tcg_gen_st_i64(t1, cpu_env, off);
6720 tcg_temp_free_i64(t1);
6721 tcg_temp_free_i64(t0);
6722}
6723
6724static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6725{
6726 TCGv_i64 t0 = tcg_temp_new_i64();
6727 TCGv_i64 t1 = tcg_temp_new_i64();
6728
6729 tcg_gen_ext_tl_i64(t0, arg);
6730 tcg_gen_ld_i64(t1, cpu_env, off);
6731 tcg_gen_concat32_i64(t1, t1, t0);
6732 tcg_gen_st_i64(t1, cpu_env, off);
6733 tcg_temp_free_i64(t1);
6734 tcg_temp_free_i64(t0);
6735}
6736
6737static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6738{
6739 TCGv_i64 t0 = tcg_temp_new_i64();
6740
6741 tcg_gen_ld_i64(t0, cpu_env, off);
6742#if defined(TARGET_MIPS64)
6743 tcg_gen_shri_i64(t0, t0, 30);
6744#else
6745 tcg_gen_shri_i64(t0, t0, 32);
6746#endif
6747 gen_move_low32(arg, t0);
6748 tcg_temp_free_i64(t0);
6749}
6750
6751static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6752{
6753 TCGv_i64 t0 = tcg_temp_new_i64();
6754
6755 tcg_gen_ld_i64(t0, cpu_env, off);
6756 tcg_gen_shri_i64(t0, t0, 32 + shift);
6757 gen_move_low32(arg, t0);
6758 tcg_temp_free_i64(t0);
6759}
6760
235785e8 6761static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4f57689a 6762{
d9bea114 6763 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 6764
d9bea114
AJ
6765 tcg_gen_ld_i32(t0, cpu_env, off);
6766 tcg_gen_ext_i32_tl(arg, t0);
6767 tcg_temp_free_i32(t0);
4f57689a
TS
6768}
6769
235785e8 6770static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4f57689a 6771{
d9bea114
AJ
6772 tcg_gen_ld_tl(arg, cpu_env, off);
6773 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
6774}
6775
235785e8 6776static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
f1aa6320 6777{
d9bea114 6778 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 6779
d9bea114
AJ
6780 tcg_gen_trunc_tl_i32(t0, arg);
6781 tcg_gen_st_i32(t0, cpu_env, off);
6782 tcg_temp_free_i32(t0);
f1aa6320
TS
6783}
6784
c98d3d79
YK
6785#define CP0_CHECK(c) \
6786 do { \
6787 if (!(c)) { \
6788 goto cp0_unimplemented; \
6789 } \
6790 } while (0)
6791
5204ea79
LA
6792static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6793{
294fc2ea 6794 const char *register_name = "invalid";
5204ea79 6795
5204ea79 6796 switch (reg) {
04992c8c 6797 case CP0_REGISTER_02:
5204ea79
LA
6798 switch (sel) {
6799 case 0:
59488dda 6800 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 6801 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 6802 register_name = "EntryLo0";
5204ea79
LA
6803 break;
6804 default:
c98d3d79 6805 goto cp0_unimplemented;
5204ea79
LA
6806 }
6807 break;
04992c8c 6808 case CP0_REGISTER_03:
5204ea79 6809 switch (sel) {
acd37316 6810 case CP0_REG03__ENTRYLO1:
59488dda 6811 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 6812 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 6813 register_name = "EntryLo1";
5204ea79
LA
6814 break;
6815 default:
c98d3d79 6816 goto cp0_unimplemented;
5204ea79
LA
6817 }
6818 break;
04992c8c 6819 case CP0_REGISTER_09:
5fb2dcd1 6820 switch (sel) {
e5a98a72 6821 case CP0_REG09__SAAR:
5fb2dcd1
YK
6822 CP0_CHECK(ctx->saar);
6823 gen_helper_mfhc0_saar(arg, cpu_env);
294fc2ea 6824 register_name = "SAAR";
5fb2dcd1
YK
6825 break;
6826 default:
6827 goto cp0_unimplemented;
6828 }
6829 break;
04992c8c 6830 case CP0_REGISTER_17:
5204ea79 6831 switch (sel) {
706ce142 6832 case CP0_REG17__LLADDR:
c7c7e1e9 6833 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5204ea79 6834 ctx->CP0_LLAddr_shift);
294fc2ea 6835 register_name = "LLAddr";
5204ea79 6836 break;
706ce142 6837 case CP0_REG17__MAAR:
f6d4dd81
YK
6838 CP0_CHECK(ctx->mrp);
6839 gen_helper_mfhc0_maar(arg, cpu_env);
294fc2ea 6840 register_name = "MAAR";
f6d4dd81 6841 break;
5204ea79 6842 default:
c98d3d79 6843 goto cp0_unimplemented;
5204ea79
LA
6844 }
6845 break;
feafe82c
YK
6846 case CP0_REGISTER_19:
6847 switch (sel) {
6848 case CP0_REG19__WATCHHI0:
6849 case CP0_REG19__WATCHHI1:
6850 case CP0_REG19__WATCHHI2:
6851 case CP0_REG19__WATCHHI3:
6852 case CP0_REG19__WATCHHI4:
6853 case CP0_REG19__WATCHHI5:
6854 case CP0_REG19__WATCHHI6:
6855 case CP0_REG19__WATCHHI7:
6856 /* upper 32 bits are only available when Config5MI != 0 */
6857 CP0_CHECK(ctx->mi);
6858 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
6859 register_name = "WatchHi";
6860 break;
6861 default:
6862 goto cp0_unimplemented;
6863 }
6864 break;
04992c8c 6865 case CP0_REGISTER_28:
5204ea79
LA
6866 switch (sel) {
6867 case 0:
6868 case 2:
6869 case 4:
6870 case 6:
6871 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
294fc2ea 6872 register_name = "TagLo";
5204ea79
LA
6873 break;
6874 default:
c98d3d79 6875 goto cp0_unimplemented;
5204ea79
LA
6876 }
6877 break;
6878 default:
c98d3d79 6879 goto cp0_unimplemented;
5204ea79 6880 }
294fc2ea 6881 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5204ea79
LA
6882 return;
6883
c98d3d79 6884cp0_unimplemented:
294fc2ea
AM
6885 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6886 register_name, reg, sel);
5204ea79
LA
6887 tcg_gen_movi_tl(arg, 0);
6888}
6889
6890static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6891{
294fc2ea 6892 const char *register_name = "invalid";
5204ea79
LA
6893 uint64_t mask = ctx->PAMask >> 36;
6894
5204ea79 6895 switch (reg) {
04992c8c 6896 case CP0_REGISTER_02:
5204ea79
LA
6897 switch (sel) {
6898 case 0:
59488dda 6899 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6900 tcg_gen_andi_tl(arg, arg, mask);
6901 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 6902 register_name = "EntryLo0";
5204ea79
LA
6903 break;
6904 default:
c98d3d79 6905 goto cp0_unimplemented;
5204ea79
LA
6906 }
6907 break;
04992c8c 6908 case CP0_REGISTER_03:
5204ea79 6909 switch (sel) {
acd37316 6910 case CP0_REG03__ENTRYLO1:
59488dda 6911 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6912 tcg_gen_andi_tl(arg, arg, mask);
6913 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 6914 register_name = "EntryLo1";
5204ea79
LA
6915 break;
6916 default:
c98d3d79 6917 goto cp0_unimplemented;
5204ea79
LA
6918 }
6919 break;
04992c8c 6920 case CP0_REGISTER_09:
5fb2dcd1 6921 switch (sel) {
e5a98a72 6922 case CP0_REG09__SAAR:
5fb2dcd1
YK
6923 CP0_CHECK(ctx->saar);
6924 gen_helper_mthc0_saar(cpu_env, arg);
294fc2ea 6925 register_name = "SAAR";
5fb2dcd1
YK
6926 break;
6927 default:
6928 goto cp0_unimplemented;
6929 }
ab8c3410 6930 break;
04992c8c 6931 case CP0_REGISTER_17:
5204ea79 6932 switch (sel) {
706ce142 6933 case CP0_REG17__LLADDR:
7480515f
AM
6934 /*
6935 * LLAddr is read-only (the only exception is bit 0 if LLB is
6936 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6937 * relevant for modern MIPS cores supporting MTHC0, therefore
6938 * treating MTHC0 to LLAddr as NOP.
6939 */
294fc2ea 6940 register_name = "LLAddr";
5204ea79 6941 break;
706ce142 6942 case CP0_REG17__MAAR:
f6d4dd81
YK
6943 CP0_CHECK(ctx->mrp);
6944 gen_helper_mthc0_maar(cpu_env, arg);
294fc2ea 6945 register_name = "MAAR";
f6d4dd81 6946 break;
5204ea79 6947 default:
c98d3d79 6948 goto cp0_unimplemented;
5204ea79
LA
6949 }
6950 break;
feafe82c
YK
6951 case CP0_REGISTER_19:
6952 switch (sel) {
6953 case CP0_REG19__WATCHHI0:
6954 case CP0_REG19__WATCHHI1:
6955 case CP0_REG19__WATCHHI2:
6956 case CP0_REG19__WATCHHI3:
6957 case CP0_REG19__WATCHHI4:
6958 case CP0_REG19__WATCHHI5:
6959 case CP0_REG19__WATCHHI6:
6960 case CP0_REG19__WATCHHI7:
6961 /* upper 32 bits are only available when Config5MI != 0 */
6962 CP0_CHECK(ctx->mi);
6963 gen_helper_0e1i(mthc0_watchhi, arg, sel);
6964 register_name = "WatchHi";
6965 break;
6966 default:
6967 goto cp0_unimplemented;
6968 }
6969 break;
04992c8c 6970 case CP0_REGISTER_28:
5204ea79
LA
6971 switch (sel) {
6972 case 0:
6973 case 2:
6974 case 4:
6975 case 6:
6976 tcg_gen_andi_tl(arg, arg, mask);
6977 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 6978 register_name = "TagLo";
5204ea79
LA
6979 break;
6980 default:
c98d3d79 6981 goto cp0_unimplemented;
5204ea79
LA
6982 }
6983 break;
6984 default:
c98d3d79 6985 goto cp0_unimplemented;
5204ea79 6986 }
294fc2ea 6987 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5204ea79 6988
c98d3d79 6989cp0_unimplemented:
294fc2ea
AM
6990 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6991 register_name, reg, sel);
5204ea79
LA
6992}
6993
e98c0d17
LA
6994static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6995{
2e211e0a 6996 if (ctx->insn_flags & ISA_MIPS_R6) {
e98c0d17
LA
6997 tcg_gen_movi_tl(arg, 0);
6998 } else {
6999 tcg_gen_movi_tl(arg, ~0);
7000 }
7001}
7002
d75c135e 7003static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 7004{
294fc2ea 7005 const char *register_name = "invalid";
873eb012 7006
1f8929d2 7007 if (sel != 0) {
bbd5e4a2 7008 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7009 }
e189e748 7010
873eb012 7011 switch (reg) {
04992c8c 7012 case CP0_REGISTER_00:
7a387fff 7013 switch (sel) {
1b142da5 7014 case CP0_REG00__INDEX:
7db13fae 7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 7016 register_name = "Index";
7a387fff 7017 break;
1b142da5 7018 case CP0_REG00__MVPCONTROL:
f31b035a 7019 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7020 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 7021 register_name = "MVPControl";
ead9360e 7022 break;
1b142da5 7023 case CP0_REG00__MVPCONF0:
f31b035a 7024 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7025 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 7026 register_name = "MVPConf0";
ead9360e 7027 break;
1b142da5 7028 case CP0_REG00__MVPCONF1:
f31b035a 7029 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7030 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 7031 register_name = "MVPConf1";
ead9360e 7032 break;
1b142da5 7033 case CP0_REG00__VPCONTROL:
01bc435b
YK
7034 CP0_CHECK(ctx->vp);
7035 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 7036 register_name = "VPControl";
01bc435b 7037 break;
7a387fff 7038 default:
f31b035a 7039 goto cp0_unimplemented;
7a387fff 7040 }
873eb012 7041 break;
04992c8c 7042 case CP0_REGISTER_01:
7a387fff 7043 switch (sel) {
30deb460 7044 case CP0_REG01__RANDOM:
2e211e0a 7045 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 7046 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 7047 register_name = "Random";
2423f660 7048 break;
30deb460 7049 case CP0_REG01__VPECONTROL:
f31b035a 7050 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7051 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 7052 register_name = "VPEControl";
ead9360e 7053 break;
30deb460 7054 case CP0_REG01__VPECONF0:
f31b035a 7055 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 7057 register_name = "VPEConf0";
ead9360e 7058 break;
30deb460 7059 case CP0_REG01__VPECONF1:
f31b035a 7060 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 7062 register_name = "VPEConf1";
ead9360e 7063 break;
30deb460 7064 case CP0_REG01__YQMASK:
f31b035a 7065 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7066 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 7067 register_name = "YQMask";
ead9360e 7068 break;
30deb460 7069 case CP0_REG01__VPESCHEDULE:
f31b035a 7070 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7071 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7072 register_name = "VPESchedule";
ead9360e 7073 break;
30deb460 7074 case CP0_REG01__VPESCHEFBACK:
f31b035a 7075 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7076 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7077 register_name = "VPEScheFBack";
ead9360e 7078 break;
30deb460 7079 case CP0_REG01__VPEOPT:
f31b035a 7080 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 7082 register_name = "VPEOpt";
ead9360e 7083 break;
7a387fff 7084 default:
f31b035a 7085 goto cp0_unimplemented;
7a387fff 7086 }
873eb012 7087 break;
04992c8c 7088 case CP0_REGISTER_02:
7a387fff 7089 switch (sel) {
6d27d5bd 7090 case CP0_REG02__ENTRYLO0:
284b731a
LA
7091 {
7092 TCGv_i64 tmp = tcg_temp_new_i64();
7093 tcg_gen_ld_i64(tmp, cpu_env,
7094 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 7095#if defined(TARGET_MIPS64)
284b731a
LA
7096 if (ctx->rxi) {
7097 /* Move RI/XI fields to bits 31:30 */
7098 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7099 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7100 }
7207c7f9 7101#endif
284b731a
LA
7102 gen_move_low32(arg, tmp);
7103 tcg_temp_free_i64(tmp);
7104 }
294fc2ea 7105 register_name = "EntryLo0";
2423f660 7106 break;
6d27d5bd 7107 case CP0_REG02__TCSTATUS:
f31b035a 7108 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7109 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 7110 register_name = "TCStatus";
ead9360e 7111 break;
6d27d5bd 7112 case CP0_REG02__TCBIND:
f31b035a 7113 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7114 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 7115 register_name = "TCBind";
ead9360e 7116 break;
6d27d5bd 7117 case CP0_REG02__TCRESTART:
f31b035a 7118 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7119 gen_helper_mfc0_tcrestart(arg, cpu_env);
294fc2ea 7120 register_name = "TCRestart";
ead9360e 7121 break;
6d27d5bd 7122 case CP0_REG02__TCHALT:
f31b035a 7123 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7124 gen_helper_mfc0_tchalt(arg, cpu_env);
294fc2ea 7125 register_name = "TCHalt";
ead9360e 7126 break;
6d27d5bd 7127 case CP0_REG02__TCCONTEXT:
f31b035a 7128 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7129 gen_helper_mfc0_tccontext(arg, cpu_env);
294fc2ea 7130 register_name = "TCContext";
ead9360e 7131 break;
6d27d5bd 7132 case CP0_REG02__TCSCHEDULE:
f31b035a 7133 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7134 gen_helper_mfc0_tcschedule(arg, cpu_env);
294fc2ea 7135 register_name = "TCSchedule";
ead9360e 7136 break;
6d27d5bd 7137 case CP0_REG02__TCSCHEFBACK:
f31b035a 7138 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7139 gen_helper_mfc0_tcschefback(arg, cpu_env);
294fc2ea 7140 register_name = "TCScheFBack";
ead9360e 7141 break;
7a387fff 7142 default:
f31b035a 7143 goto cp0_unimplemented;
7a387fff 7144 }
873eb012 7145 break;
04992c8c 7146 case CP0_REGISTER_03:
7a387fff 7147 switch (sel) {
acd37316 7148 case CP0_REG03__ENTRYLO1:
284b731a
LA
7149 {
7150 TCGv_i64 tmp = tcg_temp_new_i64();
7151 tcg_gen_ld_i64(tmp, cpu_env,
7152 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 7153#if defined(TARGET_MIPS64)
284b731a
LA
7154 if (ctx->rxi) {
7155 /* Move RI/XI fields to bits 31:30 */
7156 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7157 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7158 }
7207c7f9 7159#endif
284b731a
LA
7160 gen_move_low32(arg, tmp);
7161 tcg_temp_free_i64(tmp);
7162 }
294fc2ea 7163 register_name = "EntryLo1";
2423f660 7164 break;
acd37316 7165 case CP0_REG03__GLOBALNUM:
01bc435b
YK
7166 CP0_CHECK(ctx->vp);
7167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 7168 register_name = "GlobalNumber";
01bc435b 7169 break;
7a387fff 7170 default:
f31b035a 7171 goto cp0_unimplemented;
1579a72e 7172 }
873eb012 7173 break;
04992c8c 7174 case CP0_REGISTER_04:
7a387fff 7175 switch (sel) {
020fe379 7176 case CP0_REG04__CONTEXT:
7db13fae 7177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 7178 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7179 register_name = "Context";
2423f660 7180 break;
020fe379
AM
7181 case CP0_REG04__CONTEXTCONFIG:
7182 /* SmartMIPS ASE */
7183 /* gen_helper_mfc0_contextconfig(arg); */
294fc2ea 7184 register_name = "ContextConfig";
f31b035a 7185 goto cp0_unimplemented;
020fe379 7186 case CP0_REG04__USERLOCAL:
f31b035a 7187 CP0_CHECK(ctx->ulri);
e40df9a8
JH
7188 tcg_gen_ld_tl(arg, cpu_env,
7189 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7190 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7191 register_name = "UserLocal";
d279279e 7192 break;
99029be1
YK
7193 case CP0_REG04__MMID:
7194 CP0_CHECK(ctx->mi);
7195 gen_helper_mtc0_memorymapid(cpu_env, arg);
7196 register_name = "MMID";
7197 break;
7a387fff 7198 default:
f31b035a 7199 goto cp0_unimplemented;
1579a72e 7200 }
873eb012 7201 break;
04992c8c 7202 case CP0_REGISTER_05:
7a387fff 7203 switch (sel) {
a1e76353 7204 case CP0_REG05__PAGEMASK:
7db13fae 7205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 7206 register_name = "PageMask";
2423f660 7207 break;
a1e76353 7208 case CP0_REG05__PAGEGRAIN:
7a47bae5 7209 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 7211 register_name = "PageGrain";
2423f660 7212 break;
a1e76353 7213 case CP0_REG05__SEGCTL0:
cec56a73
JH
7214 CP0_CHECK(ctx->sc);
7215 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7216 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7217 register_name = "SegCtl0";
cec56a73 7218 break;
a1e76353 7219 case CP0_REG05__SEGCTL1:
cec56a73
JH
7220 CP0_CHECK(ctx->sc);
7221 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7222 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7223 register_name = "SegCtl1";
cec56a73 7224 break;
a1e76353 7225 case CP0_REG05__SEGCTL2:
cec56a73
JH
7226 CP0_CHECK(ctx->sc);
7227 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7228 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7229 register_name = "SegCtl2";
cec56a73 7230 break;
a1e76353 7231 case CP0_REG05__PWBASE:
5e31fdd5
YK
7232 check_pw(ctx);
7233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 7234 register_name = "PWBase";
5e31fdd5 7235 break;
a1e76353 7236 case CP0_REG05__PWFIELD:
fa75ad14
YK
7237 check_pw(ctx);
7238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 7239 register_name = "PWField";
fa75ad14 7240 break;
a1e76353 7241 case CP0_REG05__PWSIZE:
20b28ebc
YK
7242 check_pw(ctx);
7243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 7244 register_name = "PWSize";
20b28ebc 7245 break;
7a387fff 7246 default:
f31b035a 7247 goto cp0_unimplemented;
1579a72e 7248 }
873eb012 7249 break;
04992c8c 7250 case CP0_REGISTER_06:
7a387fff 7251 switch (sel) {
9023594b 7252 case CP0_REG06__WIRED:
7db13fae 7253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 7254 register_name = "Wired";
2423f660 7255 break;
9023594b 7256 case CP0_REG06__SRSCONF0:
7a47bae5 7257 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 7259 register_name = "SRSConf0";
ead9360e 7260 break;
9023594b 7261 case CP0_REG06__SRSCONF1:
7a47bae5 7262 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 7264 register_name = "SRSConf1";
ead9360e 7265 break;
9023594b 7266 case CP0_REG06__SRSCONF2:
7a47bae5 7267 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 7269 register_name = "SRSConf2";
ead9360e 7270 break;
9023594b 7271 case CP0_REG06__SRSCONF3:
7a47bae5 7272 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 7274 register_name = "SRSConf3";
ead9360e 7275 break;
9023594b 7276 case CP0_REG06__SRSCONF4:
7a47bae5 7277 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 7279 register_name = "SRSConf4";
ead9360e 7280 break;
9023594b 7281 case CP0_REG06__PWCTL:
103be64c
YK
7282 check_pw(ctx);
7283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 7284 register_name = "PWCtl";
103be64c 7285 break;
7a387fff 7286 default:
f31b035a 7287 goto cp0_unimplemented;
1579a72e 7288 }
873eb012 7289 break;
04992c8c 7290 case CP0_REGISTER_07:
7a387fff 7291 switch (sel) {
143a9875 7292 case CP0_REG07__HWRENA:
7a47bae5 7293 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 7295 register_name = "HWREna";
2423f660 7296 break;
7a387fff 7297 default:
f31b035a 7298 goto cp0_unimplemented;
1579a72e 7299 }
8c0fdd85 7300 break;
04992c8c 7301 case CP0_REGISTER_08:
7a387fff 7302 switch (sel) {
67d167d2 7303 case CP0_REG08__BADVADDR:
7db13fae 7304 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 7305 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7306 register_name = "BadVAddr";
2423f660 7307 break;
67d167d2 7308 case CP0_REG08__BADINSTR:
f31b035a
LA
7309 CP0_CHECK(ctx->bi);
7310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 7311 register_name = "BadInstr";
aea14095 7312 break;
67d167d2 7313 case CP0_REG08__BADINSTRP:
f31b035a
LA
7314 CP0_CHECK(ctx->bp);
7315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 7316 register_name = "BadInstrP";
aea14095 7317 break;
67d167d2 7318 case CP0_REG08__BADINSTRX:
25beba9b
SM
7319 CP0_CHECK(ctx->bi);
7320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7321 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 7322 register_name = "BadInstrX";
25beba9b 7323 break;
05aa7e93 7324 default:
f31b035a 7325 goto cp0_unimplemented;
aea14095 7326 }
873eb012 7327 break;
04992c8c 7328 case CP0_REGISTER_09:
7a387fff 7329 switch (sel) {
e5a98a72 7330 case CP0_REG09__COUNT:
2e70f6ef 7331 /* Mark as an IO operation because we read the time. */
eeb3bba8 7332 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7333 gen_io_start();
7d37435b 7334 }
895c2d04 7335 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
7336 /*
7337 * Break the TB to be able to take timer interrupts immediately
7338 * after reading count. DISAS_STOP isn't sufficient, we need to
7339 * ensure we break completely out of translated code.
7340 */
eeb3bba8
EC
7341 gen_save_pc(ctx->base.pc_next + 4);
7342 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 7343 register_name = "Count";
2423f660 7344 break;
e5a98a72 7345 case CP0_REG09__SAARI:
5fb2dcd1
YK
7346 CP0_CHECK(ctx->saar);
7347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 7348 register_name = "SAARI";
5fb2dcd1 7349 break;
e5a98a72 7350 case CP0_REG09__SAAR:
5fb2dcd1
YK
7351 CP0_CHECK(ctx->saar);
7352 gen_helper_mfc0_saar(arg, cpu_env);
294fc2ea 7353 register_name = "SAAR";
5fb2dcd1 7354 break;
7a387fff 7355 default:
f31b035a 7356 goto cp0_unimplemented;
2423f660 7357 }
873eb012 7358 break;
04992c8c 7359 case CP0_REGISTER_10:
7a387fff 7360 switch (sel) {
860ffef0 7361 case CP0_REG10__ENTRYHI:
7db13fae 7362 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 7363 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7364 register_name = "EntryHi";
2423f660 7365 break;
7a387fff 7366 default:
f31b035a 7367 goto cp0_unimplemented;
1579a72e 7368 }
873eb012 7369 break;
04992c8c 7370 case CP0_REGISTER_11:
7a387fff 7371 switch (sel) {
f5f3834f 7372 case CP0_REG11__COMPARE:
7db13fae 7373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 7374 register_name = "Compare";
2423f660
TS
7375 break;
7376 /* 6,7 are implementation dependent */
7a387fff 7377 default:
f31b035a 7378 goto cp0_unimplemented;
2423f660 7379 }
873eb012 7380 break;
04992c8c 7381 case CP0_REGISTER_12:
7a387fff 7382 switch (sel) {
2b084867 7383 case CP0_REG12__STATUS:
7db13fae 7384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 7385 register_name = "Status";
2423f660 7386 break;
2b084867 7387 case CP0_REG12__INTCTL:
7a47bae5 7388 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 7390 register_name = "IntCtl";
2423f660 7391 break;
2b084867 7392 case CP0_REG12__SRSCTL:
7a47bae5 7393 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 7395 register_name = "SRSCtl";
2423f660 7396 break;
2b084867 7397 case CP0_REG12__SRSMAP:
7a47bae5 7398 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 7400 register_name = "SRSMap";
fd88b6ab 7401 break;
7a387fff 7402 default:
f31b035a 7403 goto cp0_unimplemented;
7a387fff 7404 }
873eb012 7405 break;
04992c8c 7406 case CP0_REGISTER_13:
7a387fff 7407 switch (sel) {
e3c7559d 7408 case CP0_REG13__CAUSE:
7db13fae 7409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 7410 register_name = "Cause";
2423f660 7411 break;
7a387fff 7412 default:
f31b035a 7413 goto cp0_unimplemented;
7a387fff 7414 }
873eb012 7415 break;
04992c8c 7416 case CP0_REGISTER_14:
7a387fff 7417 switch (sel) {
35e4b54d 7418 case CP0_REG14__EPC:
7db13fae 7419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 7420 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7421 register_name = "EPC";
2423f660 7422 break;
7a387fff 7423 default:
f31b035a 7424 goto cp0_unimplemented;
1579a72e 7425 }
873eb012 7426 break;
04992c8c 7427 case CP0_REGISTER_15:
7a387fff 7428 switch (sel) {
4466cd49 7429 case CP0_REG15__PRID:
7db13fae 7430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 7431 register_name = "PRid";
2423f660 7432 break;
4466cd49 7433 case CP0_REG15__EBASE:
7a47bae5 7434 check_insn(ctx, ISA_MIPS_R2);
74dbf824
JH
7435 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7436 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7437 register_name = "EBase";
2423f660 7438 break;
4466cd49 7439 case CP0_REG15__CMGCRBASE:
7a47bae5 7440 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
7441 CP0_CHECK(ctx->cmgcr);
7442 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7443 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7444 register_name = "CMGCRBase";
c870e3f5 7445 break;
7a387fff 7446 default:
f31b035a 7447 goto cp0_unimplemented;
7a387fff 7448 }
873eb012 7449 break;
04992c8c 7450 case CP0_REGISTER_16:
873eb012 7451 switch (sel) {
433efb4c 7452 case CP0_REG16__CONFIG:
7db13fae 7453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 7454 register_name = "Config";
873eb012 7455 break;
433efb4c 7456 case CP0_REG16__CONFIG1:
7db13fae 7457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 7458 register_name = "Config1";
873eb012 7459 break;
433efb4c 7460 case CP0_REG16__CONFIG2:
7db13fae 7461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 7462 register_name = "Config2";
7a387fff 7463 break;
433efb4c 7464 case CP0_REG16__CONFIG3:
7db13fae 7465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 7466 register_name = "Config3";
7a387fff 7467 break;
433efb4c 7468 case CP0_REG16__CONFIG4:
b4160af1 7469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 7470 register_name = "Config4";
b4160af1 7471 break;
433efb4c 7472 case CP0_REG16__CONFIG5:
b4dd99a3 7473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 7474 register_name = "Config5";
b4dd99a3 7475 break;
e397ee33 7476 /* 6,7 are implementation dependent */
433efb4c 7477 case CP0_REG16__CONFIG6:
7db13fae 7478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 7479 register_name = "Config6";
e397ee33 7480 break;
433efb4c 7481 case CP0_REG16__CONFIG7:
7db13fae 7482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 7483 register_name = "Config7";
e397ee33 7484 break;
873eb012 7485 default:
f31b035a 7486 goto cp0_unimplemented;
873eb012
TS
7487 }
7488 break;
04992c8c 7489 case CP0_REGISTER_17:
7a387fff 7490 switch (sel) {
706ce142 7491 case CP0_REG17__LLADDR:
895c2d04 7492 gen_helper_mfc0_lladdr(arg, cpu_env);
294fc2ea 7493 register_name = "LLAddr";
2423f660 7494 break;
706ce142 7495 case CP0_REG17__MAAR:
f6d4dd81
YK
7496 CP0_CHECK(ctx->mrp);
7497 gen_helper_mfc0_maar(arg, cpu_env);
294fc2ea 7498 register_name = "MAAR";
f6d4dd81 7499 break;
706ce142 7500 case CP0_REG17__MAARI:
f6d4dd81
YK
7501 CP0_CHECK(ctx->mrp);
7502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 7503 register_name = "MAARI";
f6d4dd81 7504 break;
7a387fff 7505 default:
f31b035a 7506 goto cp0_unimplemented;
7a387fff 7507 }
873eb012 7508 break;
04992c8c 7509 case CP0_REGISTER_18:
7a387fff 7510 switch (sel) {
e8dcfe82
AM
7511 case CP0_REG18__WATCHLO0:
7512 case CP0_REG18__WATCHLO1:
7513 case CP0_REG18__WATCHLO2:
7514 case CP0_REG18__WATCHLO3:
7515 case CP0_REG18__WATCHLO4:
7516 case CP0_REG18__WATCHLO5:
7517 case CP0_REG18__WATCHLO6:
7518 case CP0_REG18__WATCHLO7:
fa192d49 7519 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7520 gen_helper_1e0i(mfc0_watchlo, arg, sel);
294fc2ea 7521 register_name = "WatchLo";
2423f660 7522 break;
7a387fff 7523 default:
f31b035a 7524 goto cp0_unimplemented;
7a387fff 7525 }
873eb012 7526 break;
04992c8c 7527 case CP0_REGISTER_19:
7a387fff 7528 switch (sel) {
be274dc1
AM
7529 case CP0_REG19__WATCHHI0:
7530 case CP0_REG19__WATCHHI1:
7531 case CP0_REG19__WATCHHI2:
7532 case CP0_REG19__WATCHHI3:
7533 case CP0_REG19__WATCHHI4:
7534 case CP0_REG19__WATCHHI5:
7535 case CP0_REG19__WATCHHI6:
7536 case CP0_REG19__WATCHHI7:
fa192d49 7537 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7538 gen_helper_1e0i(mfc0_watchhi, arg, sel);
294fc2ea 7539 register_name = "WatchHi";
2423f660 7540 break;
7a387fff 7541 default:
f31b035a 7542 goto cp0_unimplemented;
7a387fff 7543 }
873eb012 7544 break;
04992c8c 7545 case CP0_REGISTER_20:
7a387fff 7546 switch (sel) {
14f92b0b 7547 case CP0_REG20__XCONTEXT:
d26bc211 7548#if defined(TARGET_MIPS64)
d75c135e 7549 check_insn(ctx, ISA_MIPS3);
7db13fae 7550 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 7551 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7552 register_name = "XContext";
2423f660 7553 break;
703eaf37 7554#endif
7a387fff 7555 default:
f31b035a 7556 goto cp0_unimplemented;
7a387fff 7557 }
8c0fdd85 7558 break;
04992c8c 7559 case CP0_REGISTER_21:
7a387fff 7560 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 7561 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
7562 switch (sel) {
7563 case 0:
7db13fae 7564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 7565 register_name = "Framemask";
2423f660 7566 break;
7a387fff 7567 default:
f31b035a 7568 goto cp0_unimplemented;
7a387fff 7569 }
8c0fdd85 7570 break;
04992c8c 7571 case CP0_REGISTER_22:
d9bea114 7572 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7573 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 7574 break;
04992c8c 7575 case CP0_REGISTER_23:
7a387fff 7576 switch (sel) {
4cbf4b6d 7577 case CP0_REG23__DEBUG:
895c2d04 7578 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 7579 register_name = "Debug";
2423f660 7580 break;
4cbf4b6d
AM
7581 case CP0_REG23__TRACECONTROL:
7582 /* PDtrace support */
7583 /* gen_helper_mfc0_tracecontrol(arg); */
294fc2ea 7584 register_name = "TraceControl";
3570d7f6 7585 goto cp0_unimplemented;
4cbf4b6d
AM
7586 case CP0_REG23__TRACECONTROL2:
7587 /* PDtrace support */
7588 /* gen_helper_mfc0_tracecontrol2(arg); */
294fc2ea 7589 register_name = "TraceControl2";
3570d7f6 7590 goto cp0_unimplemented;
4cbf4b6d
AM
7591 case CP0_REG23__USERTRACEDATA1:
7592 /* PDtrace support */
7593 /* gen_helper_mfc0_usertracedata1(arg);*/
7594 register_name = "UserTraceData1";
3570d7f6 7595 goto cp0_unimplemented;
4cbf4b6d
AM
7596 case CP0_REG23__TRACEIBPC:
7597 /* PDtrace support */
7598 /* gen_helper_mfc0_traceibpc(arg); */
7599 register_name = "TraceIBPC";
7600 goto cp0_unimplemented;
7601 case CP0_REG23__TRACEDBPC:
7602 /* PDtrace support */
7603 /* gen_helper_mfc0_tracedbpc(arg); */
7604 register_name = "TraceDBPC";
3570d7f6 7605 goto cp0_unimplemented;
7a387fff 7606 default:
f31b035a 7607 goto cp0_unimplemented;
7a387fff 7608 }
873eb012 7609 break;
04992c8c 7610 case CP0_REGISTER_24:
7a387fff 7611 switch (sel) {
8d7b4b6e 7612 case CP0_REG24__DEPC:
f0b3f3ae 7613 /* EJTAG support */
7db13fae 7614 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 7615 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7616 register_name = "DEPC";
2423f660 7617 break;
7a387fff 7618 default:
f31b035a 7619 goto cp0_unimplemented;
7a387fff 7620 }
873eb012 7621 break;
04992c8c 7622 case CP0_REGISTER_25:
7a387fff 7623 switch (sel) {
1176b328 7624 case CP0_REG25__PERFCTL0:
7db13fae 7625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 7626 register_name = "Performance0";
7a387fff 7627 break;
1176b328 7628 case CP0_REG25__PERFCNT0:
7480515f 7629 /* gen_helper_mfc0_performance1(arg); */
294fc2ea 7630 register_name = "Performance1";
3570d7f6 7631 goto cp0_unimplemented;
1176b328 7632 case CP0_REG25__PERFCTL1:
7480515f 7633 /* gen_helper_mfc0_performance2(arg); */
294fc2ea 7634 register_name = "Performance2";
3570d7f6 7635 goto cp0_unimplemented;
1176b328 7636 case CP0_REG25__PERFCNT1:
7480515f 7637 /* gen_helper_mfc0_performance3(arg); */
294fc2ea 7638 register_name = "Performance3";
3570d7f6 7639 goto cp0_unimplemented;
1176b328 7640 case CP0_REG25__PERFCTL2:
7480515f 7641 /* gen_helper_mfc0_performance4(arg); */
294fc2ea 7642 register_name = "Performance4";
3570d7f6 7643 goto cp0_unimplemented;
1176b328 7644 case CP0_REG25__PERFCNT2:
7480515f 7645 /* gen_helper_mfc0_performance5(arg); */
294fc2ea 7646 register_name = "Performance5";
3570d7f6 7647 goto cp0_unimplemented;
1176b328 7648 case CP0_REG25__PERFCTL3:
7480515f 7649 /* gen_helper_mfc0_performance6(arg); */
294fc2ea 7650 register_name = "Performance6";
3570d7f6 7651 goto cp0_unimplemented;
1176b328 7652 case CP0_REG25__PERFCNT3:
7480515f 7653 /* gen_helper_mfc0_performance7(arg); */
294fc2ea 7654 register_name = "Performance7";
3570d7f6 7655 goto cp0_unimplemented;
7a387fff 7656 default:
f31b035a 7657 goto cp0_unimplemented;
7a387fff 7658 }
8c0fdd85 7659 break;
04992c8c 7660 case CP0_REGISTER_26:
0d74a222 7661 switch (sel) {
dbbf08b2 7662 case CP0_REG26__ERRCTL:
0d74a222 7663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 7664 register_name = "ErrCtl";
0d74a222
LA
7665 break;
7666 default:
7667 goto cp0_unimplemented;
7668 }
da80682b 7669 break;
04992c8c 7670 case CP0_REGISTER_27:
7a387fff 7671 switch (sel) {
5a10873d 7672 case CP0_REG27__CACHERR:
d9bea114 7673 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7674 register_name = "CacheErr";
2423f660 7675 break;
7a387fff 7676 default:
f31b035a 7677 goto cp0_unimplemented;
7a387fff 7678 }
8c0fdd85 7679 break;
04992c8c 7680 case CP0_REGISTER_28:
873eb012 7681 switch (sel) {
a30e2f21
AM
7682 case CP0_REG28__TAGLO:
7683 case CP0_REG28__TAGLO1:
7684 case CP0_REG28__TAGLO2:
7685 case CP0_REG28__TAGLO3:
284b731a
LA
7686 {
7687 TCGv_i64 tmp = tcg_temp_new_i64();
7688 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7689 gen_move_low32(arg, tmp);
7690 tcg_temp_free_i64(tmp);
7691 }
294fc2ea 7692 register_name = "TagLo";
873eb012 7693 break;
a30e2f21
AM
7694 case CP0_REG28__DATALO:
7695 case CP0_REG28__DATALO1:
7696 case CP0_REG28__DATALO2:
7697 case CP0_REG28__DATALO3:
7db13fae 7698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 7699 register_name = "DataLo";
873eb012
TS
7700 break;
7701 default:
f31b035a 7702 goto cp0_unimplemented;
873eb012
TS
7703 }
7704 break;
04992c8c 7705 case CP0_REGISTER_29:
7a387fff 7706 switch (sel) {
af4bb6da
AM
7707 case CP0_REG29__TAGHI:
7708 case CP0_REG29__TAGHI1:
7709 case CP0_REG29__TAGHI2:
7710 case CP0_REG29__TAGHI3:
7db13fae 7711 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 7712 register_name = "TagHi";
7a387fff 7713 break;
af4bb6da
AM
7714 case CP0_REG29__DATAHI:
7715 case CP0_REG29__DATAHI1:
7716 case CP0_REG29__DATAHI2:
7717 case CP0_REG29__DATAHI3:
7db13fae 7718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 7719 register_name = "DataHi";
7a387fff
TS
7720 break;
7721 default:
f31b035a 7722 goto cp0_unimplemented;
7a387fff 7723 }
8c0fdd85 7724 break;
04992c8c 7725 case CP0_REGISTER_30:
7a387fff 7726 switch (sel) {
4bcf121e 7727 case CP0_REG30__ERROREPC:
7db13fae 7728 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 7729 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7730 register_name = "ErrorEPC";
2423f660 7731 break;
7a387fff 7732 default:
f31b035a 7733 goto cp0_unimplemented;
7a387fff 7734 }
873eb012 7735 break;
04992c8c 7736 case CP0_REGISTER_31:
7a387fff 7737 switch (sel) {
14d92efd 7738 case CP0_REG31__DESAVE:
f0b3f3ae 7739 /* EJTAG support */
7db13fae 7740 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 7741 register_name = "DESAVE";
2423f660 7742 break;
14d92efd
AM
7743 case CP0_REG31__KSCRATCH1:
7744 case CP0_REG31__KSCRATCH2:
7745 case CP0_REG31__KSCRATCH3:
7746 case CP0_REG31__KSCRATCH4:
7747 case CP0_REG31__KSCRATCH5:
7748 case CP0_REG31__KSCRATCH6:
f31b035a
LA
7749 CP0_CHECK(ctx->kscrexist & (1 << sel));
7750 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 7751 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
f31b035a 7752 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 7753 register_name = "KScratch";
e98c0d17 7754 break;
7a387fff 7755 default:
f31b035a 7756 goto cp0_unimplemented;
7a387fff 7757 }
873eb012
TS
7758 break;
7759 default:
f31b035a 7760 goto cp0_unimplemented;
873eb012 7761 }
294fc2ea 7762 trace_mips_translate_c0("mfc0", register_name, reg, sel);
873eb012
TS
7763 return;
7764
f31b035a 7765cp0_unimplemented:
294fc2ea
AM
7766 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7767 register_name, reg, sel);
f31b035a 7768 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
7769}
7770
d75c135e 7771static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 7772{
294fc2ea 7773 const char *register_name = "invalid";
7a387fff 7774
1f8929d2 7775 if (sel != 0) {
bbd5e4a2 7776 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7777 }
e189e748 7778
eeb3bba8 7779 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7780 gen_io_start();
bd79255d 7781 }
2e70f6ef 7782
8c0fdd85 7783 switch (reg) {
04992c8c 7784 case CP0_REGISTER_00:
7a387fff 7785 switch (sel) {
1b142da5 7786 case CP0_REG00__INDEX:
895c2d04 7787 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 7788 register_name = "Index";
7a387fff 7789 break;
1b142da5 7790 case CP0_REG00__MVPCONTROL:
f31b035a 7791 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7792 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 7793 register_name = "MVPControl";
ead9360e 7794 break;
1b142da5 7795 case CP0_REG00__MVPCONF0:
f31b035a 7796 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7797 /* ignored */
294fc2ea 7798 register_name = "MVPConf0";
ead9360e 7799 break;
1b142da5 7800 case CP0_REG00__MVPCONF1:
f31b035a 7801 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7802 /* ignored */
294fc2ea 7803 register_name = "MVPConf1";
ead9360e 7804 break;
1b142da5 7805 case CP0_REG00__VPCONTROL:
01bc435b
YK
7806 CP0_CHECK(ctx->vp);
7807 /* ignored */
294fc2ea 7808 register_name = "VPControl";
01bc435b 7809 break;
7a387fff 7810 default:
f31b035a 7811 goto cp0_unimplemented;
7a387fff 7812 }
8c0fdd85 7813 break;
04992c8c 7814 case CP0_REGISTER_01:
7a387fff 7815 switch (sel) {
30deb460 7816 case CP0_REG01__RANDOM:
2423f660 7817 /* ignored */
294fc2ea 7818 register_name = "Random";
2423f660 7819 break;
30deb460 7820 case CP0_REG01__VPECONTROL:
f31b035a 7821 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7822 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 7823 register_name = "VPEControl";
ead9360e 7824 break;
30deb460 7825 case CP0_REG01__VPECONF0:
f31b035a 7826 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7827 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 7828 register_name = "VPEConf0";
ead9360e 7829 break;
30deb460 7830 case CP0_REG01__VPECONF1:
f31b035a 7831 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7832 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 7833 register_name = "VPEConf1";
ead9360e 7834 break;
30deb460 7835 case CP0_REG01__YQMASK:
f31b035a 7836 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7837 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 7838 register_name = "YQMask";
ead9360e 7839 break;
30deb460 7840 case CP0_REG01__VPESCHEDULE:
f31b035a 7841 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7842 tcg_gen_st_tl(arg, cpu_env,
7843 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7844 register_name = "VPESchedule";
ead9360e 7845 break;
30deb460 7846 case CP0_REG01__VPESCHEFBACK:
f31b035a 7847 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7848 tcg_gen_st_tl(arg, cpu_env,
7849 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7850 register_name = "VPEScheFBack";
ead9360e 7851 break;
30deb460 7852 case CP0_REG01__VPEOPT:
f31b035a 7853 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7854 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 7855 register_name = "VPEOpt";
ead9360e 7856 break;
7a387fff 7857 default:
f31b035a 7858 goto cp0_unimplemented;
7a387fff 7859 }
8c0fdd85 7860 break;
04992c8c 7861 case CP0_REGISTER_02:
7a387fff 7862 switch (sel) {
6d27d5bd 7863 case CP0_REG02__ENTRYLO0:
895c2d04 7864 gen_helper_mtc0_entrylo0(cpu_env, arg);
294fc2ea 7865 register_name = "EntryLo0";
2423f660 7866 break;
6d27d5bd 7867 case CP0_REG02__TCSTATUS:
f31b035a 7868 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7869 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 7870 register_name = "TCStatus";
ead9360e 7871 break;
6d27d5bd 7872 case CP0_REG02__TCBIND:
f31b035a 7873 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7874 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 7875 register_name = "TCBind";
ead9360e 7876 break;
6d27d5bd 7877 case CP0_REG02__TCRESTART:
f31b035a 7878 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7879 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 7880 register_name = "TCRestart";
ead9360e 7881 break;
6d27d5bd 7882 case CP0_REG02__TCHALT:
f31b035a 7883 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7884 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 7885 register_name = "TCHalt";
ead9360e 7886 break;
6d27d5bd 7887 case CP0_REG02__TCCONTEXT:
f31b035a 7888 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7889 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 7890 register_name = "TCContext";
ead9360e 7891 break;
6d27d5bd 7892 case CP0_REG02__TCSCHEDULE:
f31b035a 7893 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7894 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 7895 register_name = "TCSchedule";
ead9360e 7896 break;
6d27d5bd 7897 case CP0_REG02__TCSCHEFBACK:
f31b035a 7898 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7899 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 7900 register_name = "TCScheFBack";
ead9360e 7901 break;
7a387fff 7902 default:
f31b035a 7903 goto cp0_unimplemented;
7a387fff 7904 }
8c0fdd85 7905 break;
04992c8c 7906 case CP0_REGISTER_03:
7a387fff 7907 switch (sel) {
acd37316 7908 case CP0_REG03__ENTRYLO1:
895c2d04 7909 gen_helper_mtc0_entrylo1(cpu_env, arg);
294fc2ea 7910 register_name = "EntryLo1";
2423f660 7911 break;
acd37316 7912 case CP0_REG03__GLOBALNUM:
01bc435b
YK
7913 CP0_CHECK(ctx->vp);
7914 /* ignored */
294fc2ea 7915 register_name = "GlobalNumber";
01bc435b 7916 break;
7a387fff 7917 default:
f31b035a 7918 goto cp0_unimplemented;
876d4b07 7919 }
8c0fdd85 7920 break;
04992c8c 7921 case CP0_REGISTER_04:
7a387fff 7922 switch (sel) {
020fe379 7923 case CP0_REG04__CONTEXT:
895c2d04 7924 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 7925 register_name = "Context";
2423f660 7926 break;
020fe379
AM
7927 case CP0_REG04__CONTEXTCONFIG:
7928 /* SmartMIPS ASE */
7929 /* gen_helper_mtc0_contextconfig(arg); */
294fc2ea 7930 register_name = "ContextConfig";
f31b035a 7931 goto cp0_unimplemented;
020fe379 7932 case CP0_REG04__USERLOCAL:
f31b035a
LA
7933 CP0_CHECK(ctx->ulri);
7934 tcg_gen_st_tl(arg, cpu_env,
7935 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 7936 register_name = "UserLocal";
d279279e 7937 break;
99029be1
YK
7938 case CP0_REG04__MMID:
7939 CP0_CHECK(ctx->mi);
7940 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7941 register_name = "MMID";
7942 break;
7a387fff 7943 default:
f31b035a 7944 goto cp0_unimplemented;
876d4b07 7945 }
8c0fdd85 7946 break;
04992c8c 7947 case CP0_REGISTER_05:
7a387fff 7948 switch (sel) {
a1e76353 7949 case CP0_REG05__PAGEMASK:
895c2d04 7950 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 7951 register_name = "PageMask";
2423f660 7952 break;
a1e76353 7953 case CP0_REG05__PAGEGRAIN:
7a47bae5 7954 check_insn(ctx, ISA_MIPS_R2);
895c2d04 7955 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 7956 register_name = "PageGrain";
eeb3bba8 7957 ctx->base.is_jmp = DISAS_STOP;
2423f660 7958 break;
a1e76353 7959 case CP0_REG05__SEGCTL0:
cec56a73
JH
7960 CP0_CHECK(ctx->sc);
7961 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 7962 register_name = "SegCtl0";
cec56a73 7963 break;
a1e76353 7964 case CP0_REG05__SEGCTL1:
cec56a73
JH
7965 CP0_CHECK(ctx->sc);
7966 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 7967 register_name = "SegCtl1";
cec56a73 7968 break;
a1e76353 7969 case CP0_REG05__SEGCTL2:
cec56a73
JH
7970 CP0_CHECK(ctx->sc);
7971 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 7972 register_name = "SegCtl2";
cec56a73 7973 break;
a1e76353 7974 case CP0_REG05__PWBASE:
5e31fdd5
YK
7975 check_pw(ctx);
7976 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 7977 register_name = "PWBase";
5e31fdd5 7978 break;
a1e76353 7979 case CP0_REG05__PWFIELD:
fa75ad14
YK
7980 check_pw(ctx);
7981 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 7982 register_name = "PWField";
fa75ad14 7983 break;
a1e76353 7984 case CP0_REG05__PWSIZE:
20b28ebc
YK
7985 check_pw(ctx);
7986 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 7987 register_name = "PWSize";
20b28ebc 7988 break;
7a387fff 7989 default:
f31b035a 7990 goto cp0_unimplemented;
876d4b07 7991 }
8c0fdd85 7992 break;
04992c8c 7993 case CP0_REGISTER_06:
7a387fff 7994 switch (sel) {
9023594b 7995 case CP0_REG06__WIRED:
895c2d04 7996 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 7997 register_name = "Wired";
2423f660 7998 break;
9023594b 7999 case CP0_REG06__SRSCONF0:
7a47bae5 8000 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8001 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 8002 register_name = "SRSConf0";
ead9360e 8003 break;
9023594b 8004 case CP0_REG06__SRSCONF1:
7a47bae5 8005 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8006 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 8007 register_name = "SRSConf1";
ead9360e 8008 break;
9023594b 8009 case CP0_REG06__SRSCONF2:
7a47bae5 8010 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8011 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 8012 register_name = "SRSConf2";
ead9360e 8013 break;
9023594b 8014 case CP0_REG06__SRSCONF3:
7a47bae5 8015 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8016 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 8017 register_name = "SRSConf3";
ead9360e 8018 break;
9023594b 8019 case CP0_REG06__SRSCONF4:
7a47bae5 8020 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8021 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 8022 register_name = "SRSConf4";
ead9360e 8023 break;
9023594b 8024 case CP0_REG06__PWCTL:
103be64c
YK
8025 check_pw(ctx);
8026 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 8027 register_name = "PWCtl";
103be64c 8028 break;
7a387fff 8029 default:
f31b035a 8030 goto cp0_unimplemented;
876d4b07 8031 }
8c0fdd85 8032 break;
04992c8c 8033 case CP0_REGISTER_07:
7a387fff 8034 switch (sel) {
143a9875 8035 case CP0_REG07__HWRENA:
7a47bae5 8036 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8037 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8038 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8039 register_name = "HWREna";
2423f660 8040 break;
7a387fff 8041 default:
f31b035a 8042 goto cp0_unimplemented;
876d4b07 8043 }
8c0fdd85 8044 break;
04992c8c 8045 case CP0_REGISTER_08:
aea14095 8046 switch (sel) {
67d167d2 8047 case CP0_REG08__BADVADDR:
aea14095 8048 /* ignored */
294fc2ea 8049 register_name = "BadVAddr";
aea14095 8050 break;
67d167d2 8051 case CP0_REG08__BADINSTR:
aea14095 8052 /* ignored */
294fc2ea 8053 register_name = "BadInstr";
aea14095 8054 break;
67d167d2 8055 case CP0_REG08__BADINSTRP:
aea14095 8056 /* ignored */
294fc2ea 8057 register_name = "BadInstrP";
aea14095 8058 break;
67d167d2 8059 case CP0_REG08__BADINSTRX:
25beba9b 8060 /* ignored */
294fc2ea 8061 register_name = "BadInstrX";
25beba9b 8062 break;
aea14095 8063 default:
f31b035a 8064 goto cp0_unimplemented;
aea14095 8065 }
8c0fdd85 8066 break;
04992c8c 8067 case CP0_REGISTER_09:
7a387fff 8068 switch (sel) {
e5a98a72 8069 case CP0_REG09__COUNT:
895c2d04 8070 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 8071 register_name = "Count";
2423f660 8072 break;
e5a98a72 8073 case CP0_REG09__SAARI:
5fb2dcd1
YK
8074 CP0_CHECK(ctx->saar);
8075 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 8076 register_name = "SAARI";
5fb2dcd1 8077 break;
e5a98a72 8078 case CP0_REG09__SAAR:
5fb2dcd1
YK
8079 CP0_CHECK(ctx->saar);
8080 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 8081 register_name = "SAAR";
5fb2dcd1 8082 break;
7a387fff 8083 default:
f31b035a 8084 goto cp0_unimplemented;
876d4b07 8085 }
8c0fdd85 8086 break;
04992c8c 8087 case CP0_REGISTER_10:
7a387fff 8088 switch (sel) {
860ffef0 8089 case CP0_REG10__ENTRYHI:
895c2d04 8090 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 8091 register_name = "EntryHi";
2423f660 8092 break;
7a387fff 8093 default:
f31b035a 8094 goto cp0_unimplemented;
876d4b07 8095 }
8c0fdd85 8096 break;
04992c8c 8097 case CP0_REGISTER_11:
7a387fff 8098 switch (sel) {
f5f3834f 8099 case CP0_REG11__COMPARE:
895c2d04 8100 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 8101 register_name = "Compare";
2423f660
TS
8102 break;
8103 /* 6,7 are implementation dependent */
7a387fff 8104 default:
f31b035a 8105 goto cp0_unimplemented;
876d4b07 8106 }
8c0fdd85 8107 break;
04992c8c 8108 case CP0_REGISTER_12:
7a387fff 8109 switch (sel) {
2b084867 8110 case CP0_REG12__STATUS:
867abc7e 8111 save_cpu_state(ctx, 1);
895c2d04 8112 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8113 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8114 gen_save_pc(ctx->base.pc_next + 4);
8115 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8116 register_name = "Status";
2423f660 8117 break;
2b084867 8118 case CP0_REG12__INTCTL:
7a47bae5 8119 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8120 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8121 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8122 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8123 register_name = "IntCtl";
2423f660 8124 break;
2b084867 8125 case CP0_REG12__SRSCTL:
7a47bae5 8126 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8127 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8128 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8129 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8130 register_name = "SRSCtl";
2423f660 8131 break;
2b084867 8132 case CP0_REG12__SRSMAP:
7a47bae5 8133 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8134 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8135 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8136 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8137 register_name = "SRSMap";
fd88b6ab 8138 break;
7a387fff 8139 default:
f31b035a 8140 goto cp0_unimplemented;
876d4b07 8141 }
8c0fdd85 8142 break;
04992c8c 8143 case CP0_REGISTER_13:
7a387fff 8144 switch (sel) {
e3c7559d 8145 case CP0_REG13__CAUSE:
867abc7e 8146 save_cpu_state(ctx, 1);
895c2d04 8147 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
8148 /*
8149 * Stop translation as we may have triggered an interrupt.
b28425ba 8150 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
8151 * translated code to check for pending interrupts.
8152 */
eeb3bba8
EC
8153 gen_save_pc(ctx->base.pc_next + 4);
8154 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8155 register_name = "Cause";
2423f660 8156 break;
7a387fff 8157 default:
f31b035a 8158 goto cp0_unimplemented;
876d4b07 8159 }
8c0fdd85 8160 break;
04992c8c 8161 case CP0_REGISTER_14:
7a387fff 8162 switch (sel) {
35e4b54d 8163 case CP0_REG14__EPC:
d54a299b 8164 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 8165 register_name = "EPC";
2423f660 8166 break;
7a387fff 8167 default:
f31b035a 8168 goto cp0_unimplemented;
876d4b07 8169 }
8c0fdd85 8170 break;
04992c8c 8171 case CP0_REGISTER_15:
7a387fff 8172 switch (sel) {
4466cd49 8173 case CP0_REG15__PRID:
2423f660 8174 /* ignored */
294fc2ea 8175 register_name = "PRid";
2423f660 8176 break;
4466cd49 8177 case CP0_REG15__EBASE:
7a47bae5 8178 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8179 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 8180 register_name = "EBase";
2423f660 8181 break;
7a387fff 8182 default:
f31b035a 8183 goto cp0_unimplemented;
1579a72e 8184 }
8c0fdd85 8185 break;
04992c8c 8186 case CP0_REGISTER_16:
8c0fdd85 8187 switch (sel) {
433efb4c 8188 case CP0_REG16__CONFIG:
895c2d04 8189 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 8190 register_name = "Config";
2423f660 8191 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8192 ctx->base.is_jmp = DISAS_STOP;
7a387fff 8193 break;
433efb4c 8194 case CP0_REG16__CONFIG1:
e397ee33 8195 /* ignored, read only */
294fc2ea 8196 register_name = "Config1";
7a387fff 8197 break;
433efb4c 8198 case CP0_REG16__CONFIG2:
895c2d04 8199 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 8200 register_name = "Config2";
2423f660 8201 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8202 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 8203 break;
433efb4c 8204 case CP0_REG16__CONFIG3:
90f12d73 8205 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 8206 register_name = "Config3";
90f12d73 8207 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8208 ctx->base.is_jmp = DISAS_STOP;
7a387fff 8209 break;
433efb4c 8210 case CP0_REG16__CONFIG4:
b4160af1 8211 gen_helper_mtc0_config4(cpu_env, arg);
294fc2ea 8212 register_name = "Config4";
eeb3bba8 8213 ctx->base.is_jmp = DISAS_STOP;
b4160af1 8214 break;
433efb4c 8215 case CP0_REG16__CONFIG5:
b4dd99a3 8216 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 8217 register_name = "Config5";
b4dd99a3 8218 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8219 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 8220 break;
e397ee33 8221 /* 6,7 are implementation dependent */
433efb4c 8222 case CP0_REG16__CONFIG6:
e397ee33 8223 /* ignored */
294fc2ea 8224 register_name = "Config6";
e397ee33 8225 break;
433efb4c 8226 case CP0_REG16__CONFIG7:
e397ee33 8227 /* ignored */
294fc2ea 8228 register_name = "Config7";
e397ee33 8229 break;
8c0fdd85 8230 default:
294fc2ea 8231 register_name = "Invalid config selector";
f31b035a 8232 goto cp0_unimplemented;
8c0fdd85
TS
8233 }
8234 break;
04992c8c 8235 case CP0_REGISTER_17:
7a387fff 8236 switch (sel) {
706ce142 8237 case CP0_REG17__LLADDR:
895c2d04 8238 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 8239 register_name = "LLAddr";
2423f660 8240 break;
706ce142 8241 case CP0_REG17__MAAR:
f6d4dd81
YK
8242 CP0_CHECK(ctx->mrp);
8243 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 8244 register_name = "MAAR";
f6d4dd81 8245 break;
706ce142 8246 case CP0_REG17__MAARI:
f6d4dd81
YK
8247 CP0_CHECK(ctx->mrp);
8248 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 8249 register_name = "MAARI";
f6d4dd81 8250 break;
7a387fff 8251 default:
f31b035a 8252 goto cp0_unimplemented;
7a387fff 8253 }
8c0fdd85 8254 break;
04992c8c 8255 case CP0_REGISTER_18:
7a387fff 8256 switch (sel) {
e8dcfe82
AM
8257 case CP0_REG18__WATCHLO0:
8258 case CP0_REG18__WATCHLO1:
8259 case CP0_REG18__WATCHLO2:
8260 case CP0_REG18__WATCHLO3:
8261 case CP0_REG18__WATCHLO4:
8262 case CP0_REG18__WATCHLO5:
8263 case CP0_REG18__WATCHLO6:
8264 case CP0_REG18__WATCHLO7:
fa192d49 8265 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8266 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 8267 register_name = "WatchLo";
2423f660 8268 break;
7a387fff 8269 default:
f31b035a 8270 goto cp0_unimplemented;
7a387fff 8271 }
8c0fdd85 8272 break;
04992c8c 8273 case CP0_REGISTER_19:
7a387fff 8274 switch (sel) {
be274dc1
AM
8275 case CP0_REG19__WATCHHI0:
8276 case CP0_REG19__WATCHHI1:
8277 case CP0_REG19__WATCHHI2:
8278 case CP0_REG19__WATCHHI3:
8279 case CP0_REG19__WATCHHI4:
8280 case CP0_REG19__WATCHHI5:
8281 case CP0_REG19__WATCHHI6:
8282 case CP0_REG19__WATCHHI7:
fa192d49 8283 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8284 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 8285 register_name = "WatchHi";
2423f660 8286 break;
7a387fff 8287 default:
f31b035a 8288 goto cp0_unimplemented;
7a387fff 8289 }
8c0fdd85 8290 break;
04992c8c 8291 case CP0_REGISTER_20:
7a387fff 8292 switch (sel) {
14f92b0b 8293 case CP0_REG20__XCONTEXT:
d26bc211 8294#if defined(TARGET_MIPS64)
d75c135e 8295 check_insn(ctx, ISA_MIPS3);
895c2d04 8296 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 8297 register_name = "XContext";
2423f660 8298 break;
703eaf37 8299#endif
7a387fff 8300 default:
f31b035a 8301 goto cp0_unimplemented;
7a387fff 8302 }
8c0fdd85 8303 break;
04992c8c 8304 case CP0_REGISTER_21:
7a387fff 8305 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 8306 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
8307 switch (sel) {
8308 case 0:
895c2d04 8309 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 8310 register_name = "Framemask";
2423f660 8311 break;
7a387fff 8312 default:
f31b035a 8313 goto cp0_unimplemented;
7a387fff
TS
8314 }
8315 break;
04992c8c 8316 case CP0_REGISTER_22:
7a387fff 8317 /* ignored */
294fc2ea 8318 register_name = "Diagnostic"; /* implementation dependent */
2423f660 8319 break;
04992c8c 8320 case CP0_REGISTER_23:
7a387fff 8321 switch (sel) {
4cbf4b6d 8322 case CP0_REG23__DEBUG:
895c2d04 8323 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 8324 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8325 gen_save_pc(ctx->base.pc_next + 4);
8326 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8327 register_name = "Debug";
2423f660 8328 break;
4cbf4b6d
AM
8329 case CP0_REG23__TRACECONTROL:
8330 /* PDtrace support */
8331 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
294fc2ea 8332 register_name = "TraceControl";
8487327a 8333 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8334 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8335 goto cp0_unimplemented;
4cbf4b6d
AM
8336 case CP0_REG23__TRACECONTROL2:
8337 /* PDtrace support */
8338 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
294fc2ea 8339 register_name = "TraceControl2";
8487327a 8340 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8341 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8342 goto cp0_unimplemented;
4cbf4b6d 8343 case CP0_REG23__USERTRACEDATA1:
8487327a 8344 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8345 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
8346 /* PDtrace support */
8347 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
294fc2ea 8348 register_name = "UserTraceData";
8487327a 8349 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8350 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8351 goto cp0_unimplemented;
4cbf4b6d
AM
8352 case CP0_REG23__TRACEIBPC:
8353 /* PDtrace support */
8354 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8487327a 8355 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8356 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
8357 register_name = "TraceIBPC";
8358 goto cp0_unimplemented;
8359 case CP0_REG23__TRACEDBPC:
8360 /* PDtrace support */
8361 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8362 /* Stop translation as we may have switched the execution mode */
8363 ctx->base.is_jmp = DISAS_STOP;
8364 register_name = "TraceDBPC";
3570d7f6 8365 goto cp0_unimplemented;
7a387fff 8366 default:
f31b035a 8367 goto cp0_unimplemented;
7a387fff 8368 }
8c0fdd85 8369 break;
04992c8c 8370 case CP0_REGISTER_24:
7a387fff 8371 switch (sel) {
8d7b4b6e 8372 case CP0_REG24__DEPC:
f1aa6320 8373 /* EJTAG support */
d54a299b 8374 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 8375 register_name = "DEPC";
2423f660 8376 break;
7a387fff 8377 default:
f31b035a 8378 goto cp0_unimplemented;
7a387fff 8379 }
8c0fdd85 8380 break;
04992c8c 8381 case CP0_REGISTER_25:
7a387fff 8382 switch (sel) {
1176b328 8383 case CP0_REG25__PERFCTL0:
895c2d04 8384 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 8385 register_name = "Performance0";
2423f660 8386 break;
1176b328 8387 case CP0_REG25__PERFCNT0:
7480515f 8388 /* gen_helper_mtc0_performance1(arg); */
294fc2ea 8389 register_name = "Performance1";
3570d7f6 8390 goto cp0_unimplemented;
1176b328 8391 case CP0_REG25__PERFCTL1:
7480515f 8392 /* gen_helper_mtc0_performance2(arg); */
294fc2ea 8393 register_name = "Performance2";
3570d7f6 8394 goto cp0_unimplemented;
1176b328 8395 case CP0_REG25__PERFCNT1:
7480515f 8396 /* gen_helper_mtc0_performance3(arg); */
294fc2ea 8397 register_name = "Performance3";
3570d7f6 8398 goto cp0_unimplemented;
1176b328 8399 case CP0_REG25__PERFCTL2:
7480515f 8400 /* gen_helper_mtc0_performance4(arg); */
294fc2ea 8401 register_name = "Performance4";
3570d7f6 8402 goto cp0_unimplemented;
1176b328 8403 case CP0_REG25__PERFCNT2:
7480515f 8404 /* gen_helper_mtc0_performance5(arg); */
294fc2ea 8405 register_name = "Performance5";
3570d7f6 8406 goto cp0_unimplemented;
1176b328 8407 case CP0_REG25__PERFCTL3:
7480515f 8408 /* gen_helper_mtc0_performance6(arg); */
294fc2ea 8409 register_name = "Performance6";
3570d7f6 8410 goto cp0_unimplemented;
1176b328 8411 case CP0_REG25__PERFCNT3:
7480515f 8412 /* gen_helper_mtc0_performance7(arg); */
294fc2ea 8413 register_name = "Performance7";
3570d7f6 8414 goto cp0_unimplemented;
7a387fff 8415 default:
f31b035a 8416 goto cp0_unimplemented;
7a387fff 8417 }
8c0fdd85 8418 break;
04992c8c 8419 case CP0_REGISTER_26:
0d74a222 8420 switch (sel) {
dbbf08b2 8421 case CP0_REG26__ERRCTL:
0d74a222 8422 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8423 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8424 register_name = "ErrCtl";
0d74a222
LA
8425 break;
8426 default:
8427 goto cp0_unimplemented;
8428 }
2423f660 8429 break;
04992c8c 8430 case CP0_REGISTER_27:
7a387fff 8431 switch (sel) {
5a10873d 8432 case CP0_REG27__CACHERR:
2423f660 8433 /* ignored */
294fc2ea 8434 register_name = "CacheErr";
2423f660 8435 break;
7a387fff 8436 default:
f31b035a 8437 goto cp0_unimplemented;
7a387fff 8438 }
8c0fdd85 8439 break;
04992c8c 8440 case CP0_REGISTER_28:
8c0fdd85 8441 switch (sel) {
a30e2f21
AM
8442 case CP0_REG28__TAGLO:
8443 case CP0_REG28__TAGLO1:
8444 case CP0_REG28__TAGLO2:
8445 case CP0_REG28__TAGLO3:
895c2d04 8446 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 8447 register_name = "TagLo";
8c0fdd85 8448 break;
a30e2f21
AM
8449 case CP0_REG28__DATALO:
8450 case CP0_REG28__DATALO1:
8451 case CP0_REG28__DATALO2:
8452 case CP0_REG28__DATALO3:
895c2d04 8453 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 8454 register_name = "DataLo";
7a387fff 8455 break;
8c0fdd85 8456 default:
f31b035a 8457 goto cp0_unimplemented;
8c0fdd85
TS
8458 }
8459 break;
04992c8c 8460 case CP0_REGISTER_29:
7a387fff 8461 switch (sel) {
af4bb6da
AM
8462 case CP0_REG29__TAGHI:
8463 case CP0_REG29__TAGHI1:
8464 case CP0_REG29__TAGHI2:
8465 case CP0_REG29__TAGHI3:
895c2d04 8466 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 8467 register_name = "TagHi";
7a387fff 8468 break;
af4bb6da
AM
8469 case CP0_REG29__DATAHI:
8470 case CP0_REG29__DATAHI1:
8471 case CP0_REG29__DATAHI2:
8472 case CP0_REG29__DATAHI3:
895c2d04 8473 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 8474 register_name = "DataHi";
7a387fff
TS
8475 break;
8476 default:
294fc2ea 8477 register_name = "invalid sel";
f31b035a 8478 goto cp0_unimplemented;
7a387fff 8479 }
8c0fdd85 8480 break;
04992c8c 8481 case CP0_REGISTER_30:
7a387fff 8482 switch (sel) {
4bcf121e 8483 case CP0_REG30__ERROREPC:
d54a299b 8484 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 8485 register_name = "ErrorEPC";
2423f660 8486 break;
7a387fff 8487 default:
f31b035a 8488 goto cp0_unimplemented;
7a387fff 8489 }
8c0fdd85 8490 break;
04992c8c 8491 case CP0_REGISTER_31:
7a387fff 8492 switch (sel) {
14d92efd 8493 case CP0_REG31__DESAVE:
f1aa6320 8494 /* EJTAG support */
7db13fae 8495 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 8496 register_name = "DESAVE";
2423f660 8497 break;
14d92efd
AM
8498 case CP0_REG31__KSCRATCH1:
8499 case CP0_REG31__KSCRATCH2:
8500 case CP0_REG31__KSCRATCH3:
8501 case CP0_REG31__KSCRATCH4:
8502 case CP0_REG31__KSCRATCH5:
8503 case CP0_REG31__KSCRATCH6:
f31b035a
LA
8504 CP0_CHECK(ctx->kscrexist & (1 << sel));
8505 tcg_gen_st_tl(arg, cpu_env,
05aa7e93 8506 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 8507 register_name = "KScratch";
e98c0d17 8508 break;
7a387fff 8509 default:
f31b035a 8510 goto cp0_unimplemented;
7a387fff 8511 }
8c0fdd85
TS
8512 break;
8513 default:
f31b035a 8514 goto cp0_unimplemented;
8c0fdd85 8515 }
294fc2ea 8516 trace_mips_translate_c0("mtc0", register_name, reg, sel);
b44a7fb1 8517
bf20dc07 8518 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8519 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
8520 /*
8521 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8522 * translated code to check for pending interrupts.
8523 */
eeb3bba8
EC
8524 gen_save_pc(ctx->base.pc_next + 4);
8525 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8526 }
8c0fdd85
TS
8527 return;
8528
f31b035a 8529cp0_unimplemented:
294fc2ea
AM
8530 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8531 register_name, reg, sel);
8c0fdd85
TS
8532}
8533
d26bc211 8534#if defined(TARGET_MIPS64)
d75c135e 8535static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 8536{
294fc2ea 8537 const char *register_name = "invalid";
9c2149c8 8538
1f8929d2 8539 if (sel != 0) {
bbd5e4a2 8540 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 8541 }
e189e748 8542
9c2149c8 8543 switch (reg) {
04992c8c 8544 case CP0_REGISTER_00:
9c2149c8 8545 switch (sel) {
1b142da5 8546 case CP0_REG00__INDEX:
7db13fae 8547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 8548 register_name = "Index";
9c2149c8 8549 break;
1b142da5 8550 case CP0_REG00__MVPCONTROL:
f31b035a 8551 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8552 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 8553 register_name = "MVPControl";
ead9360e 8554 break;
1b142da5 8555 case CP0_REG00__MVPCONF0:
f31b035a 8556 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8557 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 8558 register_name = "MVPConf0";
ead9360e 8559 break;
1b142da5 8560 case CP0_REG00__MVPCONF1:
f31b035a 8561 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8562 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 8563 register_name = "MVPConf1";
ead9360e 8564 break;
1b142da5 8565 case CP0_REG00__VPCONTROL:
01bc435b
YK
8566 CP0_CHECK(ctx->vp);
8567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 8568 register_name = "VPControl";
01bc435b 8569 break;
9c2149c8 8570 default:
f31b035a 8571 goto cp0_unimplemented;
9c2149c8
TS
8572 }
8573 break;
04992c8c 8574 case CP0_REGISTER_01:
9c2149c8 8575 switch (sel) {
30deb460 8576 case CP0_REG01__RANDOM:
2e211e0a 8577 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 8578 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 8579 register_name = "Random";
2423f660 8580 break;
30deb460 8581 case CP0_REG01__VPECONTROL:
f31b035a 8582 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 8584 register_name = "VPEControl";
ead9360e 8585 break;
30deb460 8586 case CP0_REG01__VPECONF0:
f31b035a 8587 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 8589 register_name = "VPEConf0";
ead9360e 8590 break;
30deb460 8591 case CP0_REG01__VPECONF1:
f31b035a 8592 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 8594 register_name = "VPEConf1";
ead9360e 8595 break;
30deb460 8596 case CP0_REG01__YQMASK:
f31b035a 8597 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
8598 tcg_gen_ld_tl(arg, cpu_env,
8599 offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 8600 register_name = "YQMask";
ead9360e 8601 break;
30deb460 8602 case CP0_REG01__VPESCHEDULE:
f31b035a 8603 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
8604 tcg_gen_ld_tl(arg, cpu_env,
8605 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 8606 register_name = "VPESchedule";
ead9360e 8607 break;
30deb460 8608 case CP0_REG01__VPESCHEFBACK:
f31b035a 8609 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
8610 tcg_gen_ld_tl(arg, cpu_env,
8611 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 8612 register_name = "VPEScheFBack";
ead9360e 8613 break;
30deb460 8614 case CP0_REG01__VPEOPT:
f31b035a 8615 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 8617 register_name = "VPEOpt";
ead9360e 8618 break;
9c2149c8 8619 default:
f31b035a 8620 goto cp0_unimplemented;
9c2149c8
TS
8621 }
8622 break;
04992c8c 8623 case CP0_REGISTER_02:
9c2149c8 8624 switch (sel) {
6d27d5bd 8625 case CP0_REG02__ENTRYLO0:
05aa7e93
AM
8626 tcg_gen_ld_tl(arg, cpu_env,
8627 offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 8628 register_name = "EntryLo0";
2423f660 8629 break;
6d27d5bd 8630 case CP0_REG02__TCSTATUS:
f31b035a 8631 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8632 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 8633 register_name = "TCStatus";
ead9360e 8634 break;
6d27d5bd 8635 case CP0_REG02__TCBIND:
f31b035a 8636 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8637 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 8638 register_name = "TCBind";
ead9360e 8639 break;
6d27d5bd 8640 case CP0_REG02__TCRESTART:
f31b035a 8641 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8642 gen_helper_dmfc0_tcrestart(arg, cpu_env);
294fc2ea 8643 register_name = "TCRestart";
ead9360e 8644 break;
6d27d5bd 8645 case CP0_REG02__TCHALT:
f31b035a 8646 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8647 gen_helper_dmfc0_tchalt(arg, cpu_env);
294fc2ea 8648 register_name = "TCHalt";
ead9360e 8649 break;
6d27d5bd 8650 case CP0_REG02__TCCONTEXT:
f31b035a 8651 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8652 gen_helper_dmfc0_tccontext(arg, cpu_env);
294fc2ea 8653 register_name = "TCContext";
ead9360e 8654 break;
6d27d5bd 8655 case CP0_REG02__TCSCHEDULE:
f31b035a 8656 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8657 gen_helper_dmfc0_tcschedule(arg, cpu_env);
294fc2ea 8658 register_name = "TCSchedule";
ead9360e 8659 break;
6d27d5bd 8660 case CP0_REG02__TCSCHEFBACK:
f31b035a 8661 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8662 gen_helper_dmfc0_tcschefback(arg, cpu_env);
294fc2ea 8663 register_name = "TCScheFBack";
ead9360e 8664 break;
9c2149c8 8665 default:
f31b035a 8666 goto cp0_unimplemented;
9c2149c8
TS
8667 }
8668 break;
04992c8c 8669 case CP0_REGISTER_03:
9c2149c8 8670 switch (sel) {
acd37316 8671 case CP0_REG03__ENTRYLO1:
7db13fae 8672 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 8673 register_name = "EntryLo1";
2423f660 8674 break;
acd37316 8675 case CP0_REG03__GLOBALNUM:
01bc435b
YK
8676 CP0_CHECK(ctx->vp);
8677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 8678 register_name = "GlobalNumber";
01bc435b 8679 break;
9c2149c8 8680 default:
f31b035a 8681 goto cp0_unimplemented;
1579a72e 8682 }
9c2149c8 8683 break;
04992c8c 8684 case CP0_REGISTER_04:
9c2149c8 8685 switch (sel) {
020fe379 8686 case CP0_REG04__CONTEXT:
7db13fae 8687 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
294fc2ea 8688 register_name = "Context";
2423f660 8689 break;
020fe379
AM
8690 case CP0_REG04__CONTEXTCONFIG:
8691 /* SmartMIPS ASE */
8692 /* gen_helper_dmfc0_contextconfig(arg); */
294fc2ea 8693 register_name = "ContextConfig";
f31b035a 8694 goto cp0_unimplemented;
020fe379 8695 case CP0_REG04__USERLOCAL:
f31b035a
LA
8696 CP0_CHECK(ctx->ulri);
8697 tcg_gen_ld_tl(arg, cpu_env,
8698 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 8699 register_name = "UserLocal";
d279279e 8700 break;
99029be1
YK
8701 case CP0_REG04__MMID:
8702 CP0_CHECK(ctx->mi);
8703 gen_helper_mtc0_memorymapid(cpu_env, arg);
8704 register_name = "MMID";
8705 break;
9c2149c8 8706 default:
f31b035a 8707 goto cp0_unimplemented;
876d4b07 8708 }
9c2149c8 8709 break;
04992c8c 8710 case CP0_REGISTER_05:
9c2149c8 8711 switch (sel) {
a1e76353 8712 case CP0_REG05__PAGEMASK:
7db13fae 8713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 8714 register_name = "PageMask";
2423f660 8715 break;
a1e76353 8716 case CP0_REG05__PAGEGRAIN:
7a47bae5 8717 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 8719 register_name = "PageGrain";
2423f660 8720 break;
a1e76353 8721 case CP0_REG05__SEGCTL0:
cec56a73
JH
8722 CP0_CHECK(ctx->sc);
8723 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
294fc2ea 8724 register_name = "SegCtl0";
cec56a73 8725 break;
a1e76353 8726 case CP0_REG05__SEGCTL1:
cec56a73
JH
8727 CP0_CHECK(ctx->sc);
8728 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
294fc2ea 8729 register_name = "SegCtl1";
cec56a73 8730 break;
a1e76353 8731 case CP0_REG05__SEGCTL2:
cec56a73
JH
8732 CP0_CHECK(ctx->sc);
8733 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
294fc2ea 8734 register_name = "SegCtl2";
cec56a73 8735 break;
a1e76353 8736 case CP0_REG05__PWBASE:
5e31fdd5
YK
8737 check_pw(ctx);
8738 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 8739 register_name = "PWBase";
5e31fdd5 8740 break;
a1e76353 8741 case CP0_REG05__PWFIELD:
fa75ad14
YK
8742 check_pw(ctx);
8743 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 8744 register_name = "PWField";
fa75ad14 8745 break;
a1e76353 8746 case CP0_REG05__PWSIZE:
20b28ebc
YK
8747 check_pw(ctx);
8748 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 8749 register_name = "PWSize";
20b28ebc 8750 break;
9c2149c8 8751 default:
f31b035a 8752 goto cp0_unimplemented;
876d4b07 8753 }
9c2149c8 8754 break;
04992c8c 8755 case CP0_REGISTER_06:
9c2149c8 8756 switch (sel) {
9023594b 8757 case CP0_REG06__WIRED:
7db13fae 8758 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 8759 register_name = "Wired";
2423f660 8760 break;
9023594b 8761 case CP0_REG06__SRSCONF0:
7a47bae5 8762 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 8764 register_name = "SRSConf0";
ead9360e 8765 break;
9023594b 8766 case CP0_REG06__SRSCONF1:
7a47bae5 8767 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 8769 register_name = "SRSConf1";
ead9360e 8770 break;
9023594b 8771 case CP0_REG06__SRSCONF2:
7a47bae5 8772 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8773 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 8774 register_name = "SRSConf2";
ead9360e 8775 break;
9023594b 8776 case CP0_REG06__SRSCONF3:
7a47bae5 8777 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8778 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 8779 register_name = "SRSConf3";
ead9360e 8780 break;
9023594b 8781 case CP0_REG06__SRSCONF4:
7a47bae5 8782 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 8784 register_name = "SRSConf4";
ead9360e 8785 break;
9023594b 8786 case CP0_REG06__PWCTL:
103be64c
YK
8787 check_pw(ctx);
8788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 8789 register_name = "PWCtl";
103be64c 8790 break;
9c2149c8 8791 default:
f31b035a 8792 goto cp0_unimplemented;
876d4b07 8793 }
9c2149c8 8794 break;
04992c8c 8795 case CP0_REGISTER_07:
9c2149c8 8796 switch (sel) {
143a9875 8797 case CP0_REG07__HWRENA:
7a47bae5 8798 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 8800 register_name = "HWREna";
2423f660 8801 break;
9c2149c8 8802 default:
f31b035a 8803 goto cp0_unimplemented;
876d4b07 8804 }
9c2149c8 8805 break;
04992c8c 8806 case CP0_REGISTER_08:
9c2149c8 8807 switch (sel) {
67d167d2 8808 case CP0_REG08__BADVADDR:
7db13fae 8809 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
294fc2ea 8810 register_name = "BadVAddr";
2423f660 8811 break;
67d167d2 8812 case CP0_REG08__BADINSTR:
f31b035a
LA
8813 CP0_CHECK(ctx->bi);
8814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 8815 register_name = "BadInstr";
aea14095 8816 break;
67d167d2 8817 case CP0_REG08__BADINSTRP:
f31b035a
LA
8818 CP0_CHECK(ctx->bp);
8819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 8820 register_name = "BadInstrP";
aea14095 8821 break;
67d167d2 8822 case CP0_REG08__BADINSTRX:
25beba9b
SM
8823 CP0_CHECK(ctx->bi);
8824 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8825 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 8826 register_name = "BadInstrX";
25beba9b 8827 break;
9c2149c8 8828 default:
f31b035a 8829 goto cp0_unimplemented;
876d4b07 8830 }
9c2149c8 8831 break;
04992c8c 8832 case CP0_REGISTER_09:
9c2149c8 8833 switch (sel) {
e5a98a72 8834 case CP0_REG09__COUNT:
2e70f6ef 8835 /* Mark as an IO operation because we read the time. */
eeb3bba8 8836 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8837 gen_io_start();
bd79255d 8838 }
895c2d04 8839 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
8840 /*
8841 * Break the TB to be able to take timer interrupts immediately
8842 * after reading count. DISAS_STOP isn't sufficient, we need to
8843 * ensure we break completely out of translated code.
8844 */
eeb3bba8
EC
8845 gen_save_pc(ctx->base.pc_next + 4);
8846 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8847 register_name = "Count";
2423f660 8848 break;
e5a98a72 8849 case CP0_REG09__SAARI:
5fb2dcd1
YK
8850 CP0_CHECK(ctx->saar);
8851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 8852 register_name = "SAARI";
5fb2dcd1 8853 break;
e5a98a72 8854 case CP0_REG09__SAAR:
5fb2dcd1
YK
8855 CP0_CHECK(ctx->saar);
8856 gen_helper_dmfc0_saar(arg, cpu_env);
294fc2ea 8857 register_name = "SAAR";
5fb2dcd1 8858 break;
9c2149c8 8859 default:
f31b035a 8860 goto cp0_unimplemented;
876d4b07 8861 }
9c2149c8 8862 break;
04992c8c 8863 case CP0_REGISTER_10:
9c2149c8 8864 switch (sel) {
860ffef0 8865 case CP0_REG10__ENTRYHI:
7db13fae 8866 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
294fc2ea 8867 register_name = "EntryHi";
2423f660 8868 break;
9c2149c8 8869 default:
f31b035a 8870 goto cp0_unimplemented;
876d4b07 8871 }
9c2149c8 8872 break;
04992c8c 8873 case CP0_REGISTER_11:
9c2149c8 8874 switch (sel) {
f5f3834f 8875 case CP0_REG11__COMPARE:
7db13fae 8876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 8877 register_name = "Compare";
2423f660 8878 break;
876d4b07 8879 /* 6,7 are implementation dependent */
9c2149c8 8880 default:
f31b035a 8881 goto cp0_unimplemented;
876d4b07 8882 }
9c2149c8 8883 break;
04992c8c 8884 case CP0_REGISTER_12:
9c2149c8 8885 switch (sel) {
2b084867 8886 case CP0_REG12__STATUS:
7db13fae 8887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 8888 register_name = "Status";
2423f660 8889 break;
2b084867 8890 case CP0_REG12__INTCTL:
7a47bae5 8891 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8892 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 8893 register_name = "IntCtl";
2423f660 8894 break;
2b084867 8895 case CP0_REG12__SRSCTL:
7a47bae5 8896 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8897 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 8898 register_name = "SRSCtl";
2423f660 8899 break;
2b084867 8900 case CP0_REG12__SRSMAP:
7a47bae5 8901 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 8903 register_name = "SRSMap";
2423f660 8904 break;
9c2149c8 8905 default:
f31b035a 8906 goto cp0_unimplemented;
876d4b07 8907 }
9c2149c8 8908 break;
04992c8c 8909 case CP0_REGISTER_13:
9c2149c8 8910 switch (sel) {
e3c7559d 8911 case CP0_REG13__CAUSE:
7db13fae 8912 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 8913 register_name = "Cause";
2423f660 8914 break;
9c2149c8 8915 default:
f31b035a 8916 goto cp0_unimplemented;
876d4b07 8917 }
9c2149c8 8918 break;
04992c8c 8919 case CP0_REGISTER_14:
9c2149c8 8920 switch (sel) {
35e4b54d 8921 case CP0_REG14__EPC:
7db13fae 8922 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 8923 register_name = "EPC";
2423f660 8924 break;
9c2149c8 8925 default:
f31b035a 8926 goto cp0_unimplemented;
876d4b07 8927 }
9c2149c8 8928 break;
04992c8c 8929 case CP0_REGISTER_15:
9c2149c8 8930 switch (sel) {
4466cd49 8931 case CP0_REG15__PRID:
7db13fae 8932 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 8933 register_name = "PRid";
2423f660 8934 break;
4466cd49 8935 case CP0_REG15__EBASE:
7a47bae5 8936 check_insn(ctx, ISA_MIPS_R2);
74dbf824 8937 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
294fc2ea 8938 register_name = "EBase";
2423f660 8939 break;
4466cd49 8940 case CP0_REG15__CMGCRBASE:
7a47bae5 8941 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
8942 CP0_CHECK(ctx->cmgcr);
8943 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
294fc2ea 8944 register_name = "CMGCRBase";
c870e3f5 8945 break;
9c2149c8 8946 default:
f31b035a 8947 goto cp0_unimplemented;
876d4b07 8948 }
9c2149c8 8949 break;
04992c8c 8950 case CP0_REGISTER_16:
9c2149c8 8951 switch (sel) {
433efb4c 8952 case CP0_REG16__CONFIG:
7db13fae 8953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 8954 register_name = "Config";
9c2149c8 8955 break;
433efb4c 8956 case CP0_REG16__CONFIG1:
7db13fae 8957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 8958 register_name = "Config1";
9c2149c8 8959 break;
433efb4c 8960 case CP0_REG16__CONFIG2:
7db13fae 8961 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 8962 register_name = "Config2";
9c2149c8 8963 break;
433efb4c 8964 case CP0_REG16__CONFIG3:
7db13fae 8965 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 8966 register_name = "Config3";
9c2149c8 8967 break;
433efb4c 8968 case CP0_REG16__CONFIG4:
faf1f68b 8969 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 8970 register_name = "Config4";
faf1f68b 8971 break;
433efb4c 8972 case CP0_REG16__CONFIG5:
faf1f68b 8973 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 8974 register_name = "Config5";
faf1f68b 8975 break;
05aa7e93 8976 /* 6,7 are implementation dependent */
433efb4c 8977 case CP0_REG16__CONFIG6:
7db13fae 8978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 8979 register_name = "Config6";
f0b3f3ae 8980 break;
433efb4c 8981 case CP0_REG16__CONFIG7:
7db13fae 8982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 8983 register_name = "Config7";
f0b3f3ae 8984 break;
9c2149c8 8985 default:
f31b035a 8986 goto cp0_unimplemented;
9c2149c8
TS
8987 }
8988 break;
04992c8c 8989 case CP0_REGISTER_17:
9c2149c8 8990 switch (sel) {
706ce142 8991 case CP0_REG17__LLADDR:
895c2d04 8992 gen_helper_dmfc0_lladdr(arg, cpu_env);
294fc2ea 8993 register_name = "LLAddr";
2423f660 8994 break;
706ce142 8995 case CP0_REG17__MAAR:
f6d4dd81
YK
8996 CP0_CHECK(ctx->mrp);
8997 gen_helper_dmfc0_maar(arg, cpu_env);
294fc2ea 8998 register_name = "MAAR";
f6d4dd81 8999 break;
706ce142 9000 case CP0_REG17__MAARI:
f6d4dd81
YK
9001 CP0_CHECK(ctx->mrp);
9002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 9003 register_name = "MAARI";
f6d4dd81 9004 break;
9c2149c8 9005 default:
f31b035a 9006 goto cp0_unimplemented;
9c2149c8
TS
9007 }
9008 break;
04992c8c 9009 case CP0_REGISTER_18:
9c2149c8 9010 switch (sel) {
e8dcfe82
AM
9011 case CP0_REG18__WATCHLO0:
9012 case CP0_REG18__WATCHLO1:
9013 case CP0_REG18__WATCHLO2:
9014 case CP0_REG18__WATCHLO3:
9015 case CP0_REG18__WATCHLO4:
9016 case CP0_REG18__WATCHLO5:
9017 case CP0_REG18__WATCHLO6:
9018 case CP0_REG18__WATCHLO7:
fa192d49 9019 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9020 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
294fc2ea 9021 register_name = "WatchLo";
2423f660 9022 break;
9c2149c8 9023 default:
f31b035a 9024 goto cp0_unimplemented;
9c2149c8
TS
9025 }
9026 break;
04992c8c 9027 case CP0_REGISTER_19:
9c2149c8 9028 switch (sel) {
be274dc1
AM
9029 case CP0_REG19__WATCHHI0:
9030 case CP0_REG19__WATCHHI1:
9031 case CP0_REG19__WATCHHI2:
9032 case CP0_REG19__WATCHHI3:
9033 case CP0_REG19__WATCHHI4:
9034 case CP0_REG19__WATCHHI5:
9035 case CP0_REG19__WATCHHI6:
9036 case CP0_REG19__WATCHHI7:
fa192d49 9037 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
feafe82c 9038 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
294fc2ea 9039 register_name = "WatchHi";
2423f660 9040 break;
9c2149c8 9041 default:
f31b035a 9042 goto cp0_unimplemented;
9c2149c8
TS
9043 }
9044 break;
04992c8c 9045 case CP0_REGISTER_20:
9c2149c8 9046 switch (sel) {
14f92b0b 9047 case CP0_REG20__XCONTEXT:
d75c135e 9048 check_insn(ctx, ISA_MIPS3);
7db13fae 9049 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
294fc2ea 9050 register_name = "XContext";
2423f660 9051 break;
9c2149c8 9052 default:
f31b035a 9053 goto cp0_unimplemented;
9c2149c8
TS
9054 }
9055 break;
04992c8c 9056 case CP0_REGISTER_21:
05aa7e93 9057 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 9058 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
9059 switch (sel) {
9060 case 0:
7db13fae 9061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 9062 register_name = "Framemask";
2423f660 9063 break;
9c2149c8 9064 default:
f31b035a 9065 goto cp0_unimplemented;
9c2149c8
TS
9066 }
9067 break;
04992c8c 9068 case CP0_REGISTER_22:
d9bea114 9069 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 9070 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 9071 break;
04992c8c 9072 case CP0_REGISTER_23:
9c2149c8 9073 switch (sel) {
4cbf4b6d 9074 case CP0_REG23__DEBUG:
895c2d04 9075 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 9076 register_name = "Debug";
2423f660 9077 break;
4cbf4b6d
AM
9078 case CP0_REG23__TRACECONTROL:
9079 /* PDtrace support */
9080 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
294fc2ea 9081 register_name = "TraceControl";
3570d7f6 9082 goto cp0_unimplemented;
4cbf4b6d
AM
9083 case CP0_REG23__TRACECONTROL2:
9084 /* PDtrace support */
9085 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
294fc2ea 9086 register_name = "TraceControl2";
3570d7f6 9087 goto cp0_unimplemented;
4cbf4b6d
AM
9088 case CP0_REG23__USERTRACEDATA1:
9089 /* PDtrace support */
9090 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9091 register_name = "UserTraceData1";
3570d7f6 9092 goto cp0_unimplemented;
4cbf4b6d
AM
9093 case CP0_REG23__TRACEIBPC:
9094 /* PDtrace support */
9095 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9096 register_name = "TraceIBPC";
9097 goto cp0_unimplemented;
9098 case CP0_REG23__TRACEDBPC:
9099 /* PDtrace support */
9100 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9101 register_name = "TraceDBPC";
3570d7f6 9102 goto cp0_unimplemented;
9c2149c8 9103 default:
f31b035a 9104 goto cp0_unimplemented;
9c2149c8
TS
9105 }
9106 break;
04992c8c 9107 case CP0_REGISTER_24:
9c2149c8 9108 switch (sel) {
8d7b4b6e 9109 case CP0_REG24__DEPC:
f0b3f3ae 9110 /* EJTAG support */
7db13fae 9111 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 9112 register_name = "DEPC";
2423f660 9113 break;
9c2149c8 9114 default:
f31b035a 9115 goto cp0_unimplemented;
9c2149c8
TS
9116 }
9117 break;
04992c8c 9118 case CP0_REGISTER_25:
9c2149c8 9119 switch (sel) {
1176b328 9120 case CP0_REG25__PERFCTL0:
7db13fae 9121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 9122 register_name = "Performance0";
9c2149c8 9123 break;
1176b328 9124 case CP0_REG25__PERFCNT0:
7480515f 9125 /* gen_helper_dmfc0_performance1(arg); */
294fc2ea 9126 register_name = "Performance1";
3570d7f6 9127 goto cp0_unimplemented;
1176b328 9128 case CP0_REG25__PERFCTL1:
7480515f 9129 /* gen_helper_dmfc0_performance2(arg); */
294fc2ea 9130 register_name = "Performance2";
3570d7f6 9131 goto cp0_unimplemented;
1176b328 9132 case CP0_REG25__PERFCNT1:
7480515f 9133 /* gen_helper_dmfc0_performance3(arg); */
294fc2ea 9134 register_name = "Performance3";
3570d7f6 9135 goto cp0_unimplemented;
1176b328 9136 case CP0_REG25__PERFCTL2:
7480515f 9137 /* gen_helper_dmfc0_performance4(arg); */
294fc2ea 9138 register_name = "Performance4";
3570d7f6 9139 goto cp0_unimplemented;
1176b328 9140 case CP0_REG25__PERFCNT2:
7480515f 9141 /* gen_helper_dmfc0_performance5(arg); */
294fc2ea 9142 register_name = "Performance5";
3570d7f6 9143 goto cp0_unimplemented;
1176b328 9144 case CP0_REG25__PERFCTL3:
7480515f 9145 /* gen_helper_dmfc0_performance6(arg); */
294fc2ea 9146 register_name = "Performance6";
3570d7f6 9147 goto cp0_unimplemented;
1176b328 9148 case CP0_REG25__PERFCNT3:
7480515f 9149 /* gen_helper_dmfc0_performance7(arg); */
294fc2ea 9150 register_name = "Performance7";
3570d7f6 9151 goto cp0_unimplemented;
9c2149c8 9152 default:
f31b035a 9153 goto cp0_unimplemented;
9c2149c8
TS
9154 }
9155 break;
04992c8c 9156 case CP0_REGISTER_26:
0d74a222 9157 switch (sel) {
dbbf08b2 9158 case CP0_REG26__ERRCTL:
0d74a222 9159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 9160 register_name = "ErrCtl";
0d74a222
LA
9161 break;
9162 default:
9163 goto cp0_unimplemented;
9164 }
da80682b 9165 break;
04992c8c 9166 case CP0_REGISTER_27:
9c2149c8
TS
9167 switch (sel) {
9168 /* ignored */
5a10873d 9169 case CP0_REG27__CACHERR:
d9bea114 9170 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 9171 register_name = "CacheErr";
2423f660 9172 break;
9c2149c8 9173 default:
f31b035a 9174 goto cp0_unimplemented;
9c2149c8
TS
9175 }
9176 break;
04992c8c 9177 case CP0_REGISTER_28:
9c2149c8 9178 switch (sel) {
a30e2f21
AM
9179 case CP0_REG28__TAGLO:
9180 case CP0_REG28__TAGLO1:
9181 case CP0_REG28__TAGLO2:
9182 case CP0_REG28__TAGLO3:
7db13fae 9183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 9184 register_name = "TagLo";
9c2149c8 9185 break;
a30e2f21
AM
9186 case CP0_REG28__DATALO:
9187 case CP0_REG28__DATALO1:
9188 case CP0_REG28__DATALO2:
9189 case CP0_REG28__DATALO3:
7db13fae 9190 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 9191 register_name = "DataLo";
9c2149c8
TS
9192 break;
9193 default:
f31b035a 9194 goto cp0_unimplemented;
9c2149c8
TS
9195 }
9196 break;
04992c8c 9197 case CP0_REGISTER_29:
9c2149c8 9198 switch (sel) {
af4bb6da
AM
9199 case CP0_REG29__TAGHI:
9200 case CP0_REG29__TAGHI1:
9201 case CP0_REG29__TAGHI2:
9202 case CP0_REG29__TAGHI3:
7db13fae 9203 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 9204 register_name = "TagHi";
9c2149c8 9205 break;
af4bb6da
AM
9206 case CP0_REG29__DATAHI:
9207 case CP0_REG29__DATAHI1:
9208 case CP0_REG29__DATAHI2:
9209 case CP0_REG29__DATAHI3:
7db13fae 9210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 9211 register_name = "DataHi";
9c2149c8
TS
9212 break;
9213 default:
f31b035a 9214 goto cp0_unimplemented;
9c2149c8
TS
9215 }
9216 break;
04992c8c 9217 case CP0_REGISTER_30:
9c2149c8 9218 switch (sel) {
4bcf121e 9219 case CP0_REG30__ERROREPC:
7db13fae 9220 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 9221 register_name = "ErrorEPC";
2423f660 9222 break;
9c2149c8 9223 default:
f31b035a 9224 goto cp0_unimplemented;
9c2149c8
TS
9225 }
9226 break;
04992c8c 9227 case CP0_REGISTER_31:
9c2149c8 9228 switch (sel) {
14d92efd 9229 case CP0_REG31__DESAVE:
f0b3f3ae 9230 /* EJTAG support */
7db13fae 9231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 9232 register_name = "DESAVE";
2423f660 9233 break;
14d92efd
AM
9234 case CP0_REG31__KSCRATCH1:
9235 case CP0_REG31__KSCRATCH2:
9236 case CP0_REG31__KSCRATCH3:
9237 case CP0_REG31__KSCRATCH4:
9238 case CP0_REG31__KSCRATCH5:
9239 case CP0_REG31__KSCRATCH6:
f31b035a
LA
9240 CP0_CHECK(ctx->kscrexist & (1 << sel));
9241 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 9242 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 9243 register_name = "KScratch";
e98c0d17 9244 break;
9c2149c8 9245 default:
f31b035a 9246 goto cp0_unimplemented;
9c2149c8
TS
9247 }
9248 break;
9249 default:
f31b035a 9250 goto cp0_unimplemented;
9c2149c8 9251 }
294fc2ea 9252 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9c2149c8
TS
9253 return;
9254
f31b035a 9255cp0_unimplemented:
294fc2ea
AM
9256 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9257 register_name, reg, sel);
f31b035a 9258 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
9259}
9260
d75c135e 9261static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 9262{
294fc2ea 9263 const char *register_name = "invalid";
9c2149c8 9264
1f8929d2 9265 if (sel != 0) {
bbd5e4a2 9266 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 9267 }
e189e748 9268
eeb3bba8 9269 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 9270 gen_io_start();
bd79255d 9271 }
2e70f6ef 9272
9c2149c8 9273 switch (reg) {
04992c8c 9274 case CP0_REGISTER_00:
9c2149c8 9275 switch (sel) {
1b142da5 9276 case CP0_REG00__INDEX:
895c2d04 9277 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 9278 register_name = "Index";
9c2149c8 9279 break;
1b142da5 9280 case CP0_REG00__MVPCONTROL:
f31b035a 9281 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9282 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 9283 register_name = "MVPControl";
ead9360e 9284 break;
1b142da5 9285 case CP0_REG00__MVPCONF0:
f31b035a 9286 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 9287 /* ignored */
294fc2ea 9288 register_name = "MVPConf0";
ead9360e 9289 break;
1b142da5 9290 case CP0_REG00__MVPCONF1:
f31b035a 9291 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 9292 /* ignored */
294fc2ea 9293 register_name = "MVPConf1";
ead9360e 9294 break;
1b142da5 9295 case CP0_REG00__VPCONTROL:
01bc435b
YK
9296 CP0_CHECK(ctx->vp);
9297 /* ignored */
294fc2ea 9298 register_name = "VPControl";
01bc435b 9299 break;
9c2149c8 9300 default:
f31b035a 9301 goto cp0_unimplemented;
9c2149c8
TS
9302 }
9303 break;
04992c8c 9304 case CP0_REGISTER_01:
9c2149c8 9305 switch (sel) {
30deb460 9306 case CP0_REG01__RANDOM:
2423f660 9307 /* ignored */
294fc2ea 9308 register_name = "Random";
2423f660 9309 break;
30deb460 9310 case CP0_REG01__VPECONTROL:
f31b035a 9311 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9312 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 9313 register_name = "VPEControl";
ead9360e 9314 break;
30deb460 9315 case CP0_REG01__VPECONF0:
f31b035a 9316 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9317 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 9318 register_name = "VPEConf0";
ead9360e 9319 break;
30deb460 9320 case CP0_REG01__VPECONF1:
f31b035a 9321 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9322 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 9323 register_name = "VPEConf1";
ead9360e 9324 break;
30deb460 9325 case CP0_REG01__YQMASK:
f31b035a 9326 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9327 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 9328 register_name = "YQMask";
ead9360e 9329 break;
30deb460 9330 case CP0_REG01__VPESCHEDULE:
f31b035a 9331 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
9332 tcg_gen_st_tl(arg, cpu_env,
9333 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 9334 register_name = "VPESchedule";
ead9360e 9335 break;
30deb460 9336 case CP0_REG01__VPESCHEFBACK:
f31b035a 9337 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
9338 tcg_gen_st_tl(arg, cpu_env,
9339 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 9340 register_name = "VPEScheFBack";
ead9360e 9341 break;
30deb460 9342 case CP0_REG01__VPEOPT:
f31b035a 9343 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9344 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 9345 register_name = "VPEOpt";
ead9360e 9346 break;
9c2149c8 9347 default:
f31b035a 9348 goto cp0_unimplemented;
9c2149c8
TS
9349 }
9350 break;
04992c8c 9351 case CP0_REGISTER_02:
9c2149c8 9352 switch (sel) {
6d27d5bd 9353 case CP0_REG02__ENTRYLO0:
7207c7f9 9354 gen_helper_dmtc0_entrylo0(cpu_env, arg);
294fc2ea 9355 register_name = "EntryLo0";
2423f660 9356 break;
6d27d5bd 9357 case CP0_REG02__TCSTATUS:
f31b035a 9358 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9359 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 9360 register_name = "TCStatus";
ead9360e 9361 break;
6d27d5bd 9362 case CP0_REG02__TCBIND:
f31b035a 9363 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9364 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 9365 register_name = "TCBind";
ead9360e 9366 break;
6d27d5bd 9367 case CP0_REG02__TCRESTART:
f31b035a 9368 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9369 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 9370 register_name = "TCRestart";
ead9360e 9371 break;
6d27d5bd 9372 case CP0_REG02__TCHALT:
f31b035a 9373 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9374 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 9375 register_name = "TCHalt";
ead9360e 9376 break;
6d27d5bd 9377 case CP0_REG02__TCCONTEXT:
f31b035a 9378 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9379 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 9380 register_name = "TCContext";
ead9360e 9381 break;
6d27d5bd 9382 case CP0_REG02__TCSCHEDULE:
f31b035a 9383 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9384 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 9385 register_name = "TCSchedule";
ead9360e 9386 break;
6d27d5bd 9387 case CP0_REG02__TCSCHEFBACK:
f31b035a 9388 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9389 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 9390 register_name = "TCScheFBack";
ead9360e 9391 break;
9c2149c8 9392 default:
f31b035a 9393 goto cp0_unimplemented;
9c2149c8
TS
9394 }
9395 break;
04992c8c 9396 case CP0_REGISTER_03:
9c2149c8 9397 switch (sel) {
acd37316 9398 case CP0_REG03__ENTRYLO1:
7207c7f9 9399 gen_helper_dmtc0_entrylo1(cpu_env, arg);
294fc2ea 9400 register_name = "EntryLo1";
2423f660 9401 break;
acd37316 9402 case CP0_REG03__GLOBALNUM:
01bc435b
YK
9403 CP0_CHECK(ctx->vp);
9404 /* ignored */
294fc2ea 9405 register_name = "GlobalNumber";
01bc435b 9406 break;
9c2149c8 9407 default:
f31b035a 9408 goto cp0_unimplemented;
876d4b07 9409 }
9c2149c8 9410 break;
04992c8c 9411 case CP0_REGISTER_04:
9c2149c8 9412 switch (sel) {
020fe379 9413 case CP0_REG04__CONTEXT:
895c2d04 9414 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 9415 register_name = "Context";
2423f660 9416 break;
020fe379
AM
9417 case CP0_REG04__CONTEXTCONFIG:
9418 /* SmartMIPS ASE */
9419 /* gen_helper_dmtc0_contextconfig(arg); */
294fc2ea 9420 register_name = "ContextConfig";
f31b035a 9421 goto cp0_unimplemented;
020fe379 9422 case CP0_REG04__USERLOCAL:
f31b035a
LA
9423 CP0_CHECK(ctx->ulri);
9424 tcg_gen_st_tl(arg, cpu_env,
9425 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 9426 register_name = "UserLocal";
d279279e 9427 break;
99029be1
YK
9428 case CP0_REG04__MMID:
9429 CP0_CHECK(ctx->mi);
9430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
9431 register_name = "MMID";
9432 break;
9c2149c8 9433 default:
f31b035a 9434 goto cp0_unimplemented;
876d4b07 9435 }
9c2149c8 9436 break;
04992c8c 9437 case CP0_REGISTER_05:
9c2149c8 9438 switch (sel) {
a1e76353 9439 case CP0_REG05__PAGEMASK:
895c2d04 9440 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 9441 register_name = "PageMask";
2423f660 9442 break;
a1e76353 9443 case CP0_REG05__PAGEGRAIN:
7a47bae5 9444 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9445 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 9446 register_name = "PageGrain";
2423f660 9447 break;
a1e76353 9448 case CP0_REG05__SEGCTL0:
cec56a73
JH
9449 CP0_CHECK(ctx->sc);
9450 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 9451 register_name = "SegCtl0";
cec56a73 9452 break;
a1e76353 9453 case CP0_REG05__SEGCTL1:
cec56a73
JH
9454 CP0_CHECK(ctx->sc);
9455 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 9456 register_name = "SegCtl1";
cec56a73 9457 break;
a1e76353 9458 case CP0_REG05__SEGCTL2:
cec56a73
JH
9459 CP0_CHECK(ctx->sc);
9460 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 9461 register_name = "SegCtl2";
cec56a73 9462 break;
a1e76353 9463 case CP0_REG05__PWBASE:
5e31fdd5
YK
9464 check_pw(ctx);
9465 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 9466 register_name = "PWBase";
5e31fdd5 9467 break;
a1e76353 9468 case CP0_REG05__PWFIELD:
fa75ad14
YK
9469 check_pw(ctx);
9470 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 9471 register_name = "PWField";
fa75ad14 9472 break;
a1e76353 9473 case CP0_REG05__PWSIZE:
20b28ebc
YK
9474 check_pw(ctx);
9475 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 9476 register_name = "PWSize";
20b28ebc 9477 break;
9c2149c8 9478 default:
f31b035a 9479 goto cp0_unimplemented;
876d4b07 9480 }
9c2149c8 9481 break;
04992c8c 9482 case CP0_REGISTER_06:
9c2149c8 9483 switch (sel) {
9023594b 9484 case CP0_REG06__WIRED:
895c2d04 9485 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 9486 register_name = "Wired";
2423f660 9487 break;
9023594b 9488 case CP0_REG06__SRSCONF0:
7a47bae5 9489 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9490 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 9491 register_name = "SRSConf0";
ead9360e 9492 break;
9023594b 9493 case CP0_REG06__SRSCONF1:
7a47bae5 9494 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9495 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 9496 register_name = "SRSConf1";
ead9360e 9497 break;
9023594b 9498 case CP0_REG06__SRSCONF2:
7a47bae5 9499 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9500 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 9501 register_name = "SRSConf2";
ead9360e 9502 break;
9023594b 9503 case CP0_REG06__SRSCONF3:
7a47bae5 9504 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9505 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 9506 register_name = "SRSConf3";
ead9360e 9507 break;
9023594b 9508 case CP0_REG06__SRSCONF4:
7a47bae5 9509 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9510 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 9511 register_name = "SRSConf4";
ead9360e 9512 break;
9023594b 9513 case CP0_REG06__PWCTL:
103be64c
YK
9514 check_pw(ctx);
9515 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 9516 register_name = "PWCtl";
103be64c 9517 break;
9c2149c8 9518 default:
f31b035a 9519 goto cp0_unimplemented;
876d4b07 9520 }
9c2149c8 9521 break;
04992c8c 9522 case CP0_REGISTER_07:
9c2149c8 9523 switch (sel) {
143a9875 9524 case CP0_REG07__HWRENA:
7a47bae5 9525 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9526 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 9527 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9528 register_name = "HWREna";
2423f660 9529 break;
9c2149c8 9530 default:
f31b035a 9531 goto cp0_unimplemented;
876d4b07 9532 }
9c2149c8 9533 break;
04992c8c 9534 case CP0_REGISTER_08:
aea14095 9535 switch (sel) {
67d167d2 9536 case CP0_REG08__BADVADDR:
aea14095 9537 /* ignored */
294fc2ea 9538 register_name = "BadVAddr";
aea14095 9539 break;
67d167d2 9540 case CP0_REG08__BADINSTR:
aea14095 9541 /* ignored */
294fc2ea 9542 register_name = "BadInstr";
aea14095 9543 break;
67d167d2 9544 case CP0_REG08__BADINSTRP:
aea14095 9545 /* ignored */
294fc2ea 9546 register_name = "BadInstrP";
aea14095 9547 break;
67d167d2 9548 case CP0_REG08__BADINSTRX:
25beba9b 9549 /* ignored */
294fc2ea 9550 register_name = "BadInstrX";
25beba9b 9551 break;
aea14095 9552 default:
f31b035a 9553 goto cp0_unimplemented;
aea14095 9554 }
9c2149c8 9555 break;
04992c8c 9556 case CP0_REGISTER_09:
9c2149c8 9557 switch (sel) {
e5a98a72 9558 case CP0_REG09__COUNT:
895c2d04 9559 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 9560 register_name = "Count";
2423f660 9561 break;
e5a98a72 9562 case CP0_REG09__SAARI:
5fb2dcd1
YK
9563 CP0_CHECK(ctx->saar);
9564 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 9565 register_name = "SAARI";
5fb2dcd1 9566 break;
e5a98a72 9567 case CP0_REG09__SAAR:
5fb2dcd1
YK
9568 CP0_CHECK(ctx->saar);
9569 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 9570 register_name = "SAAR";
5fb2dcd1 9571 break;
9c2149c8 9572 default:
f31b035a 9573 goto cp0_unimplemented;
876d4b07
TS
9574 }
9575 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9576 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9577 break;
04992c8c 9578 case CP0_REGISTER_10:
9c2149c8 9579 switch (sel) {
860ffef0 9580 case CP0_REG10__ENTRYHI:
895c2d04 9581 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 9582 register_name = "EntryHi";
2423f660 9583 break;
9c2149c8 9584 default:
f31b035a 9585 goto cp0_unimplemented;
876d4b07 9586 }
9c2149c8 9587 break;
04992c8c 9588 case CP0_REGISTER_11:
9c2149c8 9589 switch (sel) {
f5f3834f 9590 case CP0_REG11__COMPARE:
895c2d04 9591 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 9592 register_name = "Compare";
2423f660 9593 break;
876d4b07 9594 /* 6,7 are implementation dependent */
9c2149c8 9595 default:
f31b035a 9596 goto cp0_unimplemented;
876d4b07 9597 }
de9a95f0 9598 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9599 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9600 break;
04992c8c 9601 case CP0_REGISTER_12:
9c2149c8 9602 switch (sel) {
2b084867 9603 case CP0_REG12__STATUS:
867abc7e 9604 save_cpu_state(ctx, 1);
895c2d04 9605 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 9606 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9607 gen_save_pc(ctx->base.pc_next + 4);
9608 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 9609 register_name = "Status";
2423f660 9610 break;
2b084867 9611 case CP0_REG12__INTCTL:
7a47bae5 9612 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9613 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 9614 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9615 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9616 register_name = "IntCtl";
2423f660 9617 break;
2b084867 9618 case CP0_REG12__SRSCTL:
7a47bae5 9619 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9620 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 9621 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9622 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9623 register_name = "SRSCtl";
2423f660 9624 break;
2b084867 9625 case CP0_REG12__SRSMAP:
7a47bae5 9626 check_insn(ctx, ISA_MIPS_R2);
7db13fae 9627 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 9628 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9629 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9630 register_name = "SRSMap";
2423f660
TS
9631 break;
9632 default:
f31b035a 9633 goto cp0_unimplemented;
876d4b07 9634 }
9c2149c8 9635 break;
04992c8c 9636 case CP0_REGISTER_13:
9c2149c8 9637 switch (sel) {
e3c7559d 9638 case CP0_REG13__CAUSE:
867abc7e 9639 save_cpu_state(ctx, 1);
895c2d04 9640 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
9641 /*
9642 * Stop translation as we may have triggered an interrupt.
b28425ba 9643 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
9644 * translated code to check for pending interrupts.
9645 */
eeb3bba8
EC
9646 gen_save_pc(ctx->base.pc_next + 4);
9647 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 9648 register_name = "Cause";
2423f660 9649 break;
9c2149c8 9650 default:
f31b035a 9651 goto cp0_unimplemented;
876d4b07 9652 }
9c2149c8 9653 break;
04992c8c 9654 case CP0_REGISTER_14:
9c2149c8 9655 switch (sel) {
35e4b54d 9656 case CP0_REG14__EPC:
7db13fae 9657 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 9658 register_name = "EPC";
2423f660 9659 break;
9c2149c8 9660 default:
f31b035a 9661 goto cp0_unimplemented;
876d4b07 9662 }
9c2149c8 9663 break;
04992c8c 9664 case CP0_REGISTER_15:
9c2149c8 9665 switch (sel) {
4466cd49 9666 case CP0_REG15__PRID:
2423f660 9667 /* ignored */
294fc2ea 9668 register_name = "PRid";
2423f660 9669 break;
4466cd49 9670 case CP0_REG15__EBASE:
7a47bae5 9671 check_insn(ctx, ISA_MIPS_R2);
895c2d04 9672 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 9673 register_name = "EBase";
2423f660 9674 break;
9c2149c8 9675 default:
f31b035a 9676 goto cp0_unimplemented;
876d4b07 9677 }
9c2149c8 9678 break;
04992c8c 9679 case CP0_REGISTER_16:
9c2149c8 9680 switch (sel) {
433efb4c 9681 case CP0_REG16__CONFIG:
895c2d04 9682 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 9683 register_name = "Config";
2423f660 9684 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9685 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9686 break;
433efb4c 9687 case CP0_REG16__CONFIG1:
1fc7bf6e 9688 /* ignored, read only */
294fc2ea 9689 register_name = "Config1";
9c2149c8 9690 break;
433efb4c 9691 case CP0_REG16__CONFIG2:
895c2d04 9692 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 9693 register_name = "Config2";
2423f660 9694 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9695 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9696 break;
433efb4c 9697 case CP0_REG16__CONFIG3:
90f12d73 9698 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 9699 register_name = "Config3";
90f12d73 9700 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9701 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9702 break;
433efb4c 9703 case CP0_REG16__CONFIG4:
faf1f68b 9704 /* currently ignored */
294fc2ea 9705 register_name = "Config4";
faf1f68b 9706 break;
433efb4c 9707 case CP0_REG16__CONFIG5:
faf1f68b 9708 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 9709 register_name = "Config5";
faf1f68b 9710 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9711 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 9712 break;
9c2149c8
TS
9713 /* 6,7 are implementation dependent */
9714 default:
294fc2ea 9715 register_name = "Invalid config selector";
f31b035a 9716 goto cp0_unimplemented;
9c2149c8 9717 }
9c2149c8 9718 break;
04992c8c 9719 case CP0_REGISTER_17:
9c2149c8 9720 switch (sel) {
706ce142 9721 case CP0_REG17__LLADDR:
895c2d04 9722 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 9723 register_name = "LLAddr";
2423f660 9724 break;
706ce142 9725 case CP0_REG17__MAAR:
f6d4dd81
YK
9726 CP0_CHECK(ctx->mrp);
9727 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 9728 register_name = "MAAR";
f6d4dd81 9729 break;
706ce142 9730 case CP0_REG17__MAARI:
f6d4dd81
YK
9731 CP0_CHECK(ctx->mrp);
9732 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 9733 register_name = "MAARI";
f6d4dd81 9734 break;
9c2149c8 9735 default:
f31b035a 9736 goto cp0_unimplemented;
9c2149c8
TS
9737 }
9738 break;
04992c8c 9739 case CP0_REGISTER_18:
9c2149c8 9740 switch (sel) {
e8dcfe82
AM
9741 case CP0_REG18__WATCHLO0:
9742 case CP0_REG18__WATCHLO1:
9743 case CP0_REG18__WATCHLO2:
9744 case CP0_REG18__WATCHLO3:
9745 case CP0_REG18__WATCHLO4:
9746 case CP0_REG18__WATCHLO5:
9747 case CP0_REG18__WATCHLO6:
9748 case CP0_REG18__WATCHLO7:
fa192d49 9749 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9750 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 9751 register_name = "WatchLo";
2423f660 9752 break;
9c2149c8 9753 default:
f31b035a 9754 goto cp0_unimplemented;
9c2149c8
TS
9755 }
9756 break;
04992c8c 9757 case CP0_REGISTER_19:
9c2149c8 9758 switch (sel) {
be274dc1
AM
9759 case CP0_REG19__WATCHHI0:
9760 case CP0_REG19__WATCHHI1:
9761 case CP0_REG19__WATCHHI2:
9762 case CP0_REG19__WATCHHI3:
9763 case CP0_REG19__WATCHHI4:
9764 case CP0_REG19__WATCHHI5:
9765 case CP0_REG19__WATCHHI6:
9766 case CP0_REG19__WATCHHI7:
fa192d49 9767 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9768 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 9769 register_name = "WatchHi";
2423f660 9770 break;
9c2149c8 9771 default:
f31b035a 9772 goto cp0_unimplemented;
9c2149c8
TS
9773 }
9774 break;
04992c8c 9775 case CP0_REGISTER_20:
9c2149c8 9776 switch (sel) {
14f92b0b 9777 case CP0_REG20__XCONTEXT:
d75c135e 9778 check_insn(ctx, ISA_MIPS3);
895c2d04 9779 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 9780 register_name = "XContext";
2423f660 9781 break;
9c2149c8 9782 default:
f31b035a 9783 goto cp0_unimplemented;
9c2149c8
TS
9784 }
9785 break;
04992c8c 9786 case CP0_REGISTER_21:
9c2149c8 9787 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 9788 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
9789 switch (sel) {
9790 case 0:
895c2d04 9791 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 9792 register_name = "Framemask";
2423f660 9793 break;
9c2149c8 9794 default:
f31b035a 9795 goto cp0_unimplemented;
9c2149c8
TS
9796 }
9797 break;
04992c8c 9798 case CP0_REGISTER_22:
9c2149c8 9799 /* ignored */
294fc2ea 9800 register_name = "Diagnostic"; /* implementation dependent */
876d4b07 9801 break;
04992c8c 9802 case CP0_REGISTER_23:
9c2149c8 9803 switch (sel) {
4cbf4b6d 9804 case CP0_REG23__DEBUG:
895c2d04 9805 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 9806 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9807 gen_save_pc(ctx->base.pc_next + 4);
9808 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 9809 register_name = "Debug";
2423f660 9810 break;
4cbf4b6d
AM
9811 case CP0_REG23__TRACECONTROL:
9812 /* PDtrace support */
9813 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8487327a 9814 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9815 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9816 register_name = "TraceControl";
3570d7f6 9817 goto cp0_unimplemented;
4cbf4b6d
AM
9818 case CP0_REG23__TRACECONTROL2:
9819 /* PDtrace support */
9820 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8487327a 9821 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9822 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9823 register_name = "TraceControl2";
3570d7f6 9824 goto cp0_unimplemented;
4cbf4b6d
AM
9825 case CP0_REG23__USERTRACEDATA1:
9826 /* PDtrace support */
9827 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8487327a 9828 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9829 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 9830 register_name = "UserTraceData1";
3570d7f6 9831 goto cp0_unimplemented;
4cbf4b6d
AM
9832 case CP0_REG23__TRACEIBPC:
9833 /* PDtrace support */
9834 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9835 /* Stop translation as we may have switched the execution mode */
9836 ctx->base.is_jmp = DISAS_STOP;
9837 register_name = "TraceIBPC";
9838 goto cp0_unimplemented;
9839 case CP0_REG23__TRACEDBPC:
9840 /* PDtrace support */
9841 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8487327a 9842 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9843 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 9844 register_name = "TraceDBPC";
3570d7f6 9845 goto cp0_unimplemented;
9c2149c8 9846 default:
f31b035a 9847 goto cp0_unimplemented;
9c2149c8 9848 }
9c2149c8 9849 break;
04992c8c 9850 case CP0_REGISTER_24:
9c2149c8 9851 switch (sel) {
8d7b4b6e 9852 case CP0_REG24__DEPC:
f1aa6320 9853 /* EJTAG support */
7db13fae 9854 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 9855 register_name = "DEPC";
2423f660 9856 break;
9c2149c8 9857 default:
f31b035a 9858 goto cp0_unimplemented;
9c2149c8
TS
9859 }
9860 break;
04992c8c 9861 case CP0_REGISTER_25:
9c2149c8 9862 switch (sel) {
1176b328 9863 case CP0_REG25__PERFCTL0:
895c2d04 9864 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 9865 register_name = "Performance0";
2423f660 9866 break;
1176b328 9867 case CP0_REG25__PERFCNT0:
7480515f 9868 /* gen_helper_mtc0_performance1(cpu_env, arg); */
294fc2ea 9869 register_name = "Performance1";
3570d7f6 9870 goto cp0_unimplemented;
1176b328 9871 case CP0_REG25__PERFCTL1:
7480515f 9872 /* gen_helper_mtc0_performance2(cpu_env, arg); */
294fc2ea 9873 register_name = "Performance2";
3570d7f6 9874 goto cp0_unimplemented;
1176b328 9875 case CP0_REG25__PERFCNT1:
7480515f 9876 /* gen_helper_mtc0_performance3(cpu_env, arg); */
294fc2ea 9877 register_name = "Performance3";
3570d7f6 9878 goto cp0_unimplemented;
1176b328 9879 case CP0_REG25__PERFCTL2:
7480515f 9880 /* gen_helper_mtc0_performance4(cpu_env, arg); */
294fc2ea 9881 register_name = "Performance4";
3570d7f6 9882 goto cp0_unimplemented;
1176b328 9883 case CP0_REG25__PERFCNT2:
7480515f 9884 /* gen_helper_mtc0_performance5(cpu_env, arg); */
294fc2ea 9885 register_name = "Performance5";
3570d7f6 9886 goto cp0_unimplemented;
1176b328 9887 case CP0_REG25__PERFCTL3:
7480515f 9888 /* gen_helper_mtc0_performance6(cpu_env, arg); */
294fc2ea 9889 register_name = "Performance6";
3570d7f6 9890 goto cp0_unimplemented;
1176b328 9891 case CP0_REG25__PERFCNT3:
7480515f 9892 /* gen_helper_mtc0_performance7(cpu_env, arg); */
294fc2ea 9893 register_name = "Performance7";
3570d7f6 9894 goto cp0_unimplemented;
9c2149c8 9895 default:
f31b035a 9896 goto cp0_unimplemented;
9c2149c8 9897 }
876d4b07 9898 break;
04992c8c 9899 case CP0_REGISTER_26:
0d74a222 9900 switch (sel) {
dbbf08b2 9901 case CP0_REG26__ERRCTL:
0d74a222 9902 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 9903 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 9904 register_name = "ErrCtl";
0d74a222
LA
9905 break;
9906 default:
9907 goto cp0_unimplemented;
9908 }
876d4b07 9909 break;
04992c8c 9910 case CP0_REGISTER_27:
9c2149c8 9911 switch (sel) {
5a10873d 9912 case CP0_REG27__CACHERR:
2423f660 9913 /* ignored */
294fc2ea 9914 register_name = "CacheErr";
2423f660 9915 break;
9c2149c8 9916 default:
f31b035a 9917 goto cp0_unimplemented;
9c2149c8 9918 }
876d4b07 9919 break;
04992c8c 9920 case CP0_REGISTER_28:
9c2149c8 9921 switch (sel) {
a30e2f21
AM
9922 case CP0_REG28__TAGLO:
9923 case CP0_REG28__TAGLO1:
9924 case CP0_REG28__TAGLO2:
9925 case CP0_REG28__TAGLO3:
895c2d04 9926 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 9927 register_name = "TagLo";
9c2149c8 9928 break;
a30e2f21
AM
9929 case CP0_REG28__DATALO:
9930 case CP0_REG28__DATALO1:
9931 case CP0_REG28__DATALO2:
9932 case CP0_REG28__DATALO3:
895c2d04 9933 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 9934 register_name = "DataLo";
9c2149c8
TS
9935 break;
9936 default:
f31b035a 9937 goto cp0_unimplemented;
9c2149c8
TS
9938 }
9939 break;
04992c8c 9940 case CP0_REGISTER_29:
9c2149c8 9941 switch (sel) {
af4bb6da
AM
9942 case CP0_REG29__TAGHI:
9943 case CP0_REG29__TAGHI1:
9944 case CP0_REG29__TAGHI2:
9945 case CP0_REG29__TAGHI3:
895c2d04 9946 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 9947 register_name = "TagHi";
9c2149c8 9948 break;
af4bb6da
AM
9949 case CP0_REG29__DATAHI:
9950 case CP0_REG29__DATAHI1:
9951 case CP0_REG29__DATAHI2:
9952 case CP0_REG29__DATAHI3:
895c2d04 9953 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 9954 register_name = "DataHi";
9c2149c8
TS
9955 break;
9956 default:
294fc2ea 9957 register_name = "invalid sel";
f31b035a 9958 goto cp0_unimplemented;
9c2149c8 9959 }
876d4b07 9960 break;
04992c8c 9961 case CP0_REGISTER_30:
9c2149c8 9962 switch (sel) {
4bcf121e 9963 case CP0_REG30__ERROREPC:
7db13fae 9964 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 9965 register_name = "ErrorEPC";
2423f660 9966 break;
9c2149c8 9967 default:
f31b035a 9968 goto cp0_unimplemented;
9c2149c8
TS
9969 }
9970 break;
04992c8c 9971 case CP0_REGISTER_31:
9c2149c8 9972 switch (sel) {
14d92efd 9973 case CP0_REG31__DESAVE:
f1aa6320 9974 /* EJTAG support */
7db13fae 9975 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 9976 register_name = "DESAVE";
2423f660 9977 break;
14d92efd
AM
9978 case CP0_REG31__KSCRATCH1:
9979 case CP0_REG31__KSCRATCH2:
9980 case CP0_REG31__KSCRATCH3:
9981 case CP0_REG31__KSCRATCH4:
9982 case CP0_REG31__KSCRATCH5:
9983 case CP0_REG31__KSCRATCH6:
f31b035a
LA
9984 CP0_CHECK(ctx->kscrexist & (1 << sel));
9985 tcg_gen_st_tl(arg, cpu_env,
71375b59 9986 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 9987 register_name = "KScratch";
e98c0d17 9988 break;
9c2149c8 9989 default:
f31b035a 9990 goto cp0_unimplemented;
9c2149c8 9991 }
9c2149c8
TS
9992 break;
9993 default:
f31b035a 9994 goto cp0_unimplemented;
9c2149c8 9995 }
294fc2ea 9996 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
b44a7fb1 9997
bf20dc07 9998 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 9999 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
10000 /*
10001 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10002 * translated code to check for pending interrupts.
10003 */
eeb3bba8
EC
10004 gen_save_pc(ctx->base.pc_next + 4);
10005 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 10006 }
9c2149c8
TS
10007 return;
10008
f31b035a 10009cp0_unimplemented:
294fc2ea
AM
10010 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
10011 register_name, reg, sel);
9c2149c8 10012}
d26bc211 10013#endif /* TARGET_MIPS64 */
9c2149c8 10014
7db13fae 10015static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
10016 int u, int sel, int h)
10017{
10018 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 10019 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
10020
10021 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 10022 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 10023 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
1a3fd9c3 10024 tcg_gen_movi_tl(t0, -1);
1f8929d2
AM
10025 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10026 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
1a3fd9c3 10027 tcg_gen_movi_tl(t0, -1);
1f8929d2 10028 } else if (u == 0) {
ead9360e 10029 switch (rt) {
5a25ce94
EI
10030 case 1:
10031 switch (sel) {
10032 case 1:
895c2d04 10033 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
10034 break;
10035 case 2:
895c2d04 10036 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
10037 break;
10038 default:
10039 goto die;
10040 break;
10041 }
10042 break;
ead9360e
TS
10043 case 2:
10044 switch (sel) {
10045 case 1:
895c2d04 10046 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
10047 break;
10048 case 2:
895c2d04 10049 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
10050 break;
10051 case 3:
895c2d04 10052 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
10053 break;
10054 case 4:
895c2d04 10055 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
10056 break;
10057 case 5:
895c2d04 10058 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
10059 break;
10060 case 6:
895c2d04 10061 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
10062 break;
10063 case 7:
895c2d04 10064 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
10065 break;
10066 default:
d75c135e 10067 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
10068 break;
10069 }
10070 break;
10071 case 10:
10072 switch (sel) {
10073 case 0:
895c2d04 10074 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
10075 break;
10076 default:
d75c135e 10077 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
10078 break;
10079 }
f1fadbb2 10080 break;
ead9360e
TS
10081 case 12:
10082 switch (sel) {
10083 case 0:
895c2d04 10084 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
10085 break;
10086 default:
d75c135e 10087 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
10088 break;
10089 }
f1fadbb2 10090 break;
5a25ce94
EI
10091 case 13:
10092 switch (sel) {
10093 case 0:
895c2d04 10094 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
10095 break;
10096 default:
10097 goto die;
10098 break;
10099 }
10100 break;
10101 case 14:
10102 switch (sel) {
10103 case 0:
895c2d04 10104 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
10105 break;
10106 default:
10107 goto die;
10108 break;
10109 }
10110 break;
10111 case 15:
10112 switch (sel) {
10113 case 1:
895c2d04 10114 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
10115 break;
10116 default:
10117 goto die;
10118 break;
10119 }
10120 break;
10121 case 16:
10122 switch (sel) {
c2e19f3c
AM
10123 case 0:
10124 case 1:
10125 case 2:
10126 case 3:
10127 case 4:
10128 case 5:
10129 case 6:
10130 case 7:
895c2d04 10131 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
10132 break;
10133 default:
10134 goto die;
10135 break;
10136 }
10137 break;
ead9360e
TS
10138 case 23:
10139 switch (sel) {
10140 case 0:
895c2d04 10141 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
10142 break;
10143 default:
d75c135e 10144 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
10145 break;
10146 }
10147 break;
10148 default:
d75c135e 10149 gen_mfc0(ctx, t0, rt, sel);
ead9360e 10150 }
71375b59
AM
10151 } else {
10152 switch (sel) {
10153 /* GPR registers. */
ead9360e 10154 case 0:
71375b59 10155 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e 10156 break;
71375b59 10157 /* Auxiliary CPU registers */
ead9360e 10158 case 1:
71375b59
AM
10159 switch (rt) {
10160 case 0:
10161 gen_helper_1e0i(mftlo, t0, 0);
10162 break;
10163 case 1:
10164 gen_helper_1e0i(mfthi, t0, 0);
10165 break;
10166 case 2:
10167 gen_helper_1e0i(mftacx, t0, 0);
10168 break;
10169 case 4:
10170 gen_helper_1e0i(mftlo, t0, 1);
10171 break;
10172 case 5:
10173 gen_helper_1e0i(mfthi, t0, 1);
10174 break;
10175 case 6:
10176 gen_helper_1e0i(mftacx, t0, 1);
10177 break;
10178 case 8:
10179 gen_helper_1e0i(mftlo, t0, 2);
10180 break;
10181 case 9:
10182 gen_helper_1e0i(mfthi, t0, 2);
10183 break;
10184 case 10:
10185 gen_helper_1e0i(mftacx, t0, 2);
10186 break;
10187 case 12:
10188 gen_helper_1e0i(mftlo, t0, 3);
10189 break;
10190 case 13:
10191 gen_helper_1e0i(mfthi, t0, 3);
10192 break;
10193 case 14:
10194 gen_helper_1e0i(mftacx, t0, 3);
10195 break;
10196 case 16:
10197 gen_helper_mftdsp(t0, cpu_env);
10198 break;
10199 default:
10200 goto die;
10201 }
ead9360e 10202 break;
71375b59 10203 /* Floating point (COP1). */
ead9360e 10204 case 2:
71375b59
AM
10205 /* XXX: For now we support only a single FPU context. */
10206 if (h == 0) {
10207 TCGv_i32 fp0 = tcg_temp_new_i32();
10208
10209 gen_load_fpr32(ctx, fp0, rt);
10210 tcg_gen_ext_i32_tl(t0, fp0);
10211 tcg_temp_free_i32(fp0);
10212 } else {
10213 TCGv_i32 fp0 = tcg_temp_new_i32();
10214
10215 gen_load_fpr32h(ctx, fp0, rt);
10216 tcg_gen_ext_i32_tl(t0, fp0);
10217 tcg_temp_free_i32(fp0);
10218 }
ead9360e 10219 break;
71375b59
AM
10220 case 3:
10221 /* XXX: For now we support only a single FPU context. */
10222 gen_helper_1e0i(cfc1, t0, rt);
ead9360e 10223 break;
71375b59
AM
10224 /* COP2: Not implemented. */
10225 case 4:
ead9360e 10226 case 5:
71375b59 10227 /* fall through */
ead9360e
TS
10228 default:
10229 goto die;
10230 }
ead9360e 10231 }
b44a7fb1 10232 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
10233 gen_store_gpr(t0, rd);
10234 tcg_temp_free(t0);
ead9360e
TS
10235 return;
10236
10237die:
1a3fd9c3 10238 tcg_temp_free(t0);
d12d51d5 10239 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
3a4ef3b7 10240 gen_reserved_instruction(ctx);
ead9360e
TS
10241}
10242
7db13fae 10243static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
10244 int u, int sel, int h)
10245{
10246 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 10247 TCGv t0 = tcg_temp_local_new();
ead9360e 10248
1a3fd9c3 10249 gen_load_gpr(t0, rt);
ead9360e 10250 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 10251 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 10252 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
7480515f
AM
10253 /* NOP */
10254 ;
1f8929d2
AM
10255 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10256 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
7480515f
AM
10257 /* NOP */
10258 ;
1f8929d2 10259 } else if (u == 0) {
ead9360e 10260 switch (rd) {
5a25ce94
EI
10261 case 1:
10262 switch (sel) {
10263 case 1:
895c2d04 10264 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
10265 break;
10266 case 2:
895c2d04 10267 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
10268 break;
10269 default:
10270 goto die;
10271 break;
10272 }
10273 break;
ead9360e
TS
10274 case 2:
10275 switch (sel) {
10276 case 1:
895c2d04 10277 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
10278 break;
10279 case 2:
895c2d04 10280 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
10281 break;
10282 case 3:
895c2d04 10283 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
10284 break;
10285 case 4:
895c2d04 10286 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
10287 break;
10288 case 5:
895c2d04 10289 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
10290 break;
10291 case 6:
895c2d04 10292 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
10293 break;
10294 case 7:
895c2d04 10295 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
10296 break;
10297 default:
d75c135e 10298 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
10299 break;
10300 }
10301 break;
10302 case 10:
10303 switch (sel) {
10304 case 0:
895c2d04 10305 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
10306 break;
10307 default:
d75c135e 10308 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
10309 break;
10310 }
0d0304f2 10311 break;
ead9360e
TS
10312 case 12:
10313 switch (sel) {
10314 case 0:
895c2d04 10315 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
10316 break;
10317 default:
d75c135e 10318 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
10319 break;
10320 }
0d0304f2 10321 break;
5a25ce94
EI
10322 case 13:
10323 switch (sel) {
10324 case 0:
895c2d04 10325 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
10326 break;
10327 default:
10328 goto die;
10329 break;
10330 }
10331 break;
10332 case 15:
10333 switch (sel) {
10334 case 1:
895c2d04 10335 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
10336 break;
10337 default:
10338 goto die;
10339 break;
10340 }
10341 break;
ead9360e
TS
10342 case 23:
10343 switch (sel) {
10344 case 0:
895c2d04 10345 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
10346 break;
10347 default:
d75c135e 10348 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
10349 break;
10350 }
10351 break;
10352 default:
d75c135e 10353 gen_mtc0(ctx, t0, rd, sel);
ead9360e 10354 }
71375b59
AM
10355 } else {
10356 switch (sel) {
10357 /* GPR registers. */
ead9360e 10358 case 0:
71375b59 10359 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e 10360 break;
71375b59 10361 /* Auxiliary CPU registers */
ead9360e 10362 case 1:
71375b59
AM
10363 switch (rd) {
10364 case 0:
10365 gen_helper_0e1i(mttlo, t0, 0);
10366 break;
10367 case 1:
10368 gen_helper_0e1i(mtthi, t0, 0);
10369 break;
10370 case 2:
10371 gen_helper_0e1i(mttacx, t0, 0);
10372 break;
10373 case 4:
10374 gen_helper_0e1i(mttlo, t0, 1);
10375 break;
10376 case 5:
10377 gen_helper_0e1i(mtthi, t0, 1);
10378 break;
10379 case 6:
10380 gen_helper_0e1i(mttacx, t0, 1);
10381 break;
10382 case 8:
10383 gen_helper_0e1i(mttlo, t0, 2);
10384 break;
10385 case 9:
10386 gen_helper_0e1i(mtthi, t0, 2);
10387 break;
10388 case 10:
10389 gen_helper_0e1i(mttacx, t0, 2);
10390 break;
10391 case 12:
10392 gen_helper_0e1i(mttlo, t0, 3);
10393 break;
10394 case 13:
10395 gen_helper_0e1i(mtthi, t0, 3);
10396 break;
10397 case 14:
10398 gen_helper_0e1i(mttacx, t0, 3);
10399 break;
10400 case 16:
10401 gen_helper_mttdsp(cpu_env, t0);
10402 break;
10403 default:
10404 goto die;
10405 }
ead9360e 10406 break;
71375b59 10407 /* Floating point (COP1). */
ead9360e 10408 case 2:
71375b59
AM
10409 /* XXX: For now we support only a single FPU context. */
10410 if (h == 0) {
10411 TCGv_i32 fp0 = tcg_temp_new_i32();
10412
10413 tcg_gen_trunc_tl_i32(fp0, t0);
10414 gen_store_fpr32(ctx, fp0, rd);
10415 tcg_temp_free_i32(fp0);
10416 } else {
10417 TCGv_i32 fp0 = tcg_temp_new_i32();
10418
10419 tcg_gen_trunc_tl_i32(fp0, t0);
10420 gen_store_fpr32h(ctx, fp0, rd);
10421 tcg_temp_free_i32(fp0);
10422 }
ead9360e 10423 break;
71375b59
AM
10424 case 3:
10425 /* XXX: For now we support only a single FPU context. */
10426 {
10427 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10428
10429 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10430 tcg_temp_free_i32(fs_tmp);
10431 }
10432 /* Stop translation as we may have changed hflags */
10433 ctx->base.is_jmp = DISAS_STOP;
ead9360e 10434 break;
71375b59
AM
10435 /* COP2: Not implemented. */
10436 case 4:
ead9360e 10437 case 5:
71375b59 10438 /* fall through */
ead9360e
TS
10439 default:
10440 goto die;
10441 }
ead9360e 10442 }
b44a7fb1 10443 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 10444 tcg_temp_free(t0);
ead9360e
TS
10445 return;
10446
10447die:
1a3fd9c3 10448 tcg_temp_free(t0);
d12d51d5 10449 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
3a4ef3b7 10450 gen_reserved_instruction(ctx);
ead9360e
TS
10451}
10452
235785e8
AM
10453static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10454 int rt, int rd)
6af0bf9c 10455{
287c4b84 10456 const char *opn = "ldst";
6af0bf9c 10457
2e15497c 10458 check_cp0_enabled(ctx);
6af0bf9c
FB
10459 switch (opc) {
10460 case OPC_MFC0:
10461 if (rt == 0) {
ead9360e 10462 /* Treat as NOP. */
6af0bf9c
FB
10463 return;
10464 }
d75c135e 10465 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
10466 opn = "mfc0";
10467 break;
10468 case OPC_MTC0:
1a3fd9c3 10469 {
1fc7bf6e 10470 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
10471
10472 gen_load_gpr(t0, rt);
d75c135e 10473 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
10474 tcg_temp_free(t0);
10475 }
6af0bf9c
FB
10476 opn = "mtc0";
10477 break;
d26bc211 10478#if defined(TARGET_MIPS64)
9c2149c8 10479 case OPC_DMFC0:
d75c135e 10480 check_insn(ctx, ISA_MIPS3);
9c2149c8 10481 if (rt == 0) {
ead9360e 10482 /* Treat as NOP. */
9c2149c8
TS
10483 return;
10484 }
d75c135e 10485 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
10486 opn = "dmfc0";
10487 break;
10488 case OPC_DMTC0:
d75c135e 10489 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 10490 {
1fc7bf6e 10491 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
10492
10493 gen_load_gpr(t0, rt);
d75c135e 10494 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
10495 tcg_temp_free(t0);
10496 }
9c2149c8
TS
10497 opn = "dmtc0";
10498 break;
534ce69f 10499#endif
5204ea79
LA
10500 case OPC_MFHC0:
10501 check_mvh(ctx);
10502 if (rt == 0) {
10503 /* Treat as NOP. */
10504 return;
10505 }
10506 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10507 opn = "mfhc0";
10508 break;
10509 case OPC_MTHC0:
10510 check_mvh(ctx);
10511 {
10512 TCGv t0 = tcg_temp_new();
10513 gen_load_gpr(t0, rt);
10514 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10515 tcg_temp_free(t0);
10516 }
10517 opn = "mthc0";
10518 break;
ead9360e 10519 case OPC_MFTR:
9affc1c5 10520 check_cp0_enabled(ctx);
ead9360e
TS
10521 if (rd == 0) {
10522 /* Treat as NOP. */
10523 return;
10524 }
6c5c1e20 10525 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 10526 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
10527 opn = "mftr";
10528 break;
10529 case OPC_MTTR:
9affc1c5 10530 check_cp0_enabled(ctx);
6c5c1e20 10531 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
10532 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10533 opn = "mttr";
10534 break;
6af0bf9c 10535 case OPC_TLBWI:
6af0bf9c 10536 opn = "tlbwi";
1f8929d2 10537 if (!env->tlb->helper_tlbwi) {
29929e34 10538 goto die;
1f8929d2 10539 }
895c2d04 10540 gen_helper_tlbwi(cpu_env);
6af0bf9c 10541 break;
9456c2fb
LA
10542 case OPC_TLBINV:
10543 opn = "tlbinv";
10544 if (ctx->ie >= 2) {
10545 if (!env->tlb->helper_tlbinv) {
10546 goto die;
10547 }
10548 gen_helper_tlbinv(cpu_env);
10549 } /* treat as nop if TLBINV not supported */
10550 break;
10551 case OPC_TLBINVF:
10552 opn = "tlbinvf";
10553 if (ctx->ie >= 2) {
10554 if (!env->tlb->helper_tlbinvf) {
10555 goto die;
10556 }
10557 gen_helper_tlbinvf(cpu_env);
10558 } /* treat as nop if TLBINV not supported */
10559 break;
6af0bf9c 10560 case OPC_TLBWR:
6af0bf9c 10561 opn = "tlbwr";
1f8929d2 10562 if (!env->tlb->helper_tlbwr) {
29929e34 10563 goto die;
1f8929d2 10564 }
895c2d04 10565 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
10566 break;
10567 case OPC_TLBP:
6af0bf9c 10568 opn = "tlbp";
1f8929d2 10569 if (!env->tlb->helper_tlbp) {
29929e34 10570 goto die;
1f8929d2 10571 }
895c2d04 10572 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
10573 break;
10574 case OPC_TLBR:
6af0bf9c 10575 opn = "tlbr";
1f8929d2 10576 if (!env->tlb->helper_tlbr) {
29929e34 10577 goto die;
1f8929d2 10578 }
895c2d04 10579 gen_helper_tlbr(cpu_env);
6af0bf9c 10580 break;
ce9782f4 10581 case OPC_ERET: /* OPC_ERETNC */
2e211e0a 10582 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 10583 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 10584 goto die;
ce9782f4
LA
10585 } else {
10586 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10587 if (ctx->opcode & (1 << bit_shift)) {
10588 /* OPC_ERETNC */
10589 opn = "eretnc";
5f89ce4f 10590 check_insn(ctx, ISA_MIPS_R5);
ce9782f4
LA
10591 gen_helper_eretnc(cpu_env);
10592 } else {
10593 /* OPC_ERET */
10594 opn = "eret";
10595 check_insn(ctx, ISA_MIPS2);
10596 gen_helper_eret(cpu_env);
10597 }
eeb3bba8 10598 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 10599 }
6af0bf9c
FB
10600 break;
10601 case OPC_DERET:
10602 opn = "deret";
bbd5e4a2 10603 check_insn(ctx, ISA_MIPS_R1);
2e211e0a 10604 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 10605 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10606 goto die;
10607 }
6af0bf9c 10608 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 10609 MIPS_INVAL(opn);
3a4ef3b7 10610 gen_reserved_instruction(ctx);
6af0bf9c 10611 } else {
895c2d04 10612 gen_helper_deret(cpu_env);
eeb3bba8 10613 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
10614 }
10615 break;
4ad40f36
FB
10616 case OPC_WAIT:
10617 opn = "wait";
bbd5e4a2 10618 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
2e211e0a 10619 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 10620 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10621 goto die;
10622 }
4ad40f36 10623 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 10624 ctx->base.pc_next += 4;
4ad40f36 10625 save_cpu_state(ctx, 1);
eeb3bba8 10626 ctx->base.pc_next -= 4;
895c2d04 10627 gen_helper_wait(cpu_env);
eeb3bba8 10628 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 10629 break;
6af0bf9c 10630 default:
29929e34 10631 die:
923617a3 10632 MIPS_INVAL(opn);
3a4ef3b7 10633 gen_reserved_instruction(ctx);
6af0bf9c
FB
10634 return;
10635 }
2abf314d 10636 (void)opn; /* avoid a compiler warning */
6af0bf9c 10637}
f1aa6320 10638#endif /* !CONFIG_USER_ONLY */
6af0bf9c 10639
6ea83fed 10640/* CP1 Branches (before delay slot) */
d75c135e
AJ
10641static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10642 int32_t cc, int32_t offset)
6ea83fed
FB
10643{
10644 target_ulong btarget;
a7812ae4 10645 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 10646
2e211e0a 10647 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 10648 gen_reserved_instruction(ctx);
339cd2a8
LA
10649 goto out;
10650 }
10651
1f8929d2 10652 if (cc != 0) {
bbd5e4a2 10653 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
1f8929d2 10654 }
e189e748 10655
eeb3bba8 10656 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 10657
7a387fff
TS
10658 switch (op) {
10659 case OPC_BC1F:
d94536f4
AJ
10660 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10661 tcg_gen_not_i32(t0, t0);
10662 tcg_gen_andi_i32(t0, t0, 1);
10663 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10664 goto not_likely;
7a387fff 10665 case OPC_BC1FL:
d94536f4
AJ
10666 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10667 tcg_gen_not_i32(t0, t0);
10668 tcg_gen_andi_i32(t0, t0, 1);
10669 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10670 goto likely;
7a387fff 10671 case OPC_BC1T:
d94536f4
AJ
10672 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10673 tcg_gen_andi_i32(t0, t0, 1);
10674 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 10675 goto not_likely;
7a387fff 10676 case OPC_BC1TL:
d94536f4
AJ
10677 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10678 tcg_gen_andi_i32(t0, t0, 1);
10679 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
10680 likely:
10681 ctx->hflags |= MIPS_HFLAG_BL;
10682 break;
5a5012ec 10683 case OPC_BC1FANY2:
a16336e4 10684 {
d94536f4
AJ
10685 TCGv_i32 t1 = tcg_temp_new_i32();
10686 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 10687 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 10688 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10689 tcg_temp_free_i32(t1);
d94536f4
AJ
10690 tcg_gen_andi_i32(t0, t0, 1);
10691 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10692 }
5a5012ec
TS
10693 goto not_likely;
10694 case OPC_BC1TANY2:
a16336e4 10695 {
d94536f4
AJ
10696 TCGv_i32 t1 = tcg_temp_new_i32();
10697 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 10698 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4
AJ
10699 tcg_gen_or_i32(t0, t0, t1);
10700 tcg_temp_free_i32(t1);
10701 tcg_gen_andi_i32(t0, t0, 1);
10702 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10703 }
5a5012ec
TS
10704 goto not_likely;
10705 case OPC_BC1FANY4:
a16336e4 10706 {
d94536f4
AJ
10707 TCGv_i32 t1 = tcg_temp_new_i32();
10708 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 10709 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 10710 tcg_gen_and_i32(t0, t0, t1);
71375b59 10711 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d7f66b52 10712 tcg_gen_and_i32(t0, t0, t1);
71375b59 10713 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d7f66b52 10714 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10715 tcg_temp_free_i32(t1);
d94536f4
AJ
10716 tcg_gen_andi_i32(t0, t0, 1);
10717 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10718 }
5a5012ec
TS
10719 goto not_likely;
10720 case OPC_BC1TANY4:
a16336e4 10721 {
d94536f4
AJ
10722 TCGv_i32 t1 = tcg_temp_new_i32();
10723 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 10724 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4 10725 tcg_gen_or_i32(t0, t0, t1);
71375b59 10726 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d94536f4 10727 tcg_gen_or_i32(t0, t0, t1);
71375b59 10728 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d94536f4
AJ
10729 tcg_gen_or_i32(t0, t0, t1);
10730 tcg_temp_free_i32(t1);
10731 tcg_gen_andi_i32(t0, t0, 1);
10732 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10733 }
5a5012ec
TS
10734 not_likely:
10735 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
10736 break;
10737 default:
9d68ac14 10738 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 10739 gen_reserved_instruction(ctx);
6c5c1e20 10740 goto out;
6ea83fed 10741 }
6ea83fed 10742 ctx->btarget = btarget;
b231c103 10743 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 10744 out:
a7812ae4 10745 tcg_temp_free_i32(t0);
6ea83fed
FB
10746}
10747
31837be3
YK
10748/* R6 CP1 Branches */
10749static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
10750 int32_t ft, int32_t offset,
10751 int delayslot_size)
31837be3
YK
10752{
10753 target_ulong btarget;
31837be3
YK
10754 TCGv_i64 t0 = tcg_temp_new_i64();
10755
10756 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10757#ifdef MIPS_DEBUG_DISAS
339cd2a8 10758 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10759 "\n", ctx->base.pc_next);
31837be3 10760#endif
3a4ef3b7 10761 gen_reserved_instruction(ctx);
31837be3
YK
10762 goto out;
10763 }
10764
10765 gen_load_fpr64(ctx, t0, ft);
10766 tcg_gen_andi_i64(t0, t0, 1);
10767
eeb3bba8 10768 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
10769
10770 switch (op) {
10771 case OPC_BC1EQZ:
10772 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
10773 ctx->hflags |= MIPS_HFLAG_BC;
10774 break;
10775 case OPC_BC1NEZ:
10776 /* t0 already set */
31837be3
YK
10777 ctx->hflags |= MIPS_HFLAG_BC;
10778 break;
10779 default:
9d68ac14 10780 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 10781 gen_reserved_instruction(ctx);
31837be3
YK
10782 goto out;
10783 }
10784
10785 tcg_gen_trunc_i64_tl(bcond, t0);
10786
31837be3 10787 ctx->btarget = btarget;
65935f07
YK
10788
10789 switch (delayslot_size) {
10790 case 2:
10791 ctx->hflags |= MIPS_HFLAG_BDS16;
10792 break;
10793 case 4:
10794 ctx->hflags |= MIPS_HFLAG_BDS32;
10795 break;
10796 }
31837be3
YK
10797
10798out:
10799 tcg_temp_free_i64(t0);
10800}
10801
6af0bf9c 10802/* Coprocessor 1 (FPU) */
5a5012ec 10803
5a5012ec
TS
10804#define FOP(func, fmt) (((fmt) << 21) | (func))
10805
bf4120ad
NF
10806enum fopcode {
10807 OPC_ADD_S = FOP(0, FMT_S),
10808 OPC_SUB_S = FOP(1, FMT_S),
10809 OPC_MUL_S = FOP(2, FMT_S),
10810 OPC_DIV_S = FOP(3, FMT_S),
10811 OPC_SQRT_S = FOP(4, FMT_S),
10812 OPC_ABS_S = FOP(5, FMT_S),
10813 OPC_MOV_S = FOP(6, FMT_S),
10814 OPC_NEG_S = FOP(7, FMT_S),
10815 OPC_ROUND_L_S = FOP(8, FMT_S),
10816 OPC_TRUNC_L_S = FOP(9, FMT_S),
10817 OPC_CEIL_L_S = FOP(10, FMT_S),
10818 OPC_FLOOR_L_S = FOP(11, FMT_S),
10819 OPC_ROUND_W_S = FOP(12, FMT_S),
10820 OPC_TRUNC_W_S = FOP(13, FMT_S),
10821 OPC_CEIL_W_S = FOP(14, FMT_S),
10822 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 10823 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
10824 OPC_MOVCF_S = FOP(17, FMT_S),
10825 OPC_MOVZ_S = FOP(18, FMT_S),
10826 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 10827 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
10828 OPC_RECIP_S = FOP(21, FMT_S),
10829 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
10830 OPC_SELNEZ_S = FOP(23, FMT_S),
10831 OPC_MADDF_S = FOP(24, FMT_S),
10832 OPC_MSUBF_S = FOP(25, FMT_S),
10833 OPC_RINT_S = FOP(26, FMT_S),
10834 OPC_CLASS_S = FOP(27, FMT_S),
10835 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 10836 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 10837 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 10838 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 10839 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 10840 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 10841 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
10842 OPC_RSQRT2_S = FOP(31, FMT_S),
10843 OPC_CVT_D_S = FOP(33, FMT_S),
10844 OPC_CVT_W_S = FOP(36, FMT_S),
10845 OPC_CVT_L_S = FOP(37, FMT_S),
10846 OPC_CVT_PS_S = FOP(38, FMT_S),
235785e8
AM
10847 OPC_CMP_F_S = FOP(48, FMT_S),
10848 OPC_CMP_UN_S = FOP(49, FMT_S),
10849 OPC_CMP_EQ_S = FOP(50, FMT_S),
10850 OPC_CMP_UEQ_S = FOP(51, FMT_S),
10851 OPC_CMP_OLT_S = FOP(52, FMT_S),
10852 OPC_CMP_ULT_S = FOP(53, FMT_S),
10853 OPC_CMP_OLE_S = FOP(54, FMT_S),
10854 OPC_CMP_ULE_S = FOP(55, FMT_S),
10855 OPC_CMP_SF_S = FOP(56, FMT_S),
10856 OPC_CMP_NGLE_S = FOP(57, FMT_S),
10857 OPC_CMP_SEQ_S = FOP(58, FMT_S),
10858 OPC_CMP_NGL_S = FOP(59, FMT_S),
10859 OPC_CMP_LT_S = FOP(60, FMT_S),
10860 OPC_CMP_NGE_S = FOP(61, FMT_S),
10861 OPC_CMP_LE_S = FOP(62, FMT_S),
10862 OPC_CMP_NGT_S = FOP(63, FMT_S),
bf4120ad
NF
10863
10864 OPC_ADD_D = FOP(0, FMT_D),
10865 OPC_SUB_D = FOP(1, FMT_D),
10866 OPC_MUL_D = FOP(2, FMT_D),
10867 OPC_DIV_D = FOP(3, FMT_D),
10868 OPC_SQRT_D = FOP(4, FMT_D),
10869 OPC_ABS_D = FOP(5, FMT_D),
10870 OPC_MOV_D = FOP(6, FMT_D),
10871 OPC_NEG_D = FOP(7, FMT_D),
10872 OPC_ROUND_L_D = FOP(8, FMT_D),
10873 OPC_TRUNC_L_D = FOP(9, FMT_D),
10874 OPC_CEIL_L_D = FOP(10, FMT_D),
10875 OPC_FLOOR_L_D = FOP(11, FMT_D),
10876 OPC_ROUND_W_D = FOP(12, FMT_D),
10877 OPC_TRUNC_W_D = FOP(13, FMT_D),
10878 OPC_CEIL_W_D = FOP(14, FMT_D),
10879 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 10880 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
10881 OPC_MOVCF_D = FOP(17, FMT_D),
10882 OPC_MOVZ_D = FOP(18, FMT_D),
10883 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 10884 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
10885 OPC_RECIP_D = FOP(21, FMT_D),
10886 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
10887 OPC_SELNEZ_D = FOP(23, FMT_D),
10888 OPC_MADDF_D = FOP(24, FMT_D),
10889 OPC_MSUBF_D = FOP(25, FMT_D),
10890 OPC_RINT_D = FOP(26, FMT_D),
10891 OPC_CLASS_D = FOP(27, FMT_D),
10892 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 10893 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 10894 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 10895 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 10896 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 10897 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 10898 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
10899 OPC_RSQRT2_D = FOP(31, FMT_D),
10900 OPC_CVT_S_D = FOP(32, FMT_D),
10901 OPC_CVT_W_D = FOP(36, FMT_D),
10902 OPC_CVT_L_D = FOP(37, FMT_D),
235785e8
AM
10903 OPC_CMP_F_D = FOP(48, FMT_D),
10904 OPC_CMP_UN_D = FOP(49, FMT_D),
10905 OPC_CMP_EQ_D = FOP(50, FMT_D),
10906 OPC_CMP_UEQ_D = FOP(51, FMT_D),
10907 OPC_CMP_OLT_D = FOP(52, FMT_D),
10908 OPC_CMP_ULT_D = FOP(53, FMT_D),
10909 OPC_CMP_OLE_D = FOP(54, FMT_D),
10910 OPC_CMP_ULE_D = FOP(55, FMT_D),
10911 OPC_CMP_SF_D = FOP(56, FMT_D),
10912 OPC_CMP_NGLE_D = FOP(57, FMT_D),
10913 OPC_CMP_SEQ_D = FOP(58, FMT_D),
10914 OPC_CMP_NGL_D = FOP(59, FMT_D),
10915 OPC_CMP_LT_D = FOP(60, FMT_D),
10916 OPC_CMP_NGE_D = FOP(61, FMT_D),
10917 OPC_CMP_LE_D = FOP(62, FMT_D),
10918 OPC_CMP_NGT_D = FOP(63, FMT_D),
bf4120ad
NF
10919
10920 OPC_CVT_S_W = FOP(32, FMT_W),
10921 OPC_CVT_D_W = FOP(33, FMT_W),
10922 OPC_CVT_S_L = FOP(32, FMT_L),
10923 OPC_CVT_D_L = FOP(33, FMT_L),
10924 OPC_CVT_PS_PW = FOP(38, FMT_W),
10925
10926 OPC_ADD_PS = FOP(0, FMT_PS),
10927 OPC_SUB_PS = FOP(1, FMT_PS),
10928 OPC_MUL_PS = FOP(2, FMT_PS),
10929 OPC_DIV_PS = FOP(3, FMT_PS),
10930 OPC_ABS_PS = FOP(5, FMT_PS),
10931 OPC_MOV_PS = FOP(6, FMT_PS),
10932 OPC_NEG_PS = FOP(7, FMT_PS),
10933 OPC_MOVCF_PS = FOP(17, FMT_PS),
10934 OPC_MOVZ_PS = FOP(18, FMT_PS),
10935 OPC_MOVN_PS = FOP(19, FMT_PS),
10936 OPC_ADDR_PS = FOP(24, FMT_PS),
10937 OPC_MULR_PS = FOP(26, FMT_PS),
10938 OPC_RECIP2_PS = FOP(28, FMT_PS),
10939 OPC_RECIP1_PS = FOP(29, FMT_PS),
10940 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10941 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10942
10943 OPC_CVT_S_PU = FOP(32, FMT_PS),
10944 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10945 OPC_CVT_S_PL = FOP(40, FMT_PS),
10946 OPC_PLL_PS = FOP(44, FMT_PS),
10947 OPC_PLU_PS = FOP(45, FMT_PS),
10948 OPC_PUL_PS = FOP(46, FMT_PS),
10949 OPC_PUU_PS = FOP(47, FMT_PS),
235785e8
AM
10950 OPC_CMP_F_PS = FOP(48, FMT_PS),
10951 OPC_CMP_UN_PS = FOP(49, FMT_PS),
10952 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10953 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10954 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10955 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10956 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10957 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10958 OPC_CMP_SF_PS = FOP(56, FMT_PS),
10959 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10960 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10961 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10962 OPC_CMP_LT_PS = FOP(60, FMT_PS),
10963 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10964 OPC_CMP_LE_PS = FOP(62, FMT_PS),
10965 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
bf4120ad
NF
10966};
10967
3f493883
YK
10968enum r6_f_cmp_op {
10969 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10970 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10971 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10972 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10973 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10974 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10975 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10976 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10977 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10978 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10979 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10980 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10981 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10982 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10983 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10984 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10985 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10986 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10987 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10988 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10989 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10990 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10991
10992 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10993 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10994 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10995 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10996 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10997 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10998 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10999 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
11000 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
11001 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
11002 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
11003 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
11004 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
11005 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
11006 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
11007 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
11008 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
11009 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
11010 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
11011 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
11012 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
11013 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
11014};
235785e8
AM
11015
11016static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 11017{
72c3a3ee 11018 TCGv t0 = tcg_temp_new();
6ea83fed
FB
11019
11020 switch (opc) {
11021 case OPC_MFC1:
b6d96bed 11022 {
a7812ae4 11023 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11024
7c979afd 11025 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 11026 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 11027 tcg_temp_free_i32(fp0);
6958549d 11028 }
6c5c1e20 11029 gen_store_gpr(t0, rt);
6ea83fed
FB
11030 break;
11031 case OPC_MTC1:
6c5c1e20 11032 gen_load_gpr(t0, rt);
b6d96bed 11033 {
a7812ae4 11034 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
11035
11036 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 11037 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 11038 tcg_temp_free_i32(fp0);
6958549d 11039 }
6ea83fed
FB
11040 break;
11041 case OPC_CFC1:
895c2d04 11042 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 11043 gen_store_gpr(t0, rt);
6ea83fed
FB
11044 break;
11045 case OPC_CTC1:
6c5c1e20 11046 gen_load_gpr(t0, rt);
9c708c7f 11047 save_cpu_state(ctx, 0);
736d120a
PJ
11048 {
11049 TCGv_i32 fs_tmp = tcg_const_i32(fs);
11050
11051 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
11052 tcg_temp_free_i32(fs_tmp);
11053 }
4cf8a45f 11054 /* Stop translation as we may have changed hflags */
eeb3bba8 11055 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 11056 break;
72c3a3ee 11057#if defined(TARGET_MIPS64)
9c2149c8 11058 case OPC_DMFC1:
72c3a3ee 11059 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 11060 gen_store_gpr(t0, rt);
5a5012ec 11061 break;
9c2149c8 11062 case OPC_DMTC1:
6c5c1e20 11063 gen_load_gpr(t0, rt);
72c3a3ee 11064 gen_store_fpr64(ctx, t0, fs);
5a5012ec 11065 break;
72c3a3ee 11066#endif
5a5012ec 11067 case OPC_MFHC1:
b6d96bed 11068 {
a7812ae4 11069 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11070
7f6613ce 11071 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 11072 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 11073 tcg_temp_free_i32(fp0);
6958549d 11074 }
6c5c1e20 11075 gen_store_gpr(t0, rt);
5a5012ec
TS
11076 break;
11077 case OPC_MTHC1:
6c5c1e20 11078 gen_load_gpr(t0, rt);
b6d96bed 11079 {
a7812ae4 11080 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
11081
11082 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 11083 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 11084 tcg_temp_free_i32(fp0);
6958549d 11085 }
5a5012ec 11086 break;
6ea83fed 11087 default:
9d68ac14 11088 MIPS_INVAL("cp1 move");
3a4ef3b7 11089 gen_reserved_instruction(ctx);
6c5c1e20 11090 goto out;
6ea83fed 11091 }
6c5c1e20
TS
11092
11093 out:
11094 tcg_temp_free(t0);
6ea83fed
FB
11095}
11096
235785e8 11097static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
5a5012ec 11098{
42a268c2 11099 TCGLabel *l1;
e214b9bb 11100 TCGCond cond;
af58f9ca
AJ
11101 TCGv_i32 t0;
11102
11103 if (rd == 0) {
11104 /* Treat as NOP. */
11105 return;
11106 }
6ea83fed 11107
1f8929d2 11108 if (tf) {
e214b9bb 11109 cond = TCG_COND_EQ;
1f8929d2 11110 } else {
27848470 11111 cond = TCG_COND_NE;
1f8929d2 11112 }
27848470 11113
af58f9ca
AJ
11114 l1 = gen_new_label();
11115 t0 = tcg_temp_new_i32();
fa31af0e 11116 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 11117 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 11118 tcg_temp_free_i32(t0);
af58f9ca
AJ
11119 if (rs == 0) {
11120 tcg_gen_movi_tl(cpu_gpr[rd], 0);
11121 } else {
11122 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
11123 }
e214b9bb 11124 gen_set_label(l1);
5a5012ec
TS
11125}
11126
7c979afd
LA
11127static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
11128 int tf)
a16336e4 11129{
a16336e4 11130 int cond;
cbc37b28 11131 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 11132 TCGLabel *l1 = gen_new_label();
a16336e4 11133
1f8929d2 11134 if (tf) {
a16336e4 11135 cond = TCG_COND_EQ;
1f8929d2 11136 } else {
a16336e4 11137 cond = TCG_COND_NE;
1f8929d2 11138 }
a16336e4 11139
fa31af0e 11140 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 11141 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
11142 gen_load_fpr32(ctx, t0, fs);
11143 gen_store_fpr32(ctx, t0, fd);
a16336e4 11144 gen_set_label(l1);
cbc37b28 11145 tcg_temp_free_i32(t0);
5a5012ec 11146}
a16336e4 11147
235785e8
AM
11148static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
11149 int tf)
a16336e4 11150{
a16336e4 11151 int cond;
cbc37b28
AJ
11152 TCGv_i32 t0 = tcg_temp_new_i32();
11153 TCGv_i64 fp0;
42a268c2 11154 TCGLabel *l1 = gen_new_label();
a16336e4 11155
1f8929d2 11156 if (tf) {
a16336e4 11157 cond = TCG_COND_EQ;
1f8929d2 11158 } else {
a16336e4 11159 cond = TCG_COND_NE;
1f8929d2 11160 }
a16336e4 11161
fa31af0e 11162 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 11163 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 11164 tcg_temp_free_i32(t0);
11f94258 11165 fp0 = tcg_temp_new_i64();
9bf3eb2c 11166 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 11167 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11168 tcg_temp_free_i64(fp0);
cbc37b28 11169 gen_set_label(l1);
a16336e4
TS
11170}
11171
7f6613ce
PJ
11172static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
11173 int cc, int tf)
a16336e4
TS
11174{
11175 int cond;
cbc37b28 11176 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
11177 TCGLabel *l1 = gen_new_label();
11178 TCGLabel *l2 = gen_new_label();
a16336e4 11179
1f8929d2 11180 if (tf) {
a16336e4 11181 cond = TCG_COND_EQ;
1f8929d2 11182 } else {
a16336e4 11183 cond = TCG_COND_NE;
1f8929d2 11184 }
a16336e4 11185
fa31af0e 11186 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 11187 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
11188 gen_load_fpr32(ctx, t0, fs);
11189 gen_store_fpr32(ctx, t0, fd);
a16336e4 11190 gen_set_label(l1);
9bf3eb2c 11191
71375b59 11192 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
cbc37b28 11193 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
11194 gen_load_fpr32h(ctx, t0, fs);
11195 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 11196 tcg_temp_free_i32(t0);
a16336e4 11197 gen_set_label(l2);
a16336e4
TS
11198}
11199
e7f16abb
LA
11200static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11201 int fs)
11202{
11203 TCGv_i32 t1 = tcg_const_i32(0);
11204 TCGv_i32 fp0 = tcg_temp_new_i32();
11205 TCGv_i32 fp1 = tcg_temp_new_i32();
11206 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11207 gen_load_fpr32(ctx, fp0, fd);
11208 gen_load_fpr32(ctx, fp1, ft);
11209 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
11210
11211 switch (op1) {
11212 case OPC_SEL_S:
11213 tcg_gen_andi_i32(fp0, fp0, 1);
11214 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11215 break;
11216 case OPC_SELEQZ_S:
11217 tcg_gen_andi_i32(fp1, fp1, 1);
11218 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11219 break;
11220 case OPC_SELNEZ_S:
11221 tcg_gen_andi_i32(fp1, fp1, 1);
11222 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11223 break;
11224 default:
11225 MIPS_INVAL("gen_sel_s");
3a4ef3b7 11226 gen_reserved_instruction(ctx);
e7f16abb
LA
11227 break;
11228 }
11229
7c979afd 11230 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11231 tcg_temp_free_i32(fp2);
11232 tcg_temp_free_i32(fp1);
11233 tcg_temp_free_i32(fp0);
11234 tcg_temp_free_i32(t1);
11235}
11236
11237static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11238 int fs)
11239{
11240 TCGv_i64 t1 = tcg_const_i64(0);
11241 TCGv_i64 fp0 = tcg_temp_new_i64();
11242 TCGv_i64 fp1 = tcg_temp_new_i64();
11243 TCGv_i64 fp2 = tcg_temp_new_i64();
11244 gen_load_fpr64(ctx, fp0, fd);
11245 gen_load_fpr64(ctx, fp1, ft);
11246 gen_load_fpr64(ctx, fp2, fs);
11247
11248 switch (op1) {
11249 case OPC_SEL_D:
11250 tcg_gen_andi_i64(fp0, fp0, 1);
11251 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11252 break;
11253 case OPC_SELEQZ_D:
11254 tcg_gen_andi_i64(fp1, fp1, 1);
11255 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11256 break;
11257 case OPC_SELNEZ_D:
11258 tcg_gen_andi_i64(fp1, fp1, 1);
11259 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11260 break;
11261 default:
11262 MIPS_INVAL("gen_sel_d");
3a4ef3b7 11263 gen_reserved_instruction(ctx);
e7f16abb
LA
11264 break;
11265 }
11266
11267 gen_store_fpr64(ctx, fp0, fd);
11268 tcg_temp_free_i64(fp2);
11269 tcg_temp_free_i64(fp1);
11270 tcg_temp_free_i64(fp0);
11271 tcg_temp_free_i64(t1);
11272}
6ea83fed 11273
235785e8
AM
11274static void gen_farith(DisasContext *ctx, enum fopcode op1,
11275 int ft, int fs, int fd, int cc)
6ea83fed 11276{
7a387fff 11277 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
11278 switch (op1) {
11279 case OPC_ADD_S:
b6d96bed 11280 {
a7812ae4
PB
11281 TCGv_i32 fp0 = tcg_temp_new_i32();
11282 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11283
7c979afd
LA
11284 gen_load_fpr32(ctx, fp0, fs);
11285 gen_load_fpr32(ctx, fp1, ft);
895c2d04 11286 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 11287 tcg_temp_free_i32(fp1);
7c979afd 11288 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11289 tcg_temp_free_i32(fp0);
b6d96bed 11290 }
5a5012ec 11291 break;
bf4120ad 11292 case OPC_SUB_S:
b6d96bed 11293 {
a7812ae4
PB
11294 TCGv_i32 fp0 = tcg_temp_new_i32();
11295 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11296
7c979afd
LA
11297 gen_load_fpr32(ctx, fp0, fs);
11298 gen_load_fpr32(ctx, fp1, ft);
895c2d04 11299 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 11300 tcg_temp_free_i32(fp1);
7c979afd 11301 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11302 tcg_temp_free_i32(fp0);
b6d96bed 11303 }
5a5012ec 11304 break;
bf4120ad 11305 case OPC_MUL_S:
b6d96bed 11306 {
a7812ae4
PB
11307 TCGv_i32 fp0 = tcg_temp_new_i32();
11308 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11309
7c979afd
LA
11310 gen_load_fpr32(ctx, fp0, fs);
11311 gen_load_fpr32(ctx, fp1, ft);
895c2d04 11312 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 11313 tcg_temp_free_i32(fp1);
7c979afd 11314 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11315 tcg_temp_free_i32(fp0);
b6d96bed 11316 }
5a5012ec 11317 break;
bf4120ad 11318 case OPC_DIV_S:
b6d96bed 11319 {
a7812ae4
PB
11320 TCGv_i32 fp0 = tcg_temp_new_i32();
11321 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11322
7c979afd
LA
11323 gen_load_fpr32(ctx, fp0, fs);
11324 gen_load_fpr32(ctx, fp1, ft);
895c2d04 11325 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 11326 tcg_temp_free_i32(fp1);
7c979afd 11327 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11328 tcg_temp_free_i32(fp0);
b6d96bed 11329 }
5a5012ec 11330 break;
bf4120ad 11331 case OPC_SQRT_S:
b6d96bed 11332 {
a7812ae4 11333 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11334
7c979afd 11335 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11336 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 11337 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11338 tcg_temp_free_i32(fp0);
b6d96bed 11339 }
5a5012ec 11340 break;
bf4120ad 11341 case OPC_ABS_S:
b6d96bed 11342 {
a7812ae4 11343 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11344
7c979afd 11345 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
11346 if (ctx->abs2008) {
11347 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11348 } else {
11349 gen_helper_float_abs_s(fp0, fp0);
11350 }
7c979afd 11351 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11352 tcg_temp_free_i32(fp0);
b6d96bed 11353 }
5a5012ec 11354 break;
bf4120ad 11355 case OPC_MOV_S:
b6d96bed 11356 {
a7812ae4 11357 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11358
7c979afd
LA
11359 gen_load_fpr32(ctx, fp0, fs);
11360 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11361 tcg_temp_free_i32(fp0);
b6d96bed 11362 }
5a5012ec 11363 break;
bf4120ad 11364 case OPC_NEG_S:
b6d96bed 11365 {
a7812ae4 11366 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11367
7c979afd 11368 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
11369 if (ctx->abs2008) {
11370 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11371 } else {
11372 gen_helper_float_chs_s(fp0, fp0);
11373 }
7c979afd 11374 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11375 tcg_temp_free_i32(fp0);
b6d96bed 11376 }
5a5012ec 11377 break;
bf4120ad 11378 case OPC_ROUND_L_S:
5e755519 11379 check_cp1_64bitmode(ctx);
b6d96bed 11380 {
a7812ae4
PB
11381 TCGv_i32 fp32 = tcg_temp_new_i32();
11382 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11383
7c979afd 11384 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11385 if (ctx->nan2008) {
11386 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11387 } else {
11388 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11389 }
a7812ae4 11390 tcg_temp_free_i32(fp32);
b6d96bed 11391 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11392 tcg_temp_free_i64(fp64);
b6d96bed 11393 }
5a5012ec 11394 break;
bf4120ad 11395 case OPC_TRUNC_L_S:
5e755519 11396 check_cp1_64bitmode(ctx);
b6d96bed 11397 {
a7812ae4
PB
11398 TCGv_i32 fp32 = tcg_temp_new_i32();
11399 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11400
7c979afd 11401 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11402 if (ctx->nan2008) {
11403 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11404 } else {
11405 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11406 }
a7812ae4 11407 tcg_temp_free_i32(fp32);
b6d96bed 11408 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11409 tcg_temp_free_i64(fp64);
b6d96bed 11410 }
5a5012ec 11411 break;
bf4120ad 11412 case OPC_CEIL_L_S:
5e755519 11413 check_cp1_64bitmode(ctx);
b6d96bed 11414 {
a7812ae4
PB
11415 TCGv_i32 fp32 = tcg_temp_new_i32();
11416 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11417
7c979afd 11418 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11419 if (ctx->nan2008) {
11420 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11421 } else {
11422 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11423 }
a7812ae4 11424 tcg_temp_free_i32(fp32);
b6d96bed 11425 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11426 tcg_temp_free_i64(fp64);
b6d96bed 11427 }
5a5012ec 11428 break;
bf4120ad 11429 case OPC_FLOOR_L_S:
5e755519 11430 check_cp1_64bitmode(ctx);
b6d96bed 11431 {
a7812ae4
PB
11432 TCGv_i32 fp32 = tcg_temp_new_i32();
11433 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11434
7c979afd 11435 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11436 if (ctx->nan2008) {
11437 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11438 } else {
11439 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11440 }
a7812ae4 11441 tcg_temp_free_i32(fp32);
b6d96bed 11442 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11443 tcg_temp_free_i64(fp64);
b6d96bed 11444 }
5a5012ec 11445 break;
bf4120ad 11446 case OPC_ROUND_W_S:
b6d96bed 11447 {
a7812ae4 11448 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11449
7c979afd 11450 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11451 if (ctx->nan2008) {
11452 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11453 } else {
11454 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11455 }
7c979afd 11456 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11457 tcg_temp_free_i32(fp0);
b6d96bed 11458 }
5a5012ec 11459 break;
bf4120ad 11460 case OPC_TRUNC_W_S:
b6d96bed 11461 {
a7812ae4 11462 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11463
7c979afd 11464 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11465 if (ctx->nan2008) {
11466 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11467 } else {
11468 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11469 }
7c979afd 11470 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11471 tcg_temp_free_i32(fp0);
b6d96bed 11472 }
5a5012ec 11473 break;
bf4120ad 11474 case OPC_CEIL_W_S:
b6d96bed 11475 {
a7812ae4 11476 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11477
7c979afd 11478 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11479 if (ctx->nan2008) {
11480 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11481 } else {
11482 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11483 }
7c979afd 11484 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11485 tcg_temp_free_i32(fp0);
b6d96bed 11486 }
5a5012ec 11487 break;
bf4120ad 11488 case OPC_FLOOR_W_S:
b6d96bed 11489 {
a7812ae4 11490 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11491
7c979afd 11492 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11493 if (ctx->nan2008) {
11494 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11495 } else {
11496 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11497 }
7c979afd 11498 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11499 tcg_temp_free_i32(fp0);
b6d96bed 11500 }
5a5012ec 11501 break;
e7f16abb 11502 case OPC_SEL_S:
2e211e0a 11503 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 11504 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11505 break;
11506 case OPC_SELEQZ_S:
2e211e0a 11507 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 11508 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11509 break;
11510 case OPC_SELNEZ_S:
2e211e0a 11511 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 11512 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 11513 break;
bf4120ad 11514 case OPC_MOVCF_S:
2e211e0a 11515 check_insn_opc_removed(ctx, ISA_MIPS_R6);
7c979afd 11516 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 11517 break;
bf4120ad 11518 case OPC_MOVZ_S:
2e211e0a 11519 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 11520 {
42a268c2 11521 TCGLabel *l1 = gen_new_label();
c9297f4d 11522 TCGv_i32 fp0;
a16336e4 11523
c9297f4d
AJ
11524 if (ft != 0) {
11525 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11526 }
11527 fp0 = tcg_temp_new_i32();
7c979afd
LA
11528 gen_load_fpr32(ctx, fp0, fs);
11529 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11530 tcg_temp_free_i32(fp0);
a16336e4
TS
11531 gen_set_label(l1);
11532 }
5a5012ec 11533 break;
bf4120ad 11534 case OPC_MOVN_S:
2e211e0a 11535 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 11536 {
42a268c2 11537 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11538 TCGv_i32 fp0;
11539
11540 if (ft != 0) {
11541 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11542 fp0 = tcg_temp_new_i32();
7c979afd
LA
11543 gen_load_fpr32(ctx, fp0, fs);
11544 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
11545 tcg_temp_free_i32(fp0);
11546 gen_set_label(l1);
11547 }
a16336e4 11548 }
5a5012ec 11549 break;
bf4120ad 11550 case OPC_RECIP_S:
b6d96bed 11551 {
a7812ae4 11552 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11553
7c979afd 11554 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11555 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 11556 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11557 tcg_temp_free_i32(fp0);
b6d96bed 11558 }
57fa1fb3 11559 break;
bf4120ad 11560 case OPC_RSQRT_S:
b6d96bed 11561 {
a7812ae4 11562 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11563
7c979afd 11564 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11565 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 11566 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11567 tcg_temp_free_i32(fp0);
b6d96bed 11568 }
57fa1fb3 11569 break;
e7f16abb 11570 case OPC_MADDF_S:
2e211e0a 11571 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 11572 {
a7812ae4
PB
11573 TCGv_i32 fp0 = tcg_temp_new_i32();
11574 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11575 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11576 gen_load_fpr32(ctx, fp0, fs);
11577 gen_load_fpr32(ctx, fp1, ft);
11578 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11579 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11580 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 11581 tcg_temp_free_i32(fp2);
a7812ae4 11582 tcg_temp_free_i32(fp1);
a7812ae4 11583 tcg_temp_free_i32(fp0);
b6d96bed 11584 }
57fa1fb3 11585 break;
e7f16abb 11586 case OPC_MSUBF_S:
2e211e0a 11587 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 11588 {
a7812ae4 11589 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
11590 TCGv_i32 fp1 = tcg_temp_new_i32();
11591 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11592 gen_load_fpr32(ctx, fp0, fs);
11593 gen_load_fpr32(ctx, fp1, ft);
11594 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11595 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11596 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11597 tcg_temp_free_i32(fp2);
11598 tcg_temp_free_i32(fp1);
a7812ae4 11599 tcg_temp_free_i32(fp0);
b6d96bed 11600 }
57fa1fb3 11601 break;
e7f16abb 11602 case OPC_RINT_S:
2e211e0a 11603 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 11604 {
a7812ae4 11605 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11606 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11607 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 11608 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11609 tcg_temp_free_i32(fp0);
b6d96bed 11610 }
57fa1fb3 11611 break;
e7f16abb 11612 case OPC_CLASS_S:
2e211e0a 11613 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 11614 {
e7f16abb 11615 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11616 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 11617 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 11618 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 11619 tcg_temp_free_i32(fp0);
e7f16abb
LA
11620 }
11621 break;
11622 case OPC_MIN_S: /* OPC_RECIP2_S */
2e211e0a 11623 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 11624 /* OPC_MIN_S */
a7812ae4
PB
11625 TCGv_i32 fp0 = tcg_temp_new_i32();
11626 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11627 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11628 gen_load_fpr32(ctx, fp0, fs);
11629 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11630 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 11631 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11632 tcg_temp_free_i32(fp2);
11633 tcg_temp_free_i32(fp1);
11634 tcg_temp_free_i32(fp0);
e7f16abb
LA
11635 } else {
11636 /* OPC_RECIP2_S */
11637 check_cp1_64bitmode(ctx);
11638 {
11639 TCGv_i32 fp0 = tcg_temp_new_i32();
11640 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11641
7c979afd
LA
11642 gen_load_fpr32(ctx, fp0, fs);
11643 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11644 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11645 tcg_temp_free_i32(fp1);
7c979afd 11646 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11647 tcg_temp_free_i32(fp0);
11648 }
e7f16abb
LA
11649 }
11650 break;
11651 case OPC_MINA_S: /* OPC_RECIP1_S */
2e211e0a 11652 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
11653 /* OPC_MINA_S */
11654 TCGv_i32 fp0 = tcg_temp_new_i32();
11655 TCGv_i32 fp1 = tcg_temp_new_i32();
11656 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11657 gen_load_fpr32(ctx, fp0, fs);
11658 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11659 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 11660 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11661 tcg_temp_free_i32(fp2);
11662 tcg_temp_free_i32(fp1);
11663 tcg_temp_free_i32(fp0);
e7f16abb
LA
11664 } else {
11665 /* OPC_RECIP1_S */
11666 check_cp1_64bitmode(ctx);
11667 {
11668 TCGv_i32 fp0 = tcg_temp_new_i32();
11669
7c979afd 11670 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11671 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 11672 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11673 tcg_temp_free_i32(fp0);
11674 }
e7f16abb
LA
11675 }
11676 break;
11677 case OPC_MAX_S: /* OPC_RSQRT1_S */
2e211e0a 11678 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
11679 /* OPC_MAX_S */
11680 TCGv_i32 fp0 = tcg_temp_new_i32();
11681 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11682 gen_load_fpr32(ctx, fp0, fs);
11683 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11684 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 11685 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
11686 tcg_temp_free_i32(fp1);
11687 tcg_temp_free_i32(fp0);
e7f16abb
LA
11688 } else {
11689 /* OPC_RSQRT1_S */
11690 check_cp1_64bitmode(ctx);
11691 {
11692 TCGv_i32 fp0 = tcg_temp_new_i32();
11693
7c979afd 11694 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11695 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 11696 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11697 tcg_temp_free_i32(fp0);
11698 }
e7f16abb
LA
11699 }
11700 break;
11701 case OPC_MAXA_S: /* OPC_RSQRT2_S */
2e211e0a 11702 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
11703 /* OPC_MAXA_S */
11704 TCGv_i32 fp0 = tcg_temp_new_i32();
11705 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11706 gen_load_fpr32(ctx, fp0, fs);
11707 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11708 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 11709 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 11710 tcg_temp_free_i32(fp1);
a7812ae4 11711 tcg_temp_free_i32(fp0);
e7f16abb
LA
11712 } else {
11713 /* OPC_RSQRT2_S */
11714 check_cp1_64bitmode(ctx);
11715 {
11716 TCGv_i32 fp0 = tcg_temp_new_i32();
11717 TCGv_i32 fp1 = tcg_temp_new_i32();
11718
7c979afd
LA
11719 gen_load_fpr32(ctx, fp0, fs);
11720 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11721 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11722 tcg_temp_free_i32(fp1);
7c979afd 11723 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11724 tcg_temp_free_i32(fp0);
11725 }
b6d96bed 11726 }
57fa1fb3 11727 break;
bf4120ad 11728 case OPC_CVT_D_S:
5e755519 11729 check_cp1_registers(ctx, fd);
b6d96bed 11730 {
a7812ae4
PB
11731 TCGv_i32 fp32 = tcg_temp_new_i32();
11732 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11733
7c979afd 11734 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11735 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 11736 tcg_temp_free_i32(fp32);
b6d96bed 11737 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11738 tcg_temp_free_i64(fp64);
b6d96bed 11739 }
5a5012ec 11740 break;
bf4120ad 11741 case OPC_CVT_W_S:
b6d96bed 11742 {
a7812ae4 11743 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11744
7c979afd 11745 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11746 if (ctx->nan2008) {
11747 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11748 } else {
11749 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11750 }
7c979afd 11751 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11752 tcg_temp_free_i32(fp0);
b6d96bed 11753 }
5a5012ec 11754 break;
bf4120ad 11755 case OPC_CVT_L_S:
5e755519 11756 check_cp1_64bitmode(ctx);
b6d96bed 11757 {
a7812ae4
PB
11758 TCGv_i32 fp32 = tcg_temp_new_i32();
11759 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11760
7c979afd 11761 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11762 if (ctx->nan2008) {
11763 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11764 } else {
11765 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11766 }
a7812ae4 11767 tcg_temp_free_i32(fp32);
b6d96bed 11768 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11769 tcg_temp_free_i64(fp64);
b6d96bed 11770 }
5a5012ec 11771 break;
bf4120ad 11772 case OPC_CVT_PS_S:
e29c9628 11773 check_ps(ctx);
b6d96bed 11774 {
a7812ae4
PB
11775 TCGv_i64 fp64 = tcg_temp_new_i64();
11776 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11777 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 11778
7c979afd
LA
11779 gen_load_fpr32(ctx, fp32_0, fs);
11780 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 11781 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
11782 tcg_temp_free_i32(fp32_1);
11783 tcg_temp_free_i32(fp32_0);
36aa55dc 11784 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11785 tcg_temp_free_i64(fp64);
b6d96bed 11786 }
5a5012ec 11787 break;
bf4120ad
NF
11788 case OPC_CMP_F_S:
11789 case OPC_CMP_UN_S:
11790 case OPC_CMP_EQ_S:
11791 case OPC_CMP_UEQ_S:
11792 case OPC_CMP_OLT_S:
11793 case OPC_CMP_ULT_S:
11794 case OPC_CMP_OLE_S:
11795 case OPC_CMP_ULE_S:
11796 case OPC_CMP_SF_S:
11797 case OPC_CMP_NGLE_S:
11798 case OPC_CMP_SEQ_S:
11799 case OPC_CMP_NGL_S:
11800 case OPC_CMP_LT_S:
11801 case OPC_CMP_NGE_S:
11802 case OPC_CMP_LE_S:
11803 case OPC_CMP_NGT_S:
2e211e0a 11804 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 11805 if (ctx->opcode & (1 << 6)) {
71375b59 11806 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
8153667c 11807 } else {
71375b59 11808 gen_cmp_s(ctx, func - 48, ft, fs, cc);
5a1e8ffb 11809 }
5a5012ec 11810 break;
bf4120ad 11811 case OPC_ADD_D:
5e755519 11812 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11813 {
a7812ae4
PB
11814 TCGv_i64 fp0 = tcg_temp_new_i64();
11815 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11816
11817 gen_load_fpr64(ctx, fp0, fs);
11818 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11819 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11820 tcg_temp_free_i64(fp1);
b6d96bed 11821 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11822 tcg_temp_free_i64(fp0);
b6d96bed 11823 }
6ea83fed 11824 break;
bf4120ad 11825 case OPC_SUB_D:
5e755519 11826 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11827 {
a7812ae4
PB
11828 TCGv_i64 fp0 = tcg_temp_new_i64();
11829 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11830
11831 gen_load_fpr64(ctx, fp0, fs);
11832 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11833 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11834 tcg_temp_free_i64(fp1);
b6d96bed 11835 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11836 tcg_temp_free_i64(fp0);
b6d96bed 11837 }
6ea83fed 11838 break;
bf4120ad 11839 case OPC_MUL_D:
5e755519 11840 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11841 {
a7812ae4
PB
11842 TCGv_i64 fp0 = tcg_temp_new_i64();
11843 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11844
11845 gen_load_fpr64(ctx, fp0, fs);
11846 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11847 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11848 tcg_temp_free_i64(fp1);
b6d96bed 11849 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11850 tcg_temp_free_i64(fp0);
b6d96bed 11851 }
6ea83fed 11852 break;
bf4120ad 11853 case OPC_DIV_D:
5e755519 11854 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11855 {
a7812ae4
PB
11856 TCGv_i64 fp0 = tcg_temp_new_i64();
11857 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11858
11859 gen_load_fpr64(ctx, fp0, fs);
11860 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11861 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11862 tcg_temp_free_i64(fp1);
b6d96bed 11863 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11864 tcg_temp_free_i64(fp0);
b6d96bed 11865 }
6ea83fed 11866 break;
bf4120ad 11867 case OPC_SQRT_D:
5e755519 11868 check_cp1_registers(ctx, fs | fd);
b6d96bed 11869 {
a7812ae4 11870 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11871
11872 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11873 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 11874 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11875 tcg_temp_free_i64(fp0);
b6d96bed 11876 }
6ea83fed 11877 break;
bf4120ad 11878 case OPC_ABS_D:
5e755519 11879 check_cp1_registers(ctx, fs | fd);
b6d96bed 11880 {
a7812ae4 11881 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11882
11883 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11884 if (ctx->abs2008) {
11885 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11886 } else {
11887 gen_helper_float_abs_d(fp0, fp0);
11888 }
b6d96bed 11889 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11890 tcg_temp_free_i64(fp0);
b6d96bed 11891 }
6ea83fed 11892 break;
bf4120ad 11893 case OPC_MOV_D:
5e755519 11894 check_cp1_registers(ctx, fs | fd);
b6d96bed 11895 {
a7812ae4 11896 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11897
11898 gen_load_fpr64(ctx, fp0, fs);
11899 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11900 tcg_temp_free_i64(fp0);
b6d96bed 11901 }
6ea83fed 11902 break;
bf4120ad 11903 case OPC_NEG_D:
5e755519 11904 check_cp1_registers(ctx, fs | fd);
b6d96bed 11905 {
a7812ae4 11906 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11907
11908 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11909 if (ctx->abs2008) {
11910 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11911 } else {
11912 gen_helper_float_chs_d(fp0, fp0);
11913 }
b6d96bed 11914 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11915 tcg_temp_free_i64(fp0);
b6d96bed 11916 }
6ea83fed 11917 break;
bf4120ad 11918 case OPC_ROUND_L_D:
5e755519 11919 check_cp1_64bitmode(ctx);
b6d96bed 11920 {
a7812ae4 11921 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11922
11923 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11924 if (ctx->nan2008) {
11925 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11926 } else {
11927 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11928 }
b6d96bed 11929 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11930 tcg_temp_free_i64(fp0);
b6d96bed 11931 }
5a5012ec 11932 break;
bf4120ad 11933 case OPC_TRUNC_L_D:
5e755519 11934 check_cp1_64bitmode(ctx);
b6d96bed 11935 {
a7812ae4 11936 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11937
11938 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11939 if (ctx->nan2008) {
11940 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11941 } else {
11942 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11943 }
b6d96bed 11944 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11945 tcg_temp_free_i64(fp0);
b6d96bed 11946 }
5a5012ec 11947 break;
bf4120ad 11948 case OPC_CEIL_L_D:
5e755519 11949 check_cp1_64bitmode(ctx);
b6d96bed 11950 {
a7812ae4 11951 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11952
11953 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11954 if (ctx->nan2008) {
11955 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11956 } else {
11957 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11958 }
b6d96bed 11959 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11960 tcg_temp_free_i64(fp0);
b6d96bed 11961 }
5a5012ec 11962 break;
bf4120ad 11963 case OPC_FLOOR_L_D:
5e755519 11964 check_cp1_64bitmode(ctx);
b6d96bed 11965 {
a7812ae4 11966 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11967
11968 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11969 if (ctx->nan2008) {
11970 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11971 } else {
11972 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11973 }
b6d96bed 11974 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11975 tcg_temp_free_i64(fp0);
b6d96bed 11976 }
5a5012ec 11977 break;
bf4120ad 11978 case OPC_ROUND_W_D:
5e755519 11979 check_cp1_registers(ctx, fs);
b6d96bed 11980 {
a7812ae4
PB
11981 TCGv_i32 fp32 = tcg_temp_new_i32();
11982 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11983
11984 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11985 if (ctx->nan2008) {
11986 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11987 } else {
11988 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11989 }
a7812ae4 11990 tcg_temp_free_i64(fp64);
7c979afd 11991 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11992 tcg_temp_free_i32(fp32);
b6d96bed 11993 }
6ea83fed 11994 break;
bf4120ad 11995 case OPC_TRUNC_W_D:
5e755519 11996 check_cp1_registers(ctx, fs);
b6d96bed 11997 {
a7812ae4
PB
11998 TCGv_i32 fp32 = tcg_temp_new_i32();
11999 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12000
12001 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
12002 if (ctx->nan2008) {
12003 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
12004 } else {
12005 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
12006 }
a7812ae4 12007 tcg_temp_free_i64(fp64);
7c979afd 12008 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12009 tcg_temp_free_i32(fp32);
b6d96bed 12010 }
6ea83fed 12011 break;
bf4120ad 12012 case OPC_CEIL_W_D:
5e755519 12013 check_cp1_registers(ctx, fs);
b6d96bed 12014 {
a7812ae4
PB
12015 TCGv_i32 fp32 = tcg_temp_new_i32();
12016 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12017
12018 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
12019 if (ctx->nan2008) {
12020 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
12021 } else {
12022 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
12023 }
a7812ae4 12024 tcg_temp_free_i64(fp64);
7c979afd 12025 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12026 tcg_temp_free_i32(fp32);
b6d96bed 12027 }
6ea83fed 12028 break;
bf4120ad 12029 case OPC_FLOOR_W_D:
5e755519 12030 check_cp1_registers(ctx, fs);
b6d96bed 12031 {
a7812ae4
PB
12032 TCGv_i32 fp32 = tcg_temp_new_i32();
12033 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12034
12035 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
12036 if (ctx->nan2008) {
12037 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
12038 } else {
12039 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
12040 }
a7812ae4 12041 tcg_temp_free_i64(fp64);
7c979afd 12042 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12043 tcg_temp_free_i32(fp32);
b6d96bed 12044 }
6ea83fed 12045 break;
e7f16abb 12046 case OPC_SEL_D:
2e211e0a 12047 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 12048 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
12049 break;
12050 case OPC_SELEQZ_D:
2e211e0a 12051 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 12052 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
12053 break;
12054 case OPC_SELNEZ_D:
2e211e0a 12055 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 12056 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 12057 break;
bf4120ad 12058 case OPC_MOVCF_D:
2e211e0a 12059 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6d96bed 12060 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 12061 break;
bf4120ad 12062 case OPC_MOVZ_D:
2e211e0a 12063 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 12064 {
42a268c2 12065 TCGLabel *l1 = gen_new_label();
c9297f4d 12066 TCGv_i64 fp0;
a16336e4 12067
c9297f4d
AJ
12068 if (ft != 0) {
12069 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12070 }
12071 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12072 gen_load_fpr64(ctx, fp0, fs);
12073 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12074 tcg_temp_free_i64(fp0);
a16336e4
TS
12075 gen_set_label(l1);
12076 }
5a5012ec 12077 break;
bf4120ad 12078 case OPC_MOVN_D:
2e211e0a 12079 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 12080 {
42a268c2 12081 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
12082 TCGv_i64 fp0;
12083
12084 if (ft != 0) {
12085 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12086 fp0 = tcg_temp_new_i64();
12087 gen_load_fpr64(ctx, fp0, fs);
12088 gen_store_fpr64(ctx, fp0, fd);
12089 tcg_temp_free_i64(fp0);
12090 gen_set_label(l1);
12091 }
a16336e4 12092 }
6ea83fed 12093 break;
bf4120ad 12094 case OPC_RECIP_D:
ca6c7803 12095 check_cp1_registers(ctx, fs | fd);
b6d96bed 12096 {
a7812ae4 12097 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12098
12099 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12100 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 12101 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12102 tcg_temp_free_i64(fp0);
b6d96bed 12103 }
57fa1fb3 12104 break;
bf4120ad 12105 case OPC_RSQRT_D:
ca6c7803 12106 check_cp1_registers(ctx, fs | fd);
b6d96bed 12107 {
a7812ae4 12108 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12109
12110 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12111 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 12112 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12113 tcg_temp_free_i64(fp0);
b6d96bed 12114 }
57fa1fb3 12115 break;
e7f16abb 12116 case OPC_MADDF_D:
2e211e0a 12117 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 12118 {
a7812ae4
PB
12119 TCGv_i64 fp0 = tcg_temp_new_i64();
12120 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 12121 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12122 gen_load_fpr64(ctx, fp0, fs);
12123 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
12124 gen_load_fpr64(ctx, fp2, fd);
12125 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
12126 gen_store_fpr64(ctx, fp2, fd);
12127 tcg_temp_free_i64(fp2);
a7812ae4 12128 tcg_temp_free_i64(fp1);
a7812ae4 12129 tcg_temp_free_i64(fp0);
b6d96bed 12130 }
57fa1fb3 12131 break;
e7f16abb 12132 case OPC_MSUBF_D:
2e211e0a 12133 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 12134 {
a7812ae4 12135 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
12136 TCGv_i64 fp1 = tcg_temp_new_i64();
12137 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 12138 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
12139 gen_load_fpr64(ctx, fp1, ft);
12140 gen_load_fpr64(ctx, fp2, fd);
12141 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
12142 gen_store_fpr64(ctx, fp2, fd);
12143 tcg_temp_free_i64(fp2);
12144 tcg_temp_free_i64(fp1);
a7812ae4 12145 tcg_temp_free_i64(fp0);
b6d96bed 12146 }
57fa1fb3 12147 break;
e7f16abb 12148 case OPC_RINT_D:
2e211e0a 12149 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 12150 {
a7812ae4 12151 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12152 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 12153 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 12154 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12155 tcg_temp_free_i64(fp0);
b6d96bed 12156 }
57fa1fb3 12157 break;
e7f16abb 12158 case OPC_CLASS_D:
2e211e0a 12159 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 12160 {
e7f16abb
LA
12161 TCGv_i64 fp0 = tcg_temp_new_i64();
12162 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 12163 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
12164 gen_store_fpr64(ctx, fp0, fd);
12165 tcg_temp_free_i64(fp0);
e7f16abb
LA
12166 }
12167 break;
12168 case OPC_MIN_D: /* OPC_RECIP2_D */
2e211e0a 12169 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 12170 /* OPC_MIN_D */
a7812ae4
PB
12171 TCGv_i64 fp0 = tcg_temp_new_i64();
12172 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
12173 gen_load_fpr64(ctx, fp0, fs);
12174 gen_load_fpr64(ctx, fp1, ft);
12175 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
12176 gen_store_fpr64(ctx, fp1, fd);
12177 tcg_temp_free_i64(fp1);
12178 tcg_temp_free_i64(fp0);
e7f16abb
LA
12179 } else {
12180 /* OPC_RECIP2_D */
12181 check_cp1_64bitmode(ctx);
12182 {
12183 TCGv_i64 fp0 = tcg_temp_new_i64();
12184 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 12185
e7f16abb
LA
12186 gen_load_fpr64(ctx, fp0, fs);
12187 gen_load_fpr64(ctx, fp1, ft);
12188 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
12189 tcg_temp_free_i64(fp1);
12190 gen_store_fpr64(ctx, fp0, fd);
12191 tcg_temp_free_i64(fp0);
12192 }
e7f16abb
LA
12193 }
12194 break;
12195 case OPC_MINA_D: /* OPC_RECIP1_D */
2e211e0a 12196 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
12197 /* OPC_MINA_D */
12198 TCGv_i64 fp0 = tcg_temp_new_i64();
12199 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12200 gen_load_fpr64(ctx, fp0, fs);
12201 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
12202 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
12203 gen_store_fpr64(ctx, fp1, fd);
12204 tcg_temp_free_i64(fp1);
12205 tcg_temp_free_i64(fp0);
e7f16abb
LA
12206 } else {
12207 /* OPC_RECIP1_D */
12208 check_cp1_64bitmode(ctx);
12209 {
12210 TCGv_i64 fp0 = tcg_temp_new_i64();
12211
12212 gen_load_fpr64(ctx, fp0, fs);
12213 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
12214 gen_store_fpr64(ctx, fp0, fd);
12215 tcg_temp_free_i64(fp0);
12216 }
e7f16abb
LA
12217 }
12218 break;
12219 case OPC_MAX_D: /* OPC_RSQRT1_D */
2e211e0a 12220 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
12221 /* OPC_MAX_D */
12222 TCGv_i64 fp0 = tcg_temp_new_i64();
12223 TCGv_i64 fp1 = tcg_temp_new_i64();
12224 gen_load_fpr64(ctx, fp0, fs);
12225 gen_load_fpr64(ctx, fp1, ft);
12226 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
12227 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 12228 tcg_temp_free_i64(fp1);
a7812ae4 12229 tcg_temp_free_i64(fp0);
e7f16abb
LA
12230 } else {
12231 /* OPC_RSQRT1_D */
12232 check_cp1_64bitmode(ctx);
12233 {
12234 TCGv_i64 fp0 = tcg_temp_new_i64();
12235
12236 gen_load_fpr64(ctx, fp0, fs);
12237 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
12238 gen_store_fpr64(ctx, fp0, fd);
12239 tcg_temp_free_i64(fp0);
12240 }
e7f16abb
LA
12241 }
12242 break;
12243 case OPC_MAXA_D: /* OPC_RSQRT2_D */
2e211e0a 12244 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
12245 /* OPC_MAXA_D */
12246 TCGv_i64 fp0 = tcg_temp_new_i64();
12247 TCGv_i64 fp1 = tcg_temp_new_i64();
12248 gen_load_fpr64(ctx, fp0, fs);
12249 gen_load_fpr64(ctx, fp1, ft);
12250 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
12251 gen_store_fpr64(ctx, fp1, fd);
12252 tcg_temp_free_i64(fp1);
12253 tcg_temp_free_i64(fp0);
e7f16abb
LA
12254 } else {
12255 /* OPC_RSQRT2_D */
12256 check_cp1_64bitmode(ctx);
12257 {
12258 TCGv_i64 fp0 = tcg_temp_new_i64();
12259 TCGv_i64 fp1 = tcg_temp_new_i64();
12260
12261 gen_load_fpr64(ctx, fp0, fs);
12262 gen_load_fpr64(ctx, fp1, ft);
12263 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12264 tcg_temp_free_i64(fp1);
12265 gen_store_fpr64(ctx, fp0, fd);
12266 tcg_temp_free_i64(fp0);
12267 }
b6d96bed 12268 }
57fa1fb3 12269 break;
bf4120ad
NF
12270 case OPC_CMP_F_D:
12271 case OPC_CMP_UN_D:
12272 case OPC_CMP_EQ_D:
12273 case OPC_CMP_UEQ_D:
12274 case OPC_CMP_OLT_D:
12275 case OPC_CMP_ULT_D:
12276 case OPC_CMP_OLE_D:
12277 case OPC_CMP_ULE_D:
12278 case OPC_CMP_SF_D:
12279 case OPC_CMP_NGLE_D:
12280 case OPC_CMP_SEQ_D:
12281 case OPC_CMP_NGL_D:
12282 case OPC_CMP_LT_D:
12283 case OPC_CMP_NGE_D:
12284 case OPC_CMP_LE_D:
12285 case OPC_CMP_NGT_D:
2e211e0a 12286 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 12287 if (ctx->opcode & (1 << 6)) {
71375b59 12288 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
8153667c 12289 } else {
71375b59 12290 gen_cmp_d(ctx, func - 48, ft, fs, cc);
5a1e8ffb 12291 }
6ea83fed 12292 break;
bf4120ad 12293 case OPC_CVT_S_D:
5e755519 12294 check_cp1_registers(ctx, fs);
b6d96bed 12295 {
a7812ae4
PB
12296 TCGv_i32 fp32 = tcg_temp_new_i32();
12297 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12298
12299 gen_load_fpr64(ctx, fp64, fs);
895c2d04 12300 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 12301 tcg_temp_free_i64(fp64);
7c979afd 12302 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12303 tcg_temp_free_i32(fp32);
b6d96bed 12304 }
5a5012ec 12305 break;
bf4120ad 12306 case OPC_CVT_W_D:
5e755519 12307 check_cp1_registers(ctx, fs);
b6d96bed 12308 {
a7812ae4
PB
12309 TCGv_i32 fp32 = tcg_temp_new_i32();
12310 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12311
12312 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
12313 if (ctx->nan2008) {
12314 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12315 } else {
12316 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12317 }
a7812ae4 12318 tcg_temp_free_i64(fp64);
7c979afd 12319 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12320 tcg_temp_free_i32(fp32);
b6d96bed 12321 }
5a5012ec 12322 break;
bf4120ad 12323 case OPC_CVT_L_D:
5e755519 12324 check_cp1_64bitmode(ctx);
b6d96bed 12325 {
a7812ae4 12326 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12327
12328 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
12329 if (ctx->nan2008) {
12330 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12331 } else {
12332 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12333 }
b6d96bed 12334 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12335 tcg_temp_free_i64(fp0);
b6d96bed 12336 }
5a5012ec 12337 break;
bf4120ad 12338 case OPC_CVT_S_W:
b6d96bed 12339 {
a7812ae4 12340 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12341
7c979afd 12342 gen_load_fpr32(ctx, fp0, fs);
895c2d04 12343 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 12344 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12345 tcg_temp_free_i32(fp0);
b6d96bed 12346 }
6ea83fed 12347 break;
bf4120ad 12348 case OPC_CVT_D_W:
5e755519 12349 check_cp1_registers(ctx, fd);
b6d96bed 12350 {
a7812ae4
PB
12351 TCGv_i32 fp32 = tcg_temp_new_i32();
12352 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 12353
7c979afd 12354 gen_load_fpr32(ctx, fp32, fs);
895c2d04 12355 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 12356 tcg_temp_free_i32(fp32);
b6d96bed 12357 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 12358 tcg_temp_free_i64(fp64);
b6d96bed 12359 }
5a5012ec 12360 break;
bf4120ad 12361 case OPC_CVT_S_L:
5e755519 12362 check_cp1_64bitmode(ctx);
b6d96bed 12363 {
a7812ae4
PB
12364 TCGv_i32 fp32 = tcg_temp_new_i32();
12365 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
12366
12367 gen_load_fpr64(ctx, fp64, fs);
895c2d04 12368 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 12369 tcg_temp_free_i64(fp64);
7c979afd 12370 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 12371 tcg_temp_free_i32(fp32);
b6d96bed 12372 }
5a5012ec 12373 break;
bf4120ad 12374 case OPC_CVT_D_L:
5e755519 12375 check_cp1_64bitmode(ctx);
b6d96bed 12376 {
a7812ae4 12377 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12378
12379 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12380 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 12381 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12382 tcg_temp_free_i64(fp0);
b6d96bed 12383 }
5a5012ec 12384 break;
bf4120ad 12385 case OPC_CVT_PS_PW:
e29c9628 12386 check_ps(ctx);
b6d96bed 12387 {
a7812ae4 12388 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12389
12390 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12391 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 12392 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12393 tcg_temp_free_i64(fp0);
b6d96bed 12394 }
5a5012ec 12395 break;
bf4120ad 12396 case OPC_ADD_PS:
e29c9628 12397 check_ps(ctx);
b6d96bed 12398 {
a7812ae4
PB
12399 TCGv_i64 fp0 = tcg_temp_new_i64();
12400 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12401
12402 gen_load_fpr64(ctx, fp0, fs);
12403 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12404 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12405 tcg_temp_free_i64(fp1);
b6d96bed 12406 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12407 tcg_temp_free_i64(fp0);
b6d96bed 12408 }
6ea83fed 12409 break;
bf4120ad 12410 case OPC_SUB_PS:
e29c9628 12411 check_ps(ctx);
b6d96bed 12412 {
a7812ae4
PB
12413 TCGv_i64 fp0 = tcg_temp_new_i64();
12414 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12415
12416 gen_load_fpr64(ctx, fp0, fs);
12417 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12418 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12419 tcg_temp_free_i64(fp1);
b6d96bed 12420 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12421 tcg_temp_free_i64(fp0);
b6d96bed 12422 }
6ea83fed 12423 break;
bf4120ad 12424 case OPC_MUL_PS:
e29c9628 12425 check_ps(ctx);
b6d96bed 12426 {
a7812ae4
PB
12427 TCGv_i64 fp0 = tcg_temp_new_i64();
12428 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12429
12430 gen_load_fpr64(ctx, fp0, fs);
12431 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12432 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12433 tcg_temp_free_i64(fp1);
b6d96bed 12434 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12435 tcg_temp_free_i64(fp0);
b6d96bed 12436 }
6ea83fed 12437 break;
bf4120ad 12438 case OPC_ABS_PS:
e29c9628 12439 check_ps(ctx);
b6d96bed 12440 {
a7812ae4 12441 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12442
12443 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 12444 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 12445 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12446 tcg_temp_free_i64(fp0);
b6d96bed 12447 }
6ea83fed 12448 break;
bf4120ad 12449 case OPC_MOV_PS:
e29c9628 12450 check_ps(ctx);
b6d96bed 12451 {
a7812ae4 12452 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12453
12454 gen_load_fpr64(ctx, fp0, fs);
12455 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12456 tcg_temp_free_i64(fp0);
b6d96bed 12457 }
6ea83fed 12458 break;
bf4120ad 12459 case OPC_NEG_PS:
e29c9628 12460 check_ps(ctx);
b6d96bed 12461 {
a7812ae4 12462 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12463
12464 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 12465 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 12466 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12467 tcg_temp_free_i64(fp0);
b6d96bed 12468 }
6ea83fed 12469 break;
bf4120ad 12470 case OPC_MOVCF_PS:
e29c9628 12471 check_ps(ctx);
7f6613ce 12472 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 12473 break;
bf4120ad 12474 case OPC_MOVZ_PS:
e29c9628 12475 check_ps(ctx);
a16336e4 12476 {
42a268c2 12477 TCGLabel *l1 = gen_new_label();
30a3848b 12478 TCGv_i64 fp0;
a16336e4 12479
1f8929d2 12480 if (ft != 0) {
c9297f4d 12481 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
1f8929d2 12482 }
c9297f4d
AJ
12483 fp0 = tcg_temp_new_i64();
12484 gen_load_fpr64(ctx, fp0, fs);
12485 gen_store_fpr64(ctx, fp0, fd);
12486 tcg_temp_free_i64(fp0);
a16336e4
TS
12487 gen_set_label(l1);
12488 }
6ea83fed 12489 break;
bf4120ad 12490 case OPC_MOVN_PS:
e29c9628 12491 check_ps(ctx);
a16336e4 12492 {
42a268c2 12493 TCGLabel *l1 = gen_new_label();
30a3848b 12494 TCGv_i64 fp0;
c9297f4d
AJ
12495
12496 if (ft != 0) {
12497 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12498 fp0 = tcg_temp_new_i64();
12499 gen_load_fpr64(ctx, fp0, fs);
12500 gen_store_fpr64(ctx, fp0, fd);
12501 tcg_temp_free_i64(fp0);
12502 gen_set_label(l1);
12503 }
a16336e4 12504 }
6ea83fed 12505 break;
bf4120ad 12506 case OPC_ADDR_PS:
e29c9628 12507 check_ps(ctx);
b6d96bed 12508 {
a7812ae4
PB
12509 TCGv_i64 fp0 = tcg_temp_new_i64();
12510 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12511
12512 gen_load_fpr64(ctx, fp0, ft);
12513 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12514 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12515 tcg_temp_free_i64(fp1);
b6d96bed 12516 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12517 tcg_temp_free_i64(fp0);
b6d96bed 12518 }
fbcc6828 12519 break;
bf4120ad 12520 case OPC_MULR_PS:
e29c9628 12521 check_ps(ctx);
b6d96bed 12522 {
a7812ae4
PB
12523 TCGv_i64 fp0 = tcg_temp_new_i64();
12524 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12525
12526 gen_load_fpr64(ctx, fp0, ft);
12527 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12528 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12529 tcg_temp_free_i64(fp1);
b6d96bed 12530 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12531 tcg_temp_free_i64(fp0);
b6d96bed 12532 }
57fa1fb3 12533 break;
bf4120ad 12534 case OPC_RECIP2_PS:
e29c9628 12535 check_ps(ctx);
b6d96bed 12536 {
a7812ae4
PB
12537 TCGv_i64 fp0 = tcg_temp_new_i64();
12538 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12539
12540 gen_load_fpr64(ctx, fp0, fs);
d22d7289 12541 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12542 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12543 tcg_temp_free_i64(fp1);
b6d96bed 12544 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12545 tcg_temp_free_i64(fp0);
b6d96bed 12546 }
57fa1fb3 12547 break;
bf4120ad 12548 case OPC_RECIP1_PS:
e29c9628 12549 check_ps(ctx);
b6d96bed 12550 {
a7812ae4 12551 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12552
12553 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12554 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 12555 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12556 tcg_temp_free_i64(fp0);
b6d96bed 12557 }
57fa1fb3 12558 break;
bf4120ad 12559 case OPC_RSQRT1_PS:
e29c9628 12560 check_ps(ctx);
b6d96bed 12561 {
a7812ae4 12562 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12563
12564 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12565 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 12566 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12567 tcg_temp_free_i64(fp0);
b6d96bed 12568 }
57fa1fb3 12569 break;
bf4120ad 12570 case OPC_RSQRT2_PS:
e29c9628 12571 check_ps(ctx);
b6d96bed 12572 {
a7812ae4
PB
12573 TCGv_i64 fp0 = tcg_temp_new_i64();
12574 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12575
12576 gen_load_fpr64(ctx, fp0, fs);
12577 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12578 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12579 tcg_temp_free_i64(fp1);
b6d96bed 12580 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12581 tcg_temp_free_i64(fp0);
b6d96bed 12582 }
57fa1fb3 12583 break;
bf4120ad 12584 case OPC_CVT_S_PU:
5e755519 12585 check_cp1_64bitmode(ctx);
b6d96bed 12586 {
a7812ae4 12587 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12588
7f6613ce 12589 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 12590 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 12591 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12592 tcg_temp_free_i32(fp0);
b6d96bed 12593 }
dd016883 12594 break;
bf4120ad 12595 case OPC_CVT_PW_PS:
e29c9628 12596 check_ps(ctx);
b6d96bed 12597 {
a7812ae4 12598 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12599
12600 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12601 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 12602 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12603 tcg_temp_free_i64(fp0);
b6d96bed 12604 }
6ea83fed 12605 break;
bf4120ad 12606 case OPC_CVT_S_PL:
5e755519 12607 check_cp1_64bitmode(ctx);
b6d96bed 12608 {
a7812ae4 12609 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12610
7c979afd 12611 gen_load_fpr32(ctx, fp0, fs);
895c2d04 12612 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 12613 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12614 tcg_temp_free_i32(fp0);
b6d96bed 12615 }
6ea83fed 12616 break;
bf4120ad 12617 case OPC_PLL_PS:
e29c9628 12618 check_ps(ctx);
b6d96bed 12619 {
a7812ae4
PB
12620 TCGv_i32 fp0 = tcg_temp_new_i32();
12621 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12622
7c979afd
LA
12623 gen_load_fpr32(ctx, fp0, fs);
12624 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 12625 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 12626 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
12627 tcg_temp_free_i32(fp0);
12628 tcg_temp_free_i32(fp1);
b6d96bed 12629 }
6ea83fed 12630 break;
bf4120ad 12631 case OPC_PLU_PS:
e29c9628 12632 check_ps(ctx);
b6d96bed 12633 {
a7812ae4
PB
12634 TCGv_i32 fp0 = tcg_temp_new_i32();
12635 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12636
7c979afd 12637 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 12638 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12639 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12640 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12641 tcg_temp_free_i32(fp0);
12642 tcg_temp_free_i32(fp1);
b6d96bed 12643 }
5a5012ec 12644 break;
bf4120ad 12645 case OPC_PUL_PS:
e29c9628 12646 check_ps(ctx);
b6d96bed 12647 {
a7812ae4
PB
12648 TCGv_i32 fp0 = tcg_temp_new_i32();
12649 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12650
7f6613ce 12651 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
12652 gen_load_fpr32(ctx, fp1, ft);
12653 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12654 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12655 tcg_temp_free_i32(fp0);
12656 tcg_temp_free_i32(fp1);
b6d96bed 12657 }
5a5012ec 12658 break;
bf4120ad 12659 case OPC_PUU_PS:
e29c9628 12660 check_ps(ctx);
b6d96bed 12661 {
a7812ae4
PB
12662 TCGv_i32 fp0 = tcg_temp_new_i32();
12663 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12664
7f6613ce
PJ
12665 gen_load_fpr32h(ctx, fp0, fs);
12666 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12667 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12668 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12669 tcg_temp_free_i32(fp0);
12670 tcg_temp_free_i32(fp1);
b6d96bed 12671 }
5a5012ec 12672 break;
bf4120ad
NF
12673 case OPC_CMP_F_PS:
12674 case OPC_CMP_UN_PS:
12675 case OPC_CMP_EQ_PS:
12676 case OPC_CMP_UEQ_PS:
12677 case OPC_CMP_OLT_PS:
12678 case OPC_CMP_ULT_PS:
12679 case OPC_CMP_OLE_PS:
12680 case OPC_CMP_ULE_PS:
12681 case OPC_CMP_SF_PS:
12682 case OPC_CMP_NGLE_PS:
12683 case OPC_CMP_SEQ_PS:
12684 case OPC_CMP_NGL_PS:
12685 case OPC_CMP_LT_PS:
12686 case OPC_CMP_NGE_PS:
12687 case OPC_CMP_LE_PS:
12688 case OPC_CMP_NGT_PS:
8153667c 12689 if (ctx->opcode & (1 << 6)) {
71375b59 12690 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
8153667c 12691 } else {
71375b59 12692 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
5a1e8ffb 12693 }
6ea83fed 12694 break;
5a5012ec 12695 default:
9d68ac14 12696 MIPS_INVAL("farith");
3a4ef3b7 12697 gen_reserved_instruction(ctx);
6ea83fed
FB
12698 return;
12699 }
6ea83fed 12700}
6af0bf9c 12701
5a5012ec 12702/* Coprocessor 3 (FPU) */
235785e8
AM
12703static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12704 int fd, int fs, int base, int index)
7a387fff 12705{
4e2474d6 12706 TCGv t0 = tcg_temp_new();
7a387fff 12707
93b12ccc 12708 if (base == 0) {
6c5c1e20 12709 gen_load_gpr(t0, index);
93b12ccc 12710 } else if (index == 0) {
6c5c1e20 12711 gen_load_gpr(t0, base);
93b12ccc 12712 } else {
05168674 12713 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 12714 }
7480515f
AM
12715 /*
12716 * Don't do NOP if destination is zero: we must perform the actual
12717 * memory access.
12718 */
5a5012ec
TS
12719 switch (opc) {
12720 case OPC_LWXC1:
8c0ab41f 12721 check_cop1x(ctx);
b6d96bed 12722 {
a7812ae4 12723 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12724
5f68f5ae 12725 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 12726 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 12727 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12728 tcg_temp_free_i32(fp0);
b6d96bed 12729 }
5a5012ec
TS
12730 break;
12731 case OPC_LDXC1:
8c0ab41f
AJ
12732 check_cop1x(ctx);
12733 check_cp1_registers(ctx, fd);
b6d96bed 12734 {
a7812ae4 12735 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 12736 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12737 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12738 tcg_temp_free_i64(fp0);
b6d96bed 12739 }
5a5012ec
TS
12740 break;
12741 case OPC_LUXC1:
8c0ab41f 12742 check_cp1_64bitmode(ctx);
6c5c1e20 12743 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12744 {
a7812ae4 12745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12746
5f68f5ae 12747 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12749 tcg_temp_free_i64(fp0);
b6d96bed 12750 }
5a5012ec
TS
12751 break;
12752 case OPC_SWXC1:
8c0ab41f 12753 check_cop1x(ctx);
b6d96bed 12754 {
a7812ae4 12755 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 12756 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 12757 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 12758 tcg_temp_free_i32(fp0);
b6d96bed 12759 }
5a5012ec
TS
12760 break;
12761 case OPC_SDXC1:
8c0ab41f
AJ
12762 check_cop1x(ctx);
12763 check_cp1_registers(ctx, fs);
b6d96bed 12764 {
a7812ae4 12765 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12766 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12767 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12768 tcg_temp_free_i64(fp0);
b6d96bed 12769 }
5a5012ec
TS
12770 break;
12771 case OPC_SUXC1:
8c0ab41f 12772 check_cp1_64bitmode(ctx);
6c5c1e20 12773 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12774 {
a7812ae4 12775 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12776 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12777 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12778 tcg_temp_free_i64(fp0);
b6d96bed 12779 }
5a5012ec 12780 break;
5a5012ec 12781 }
6c5c1e20 12782 tcg_temp_free(t0);
5a5012ec
TS
12783}
12784
235785e8
AM
12785static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12786 int fd, int fr, int fs, int ft)
5a5012ec 12787{
5a5012ec
TS
12788 switch (opc) {
12789 case OPC_ALNV_PS:
e29c9628 12790 check_ps(ctx);
a16336e4 12791 {
a7812ae4 12792 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
12793 TCGv_i32 fp = tcg_temp_new_i32();
12794 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
12795 TCGLabel *l1 = gen_new_label();
12796 TCGLabel *l2 = gen_new_label();
a16336e4 12797
6c5c1e20
TS
12798 gen_load_gpr(t0, fr);
12799 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
12800
12801 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 12802 gen_load_fpr32(ctx, fp, fs);
7f6613ce 12803 gen_load_fpr32h(ctx, fph, fs);
7c979afd 12804 gen_store_fpr32(ctx, fp, fd);
7f6613ce 12805 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
12806 tcg_gen_br(l2);
12807 gen_set_label(l1);
6c5c1e20
TS
12808 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12809 tcg_temp_free(t0);
a16336e4 12810#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 12811 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
12812 gen_load_fpr32h(ctx, fph, ft);
12813 gen_store_fpr32h(ctx, fp, fd);
7c979afd 12814 gen_store_fpr32(ctx, fph, fd);
a16336e4 12815#else
7f6613ce 12816 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
12817 gen_load_fpr32(ctx, fp, ft);
12818 gen_store_fpr32(ctx, fph, fd);
7f6613ce 12819 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
12820#endif
12821 gen_set_label(l2);
c905fdac
AJ
12822 tcg_temp_free_i32(fp);
12823 tcg_temp_free_i32(fph);
a16336e4 12824 }
5a5012ec
TS
12825 break;
12826 case OPC_MADD_S:
b8aa4598 12827 check_cop1x(ctx);
b6d96bed 12828 {
a7812ae4
PB
12829 TCGv_i32 fp0 = tcg_temp_new_i32();
12830 TCGv_i32 fp1 = tcg_temp_new_i32();
12831 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12832
7c979afd
LA
12833 gen_load_fpr32(ctx, fp0, fs);
12834 gen_load_fpr32(ctx, fp1, ft);
12835 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12836 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12837 tcg_temp_free_i32(fp0);
12838 tcg_temp_free_i32(fp1);
7c979afd 12839 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12840 tcg_temp_free_i32(fp2);
b6d96bed 12841 }
5a5012ec
TS
12842 break;
12843 case OPC_MADD_D:
b8aa4598
TS
12844 check_cop1x(ctx);
12845 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12846 {
a7812ae4
PB
12847 TCGv_i64 fp0 = tcg_temp_new_i64();
12848 TCGv_i64 fp1 = tcg_temp_new_i64();
12849 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12850
12851 gen_load_fpr64(ctx, fp0, fs);
12852 gen_load_fpr64(ctx, fp1, ft);
12853 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12854 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12855 tcg_temp_free_i64(fp0);
12856 tcg_temp_free_i64(fp1);
b6d96bed 12857 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12858 tcg_temp_free_i64(fp2);
b6d96bed 12859 }
5a5012ec
TS
12860 break;
12861 case OPC_MADD_PS:
e29c9628 12862 check_ps(ctx);
b6d96bed 12863 {
a7812ae4
PB
12864 TCGv_i64 fp0 = tcg_temp_new_i64();
12865 TCGv_i64 fp1 = tcg_temp_new_i64();
12866 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12867
12868 gen_load_fpr64(ctx, fp0, fs);
12869 gen_load_fpr64(ctx, fp1, ft);
12870 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12871 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12872 tcg_temp_free_i64(fp0);
12873 tcg_temp_free_i64(fp1);
b6d96bed 12874 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12875 tcg_temp_free_i64(fp2);
b6d96bed 12876 }
5a5012ec
TS
12877 break;
12878 case OPC_MSUB_S:
b8aa4598 12879 check_cop1x(ctx);
b6d96bed 12880 {
a7812ae4
PB
12881 TCGv_i32 fp0 = tcg_temp_new_i32();
12882 TCGv_i32 fp1 = tcg_temp_new_i32();
12883 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12884
7c979afd
LA
12885 gen_load_fpr32(ctx, fp0, fs);
12886 gen_load_fpr32(ctx, fp1, ft);
12887 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12888 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12889 tcg_temp_free_i32(fp0);
12890 tcg_temp_free_i32(fp1);
7c979afd 12891 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12892 tcg_temp_free_i32(fp2);
b6d96bed 12893 }
5a5012ec
TS
12894 break;
12895 case OPC_MSUB_D:
b8aa4598
TS
12896 check_cop1x(ctx);
12897 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12898 {
a7812ae4
PB
12899 TCGv_i64 fp0 = tcg_temp_new_i64();
12900 TCGv_i64 fp1 = tcg_temp_new_i64();
12901 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12902
12903 gen_load_fpr64(ctx, fp0, fs);
12904 gen_load_fpr64(ctx, fp1, ft);
12905 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12906 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12907 tcg_temp_free_i64(fp0);
12908 tcg_temp_free_i64(fp1);
b6d96bed 12909 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12910 tcg_temp_free_i64(fp2);
b6d96bed 12911 }
5a5012ec
TS
12912 break;
12913 case OPC_MSUB_PS:
e29c9628 12914 check_ps(ctx);
b6d96bed 12915 {
a7812ae4
PB
12916 TCGv_i64 fp0 = tcg_temp_new_i64();
12917 TCGv_i64 fp1 = tcg_temp_new_i64();
12918 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12919
12920 gen_load_fpr64(ctx, fp0, fs);
12921 gen_load_fpr64(ctx, fp1, ft);
12922 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12923 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12924 tcg_temp_free_i64(fp0);
12925 tcg_temp_free_i64(fp1);
b6d96bed 12926 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12927 tcg_temp_free_i64(fp2);
b6d96bed 12928 }
5a5012ec
TS
12929 break;
12930 case OPC_NMADD_S:
b8aa4598 12931 check_cop1x(ctx);
b6d96bed 12932 {
a7812ae4
PB
12933 TCGv_i32 fp0 = tcg_temp_new_i32();
12934 TCGv_i32 fp1 = tcg_temp_new_i32();
12935 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12936
7c979afd
LA
12937 gen_load_fpr32(ctx, fp0, fs);
12938 gen_load_fpr32(ctx, fp1, ft);
12939 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12940 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12941 tcg_temp_free_i32(fp0);
12942 tcg_temp_free_i32(fp1);
7c979afd 12943 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12944 tcg_temp_free_i32(fp2);
b6d96bed 12945 }
5a5012ec
TS
12946 break;
12947 case OPC_NMADD_D:
b8aa4598
TS
12948 check_cop1x(ctx);
12949 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12950 {
a7812ae4
PB
12951 TCGv_i64 fp0 = tcg_temp_new_i64();
12952 TCGv_i64 fp1 = tcg_temp_new_i64();
12953 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12954
12955 gen_load_fpr64(ctx, fp0, fs);
12956 gen_load_fpr64(ctx, fp1, ft);
12957 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12958 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12959 tcg_temp_free_i64(fp0);
12960 tcg_temp_free_i64(fp1);
b6d96bed 12961 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12962 tcg_temp_free_i64(fp2);
b6d96bed 12963 }
5a5012ec
TS
12964 break;
12965 case OPC_NMADD_PS:
e29c9628 12966 check_ps(ctx);
b6d96bed 12967 {
a7812ae4
PB
12968 TCGv_i64 fp0 = tcg_temp_new_i64();
12969 TCGv_i64 fp1 = tcg_temp_new_i64();
12970 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12971
12972 gen_load_fpr64(ctx, fp0, fs);
12973 gen_load_fpr64(ctx, fp1, ft);
12974 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12975 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12976 tcg_temp_free_i64(fp0);
12977 tcg_temp_free_i64(fp1);
b6d96bed 12978 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12979 tcg_temp_free_i64(fp2);
b6d96bed 12980 }
5a5012ec
TS
12981 break;
12982 case OPC_NMSUB_S:
b8aa4598 12983 check_cop1x(ctx);
b6d96bed 12984 {
a7812ae4
PB
12985 TCGv_i32 fp0 = tcg_temp_new_i32();
12986 TCGv_i32 fp1 = tcg_temp_new_i32();
12987 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12988
7c979afd
LA
12989 gen_load_fpr32(ctx, fp0, fs);
12990 gen_load_fpr32(ctx, fp1, ft);
12991 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12992 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12993 tcg_temp_free_i32(fp0);
12994 tcg_temp_free_i32(fp1);
7c979afd 12995 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12996 tcg_temp_free_i32(fp2);
b6d96bed 12997 }
5a5012ec
TS
12998 break;
12999 case OPC_NMSUB_D:
b8aa4598
TS
13000 check_cop1x(ctx);
13001 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 13002 {
a7812ae4
PB
13003 TCGv_i64 fp0 = tcg_temp_new_i64();
13004 TCGv_i64 fp1 = tcg_temp_new_i64();
13005 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
13006
13007 gen_load_fpr64(ctx, fp0, fs);
13008 gen_load_fpr64(ctx, fp1, ft);
13009 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 13010 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
13011 tcg_temp_free_i64(fp0);
13012 tcg_temp_free_i64(fp1);
b6d96bed 13013 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 13014 tcg_temp_free_i64(fp2);
b6d96bed 13015 }
5a5012ec
TS
13016 break;
13017 case OPC_NMSUB_PS:
e29c9628 13018 check_ps(ctx);
b6d96bed 13019 {
a7812ae4
PB
13020 TCGv_i64 fp0 = tcg_temp_new_i64();
13021 TCGv_i64 fp1 = tcg_temp_new_i64();
13022 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
13023
13024 gen_load_fpr64(ctx, fp0, fs);
13025 gen_load_fpr64(ctx, fp1, ft);
13026 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 13027 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
13028 tcg_temp_free_i64(fp0);
13029 tcg_temp_free_i64(fp1);
b6d96bed 13030 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 13031 tcg_temp_free_i64(fp2);
b6d96bed 13032 }
5a5012ec 13033 break;
923617a3 13034 default:
9d68ac14 13035 MIPS_INVAL("flt3_arith");
3a4ef3b7 13036 gen_reserved_instruction(ctx);
5a5012ec
TS
13037 return;
13038 }
7a387fff
TS
13039}
13040
b00c7218 13041static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
13042{
13043 TCGv t0;
13044
b3167288 13045#if !defined(CONFIG_USER_ONLY)
7480515f
AM
13046 /*
13047 * The Linux kernel will emulate rdhwr if it's not supported natively.
13048 * Therefore only check the ISA in system mode.
13049 */
7a47bae5 13050 check_insn(ctx, ISA_MIPS_R2);
b3167288 13051#endif
26ebe468
NF
13052 t0 = tcg_temp_new();
13053
13054 switch (rd) {
13055 case 0:
895c2d04 13056 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
13057 gen_store_gpr(t0, rt);
13058 break;
13059 case 1:
895c2d04 13060 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
13061 gen_store_gpr(t0, rt);
13062 break;
13063 case 2:
eeb3bba8 13064 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
13065 gen_io_start();
13066 }
895c2d04 13067 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468 13068 gen_store_gpr(t0, rt);
7480515f
AM
13069 /*
13070 * Break the TB to be able to take timer interrupts immediately
13071 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13072 * we break completely out of translated code.
13073 */
eeb3bba8
EC
13074 gen_save_pc(ctx->base.pc_next + 4);
13075 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
13076 break;
13077 case 3:
895c2d04 13078 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
13079 gen_store_gpr(t0, rt);
13080 break;
b00c7218 13081 case 4:
2e211e0a 13082 check_insn(ctx, ISA_MIPS_R6);
b00c7218 13083 if (sel != 0) {
7480515f
AM
13084 /*
13085 * Performance counter registers are not implemented other than
b00c7218
YK
13086 * control register 0.
13087 */
13088 generate_exception(ctx, EXCP_RI);
13089 }
13090 gen_helper_rdhwr_performance(t0, cpu_env);
13091 gen_store_gpr(t0, rt);
13092 break;
13093 case 5:
2e211e0a 13094 check_insn(ctx, ISA_MIPS_R6);
b00c7218
YK
13095 gen_helper_rdhwr_xnp(t0, cpu_env);
13096 gen_store_gpr(t0, rt);
13097 break;
26ebe468
NF
13098 case 29:
13099#if defined(CONFIG_USER_ONLY)
d279279e
PJ
13100 tcg_gen_ld_tl(t0, cpu_env,
13101 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
13102 gen_store_gpr(t0, rt);
13103 break;
13104#else
d279279e
PJ
13105 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
13106 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
13107 tcg_gen_ld_tl(t0, cpu_env,
13108 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
13109 gen_store_gpr(t0, rt);
13110 } else {
3a4ef3b7 13111 gen_reserved_instruction(ctx);
d279279e
PJ
13112 }
13113 break;
26ebe468
NF
13114#endif
13115 default: /* Invalid */
13116 MIPS_INVAL("rdhwr");
3a4ef3b7 13117 gen_reserved_instruction(ctx);
26ebe468
NF
13118 break;
13119 }
13120 tcg_temp_free(t0);
13121}
13122
a5f53390
LA
13123static inline void clear_branch_hflags(DisasContext *ctx)
13124{
13125 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 13126 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
13127 save_cpu_state(ctx, 0);
13128 } else {
7480515f
AM
13129 /*
13130 * It is not safe to save ctx->hflags as hflags may be changed
13131 * in execution time by the instruction in delay / forbidden slot.
13132 */
a5f53390
LA
13133 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
13134 }
13135}
13136
31837be3 13137static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
13138{
13139 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 13140 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 13141 /* Branches completion */
a5f53390 13142 clear_branch_hflags(ctx);
eeb3bba8 13143 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 13144 /* FIXME: Need to clear can_do_io. */
364d4831 13145 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 13146 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 13147 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 13148 break;
c9602061
NF
13149 case MIPS_HFLAG_B:
13150 /* unconditional branch */
364d4831
NF
13151 if (proc_hflags & MIPS_HFLAG_BX) {
13152 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
13153 }
c9602061
NF
13154 gen_goto_tb(ctx, 0, ctx->btarget);
13155 break;
13156 case MIPS_HFLAG_BL:
13157 /* blikely taken case */
c9602061
NF
13158 gen_goto_tb(ctx, 0, ctx->btarget);
13159 break;
13160 case MIPS_HFLAG_BC:
13161 /* Conditional branch */
c9602061 13162 {
42a268c2 13163 TCGLabel *l1 = gen_new_label();
c9602061
NF
13164
13165 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 13166 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
13167 gen_set_label(l1);
13168 gen_goto_tb(ctx, 0, ctx->btarget);
13169 }
13170 break;
13171 case MIPS_HFLAG_BR:
13172 /* unconditional branch to register */
d75c135e 13173 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
13174 TCGv t0 = tcg_temp_new();
13175 TCGv_i32 t1 = tcg_temp_new_i32();
13176
13177 tcg_gen_andi_tl(t0, btarget, 0x1);
13178 tcg_gen_trunc_tl_i32(t1, t0);
13179 tcg_temp_free(t0);
13180 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
13181 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
13182 tcg_gen_or_i32(hflags, hflags, t1);
13183 tcg_temp_free_i32(t1);
13184
13185 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
13186 } else {
13187 tcg_gen_mov_tl(cpu_PC, btarget);
13188 }
eeb3bba8 13189 if (ctx->base.singlestep_enabled) {
c9602061 13190 save_cpu_state(ctx, 0);
9c708c7f 13191 gen_helper_raise_exception_debug(cpu_env);
c9602061 13192 }
7f11636d 13193 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
13194 break;
13195 default:
a5f53390
LA
13196 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
13197 abort();
c9602061
NF
13198 }
13199 }
13200}
13201
6893f074
YK
13202/* Compact Branches */
13203static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
13204 int rs, int rt, int32_t offset)
13205{
13206 int bcond_compute = 0;
13207 TCGv t0 = tcg_temp_new();
13208 TCGv t1 = tcg_temp_new();
65935f07 13209 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
13210
13211 if (ctx->hflags & MIPS_HFLAG_BMASK) {
13212#ifdef MIPS_DEBUG_DISAS
13213 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 13214 "\n", ctx->base.pc_next);
6893f074 13215#endif
3a4ef3b7 13216 gen_reserved_instruction(ctx);
6893f074
YK
13217 goto out;
13218 }
13219
13220 /* Load needed operands and calculate btarget */
13221 switch (opc) {
13222 /* compact branch */
13223 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13224 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13225 gen_load_gpr(t0, rs);
13226 gen_load_gpr(t1, rt);
13227 bcond_compute = 1;
eeb3bba8 13228 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
13229 if (rs <= rt && rs == 0) {
13230 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 13231 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
13232 }
13233 break;
13234 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13235 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13236 gen_load_gpr(t0, rs);
13237 gen_load_gpr(t1, rt);
13238 bcond_compute = 1;
eeb3bba8 13239 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
13240 break;
13241 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13242 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13243 if (rs == 0 || rs == rt) {
13244 /* OPC_BLEZALC, OPC_BGEZALC */
13245 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 13246 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
13247 }
13248 gen_load_gpr(t0, rs);
13249 gen_load_gpr(t1, rt);
13250 bcond_compute = 1;
eeb3bba8 13251 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
13252 break;
13253 case OPC_BC:
13254 case OPC_BALC:
eeb3bba8 13255 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
13256 break;
13257 case OPC_BEQZC:
13258 case OPC_BNEZC:
13259 if (rs != 0) {
13260 /* OPC_BEQZC, OPC_BNEZC */
13261 gen_load_gpr(t0, rs);
13262 bcond_compute = 1;
eeb3bba8 13263 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
13264 } else {
13265 /* OPC_JIC, OPC_JIALC */
13266 TCGv tbase = tcg_temp_new();
13267 TCGv toffset = tcg_temp_new();
13268
13269 gen_load_gpr(tbase, rt);
13270 tcg_gen_movi_tl(toffset, offset);
13271 gen_op_addr_add(ctx, btarget, tbase, toffset);
13272 tcg_temp_free(tbase);
13273 tcg_temp_free(toffset);
13274 }
13275 break;
13276 default:
13277 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 13278 gen_reserved_instruction(ctx);
6893f074
YK
13279 goto out;
13280 }
13281
13282 if (bcond_compute == 0) {
13283 /* Uncoditional compact branch */
13284 switch (opc) {
13285 case OPC_JIALC:
eeb3bba8 13286 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
13287 /* Fallthrough */
13288 case OPC_JIC:
13289 ctx->hflags |= MIPS_HFLAG_BR;
13290 break;
13291 case OPC_BALC:
eeb3bba8 13292 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
13293 /* Fallthrough */
13294 case OPC_BC:
13295 ctx->hflags |= MIPS_HFLAG_B;
13296 break;
13297 default:
13298 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 13299 gen_reserved_instruction(ctx);
6893f074
YK
13300 goto out;
13301 }
13302
13303 /* Generating branch here as compact branches don't have delay slot */
13304 gen_branch(ctx, 4);
13305 } else {
13306 /* Conditional compact branch */
13307 TCGLabel *fs = gen_new_label();
13308 save_cpu_state(ctx, 0);
13309
13310 switch (opc) {
13311 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13312 if (rs == 0 && rt != 0) {
13313 /* OPC_BLEZALC */
13314 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13315 } else if (rs != 0 && rt != 0 && rs == rt) {
13316 /* OPC_BGEZALC */
13317 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13318 } else {
13319 /* OPC_BGEUC */
13320 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13321 }
13322 break;
13323 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13324 if (rs == 0 && rt != 0) {
13325 /* OPC_BGTZALC */
13326 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13327 } else if (rs != 0 && rt != 0 && rs == rt) {
13328 /* OPC_BLTZALC */
13329 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13330 } else {
13331 /* OPC_BLTUC */
13332 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13333 }
13334 break;
13335 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13336 if (rs == 0 && rt != 0) {
13337 /* OPC_BLEZC */
13338 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13339 } else if (rs != 0 && rt != 0 && rs == rt) {
13340 /* OPC_BGEZC */
13341 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13342 } else {
13343 /* OPC_BGEC */
13344 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13345 }
13346 break;
13347 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13348 if (rs == 0 && rt != 0) {
13349 /* OPC_BGTZC */
13350 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13351 } else if (rs != 0 && rt != 0 && rs == rt) {
13352 /* OPC_BLTZC */
13353 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13354 } else {
13355 /* OPC_BLTC */
13356 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13357 }
13358 break;
13359 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13360 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13361 if (rs >= rt) {
13362 /* OPC_BOVC, OPC_BNVC */
13363 TCGv t2 = tcg_temp_new();
13364 TCGv t3 = tcg_temp_new();
13365 TCGv t4 = tcg_temp_new();
13366 TCGv input_overflow = tcg_temp_new();
13367
13368 gen_load_gpr(t0, rs);
13369 gen_load_gpr(t1, rt);
13370 tcg_gen_ext32s_tl(t2, t0);
13371 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13372 tcg_gen_ext32s_tl(t3, t1);
13373 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13374 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13375
13376 tcg_gen_add_tl(t4, t2, t3);
13377 tcg_gen_ext32s_tl(t4, t4);
13378 tcg_gen_xor_tl(t2, t2, t3);
13379 tcg_gen_xor_tl(t3, t4, t3);
13380 tcg_gen_andc_tl(t2, t3, t2);
13381 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13382 tcg_gen_or_tl(t4, t4, input_overflow);
13383 if (opc == OPC_BOVC) {
13384 /* OPC_BOVC */
13385 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13386 } else {
13387 /* OPC_BNVC */
13388 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13389 }
13390 tcg_temp_free(input_overflow);
13391 tcg_temp_free(t4);
13392 tcg_temp_free(t3);
13393 tcg_temp_free(t2);
13394 } else if (rs < rt && rs == 0) {
13395 /* OPC_BEQZALC, OPC_BNEZALC */
13396 if (opc == OPC_BEQZALC) {
13397 /* OPC_BEQZALC */
13398 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13399 } else {
13400 /* OPC_BNEZALC */
13401 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13402 }
13403 } else {
13404 /* OPC_BEQC, OPC_BNEC */
13405 if (opc == OPC_BEQC) {
13406 /* OPC_BEQC */
13407 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13408 } else {
13409 /* OPC_BNEC */
13410 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13411 }
13412 }
13413 break;
13414 case OPC_BEQZC:
13415 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13416 break;
13417 case OPC_BNEZC:
13418 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13419 break;
13420 default:
13421 MIPS_INVAL("Compact conditional branch/jump");
3a4ef3b7 13422 gen_reserved_instruction(ctx);
6893f074
YK
13423 goto out;
13424 }
13425
13426 /* Generating branch here as compact branches don't have delay slot */
13427 gen_goto_tb(ctx, 1, ctx->btarget);
13428 gen_set_label(fs);
13429
13430 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
13431 }
13432
13433out:
13434 tcg_temp_free(t0);
13435 tcg_temp_free(t1);
13436}
13437
7a387fff 13438/* ISA extensions (ASEs) */
6af0bf9c 13439/* MIPS16 extension to MIPS32 */
6ea219d0
NF
13440
13441/* MIPS16 major opcodes */
13442enum {
13443 M16_OPC_ADDIUSP = 0x00,
13444 M16_OPC_ADDIUPC = 0x01,
13445 M16_OPC_B = 0x02,
13446 M16_OPC_JAL = 0x03,
13447 M16_OPC_BEQZ = 0x04,
13448 M16_OPC_BNEQZ = 0x05,
13449 M16_OPC_SHIFT = 0x06,
13450 M16_OPC_LD = 0x07,
13451 M16_OPC_RRIA = 0x08,
13452 M16_OPC_ADDIU8 = 0x09,
13453 M16_OPC_SLTI = 0x0a,
13454 M16_OPC_SLTIU = 0x0b,
13455 M16_OPC_I8 = 0x0c,
13456 M16_OPC_LI = 0x0d,
13457 M16_OPC_CMPI = 0x0e,
13458 M16_OPC_SD = 0x0f,
13459 M16_OPC_LB = 0x10,
13460 M16_OPC_LH = 0x11,
13461 M16_OPC_LWSP = 0x12,
13462 M16_OPC_LW = 0x13,
13463 M16_OPC_LBU = 0x14,
13464 M16_OPC_LHU = 0x15,
13465 M16_OPC_LWPC = 0x16,
13466 M16_OPC_LWU = 0x17,
13467 M16_OPC_SB = 0x18,
13468 M16_OPC_SH = 0x19,
13469 M16_OPC_SWSP = 0x1a,
13470 M16_OPC_SW = 0x1b,
13471 M16_OPC_RRR = 0x1c,
13472 M16_OPC_RR = 0x1d,
13473 M16_OPC_EXTEND = 0x1e,
13474 M16_OPC_I64 = 0x1f
13475};
13476
13477/* I8 funct field */
13478enum {
13479 I8_BTEQZ = 0x0,
13480 I8_BTNEZ = 0x1,
13481 I8_SWRASP = 0x2,
13482 I8_ADJSP = 0x3,
13483 I8_SVRS = 0x4,
13484 I8_MOV32R = 0x5,
13485 I8_MOVR32 = 0x7
13486};
13487
13488/* RRR f field */
13489enum {
13490 RRR_DADDU = 0x0,
13491 RRR_ADDU = 0x1,
13492 RRR_DSUBU = 0x2,
13493 RRR_SUBU = 0x3
13494};
13495
13496/* RR funct field */
13497enum {
13498 RR_JR = 0x00,
13499 RR_SDBBP = 0x01,
13500 RR_SLT = 0x02,
13501 RR_SLTU = 0x03,
13502 RR_SLLV = 0x04,
13503 RR_BREAK = 0x05,
13504 RR_SRLV = 0x06,
13505 RR_SRAV = 0x07,
13506 RR_DSRL = 0x08,
13507 RR_CMP = 0x0a,
13508 RR_NEG = 0x0b,
13509 RR_AND = 0x0c,
13510 RR_OR = 0x0d,
13511 RR_XOR = 0x0e,
13512 RR_NOT = 0x0f,
13513 RR_MFHI = 0x10,
13514 RR_CNVT = 0x11,
13515 RR_MFLO = 0x12,
13516 RR_DSRA = 0x13,
13517 RR_DSLLV = 0x14,
13518 RR_DSRLV = 0x16,
13519 RR_DSRAV = 0x17,
13520 RR_MULT = 0x18,
13521 RR_MULTU = 0x19,
13522 RR_DIV = 0x1a,
13523 RR_DIVU = 0x1b,
13524 RR_DMULT = 0x1c,
13525 RR_DMULTU = 0x1d,
13526 RR_DDIV = 0x1e,
13527 RR_DDIVU = 0x1f
13528};
13529
13530/* I64 funct field */
13531enum {
13532 I64_LDSP = 0x0,
13533 I64_SDSP = 0x1,
13534 I64_SDRASP = 0x2,
13535 I64_DADJSP = 0x3,
13536 I64_LDPC = 0x4,
364d4831 13537 I64_DADDIU5 = 0x5,
6ea219d0
NF
13538 I64_DADDIUPC = 0x6,
13539 I64_DADDIUSP = 0x7
13540};
13541
13542/* RR ry field for CNVT */
13543enum {
13544 RR_RY_CNVT_ZEB = 0x0,
13545 RR_RY_CNVT_ZEH = 0x1,
13546 RR_RY_CNVT_ZEW = 0x2,
13547 RR_RY_CNVT_SEB = 0x4,
13548 RR_RY_CNVT_SEH = 0x5,
13549 RR_RY_CNVT_SEW = 0x6,
13550};
13551
235785e8 13552static int xlat(int r)
364d4831
NF
13553{
13554 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13555
13556 return map[r];
13557}
13558
235785e8
AM
13559static void gen_mips16_save(DisasContext *ctx,
13560 int xsregs, int aregs,
13561 int do_ra, int do_s0, int do_s1,
13562 int framesize)
364d4831
NF
13563{
13564 TCGv t0 = tcg_temp_new();
13565 TCGv t1 = tcg_temp_new();
c48245f0 13566 TCGv t2 = tcg_temp_new();
364d4831
NF
13567 int args, astatic;
13568
13569 switch (aregs) {
13570 case 0:
13571 case 1:
13572 case 2:
13573 case 3:
13574 case 11:
13575 args = 0;
13576 break;
13577 case 4:
13578 case 5:
13579 case 6:
13580 case 7:
13581 args = 1;
13582 break;
13583 case 8:
13584 case 9:
13585 case 10:
13586 args = 2;
13587 break;
13588 case 12:
13589 case 13:
13590 args = 3;
13591 break;
13592 case 14:
13593 args = 4;
13594 break;
13595 default:
3a4ef3b7 13596 gen_reserved_instruction(ctx);
364d4831
NF
13597 return;
13598 }
13599
13600 switch (args) {
13601 case 4:
13602 gen_base_offset_addr(ctx, t0, 29, 12);
13603 gen_load_gpr(t1, 7);
5f68f5ae 13604 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13605 /* Fall through */
13606 case 3:
13607 gen_base_offset_addr(ctx, t0, 29, 8);
13608 gen_load_gpr(t1, 6);
5f68f5ae 13609 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13610 /* Fall through */
13611 case 2:
13612 gen_base_offset_addr(ctx, t0, 29, 4);
13613 gen_load_gpr(t1, 5);
5f68f5ae 13614 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13615 /* Fall through */
13616 case 1:
13617 gen_base_offset_addr(ctx, t0, 29, 0);
13618 gen_load_gpr(t1, 4);
5f68f5ae 13619 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13620 }
13621
13622 gen_load_gpr(t0, 29);
13623
5f68f5ae 13624#define DECR_AND_STORE(reg) do { \
c48245f0
MR
13625 tcg_gen_movi_tl(t2, -4); \
13626 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13627 gen_load_gpr(t1, reg); \
13628 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
13629 } while (0)
13630
13631 if (do_ra) {
13632 DECR_AND_STORE(31);
13633 }
13634
13635 switch (xsregs) {
13636 case 7:
13637 DECR_AND_STORE(30);
13638 /* Fall through */
13639 case 6:
13640 DECR_AND_STORE(23);
13641 /* Fall through */
13642 case 5:
13643 DECR_AND_STORE(22);
13644 /* Fall through */
13645 case 4:
13646 DECR_AND_STORE(21);
13647 /* Fall through */
13648 case 3:
13649 DECR_AND_STORE(20);
13650 /* Fall through */
13651 case 2:
13652 DECR_AND_STORE(19);
13653 /* Fall through */
13654 case 1:
13655 DECR_AND_STORE(18);
13656 }
13657
13658 if (do_s1) {
13659 DECR_AND_STORE(17);
13660 }
13661 if (do_s0) {
13662 DECR_AND_STORE(16);
13663 }
13664
13665 switch (aregs) {
13666 case 0:
13667 case 4:
13668 case 8:
13669 case 12:
13670 case 14:
13671 astatic = 0;
13672 break;
13673 case 1:
13674 case 5:
13675 case 9:
13676 case 13:
13677 astatic = 1;
13678 break;
13679 case 2:
13680 case 6:
13681 case 10:
13682 astatic = 2;
13683 break;
13684 case 3:
13685 case 7:
13686 astatic = 3;
13687 break;
13688 case 11:
13689 astatic = 4;
13690 break;
13691 default:
3a4ef3b7 13692 gen_reserved_instruction(ctx);
364d4831
NF
13693 return;
13694 }
13695
13696 if (astatic > 0) {
13697 DECR_AND_STORE(7);
13698 if (astatic > 1) {
13699 DECR_AND_STORE(6);
13700 if (astatic > 2) {
13701 DECR_AND_STORE(5);
13702 if (astatic > 3) {
13703 DECR_AND_STORE(4);
13704 }
13705 }
13706 }
13707 }
13708#undef DECR_AND_STORE
13709
c48245f0
MR
13710 tcg_gen_movi_tl(t2, -framesize);
13711 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13712 tcg_temp_free(t0);
13713 tcg_temp_free(t1);
c48245f0 13714 tcg_temp_free(t2);
364d4831
NF
13715}
13716
235785e8
AM
13717static void gen_mips16_restore(DisasContext *ctx,
13718 int xsregs, int aregs,
13719 int do_ra, int do_s0, int do_s1,
13720 int framesize)
364d4831
NF
13721{
13722 int astatic;
13723 TCGv t0 = tcg_temp_new();
13724 TCGv t1 = tcg_temp_new();
c48245f0 13725 TCGv t2 = tcg_temp_new();
364d4831 13726
c48245f0
MR
13727 tcg_gen_movi_tl(t2, framesize);
13728 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 13729
5f68f5ae 13730#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
13731 tcg_gen_movi_tl(t2, -4); \
13732 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13733 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13734 gen_store_gpr(t1, reg); \
364d4831
NF
13735 } while (0)
13736
13737 if (do_ra) {
13738 DECR_AND_LOAD(31);
13739 }
13740
13741 switch (xsregs) {
13742 case 7:
13743 DECR_AND_LOAD(30);
13744 /* Fall through */
13745 case 6:
13746 DECR_AND_LOAD(23);
13747 /* Fall through */
13748 case 5:
13749 DECR_AND_LOAD(22);
13750 /* Fall through */
13751 case 4:
13752 DECR_AND_LOAD(21);
13753 /* Fall through */
13754 case 3:
13755 DECR_AND_LOAD(20);
13756 /* Fall through */
13757 case 2:
13758 DECR_AND_LOAD(19);
13759 /* Fall through */
13760 case 1:
13761 DECR_AND_LOAD(18);
13762 }
13763
13764 if (do_s1) {
13765 DECR_AND_LOAD(17);
13766 }
13767 if (do_s0) {
13768 DECR_AND_LOAD(16);
13769 }
13770
13771 switch (aregs) {
13772 case 0:
13773 case 4:
13774 case 8:
13775 case 12:
13776 case 14:
13777 astatic = 0;
13778 break;
13779 case 1:
13780 case 5:
13781 case 9:
13782 case 13:
13783 astatic = 1;
13784 break;
13785 case 2:
13786 case 6:
13787 case 10:
13788 astatic = 2;
13789 break;
13790 case 3:
13791 case 7:
13792 astatic = 3;
13793 break;
13794 case 11:
13795 astatic = 4;
13796 break;
13797 default:
3a4ef3b7 13798 gen_reserved_instruction(ctx);
364d4831
NF
13799 return;
13800 }
13801
13802 if (astatic > 0) {
13803 DECR_AND_LOAD(7);
13804 if (astatic > 1) {
13805 DECR_AND_LOAD(6);
13806 if (astatic > 2) {
13807 DECR_AND_LOAD(5);
13808 if (astatic > 3) {
13809 DECR_AND_LOAD(4);
13810 }
13811 }
13812 }
13813 }
13814#undef DECR_AND_LOAD
13815
c48245f0
MR
13816 tcg_gen_movi_tl(t2, framesize);
13817 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13818 tcg_temp_free(t0);
13819 tcg_temp_free(t1);
c48245f0 13820 tcg_temp_free(t2);
364d4831
NF
13821}
13822
235785e8
AM
13823static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13824 int is_64_bit, int extended)
364d4831
NF
13825{
13826 TCGv t0;
13827
13828 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 13829 gen_reserved_instruction(ctx);
364d4831
NF
13830 return;
13831 }
13832
13833 t0 = tcg_temp_new();
13834
13835 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13836 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13837 if (!is_64_bit) {
13838 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13839 }
13840
13841 tcg_temp_free(t0);
13842}
13843
0d74a222
LA
13844static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13845 int16_t offset)
13846{
13847 TCGv_i32 t0 = tcg_const_i32(op);
13848 TCGv t1 = tcg_temp_new();
13849 gen_base_offset_addr(ctx, t1, base, offset);
13850 gen_helper_cache(cpu_env, t1, t0);
13851}
13852
364d4831 13853#if defined(TARGET_MIPS64)
235785e8
AM
13854static void decode_i64_mips16(DisasContext *ctx,
13855 int ry, int funct, int16_t offset,
13856 int extended)
364d4831
NF
13857{
13858 switch (funct) {
13859 case I64_LDSP:
d9224450 13860 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13861 check_mips_64(ctx);
13862 offset = extended ? offset : offset << 3;
d75c135e 13863 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
13864 break;
13865 case I64_SDSP:
d9224450 13866 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13867 check_mips_64(ctx);
13868 offset = extended ? offset : offset << 3;
5c13fdfd 13869 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
13870 break;
13871 case I64_SDRASP:
d9224450 13872 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13873 check_mips_64(ctx);
13874 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 13875 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
13876 break;
13877 case I64_DADJSP:
d9224450 13878 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13879 check_mips_64(ctx);
13880 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 13881 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
13882 break;
13883 case I64_LDPC:
d9224450
MR
13884 check_insn(ctx, ISA_MIPS3);
13885 check_mips_64(ctx);
364d4831 13886 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 13887 gen_reserved_instruction(ctx);
364d4831
NF
13888 } else {
13889 offset = extended ? offset : offset << 3;
d75c135e 13890 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
13891 }
13892 break;
13893 case I64_DADDIU5:
d9224450 13894 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13895 check_mips_64(ctx);
13896 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 13897 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
13898 break;
13899 case I64_DADDIUPC:
d9224450 13900 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13901 check_mips_64(ctx);
13902 offset = extended ? offset : offset << 2;
13903 gen_addiupc(ctx, ry, offset, 1, extended);
13904 break;
13905 case I64_DADDIUSP:
d9224450 13906 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13907 check_mips_64(ctx);
13908 offset = extended ? offset : offset << 2;
d75c135e 13909 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
13910 break;
13911 }
13912}
13913#endif
13914
235785e8 13915static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
364d4831 13916{
eeb3bba8 13917 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13918 int op, rx, ry, funct, sa;
13919 int16_t imm, offset;
13920
13921 ctx->opcode = (ctx->opcode << 16) | extend;
13922 op = (ctx->opcode >> 11) & 0x1f;
13923 sa = (ctx->opcode >> 22) & 0x1f;
13924 funct = (ctx->opcode >> 8) & 0x7;
13925 rx = xlat((ctx->opcode >> 8) & 0x7);
13926 ry = xlat((ctx->opcode >> 5) & 0x7);
13927 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13928 | ((ctx->opcode >> 21) & 0x3f) << 5
13929 | (ctx->opcode & 0x1f));
13930
7480515f
AM
13931 /*
13932 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13933 * counterparts.
13934 */
364d4831
NF
13935 switch (op) {
13936 case M16_OPC_ADDIUSP:
d75c135e 13937 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13938 break;
13939 case M16_OPC_ADDIUPC:
13940 gen_addiupc(ctx, rx, imm, 0, 1);
13941 break;
13942 case M16_OPC_B:
b231c103 13943 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
13944 /* No delay slot, so just process as a normal instruction */
13945 break;
13946 case M16_OPC_BEQZ:
b231c103 13947 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
13948 /* No delay slot, so just process as a normal instruction */
13949 break;
13950 case M16_OPC_BNEQZ:
b231c103 13951 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
13952 /* No delay slot, so just process as a normal instruction */
13953 break;
13954 case M16_OPC_SHIFT:
13955 switch (ctx->opcode & 0x3) {
13956 case 0x0:
d75c135e 13957 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13958 break;
13959 case 0x1:
13960#if defined(TARGET_MIPS64)
13961 check_mips_64(ctx);
d75c135e 13962 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13963#else
3a4ef3b7 13964 gen_reserved_instruction(ctx);
364d4831
NF
13965#endif
13966 break;
13967 case 0x2:
d75c135e 13968 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13969 break;
13970 case 0x3:
d75c135e 13971 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13972 break;
13973 }
13974 break;
13975#if defined(TARGET_MIPS64)
13976 case M16_OPC_LD:
d9224450 13977 check_insn(ctx, ISA_MIPS3);
d75de749 13978 check_mips_64(ctx);
d75c135e 13979 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
13980 break;
13981#endif
13982 case M16_OPC_RRIA:
13983 imm = ctx->opcode & 0xf;
13984 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13985 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13986 imm = (int16_t) (imm << 1) >> 1;
13987 if ((ctx->opcode >> 4) & 0x1) {
13988#if defined(TARGET_MIPS64)
13989 check_mips_64(ctx);
d75c135e 13990 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13991#else
3a4ef3b7 13992 gen_reserved_instruction(ctx);
364d4831
NF
13993#endif
13994 } else {
d75c135e 13995 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13996 }
13997 break;
13998 case M16_OPC_ADDIU8:
d75c135e 13999 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
14000 break;
14001 case M16_OPC_SLTI:
d75c135e 14002 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
14003 break;
14004 case M16_OPC_SLTIU:
d75c135e 14005 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
14006 break;
14007 case M16_OPC_I8:
14008 switch (funct) {
14009 case I8_BTEQZ:
b231c103 14010 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
14011 break;
14012 case I8_BTNEZ:
b231c103 14013 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
14014 break;
14015 case I8_SWRASP:
5c13fdfd 14016 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
14017 break;
14018 case I8_ADJSP:
d75c135e 14019 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
14020 break;
14021 case I8_SVRS:
bbd5e4a2 14022 check_insn(ctx, ISA_MIPS_R1);
364d4831
NF
14023 {
14024 int xsregs = (ctx->opcode >> 24) & 0x7;
14025 int aregs = (ctx->opcode >> 16) & 0xf;
14026 int do_ra = (ctx->opcode >> 6) & 0x1;
14027 int do_s0 = (ctx->opcode >> 5) & 0x1;
14028 int do_s1 = (ctx->opcode >> 4) & 0x1;
14029 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
14030 | (ctx->opcode & 0xf)) << 3;
14031
14032 if (ctx->opcode & (1 << 7)) {
14033 gen_mips16_save(ctx, xsregs, aregs,
14034 do_ra, do_s0, do_s1,
14035 framesize);
14036 } else {
14037 gen_mips16_restore(ctx, xsregs, aregs,
14038 do_ra, do_s0, do_s1,
14039 framesize);
14040 }
14041 }
14042 break;
14043 default:
3a4ef3b7 14044 gen_reserved_instruction(ctx);
364d4831
NF
14045 break;
14046 }
14047 break;
14048 case M16_OPC_LI:
14049 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
14050 break;
14051 case M16_OPC_CMPI:
14052 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
14053 break;
14054#if defined(TARGET_MIPS64)
14055 case M16_OPC_SD:
d9224450
MR
14056 check_insn(ctx, ISA_MIPS3);
14057 check_mips_64(ctx);
5c13fdfd 14058 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
14059 break;
14060#endif
14061 case M16_OPC_LB:
d75c135e 14062 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
14063 break;
14064 case M16_OPC_LH:
d75c135e 14065 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
14066 break;
14067 case M16_OPC_LWSP:
d75c135e 14068 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
14069 break;
14070 case M16_OPC_LW:
d75c135e 14071 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
14072 break;
14073 case M16_OPC_LBU:
d75c135e 14074 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
14075 break;
14076 case M16_OPC_LHU:
d75c135e 14077 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
14078 break;
14079 case M16_OPC_LWPC:
d75c135e 14080 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
14081 break;
14082#if defined(TARGET_MIPS64)
14083 case M16_OPC_LWU:
d9224450
MR
14084 check_insn(ctx, ISA_MIPS3);
14085 check_mips_64(ctx);
d75c135e 14086 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
14087 break;
14088#endif
14089 case M16_OPC_SB:
5c13fdfd 14090 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
14091 break;
14092 case M16_OPC_SH:
5c13fdfd 14093 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
14094 break;
14095 case M16_OPC_SWSP:
5c13fdfd 14096 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
14097 break;
14098 case M16_OPC_SW:
5c13fdfd 14099 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
14100 break;
14101#if defined(TARGET_MIPS64)
14102 case M16_OPC_I64:
d75c135e 14103 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
14104 break;
14105#endif
14106 default:
3a4ef3b7 14107 gen_reserved_instruction(ctx);
364d4831
NF
14108 break;
14109 }
14110
14111 return 4;
14112}
14113
3b3c1694
LA
14114static inline bool is_uhi(int sdbbp_code)
14115{
14116#ifdef CONFIG_USER_ONLY
14117 return false;
14118#else
14119 return semihosting_enabled() && sdbbp_code == 1;
14120#endif
14121}
14122
82ba4266
AB
14123#ifdef CONFIG_USER_ONLY
14124/* The above should dead-code away any calls to this..*/
14125static inline void gen_helper_do_semihosting(void *env)
14126{
14127 g_assert_not_reached();
14128}
14129#endif
14130
235785e8 14131static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
14132{
14133 int rx, ry;
14134 int sa;
14135 int op, cnvt_op, op1, offset;
14136 int funct;
14137 int n_bytes;
14138
14139 op = (ctx->opcode >> 11) & 0x1f;
14140 sa = (ctx->opcode >> 2) & 0x7;
14141 sa = sa == 0 ? 8 : sa;
14142 rx = xlat((ctx->opcode >> 8) & 0x7);
14143 cnvt_op = (ctx->opcode >> 5) & 0x7;
14144 ry = xlat((ctx->opcode >> 5) & 0x7);
14145 op1 = offset = ctx->opcode & 0x1f;
14146
14147 n_bytes = 2;
14148
14149 switch (op) {
14150 case M16_OPC_ADDIUSP:
14151 {
14152 int16_t imm = ((uint8_t) ctx->opcode) << 2;
14153
d75c135e 14154 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
14155 }
14156 break;
14157 case M16_OPC_ADDIUPC:
14158 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
14159 break;
14160 case M16_OPC_B:
14161 offset = (ctx->opcode & 0x7ff) << 1;
14162 offset = (int16_t)(offset << 4) >> 4;
b231c103 14163 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
14164 /* No delay slot, so just process as a normal instruction */
14165 break;
14166 case M16_OPC_JAL:
eeb3bba8 14167 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
14168 offset = (((ctx->opcode & 0x1f) << 21)
14169 | ((ctx->opcode >> 5) & 0x1f) << 16
14170 | offset) << 2;
b231c103
YK
14171 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
14172 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 14173 n_bytes = 4;
364d4831
NF
14174 break;
14175 case M16_OPC_BEQZ:
b231c103
YK
14176 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
14177 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
14178 /* No delay slot, so just process as a normal instruction */
14179 break;
14180 case M16_OPC_BNEQZ:
b231c103
YK
14181 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
14182 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
14183 /* No delay slot, so just process as a normal instruction */
14184 break;
14185 case M16_OPC_SHIFT:
14186 switch (ctx->opcode & 0x3) {
14187 case 0x0:
d75c135e 14188 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
14189 break;
14190 case 0x1:
14191#if defined(TARGET_MIPS64)
d9224450 14192 check_insn(ctx, ISA_MIPS3);
364d4831 14193 check_mips_64(ctx);
d75c135e 14194 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 14195#else
3a4ef3b7 14196 gen_reserved_instruction(ctx);
364d4831
NF
14197#endif
14198 break;
14199 case 0x2:
d75c135e 14200 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
14201 break;
14202 case 0x3:
d75c135e 14203 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
14204 break;
14205 }
14206 break;
14207#if defined(TARGET_MIPS64)
14208 case M16_OPC_LD:
d9224450 14209 check_insn(ctx, ISA_MIPS3);
364d4831 14210 check_mips_64(ctx);
d75c135e 14211 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
14212 break;
14213#endif
14214 case M16_OPC_RRIA:
14215 {
14216 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
14217
14218 if ((ctx->opcode >> 4) & 1) {
14219#if defined(TARGET_MIPS64)
d9224450 14220 check_insn(ctx, ISA_MIPS3);
364d4831 14221 check_mips_64(ctx);
d75c135e 14222 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 14223#else
3a4ef3b7 14224 gen_reserved_instruction(ctx);
364d4831
NF
14225#endif
14226 } else {
d75c135e 14227 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
14228 }
14229 }
14230 break;
14231 case M16_OPC_ADDIU8:
14232 {
14233 int16_t imm = (int8_t) ctx->opcode;
14234
d75c135e 14235 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
14236 }
14237 break;
14238 case M16_OPC_SLTI:
14239 {
14240 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 14241 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
14242 }
14243 break;
14244 case M16_OPC_SLTIU:
14245 {
14246 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 14247 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
14248 }
14249 break;
14250 case M16_OPC_I8:
14251 {
14252 int reg32;
14253
14254 funct = (ctx->opcode >> 8) & 0x7;
14255 switch (funct) {
14256 case I8_BTEQZ:
14257 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 14258 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
14259 break;
14260 case I8_BTNEZ:
14261 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 14262 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
14263 break;
14264 case I8_SWRASP:
5c13fdfd 14265 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
14266 break;
14267 case I8_ADJSP:
d75c135e 14268 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
14269 ((int8_t)ctx->opcode) << 3);
14270 break;
14271 case I8_SVRS:
bbd5e4a2 14272 check_insn(ctx, ISA_MIPS_R1);
364d4831
NF
14273 {
14274 int do_ra = ctx->opcode & (1 << 6);
14275 int do_s0 = ctx->opcode & (1 << 5);
14276 int do_s1 = ctx->opcode & (1 << 4);
14277 int framesize = ctx->opcode & 0xf;
14278
14279 if (framesize == 0) {
14280 framesize = 128;
14281 } else {
14282 framesize = framesize << 3;
14283 }
14284
14285 if (ctx->opcode & (1 << 7)) {
14286 gen_mips16_save(ctx, 0, 0,
14287 do_ra, do_s0, do_s1, framesize);
14288 } else {
14289 gen_mips16_restore(ctx, 0, 0,
14290 do_ra, do_s0, do_s1, framesize);
14291 }
14292 }
14293 break;
14294 case I8_MOV32R:
14295 {
14296 int rz = xlat(ctx->opcode & 0x7);
14297
14298 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14299 ((ctx->opcode >> 5) & 0x7);
d75c135e 14300 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
14301 }
14302 break;
14303 case I8_MOVR32:
14304 reg32 = ctx->opcode & 0x1f;
d75c135e 14305 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
14306 break;
14307 default:
3a4ef3b7 14308 gen_reserved_instruction(ctx);
364d4831
NF
14309 break;
14310 }
14311 }
14312 break;
14313 case M16_OPC_LI:
14314 {
14315 int16_t imm = (uint8_t) ctx->opcode;
14316
d75c135e 14317 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
14318 }
14319 break;
14320 case M16_OPC_CMPI:
14321 {
14322 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 14323 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
14324 }
14325 break;
14326#if defined(TARGET_MIPS64)
14327 case M16_OPC_SD:
d9224450 14328 check_insn(ctx, ISA_MIPS3);
364d4831 14329 check_mips_64(ctx);
5c13fdfd 14330 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
14331 break;
14332#endif
14333 case M16_OPC_LB:
d75c135e 14334 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
14335 break;
14336 case M16_OPC_LH:
d75c135e 14337 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
14338 break;
14339 case M16_OPC_LWSP:
d75c135e 14340 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
14341 break;
14342 case M16_OPC_LW:
d75c135e 14343 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
14344 break;
14345 case M16_OPC_LBU:
d75c135e 14346 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
14347 break;
14348 case M16_OPC_LHU:
d75c135e 14349 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
14350 break;
14351 case M16_OPC_LWPC:
d75c135e 14352 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831 14353 break;
235785e8 14354#if defined(TARGET_MIPS64)
364d4831 14355 case M16_OPC_LWU:
d9224450 14356 check_insn(ctx, ISA_MIPS3);
364d4831 14357 check_mips_64(ctx);
d75c135e 14358 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
14359 break;
14360#endif
14361 case M16_OPC_SB:
5c13fdfd 14362 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
14363 break;
14364 case M16_OPC_SH:
5c13fdfd 14365 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
14366 break;
14367 case M16_OPC_SWSP:
5c13fdfd 14368 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
14369 break;
14370 case M16_OPC_SW:
5c13fdfd 14371 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
14372 break;
14373 case M16_OPC_RRR:
14374 {
14375 int rz = xlat((ctx->opcode >> 2) & 0x7);
14376 int mips32_op;
14377
14378 switch (ctx->opcode & 0x3) {
14379 case RRR_ADDU:
14380 mips32_op = OPC_ADDU;
14381 break;
14382 case RRR_SUBU:
14383 mips32_op = OPC_SUBU;
14384 break;
14385#if defined(TARGET_MIPS64)
14386 case RRR_DADDU:
14387 mips32_op = OPC_DADDU;
d9224450 14388 check_insn(ctx, ISA_MIPS3);
364d4831
NF
14389 check_mips_64(ctx);
14390 break;
14391 case RRR_DSUBU:
14392 mips32_op = OPC_DSUBU;
d9224450 14393 check_insn(ctx, ISA_MIPS3);
364d4831
NF
14394 check_mips_64(ctx);
14395 break;
14396#endif
14397 default:
3a4ef3b7 14398 gen_reserved_instruction(ctx);
364d4831
NF
14399 goto done;
14400 }
14401
d75c135e 14402 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
14403 done:
14404 ;
14405 }
14406 break;
14407 case M16_OPC_RR:
14408 switch (op1) {
14409 case RR_JR:
14410 {
14411 int nd = (ctx->opcode >> 7) & 0x1;
14412 int link = (ctx->opcode >> 6) & 0x1;
14413 int ra = (ctx->opcode >> 5) & 0x1;
14414
d9224450 14415 if (nd) {
bbd5e4a2 14416 check_insn(ctx, ISA_MIPS_R1);
d9224450
MR
14417 }
14418
364d4831 14419 if (link) {
b231c103 14420 op = OPC_JALR;
364d4831
NF
14421 } else {
14422 op = OPC_JR;
14423 }
14424
b231c103
YK
14425 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14426 (nd ? 0 : 2));
364d4831
NF
14427 }
14428 break;
14429 case RR_SDBBP:
3b3c1694
LA
14430 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14431 gen_helper_do_semihosting(cpu_env);
14432 } else {
7480515f
AM
14433 /*
14434 * XXX: not clear which exception should be raised
3b3c1694
LA
14435 * when in debug mode...
14436 */
bbd5e4a2 14437 check_insn(ctx, ISA_MIPS_R1);
9c708c7f 14438 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14439 }
364d4831
NF
14440 break;
14441 case RR_SLT:
d75c135e 14442 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
14443 break;
14444 case RR_SLTU:
d75c135e 14445 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
14446 break;
14447 case RR_BREAK:
9c708c7f 14448 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
14449 break;
14450 case RR_SLLV:
d75c135e 14451 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
14452 break;
14453 case RR_SRLV:
d75c135e 14454 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
14455 break;
14456 case RR_SRAV:
d75c135e 14457 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831 14458 break;
235785e8 14459#if defined(TARGET_MIPS64)
364d4831 14460 case RR_DSRL:
d9224450 14461 check_insn(ctx, ISA_MIPS3);
364d4831 14462 check_mips_64(ctx);
d75c135e 14463 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
14464 break;
14465#endif
14466 case RR_CMP:
d75c135e 14467 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
14468 break;
14469 case RR_NEG:
d75c135e 14470 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
14471 break;
14472 case RR_AND:
d75c135e 14473 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
14474 break;
14475 case RR_OR:
d75c135e 14476 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
14477 break;
14478 case RR_XOR:
d75c135e 14479 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
14480 break;
14481 case RR_NOT:
d75c135e 14482 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
14483 break;
14484 case RR_MFHI:
26135ead 14485 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
14486 break;
14487 case RR_CNVT:
bbd5e4a2 14488 check_insn(ctx, ISA_MIPS_R1);
364d4831
NF
14489 switch (cnvt_op) {
14490 case RR_RY_CNVT_ZEB:
14491 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14492 break;
14493 case RR_RY_CNVT_ZEH:
14494 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14495 break;
14496 case RR_RY_CNVT_SEB:
14497 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14498 break;
14499 case RR_RY_CNVT_SEH:
14500 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14501 break;
71375b59 14502#if defined(TARGET_MIPS64)
364d4831 14503 case RR_RY_CNVT_ZEW:
bbd5e4a2 14504 check_insn(ctx, ISA_MIPS_R1);
364d4831
NF
14505 check_mips_64(ctx);
14506 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14507 break;
14508 case RR_RY_CNVT_SEW:
bbd5e4a2 14509 check_insn(ctx, ISA_MIPS_R1);
364d4831
NF
14510 check_mips_64(ctx);
14511 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14512 break;
14513#endif
14514 default:
3a4ef3b7 14515 gen_reserved_instruction(ctx);
364d4831
NF
14516 break;
14517 }
14518 break;
14519 case RR_MFLO:
26135ead 14520 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831 14521 break;
235785e8 14522#if defined(TARGET_MIPS64)
364d4831 14523 case RR_DSRA:
d9224450 14524 check_insn(ctx, ISA_MIPS3);
364d4831 14525 check_mips_64(ctx);
d75c135e 14526 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
14527 break;
14528 case RR_DSLLV:
d9224450 14529 check_insn(ctx, ISA_MIPS3);
364d4831 14530 check_mips_64(ctx);
d75c135e 14531 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
14532 break;
14533 case RR_DSRLV:
d9224450 14534 check_insn(ctx, ISA_MIPS3);
364d4831 14535 check_mips_64(ctx);
d75c135e 14536 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
14537 break;
14538 case RR_DSRAV:
d9224450 14539 check_insn(ctx, ISA_MIPS3);
364d4831 14540 check_mips_64(ctx);
d75c135e 14541 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
14542 break;
14543#endif
14544 case RR_MULT:
26135ead 14545 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
14546 break;
14547 case RR_MULTU:
26135ead 14548 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
14549 break;
14550 case RR_DIV:
26135ead 14551 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
14552 break;
14553 case RR_DIVU:
26135ead 14554 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831 14555 break;
235785e8 14556#if defined(TARGET_MIPS64)
364d4831 14557 case RR_DMULT:
d9224450 14558 check_insn(ctx, ISA_MIPS3);
364d4831 14559 check_mips_64(ctx);
26135ead 14560 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
14561 break;
14562 case RR_DMULTU:
d9224450 14563 check_insn(ctx, ISA_MIPS3);
364d4831 14564 check_mips_64(ctx);
26135ead 14565 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
14566 break;
14567 case RR_DDIV:
d9224450 14568 check_insn(ctx, ISA_MIPS3);
364d4831 14569 check_mips_64(ctx);
26135ead 14570 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
14571 break;
14572 case RR_DDIVU:
d9224450 14573 check_insn(ctx, ISA_MIPS3);
364d4831 14574 check_mips_64(ctx);
26135ead 14575 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
14576 break;
14577#endif
14578 default:
3a4ef3b7 14579 gen_reserved_instruction(ctx);
364d4831
NF
14580 break;
14581 }
14582 break;
14583 case M16_OPC_EXTEND:
240ce26a 14584 decode_extended_mips16_opc(env, ctx);
364d4831
NF
14585 n_bytes = 4;
14586 break;
14587#if defined(TARGET_MIPS64)
14588 case M16_OPC_I64:
14589 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 14590 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
14591 break;
14592#endif
14593 default:
3a4ef3b7 14594 gen_reserved_instruction(ctx);
364d4831
NF
14595 break;
14596 }
14597
14598 return n_bytes;
14599}
14600
211da992 14601/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 14602
211da992
CWR
14603/*
14604 * microMIPS32/microMIPS64 major opcodes
14605 *
14606 * 1. MIPS Architecture for Programmers Volume II-B:
14607 * The microMIPS32 Instruction Set (Revision 3.05)
14608 *
14609 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14610 *
14611 * 2. MIPS Architecture For Programmers Volume II-A:
14612 * The MIPS64 Instruction Set (Revision 3.51)
14613 */
6af0bf9c 14614
3c824109
NF
14615enum {
14616 POOL32A = 0x00,
14617 POOL16A = 0x01,
14618 LBU16 = 0x02,
14619 MOVE16 = 0x03,
14620 ADDI32 = 0x04,
3a1f4268
YK
14621 R6_LUI = 0x04,
14622 AUI = 0x04,
3c824109
NF
14623 LBU32 = 0x05,
14624 SB32 = 0x06,
14625 LB32 = 0x07,
14626
14627 POOL32B = 0x08,
14628 POOL16B = 0x09,
14629 LHU16 = 0x0a,
14630 ANDI16 = 0x0b,
14631 ADDIU32 = 0x0c,
14632 LHU32 = 0x0d,
14633 SH32 = 0x0e,
14634 LH32 = 0x0f,
14635
14636 POOL32I = 0x10,
14637 POOL16C = 0x11,
14638 LWSP16 = 0x12,
14639 POOL16D = 0x13,
14640 ORI32 = 0x14,
14641 POOL32F = 0x15,
211da992
CWR
14642 POOL32S = 0x16, /* MIPS64 */
14643 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
14644
14645 POOL32C = 0x18,
14646 LWGP16 = 0x19,
14647 LW16 = 0x1a,
14648 POOL16E = 0x1b,
14649 XORI32 = 0x1c,
14650 JALS32 = 0x1d,
3a1f4268
YK
14651 BOVC = 0x1d,
14652 BEQC = 0x1d,
14653 BEQZALC = 0x1d,
3c824109 14654 ADDIUPC = 0x1e,
3a1f4268
YK
14655 PCREL = 0x1e,
14656 BNVC = 0x1f,
14657 BNEC = 0x1f,
14658 BNEZALC = 0x1f,
3c824109 14659
3a1f4268
YK
14660 R6_BEQZC = 0x20,
14661 JIC = 0x20,
3c824109
NF
14662 POOL16F = 0x21,
14663 SB16 = 0x22,
14664 BEQZ16 = 0x23,
3a1f4268 14665 BEQZC16 = 0x23,
3c824109
NF
14666 SLTI32 = 0x24,
14667 BEQ32 = 0x25,
3a1f4268 14668 BC = 0x25,
3c824109
NF
14669 SWC132 = 0x26,
14670 LWC132 = 0x27,
14671
3a1f4268 14672 /* 0x29 is reserved */
3c824109 14673 RES_29 = 0x29,
3a1f4268
YK
14674 R6_BNEZC = 0x28,
14675 JIALC = 0x28,
3c824109
NF
14676 SH16 = 0x2a,
14677 BNEZ16 = 0x2b,
3a1f4268 14678 BNEZC16 = 0x2b,
3c824109
NF
14679 SLTIU32 = 0x2c,
14680 BNE32 = 0x2d,
3a1f4268 14681 BALC = 0x2d,
3c824109
NF
14682 SDC132 = 0x2e,
14683 LDC132 = 0x2f,
14684
3a1f4268 14685 /* 0x31 is reserved */
3c824109 14686 RES_31 = 0x31,
3a1f4268
YK
14687 BLEZALC = 0x30,
14688 BGEZALC = 0x30,
14689 BGEUC = 0x30,
3c824109
NF
14690 SWSP16 = 0x32,
14691 B16 = 0x33,
3a1f4268 14692 BC16 = 0x33,
3c824109
NF
14693 ANDI32 = 0x34,
14694 J32 = 0x35,
3a1f4268
YK
14695 BGTZC = 0x35,
14696 BLTZC = 0x35,
14697 BLTC = 0x35,
211da992
CWR
14698 SD32 = 0x36, /* MIPS64 */
14699 LD32 = 0x37, /* MIPS64 */
3c824109 14700
3a1f4268 14701 /* 0x39 is reserved */
3c824109 14702 RES_39 = 0x39,
3a1f4268
YK
14703 BGTZALC = 0x38,
14704 BLTZALC = 0x38,
14705 BLTUC = 0x38,
3c824109
NF
14706 SW16 = 0x3a,
14707 LI16 = 0x3b,
14708 JALX32 = 0x3c,
14709 JAL32 = 0x3d,
3a1f4268
YK
14710 BLEZC = 0x3d,
14711 BGEZC = 0x3d,
14712 BGEC = 0x3d,
3c824109
NF
14713 SW32 = 0x3e,
14714 LW32 = 0x3f
14715};
14716
3a1f4268
YK
14717/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14718enum {
14719 ADDIUPC_00 = 0x00,
c38a1d52
AR
14720 ADDIUPC_01 = 0x01,
14721 ADDIUPC_02 = 0x02,
14722 ADDIUPC_03 = 0x03,
14723 ADDIUPC_04 = 0x04,
14724 ADDIUPC_05 = 0x05,
14725 ADDIUPC_06 = 0x06,
3a1f4268
YK
14726 ADDIUPC_07 = 0x07,
14727 AUIPC = 0x1e,
14728 ALUIPC = 0x1f,
14729 LWPC_08 = 0x08,
c38a1d52
AR
14730 LWPC_09 = 0x09,
14731 LWPC_0A = 0x0A,
14732 LWPC_0B = 0x0B,
14733 LWPC_0C = 0x0C,
14734 LWPC_0D = 0x0D,
14735 LWPC_0E = 0x0E,
3a1f4268
YK
14736 LWPC_0F = 0x0F,
14737};
14738
3c824109
NF
14739/* POOL32A encoding of minor opcode field */
14740
14741enum {
7480515f
AM
14742 /*
14743 * These opcodes are distinguished only by bits 9..6; those bits are
14744 * what are recorded below.
14745 */
3c824109
NF
14746 SLL32 = 0x0,
14747 SRL32 = 0x1,
14748 SRA = 0x2,
14749 ROTR = 0x3,
3a1f4268
YK
14750 SELEQZ = 0x5,
14751 SELNEZ = 0x6,
b00c7218 14752 R6_RDHWR = 0x7,
3c824109
NF
14753
14754 SLLV = 0x0,
14755 SRLV = 0x1,
14756 SRAV = 0x2,
14757 ROTRV = 0x3,
14758 ADD = 0x4,
14759 ADDU32 = 0x5,
14760 SUB = 0x6,
14761 SUBU32 = 0x7,
14762 MUL = 0x8,
14763 AND = 0x9,
14764 OR32 = 0xa,
14765 NOR = 0xb,
14766 XOR32 = 0xc,
14767 SLT = 0xd,
14768 SLTU = 0xe,
14769
14770 MOVN = 0x0,
3a1f4268 14771 R6_MUL = 0x0,
3c824109 14772 MOVZ = 0x1,
3a1f4268
YK
14773 MUH = 0x1,
14774 MULU = 0x2,
14775 MUHU = 0x3,
3c824109 14776 LWXS = 0x4,
3a1f4268
YK
14777 R6_DIV = 0x4,
14778 MOD = 0x5,
14779 R6_DIVU = 0x6,
14780 MODU = 0x7,
3c824109
NF
14781
14782 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 14783 BREAK32 = 0x07,
3c824109 14784 INS = 0x0c,
3a1f4268
YK
14785 LSA = 0x0f,
14786 ALIGN = 0x1f,
3c824109 14787 EXT = 0x2c,
bb238210
YK
14788 POOL32AXF = 0x3c,
14789 SIGRIE = 0x3f
3c824109
NF
14790};
14791
14792/* POOL32AXF encoding of minor opcode field extension */
14793
d132c79f
CWR
14794/*
14795 * 1. MIPS Architecture for Programmers Volume II-B:
14796 * The microMIPS32 Instruction Set (Revision 3.05)
14797 *
14798 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14799 *
14800 * 2. MIPS Architecture for Programmers VolumeIV-e:
14801 * The MIPS DSP Application-Specific Extension
14802 * to the microMIPS32 Architecture (Revision 2.34)
14803 *
14804 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14805 */
14806
3c824109
NF
14807enum {
14808 /* bits 11..6 */
14809 TEQ = 0x00,
14810 TGE = 0x08,
14811 TGEU = 0x10,
14812 TLT = 0x20,
14813 TLTU = 0x28,
14814 TNE = 0x30,
14815
14816 MFC0 = 0x03,
14817 MTC0 = 0x0b,
14818
d132c79f
CWR
14819 /* begin of microMIPS32 DSP */
14820
3c824109
NF
14821 /* bits 13..12 for 0x01 */
14822 MFHI_ACC = 0x0,
14823 MFLO_ACC = 0x1,
14824 MTHI_ACC = 0x2,
14825 MTLO_ACC = 0x3,
14826
14827 /* bits 13..12 for 0x2a */
14828 MADD_ACC = 0x0,
14829 MADDU_ACC = 0x1,
14830 MSUB_ACC = 0x2,
14831 MSUBU_ACC = 0x3,
14832
14833 /* bits 13..12 for 0x32 */
14834 MULT_ACC = 0x0,
6801038b 14835 MULTU_ACC = 0x1,
3c824109 14836
d132c79f
CWR
14837 /* end of microMIPS32 DSP */
14838
3c824109 14839 /* bits 15..12 for 0x2c */
3a1f4268 14840 BITSWAP = 0x0,
3c824109
NF
14841 SEB = 0x2,
14842 SEH = 0x3,
14843 CLO = 0x4,
14844 CLZ = 0x5,
14845 RDHWR = 0x6,
14846 WSBH = 0x7,
14847 MULT = 0x8,
14848 MULTU = 0x9,
14849 DIV = 0xa,
14850 DIVU = 0xb,
14851 MADD = 0xc,
14852 MADDU = 0xd,
14853 MSUB = 0xe,
14854 MSUBU = 0xf,
14855
14856 /* bits 15..12 for 0x34 */
14857 MFC2 = 0x4,
14858 MTC2 = 0x5,
14859 MFHC2 = 0x8,
14860 MTHC2 = 0x9,
14861 CFC2 = 0xc,
14862 CTC2 = 0xd,
14863
14864 /* bits 15..12 for 0x3c */
14865 JALR = 0x0,
14866 JR = 0x0, /* alias */
3a1f4268
YK
14867 JALRC = 0x0,
14868 JRC = 0x0,
3c824109 14869 JALR_HB = 0x1,
3a1f4268 14870 JALRC_HB = 0x1,
3c824109
NF
14871 JALRS = 0x4,
14872 JALRS_HB = 0x5,
14873
14874 /* bits 15..12 for 0x05 */
14875 RDPGPR = 0xe,
14876 WRPGPR = 0xf,
14877
14878 /* bits 15..12 for 0x0d */
14879 TLBP = 0x0,
14880 TLBR = 0x1,
14881 TLBWI = 0x2,
14882 TLBWR = 0x3,
e60ec063
YK
14883 TLBINV = 0x4,
14884 TLBINVF = 0x5,
3c824109
NF
14885 WAIT = 0x9,
14886 IRET = 0xd,
14887 DERET = 0xe,
14888 ERET = 0xf,
14889
14890 /* bits 15..12 for 0x15 */
14891 DMT = 0x0,
14892 DVPE = 0x1,
14893 EMT = 0x2,
14894 EVPE = 0x3,
14895
14896 /* bits 15..12 for 0x1d */
14897 DI = 0x4,
14898 EI = 0x5,
14899
14900 /* bits 15..12 for 0x2d */
14901 SYNC = 0x6,
14902 SYSCALL = 0x8,
14903 SDBBP = 0xd,
14904
14905 /* bits 15..12 for 0x35 */
14906 MFHI32 = 0x0,
14907 MFLO32 = 0x1,
14908 MTHI32 = 0x2,
14909 MTLO32 = 0x3,
14910};
14911
14912/* POOL32B encoding of minor opcode field (bits 15..12) */
14913
14914enum {
14915 LWC2 = 0x0,
14916 LWP = 0x1,
14917 LDP = 0x4,
14918 LWM32 = 0x5,
14919 CACHE = 0x6,
14920 LDM = 0x7,
14921 SWC2 = 0x8,
14922 SWP = 0x9,
14923 SDP = 0xc,
14924 SWM32 = 0xd,
14925 SDM = 0xf
14926};
14927
14928/* POOL32C encoding of minor opcode field (bits 15..12) */
14929
14930enum {
14931 LWL = 0x0,
14932 SWL = 0x8,
14933 LWR = 0x1,
14934 SWR = 0x9,
14935 PREF = 0x2,
8fffc646 14936 ST_EVA = 0xa,
3c824109
NF
14937 LL = 0x3,
14938 SC = 0xb,
14939 LDL = 0x4,
14940 SDL = 0xc,
14941 LDR = 0x5,
14942 SDR = 0xd,
8fffc646 14943 LD_EVA = 0x6,
3c824109
NF
14944 LWU = 0xe,
14945 LLD = 0x7,
14946 SCD = 0xf
14947};
14948
8fffc646
JH
14949/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14950
14951enum {
14952 LBUE = 0x0,
14953 LHUE = 0x1,
14954 LWLE = 0x2,
14955 LWRE = 0x3,
14956 LBE = 0x4,
14957 LHE = 0x5,
14958 LLE = 0x6,
14959 LWE = 0x7,
14960};
14961
14962/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14963
14964enum {
14965 SWLE = 0x0,
14966 SWRE = 0x1,
14967 PREFE = 0x2,
14968 CACHEE = 0x3,
14969 SBE = 0x4,
14970 SHE = 0x5,
14971 SCE = 0x6,
14972 SWE = 0x7,
14973};
14974
3c824109
NF
14975/* POOL32F encoding of minor opcode field (bits 5..0) */
14976
14977enum {
14978 /* These are the bit 7..6 values */
14979 ADD_FMT = 0x0,
3c824109
NF
14980
14981 SUB_FMT = 0x1,
3c824109
NF
14982
14983 MUL_FMT = 0x2,
14984
14985 DIV_FMT = 0x3,
14986
14987 /* These are the bit 8..6 values */
3a1f4268 14988 MOVN_FMT = 0x0,
3c824109
NF
14989 RSQRT2_FMT = 0x0,
14990 MOVF_FMT = 0x0,
3a1f4268
YK
14991 RINT_FMT = 0x0,
14992 SELNEZ_FMT = 0x0,
3c824109 14993
3a1f4268 14994 MOVZ_FMT = 0x1,
3c824109
NF
14995 LWXC1 = 0x1,
14996 MOVT_FMT = 0x1,
3a1f4268
YK
14997 CLASS_FMT = 0x1,
14998 SELEQZ_FMT = 0x1,
3c824109
NF
14999
15000 PLL_PS = 0x2,
15001 SWXC1 = 0x2,
3a1f4268 15002 SEL_FMT = 0x2,
3c824109
NF
15003
15004 PLU_PS = 0x3,
15005 LDXC1 = 0x3,
15006
3a1f4268 15007 MOVN_FMT_04 = 0x4,
3c824109
NF
15008 PUL_PS = 0x4,
15009 SDXC1 = 0x4,
15010 RECIP2_FMT = 0x4,
15011
3a1f4268 15012 MOVZ_FMT_05 = 0x05,
3c824109
NF
15013 PUU_PS = 0x5,
15014 LUXC1 = 0x5,
15015
15016 CVT_PS_S = 0x6,
15017 SUXC1 = 0x6,
15018 ADDR_PS = 0x6,
15019 PREFX = 0x6,
3a1f4268 15020 MADDF_FMT = 0x6,
3c824109
NF
15021
15022 MULR_PS = 0x7,
3a1f4268 15023 MSUBF_FMT = 0x7,
3c824109
NF
15024
15025 MADD_S = 0x01,
15026 MADD_D = 0x09,
15027 MADD_PS = 0x11,
15028 ALNV_PS = 0x19,
15029 MSUB_S = 0x21,
15030 MSUB_D = 0x29,
15031 MSUB_PS = 0x31,
15032
15033 NMADD_S = 0x02,
15034 NMADD_D = 0x0a,
15035 NMADD_PS = 0x12,
15036 NMSUB_S = 0x22,
15037 NMSUB_D = 0x2a,
15038 NMSUB_PS = 0x32,
15039
3a1f4268
YK
15040 MIN_FMT = 0x3,
15041 MAX_FMT = 0xb,
15042 MINA_FMT = 0x23,
15043 MAXA_FMT = 0x2b,
3c824109
NF
15044 POOL32FXF = 0x3b,
15045
15046 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
15047 C_COND_FMT = 0x3c,
15048
15049 CMP_CONDN_S = 0x5,
15050 CMP_CONDN_D = 0x15
3c824109
NF
15051};
15052
15053/* POOL32Fxf encoding of minor opcode extension field */
15054
15055enum {
15056 CVT_L = 0x04,
15057 RSQRT_FMT = 0x08,
15058 FLOOR_L = 0x0c,
15059 CVT_PW_PS = 0x1c,
15060 CVT_W = 0x24,
15061 SQRT_FMT = 0x28,
15062 FLOOR_W = 0x2c,
15063 CVT_PS_PW = 0x3c,
15064 CFC1 = 0x40,
15065 RECIP_FMT = 0x48,
15066 CEIL_L = 0x4c,
15067 CTC1 = 0x60,
15068 CEIL_W = 0x6c,
15069 MFC1 = 0x80,
15070 CVT_S_PL = 0x84,
15071 TRUNC_L = 0x8c,
15072 MTC1 = 0xa0,
15073 CVT_S_PU = 0xa4,
15074 TRUNC_W = 0xac,
15075 MFHC1 = 0xc0,
15076 ROUND_L = 0xcc,
15077 MTHC1 = 0xe0,
15078 ROUND_W = 0xec,
15079
15080 MOV_FMT = 0x01,
15081 MOVF = 0x05,
15082 ABS_FMT = 0x0d,
15083 RSQRT1_FMT = 0x1d,
15084 MOVT = 0x25,
15085 NEG_FMT = 0x2d,
15086 CVT_D = 0x4d,
15087 RECIP1_FMT = 0x5d,
15088 CVT_S = 0x6d
15089};
15090
15091/* POOL32I encoding of minor opcode field (bits 25..21) */
15092
15093enum {
15094 BLTZ = 0x00,
15095 BLTZAL = 0x01,
15096 BGEZ = 0x02,
15097 BGEZAL = 0x03,
15098 BLEZ = 0x04,
15099 BNEZC = 0x05,
15100 BGTZ = 0x06,
15101 BEQZC = 0x07,
15102 TLTI = 0x08,
3a1f4268 15103 BC1EQZC = 0x08,
3c824109 15104 TGEI = 0x09,
3a1f4268 15105 BC1NEZC = 0x09,
3c824109 15106 TLTIU = 0x0a,
3a1f4268 15107 BC2EQZC = 0x0a,
3c824109 15108 TGEIU = 0x0b,
3a1f4268 15109 BC2NEZC = 0x0a,
3c824109 15110 TNEI = 0x0c,
3a1f4268 15111 R6_SYNCI = 0x0c,
3c824109
NF
15112 LUI = 0x0d,
15113 TEQI = 0x0e,
15114 SYNCI = 0x10,
15115 BLTZALS = 0x11,
15116 BGEZALS = 0x13,
15117 BC2F = 0x14,
15118 BC2T = 0x15,
15119 BPOSGE64 = 0x1a,
15120 BPOSGE32 = 0x1b,
15121 /* These overlap and are distinguished by bit16 of the instruction */
15122 BC1F = 0x1c,
15123 BC1T = 0x1d,
15124 BC1ANY2F = 0x1c,
15125 BC1ANY2T = 0x1d,
15126 BC1ANY4F = 0x1e,
15127 BC1ANY4T = 0x1f
15128};
15129
15130/* POOL16A encoding of minor opcode field */
15131
15132enum {
15133 ADDU16 = 0x0,
15134 SUBU16 = 0x1
15135};
15136
15137/* POOL16B encoding of minor opcode field */
15138
15139enum {
15140 SLL16 = 0x0,
15141 SRL16 = 0x1
15142};
15143
15144/* POOL16C encoding of minor opcode field */
15145
15146enum {
15147 NOT16 = 0x00,
15148 XOR16 = 0x04,
15149 AND16 = 0x08,
15150 OR16 = 0x0c,
15151 LWM16 = 0x10,
15152 SWM16 = 0x14,
15153 JR16 = 0x18,
15154 JRC16 = 0x1a,
15155 JALR16 = 0x1c,
15156 JALR16S = 0x1e,
15157 MFHI16 = 0x20,
15158 MFLO16 = 0x24,
15159 BREAK16 = 0x28,
15160 SDBBP16 = 0x2c,
15161 JRADDIUSP = 0x30
15162};
15163
3a1f4268
YK
15164/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15165
15166enum {
15167 R6_NOT16 = 0x00,
15168 R6_AND16 = 0x01,
15169 R6_LWM16 = 0x02,
15170 R6_JRC16 = 0x03,
15171 MOVEP = 0x04,
c38a1d52
AR
15172 MOVEP_05 = 0x05,
15173 MOVEP_06 = 0x06,
3a1f4268
YK
15174 MOVEP_07 = 0x07,
15175 R6_XOR16 = 0x08,
15176 R6_OR16 = 0x09,
15177 R6_SWM16 = 0x0a,
15178 JALRC16 = 0x0b,
15179 MOVEP_0C = 0x0c,
c38a1d52
AR
15180 MOVEP_0D = 0x0d,
15181 MOVEP_0E = 0x0e,
3a1f4268
YK
15182 MOVEP_0F = 0x0f,
15183 JRCADDIUSP = 0x13,
15184 R6_BREAK16 = 0x1b,
15185 R6_SDBBP16 = 0x3b
15186};
15187
3c824109
NF
15188/* POOL16D encoding of minor opcode field */
15189
15190enum {
15191 ADDIUS5 = 0x0,
15192 ADDIUSP = 0x1
15193};
15194
15195/* POOL16E encoding of minor opcode field */
15196
15197enum {
15198 ADDIUR2 = 0x0,
15199 ADDIUR1SP = 0x1
15200};
15201
235785e8 15202static int mmreg(int r)
3c824109
NF
15203{
15204 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15205
15206 return map[r];
15207}
15208
15209/* Used for 16-bit store instructions. */
235785e8 15210static int mmreg2(int r)
3c824109
NF
15211{
15212 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15213
15214 return map[r];
15215}
15216
15217#define uMIPS_RD(op) ((op >> 7) & 0x7)
15218#define uMIPS_RS(op) ((op >> 4) & 0x7)
15219#define uMIPS_RS2(op) uMIPS_RS(op)
15220#define uMIPS_RS1(op) ((op >> 1) & 0x7)
15221#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15222#define uMIPS_RS5(op) (op & 0x1f)
15223
15224/* Signed immediate */
15225#define SIMM(op, start, width) \
71375b59
AM
15226 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15227 << (32 - width)) \
15228 >> (32 - width))
3c824109 15229/* Zero-extended immediate */
71375b59 15230#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
3c824109 15231
d75c135e 15232static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
15233{
15234 int rd = mmreg(uMIPS_RD(ctx->opcode));
15235
d75c135e 15236 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
15237}
15238
d75c135e 15239static void gen_addiur2(DisasContext *ctx)
3c824109
NF
15240{
15241 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15242 int rd = mmreg(uMIPS_RD(ctx->opcode));
15243 int rs = mmreg(uMIPS_RS(ctx->opcode));
15244
d75c135e 15245 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
15246}
15247
d75c135e 15248static void gen_addiusp(DisasContext *ctx)
3c824109
NF
15249{
15250 int encoded = ZIMM(ctx->opcode, 1, 9);
15251 int decoded;
15252
15253 if (encoded <= 1) {
15254 decoded = 256 + encoded;
15255 } else if (encoded <= 255) {
15256 decoded = encoded;
15257 } else if (encoded <= 509) {
15258 decoded = encoded - 512;
15259 } else {
15260 decoded = encoded - 768;
15261 }
15262
d75c135e 15263 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
15264}
15265
d75c135e 15266static void gen_addius5(DisasContext *ctx)
3c824109
NF
15267{
15268 int imm = SIMM(ctx->opcode, 1, 4);
15269 int rd = (ctx->opcode >> 5) & 0x1f;
15270
d75c135e 15271 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
15272}
15273
d75c135e 15274static void gen_andi16(DisasContext *ctx)
3c824109
NF
15275{
15276 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15277 31, 32, 63, 64, 255, 32768, 65535 };
15278 int rd = mmreg(uMIPS_RD(ctx->opcode));
15279 int rs = mmreg(uMIPS_RS(ctx->opcode));
15280 int encoded = ZIMM(ctx->opcode, 0, 4);
15281
d75c135e 15282 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
15283}
15284
235785e8
AM
15285static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15286 int base, int16_t offset)
3c824109
NF
15287{
15288 TCGv t0, t1;
15289 TCGv_i32 t2;
15290
15291 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3a4ef3b7 15292 gen_reserved_instruction(ctx);
3c824109
NF
15293 return;
15294 }
15295
15296 t0 = tcg_temp_new();
15297
15298 gen_base_offset_addr(ctx, t0, base, offset);
15299
15300 t1 = tcg_const_tl(reglist);
15301 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 15302
3c824109
NF
15303 save_cpu_state(ctx, 1);
15304 switch (opc) {
15305 case LWM32:
895c2d04 15306 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
15307 break;
15308 case SWM32:
895c2d04 15309 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
15310 break;
15311#ifdef TARGET_MIPS64
15312 case LDM:
895c2d04 15313 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
15314 break;
15315 case SDM:
895c2d04 15316 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 15317 break;
6af0bf9c 15318#endif
3c824109 15319 }
3c824109 15320 tcg_temp_free(t0);
33087598 15321 tcg_temp_free(t1);
3c824109
NF
15322 tcg_temp_free_i32(t2);
15323}
6af0bf9c 15324
3c824109 15325
240ce26a 15326static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 15327{
3c824109
NF
15328 int rd = mmreg((ctx->opcode >> 3) & 0x7);
15329 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 15330
3c824109
NF
15331 switch (((ctx->opcode) >> 4) & 0x3f) {
15332 case NOT16 + 0:
15333 case NOT16 + 1:
15334 case NOT16 + 2:
15335 case NOT16 + 3:
d75c135e 15336 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
15337 break;
15338 case XOR16 + 0:
15339 case XOR16 + 1:
15340 case XOR16 + 2:
15341 case XOR16 + 3:
d75c135e 15342 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
15343 break;
15344 case AND16 + 0:
15345 case AND16 + 1:
15346 case AND16 + 2:
15347 case AND16 + 3:
d75c135e 15348 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
15349 break;
15350 case OR16 + 0:
15351 case OR16 + 1:
15352 case OR16 + 2:
15353 case OR16 + 3:
d75c135e 15354 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
15355 break;
15356 case LWM16 + 0:
15357 case LWM16 + 1:
15358 case LWM16 + 2:
15359 case LWM16 + 3:
15360 {
15361 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15362 int offset = ZIMM(ctx->opcode, 0, 4);
15363
15364 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15365 29, offset << 2);
15366 }
15367 break;
15368 case SWM16 + 0:
15369 case SWM16 + 1:
15370 case SWM16 + 2:
15371 case SWM16 + 3:
15372 {
15373 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15374 int offset = ZIMM(ctx->opcode, 0, 4);
15375
15376 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15377 29, offset << 2);
15378 }
15379 break;
15380 case JR16 + 0:
15381 case JR16 + 1:
15382 {
15383 int reg = ctx->opcode & 0x1f;
15384
b231c103 15385 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 15386 }
3c824109
NF
15387 break;
15388 case JRC16 + 0:
15389 case JRC16 + 1:
15390 {
15391 int reg = ctx->opcode & 0x1f;
b231c103 15392 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
7480515f
AM
15393 /*
15394 * Let normal delay slot handling in our caller take us
15395 * to the branch target.
15396 */
3c824109
NF
15397 }
15398 break;
15399 case JALR16 + 0:
15400 case JALR16 + 1:
b231c103
YK
15401 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15402 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15403 break;
3c824109
NF
15404 case JALR16S + 0:
15405 case JALR16S + 1:
b231c103
YK
15406 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15407 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15408 break;
15409 case MFHI16 + 0:
15410 case MFHI16 + 1:
26135ead 15411 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
15412 break;
15413 case MFLO16 + 0:
15414 case MFLO16 + 1:
26135ead 15415 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
15416 break;
15417 case BREAK16:
9c708c7f 15418 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
15419 break;
15420 case SDBBP16:
3b3c1694
LA
15421 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15422 gen_helper_do_semihosting(cpu_env);
15423 } else {
7480515f
AM
15424 /*
15425 * XXX: not clear which exception should be raised
3b3c1694
LA
15426 * when in debug mode...
15427 */
bbd5e4a2 15428 check_insn(ctx, ISA_MIPS_R1);
9c708c7f 15429 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 15430 }
3c824109
NF
15431 break;
15432 case JRADDIUSP + 0:
15433 case JRADDIUSP + 1:
15434 {
15435 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 15436 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 15437 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
7480515f
AM
15438 /*
15439 * Let normal delay slot handling in our caller take us
15440 * to the branch target.
15441 */
3c824109
NF
15442 }
15443 break;
15444 default:
3a4ef3b7 15445 gen_reserved_instruction(ctx);
3c824109
NF
15446 break;
15447 }
15448}
15449
ed7ce6c0
YK
15450static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15451 int enc_rs)
15452{
15453 int rd, rs, re, rt;
15454 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15455 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15456 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15457 rd = rd_enc[enc_dest];
15458 re = re_enc[enc_dest];
15459 rs = rs_rt_enc[enc_rs];
15460 rt = rs_rt_enc[enc_rt];
15461 if (rs) {
15462 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15463 } else {
15464 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15465 }
15466 if (rt) {
15467 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15468 } else {
15469 tcg_gen_movi_tl(cpu_gpr[re], 0);
15470 }
15471}
15472
15473static void gen_pool16c_r6_insn(DisasContext *ctx)
15474{
15475 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15476 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15477
15478 switch (ctx->opcode & 0xf) {
15479 case R6_NOT16:
15480 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15481 break;
15482 case R6_AND16:
15483 gen_logic(ctx, OPC_AND, rt, rt, rs);
15484 break;
15485 case R6_LWM16:
15486 {
15487 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15488 int offset = extract32(ctx->opcode, 4, 4);
15489 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15490 }
15491 break;
15492 case R6_JRC16: /* JRCADDIUSP */
15493 if ((ctx->opcode >> 4) & 1) {
15494 /* JRCADDIUSP */
15495 int imm = extract32(ctx->opcode, 5, 5);
15496 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15497 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15498 } else {
15499 /* JRC16 */
e1555d7d 15500 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
15501 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15502 }
15503 break;
c38a1d52
AR
15504 case MOVEP:
15505 case MOVEP_05:
15506 case MOVEP_06:
15507 case MOVEP_07:
15508 case MOVEP_0C:
15509 case MOVEP_0D:
15510 case MOVEP_0E:
15511 case MOVEP_0F:
ed7ce6c0
YK
15512 {
15513 int enc_dest = uMIPS_RD(ctx->opcode);
15514 int enc_rt = uMIPS_RS2(ctx->opcode);
15515 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15516 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15517 }
15518 break;
15519 case R6_XOR16:
15520 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15521 break;
15522 case R6_OR16:
15523 gen_logic(ctx, OPC_OR, rt, rt, rs);
15524 break;
15525 case R6_SWM16:
15526 {
15527 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15528 int offset = extract32(ctx->opcode, 4, 4);
15529 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15530 }
15531 break;
15532 case JALRC16: /* BREAK16, SDBBP16 */
15533 switch (ctx->opcode & 0x3f) {
15534 case JALRC16:
15535 case JALRC16 + 0x20:
15536 /* JALRC16 */
15537 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15538 31, 0, 0);
15539 break;
15540 case R6_BREAK16:
15541 /* BREAK16 */
15542 generate_exception(ctx, EXCP_BREAK);
15543 break;
15544 case R6_SDBBP16:
15545 /* SDBBP16 */
060ebfef
LA
15546 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15547 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 15548 } else {
060ebfef
LA
15549 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15550 generate_exception(ctx, EXCP_RI);
15551 } else {
15552 generate_exception(ctx, EXCP_DBp);
15553 }
ed7ce6c0
YK
15554 }
15555 break;
15556 }
15557 break;
15558 default:
15559 generate_exception(ctx, EXCP_RI);
15560 break;
15561 }
15562}
15563
235785e8 15564static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
3c824109
NF
15565{
15566 TCGv t0 = tcg_temp_new();
15567 TCGv t1 = tcg_temp_new();
15568
15569 gen_load_gpr(t0, base);
15570
15571 if (index != 0) {
15572 gen_load_gpr(t1, index);
15573 tcg_gen_shli_tl(t1, t1, 2);
15574 gen_op_addr_add(ctx, t0, t1, t0);
15575 }
15576
5f68f5ae 15577 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15578 gen_store_gpr(t1, rd);
15579
15580 tcg_temp_free(t0);
15581 tcg_temp_free(t1);
15582}
15583
235785e8
AM
15584static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15585 int base, int16_t offset)
3c824109 15586{
3c824109
NF
15587 TCGv t0, t1;
15588
36c6711b 15589 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3a4ef3b7 15590 gen_reserved_instruction(ctx);
d796321b
FB
15591 return;
15592 }
15593
3c824109
NF
15594 t0 = tcg_temp_new();
15595 t1 = tcg_temp_new();
8e9ade68 15596
3c824109
NF
15597 gen_base_offset_addr(ctx, t0, base, offset);
15598
15599 switch (opc) {
15600 case LWP:
36c6711b 15601 if (rd == base) {
3a4ef3b7 15602 gen_reserved_instruction(ctx);
36c6711b
EJ
15603 return;
15604 }
5f68f5ae 15605 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15606 gen_store_gpr(t1, rd);
15607 tcg_gen_movi_tl(t1, 4);
15608 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15609 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
235785e8 15610 gen_store_gpr(t1, rd + 1);
3c824109
NF
15611 break;
15612 case SWP:
3c824109 15613 gen_load_gpr(t1, rd);
5f68f5ae 15614 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15615 tcg_gen_movi_tl(t1, 4);
15616 gen_op_addr_add(ctx, t0, t0, t1);
235785e8 15617 gen_load_gpr(t1, rd + 1);
5f68f5ae 15618 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15619 break;
15620#ifdef TARGET_MIPS64
15621 case LDP:
36c6711b 15622 if (rd == base) {
3a4ef3b7 15623 gen_reserved_instruction(ctx);
36c6711b
EJ
15624 return;
15625 }
5f68f5ae 15626 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15627 gen_store_gpr(t1, rd);
15628 tcg_gen_movi_tl(t1, 8);
15629 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15630 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
235785e8 15631 gen_store_gpr(t1, rd + 1);
3c824109
NF
15632 break;
15633 case SDP:
3c824109 15634 gen_load_gpr(t1, rd);
5f68f5ae 15635 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15636 tcg_gen_movi_tl(t1, 8);
15637 gen_op_addr_add(ctx, t0, t0, t1);
235785e8 15638 gen_load_gpr(t1, rd + 1);
5f68f5ae 15639 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15640 break;
15641#endif
6af0bf9c 15642 }
3c824109
NF
15643 tcg_temp_free(t0);
15644 tcg_temp_free(t1);
15645}
618b0fe9 15646
d208ac0c
LA
15647static void gen_sync(int stype)
15648{
15649 TCGBar tcg_mo = TCG_BAR_SC;
15650
15651 switch (stype) {
15652 case 0x4: /* SYNC_WMB */
15653 tcg_mo |= TCG_MO_ST_ST;
15654 break;
15655 case 0x10: /* SYNC_MB */
15656 tcg_mo |= TCG_MO_ALL;
15657 break;
15658 case 0x11: /* SYNC_ACQUIRE */
15659 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15660 break;
15661 case 0x12: /* SYNC_RELEASE */
15662 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15663 break;
15664 case 0x13: /* SYNC_RMB */
15665 tcg_mo |= TCG_MO_LD_LD;
15666 break;
15667 default:
15668 tcg_mo |= TCG_MO_ALL;
15669 break;
15670 }
15671
15672 tcg_gen_mb(tcg_mo);
15673}
15674
235785e8 15675static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
15676{
15677 int extension = (ctx->opcode >> 6) & 0x3f;
15678 int minor = (ctx->opcode >> 12) & 0xf;
15679 uint32_t mips32_op;
15680
15681 switch (extension) {
15682 case TEQ:
15683 mips32_op = OPC_TEQ;
15684 goto do_trap;
15685 case TGE:
15686 mips32_op = OPC_TGE;
15687 goto do_trap;
15688 case TGEU:
15689 mips32_op = OPC_TGEU;
15690 goto do_trap;
15691 case TLT:
15692 mips32_op = OPC_TLT;
15693 goto do_trap;
15694 case TLTU:
15695 mips32_op = OPC_TLTU;
15696 goto do_trap;
15697 case TNE:
15698 mips32_op = OPC_TNE;
15699 do_trap:
15700 gen_trap(ctx, mips32_op, rs, rt, -1);
15701 break;
15702#ifndef CONFIG_USER_ONLY
15703 case MFC0:
15704 case MFC0 + 32:
2e15497c 15705 check_cp0_enabled(ctx);
3c824109
NF
15706 if (rt == 0) {
15707 /* Treat as NOP. */
15708 break;
15709 }
d75c135e 15710 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15711 break;
15712 case MTC0:
15713 case MTC0 + 32:
2e15497c 15714 check_cp0_enabled(ctx);
3c824109
NF
15715 {
15716 TCGv t0 = tcg_temp_new();
618b0fe9 15717
3c824109 15718 gen_load_gpr(t0, rt);
d75c135e 15719 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15720 tcg_temp_free(t0);
15721 }
15722 break;
15723#endif
a1fc6246
LA
15724 case 0x2a:
15725 switch (minor & 3) {
15726 case MADD_ACC:
15727 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15728 break;
15729 case MADDU_ACC:
15730 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15731 break;
15732 case MSUB_ACC:
15733 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15734 break;
15735 case MSUBU_ACC:
15736 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15737 break;
15738 default:
15739 goto pool32axf_invalid;
15740 }
15741 break;
15742 case 0x32:
15743 switch (minor & 3) {
15744 case MULT_ACC:
15745 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15746 break;
15747 case MULTU_ACC:
15748 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15749 break;
15750 default:
15751 goto pool32axf_invalid;
15752 }
15753 break;
3c824109
NF
15754 case 0x2c:
15755 switch (minor) {
e0332095 15756 case BITSWAP:
2e211e0a 15757 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
15758 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15759 break;
3c824109
NF
15760 case SEB:
15761 gen_bshfl(ctx, OPC_SEB, rs, rt);
15762 break;
15763 case SEH:
15764 gen_bshfl(ctx, OPC_SEH, rs, rt);
15765 break;
15766 case CLO:
15767 mips32_op = OPC_CLO;
15768 goto do_cl;
15769 case CLZ:
15770 mips32_op = OPC_CLZ;
15771 do_cl:
bbd5e4a2 15772 check_insn(ctx, ISA_MIPS_R1);
3c824109
NF
15773 gen_cl(ctx, mips32_op, rt, rs);
15774 break;
15775 case RDHWR:
2e211e0a 15776 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b00c7218 15777 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
15778 break;
15779 case WSBH:
15780 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15781 break;
15782 case MULT:
2e211e0a 15783 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15784 mips32_op = OPC_MULT;
26135ead 15785 goto do_mul;
3c824109 15786 case MULTU:
2e211e0a 15787 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15788 mips32_op = OPC_MULTU;
26135ead 15789 goto do_mul;
3c824109 15790 case DIV:
2e211e0a 15791 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15792 mips32_op = OPC_DIV;
26135ead 15793 goto do_div;
3c824109 15794 case DIVU:
2e211e0a 15795 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15796 mips32_op = OPC_DIVU;
26135ead
RS
15797 goto do_div;
15798 do_div:
bbd5e4a2 15799 check_insn(ctx, ISA_MIPS_R1);
26135ead
RS
15800 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15801 break;
3c824109 15802 case MADD:
2e211e0a 15803 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15804 mips32_op = OPC_MADD;
26135ead 15805 goto do_mul;
3c824109 15806 case MADDU:
2e211e0a 15807 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15808 mips32_op = OPC_MADDU;
26135ead 15809 goto do_mul;
3c824109 15810 case MSUB:
2e211e0a 15811 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15812 mips32_op = OPC_MSUB;
26135ead 15813 goto do_mul;
3c824109 15814 case MSUBU:
2e211e0a 15815 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 15816 mips32_op = OPC_MSUBU;
26135ead 15817 do_mul:
bbd5e4a2 15818 check_insn(ctx, ISA_MIPS_R1);
a1fc6246 15819 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
15820 break;
15821 default:
15822 goto pool32axf_invalid;
15823 }
15824 break;
15825 case 0x34:
15826 switch (minor) {
15827 case MFC2:
15828 case MTC2:
15829 case MFHC2:
15830 case MTHC2:
15831 case CFC2:
15832 case CTC2:
15833 generate_exception_err(ctx, EXCP_CpU, 2);
15834 break;
15835 default:
15836 goto pool32axf_invalid;
15837 }
15838 break;
15839 case 0x3c:
15840 switch (minor) {
65935f07
YK
15841 case JALR: /* JALRC */
15842 case JALR_HB: /* JALRC_HB */
2e211e0a 15843 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
15844 /* JALRC, JALRC_HB */
15845 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15846 } else {
15847 /* JALR, JALR_HB */
15848 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15849 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15850 }
3c824109
NF
15851 break;
15852 case JALRS:
15853 case JALRS_HB:
2e211e0a 15854 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
15855 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15856 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15857 break;
15858 default:
15859 goto pool32axf_invalid;
15860 }
15861 break;
15862 case 0x05:
15863 switch (minor) {
15864 case RDPGPR:
2e15497c 15865 check_cp0_enabled(ctx);
7a47bae5 15866 check_insn(ctx, ISA_MIPS_R2);
1bf5902d 15867 gen_load_srsgpr(rs, rt);
3c824109
NF
15868 break;
15869 case WRPGPR:
2e15497c 15870 check_cp0_enabled(ctx);
7a47bae5 15871 check_insn(ctx, ISA_MIPS_R2);
1bf5902d 15872 gen_store_srsgpr(rs, rt);
3c824109
NF
15873 break;
15874 default:
15875 goto pool32axf_invalid;
15876 }
15877 break;
15878#ifndef CONFIG_USER_ONLY
15879 case 0x0d:
15880 switch (minor) {
15881 case TLBP:
15882 mips32_op = OPC_TLBP;
15883 goto do_cp0;
15884 case TLBR:
15885 mips32_op = OPC_TLBR;
15886 goto do_cp0;
15887 case TLBWI:
15888 mips32_op = OPC_TLBWI;
15889 goto do_cp0;
15890 case TLBWR:
15891 mips32_op = OPC_TLBWR;
15892 goto do_cp0;
e60ec063
YK
15893 case TLBINV:
15894 mips32_op = OPC_TLBINV;
15895 goto do_cp0;
15896 case TLBINVF:
15897 mips32_op = OPC_TLBINVF;
15898 goto do_cp0;
3c824109
NF
15899 case WAIT:
15900 mips32_op = OPC_WAIT;
15901 goto do_cp0;
15902 case DERET:
15903 mips32_op = OPC_DERET;
15904 goto do_cp0;
15905 case ERET:
15906 mips32_op = OPC_ERET;
15907 do_cp0:
15908 gen_cp0(env, ctx, mips32_op, rt, rs);
15909 break;
15910 default:
15911 goto pool32axf_invalid;
15912 }
15913 break;
15914 case 0x1d:
15915 switch (minor) {
15916 case DI:
2e15497c 15917 check_cp0_enabled(ctx);
3c824109
NF
15918 {
15919 TCGv t0 = tcg_temp_new();
15920
15921 save_cpu_state(ctx, 1);
895c2d04 15922 gen_helper_di(t0, cpu_env);
3c824109 15923 gen_store_gpr(t0, rs);
71375b59
AM
15924 /*
15925 * Stop translation as we may have switched the execution
15926 * mode.
15927 */
eeb3bba8 15928 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15929 tcg_temp_free(t0);
15930 }
15931 break;
15932 case EI:
2e15497c 15933 check_cp0_enabled(ctx);
3c824109
NF
15934 {
15935 TCGv t0 = tcg_temp_new();
15936
15937 save_cpu_state(ctx, 1);
895c2d04 15938 gen_helper_ei(t0, cpu_env);
3c824109 15939 gen_store_gpr(t0, rs);
7480515f
AM
15940 /*
15941 * DISAS_STOP isn't sufficient, we need to ensure we break out
15942 * of translated code to check for pending interrupts.
15943 */
eeb3bba8
EC
15944 gen_save_pc(ctx->base.pc_next + 4);
15945 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
15946 tcg_temp_free(t0);
15947 }
15948 break;
15949 default:
15950 goto pool32axf_invalid;
15951 }
15952 break;
15953#endif
15954 case 0x2d:
15955 switch (minor) {
15956 case SYNC:
d208ac0c 15957 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
15958 break;
15959 case SYSCALL:
9c708c7f 15960 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
15961 break;
15962 case SDBBP:
3b3c1694
LA
15963 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15964 gen_helper_do_semihosting(cpu_env);
15965 } else {
bbd5e4a2 15966 check_insn(ctx, ISA_MIPS_R1);
e0332095 15967 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 15968 gen_reserved_instruction(ctx);
e0332095 15969 } else {
9c708c7f 15970 generate_exception_end(ctx, EXCP_DBp);
e0332095 15971 }
3b3c1694 15972 }
3c824109
NF
15973 break;
15974 default:
15975 goto pool32axf_invalid;
15976 }
15977 break;
a1fc6246 15978 case 0x01:
26135ead 15979 switch (minor & 3) {
a1fc6246 15980 case MFHI_ACC:
26135ead 15981 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 15982 break;
a1fc6246 15983 case MFLO_ACC:
26135ead 15984 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 15985 break;
a1fc6246 15986 case MTHI_ACC:
26135ead 15987 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 15988 break;
a1fc6246 15989 case MTLO_ACC:
26135ead 15990 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
15991 break;
15992 default:
15993 goto pool32axf_invalid;
15994 }
15995 break;
a1fc6246 15996 case 0x35:
2e211e0a 15997 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a1fc6246
LA
15998 switch (minor) {
15999 case MFHI32:
16000 gen_HILO(ctx, OPC_MFHI, 0, rs);
16001 break;
16002 case MFLO32:
16003 gen_HILO(ctx, OPC_MFLO, 0, rs);
16004 break;
16005 case MTHI32:
16006 gen_HILO(ctx, OPC_MTHI, 0, rs);
16007 break;
16008 case MTLO32:
16009 gen_HILO(ctx, OPC_MTLO, 0, rs);
16010 break;
16011 default:
16012 goto pool32axf_invalid;
16013 }
16014 break;
3c824109
NF
16015 default:
16016 pool32axf_invalid:
16017 MIPS_INVAL("pool32axf");
3a4ef3b7 16018 gen_reserved_instruction(ctx);
3c824109
NF
16019 break;
16020 }
16021}
16022
7480515f
AM
16023/*
16024 * Values for microMIPS fmt field. Variable-width, depending on which
16025 * formats the instruction supports.
16026 */
3c824109
NF
16027enum {
16028 FMT_SD_S = 0,
16029 FMT_SD_D = 1,
16030
16031 FMT_SDPS_S = 0,
16032 FMT_SDPS_D = 1,
16033 FMT_SDPS_PS = 2,
16034
16035 FMT_SWL_S = 0,
16036 FMT_SWL_W = 1,
16037 FMT_SWL_L = 2,
16038
16039 FMT_DWL_D = 0,
16040 FMT_DWL_W = 1,
16041 FMT_DWL_L = 2
16042};
16043
d75c135e 16044static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
16045{
16046 int extension = (ctx->opcode >> 6) & 0x3ff;
16047 uint32_t mips32_op;
16048
71375b59
AM
16049#define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16050#define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16051#define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
3c824109
NF
16052
16053 switch (extension) {
16054 case FLOAT_1BIT_FMT(CFC1, 0):
16055 mips32_op = OPC_CFC1;
16056 goto do_cp1;
16057 case FLOAT_1BIT_FMT(CTC1, 0):
16058 mips32_op = OPC_CTC1;
16059 goto do_cp1;
16060 case FLOAT_1BIT_FMT(MFC1, 0):
16061 mips32_op = OPC_MFC1;
16062 goto do_cp1;
16063 case FLOAT_1BIT_FMT(MTC1, 0):
16064 mips32_op = OPC_MTC1;
16065 goto do_cp1;
16066 case FLOAT_1BIT_FMT(MFHC1, 0):
16067 mips32_op = OPC_MFHC1;
16068 goto do_cp1;
16069 case FLOAT_1BIT_FMT(MTHC1, 0):
16070 mips32_op = OPC_MTHC1;
16071 do_cp1:
16072 gen_cp1(ctx, mips32_op, rt, rs);
16073 break;
16074
16075 /* Reciprocal square root */
16076 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
16077 mips32_op = OPC_RSQRT_S;
16078 goto do_unaryfp;
16079 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
16080 mips32_op = OPC_RSQRT_D;
16081 goto do_unaryfp;
16082
16083 /* Square root */
16084 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
16085 mips32_op = OPC_SQRT_S;
16086 goto do_unaryfp;
16087 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
16088 mips32_op = OPC_SQRT_D;
16089 goto do_unaryfp;
16090
16091 /* Reciprocal */
16092 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
16093 mips32_op = OPC_RECIP_S;
16094 goto do_unaryfp;
16095 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
16096 mips32_op = OPC_RECIP_D;
16097 goto do_unaryfp;
16098
16099 /* Floor */
16100 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
16101 mips32_op = OPC_FLOOR_L_S;
16102 goto do_unaryfp;
16103 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
16104 mips32_op = OPC_FLOOR_L_D;
16105 goto do_unaryfp;
16106 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
16107 mips32_op = OPC_FLOOR_W_S;
16108 goto do_unaryfp;
16109 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
16110 mips32_op = OPC_FLOOR_W_D;
16111 goto do_unaryfp;
16112
16113 /* Ceiling */
16114 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
16115 mips32_op = OPC_CEIL_L_S;
16116 goto do_unaryfp;
16117 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
16118 mips32_op = OPC_CEIL_L_D;
16119 goto do_unaryfp;
16120 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
16121 mips32_op = OPC_CEIL_W_S;
16122 goto do_unaryfp;
16123 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
16124 mips32_op = OPC_CEIL_W_D;
16125 goto do_unaryfp;
16126
16127 /* Truncation */
16128 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
16129 mips32_op = OPC_TRUNC_L_S;
16130 goto do_unaryfp;
16131 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
16132 mips32_op = OPC_TRUNC_L_D;
16133 goto do_unaryfp;
16134 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
16135 mips32_op = OPC_TRUNC_W_S;
16136 goto do_unaryfp;
16137 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
16138 mips32_op = OPC_TRUNC_W_D;
16139 goto do_unaryfp;
16140
16141 /* Round */
16142 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
16143 mips32_op = OPC_ROUND_L_S;
16144 goto do_unaryfp;
16145 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
16146 mips32_op = OPC_ROUND_L_D;
16147 goto do_unaryfp;
16148 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
16149 mips32_op = OPC_ROUND_W_S;
16150 goto do_unaryfp;
16151 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
16152 mips32_op = OPC_ROUND_W_D;
16153 goto do_unaryfp;
16154
16155 /* Integer to floating-point conversion */
16156 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
16157 mips32_op = OPC_CVT_L_S;
16158 goto do_unaryfp;
16159 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
16160 mips32_op = OPC_CVT_L_D;
16161 goto do_unaryfp;
16162 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
16163 mips32_op = OPC_CVT_W_S;
16164 goto do_unaryfp;
16165 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
16166 mips32_op = OPC_CVT_W_D;
16167 goto do_unaryfp;
16168
16169 /* Paired-foo conversions */
16170 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
16171 mips32_op = OPC_CVT_S_PL;
16172 goto do_unaryfp;
16173 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
16174 mips32_op = OPC_CVT_S_PU;
16175 goto do_unaryfp;
16176 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
16177 mips32_op = OPC_CVT_PW_PS;
16178 goto do_unaryfp;
16179 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
16180 mips32_op = OPC_CVT_PS_PW;
16181 goto do_unaryfp;
16182
16183 /* Floating-point moves */
16184 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
16185 mips32_op = OPC_MOV_S;
16186 goto do_unaryfp;
16187 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
16188 mips32_op = OPC_MOV_D;
16189 goto do_unaryfp;
16190 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
16191 mips32_op = OPC_MOV_PS;
16192 goto do_unaryfp;
16193
16194 /* Absolute value */
16195 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
16196 mips32_op = OPC_ABS_S;
16197 goto do_unaryfp;
16198 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
16199 mips32_op = OPC_ABS_D;
16200 goto do_unaryfp;
16201 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
16202 mips32_op = OPC_ABS_PS;
16203 goto do_unaryfp;
16204
16205 /* Negation */
16206 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
16207 mips32_op = OPC_NEG_S;
16208 goto do_unaryfp;
16209 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
16210 mips32_op = OPC_NEG_D;
16211 goto do_unaryfp;
16212 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
16213 mips32_op = OPC_NEG_PS;
16214 goto do_unaryfp;
16215
16216 /* Reciprocal square root step */
16217 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
16218 mips32_op = OPC_RSQRT1_S;
16219 goto do_unaryfp;
16220 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
16221 mips32_op = OPC_RSQRT1_D;
16222 goto do_unaryfp;
16223 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
16224 mips32_op = OPC_RSQRT1_PS;
16225 goto do_unaryfp;
16226
16227 /* Reciprocal step */
16228 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
16229 mips32_op = OPC_RECIP1_S;
16230 goto do_unaryfp;
16231 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
16232 mips32_op = OPC_RECIP1_S;
16233 goto do_unaryfp;
16234 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
16235 mips32_op = OPC_RECIP1_PS;
16236 goto do_unaryfp;
16237
16238 /* Conversions from double */
16239 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
16240 mips32_op = OPC_CVT_D_S;
16241 goto do_unaryfp;
16242 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
16243 mips32_op = OPC_CVT_D_W;
16244 goto do_unaryfp;
16245 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
16246 mips32_op = OPC_CVT_D_L;
16247 goto do_unaryfp;
16248
16249 /* Conversions from single */
16250 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
16251 mips32_op = OPC_CVT_S_D;
16252 goto do_unaryfp;
16253 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
16254 mips32_op = OPC_CVT_S_W;
16255 goto do_unaryfp;
16256 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16257 mips32_op = OPC_CVT_S_L;
16258 do_unaryfp:
16259 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16260 break;
16261
16262 /* Conditional moves on floating-point codes */
16263 case COND_FLOAT_MOV(MOVT, 0):
16264 case COND_FLOAT_MOV(MOVT, 1):
16265 case COND_FLOAT_MOV(MOVT, 2):
16266 case COND_FLOAT_MOV(MOVT, 3):
16267 case COND_FLOAT_MOV(MOVT, 4):
16268 case COND_FLOAT_MOV(MOVT, 5):
16269 case COND_FLOAT_MOV(MOVT, 6):
16270 case COND_FLOAT_MOV(MOVT, 7):
2e211e0a 16271 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16272 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16273 break;
16274 case COND_FLOAT_MOV(MOVF, 0):
16275 case COND_FLOAT_MOV(MOVF, 1):
16276 case COND_FLOAT_MOV(MOVF, 2):
16277 case COND_FLOAT_MOV(MOVF, 3):
16278 case COND_FLOAT_MOV(MOVF, 4):
16279 case COND_FLOAT_MOV(MOVF, 5):
16280 case COND_FLOAT_MOV(MOVF, 6):
16281 case COND_FLOAT_MOV(MOVF, 7):
2e211e0a 16282 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16283 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16284 break;
16285 default:
16286 MIPS_INVAL("pool32fxf");
3a4ef3b7 16287 gen_reserved_instruction(ctx);
3c824109
NF
16288 break;
16289 }
16290}
16291
f60eeb0c 16292static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
16293{
16294 int32_t offset;
16295 uint16_t insn;
16296 int rt, rs, rd, rr;
16297 int16_t imm;
8fffc646 16298 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
16299 uint32_t cond, fmt, cc;
16300
eeb3bba8 16301 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
16302 ctx->opcode = (ctx->opcode << 16) | insn;
16303
16304 rt = (ctx->opcode >> 21) & 0x1f;
16305 rs = (ctx->opcode >> 16) & 0x1f;
16306 rd = (ctx->opcode >> 11) & 0x1f;
16307 rr = (ctx->opcode >> 6) & 0x1f;
16308 imm = (int16_t) ctx->opcode;
16309
16310 op = (ctx->opcode >> 26) & 0x3f;
16311 switch (op) {
16312 case POOL32A:
16313 minor = ctx->opcode & 0x3f;
16314 switch (minor) {
16315 case 0x00:
16316 minor = (ctx->opcode >> 6) & 0xf;
16317 switch (minor) {
16318 case SLL32:
16319 mips32_op = OPC_SLL;
16320 goto do_shifti;
16321 case SRA:
16322 mips32_op = OPC_SRA;
16323 goto do_shifti;
16324 case SRL32:
16325 mips32_op = OPC_SRL;
16326 goto do_shifti;
16327 case ROTR:
16328 mips32_op = OPC_ROTR;
16329 do_shifti:
d75c135e 16330 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 16331 break;
e0332095 16332 case SELEQZ:
2e211e0a 16333 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
16334 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16335 break;
16336 case SELNEZ:
2e211e0a 16337 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
16338 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16339 break;
b00c7218 16340 case R6_RDHWR:
2e211e0a 16341 check_insn(ctx, ISA_MIPS_R6);
b00c7218
YK
16342 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16343 break;
3c824109
NF
16344 default:
16345 goto pool32a_invalid;
16346 }
16347 break;
16348 case 0x10:
16349 minor = (ctx->opcode >> 6) & 0xf;
16350 switch (minor) {
16351 /* Arithmetic */
16352 case ADD:
16353 mips32_op = OPC_ADD;
16354 goto do_arith;
16355 case ADDU32:
16356 mips32_op = OPC_ADDU;
16357 goto do_arith;
16358 case SUB:
16359 mips32_op = OPC_SUB;
16360 goto do_arith;
16361 case SUBU32:
16362 mips32_op = OPC_SUBU;
16363 goto do_arith;
16364 case MUL:
2e211e0a 16365 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16366 mips32_op = OPC_MUL;
16367 do_arith:
d75c135e 16368 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
16369 break;
16370 /* Shifts */
16371 case SLLV:
16372 mips32_op = OPC_SLLV;
16373 goto do_shift;
16374 case SRLV:
16375 mips32_op = OPC_SRLV;
16376 goto do_shift;
16377 case SRAV:
16378 mips32_op = OPC_SRAV;
16379 goto do_shift;
16380 case ROTRV:
16381 mips32_op = OPC_ROTRV;
16382 do_shift:
d75c135e 16383 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
16384 break;
16385 /* Logical operations */
16386 case AND:
16387 mips32_op = OPC_AND;
16388 goto do_logic;
16389 case OR32:
16390 mips32_op = OPC_OR;
16391 goto do_logic;
16392 case NOR:
16393 mips32_op = OPC_NOR;
16394 goto do_logic;
16395 case XOR32:
16396 mips32_op = OPC_XOR;
16397 do_logic:
d75c135e 16398 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
16399 break;
16400 /* Set less than */
16401 case SLT:
16402 mips32_op = OPC_SLT;
16403 goto do_slt;
16404 case SLTU:
16405 mips32_op = OPC_SLTU;
16406 do_slt:
d75c135e 16407 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
16408 break;
16409 default:
16410 goto pool32a_invalid;
16411 }
16412 break;
16413 case 0x18:
16414 minor = (ctx->opcode >> 6) & 0xf;
16415 switch (minor) {
16416 /* Conditional moves */
e0332095 16417 case MOVN: /* MUL */
2e211e0a 16418 if (ctx->insn_flags & ISA_MIPS_R6) {
e0332095
YK
16419 /* MUL */
16420 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16421 } else {
16422 /* MOVN */
16423 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16424 }
16425 break;
16426 case MOVZ: /* MUH */
2e211e0a 16427 if (ctx->insn_flags & ISA_MIPS_R6) {
e0332095
YK
16428 /* MUH */
16429 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16430 } else {
16431 /* MOVZ */
16432 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16433 }
16434 break;
16435 case MULU:
2e211e0a 16436 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
16437 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16438 break;
16439 case MUHU:
2e211e0a 16440 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
16441 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16442 break;
16443 case LWXS: /* DIV */
2e211e0a 16444 if (ctx->insn_flags & ISA_MIPS_R6) {
e0332095
YK
16445 /* DIV */
16446 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16447 } else {
16448 /* LWXS */
16449 gen_ldxs(ctx, rs, rt, rd);
16450 }
16451 break;
16452 case MOD:
2e211e0a 16453 check_insn(ctx, ISA_MIPS_R6);
e0332095
YK
16454 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16455 break;
16456 case R6_DIVU:
2e211e0a 16457 check_insn(ctx, ISA_MIPS_R6);
e0332095 16458 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 16459 break;
e0332095 16460 case MODU:
2e211e0a 16461 check_insn(ctx, ISA_MIPS_R6);
e0332095 16462 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
16463 break;
16464 default:
16465 goto pool32a_invalid;
16466 }
16467 break;
16468 case INS:
16469 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16470 return;
e0332095 16471 case LSA:
2e211e0a 16472 check_insn(ctx, ISA_MIPS_R6);
a685f7d0 16473 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2));
e0332095
YK
16474 break;
16475 case ALIGN:
2e211e0a 16476 check_insn(ctx, ISA_MIPS_R6);
821f2008 16477 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 16478 break;
3c824109
NF
16479 case EXT:
16480 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16481 return;
16482 case POOL32AXF:
240ce26a 16483 gen_pool32axf(env, ctx, rt, rs);
3c824109 16484 break;
dbd8af98 16485 case BREAK32:
9c708c7f 16486 generate_exception_end(ctx, EXCP_BREAK);
3c824109 16487 break;
bb238210 16488 case SIGRIE:
2e211e0a 16489 check_insn(ctx, ISA_MIPS_R6);
3a4ef3b7 16490 gen_reserved_instruction(ctx);
bb238210 16491 break;
3c824109
NF
16492 default:
16493 pool32a_invalid:
16494 MIPS_INVAL("pool32a");
3a4ef3b7 16495 gen_reserved_instruction(ctx);
3c824109
NF
16496 break;
16497 }
16498 break;
16499 case POOL32B:
16500 minor = (ctx->opcode >> 12) & 0xf;
16501 switch (minor) {
16502 case CACHE:
2e15497c 16503 check_cp0_enabled(ctx);
0d74a222
LA
16504 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16505 gen_cache_operation(ctx, rt, rs, imm);
16506 }
3c824109
NF
16507 break;
16508 case LWC2:
16509 case SWC2:
16510 /* COP2: Not implemented. */
16511 generate_exception_err(ctx, EXCP_CpU, 2);
16512 break;
3c824109
NF
16513#ifdef TARGET_MIPS64
16514 case LDP:
16515 case SDP:
d9224450
MR
16516 check_insn(ctx, ISA_MIPS3);
16517 check_mips_64(ctx);
3c824109 16518#endif
146dd620 16519 /* fall through */
d9224450
MR
16520 case LWP:
16521 case SWP:
3c824109
NF
16522 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16523 break;
3c824109
NF
16524#ifdef TARGET_MIPS64
16525 case LDM:
16526 case SDM:
d9224450
MR
16527 check_insn(ctx, ISA_MIPS3);
16528 check_mips_64(ctx);
3c824109 16529#endif
146dd620 16530 /* fall through */
d9224450
MR
16531 case LWM32:
16532 case SWM32:
3c824109
NF
16533 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16534 break;
16535 default:
16536 MIPS_INVAL("pool32b");
3a4ef3b7 16537 gen_reserved_instruction(ctx);
3c824109
NF
16538 break;
16539 }
16540 break;
16541 case POOL32F:
5ab5c041 16542 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
16543 minor = ctx->opcode & 0x3f;
16544 check_cp1_enabled(ctx);
16545 switch (minor) {
16546 case ALNV_PS:
2e211e0a 16547 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16548 mips32_op = OPC_ALNV_PS;
16549 goto do_madd;
16550 case MADD_S:
2e211e0a 16551 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16552 mips32_op = OPC_MADD_S;
16553 goto do_madd;
16554 case MADD_D:
2e211e0a 16555 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16556 mips32_op = OPC_MADD_D;
16557 goto do_madd;
16558 case MADD_PS:
2e211e0a 16559 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16560 mips32_op = OPC_MADD_PS;
16561 goto do_madd;
16562 case MSUB_S:
2e211e0a 16563 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16564 mips32_op = OPC_MSUB_S;
16565 goto do_madd;
16566 case MSUB_D:
2e211e0a 16567 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16568 mips32_op = OPC_MSUB_D;
16569 goto do_madd;
16570 case MSUB_PS:
2e211e0a 16571 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16572 mips32_op = OPC_MSUB_PS;
16573 goto do_madd;
16574 case NMADD_S:
2e211e0a 16575 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16576 mips32_op = OPC_NMADD_S;
16577 goto do_madd;
16578 case NMADD_D:
2e211e0a 16579 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16580 mips32_op = OPC_NMADD_D;
16581 goto do_madd;
16582 case NMADD_PS:
2e211e0a 16583 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16584 mips32_op = OPC_NMADD_PS;
16585 goto do_madd;
16586 case NMSUB_S:
2e211e0a 16587 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16588 mips32_op = OPC_NMSUB_S;
16589 goto do_madd;
16590 case NMSUB_D:
2e211e0a 16591 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16592 mips32_op = OPC_NMSUB_D;
16593 goto do_madd;
16594 case NMSUB_PS:
2e211e0a 16595 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16596 mips32_op = OPC_NMSUB_PS;
16597 do_madd:
16598 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16599 break;
16600 case CABS_COND_FMT:
2e211e0a 16601 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16602 cond = (ctx->opcode >> 6) & 0xf;
16603 cc = (ctx->opcode >> 13) & 0x7;
16604 fmt = (ctx->opcode >> 10) & 0x3;
16605 switch (fmt) {
16606 case 0x0:
16607 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16608 break;
16609 case 0x1:
16610 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16611 break;
16612 case 0x2:
16613 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16614 break;
16615 default:
16616 goto pool32f_invalid;
16617 }
16618 break;
16619 case C_COND_FMT:
2e211e0a 16620 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16621 cond = (ctx->opcode >> 6) & 0xf;
16622 cc = (ctx->opcode >> 13) & 0x7;
16623 fmt = (ctx->opcode >> 10) & 0x3;
16624 switch (fmt) {
16625 case 0x0:
16626 gen_cmp_s(ctx, cond, rt, rs, cc);
16627 break;
16628 case 0x1:
16629 gen_cmp_d(ctx, cond, rt, rs, cc);
16630 break;
16631 case 0x2:
16632 gen_cmp_ps(ctx, cond, rt, rs, cc);
16633 break;
16634 default:
16635 goto pool32f_invalid;
16636 }
16637 break;
2a24a7ba 16638 case CMP_CONDN_S:
2e211e0a 16639 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16640 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16641 break;
16642 case CMP_CONDN_D:
2e211e0a 16643 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16644 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16645 break;
3c824109 16646 case POOL32FXF:
d75c135e 16647 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
16648 break;
16649 case 0x00:
16650 /* PLL foo */
16651 switch ((ctx->opcode >> 6) & 0x7) {
16652 case PLL_PS:
16653 mips32_op = OPC_PLL_PS;
16654 goto do_ps;
16655 case PLU_PS:
16656 mips32_op = OPC_PLU_PS;
16657 goto do_ps;
16658 case PUL_PS:
16659 mips32_op = OPC_PUL_PS;
16660 goto do_ps;
16661 case PUU_PS:
16662 mips32_op = OPC_PUU_PS;
16663 goto do_ps;
16664 case CVT_PS_S:
2e211e0a 16665 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16666 mips32_op = OPC_CVT_PS_S;
16667 do_ps:
16668 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16669 break;
16670 default:
16671 goto pool32f_invalid;
16672 }
16673 break;
2a24a7ba 16674 case MIN_FMT:
2e211e0a 16675 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16676 switch ((ctx->opcode >> 9) & 0x3) {
16677 case FMT_SDPS_S:
16678 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16679 break;
16680 case FMT_SDPS_D:
16681 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16682 break;
16683 default:
16684 goto pool32f_invalid;
16685 }
16686 break;
3c824109
NF
16687 case 0x08:
16688 /* [LS][WDU]XC1 */
16689 switch ((ctx->opcode >> 6) & 0x7) {
16690 case LWXC1:
2e211e0a 16691 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16692 mips32_op = OPC_LWXC1;
16693 goto do_ldst_cp1;
16694 case SWXC1:
2e211e0a 16695 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16696 mips32_op = OPC_SWXC1;
16697 goto do_ldst_cp1;
16698 case LDXC1:
2e211e0a 16699 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16700 mips32_op = OPC_LDXC1;
16701 goto do_ldst_cp1;
16702 case SDXC1:
2e211e0a 16703 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16704 mips32_op = OPC_SDXC1;
16705 goto do_ldst_cp1;
16706 case LUXC1:
2e211e0a 16707 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16708 mips32_op = OPC_LUXC1;
16709 goto do_ldst_cp1;
16710 case SUXC1:
2e211e0a 16711 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16712 mips32_op = OPC_SUXC1;
16713 do_ldst_cp1:
16714 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16715 break;
16716 default:
16717 goto pool32f_invalid;
16718 }
16719 break;
2a24a7ba 16720 case MAX_FMT:
2e211e0a 16721 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16722 switch ((ctx->opcode >> 9) & 0x3) {
16723 case FMT_SDPS_S:
16724 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16725 break;
16726 case FMT_SDPS_D:
16727 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16728 break;
16729 default:
16730 goto pool32f_invalid;
16731 }
16732 break;
3c824109
NF
16733 case 0x18:
16734 /* 3D insns */
2e211e0a 16735 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16736 fmt = (ctx->opcode >> 9) & 0x3;
16737 switch ((ctx->opcode >> 6) & 0x7) {
16738 case RSQRT2_FMT:
16739 switch (fmt) {
16740 case FMT_SDPS_S:
16741 mips32_op = OPC_RSQRT2_S;
16742 goto do_3d;
16743 case FMT_SDPS_D:
16744 mips32_op = OPC_RSQRT2_D;
16745 goto do_3d;
16746 case FMT_SDPS_PS:
16747 mips32_op = OPC_RSQRT2_PS;
16748 goto do_3d;
16749 default:
16750 goto pool32f_invalid;
16751 }
16752 break;
16753 case RECIP2_FMT:
16754 switch (fmt) {
16755 case FMT_SDPS_S:
16756 mips32_op = OPC_RECIP2_S;
16757 goto do_3d;
16758 case FMT_SDPS_D:
16759 mips32_op = OPC_RECIP2_D;
16760 goto do_3d;
16761 case FMT_SDPS_PS:
16762 mips32_op = OPC_RECIP2_PS;
16763 goto do_3d;
16764 default:
16765 goto pool32f_invalid;
16766 }
16767 break;
16768 case ADDR_PS:
16769 mips32_op = OPC_ADDR_PS;
16770 goto do_3d;
16771 case MULR_PS:
16772 mips32_op = OPC_MULR_PS;
16773 do_3d:
16774 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16775 break;
16776 default:
16777 goto pool32f_invalid;
16778 }
16779 break;
16780 case 0x20:
2a24a7ba 16781 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
16782 cc = (ctx->opcode >> 13) & 0x7;
16783 fmt = (ctx->opcode >> 9) & 0x3;
16784 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba 16785 case MOVF_FMT: /* RINT_FMT */
2e211e0a 16786 if (ctx->insn_flags & ISA_MIPS_R6) {
2a24a7ba
YK
16787 /* RINT_FMT */
16788 switch (fmt) {
16789 case FMT_SDPS_S:
16790 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16791 break;
16792 case FMT_SDPS_D:
16793 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16794 break;
16795 default:
16796 goto pool32f_invalid;
16797 }
16798 } else {
16799 /* MOVF_FMT */
16800 switch (fmt) {
16801 case FMT_SDPS_S:
16802 gen_movcf_s(ctx, rs, rt, cc, 0);
16803 break;
16804 case FMT_SDPS_D:
16805 gen_movcf_d(ctx, rs, rt, cc, 0);
16806 break;
16807 case FMT_SDPS_PS:
16808 check_ps(ctx);
16809 gen_movcf_ps(ctx, rs, rt, cc, 0);
16810 break;
16811 default:
16812 goto pool32f_invalid;
16813 }
3c824109
NF
16814 }
16815 break;
2a24a7ba 16816 case MOVT_FMT: /* CLASS_FMT */
2e211e0a 16817 if (ctx->insn_flags & ISA_MIPS_R6) {
2a24a7ba
YK
16818 /* CLASS_FMT */
16819 switch (fmt) {
16820 case FMT_SDPS_S:
16821 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16822 break;
16823 case FMT_SDPS_D:
16824 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16825 break;
16826 default:
16827 goto pool32f_invalid;
16828 }
16829 } else {
16830 /* MOVT_FMT */
16831 switch (fmt) {
16832 case FMT_SDPS_S:
16833 gen_movcf_s(ctx, rs, rt, cc, 1);
16834 break;
16835 case FMT_SDPS_D:
16836 gen_movcf_d(ctx, rs, rt, cc, 1);
16837 break;
16838 case FMT_SDPS_PS:
16839 check_ps(ctx);
16840 gen_movcf_ps(ctx, rs, rt, cc, 1);
16841 break;
16842 default:
16843 goto pool32f_invalid;
16844 }
3c824109
NF
16845 }
16846 break;
16847 case PREFX:
2e211e0a 16848 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16849 break;
16850 default:
16851 goto pool32f_invalid;
16852 }
16853 break;
16854#define FINSN_3ARG_SDPS(prfx) \
16855 switch ((ctx->opcode >> 8) & 0x3) { \
16856 case FMT_SDPS_S: \
16857 mips32_op = OPC_##prfx##_S; \
16858 goto do_fpop; \
16859 case FMT_SDPS_D: \
16860 mips32_op = OPC_##prfx##_D; \
16861 goto do_fpop; \
16862 case FMT_SDPS_PS: \
e29c9628 16863 check_ps(ctx); \
3c824109
NF
16864 mips32_op = OPC_##prfx##_PS; \
16865 goto do_fpop; \
16866 default: \
16867 goto pool32f_invalid; \
16868 }
2a24a7ba 16869 case MINA_FMT:
2e211e0a 16870 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16871 switch ((ctx->opcode >> 9) & 0x3) {
16872 case FMT_SDPS_S:
16873 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16874 break;
16875 case FMT_SDPS_D:
16876 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16877 break;
16878 default:
16879 goto pool32f_invalid;
16880 }
16881 break;
16882 case MAXA_FMT:
2e211e0a 16883 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16884 switch ((ctx->opcode >> 9) & 0x3) {
16885 case FMT_SDPS_S:
16886 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16887 break;
16888 case FMT_SDPS_D:
16889 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16890 break;
16891 default:
16892 goto pool32f_invalid;
16893 }
16894 break;
3c824109
NF
16895 case 0x30:
16896 /* regular FP ops */
16897 switch ((ctx->opcode >> 6) & 0x3) {
16898 case ADD_FMT:
16899 FINSN_3ARG_SDPS(ADD);
16900 break;
16901 case SUB_FMT:
16902 FINSN_3ARG_SDPS(SUB);
16903 break;
16904 case MUL_FMT:
16905 FINSN_3ARG_SDPS(MUL);
16906 break;
16907 case DIV_FMT:
16908 fmt = (ctx->opcode >> 8) & 0x3;
16909 if (fmt == 1) {
16910 mips32_op = OPC_DIV_D;
16911 } else if (fmt == 0) {
16912 mips32_op = OPC_DIV_S;
16913 } else {
16914 goto pool32f_invalid;
16915 }
16916 goto do_fpop;
16917 default:
16918 goto pool32f_invalid;
16919 }
16920 break;
16921 case 0x38:
16922 /* cmovs */
2a24a7ba 16923 switch ((ctx->opcode >> 6) & 0x7) {
fdac60cd 16924 case MOVN_FMT: /* SELEQZ_FMT */
2e211e0a 16925 if (ctx->insn_flags & ISA_MIPS_R6) {
fdac60cd 16926 /* SELEQZ_FMT */
2a24a7ba
YK
16927 switch ((ctx->opcode >> 9) & 0x3) {
16928 case FMT_SDPS_S:
fdac60cd 16929 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2a24a7ba
YK
16930 break;
16931 case FMT_SDPS_D:
fdac60cd 16932 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2a24a7ba
YK
16933 break;
16934 default:
16935 goto pool32f_invalid;
16936 }
16937 } else {
16938 /* MOVN_FMT */
16939 FINSN_3ARG_SDPS(MOVN);
16940 }
16941 break;
16942 case MOVN_FMT_04:
2e211e0a 16943 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16944 FINSN_3ARG_SDPS(MOVN);
16945 break;
fdac60cd 16946 case MOVZ_FMT: /* SELNEZ_FMT */
2e211e0a 16947 if (ctx->insn_flags & ISA_MIPS_R6) {
fdac60cd 16948 /* SELNEZ_FMT */
2a24a7ba
YK
16949 switch ((ctx->opcode >> 9) & 0x3) {
16950 case FMT_SDPS_S:
fdac60cd 16951 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2a24a7ba
YK
16952 break;
16953 case FMT_SDPS_D:
fdac60cd 16954 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2a24a7ba
YK
16955 break;
16956 default:
16957 goto pool32f_invalid;
16958 }
16959 } else {
16960 /* MOVZ_FMT */
16961 FINSN_3ARG_SDPS(MOVZ);
16962 }
16963 break;
16964 case MOVZ_FMT_05:
2e211e0a 16965 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
16966 FINSN_3ARG_SDPS(MOVZ);
16967 break;
2a24a7ba 16968 case SEL_FMT:
2e211e0a 16969 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16970 switch ((ctx->opcode >> 9) & 0x3) {
16971 case FMT_SDPS_S:
16972 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16973 break;
16974 case FMT_SDPS_D:
16975 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16976 break;
16977 default:
16978 goto pool32f_invalid;
16979 }
16980 break;
16981 case MADDF_FMT:
2e211e0a 16982 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16983 switch ((ctx->opcode >> 9) & 0x3) {
16984 case FMT_SDPS_S:
16985 mips32_op = OPC_MADDF_S;
16986 goto do_fpop;
16987 case FMT_SDPS_D:
16988 mips32_op = OPC_MADDF_D;
16989 goto do_fpop;
16990 default:
16991 goto pool32f_invalid;
16992 }
16993 break;
16994 case MSUBF_FMT:
2e211e0a 16995 check_insn(ctx, ISA_MIPS_R6);
2a24a7ba
YK
16996 switch ((ctx->opcode >> 9) & 0x3) {
16997 case FMT_SDPS_S:
16998 mips32_op = OPC_MSUBF_S;
16999 goto do_fpop;
17000 case FMT_SDPS_D:
17001 mips32_op = OPC_MSUBF_D;
17002 goto do_fpop;
17003 default:
17004 goto pool32f_invalid;
17005 }
17006 break;
3c824109
NF
17007 default:
17008 goto pool32f_invalid;
17009 }
17010 break;
17011 do_fpop:
17012 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
17013 break;
17014 default:
17015 pool32f_invalid:
17016 MIPS_INVAL("pool32f");
3a4ef3b7 17017 gen_reserved_instruction(ctx);
3c824109
NF
17018 break;
17019 }
17020 } else {
17021 generate_exception_err(ctx, EXCP_CpU, 1);
17022 }
17023 break;
17024 case POOL32I:
17025 minor = (ctx->opcode >> 21) & 0x1f;
17026 switch (minor) {
17027 case BLTZ:
2e211e0a 17028 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17029 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
17030 break;
3c824109 17031 case BLTZAL:
2e211e0a 17032 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17033 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
17034 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17035 break;
3c824109 17036 case BLTZALS:
2e211e0a 17037 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17038 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
17039 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17040 break;
3c824109 17041 case BGEZ:
2e211e0a 17042 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17043 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
17044 break;
3c824109 17045 case BGEZAL:
2e211e0a 17046 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17047 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
17048 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17049 break;
3c824109 17050 case BGEZALS:
2e211e0a 17051 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17052 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
17053 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17054 break;
3c824109 17055 case BLEZ:
2e211e0a 17056 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103
YK
17057 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
17058 break;
3c824109 17059 case BGTZ:
2e211e0a 17060 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b231c103 17061 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
17062 break;
17063
17064 /* Traps */
65935f07 17065 case TLTI: /* BC1EQZC */
2e211e0a 17066 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17067 /* BC1EQZC */
17068 check_cp1_enabled(ctx);
17069 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
17070 } else {
17071 /* TLTI */
17072 mips32_op = OPC_TLTI;
17073 goto do_trapi;
17074 }
17075 break;
17076 case TGEI: /* BC1NEZC */
2e211e0a 17077 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17078 /* BC1NEZC */
17079 check_cp1_enabled(ctx);
17080 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
17081 } else {
17082 /* TGEI */
17083 mips32_op = OPC_TGEI;
17084 goto do_trapi;
17085 }
17086 break;
3c824109 17087 case TLTIU:
2e211e0a 17088 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17089 mips32_op = OPC_TLTIU;
17090 goto do_trapi;
17091 case TGEIU:
2e211e0a 17092 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17093 mips32_op = OPC_TGEIU;
17094 goto do_trapi;
3b4a5489 17095 case TNEI: /* SYNCI */
2e211e0a 17096 if (ctx->insn_flags & ISA_MIPS_R6) {
3b4a5489 17097 /* SYNCI */
7480515f
AM
17098 /*
17099 * Break the TB to be able to sync copied instructions
17100 * immediately.
17101 */
eeb3bba8 17102 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
17103 } else {
17104 /* TNEI */
17105 mips32_op = OPC_TNEI;
17106 goto do_trapi;
17107 }
17108 break;
3c824109 17109 case TEQI:
2e211e0a 17110 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17111 mips32_op = OPC_TEQI;
17112 do_trapi:
17113 gen_trap(ctx, mips32_op, rs, -1, imm);
17114 break;
17115
17116 case BNEZC:
17117 case BEQZC:
2e211e0a 17118 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17119 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 17120 4, rs, 0, imm << 1, 0);
7480515f
AM
17121 /*
17122 * Compact branches don't have a delay slot, so just let
17123 * the normal delay slot handling take us to the branch
17124 * target.
17125 */
3c824109
NF
17126 break;
17127 case LUI:
2e211e0a 17128 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5e88759a 17129 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
17130 break;
17131 case SYNCI:
2e211e0a 17132 check_insn_opc_removed(ctx, ISA_MIPS_R6);
7480515f
AM
17133 /*
17134 * Break the TB to be able to sync copied instructions
17135 * immediately.
17136 */
eeb3bba8 17137 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
17138 break;
17139 case BC2F:
17140 case BC2T:
2e211e0a 17141 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17142 /* COP2: Not implemented. */
17143 generate_exception_err(ctx, EXCP_CpU, 2);
17144 break;
17145 case BC1F:
2e211e0a 17146 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17147 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
17148 goto do_cp1branch;
17149 case BC1T:
2e211e0a 17150 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17151 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
17152 goto do_cp1branch;
17153 case BC1ANY4F:
2e211e0a 17154 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17155 mips32_op = OPC_BC1FANY4;
17156 goto do_cp1mips3d;
17157 case BC1ANY4T:
2e211e0a 17158 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109
NF
17159 mips32_op = OPC_BC1TANY4;
17160 do_cp1mips3d:
17161 check_cop1x(ctx);
d75c135e 17162 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
17163 /* Fall through */
17164 do_cp1branch:
272f458d
MR
17165 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17166 check_cp1_enabled(ctx);
17167 gen_compute_branch1(ctx, mips32_op,
17168 (ctx->opcode >> 18) & 0x7, imm << 1);
17169 } else {
17170 generate_exception_err(ctx, EXCP_CpU, 1);
17171 }
3c824109
NF
17172 break;
17173 case BPOSGE64:
17174 case BPOSGE32:
17175 /* MIPS DSP: not implemented */
17176 /* Fall through */
17177 default:
17178 MIPS_INVAL("pool32i");
3a4ef3b7 17179 gen_reserved_instruction(ctx);
3c824109
NF
17180 break;
17181 }
17182 break;
17183 case POOL32C:
17184 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489 17185 offset = sextract32(ctx->opcode, 0,
2e211e0a 17186 (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12);
3c824109
NF
17187 switch (minor) {
17188 case LWL:
2e211e0a 17189 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17190 mips32_op = OPC_LWL;
5c13fdfd 17191 goto do_ld_lr;
3c824109 17192 case SWL:
2e211e0a 17193 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17194 mips32_op = OPC_SWL;
5c13fdfd 17195 goto do_st_lr;
3c824109 17196 case LWR:
2e211e0a 17197 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17198 mips32_op = OPC_LWR;
5c13fdfd 17199 goto do_ld_lr;
3c824109 17200 case SWR:
2e211e0a 17201 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17202 mips32_op = OPC_SWR;
5c13fdfd 17203 goto do_st_lr;
3c824109
NF
17204#if defined(TARGET_MIPS64)
17205 case LDL:
d9224450
MR
17206 check_insn(ctx, ISA_MIPS3);
17207 check_mips_64(ctx);
2e211e0a 17208 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17209 mips32_op = OPC_LDL;
5c13fdfd 17210 goto do_ld_lr;
3c824109 17211 case SDL:
d9224450
MR
17212 check_insn(ctx, ISA_MIPS3);
17213 check_mips_64(ctx);
2e211e0a 17214 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17215 mips32_op = OPC_SDL;
5c13fdfd 17216 goto do_st_lr;
3c824109 17217 case LDR:
d9224450
MR
17218 check_insn(ctx, ISA_MIPS3);
17219 check_mips_64(ctx);
2e211e0a 17220 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17221 mips32_op = OPC_LDR;
5c13fdfd 17222 goto do_ld_lr;
3c824109 17223 case SDR:
d9224450
MR
17224 check_insn(ctx, ISA_MIPS3);
17225 check_mips_64(ctx);
2e211e0a 17226 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17227 mips32_op = OPC_SDR;
5c13fdfd 17228 goto do_st_lr;
3c824109 17229 case LWU:
d9224450
MR
17230 check_insn(ctx, ISA_MIPS3);
17231 check_mips_64(ctx);
3c824109 17232 mips32_op = OPC_LWU;
5c13fdfd 17233 goto do_ld_lr;
3c824109 17234 case LLD:
d9224450
MR
17235 check_insn(ctx, ISA_MIPS3);
17236 check_mips_64(ctx);
3c824109 17237 mips32_op = OPC_LLD;
5c13fdfd 17238 goto do_ld_lr;
3c824109
NF
17239#endif
17240 case LL:
17241 mips32_op = OPC_LL;
5c13fdfd
AJ
17242 goto do_ld_lr;
17243 do_ld_lr:
3b4a5489 17244 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
17245 break;
17246 do_st_lr:
8fffc646 17247 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
17248 break;
17249 case SC:
33a07fa2 17250 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
3c824109
NF
17251 break;
17252#if defined(TARGET_MIPS64)
17253 case SCD:
d9224450
MR
17254 check_insn(ctx, ISA_MIPS3);
17255 check_mips_64(ctx);
33a07fa2 17256 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
3c824109
NF
17257 break;
17258#endif
8fffc646
JH
17259 case LD_EVA:
17260 if (!ctx->eva) {
17261 MIPS_INVAL("pool32c ld-eva");
3a4ef3b7 17262 gen_reserved_instruction(ctx);
8fffc646
JH
17263 break;
17264 }
17265 check_cp0_enabled(ctx);
17266
17267 minor2 = (ctx->opcode >> 9) & 0x7;
17268 offset = sextract32(ctx->opcode, 0, 9);
17269 switch (minor2) {
17270 case LBUE:
17271 mips32_op = OPC_LBUE;
17272 goto do_ld_lr;
17273 case LHUE:
17274 mips32_op = OPC_LHUE;
17275 goto do_ld_lr;
17276 case LWLE:
2e211e0a 17277 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8fffc646
JH
17278 mips32_op = OPC_LWLE;
17279 goto do_ld_lr;
17280 case LWRE:
2e211e0a 17281 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8fffc646
JH
17282 mips32_op = OPC_LWRE;
17283 goto do_ld_lr;
17284 case LBE:
17285 mips32_op = OPC_LBE;
17286 goto do_ld_lr;
17287 case LHE:
17288 mips32_op = OPC_LHE;
17289 goto do_ld_lr;
17290 case LLE:
17291 mips32_op = OPC_LLE;
17292 goto do_ld_lr;
17293 case LWE:
17294 mips32_op = OPC_LWE;
17295 goto do_ld_lr;
17296 };
17297 break;
17298 case ST_EVA:
17299 if (!ctx->eva) {
17300 MIPS_INVAL("pool32c st-eva");
3a4ef3b7 17301 gen_reserved_instruction(ctx);
8fffc646
JH
17302 break;
17303 }
17304 check_cp0_enabled(ctx);
17305
17306 minor2 = (ctx->opcode >> 9) & 0x7;
17307 offset = sextract32(ctx->opcode, 0, 9);
17308 switch (minor2) {
17309 case SWLE:
2e211e0a 17310 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8fffc646
JH
17311 mips32_op = OPC_SWLE;
17312 goto do_st_lr;
17313 case SWRE:
2e211e0a 17314 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8fffc646
JH
17315 mips32_op = OPC_SWRE;
17316 goto do_st_lr;
17317 case PREFE:
17318 /* Treat as no-op */
2e211e0a 17319 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
8fffc646
JH
17320 /* hint codes 24-31 are reserved and signal RI */
17321 generate_exception(ctx, EXCP_RI);
17322 }
17323 break;
17324 case CACHEE:
17325 /* Treat as no-op */
17326 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17327 gen_cache_operation(ctx, rt, rs, offset);
17328 }
17329 break;
17330 case SBE:
17331 mips32_op = OPC_SBE;
17332 goto do_st_lr;
17333 case SHE:
17334 mips32_op = OPC_SHE;
17335 goto do_st_lr;
17336 case SCE:
33a07fa2 17337 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
8fffc646
JH
17338 break;
17339 case SWE:
17340 mips32_op = OPC_SWE;
17341 goto do_st_lr;
17342 };
17343 break;
3c824109
NF
17344 case PREF:
17345 /* Treat as no-op */
2e211e0a 17346 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
3b4a5489
YK
17347 /* hint codes 24-31 are reserved and signal RI */
17348 generate_exception(ctx, EXCP_RI);
17349 }
3c824109
NF
17350 break;
17351 default:
17352 MIPS_INVAL("pool32c");
3a4ef3b7 17353 gen_reserved_instruction(ctx);
3c824109
NF
17354 break;
17355 }
17356 break;
ab39ee45 17357 case ADDI32: /* AUI, LUI */
2e211e0a 17358 if (ctx->insn_flags & ISA_MIPS_R6) {
ab39ee45
YK
17359 /* AUI, LUI */
17360 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17361 } else {
17362 /* ADDI32 */
17363 mips32_op = OPC_ADDI;
17364 goto do_addi;
17365 }
17366 break;
3c824109
NF
17367 case ADDIU32:
17368 mips32_op = OPC_ADDIU;
17369 do_addi:
d75c135e 17370 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17371 break;
17372
17373 /* Logical operations */
17374 case ORI32:
17375 mips32_op = OPC_ORI;
17376 goto do_logici;
17377 case XORI32:
17378 mips32_op = OPC_XORI;
17379 goto do_logici;
17380 case ANDI32:
17381 mips32_op = OPC_ANDI;
17382 do_logici:
d75c135e 17383 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17384 break;
17385
17386 /* Set less than immediate */
17387 case SLTI32:
17388 mips32_op = OPC_SLTI;
17389 goto do_slti;
17390 case SLTIU32:
17391 mips32_op = OPC_SLTIU;
17392 do_slti:
d75c135e 17393 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17394 break;
17395 case JALX32:
2e211e0a 17396 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17397 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
17398 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17399 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 17400 break;
65935f07 17401 case JALS32: /* BOVC, BEQC, BEQZALC */
2e211e0a 17402 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17403 if (rs >= rt) {
17404 /* BOVC */
17405 mips32_op = OPC_BOVC;
17406 } else if (rs < rt && rs == 0) {
17407 /* BEQZALC */
17408 mips32_op = OPC_BEQZALC;
17409 } else {
17410 /* BEQC */
17411 mips32_op = OPC_BEQC;
17412 }
17413 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17414 } else {
17415 /* JALS32 */
17416 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17417 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17418 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17419 }
3c824109 17420 break;
65935f07 17421 case BEQ32: /* BC */
2e211e0a 17422 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17423 /* BC */
17424 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17425 sextract32(ctx->opcode << 1, 0, 27));
17426 } else {
17427 /* BEQ32 */
17428 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17429 }
3c824109 17430 break;
65935f07 17431 case BNE32: /* BALC */
2e211e0a 17432 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17433 /* BALC */
17434 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17435 sextract32(ctx->opcode << 1, 0, 27));
17436 } else {
17437 /* BNE32 */
17438 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17439 }
3c824109 17440 break;
65935f07 17441 case J32: /* BGTZC, BLTZC, BLTC */
2e211e0a 17442 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17443 if (rs == 0 && rt != 0) {
17444 /* BGTZC */
17445 mips32_op = OPC_BGTZC;
17446 } else if (rs != 0 && rt != 0 && rs == rt) {
17447 /* BLTZC */
17448 mips32_op = OPC_BLTZC;
17449 } else {
17450 /* BLTC */
17451 mips32_op = OPC_BLTC;
17452 }
17453 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17454 } else {
17455 /* J32 */
17456 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17457 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17458 }
3c824109 17459 break;
65935f07 17460 case JAL32: /* BLEZC, BGEZC, BGEC */
2e211e0a 17461 if (ctx->insn_flags & ISA_MIPS_R6) {
65935f07
YK
17462 if (rs == 0 && rt != 0) {
17463 /* BLEZC */
17464 mips32_op = OPC_BLEZC;
17465 } else if (rs != 0 && rt != 0 && rs == rt) {
17466 /* BGEZC */
17467 mips32_op = OPC_BGEZC;
17468 } else {
17469 /* BGEC */
17470 mips32_op = OPC_BGEC;
17471 }
17472 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17473 } else {
17474 /* JAL32 */
17475 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17476 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17477 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17478 }
3c824109
NF
17479 break;
17480 /* Floating point (COP1) */
17481 case LWC132:
17482 mips32_op = OPC_LWC1;
17483 goto do_cop1;
17484 case LDC132:
17485 mips32_op = OPC_LDC1;
17486 goto do_cop1;
17487 case SWC132:
17488 mips32_op = OPC_SWC1;
17489 goto do_cop1;
17490 case SDC132:
17491 mips32_op = OPC_SDC1;
17492 do_cop1:
5ab5c041 17493 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 17494 break;
ab39ee45 17495 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
2e211e0a 17496 if (ctx->insn_flags & ISA_MIPS_R6) {
ab39ee45
YK
17497 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17498 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
17499 case ADDIUPC_00:
17500 case ADDIUPC_01:
17501 case ADDIUPC_02:
17502 case ADDIUPC_03:
17503 case ADDIUPC_04:
17504 case ADDIUPC_05:
17505 case ADDIUPC_06:
17506 case ADDIUPC_07:
eeb3bba8 17507 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
17508 break;
17509 case AUIPC:
eeb3bba8 17510 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
17511 break;
17512 case ALUIPC:
eeb3bba8 17513 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 17514 break;
c38a1d52
AR
17515 case LWPC_08:
17516 case LWPC_09:
17517 case LWPC_0A:
17518 case LWPC_0B:
17519 case LWPC_0C:
17520 case LWPC_0D:
17521 case LWPC_0E:
17522 case LWPC_0F:
eeb3bba8 17523 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
17524 break;
17525 default:
17526 generate_exception(ctx, EXCP_RI);
17527 break;
17528 }
17529 } else {
17530 /* ADDIUPC */
3c824109 17531 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 17532 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
17533
17534 gen_addiupc(ctx, reg, offset, 0, 0);
17535 }
17536 break;
65935f07 17537 case BNVC: /* BNEC, BNEZALC */
2e211e0a 17538 check_insn(ctx, ISA_MIPS_R6);
65935f07
YK
17539 if (rs >= rt) {
17540 /* BNVC */
17541 mips32_op = OPC_BNVC;
17542 } else if (rs < rt && rs == 0) {
17543 /* BNEZALC */
17544 mips32_op = OPC_BNEZALC;
17545 } else {
17546 /* BNEC */
17547 mips32_op = OPC_BNEC;
17548 }
17549 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17550 break;
17551 case R6_BNEZC: /* JIALC */
2e211e0a 17552 check_insn(ctx, ISA_MIPS_R6);
65935f07
YK
17553 if (rt != 0) {
17554 /* BNEZC */
17555 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17556 sextract32(ctx->opcode << 1, 0, 22));
17557 } else {
17558 /* JIALC */
17559 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17560 }
17561 break;
17562 case R6_BEQZC: /* JIC */
2e211e0a 17563 check_insn(ctx, ISA_MIPS_R6);
65935f07
YK
17564 if (rt != 0) {
17565 /* BEQZC */
17566 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17567 sextract32(ctx->opcode << 1, 0, 22));
17568 } else {
17569 /* JIC */
17570 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17571 }
17572 break;
17573 case BLEZALC: /* BGEZALC, BGEUC */
2e211e0a 17574 check_insn(ctx, ISA_MIPS_R6);
65935f07
YK
17575 if (rs == 0 && rt != 0) {
17576 /* BLEZALC */
17577 mips32_op = OPC_BLEZALC;
17578 } else if (rs != 0 && rt != 0 && rs == rt) {
17579 /* BGEZALC */
17580 mips32_op = OPC_BGEZALC;
17581 } else {
17582 /* BGEUC */
17583 mips32_op = OPC_BGEUC;
17584 }
17585 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17586 break;
17587 case BGTZALC: /* BLTZALC, BLTUC */
2e211e0a 17588 check_insn(ctx, ISA_MIPS_R6);
65935f07
YK
17589 if (rs == 0 && rt != 0) {
17590 /* BGTZALC */
17591 mips32_op = OPC_BGTZALC;
17592 } else if (rs != 0 && rt != 0 && rs == rt) {
17593 /* BLTZALC */
17594 mips32_op = OPC_BLTZALC;
17595 } else {
17596 /* BLTUC */
17597 mips32_op = OPC_BLTUC;
17598 }
17599 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17600 break;
3c824109
NF
17601 /* Loads and stores */
17602 case LB32:
17603 mips32_op = OPC_LB;
5c13fdfd 17604 goto do_ld;
3c824109
NF
17605 case LBU32:
17606 mips32_op = OPC_LBU;
5c13fdfd 17607 goto do_ld;
3c824109
NF
17608 case LH32:
17609 mips32_op = OPC_LH;
5c13fdfd 17610 goto do_ld;
3c824109
NF
17611 case LHU32:
17612 mips32_op = OPC_LHU;
5c13fdfd 17613 goto do_ld;
3c824109
NF
17614 case LW32:
17615 mips32_op = OPC_LW;
5c13fdfd 17616 goto do_ld;
3c824109
NF
17617#ifdef TARGET_MIPS64
17618 case LD32:
d9224450
MR
17619 check_insn(ctx, ISA_MIPS3);
17620 check_mips_64(ctx);
3c824109 17621 mips32_op = OPC_LD;
5c13fdfd 17622 goto do_ld;
3c824109 17623 case SD32:
d9224450
MR
17624 check_insn(ctx, ISA_MIPS3);
17625 check_mips_64(ctx);
3c824109 17626 mips32_op = OPC_SD;
5c13fdfd 17627 goto do_st;
3c824109
NF
17628#endif
17629 case SB32:
17630 mips32_op = OPC_SB;
5c13fdfd 17631 goto do_st;
3c824109
NF
17632 case SH32:
17633 mips32_op = OPC_SH;
5c13fdfd 17634 goto do_st;
3c824109
NF
17635 case SW32:
17636 mips32_op = OPC_SW;
5c13fdfd
AJ
17637 goto do_st;
17638 do_ld:
d75c135e 17639 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
17640 break;
17641 do_st:
17642 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17643 break;
17644 default:
3a4ef3b7 17645 gen_reserved_instruction(ctx);
3c824109
NF
17646 break;
17647 }
17648}
17649
235785e8 17650static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
17651{
17652 uint32_t op;
17653
17654 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
17655 if (ctx->base.pc_next & 0x1) {
17656 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 17657 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
17658 return 2;
17659 }
17660
17661 op = (ctx->opcode >> 10) & 0x3f;
17662 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
17663 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17664 switch (op & 0x7) { /* MSB-3..MSB-5 */
17665 case 0:
17666 /* POOL32A, POOL32B, POOL32I, POOL32C */
17667 case 4:
17668 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17669 case 5:
17670 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17671 case 6:
17672 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17673 case 7:
17674 /* LB32, LH32, LWC132, LDC132, LW32 */
17675 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3a4ef3b7 17676 gen_reserved_instruction(ctx);
3c824109
NF
17677 return 2;
17678 }
17679 break;
b231c103
YK
17680 case 1:
17681 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17682 case 2:
17683 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17684 case 3:
17685 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17686 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3a4ef3b7 17687 gen_reserved_instruction(ctx);
3c824109
NF
17688 return 2;
17689 }
17690 break;
3c824109
NF
17691 }
17692 }
b231c103 17693
3c824109
NF
17694 switch (op) {
17695 case POOL16A:
17696 {
17697 int rd = mmreg(uMIPS_RD(ctx->opcode));
17698 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17699 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17700 uint32_t opc = 0;
17701
17702 switch (ctx->opcode & 0x1) {
17703 case ADDU16:
17704 opc = OPC_ADDU;
17705 break;
17706 case SUBU16:
17707 opc = OPC_SUBU;
17708 break;
17709 }
2e211e0a 17710 if (ctx->insn_flags & ISA_MIPS_R6) {
7480515f
AM
17711 /*
17712 * In the Release 6, the register number location in
ed7ce6c0
YK
17713 * the instruction encoding has changed.
17714 */
17715 gen_arith(ctx, opc, rs1, rd, rs2);
17716 } else {
17717 gen_arith(ctx, opc, rd, rs1, rs2);
17718 }
3c824109
NF
17719 }
17720 break;
17721 case POOL16B:
17722 {
17723 int rd = mmreg(uMIPS_RD(ctx->opcode));
17724 int rs = mmreg(uMIPS_RS(ctx->opcode));
17725 int amount = (ctx->opcode >> 1) & 0x7;
17726 uint32_t opc = 0;
17727 amount = amount == 0 ? 8 : amount;
17728
17729 switch (ctx->opcode & 0x1) {
17730 case SLL16:
17731 opc = OPC_SLL;
17732 break;
17733 case SRL16:
17734 opc = OPC_SRL;
17735 break;
17736 }
17737
d75c135e 17738 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
17739 }
17740 break;
17741 case POOL16C:
2e211e0a 17742 if (ctx->insn_flags & ISA_MIPS_R6) {
ed7ce6c0
YK
17743 gen_pool16c_r6_insn(ctx);
17744 } else {
17745 gen_pool16c_insn(ctx);
17746 }
3c824109
NF
17747 break;
17748 case LWGP16:
17749 {
17750 int rd = mmreg(uMIPS_RD(ctx->opcode));
17751 int rb = 28; /* GP */
17752 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17753
d75c135e 17754 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17755 }
17756 break;
17757 case POOL16F:
2e211e0a 17758 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3c824109 17759 if (ctx->opcode & 1) {
3a4ef3b7 17760 gen_reserved_instruction(ctx);
3c824109
NF
17761 } else {
17762 /* MOVEP */
17763 int enc_dest = uMIPS_RD(ctx->opcode);
17764 int enc_rt = uMIPS_RS2(ctx->opcode);
17765 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 17766 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
17767 }
17768 break;
17769 case LBU16:
17770 {
17771 int rd = mmreg(uMIPS_RD(ctx->opcode));
17772 int rb = mmreg(uMIPS_RS(ctx->opcode));
17773 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17774 offset = (offset == 0xf ? -1 : offset);
17775
d75c135e 17776 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
17777 }
17778 break;
17779 case LHU16:
17780 {
17781 int rd = mmreg(uMIPS_RD(ctx->opcode));
17782 int rb = mmreg(uMIPS_RS(ctx->opcode));
17783 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17784
d75c135e 17785 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
17786 }
17787 break;
17788 case LWSP16:
17789 {
17790 int rd = (ctx->opcode >> 5) & 0x1f;
17791 int rb = 29; /* SP */
17792 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17793
d75c135e 17794 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17795 }
17796 break;
17797 case LW16:
17798 {
17799 int rd = mmreg(uMIPS_RD(ctx->opcode));
17800 int rb = mmreg(uMIPS_RS(ctx->opcode));
17801 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17802
d75c135e 17803 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17804 }
17805 break;
17806 case SB16:
17807 {
17808 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17809 int rb = mmreg(uMIPS_RS(ctx->opcode));
17810 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17811
5c13fdfd 17812 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
17813 }
17814 break;
17815 case SH16:
17816 {
17817 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17818 int rb = mmreg(uMIPS_RS(ctx->opcode));
17819 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17820
5c13fdfd 17821 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
17822 }
17823 break;
17824 case SWSP16:
17825 {
17826 int rd = (ctx->opcode >> 5) & 0x1f;
17827 int rb = 29; /* SP */
17828 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17829
5c13fdfd 17830 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17831 }
17832 break;
17833 case SW16:
17834 {
17835 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17836 int rb = mmreg(uMIPS_RS(ctx->opcode));
17837 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17838
5c13fdfd 17839 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17840 }
17841 break;
17842 case MOVE16:
17843 {
17844 int rd = uMIPS_RD5(ctx->opcode);
17845 int rs = uMIPS_RS5(ctx->opcode);
17846
7215d7e7 17847 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
17848 }
17849 break;
17850 case ANDI16:
d75c135e 17851 gen_andi16(ctx);
3c824109
NF
17852 break;
17853 case POOL16D:
17854 switch (ctx->opcode & 0x1) {
17855 case ADDIUS5:
d75c135e 17856 gen_addius5(ctx);
3c824109
NF
17857 break;
17858 case ADDIUSP:
d75c135e 17859 gen_addiusp(ctx);
3c824109
NF
17860 break;
17861 }
17862 break;
17863 case POOL16E:
17864 switch (ctx->opcode & 0x1) {
17865 case ADDIUR2:
d75c135e 17866 gen_addiur2(ctx);
3c824109
NF
17867 break;
17868 case ADDIUR1SP:
d75c135e 17869 gen_addiur1sp(ctx);
3c824109
NF
17870 break;
17871 }
17872 break;
65935f07 17873 case B16: /* BC16 */
3c824109 17874 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07 17875 sextract32(ctx->opcode, 0, 10) << 1,
2e211e0a 17876 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
3c824109 17877 break;
65935f07
YK
17878 case BNEZ16: /* BNEZC16 */
17879 case BEQZ16: /* BEQZC16 */
3c824109
NF
17880 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17881 mmreg(uMIPS_RD(ctx->opcode)),
65935f07 17882 0, sextract32(ctx->opcode, 0, 7) << 1,
2e211e0a 17883 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
65935f07 17884
3c824109
NF
17885 break;
17886 case LI16:
17887 {
17888 int reg = mmreg(uMIPS_RD(ctx->opcode));
17889 int imm = ZIMM(ctx->opcode, 0, 7);
17890
17891 imm = (imm == 0x7f ? -1 : imm);
17892 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17893 }
17894 break;
3c824109 17895 case RES_29:
3c824109 17896 case RES_31:
3c824109 17897 case RES_39:
3a4ef3b7 17898 gen_reserved_instruction(ctx);
3c824109
NF
17899 break;
17900 default:
f60eeb0c 17901 decode_micromips32_opc(env, ctx);
3c824109
NF
17902 return 4;
17903 }
17904
17905 return 2;
17906}
17907
261c95a0
YK
17908/*
17909 *
17910 * nanoMIPS opcodes
17911 *
17912 */
17913
17914/* MAJOR, P16, and P32 pools opcodes */
17915enum {
17916 NM_P_ADDIU = 0x00,
17917 NM_ADDIUPC = 0x01,
17918 NM_MOVE_BALC = 0x02,
17919 NM_P16_MV = 0x04,
17920 NM_LW16 = 0x05,
17921 NM_BC16 = 0x06,
17922 NM_P16_SR = 0x07,
17923
17924 NM_POOL32A = 0x08,
17925 NM_P_BAL = 0x0a,
17926 NM_P16_SHIFT = 0x0c,
17927 NM_LWSP16 = 0x0d,
17928 NM_BALC16 = 0x0e,
17929 NM_P16_4X4 = 0x0f,
17930
17931 NM_P_GP_W = 0x10,
17932 NM_P_GP_BH = 0x11,
17933 NM_P_J = 0x12,
17934 NM_P16C = 0x14,
17935 NM_LWGP16 = 0x15,
17936 NM_P16_LB = 0x17,
17937
17938 NM_P48I = 0x18,
17939 NM_P16_A1 = 0x1c,
17940 NM_LW4X4 = 0x1d,
17941 NM_P16_LH = 0x1f,
17942
17943 NM_P_U12 = 0x20,
17944 NM_P_LS_U12 = 0x21,
17945 NM_P_BR1 = 0x22,
17946 NM_P16_A2 = 0x24,
17947 NM_SW16 = 0x25,
17948 NM_BEQZC16 = 0x26,
17949
17950 NM_POOL32F = 0x28,
17951 NM_P_LS_S9 = 0x29,
17952 NM_P_BR2 = 0x2a,
17953
17954 NM_P16_ADDU = 0x2c,
17955 NM_SWSP16 = 0x2d,
17956 NM_BNEZC16 = 0x2e,
17957 NM_MOVEP = 0x2f,
17958
17959 NM_POOL32S = 0x30,
17960 NM_P_BRI = 0x32,
17961 NM_LI16 = 0x34,
17962 NM_SWGP16 = 0x35,
17963 NM_P16_BR = 0x36,
17964
17965 NM_P_LUI = 0x38,
17966 NM_ANDI16 = 0x3c,
17967 NM_SW4X4 = 0x3d,
17968 NM_MOVEPREV = 0x3f,
17969};
17970
17971/* POOL32A instruction pool */
17972enum {
17973 NM_POOL32A0 = 0x00,
17974 NM_SPECIAL2 = 0x01,
17975 NM_COP2_1 = 0x02,
17976 NM_UDI = 0x03,
17977 NM_POOL32A5 = 0x05,
17978 NM_POOL32A7 = 0x07,
17979};
17980
17981/* P.GP.W instruction pool */
17982enum {
17983 NM_ADDIUGP_W = 0x00,
17984 NM_LWGP = 0x02,
17985 NM_SWGP = 0x03,
17986};
17987
17988/* P48I instruction pool */
17989enum {
17990 NM_LI48 = 0x00,
17991 NM_ADDIU48 = 0x01,
17992 NM_ADDIUGP48 = 0x02,
17993 NM_ADDIUPC48 = 0x03,
17994 NM_LWPC48 = 0x0b,
17995 NM_SWPC48 = 0x0f,
17996};
17997
17998/* P.U12 instruction pool */
17999enum {
18000 NM_ORI = 0x00,
18001 NM_XORI = 0x01,
18002 NM_ANDI = 0x02,
18003 NM_P_SR = 0x03,
18004 NM_SLTI = 0x04,
18005 NM_SLTIU = 0x05,
18006 NM_SEQI = 0x06,
18007 NM_ADDIUNEG = 0x08,
18008 NM_P_SHIFT = 0x0c,
18009 NM_P_ROTX = 0x0d,
18010 NM_P_INS = 0x0e,
18011 NM_P_EXT = 0x0f,
18012};
18013
18014/* POOL32F instruction pool */
18015enum {
18016 NM_POOL32F_0 = 0x00,
18017 NM_POOL32F_3 = 0x03,
18018 NM_POOL32F_5 = 0x05,
18019};
18020
18021/* POOL32S instruction pool */
18022enum {
18023 NM_POOL32S_0 = 0x00,
18024 NM_POOL32S_4 = 0x04,
18025};
18026
18027/* P.LUI instruction pool */
18028enum {
18029 NM_LUI = 0x00,
18030 NM_ALUIPC = 0x01,
18031};
18032
18033/* P.GP.BH instruction pool */
18034enum {
18035 NM_LBGP = 0x00,
18036 NM_SBGP = 0x01,
18037 NM_LBUGP = 0x02,
18038 NM_ADDIUGP_B = 0x03,
18039 NM_P_GP_LH = 0x04,
18040 NM_P_GP_SH = 0x05,
18041 NM_P_GP_CP1 = 0x06,
18042};
18043
18044/* P.LS.U12 instruction pool */
18045enum {
18046 NM_LB = 0x00,
18047 NM_SB = 0x01,
18048 NM_LBU = 0x02,
18049 NM_P_PREFU12 = 0x03,
18050 NM_LH = 0x04,
18051 NM_SH = 0x05,
18052 NM_LHU = 0x06,
18053 NM_LWU = 0x07,
18054 NM_LW = 0x08,
18055 NM_SW = 0x09,
18056 NM_LWC1 = 0x0a,
18057 NM_SWC1 = 0x0b,
18058 NM_LDC1 = 0x0e,
18059 NM_SDC1 = 0x0f,
18060};
18061
18062/* P.LS.S9 instruction pool */
18063enum {
18064 NM_P_LS_S0 = 0x00,
18065 NM_P_LS_S1 = 0x01,
18066 NM_P_LS_E0 = 0x02,
18067 NM_P_LS_WM = 0x04,
18068 NM_P_LS_UAWM = 0x05,
18069};
18070
18071/* P.BAL instruction pool */
18072enum {
18073 NM_BC = 0x00,
18074 NM_BALC = 0x01,
18075};
18076
18077/* P.J instruction pool */
18078enum {
18079 NM_JALRC = 0x00,
18080 NM_JALRC_HB = 0x01,
18081 NM_P_BALRSC = 0x08,
18082};
18083
18084/* P.BR1 instruction pool */
18085enum {
18086 NM_BEQC = 0x00,
18087 NM_P_BR3A = 0x01,
18088 NM_BGEC = 0x02,
18089 NM_BGEUC = 0x03,
18090};
18091
18092/* P.BR2 instruction pool */
18093enum {
18094 NM_BNEC = 0x00,
18095 NM_BLTC = 0x02,
18096 NM_BLTUC = 0x03,
18097};
18098
18099/* P.BRI instruction pool */
18100enum {
18101 NM_BEQIC = 0x00,
18102 NM_BBEQZC = 0x01,
18103 NM_BGEIC = 0x02,
18104 NM_BGEIUC = 0x03,
18105 NM_BNEIC = 0x04,
18106 NM_BBNEZC = 0x05,
18107 NM_BLTIC = 0x06,
18108 NM_BLTIUC = 0x07,
18109};
18110
18111/* P16.SHIFT instruction pool */
18112enum {
18113 NM_SLL16 = 0x00,
18114 NM_SRL16 = 0x01,
18115};
18116
18117/* POOL16C instruction pool */
18118enum {
18119 NM_POOL16C_0 = 0x00,
18120 NM_LWXS16 = 0x01,
18121};
18122
18123/* P16.A1 instruction pool */
18124enum {
18125 NM_ADDIUR1SP = 0x01,
18126};
18127
18128/* P16.A2 instruction pool */
18129enum {
18130 NM_ADDIUR2 = 0x00,
18131 NM_P_ADDIURS5 = 0x01,
18132};
18133
18134/* P16.ADDU instruction pool */
18135enum {
18136 NM_ADDU16 = 0x00,
18137 NM_SUBU16 = 0x01,
18138};
18139
18140/* P16.SR instruction pool */
18141enum {
18142 NM_SAVE16 = 0x00,
18143 NM_RESTORE_JRC16 = 0x01,
18144};
18145
18146/* P16.4X4 instruction pool */
18147enum {
18148 NM_ADDU4X4 = 0x00,
18149 NM_MUL4X4 = 0x01,
18150};
18151
18152/* P16.LB instruction pool */
18153enum {
18154 NM_LB16 = 0x00,
18155 NM_SB16 = 0x01,
18156 NM_LBU16 = 0x02,
18157};
18158
18159/* P16.LH instruction pool */
18160enum {
18161 NM_LH16 = 0x00,
18162 NM_SH16 = 0x01,
18163 NM_LHU16 = 0x02,
18164};
18165
18166/* P.RI instruction pool */
18167enum {
18168 NM_SIGRIE = 0x00,
18169 NM_P_SYSCALL = 0x01,
18170 NM_BREAK = 0x02,
18171 NM_SDBBP = 0x03,
18172};
18173
18174/* POOL32A0 instruction pool */
18175enum {
18176 NM_P_TRAP = 0x00,
18177 NM_SEB = 0x01,
18178 NM_SLLV = 0x02,
18179 NM_MUL = 0x03,
18180 NM_MFC0 = 0x06,
18181 NM_MFHC0 = 0x07,
18182 NM_SEH = 0x09,
18183 NM_SRLV = 0x0a,
18184 NM_MUH = 0x0b,
18185 NM_MTC0 = 0x0e,
18186 NM_MTHC0 = 0x0f,
18187 NM_SRAV = 0x12,
18188 NM_MULU = 0x13,
18189 NM_ROTRV = 0x1a,
18190 NM_MUHU = 0x1b,
18191 NM_ADD = 0x22,
18192 NM_DIV = 0x23,
18193 NM_ADDU = 0x2a,
18194 NM_MOD = 0x2b,
18195 NM_SUB = 0x32,
18196 NM_DIVU = 0x33,
18197 NM_RDHWR = 0x38,
18198 NM_SUBU = 0x3a,
18199 NM_MODU = 0x3b,
18200 NM_P_CMOVE = 0x42,
18201 NM_FORK = 0x45,
18202 NM_MFTR = 0x46,
18203 NM_MFHTR = 0x47,
18204 NM_AND = 0x4a,
18205 NM_YIELD = 0x4d,
18206 NM_MTTR = 0x4e,
18207 NM_MTHTR = 0x4f,
18208 NM_OR = 0x52,
18209 NM_D_E_MT_VPE = 0x56,
18210 NM_NOR = 0x5a,
18211 NM_XOR = 0x62,
18212 NM_SLT = 0x6a,
18213 NM_P_SLTU = 0x72,
18214 NM_SOV = 0x7a,
18215};
18216
ba1e8117
AM
18217/* CRC32 instruction pool */
18218enum {
18219 NM_CRC32B = 0x00,
18220 NM_CRC32H = 0x01,
18221 NM_CRC32W = 0x02,
18222 NM_CRC32CB = 0x04,
18223 NM_CRC32CH = 0x05,
18224 NM_CRC32CW = 0x06,
18225};
18226
b3979b6f
SM
18227/* POOL32A5 instruction pool */
18228enum {
18229 NM_CMP_EQ_PH = 0x00,
18230 NM_CMP_LT_PH = 0x08,
18231 NM_CMP_LE_PH = 0x10,
18232 NM_CMPGU_EQ_QB = 0x18,
18233 NM_CMPGU_LT_QB = 0x20,
18234 NM_CMPGU_LE_QB = 0x28,
18235 NM_CMPGDU_EQ_QB = 0x30,
18236 NM_CMPGDU_LT_QB = 0x38,
18237 NM_CMPGDU_LE_QB = 0x40,
18238 NM_CMPU_EQ_QB = 0x48,
18239 NM_CMPU_LT_QB = 0x50,
18240 NM_CMPU_LE_QB = 0x58,
18241 NM_ADDQ_S_W = 0x60,
18242 NM_SUBQ_S_W = 0x68,
18243 NM_ADDSC = 0x70,
18244 NM_ADDWC = 0x78,
18245
18246 NM_ADDQ_S_PH = 0x01,
18247 NM_ADDQH_R_PH = 0x09,
18248 NM_ADDQH_R_W = 0x11,
18249 NM_ADDU_S_QB = 0x19,
18250 NM_ADDU_S_PH = 0x21,
18251 NM_ADDUH_R_QB = 0x29,
18252 NM_SHRAV_R_PH = 0x31,
18253 NM_SHRAV_R_QB = 0x39,
18254 NM_SUBQ_S_PH = 0x41,
18255 NM_SUBQH_R_PH = 0x49,
18256 NM_SUBQH_R_W = 0x51,
18257 NM_SUBU_S_QB = 0x59,
18258 NM_SUBU_S_PH = 0x61,
18259 NM_SUBUH_R_QB = 0x69,
18260 NM_SHLLV_S_PH = 0x71,
18261 NM_PRECR_SRA_R_PH_W = 0x79,
18262
18263 NM_MULEU_S_PH_QBL = 0x12,
18264 NM_MULEU_S_PH_QBR = 0x1a,
18265 NM_MULQ_RS_PH = 0x22,
18266 NM_MULQ_S_PH = 0x2a,
18267 NM_MULQ_RS_W = 0x32,
18268 NM_MULQ_S_W = 0x3a,
18269 NM_APPEND = 0x42,
18270 NM_MODSUB = 0x52,
18271 NM_SHRAV_R_W = 0x5a,
18272 NM_SHRLV_PH = 0x62,
18273 NM_SHRLV_QB = 0x6a,
18274 NM_SHLLV_QB = 0x72,
18275 NM_SHLLV_S_W = 0x7a,
18276
18277 NM_SHILO = 0x03,
18278
18279 NM_MULEQ_S_W_PHL = 0x04,
18280 NM_MULEQ_S_W_PHR = 0x0c,
18281
18282 NM_MUL_S_PH = 0x05,
18283 NM_PRECR_QB_PH = 0x0d,
18284 NM_PRECRQ_QB_PH = 0x15,
18285 NM_PRECRQ_PH_W = 0x1d,
18286 NM_PRECRQ_RS_PH_W = 0x25,
18287 NM_PRECRQU_S_QB_PH = 0x2d,
18288 NM_PACKRL_PH = 0x35,
18289 NM_PICK_QB = 0x3d,
18290 NM_PICK_PH = 0x45,
18291
18292 NM_SHRA_R_W = 0x5e,
18293 NM_SHRA_R_PH = 0x66,
18294 NM_SHLL_S_PH = 0x76,
18295 NM_SHLL_S_W = 0x7e,
18296
18297 NM_REPL_PH = 0x07
18298};
18299
261c95a0
YK
18300/* POOL32A7 instruction pool */
18301enum {
18302 NM_P_LSX = 0x00,
18303 NM_LSA = 0x01,
18304 NM_EXTW = 0x03,
18305 NM_POOL32AXF = 0x07,
18306};
18307
18308/* P.SR instruction pool */
18309enum {
18310 NM_PP_SR = 0x00,
18311 NM_P_SR_F = 0x01,
18312};
18313
18314/* P.SHIFT instruction pool */
18315enum {
18316 NM_P_SLL = 0x00,
18317 NM_SRL = 0x02,
18318 NM_SRA = 0x04,
18319 NM_ROTR = 0x06,
18320};
18321
18322/* P.ROTX instruction pool */
18323enum {
18324 NM_ROTX = 0x00,
18325};
18326
18327/* P.INS instruction pool */
18328enum {
18329 NM_INS = 0x00,
18330};
18331
18332/* P.EXT instruction pool */
18333enum {
18334 NM_EXT = 0x00,
18335};
18336
18337/* POOL32F_0 (fmt) instruction pool */
18338enum {
18339 NM_RINT_S = 0x04,
18340 NM_RINT_D = 0x44,
18341 NM_ADD_S = 0x06,
18342 NM_SELEQZ_S = 0x07,
18343 NM_SELEQZ_D = 0x47,
18344 NM_CLASS_S = 0x0c,
18345 NM_CLASS_D = 0x4c,
18346 NM_SUB_S = 0x0e,
18347 NM_SELNEZ_S = 0x0f,
18348 NM_SELNEZ_D = 0x4f,
18349 NM_MUL_S = 0x16,
18350 NM_SEL_S = 0x17,
18351 NM_SEL_D = 0x57,
18352 NM_DIV_S = 0x1e,
18353 NM_ADD_D = 0x26,
18354 NM_SUB_D = 0x2e,
18355 NM_MUL_D = 0x36,
18356 NM_MADDF_S = 0x37,
18357 NM_MADDF_D = 0x77,
18358 NM_DIV_D = 0x3e,
18359 NM_MSUBF_S = 0x3f,
18360 NM_MSUBF_D = 0x7f,
18361};
18362
18363/* POOL32F_3 instruction pool */
18364enum {
18365 NM_MIN_FMT = 0x00,
18366 NM_MAX_FMT = 0x01,
18367 NM_MINA_FMT = 0x04,
18368 NM_MAXA_FMT = 0x05,
18369 NM_POOL32FXF = 0x07,
18370};
18371
18372/* POOL32F_5 instruction pool */
18373enum {
18374 NM_CMP_CONDN_S = 0x00,
18375 NM_CMP_CONDN_D = 0x02,
18376};
18377
18378/* P.GP.LH instruction pool */
18379enum {
18380 NM_LHGP = 0x00,
18381 NM_LHUGP = 0x01,
18382};
18383
18384/* P.GP.SH instruction pool */
18385enum {
18386 NM_SHGP = 0x00,
18387};
18388
18389/* P.GP.CP1 instruction pool */
18390enum {
18391 NM_LWC1GP = 0x00,
18392 NM_SWC1GP = 0x01,
18393 NM_LDC1GP = 0x02,
18394 NM_SDC1GP = 0x03,
18395};
18396
18397/* P.LS.S0 instruction pool */
18398enum {
18399 NM_LBS9 = 0x00,
18400 NM_LHS9 = 0x04,
18401 NM_LWS9 = 0x08,
18402 NM_LDS9 = 0x0c,
18403
18404 NM_SBS9 = 0x01,
18405 NM_SHS9 = 0x05,
18406 NM_SWS9 = 0x09,
18407 NM_SDS9 = 0x0d,
18408
18409 NM_LBUS9 = 0x02,
18410 NM_LHUS9 = 0x06,
18411 NM_LWC1S9 = 0x0a,
18412 NM_LDC1S9 = 0x0e,
18413
18414 NM_P_PREFS9 = 0x03,
18415 NM_LWUS9 = 0x07,
18416 NM_SWC1S9 = 0x0b,
18417 NM_SDC1S9 = 0x0f,
18418};
18419
18420/* P.LS.S1 instruction pool */
18421enum {
18422 NM_ASET_ACLR = 0x02,
18423 NM_UALH = 0x04,
18424 NM_UASH = 0x05,
18425 NM_CACHE = 0x07,
18426 NM_P_LL = 0x0a,
18427 NM_P_SC = 0x0b,
18428};
18429
0d30b3bb
DN
18430/* P.LS.E0 instruction pool */
18431enum {
18432 NM_LBE = 0x00,
18433 NM_SBE = 0x01,
18434 NM_LBUE = 0x02,
18435 NM_P_PREFE = 0x03,
18436 NM_LHE = 0x04,
18437 NM_SHE = 0x05,
18438 NM_LHUE = 0x06,
18439 NM_CACHEE = 0x07,
18440 NM_LWE = 0x08,
18441 NM_SWE = 0x09,
18442 NM_P_LLE = 0x0a,
18443 NM_P_SCE = 0x0b,
18444};
18445
18446/* P.PREFE instruction pool */
18447enum {
18448 NM_SYNCIE = 0x00,
18449 NM_PREFE = 0x01,
18450};
18451
18452/* P.LLE instruction pool */
18453enum {
18454 NM_LLE = 0x00,
18455 NM_LLWPE = 0x01,
18456};
18457
18458/* P.SCE instruction pool */
18459enum {
18460 NM_SCE = 0x00,
18461 NM_SCWPE = 0x01,
18462};
18463
261c95a0
YK
18464/* P.LS.WM instruction pool */
18465enum {
18466 NM_LWM = 0x00,
18467 NM_SWM = 0x01,
18468};
18469
18470/* P.LS.UAWM instruction pool */
18471enum {
18472 NM_UALWM = 0x00,
18473 NM_UASWM = 0x01,
18474};
18475
18476/* P.BR3A instruction pool */
18477enum {
18478 NM_BC1EQZC = 0x00,
18479 NM_BC1NEZC = 0x01,
18480 NM_BC2EQZC = 0x02,
18481 NM_BC2NEZC = 0x03,
18482 NM_BPOSGE32C = 0x04,
18483};
18484
18485/* P16.RI instruction pool */
18486enum {
18487 NM_P16_SYSCALL = 0x01,
18488 NM_BREAK16 = 0x02,
18489 NM_SDBBP16 = 0x03,
18490};
18491
18492/* POOL16C_0 instruction pool */
18493enum {
18494 NM_POOL16C_00 = 0x00,
18495};
18496
18497/* P16.JRC instruction pool */
18498enum {
18499 NM_JRC = 0x00,
18500 NM_JALRC16 = 0x01,
18501};
18502
18503/* P.SYSCALL instruction pool */
18504enum {
18505 NM_SYSCALL = 0x00,
18506 NM_HYPCALL = 0x01,
18507};
18508
18509/* P.TRAP instruction pool */
18510enum {
18511 NM_TEQ = 0x00,
18512 NM_TNE = 0x01,
18513};
18514
18515/* P.CMOVE instruction pool */
18516enum {
18517 NM_MOVZ = 0x00,
18518 NM_MOVN = 0x01,
18519};
18520
18521/* POOL32Axf instruction pool */
18522enum {
b3979b6f
SM
18523 NM_POOL32AXF_1 = 0x01,
18524 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
18525 NM_POOL32AXF_4 = 0x04,
18526 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
18527 NM_POOL32AXF_7 = 0x07,
18528};
18529
18530/* POOL32Axf_1 instruction pool */
18531enum {
18532 NM_POOL32AXF_1_0 = 0x00,
18533 NM_POOL32AXF_1_1 = 0x01,
18534 NM_POOL32AXF_1_3 = 0x03,
18535 NM_POOL32AXF_1_4 = 0x04,
18536 NM_POOL32AXF_1_5 = 0x05,
18537 NM_POOL32AXF_1_7 = 0x07,
18538};
18539
18540/* POOL32Axf_2 instruction pool */
18541enum {
18542 NM_POOL32AXF_2_0_7 = 0x00,
18543 NM_POOL32AXF_2_8_15 = 0x01,
18544 NM_POOL32AXF_2_16_23 = 0x02,
18545 NM_POOL32AXF_2_24_31 = 0x03,
18546};
18547
18548/* POOL32Axf_7 instruction pool */
18549enum {
18550 NM_SHRA_R_QB = 0x0,
18551 NM_SHRL_PH = 0x1,
18552 NM_REPL_QB = 0x2,
18553};
18554
18555/* POOL32Axf_1_0 instruction pool */
18556enum {
18557 NM_MFHI = 0x0,
18558 NM_MFLO = 0x1,
18559 NM_MTHI = 0x2,
18560 NM_MTLO = 0x3,
18561};
18562
18563/* POOL32Axf_1_1 instruction pool */
18564enum {
18565 NM_MTHLIP = 0x0,
18566 NM_SHILOV = 0x1,
18567};
18568
18569/* POOL32Axf_1_3 instruction pool */
18570enum {
18571 NM_RDDSP = 0x0,
18572 NM_WRDSP = 0x1,
18573 NM_EXTP = 0x2,
18574 NM_EXTPDP = 0x3,
18575};
18576
18577/* POOL32Axf_1_4 instruction pool */
18578enum {
18579 NM_SHLL_QB = 0x0,
18580 NM_SHRL_QB = 0x1,
18581};
18582
18583/* POOL32Axf_1_5 instruction pool */
18584enum {
18585 NM_MAQ_S_W_PHR = 0x0,
18586 NM_MAQ_S_W_PHL = 0x1,
18587 NM_MAQ_SA_W_PHR = 0x2,
18588 NM_MAQ_SA_W_PHL = 0x3,
18589};
18590
18591/* POOL32Axf_1_7 instruction pool */
18592enum {
18593 NM_EXTR_W = 0x0,
18594 NM_EXTR_R_W = 0x1,
18595 NM_EXTR_RS_W = 0x2,
18596 NM_EXTR_S_H = 0x3,
18597};
18598
18599/* POOL32Axf_2_0_7 instruction pool */
18600enum {
18601 NM_DPA_W_PH = 0x0,
18602 NM_DPAQ_S_W_PH = 0x1,
18603 NM_DPS_W_PH = 0x2,
18604 NM_DPSQ_S_W_PH = 0x3,
18605 NM_BALIGN = 0x4,
18606 NM_MADD = 0x5,
18607 NM_MULT = 0x6,
18608 NM_EXTRV_W = 0x7,
18609};
18610
18611/* POOL32Axf_2_8_15 instruction pool */
18612enum {
18613 NM_DPAX_W_PH = 0x0,
18614 NM_DPAQ_SA_L_W = 0x1,
18615 NM_DPSX_W_PH = 0x2,
18616 NM_DPSQ_SA_L_W = 0x3,
18617 NM_MADDU = 0x5,
18618 NM_MULTU = 0x6,
18619 NM_EXTRV_R_W = 0x7,
18620};
18621
18622/* POOL32Axf_2_16_23 instruction pool */
18623enum {
18624 NM_DPAU_H_QBL = 0x0,
18625 NM_DPAQX_S_W_PH = 0x1,
18626 NM_DPSU_H_QBL = 0x2,
18627 NM_DPSQX_S_W_PH = 0x3,
18628 NM_EXTPV = 0x4,
18629 NM_MSUB = 0x5,
18630 NM_MULSA_W_PH = 0x6,
18631 NM_EXTRV_RS_W = 0x7,
18632};
18633
18634/* POOL32Axf_2_24_31 instruction pool */
18635enum {
18636 NM_DPAU_H_QBR = 0x0,
18637 NM_DPAQX_SA_W_PH = 0x1,
18638 NM_DPSU_H_QBR = 0x2,
18639 NM_DPSQX_SA_W_PH = 0x3,
18640 NM_EXTPDPV = 0x4,
18641 NM_MSUBU = 0x5,
18642 NM_MULSAQ_S_W_PH = 0x6,
18643 NM_EXTRV_S_H = 0x7,
261c95a0
YK
18644};
18645
18646/* POOL32Axf_{4, 5} instruction pool */
18647enum {
18648 NM_CLO = 0x25,
18649 NM_CLZ = 0x2d,
18650
18651 NM_TLBP = 0x01,
18652 NM_TLBR = 0x09,
18653 NM_TLBWI = 0x11,
18654 NM_TLBWR = 0x19,
18655 NM_TLBINV = 0x03,
18656 NM_TLBINVF = 0x0b,
18657 NM_DI = 0x23,
18658 NM_EI = 0x2b,
18659 NM_RDPGPR = 0x70,
18660 NM_WRPGPR = 0x78,
18661 NM_WAIT = 0x61,
18662 NM_DERET = 0x71,
18663 NM_ERETX = 0x79,
b3979b6f
SM
18664
18665 /* nanoMIPS DSP instructions */
18666 NM_ABSQ_S_QB = 0x00,
18667 NM_ABSQ_S_PH = 0x08,
18668 NM_ABSQ_S_W = 0x10,
18669 NM_PRECEQ_W_PHL = 0x28,
18670 NM_PRECEQ_W_PHR = 0x30,
18671 NM_PRECEQU_PH_QBL = 0x38,
18672 NM_PRECEQU_PH_QBR = 0x48,
18673 NM_PRECEU_PH_QBL = 0x58,
18674 NM_PRECEU_PH_QBR = 0x68,
18675 NM_PRECEQU_PH_QBLA = 0x39,
18676 NM_PRECEQU_PH_QBRA = 0x49,
18677 NM_PRECEU_PH_QBLA = 0x59,
18678 NM_PRECEU_PH_QBRA = 0x69,
18679 NM_REPLV_PH = 0x01,
18680 NM_REPLV_QB = 0x09,
18681 NM_BITREV = 0x18,
18682 NM_INSV = 0x20,
18683 NM_RADDU_W_QB = 0x78,
18684
18685 NM_BITSWAP = 0x05,
18686 NM_WSBH = 0x3d,
261c95a0
YK
18687};
18688
18689/* PP.SR instruction pool */
18690enum {
18691 NM_SAVE = 0x00,
18692 NM_RESTORE = 0x02,
18693 NM_RESTORE_JRC = 0x03,
18694};
18695
18696/* P.SR.F instruction pool */
18697enum {
18698 NM_SAVEF = 0x00,
18699 NM_RESTOREF = 0x01,
18700};
18701
18702/* P16.SYSCALL instruction pool */
18703enum {
18704 NM_SYSCALL16 = 0x00,
18705 NM_HYPCALL16 = 0x01,
18706};
18707
18708/* POOL16C_00 instruction pool */
18709enum {
18710 NM_NOT16 = 0x00,
18711 NM_XOR16 = 0x01,
18712 NM_AND16 = 0x02,
18713 NM_OR16 = 0x03,
18714};
18715
18716/* PP.LSX and PP.LSXS instruction pool */
18717enum {
18718 NM_LBX = 0x00,
18719 NM_LHX = 0x04,
18720 NM_LWX = 0x08,
18721 NM_LDX = 0x0c,
18722
18723 NM_SBX = 0x01,
18724 NM_SHX = 0x05,
18725 NM_SWX = 0x09,
18726 NM_SDX = 0x0d,
18727
18728 NM_LBUX = 0x02,
18729 NM_LHUX = 0x06,
18730 NM_LWC1X = 0x0a,
18731 NM_LDC1X = 0x0e,
18732
18733 NM_LWUX = 0x07,
18734 NM_SWC1X = 0x0b,
18735 NM_SDC1X = 0x0f,
18736
18737 NM_LHXS = 0x04,
18738 NM_LWXS = 0x08,
18739 NM_LDXS = 0x0c,
18740
18741 NM_SHXS = 0x05,
18742 NM_SWXS = 0x09,
18743 NM_SDXS = 0x0d,
18744
18745 NM_LHUXS = 0x06,
18746 NM_LWC1XS = 0x0a,
18747 NM_LDC1XS = 0x0e,
18748
18749 NM_LWUXS = 0x07,
18750 NM_SWC1XS = 0x0b,
18751 NM_SDC1XS = 0x0f,
18752};
18753
18754/* ERETx instruction pool */
18755enum {
18756 NM_ERET = 0x00,
18757 NM_ERETNC = 0x01,
18758};
18759
18760/* POOL32FxF_{0, 1} insturction pool */
18761enum {
18762 NM_CFC1 = 0x40,
18763 NM_CTC1 = 0x60,
18764 NM_MFC1 = 0x80,
18765 NM_MTC1 = 0xa0,
18766 NM_MFHC1 = 0xc0,
18767 NM_MTHC1 = 0xe0,
18768
18769 NM_CVT_S_PL = 0x84,
18770 NM_CVT_S_PU = 0xa4,
18771
18772 NM_CVT_L_S = 0x004,
18773 NM_CVT_L_D = 0x104,
18774 NM_CVT_W_S = 0x024,
18775 NM_CVT_W_D = 0x124,
18776
18777 NM_RSQRT_S = 0x008,
18778 NM_RSQRT_D = 0x108,
18779
18780 NM_SQRT_S = 0x028,
18781 NM_SQRT_D = 0x128,
18782
18783 NM_RECIP_S = 0x048,
18784 NM_RECIP_D = 0x148,
18785
18786 NM_FLOOR_L_S = 0x00c,
18787 NM_FLOOR_L_D = 0x10c,
18788
18789 NM_FLOOR_W_S = 0x02c,
18790 NM_FLOOR_W_D = 0x12c,
18791
18792 NM_CEIL_L_S = 0x04c,
18793 NM_CEIL_L_D = 0x14c,
18794 NM_CEIL_W_S = 0x06c,
18795 NM_CEIL_W_D = 0x16c,
18796 NM_TRUNC_L_S = 0x08c,
18797 NM_TRUNC_L_D = 0x18c,
18798 NM_TRUNC_W_S = 0x0ac,
18799 NM_TRUNC_W_D = 0x1ac,
18800 NM_ROUND_L_S = 0x0cc,
18801 NM_ROUND_L_D = 0x1cc,
18802 NM_ROUND_W_S = 0x0ec,
18803 NM_ROUND_W_D = 0x1ec,
18804
18805 NM_MOV_S = 0x01,
18806 NM_MOV_D = 0x81,
18807 NM_ABS_S = 0x0d,
18808 NM_ABS_D = 0x8d,
18809 NM_NEG_S = 0x2d,
18810 NM_NEG_D = 0xad,
18811 NM_CVT_D_S = 0x04d,
18812 NM_CVT_D_W = 0x0cd,
18813 NM_CVT_D_L = 0x14d,
18814 NM_CVT_S_D = 0x06d,
18815 NM_CVT_S_W = 0x0ed,
18816 NM_CVT_S_L = 0x16d,
18817};
18818
18819/* P.LL instruction pool */
18820enum {
18821 NM_LL = 0x00,
18822 NM_LLWP = 0x01,
18823};
18824
18825/* P.SC instruction pool */
18826enum {
18827 NM_SC = 0x00,
18828 NM_SCWP = 0x01,
18829};
18830
18831/* P.DVP instruction pool */
18832enum {
18833 NM_DVP = 0x00,
18834 NM_EVP = 0x01,
18835};
18836
c533c0f4
AM
18837
18838/*
18839 *
18840 * nanoMIPS decoding engine
18841 *
18842 */
18843
6bfa9f4c
AM
18844
18845/* extraction utilities */
18846
99e49abf
AM
18847#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18848#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18849#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
6bfa9f4c
AM
18850#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18851#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18852
ea4ca3c2
YK
18853/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18854static inline int decode_gpr_gpr3(int r)
18855{
18856 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18857
18858 return map[r & 0x7];
18859}
18860
8bdb7029
YK
18861/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18862static inline int decode_gpr_gpr3_src_store(int r)
18863{
18864 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18865
18866 return map[r & 0x7];
18867}
18868
ea4ca3c2
YK
18869/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18870static inline int decode_gpr_gpr4(int r)
18871{
18872 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18873 16, 17, 18, 19, 20, 21, 22, 23 };
18874
18875 return map[r & 0xf];
18876}
18877
8bdb7029
YK
18878/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18879static inline int decode_gpr_gpr4_zero(int r)
18880{
18881 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18882 16, 17, 18, 19, 20, 21, 22, 23 };
18883
18884 return map[r & 0xf];
18885}
18886
6bfa9f4c 18887
bf0718c5
SM
18888static void gen_adjust_sp(DisasContext *ctx, int u)
18889{
18890 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18891}
18892
18893static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18894 uint8_t gp, uint16_t u)
18895{
18896 int counter = 0;
18897 TCGv va = tcg_temp_new();
18898 TCGv t0 = tcg_temp_new();
18899
18900 while (counter != count) {
18901 bool use_gp = gp && (counter == count - 1);
18902 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18903 int this_offset = -((counter + 1) << 2);
18904 gen_base_offset_addr(ctx, va, 29, this_offset);
18905 gen_load_gpr(t0, this_rt);
18906 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18907 (MO_TEUL | ctx->default_tcg_memop_mask));
18908 counter++;
18909 }
18910
18911 /* adjust stack pointer */
18912 gen_adjust_sp(ctx, -u);
18913
18914 tcg_temp_free(t0);
18915 tcg_temp_free(va);
18916}
18917
18918static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18919 uint8_t gp, uint16_t u)
18920{
18921 int counter = 0;
18922 TCGv va = tcg_temp_new();
18923 TCGv t0 = tcg_temp_new();
18924
18925 while (counter != count) {
18926 bool use_gp = gp && (counter == count - 1);
18927 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18928 int this_offset = u - ((counter + 1) << 2);
18929 gen_base_offset_addr(ctx, va, 29, this_offset);
18930 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18931 ctx->default_tcg_memop_mask);
18932 tcg_gen_ext32s_tl(t0, t0);
18933 gen_store_gpr(t0, this_rt);
18934 counter++;
18935 }
18936
18937 /* adjust stack pointer */
18938 gen_adjust_sp(ctx, u);
18939
18940 tcg_temp_free(t0);
18941 tcg_temp_free(va);
18942}
18943
80845edf
YK
18944static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18945{
99e49abf
AM
18946 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18947 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
80845edf
YK
18948
18949 switch (extract32(ctx->opcode, 2, 2)) {
18950 case NM_NOT16:
18951 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18952 break;
18953 case NM_AND16:
18954 gen_logic(ctx, OPC_AND, rt, rt, rs);
18955 break;
18956 case NM_XOR16:
18957 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18958 break;
18959 case NM_OR16:
18960 gen_logic(ctx, OPC_OR, rt, rt, rs);
18961 break;
18962 }
18963}
18964
0a1a6ed7 18965static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
18966{
18967 int rt = extract32(ctx->opcode, 21, 5);
18968 int rs = extract32(ctx->opcode, 16, 5);
18969 int rd = extract32(ctx->opcode, 11, 5);
18970
18971 switch (extract32(ctx->opcode, 3, 7)) {
18972 case NM_P_TRAP:
18973 switch (extract32(ctx->opcode, 10, 1)) {
18974 case NM_TEQ:
fb32f8c8 18975 check_nms(ctx);
e0cf0e65
YK
18976 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18977 break;
18978 case NM_TNE:
fb32f8c8 18979 check_nms(ctx);
e0cf0e65
YK
18980 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18981 break;
18982 }
18983 break;
18984 case NM_RDHWR:
fb32f8c8 18985 check_nms(ctx);
e0cf0e65
YK
18986 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18987 break;
18988 case NM_SEB:
fb32f8c8 18989 check_nms(ctx);
e0cf0e65
YK
18990 gen_bshfl(ctx, OPC_SEB, rs, rt);
18991 break;
18992 case NM_SEH:
18993 gen_bshfl(ctx, OPC_SEH, rs, rt);
18994 break;
18995 case NM_SLLV:
18996 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18997 break;
18998 case NM_SRLV:
18999 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
19000 break;
19001 case NM_SRAV:
19002 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
19003 break;
19004 case NM_ROTRV:
19005 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
19006 break;
19007 case NM_ADD:
19008 gen_arith(ctx, OPC_ADD, rd, rs, rt);
19009 break;
19010 case NM_ADDU:
19011 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
19012 break;
19013 case NM_SUB:
fb32f8c8 19014 check_nms(ctx);
e0cf0e65
YK
19015 gen_arith(ctx, OPC_SUB, rd, rs, rt);
19016 break;
19017 case NM_SUBU:
19018 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
19019 break;
19020 case NM_P_CMOVE:
19021 switch (extract32(ctx->opcode, 10, 1)) {
19022 case NM_MOVZ:
19023 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
19024 break;
19025 case NM_MOVN:
19026 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
19027 break;
19028 }
19029 break;
19030 case NM_AND:
19031 gen_logic(ctx, OPC_AND, rd, rs, rt);
19032 break;
19033 case NM_OR:
19034 gen_logic(ctx, OPC_OR, rd, rs, rt);
19035 break;
19036 case NM_NOR:
19037 gen_logic(ctx, OPC_NOR, rd, rs, rt);
19038 break;
19039 case NM_XOR:
19040 gen_logic(ctx, OPC_XOR, rd, rs, rt);
19041 break;
19042 case NM_SLT:
19043 gen_slt(ctx, OPC_SLT, rd, rs, rt);
19044 break;
19045 case NM_P_SLTU:
19046 if (rd == 0) {
19047 /* P_DVP */
19048#ifndef CONFIG_USER_ONLY
19049 TCGv t0 = tcg_temp_new();
19050 switch (extract32(ctx->opcode, 10, 1)) {
19051 case NM_DVP:
19052 if (ctx->vp) {
19053 check_cp0_enabled(ctx);
19054 gen_helper_dvp(t0, cpu_env);
19055 gen_store_gpr(t0, rt);
19056 }
19057 break;
19058 case NM_EVP:
19059 if (ctx->vp) {
19060 check_cp0_enabled(ctx);
19061 gen_helper_evp(t0, cpu_env);
19062 gen_store_gpr(t0, rt);
19063 }
19064 break;
19065 }
19066 tcg_temp_free(t0);
19067#endif
19068 } else {
19069 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
19070 }
19071 break;
19072 case NM_SOV:
19073 {
19074 TCGv t0 = tcg_temp_new();
19075 TCGv t1 = tcg_temp_new();
19076 TCGv t2 = tcg_temp_new();
19077
19078 gen_load_gpr(t1, rs);
19079 gen_load_gpr(t2, rt);
19080 tcg_gen_add_tl(t0, t1, t2);
19081 tcg_gen_ext32s_tl(t0, t0);
19082 tcg_gen_xor_tl(t1, t1, t2);
19083 tcg_gen_xor_tl(t2, t0, t2);
19084 tcg_gen_andc_tl(t1, t2, t1);
19085
19086 /* operands of same sign, result different sign */
19087 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
19088 gen_store_gpr(t0, rd);
19089
19090 tcg_temp_free(t0);
19091 tcg_temp_free(t1);
19092 tcg_temp_free(t2);
19093 }
19094 break;
19095 case NM_MUL:
19096 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
19097 break;
19098 case NM_MUH:
19099 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
19100 break;
19101 case NM_MULU:
19102 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
19103 break;
19104 case NM_MUHU:
19105 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
19106 break;
19107 case NM_DIV:
19108 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
19109 break;
19110 case NM_MOD:
19111 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
19112 break;
19113 case NM_DIVU:
19114 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
19115 break;
19116 case NM_MODU:
19117 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
19118 break;
19119#ifndef CONFIG_USER_ONLY
19120 case NM_MFC0:
19121 check_cp0_enabled(ctx);
19122 if (rt == 0) {
19123 /* Treat as NOP. */
19124 break;
19125 }
19126 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
19127 break;
19128 case NM_MTC0:
19129 check_cp0_enabled(ctx);
19130 {
19131 TCGv t0 = tcg_temp_new();
19132
19133 gen_load_gpr(t0, rt);
19134 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
19135 tcg_temp_free(t0);
19136 }
19137 break;
0a1a6ed7
SM
19138 case NM_D_E_MT_VPE:
19139 {
19140 uint8_t sc = extract32(ctx->opcode, 10, 1);
19141 TCGv t0 = tcg_temp_new();
19142
19143 switch (sc) {
19144 case 0:
19145 if (rs == 1) {
19146 /* DMT */
19147 check_cp0_mt(ctx);
19148 gen_helper_dmt(t0);
19149 gen_store_gpr(t0, rt);
19150 } else if (rs == 0) {
19151 /* DVPE */
19152 check_cp0_mt(ctx);
19153 gen_helper_dvpe(t0, cpu_env);
19154 gen_store_gpr(t0, rt);
19155 } else {
3a4ef3b7 19156 gen_reserved_instruction(ctx);
0a1a6ed7
SM
19157 }
19158 break;
19159 case 1:
19160 if (rs == 1) {
19161 /* EMT */
19162 check_cp0_mt(ctx);
19163 gen_helper_emt(t0);
19164 gen_store_gpr(t0, rt);
19165 } else if (rs == 0) {
19166 /* EVPE */
19167 check_cp0_mt(ctx);
19168 gen_helper_evpe(t0, cpu_env);
19169 gen_store_gpr(t0, rt);
19170 } else {
3a4ef3b7 19171 gen_reserved_instruction(ctx);
0a1a6ed7
SM
19172 }
19173 break;
19174 }
19175
19176 tcg_temp_free(t0);
19177 }
19178 break;
19179 case NM_FORK:
19180 check_mt(ctx);
19181 {
19182 TCGv t0 = tcg_temp_new();
19183 TCGv t1 = tcg_temp_new();
19184
19185 gen_load_gpr(t0, rt);
19186 gen_load_gpr(t1, rs);
19187 gen_helper_fork(t0, t1);
19188 tcg_temp_free(t0);
19189 tcg_temp_free(t1);
19190 }
19191 break;
19192 case NM_MFTR:
19193 case NM_MFHTR:
19194 check_cp0_enabled(ctx);
19195 if (rd == 0) {
19196 /* Treat as NOP. */
19197 return;
19198 }
19199 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19200 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19201 break;
19202 case NM_MTTR:
19203 case NM_MTHTR:
19204 check_cp0_enabled(ctx);
19205 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19206 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19207 break;
19208 case NM_YIELD:
19209 check_mt(ctx);
19210 {
19211 TCGv t0 = tcg_temp_new();
19212
19213 gen_load_gpr(t0, rs);
19214 gen_helper_yield(t0, cpu_env, t0);
19215 gen_store_gpr(t0, rt);
19216 tcg_temp_free(t0);
19217 }
19218 break;
e0cf0e65
YK
19219#endif
19220 default:
3a4ef3b7 19221 gen_reserved_instruction(ctx);
e0cf0e65
YK
19222 break;
19223 }
19224}
19225
2ed42efa
SM
19226/* dsp */
19227static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
19228 int ret, int v1, int v2)
19229{
19230 TCGv_i32 t0;
19231 TCGv v0_t;
19232 TCGv v1_t;
19233
19234 t0 = tcg_temp_new_i32();
19235
19236 v0_t = tcg_temp_new();
19237 v1_t = tcg_temp_new();
19238
19239 tcg_gen_movi_i32(t0, v2 >> 3);
19240
19241 gen_load_gpr(v0_t, ret);
19242 gen_load_gpr(v1_t, v1);
19243
19244 switch (opc) {
19245 case NM_MAQ_S_W_PHR:
19246 check_dsp(ctx);
19247 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
19248 break;
19249 case NM_MAQ_S_W_PHL:
19250 check_dsp(ctx);
19251 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
19252 break;
19253 case NM_MAQ_SA_W_PHR:
19254 check_dsp(ctx);
19255 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19256 break;
19257 case NM_MAQ_SA_W_PHL:
19258 check_dsp(ctx);
19259 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19260 break;
19261 default:
3a4ef3b7 19262 gen_reserved_instruction(ctx);
2ed42efa
SM
19263 break;
19264 }
19265
19266 tcg_temp_free_i32(t0);
19267
19268 tcg_temp_free(v0_t);
19269 tcg_temp_free(v1_t);
19270}
19271
19272
19273static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19274 int ret, int v1, int v2)
19275{
19276 int16_t imm;
19277 TCGv t0 = tcg_temp_new();
19278 TCGv t1 = tcg_temp_new();
19279 TCGv v0_t = tcg_temp_new();
19280
19281 gen_load_gpr(v0_t, v1);
19282
19283 switch (opc) {
19284 case NM_POOL32AXF_1_0:
19285 check_dsp(ctx);
19286 switch (extract32(ctx->opcode, 12, 2)) {
19287 case NM_MFHI:
19288 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19289 break;
19290 case NM_MFLO:
19291 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19292 break;
19293 case NM_MTHI:
19294 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19295 break;
19296 case NM_MTLO:
19297 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19298 break;
19299 }
19300 break;
19301 case NM_POOL32AXF_1_1:
19302 check_dsp(ctx);
19303 switch (extract32(ctx->opcode, 12, 2)) {
19304 case NM_MTHLIP:
19305 tcg_gen_movi_tl(t0, v2);
19306 gen_helper_mthlip(t0, v0_t, cpu_env);
19307 break;
19308 case NM_SHILOV:
19309 tcg_gen_movi_tl(t0, v2 >> 3);
19310 gen_helper_shilo(t0, v0_t, cpu_env);
19311 break;
19312 default:
3a4ef3b7 19313 gen_reserved_instruction(ctx);
2ed42efa
SM
19314 break;
19315 }
19316 break;
19317 case NM_POOL32AXF_1_3:
19318 check_dsp(ctx);
19319 imm = extract32(ctx->opcode, 14, 7);
19320 switch (extract32(ctx->opcode, 12, 2)) {
19321 case NM_RDDSP:
19322 tcg_gen_movi_tl(t0, imm);
19323 gen_helper_rddsp(t0, t0, cpu_env);
19324 gen_store_gpr(t0, ret);
19325 break;
19326 case NM_WRDSP:
19327 gen_load_gpr(t0, ret);
19328 tcg_gen_movi_tl(t1, imm);
19329 gen_helper_wrdsp(t0, t1, cpu_env);
19330 break;
19331 case NM_EXTP:
19332 tcg_gen_movi_tl(t0, v2 >> 3);
19333 tcg_gen_movi_tl(t1, v1);
19334 gen_helper_extp(t0, t0, t1, cpu_env);
19335 gen_store_gpr(t0, ret);
19336 break;
19337 case NM_EXTPDP:
19338 tcg_gen_movi_tl(t0, v2 >> 3);
19339 tcg_gen_movi_tl(t1, v1);
19340 gen_helper_extpdp(t0, t0, t1, cpu_env);
19341 gen_store_gpr(t0, ret);
19342 break;
19343 }
19344 break;
19345 case NM_POOL32AXF_1_4:
19346 check_dsp(ctx);
19347 tcg_gen_movi_tl(t0, v2 >> 2);
19348 switch (extract32(ctx->opcode, 12, 1)) {
19349 case NM_SHLL_QB:
19350 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19351 gen_store_gpr(t0, ret);
19352 break;
19353 case NM_SHRL_QB:
19354 gen_helper_shrl_qb(t0, t0, v0_t);
19355 gen_store_gpr(t0, ret);
19356 break;
19357 }
19358 break;
19359 case NM_POOL32AXF_1_5:
19360 opc = extract32(ctx->opcode, 12, 2);
19361 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19362 break;
19363 case NM_POOL32AXF_1_7:
19364 check_dsp(ctx);
19365 tcg_gen_movi_tl(t0, v2 >> 3);
19366 tcg_gen_movi_tl(t1, v1);
19367 switch (extract32(ctx->opcode, 12, 2)) {
19368 case NM_EXTR_W:
19369 gen_helper_extr_w(t0, t0, t1, cpu_env);
19370 gen_store_gpr(t0, ret);
19371 break;
19372 case NM_EXTR_R_W:
19373 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19374 gen_store_gpr(t0, ret);
19375 break;
19376 case NM_EXTR_RS_W:
19377 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19378 gen_store_gpr(t0, ret);
19379 break;
19380 case NM_EXTR_S_H:
19381 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19382 gen_store_gpr(t0, ret);
19383 break;
19384 }
19385 break;
19386 default:
3a4ef3b7 19387 gen_reserved_instruction(ctx);
2ed42efa
SM
19388 break;
19389 }
19390
19391 tcg_temp_free(t0);
19392 tcg_temp_free(t1);
19393 tcg_temp_free(v0_t);
19394}
19395
8b3698b2
SM
19396static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19397 TCGv v0, TCGv v1, int rd)
19398{
19399 TCGv_i32 t0;
19400
19401 t0 = tcg_temp_new_i32();
19402
19403 tcg_gen_movi_i32(t0, rd >> 3);
19404
19405 switch (opc) {
19406 case NM_POOL32AXF_2_0_7:
19407 switch (extract32(ctx->opcode, 9, 3)) {
19408 case NM_DPA_W_PH:
908f6be1 19409 check_dsp_r2(ctx);
8b3698b2
SM
19410 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19411 break;
19412 case NM_DPAQ_S_W_PH:
19413 check_dsp(ctx);
19414 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19415 break;
19416 case NM_DPS_W_PH:
908f6be1 19417 check_dsp_r2(ctx);
8b3698b2
SM
19418 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19419 break;
19420 case NM_DPSQ_S_W_PH:
19421 check_dsp(ctx);
19422 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19423 break;
19424 default:
3a4ef3b7 19425 gen_reserved_instruction(ctx);
8b3698b2
SM
19426 break;
19427 }
19428 break;
19429 case NM_POOL32AXF_2_8_15:
19430 switch (extract32(ctx->opcode, 9, 3)) {
19431 case NM_DPAX_W_PH:
908f6be1 19432 check_dsp_r2(ctx);
8b3698b2
SM
19433 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19434 break;
19435 case NM_DPAQ_SA_L_W:
19436 check_dsp(ctx);
19437 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19438 break;
19439 case NM_DPSX_W_PH:
908f6be1 19440 check_dsp_r2(ctx);
8b3698b2
SM
19441 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19442 break;
19443 case NM_DPSQ_SA_L_W:
19444 check_dsp(ctx);
19445 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19446 break;
19447 default:
3a4ef3b7 19448 gen_reserved_instruction(ctx);
8b3698b2
SM
19449 break;
19450 }
19451 break;
19452 case NM_POOL32AXF_2_16_23:
19453 switch (extract32(ctx->opcode, 9, 3)) {
19454 case NM_DPAU_H_QBL:
19455 check_dsp(ctx);
19456 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19457 break;
19458 case NM_DPAQX_S_W_PH:
908f6be1 19459 check_dsp_r2(ctx);
8b3698b2
SM
19460 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19461 break;
19462 case NM_DPSU_H_QBL:
19463 check_dsp(ctx);
19464 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19465 break;
19466 case NM_DPSQX_S_W_PH:
908f6be1 19467 check_dsp_r2(ctx);
8b3698b2
SM
19468 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19469 break;
19470 case NM_MULSA_W_PH:
908f6be1 19471 check_dsp_r2(ctx);
8b3698b2
SM
19472 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19473 break;
19474 default:
3a4ef3b7 19475 gen_reserved_instruction(ctx);
8b3698b2
SM
19476 break;
19477 }
19478 break;
19479 case NM_POOL32AXF_2_24_31:
19480 switch (extract32(ctx->opcode, 9, 3)) {
19481 case NM_DPAU_H_QBR:
19482 check_dsp(ctx);
19483 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19484 break;
19485 case NM_DPAQX_SA_W_PH:
908f6be1 19486 check_dsp_r2(ctx);
8b3698b2
SM
19487 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19488 break;
19489 case NM_DPSU_H_QBR:
19490 check_dsp(ctx);
19491 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19492 break;
19493 case NM_DPSQX_SA_W_PH:
908f6be1 19494 check_dsp_r2(ctx);
8b3698b2
SM
19495 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19496 break;
19497 case NM_MULSAQ_S_W_PH:
19498 check_dsp(ctx);
19499 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19500 break;
19501 default:
3a4ef3b7 19502 gen_reserved_instruction(ctx);
8b3698b2
SM
19503 break;
19504 }
19505 break;
19506 default:
3a4ef3b7 19507 gen_reserved_instruction(ctx);
8b3698b2
SM
19508 break;
19509 }
19510
19511 tcg_temp_free_i32(t0);
19512}
19513
19514static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19515 int rt, int rs, int rd)
19516{
19517 int ret = rt;
19518 TCGv t0 = tcg_temp_new();
19519 TCGv t1 = tcg_temp_new();
19520 TCGv v0_t = tcg_temp_new();
19521 TCGv v1_t = tcg_temp_new();
19522
19523 gen_load_gpr(v0_t, rt);
19524 gen_load_gpr(v1_t, rs);
19525
19526 switch (opc) {
19527 case NM_POOL32AXF_2_0_7:
19528 switch (extract32(ctx->opcode, 9, 3)) {
19529 case NM_DPA_W_PH:
19530 case NM_DPAQ_S_W_PH:
19531 case NM_DPS_W_PH:
19532 case NM_DPSQ_S_W_PH:
19533 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19534 break;
19535 case NM_BALIGN:
908f6be1 19536 check_dsp_r2(ctx);
8b3698b2
SM
19537 if (rt != 0) {
19538 gen_load_gpr(t0, rs);
19539 rd &= 3;
19540 if (rd != 0 && rd != 2) {
19541 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19542 tcg_gen_ext32u_tl(t0, t0);
19543 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19544 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19545 }
19546 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19547 }
19548 break;
19549 case NM_MADD:
19550 check_dsp(ctx);
19551 {
19552 int acc = extract32(ctx->opcode, 14, 2);
19553 TCGv_i64 t2 = tcg_temp_new_i64();
19554 TCGv_i64 t3 = tcg_temp_new_i64();
19555
19556 gen_load_gpr(t0, rt);
19557 gen_load_gpr(t1, rs);
19558 tcg_gen_ext_tl_i64(t2, t0);
19559 tcg_gen_ext_tl_i64(t3, t1);
19560 tcg_gen_mul_i64(t2, t2, t3);
19561 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19562 tcg_gen_add_i64(t2, t2, t3);
19563 tcg_temp_free_i64(t3);
19564 gen_move_low32(cpu_LO[acc], t2);
19565 gen_move_high32(cpu_HI[acc], t2);
19566 tcg_temp_free_i64(t2);
19567 }
19568 break;
19569 case NM_MULT:
19570 check_dsp(ctx);
19571 {
19572 int acc = extract32(ctx->opcode, 14, 2);
19573 TCGv_i32 t2 = tcg_temp_new_i32();
19574 TCGv_i32 t3 = tcg_temp_new_i32();
19575
19576 gen_load_gpr(t0, rs);
19577 gen_load_gpr(t1, rt);
19578 tcg_gen_trunc_tl_i32(t2, t0);
19579 tcg_gen_trunc_tl_i32(t3, t1);
19580 tcg_gen_muls2_i32(t2, t3, t2, t3);
19581 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19582 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19583 tcg_temp_free_i32(t2);
19584 tcg_temp_free_i32(t3);
19585 }
19586 break;
19587 case NM_EXTRV_W:
19588 check_dsp(ctx);
19589 gen_load_gpr(v1_t, rs);
19590 tcg_gen_movi_tl(t0, rd >> 3);
19591 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19592 gen_store_gpr(t0, ret);
19593 break;
19594 }
19595 break;
19596 case NM_POOL32AXF_2_8_15:
19597 switch (extract32(ctx->opcode, 9, 3)) {
19598 case NM_DPAX_W_PH:
19599 case NM_DPAQ_SA_L_W:
19600 case NM_DPSX_W_PH:
19601 case NM_DPSQ_SA_L_W:
19602 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19603 break;
19604 case NM_MADDU:
19605 check_dsp(ctx);
19606 {
19607 int acc = extract32(ctx->opcode, 14, 2);
19608 TCGv_i64 t2 = tcg_temp_new_i64();
19609 TCGv_i64 t3 = tcg_temp_new_i64();
19610
19611 gen_load_gpr(t0, rs);
19612 gen_load_gpr(t1, rt);
19613 tcg_gen_ext32u_tl(t0, t0);
19614 tcg_gen_ext32u_tl(t1, t1);
19615 tcg_gen_extu_tl_i64(t2, t0);
19616 tcg_gen_extu_tl_i64(t3, t1);
19617 tcg_gen_mul_i64(t2, t2, t3);
19618 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19619 tcg_gen_add_i64(t2, t2, t3);
19620 tcg_temp_free_i64(t3);
19621 gen_move_low32(cpu_LO[acc], t2);
19622 gen_move_high32(cpu_HI[acc], t2);
19623 tcg_temp_free_i64(t2);
19624 }
19625 break;
19626 case NM_MULTU:
19627 check_dsp(ctx);
19628 {
19629 int acc = extract32(ctx->opcode, 14, 2);
19630 TCGv_i32 t2 = tcg_temp_new_i32();
19631 TCGv_i32 t3 = tcg_temp_new_i32();
19632
19633 gen_load_gpr(t0, rs);
19634 gen_load_gpr(t1, rt);
19635 tcg_gen_trunc_tl_i32(t2, t0);
19636 tcg_gen_trunc_tl_i32(t3, t1);
19637 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19638 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19639 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19640 tcg_temp_free_i32(t2);
19641 tcg_temp_free_i32(t3);
19642 }
19643 break;
19644 case NM_EXTRV_R_W:
19645 check_dsp(ctx);
19646 tcg_gen_movi_tl(t0, rd >> 3);
19647 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19648 gen_store_gpr(t0, ret);
19649 break;
19650 default:
3a4ef3b7 19651 gen_reserved_instruction(ctx);
8b3698b2
SM
19652 break;
19653 }
19654 break;
19655 case NM_POOL32AXF_2_16_23:
19656 switch (extract32(ctx->opcode, 9, 3)) {
19657 case NM_DPAU_H_QBL:
19658 case NM_DPAQX_S_W_PH:
19659 case NM_DPSU_H_QBL:
19660 case NM_DPSQX_S_W_PH:
19661 case NM_MULSA_W_PH:
19662 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19663 break;
19664 case NM_EXTPV:
19665 check_dsp(ctx);
19666 tcg_gen_movi_tl(t0, rd >> 3);
19667 gen_helper_extp(t0, t0, v1_t, cpu_env);
19668 gen_store_gpr(t0, ret);
19669 break;
19670 case NM_MSUB:
19671 check_dsp(ctx);
19672 {
19673 int acc = extract32(ctx->opcode, 14, 2);
19674 TCGv_i64 t2 = tcg_temp_new_i64();
19675 TCGv_i64 t3 = tcg_temp_new_i64();
19676
19677 gen_load_gpr(t0, rs);
19678 gen_load_gpr(t1, rt);
19679 tcg_gen_ext_tl_i64(t2, t0);
19680 tcg_gen_ext_tl_i64(t3, t1);
19681 tcg_gen_mul_i64(t2, t2, t3);
19682 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19683 tcg_gen_sub_i64(t2, t3, t2);
19684 tcg_temp_free_i64(t3);
19685 gen_move_low32(cpu_LO[acc], t2);
19686 gen_move_high32(cpu_HI[acc], t2);
19687 tcg_temp_free_i64(t2);
19688 }
19689 break;
19690 case NM_EXTRV_RS_W:
19691 check_dsp(ctx);
19692 tcg_gen_movi_tl(t0, rd >> 3);
19693 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19694 gen_store_gpr(t0, ret);
19695 break;
19696 }
19697 break;
19698 case NM_POOL32AXF_2_24_31:
19699 switch (extract32(ctx->opcode, 9, 3)) {
19700 case NM_DPAU_H_QBR:
19701 case NM_DPAQX_SA_W_PH:
19702 case NM_DPSU_H_QBR:
19703 case NM_DPSQX_SA_W_PH:
19704 case NM_MULSAQ_S_W_PH:
19705 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19706 break;
19707 case NM_EXTPDPV:
19708 check_dsp(ctx);
19709 tcg_gen_movi_tl(t0, rd >> 3);
19710 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19711 gen_store_gpr(t0, ret);
19712 break;
19713 case NM_MSUBU:
19714 check_dsp(ctx);
19715 {
19716 int acc = extract32(ctx->opcode, 14, 2);
19717 TCGv_i64 t2 = tcg_temp_new_i64();
19718 TCGv_i64 t3 = tcg_temp_new_i64();
19719
19720 gen_load_gpr(t0, rs);
19721 gen_load_gpr(t1, rt);
19722 tcg_gen_ext32u_tl(t0, t0);
19723 tcg_gen_ext32u_tl(t1, t1);
19724 tcg_gen_extu_tl_i64(t2, t0);
19725 tcg_gen_extu_tl_i64(t3, t1);
19726 tcg_gen_mul_i64(t2, t2, t3);
19727 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19728 tcg_gen_sub_i64(t2, t3, t2);
19729 tcg_temp_free_i64(t3);
19730 gen_move_low32(cpu_LO[acc], t2);
19731 gen_move_high32(cpu_HI[acc], t2);
19732 tcg_temp_free_i64(t2);
19733 }
19734 break;
19735 case NM_EXTRV_S_H:
19736 check_dsp(ctx);
19737 tcg_gen_movi_tl(t0, rd >> 3);
19738 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19739 gen_store_gpr(t0, ret);
19740 break;
19741 }
19742 break;
19743 default:
3a4ef3b7 19744 gen_reserved_instruction(ctx);
8b3698b2
SM
19745 break;
19746 }
19747
19748 tcg_temp_free(t0);
19749 tcg_temp_free(t1);
19750
19751 tcg_temp_free(v0_t);
19752 tcg_temp_free(v1_t);
19753}
19754
4c75c985
SM
19755static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19756 int rt, int rs)
19757{
19758 int ret = rt;
19759 TCGv t0 = tcg_temp_new();
19760 TCGv v0_t = tcg_temp_new();
19761
19762 gen_load_gpr(v0_t, rs);
19763
19764 switch (opc) {
19765 case NM_ABSQ_S_QB:
908f6be1 19766 check_dsp_r2(ctx);
4c75c985
SM
19767 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19768 gen_store_gpr(v0_t, ret);
19769 break;
19770 case NM_ABSQ_S_PH:
19771 check_dsp(ctx);
19772 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19773 gen_store_gpr(v0_t, ret);
19774 break;
19775 case NM_ABSQ_S_W:
19776 check_dsp(ctx);
19777 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19778 gen_store_gpr(v0_t, ret);
19779 break;
19780 case NM_PRECEQ_W_PHL:
19781 check_dsp(ctx);
19782 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19783 tcg_gen_ext32s_tl(v0_t, v0_t);
19784 gen_store_gpr(v0_t, ret);
19785 break;
19786 case NM_PRECEQ_W_PHR:
19787 check_dsp(ctx);
19788 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19789 tcg_gen_shli_tl(v0_t, v0_t, 16);
19790 tcg_gen_ext32s_tl(v0_t, v0_t);
19791 gen_store_gpr(v0_t, ret);
19792 break;
19793 case NM_PRECEQU_PH_QBL:
19794 check_dsp(ctx);
19795 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19796 gen_store_gpr(v0_t, ret);
19797 break;
19798 case NM_PRECEQU_PH_QBR:
19799 check_dsp(ctx);
19800 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19801 gen_store_gpr(v0_t, ret);
19802 break;
19803 case NM_PRECEQU_PH_QBLA:
19804 check_dsp(ctx);
19805 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19806 gen_store_gpr(v0_t, ret);
19807 break;
19808 case NM_PRECEQU_PH_QBRA:
19809 check_dsp(ctx);
19810 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19811 gen_store_gpr(v0_t, ret);
19812 break;
19813 case NM_PRECEU_PH_QBL:
19814 check_dsp(ctx);
19815 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19816 gen_store_gpr(v0_t, ret);
19817 break;
19818 case NM_PRECEU_PH_QBR:
19819 check_dsp(ctx);
19820 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19821 gen_store_gpr(v0_t, ret);
19822 break;
19823 case NM_PRECEU_PH_QBLA:
19824 check_dsp(ctx);
19825 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19826 gen_store_gpr(v0_t, ret);
19827 break;
19828 case NM_PRECEU_PH_QBRA:
19829 check_dsp(ctx);
19830 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19831 gen_store_gpr(v0_t, ret);
19832 break;
19833 case NM_REPLV_PH:
19834 check_dsp(ctx);
19835 tcg_gen_ext16u_tl(v0_t, v0_t);
19836 tcg_gen_shli_tl(t0, v0_t, 16);
19837 tcg_gen_or_tl(v0_t, v0_t, t0);
19838 tcg_gen_ext32s_tl(v0_t, v0_t);
19839 gen_store_gpr(v0_t, ret);
19840 break;
19841 case NM_REPLV_QB:
19842 check_dsp(ctx);
19843 tcg_gen_ext8u_tl(v0_t, v0_t);
19844 tcg_gen_shli_tl(t0, v0_t, 8);
19845 tcg_gen_or_tl(v0_t, v0_t, t0);
19846 tcg_gen_shli_tl(t0, v0_t, 16);
19847 tcg_gen_or_tl(v0_t, v0_t, t0);
19848 tcg_gen_ext32s_tl(v0_t, v0_t);
19849 gen_store_gpr(v0_t, ret);
19850 break;
19851 case NM_BITREV:
19852 check_dsp(ctx);
19853 gen_helper_bitrev(v0_t, v0_t);
19854 gen_store_gpr(v0_t, ret);
19855 break;
19856 case NM_INSV:
19857 check_dsp(ctx);
19858 {
19859 TCGv tv0 = tcg_temp_new();
19860
19861 gen_load_gpr(tv0, rt);
19862 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19863 gen_store_gpr(v0_t, ret);
19864 tcg_temp_free(tv0);
19865 }
19866 break;
19867 case NM_RADDU_W_QB:
19868 check_dsp(ctx);
19869 gen_helper_raddu_w_qb(v0_t, v0_t);
19870 gen_store_gpr(v0_t, ret);
19871 break;
19872 case NM_BITSWAP:
19873 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19874 break;
19875 case NM_CLO:
fb32f8c8 19876 check_nms(ctx);
4c75c985
SM
19877 gen_cl(ctx, OPC_CLO, ret, rs);
19878 break;
19879 case NM_CLZ:
fb32f8c8 19880 check_nms(ctx);
4c75c985
SM
19881 gen_cl(ctx, OPC_CLZ, ret, rs);
19882 break;
19883 case NM_WSBH:
19884 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19885 break;
19886 default:
3a4ef3b7 19887 gen_reserved_instruction(ctx);
4c75c985
SM
19888 break;
19889 }
19890
19891 tcg_temp_free(v0_t);
19892 tcg_temp_free(t0);
19893}
19894
0b591184
SM
19895static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19896 int rt, int rs, int rd)
19897{
19898 TCGv t0 = tcg_temp_new();
19899 TCGv rs_t = tcg_temp_new();
19900
19901 gen_load_gpr(rs_t, rs);
19902
19903 switch (opc) {
19904 case NM_SHRA_R_QB:
908f6be1 19905 check_dsp_r2(ctx);
0b591184
SM
19906 tcg_gen_movi_tl(t0, rd >> 2);
19907 switch (extract32(ctx->opcode, 12, 1)) {
19908 case 0:
19909 /* NM_SHRA_QB */
19910 gen_helper_shra_qb(t0, t0, rs_t);
19911 gen_store_gpr(t0, rt);
19912 break;
19913 case 1:
19914 /* NM_SHRA_R_QB */
19915 gen_helper_shra_r_qb(t0, t0, rs_t);
19916 gen_store_gpr(t0, rt);
19917 break;
19918 }
19919 break;
19920 case NM_SHRL_PH:
908f6be1 19921 check_dsp_r2(ctx);
0b591184
SM
19922 tcg_gen_movi_tl(t0, rd >> 1);
19923 gen_helper_shrl_ph(t0, t0, rs_t);
19924 gen_store_gpr(t0, rt);
19925 break;
19926 case NM_REPL_QB:
19927 check_dsp(ctx);
19928 {
19929 int16_t imm;
19930 target_long result;
19931 imm = extract32(ctx->opcode, 13, 8);
19932 result = (uint32_t)imm << 24 |
19933 (uint32_t)imm << 16 |
19934 (uint32_t)imm << 8 |
19935 (uint32_t)imm;
19936 result = (int32_t)result;
19937 tcg_gen_movi_tl(t0, result);
19938 gen_store_gpr(t0, rt);
19939 }
19940 break;
19941 default:
3a4ef3b7 19942 gen_reserved_instruction(ctx);
0b591184
SM
19943 break;
19944 }
19945 tcg_temp_free(t0);
19946 tcg_temp_free(rs_t);
19947}
19948
2ed42efa 19949
64224187
YK
19950static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19951{
64224187
YK
19952 int rt = extract32(ctx->opcode, 21, 5);
19953 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 19954 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
19955
19956 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
19957 case NM_POOL32AXF_1:
19958 {
19959 int32_t op1 = extract32(ctx->opcode, 9, 3);
19960 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19961 }
19962 break;
19963 case NM_POOL32AXF_2:
8b3698b2
SM
19964 {
19965 int32_t op1 = extract32(ctx->opcode, 12, 2);
19966 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19967 }
2ed42efa 19968 break;
64224187 19969 case NM_POOL32AXF_4:
4c75c985
SM
19970 {
19971 int32_t op1 = extract32(ctx->opcode, 9, 7);
19972 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19973 }
2ed42efa 19974 break;
64224187
YK
19975 case NM_POOL32AXF_5:
19976 switch (extract32(ctx->opcode, 9, 7)) {
19977#ifndef CONFIG_USER_ONLY
19978 case NM_TLBP:
19979 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19980 break;
19981 case NM_TLBR:
19982 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19983 break;
19984 case NM_TLBWI:
19985 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19986 break;
19987 case NM_TLBWR:
19988 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19989 break;
19990 case NM_TLBINV:
19991 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19992 break;
19993 case NM_TLBINVF:
19994 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19995 break;
19996 case NM_DI:
19997 check_cp0_enabled(ctx);
19998 {
19999 TCGv t0 = tcg_temp_new();
20000
20001 save_cpu_state(ctx, 1);
20002 gen_helper_di(t0, cpu_env);
20003 gen_store_gpr(t0, rt);
20004 /* Stop translation as we may have switched the execution mode */
20005 ctx->base.is_jmp = DISAS_STOP;
20006 tcg_temp_free(t0);
20007 }
20008 break;
20009 case NM_EI:
20010 check_cp0_enabled(ctx);
20011 {
20012 TCGv t0 = tcg_temp_new();
20013
20014 save_cpu_state(ctx, 1);
20015 gen_helper_ei(t0, cpu_env);
20016 gen_store_gpr(t0, rt);
20017 /* Stop translation as we may have switched the execution mode */
20018 ctx->base.is_jmp = DISAS_STOP;
20019 tcg_temp_free(t0);
20020 }
20021 break;
20022 case NM_RDPGPR:
20023 gen_load_srsgpr(rs, rt);
20024 break;
20025 case NM_WRPGPR:
20026 gen_store_srsgpr(rs, rt);
20027 break;
20028 case NM_WAIT:
20029 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
20030 break;
20031 case NM_DERET:
20032 gen_cp0(env, ctx, OPC_DERET, 0, 0);
20033 break;
20034 case NM_ERETX:
20035 gen_cp0(env, ctx, OPC_ERET, 0, 0);
20036 break;
20037#endif
20038 default:
3a4ef3b7 20039 gen_reserved_instruction(ctx);
64224187
YK
20040 break;
20041 }
20042 break;
2ed42efa 20043 case NM_POOL32AXF_7:
0b591184
SM
20044 {
20045 int32_t op1 = extract32(ctx->opcode, 9, 3);
20046 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
20047 }
2ed42efa 20048 break;
64224187 20049 default:
3a4ef3b7 20050 gen_reserved_instruction(ctx);
64224187
YK
20051 break;
20052 }
20053}
20054
11d0fc10
SM
20055/* Immediate Value Compact Branches */
20056static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
20057 int rt, int32_t imm, int32_t offset)
20058{
10266143 20059 TCGCond cond = TCG_COND_ALWAYS;
11d0fc10
SM
20060 TCGv t0 = tcg_temp_new();
20061 TCGv t1 = tcg_temp_new();
20062
20063 gen_load_gpr(t0, rt);
20064 tcg_gen_movi_tl(t1, imm);
20065 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20066
20067 /* Load needed operands and calculate btarget */
20068 switch (opc) {
20069 case NM_BEQIC:
20070 if (rt == 0 && imm == 0) {
20071 /* Unconditional branch */
20072 } else if (rt == 0 && imm != 0) {
20073 /* Treat as NOP */
20074 goto out;
20075 } else {
11d0fc10
SM
20076 cond = TCG_COND_EQ;
20077 }
20078 break;
20079 case NM_BBEQZC:
20080 case NM_BBNEZC:
fb32f8c8 20081 check_nms(ctx);
11d0fc10 20082 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
3a4ef3b7 20083 gen_reserved_instruction(ctx);
11d0fc10
SM
20084 goto out;
20085 } else if (rt == 0 && opc == NM_BBEQZC) {
20086 /* Unconditional branch */
20087 } else if (rt == 0 && opc == NM_BBNEZC) {
20088 /* Treat as NOP */
20089 goto out;
20090 } else {
20091 tcg_gen_shri_tl(t0, t0, imm);
20092 tcg_gen_andi_tl(t0, t0, 1);
20093 tcg_gen_movi_tl(t1, 0);
11d0fc10
SM
20094 if (opc == NM_BBEQZC) {
20095 cond = TCG_COND_EQ;
20096 } else {
20097 cond = TCG_COND_NE;
20098 }
20099 }
20100 break;
20101 case NM_BNEIC:
20102 if (rt == 0 && imm == 0) {
20103 /* Treat as NOP */
20104 goto out;
20105 } else if (rt == 0 && imm != 0) {
20106 /* Unconditional branch */
20107 } else {
11d0fc10
SM
20108 cond = TCG_COND_NE;
20109 }
20110 break;
20111 case NM_BGEIC:
20112 if (rt == 0 && imm == 0) {
20113 /* Unconditional branch */
20114 } else {
11d0fc10
SM
20115 cond = TCG_COND_GE;
20116 }
20117 break;
20118 case NM_BLTIC:
11d0fc10
SM
20119 cond = TCG_COND_LT;
20120 break;
20121 case NM_BGEIUC:
20122 if (rt == 0 && imm == 0) {
20123 /* Unconditional branch */
20124 } else {
11d0fc10
SM
20125 cond = TCG_COND_GEU;
20126 }
20127 break;
20128 case NM_BLTIUC:
11d0fc10
SM
20129 cond = TCG_COND_LTU;
20130 break;
20131 default:
20132 MIPS_INVAL("Immediate Value Compact branch");
3a4ef3b7 20133 gen_reserved_instruction(ctx);
11d0fc10
SM
20134 goto out;
20135 }
20136
697b7b6b
SM
20137 /* branch completion */
20138 clear_branch_hflags(ctx);
20139 ctx->base.is_jmp = DISAS_NORETURN;
20140
10266143 20141 if (cond == TCG_COND_ALWAYS) {
11d0fc10
SM
20142 /* Uncoditional compact branch */
20143 gen_goto_tb(ctx, 0, ctx->btarget);
20144 } else {
20145 /* Conditional compact branch */
20146 TCGLabel *fs = gen_new_label();
20147
20148 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
20149
20150 gen_goto_tb(ctx, 1, ctx->btarget);
20151 gen_set_label(fs);
20152
20153 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20154 }
20155
20156out:
20157 tcg_temp_free(t0);
20158 tcg_temp_free(t1);
20159}
20160
20161/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20162static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
20163 int rt)
20164{
20165 TCGv t0 = tcg_temp_new();
20166 TCGv t1 = tcg_temp_new();
20167
20168 /* load rs */
20169 gen_load_gpr(t0, rs);
20170
20171 /* link */
20172 if (rt != 0) {
20173 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
20174 }
20175
20176 /* calculate btarget */
20177 tcg_gen_shli_tl(t0, t0, 1);
20178 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
20179 gen_op_addr_add(ctx, btarget, t1, t0);
20180
697b7b6b
SM
20181 /* branch completion */
20182 clear_branch_hflags(ctx);
20183 ctx->base.is_jmp = DISAS_NORETURN;
20184
11d0fc10
SM
20185 /* unconditional branch to register */
20186 tcg_gen_mov_tl(cpu_PC, btarget);
20187 tcg_gen_lookup_and_goto_ptr();
20188
20189 tcg_temp_free(t0);
20190 tcg_temp_free(t1);
20191}
20192
20193/* nanoMIPS Branches */
20194static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
20195 int rs, int rt, int32_t offset)
20196{
20197 int bcond_compute = 0;
20198 TCGv t0 = tcg_temp_new();
20199 TCGv t1 = tcg_temp_new();
20200
20201 /* Load needed operands and calculate btarget */
20202 switch (opc) {
20203 /* compact branch */
20204 case OPC_BGEC:
20205 case OPC_BLTC:
20206 gen_load_gpr(t0, rs);
20207 gen_load_gpr(t1, rt);
20208 bcond_compute = 1;
20209 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20210 break;
20211 case OPC_BGEUC:
20212 case OPC_BLTUC:
20213 if (rs == 0 || rs == rt) {
20214 /* OPC_BLEZALC, OPC_BGEZALC */
20215 /* OPC_BGTZALC, OPC_BLTZALC */
20216 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
20217 }
20218 gen_load_gpr(t0, rs);
20219 gen_load_gpr(t1, rt);
20220 bcond_compute = 1;
20221 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20222 break;
20223 case OPC_BC:
20224 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20225 break;
20226 case OPC_BEQZC:
20227 if (rs != 0) {
20228 /* OPC_BEQZC, OPC_BNEZC */
20229 gen_load_gpr(t0, rs);
20230 bcond_compute = 1;
20231 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20232 } else {
20233 /* OPC_JIC, OPC_JIALC */
20234 TCGv tbase = tcg_temp_new();
20235 TCGv toffset = tcg_temp_new();
20236
20237 gen_load_gpr(tbase, rt);
20238 tcg_gen_movi_tl(toffset, offset);
20239 gen_op_addr_add(ctx, btarget, tbase, toffset);
20240 tcg_temp_free(tbase);
20241 tcg_temp_free(toffset);
20242 }
20243 break;
20244 default:
20245 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 20246 gen_reserved_instruction(ctx);
11d0fc10
SM
20247 goto out;
20248 }
20249
20250 if (bcond_compute == 0) {
20251 /* Uncoditional compact branch */
20252 switch (opc) {
20253 case OPC_BC:
20254 gen_goto_tb(ctx, 0, ctx->btarget);
20255 break;
20256 default:
20257 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 20258 gen_reserved_instruction(ctx);
11d0fc10
SM
20259 goto out;
20260 }
20261 } else {
20262 /* Conditional compact branch */
20263 TCGLabel *fs = gen_new_label();
20264
20265 switch (opc) {
20266 case OPC_BGEUC:
20267 if (rs == 0 && rt != 0) {
20268 /* OPC_BLEZALC */
20269 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20270 } else if (rs != 0 && rt != 0 && rs == rt) {
20271 /* OPC_BGEZALC */
20272 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20273 } else {
20274 /* OPC_BGEUC */
20275 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20276 }
20277 break;
20278 case OPC_BLTUC:
20279 if (rs == 0 && rt != 0) {
20280 /* OPC_BGTZALC */
20281 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20282 } else if (rs != 0 && rt != 0 && rs == rt) {
20283 /* OPC_BLTZALC */
20284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20285 } else {
20286 /* OPC_BLTUC */
20287 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20288 }
20289 break;
20290 case OPC_BGEC:
20291 if (rs == 0 && rt != 0) {
20292 /* OPC_BLEZC */
20293 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20294 } else if (rs != 0 && rt != 0 && rs == rt) {
20295 /* OPC_BGEZC */
20296 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20297 } else {
20298 /* OPC_BGEC */
20299 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20300 }
20301 break;
20302 case OPC_BLTC:
20303 if (rs == 0 && rt != 0) {
20304 /* OPC_BGTZC */
20305 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20306 } else if (rs != 0 && rt != 0 && rs == rt) {
20307 /* OPC_BLTZC */
20308 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20309 } else {
20310 /* OPC_BLTC */
20311 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20312 }
20313 break;
20314 case OPC_BEQZC:
20315 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20316 break;
20317 default:
20318 MIPS_INVAL("Compact conditional branch/jump");
3a4ef3b7 20319 gen_reserved_instruction(ctx);
11d0fc10
SM
20320 goto out;
20321 }
20322
697b7b6b
SM
20323 /* branch completion */
20324 clear_branch_hflags(ctx);
20325 ctx->base.is_jmp = DISAS_NORETURN;
20326
11d0fc10
SM
20327 /* Generating branch here as compact branches don't have delay slot */
20328 gen_goto_tb(ctx, 1, ctx->btarget);
20329 gen_set_label(fs);
20330
20331 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20332 }
20333
20334out:
20335 tcg_temp_free(t0);
20336 tcg_temp_free(t1);
20337}
20338
20339
20340/* nanoMIPS CP1 Branches */
20341static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20342 int32_t ft, int32_t offset)
20343{
20344 target_ulong btarget;
20345 TCGv_i64 t0 = tcg_temp_new_i64();
20346
20347 gen_load_fpr64(ctx, t0, ft);
20348 tcg_gen_andi_i64(t0, t0, 1);
20349
20350 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20351
20352 switch (op) {
20353 case NM_BC1EQZC:
20354 tcg_gen_xori_i64(t0, t0, 1);
20355 ctx->hflags |= MIPS_HFLAG_BC;
20356 break;
20357 case NM_BC1NEZC:
20358 /* t0 already set */
20359 ctx->hflags |= MIPS_HFLAG_BC;
20360 break;
20361 default:
20362 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 20363 gen_reserved_instruction(ctx);
11d0fc10
SM
20364 goto out;
20365 }
20366
20367 tcg_gen_trunc_i64_tl(bcond, t0);
20368
20369 ctx->btarget = btarget;
20370
20371out:
20372 tcg_temp_free_i64(t0);
20373}
20374
eac52664
YK
20375
20376static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20377{
20378 TCGv t0, t1;
20379 t0 = tcg_temp_new();
20380 t1 = tcg_temp_new();
20381
20382 gen_load_gpr(t0, rs);
20383 gen_load_gpr(t1, rt);
20384
20385 if ((extract32(ctx->opcode, 6, 1)) == 1) {
20386 /* PP.LSXS instructions require shifting */
20387 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 20388 case NM_SHXS:
fb32f8c8 20389 check_nms(ctx);
45152d05 20390 /* fall through */
fb32f8c8 20391 case NM_LHXS:
eac52664
YK
20392 case NM_LHUXS:
20393 tcg_gen_shli_tl(t0, t0, 1);
20394 break;
eac52664 20395 case NM_SWXS:
fb32f8c8 20396 check_nms(ctx);
45152d05 20397 /* fall through */
fb32f8c8 20398 case NM_LWXS:
eac52664
YK
20399 case NM_LWC1XS:
20400 case NM_SWC1XS:
20401 tcg_gen_shli_tl(t0, t0, 2);
20402 break;
20403 case NM_LDC1XS:
20404 case NM_SDC1XS:
20405 tcg_gen_shli_tl(t0, t0, 3);
20406 break;
20407 }
20408 }
20409 gen_op_addr_add(ctx, t0, t0, t1);
20410
20411 switch (extract32(ctx->opcode, 7, 4)) {
20412 case NM_LBX:
20413 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20414 MO_SB);
20415 gen_store_gpr(t0, rd);
20416 break;
20417 case NM_LHX:
20418 /*case NM_LHXS:*/
20419 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20420 MO_TESW);
20421 gen_store_gpr(t0, rd);
20422 break;
20423 case NM_LWX:
20424 /*case NM_LWXS:*/
20425 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20426 MO_TESL);
20427 gen_store_gpr(t0, rd);
20428 break;
20429 case NM_LBUX:
20430 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20431 MO_UB);
20432 gen_store_gpr(t0, rd);
20433 break;
20434 case NM_LHUX:
20435 /*case NM_LHUXS:*/
20436 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20437 MO_TEUW);
20438 gen_store_gpr(t0, rd);
20439 break;
20440 case NM_SBX:
fb32f8c8 20441 check_nms(ctx);
eac52664
YK
20442 gen_load_gpr(t1, rd);
20443 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20444 MO_8);
20445 break;
20446 case NM_SHX:
20447 /*case NM_SHXS:*/
fb32f8c8 20448 check_nms(ctx);
eac52664
YK
20449 gen_load_gpr(t1, rd);
20450 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20451 MO_TEUW);
20452 break;
20453 case NM_SWX:
20454 /*case NM_SWXS:*/
fb32f8c8 20455 check_nms(ctx);
eac52664
YK
20456 gen_load_gpr(t1, rd);
20457 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20458 MO_TEUL);
20459 break;
20460 case NM_LWC1X:
20461 /*case NM_LWC1XS:*/
20462 case NM_LDC1X:
20463 /*case NM_LDC1XS:*/
20464 case NM_SWC1X:
20465 /*case NM_SWC1XS:*/
20466 case NM_SDC1X:
20467 /*case NM_SDC1XS:*/
20468 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20469 check_cp1_enabled(ctx);
20470 switch (extract32(ctx->opcode, 7, 4)) {
20471 case NM_LWC1X:
20472 /*case NM_LWC1XS:*/
20473 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20474 break;
20475 case NM_LDC1X:
20476 /*case NM_LDC1XS:*/
20477 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20478 break;
20479 case NM_SWC1X:
20480 /*case NM_SWC1XS:*/
20481 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20482 break;
20483 case NM_SDC1X:
20484 /*case NM_SDC1XS:*/
20485 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20486 break;
20487 }
20488 } else {
20489 generate_exception_err(ctx, EXCP_CpU, 1);
20490 }
20491 break;
20492 default:
3a4ef3b7 20493 gen_reserved_instruction(ctx);
eac52664
YK
20494 break;
20495 }
20496
20497 tcg_temp_free(t0);
20498 tcg_temp_free(t1);
20499}
20500
579b8ea9
YK
20501static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20502{
20503 int rt, rs, rd;
20504
20505 rt = extract32(ctx->opcode, 21, 5);
20506 rs = extract32(ctx->opcode, 16, 5);
20507 rd = extract32(ctx->opcode, 11, 5);
20508
20509 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
3a4ef3b7 20510 gen_reserved_instruction(ctx);
579b8ea9
YK
20511 return;
20512 }
20513 check_cp1_enabled(ctx);
20514 switch (extract32(ctx->opcode, 0, 3)) {
20515 case NM_POOL32F_0:
20516 switch (extract32(ctx->opcode, 3, 7)) {
20517 case NM_RINT_S:
20518 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20519 break;
20520 case NM_RINT_D:
20521 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20522 break;
20523 case NM_CLASS_S:
20524 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20525 break;
20526 case NM_CLASS_D:
20527 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20528 break;
20529 case NM_ADD_S:
20530 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20531 break;
20532 case NM_ADD_D:
20533 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20534 break;
20535 case NM_SUB_S:
20536 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20537 break;
20538 case NM_SUB_D:
20539 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20540 break;
20541 case NM_MUL_S:
20542 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20543 break;
20544 case NM_MUL_D:
20545 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20546 break;
20547 case NM_DIV_S:
20548 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20549 break;
20550 case NM_DIV_D:
20551 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20552 break;
20553 case NM_SELEQZ_S:
20554 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20555 break;
20556 case NM_SELEQZ_D:
20557 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20558 break;
20559 case NM_SELNEZ_S:
20560 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20561 break;
20562 case NM_SELNEZ_D:
20563 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20564 break;
20565 case NM_SEL_S:
20566 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20567 break;
20568 case NM_SEL_D:
20569 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20570 break;
20571 case NM_MADDF_S:
20572 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20573 break;
20574 case NM_MADDF_D:
20575 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20576 break;
20577 case NM_MSUBF_S:
20578 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20579 break;
20580 case NM_MSUBF_D:
20581 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20582 break;
20583 default:
3a4ef3b7 20584 gen_reserved_instruction(ctx);
579b8ea9
YK
20585 break;
20586 }
20587 break;
20588 case NM_POOL32F_3:
20589 switch (extract32(ctx->opcode, 3, 3)) {
20590 case NM_MIN_FMT:
20591 switch (extract32(ctx->opcode, 9, 1)) {
20592 case FMT_SDPS_S:
20593 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20594 break;
20595 case FMT_SDPS_D:
20596 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20597 break;
20598 }
20599 break;
20600 case NM_MAX_FMT:
20601 switch (extract32(ctx->opcode, 9, 1)) {
20602 case FMT_SDPS_S:
20603 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20604 break;
20605 case FMT_SDPS_D:
20606 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20607 break;
20608 }
20609 break;
20610 case NM_MINA_FMT:
20611 switch (extract32(ctx->opcode, 9, 1)) {
20612 case FMT_SDPS_S:
20613 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20614 break;
20615 case FMT_SDPS_D:
20616 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20617 break;
20618 }
20619 break;
20620 case NM_MAXA_FMT:
20621 switch (extract32(ctx->opcode, 9, 1)) {
20622 case FMT_SDPS_S:
20623 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20624 break;
20625 case FMT_SDPS_D:
20626 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20627 break;
20628 }
20629 break;
20630 case NM_POOL32FXF:
20631 switch (extract32(ctx->opcode, 6, 8)) {
20632 case NM_CFC1:
20633 gen_cp1(ctx, OPC_CFC1, rt, rs);
20634 break;
20635 case NM_CTC1:
20636 gen_cp1(ctx, OPC_CTC1, rt, rs);
20637 break;
20638 case NM_MFC1:
20639 gen_cp1(ctx, OPC_MFC1, rt, rs);
20640 break;
20641 case NM_MTC1:
20642 gen_cp1(ctx, OPC_MTC1, rt, rs);
20643 break;
20644 case NM_MFHC1:
20645 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20646 break;
20647 case NM_MTHC1:
20648 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20649 break;
20650 case NM_CVT_S_PL:
20651 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20652 break;
20653 case NM_CVT_S_PU:
20654 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20655 break;
20656 default:
20657 switch (extract32(ctx->opcode, 6, 9)) {
20658 case NM_CVT_L_S:
20659 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20660 break;
20661 case NM_CVT_L_D:
20662 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20663 break;
20664 case NM_CVT_W_S:
20665 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20666 break;
20667 case NM_CVT_W_D:
20668 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20669 break;
20670 case NM_RSQRT_S:
20671 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20672 break;
20673 case NM_RSQRT_D:
20674 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20675 break;
20676 case NM_SQRT_S:
20677 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20678 break;
20679 case NM_SQRT_D:
20680 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20681 break;
20682 case NM_RECIP_S:
20683 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20684 break;
20685 case NM_RECIP_D:
20686 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20687 break;
20688 case NM_FLOOR_L_S:
20689 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20690 break;
20691 case NM_FLOOR_L_D:
20692 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20693 break;
20694 case NM_FLOOR_W_S:
20695 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20696 break;
20697 case NM_FLOOR_W_D:
20698 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20699 break;
20700 case NM_CEIL_L_S:
20701 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20702 break;
20703 case NM_CEIL_L_D:
20704 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20705 break;
20706 case NM_CEIL_W_S:
20707 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20708 break;
20709 case NM_CEIL_W_D:
20710 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20711 break;
20712 case NM_TRUNC_L_S:
20713 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20714 break;
20715 case NM_TRUNC_L_D:
20716 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20717 break;
20718 case NM_TRUNC_W_S:
20719 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20720 break;
20721 case NM_TRUNC_W_D:
20722 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20723 break;
20724 case NM_ROUND_L_S:
20725 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20726 break;
20727 case NM_ROUND_L_D:
20728 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20729 break;
20730 case NM_ROUND_W_S:
20731 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20732 break;
20733 case NM_ROUND_W_D:
20734 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20735 break;
20736 case NM_MOV_S:
20737 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20738 break;
20739 case NM_MOV_D:
20740 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20741 break;
20742 case NM_ABS_S:
20743 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20744 break;
20745 case NM_ABS_D:
20746 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20747 break;
20748 case NM_NEG_S:
20749 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20750 break;
20751 case NM_NEG_D:
20752 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20753 break;
20754 case NM_CVT_D_S:
20755 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20756 break;
20757 case NM_CVT_D_W:
20758 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20759 break;
20760 case NM_CVT_D_L:
20761 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20762 break;
20763 case NM_CVT_S_D:
20764 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20765 break;
20766 case NM_CVT_S_W:
20767 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20768 break;
20769 case NM_CVT_S_L:
20770 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20771 break;
20772 default:
3a4ef3b7 20773 gen_reserved_instruction(ctx);
579b8ea9
YK
20774 break;
20775 }
20776 break;
20777 }
20778 break;
20779 }
20780 break;
20781 case NM_POOL32F_5:
20782 switch (extract32(ctx->opcode, 3, 3)) {
20783 case NM_CMP_CONDN_S:
20784 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20785 break;
20786 case NM_CMP_CONDN_D:
20787 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20788 break;
20789 default:
3a4ef3b7 20790 gen_reserved_instruction(ctx);
579b8ea9
YK
20791 break;
20792 }
20793 break;
20794 default:
3a4ef3b7 20795 gen_reserved_instruction(ctx);
579b8ea9
YK
20796 break;
20797 }
20798}
20799
3285a3e4
SM
20800static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20801 int rd, int rs, int rt)
20802{
20803 int ret = rd;
20804 TCGv t0 = tcg_temp_new();
20805 TCGv v1_t = tcg_temp_new();
20806 TCGv v2_t = tcg_temp_new();
20807
20808 gen_load_gpr(v1_t, rs);
20809 gen_load_gpr(v2_t, rt);
20810
20811 switch (opc) {
20812 case NM_CMP_EQ_PH:
20813 check_dsp(ctx);
20814 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20815 break;
20816 case NM_CMP_LT_PH:
20817 check_dsp(ctx);
20818 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20819 break;
20820 case NM_CMP_LE_PH:
20821 check_dsp(ctx);
20822 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20823 break;
20824 case NM_CMPU_EQ_QB:
20825 check_dsp(ctx);
20826 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20827 break;
20828 case NM_CMPU_LT_QB:
20829 check_dsp(ctx);
20830 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20831 break;
20832 case NM_CMPU_LE_QB:
20833 check_dsp(ctx);
20834 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20835 break;
20836 case NM_CMPGU_EQ_QB:
20837 check_dsp(ctx);
20838 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20839 gen_store_gpr(v1_t, ret);
20840 break;
20841 case NM_CMPGU_LT_QB:
20842 check_dsp(ctx);
20843 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20844 gen_store_gpr(v1_t, ret);
20845 break;
20846 case NM_CMPGU_LE_QB:
20847 check_dsp(ctx);
20848 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20849 gen_store_gpr(v1_t, ret);
20850 break;
20851 case NM_CMPGDU_EQ_QB:
908f6be1 20852 check_dsp_r2(ctx);
3285a3e4
SM
20853 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20854 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20855 gen_store_gpr(v1_t, ret);
20856 break;
20857 case NM_CMPGDU_LT_QB:
908f6be1 20858 check_dsp_r2(ctx);
3285a3e4
SM
20859 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20860 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20861 gen_store_gpr(v1_t, ret);
20862 break;
20863 case NM_CMPGDU_LE_QB:
908f6be1 20864 check_dsp_r2(ctx);
3285a3e4
SM
20865 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20866 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20867 gen_store_gpr(v1_t, ret);
20868 break;
20869 case NM_PACKRL_PH:
20870 check_dsp(ctx);
20871 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20872 gen_store_gpr(v1_t, ret);
20873 break;
20874 case NM_PICK_QB:
20875 check_dsp(ctx);
20876 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20877 gen_store_gpr(v1_t, ret);
20878 break;
20879 case NM_PICK_PH:
20880 check_dsp(ctx);
20881 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20882 gen_store_gpr(v1_t, ret);
20883 break;
20884 case NM_ADDQ_S_W:
20885 check_dsp(ctx);
20886 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20887 gen_store_gpr(v1_t, ret);
20888 break;
20889 case NM_SUBQ_S_W:
20890 check_dsp(ctx);
20891 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20892 gen_store_gpr(v1_t, ret);
20893 break;
20894 case NM_ADDSC:
20895 check_dsp(ctx);
20896 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20897 gen_store_gpr(v1_t, ret);
20898 break;
20899 case NM_ADDWC:
20900 check_dsp(ctx);
20901 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20902 gen_store_gpr(v1_t, ret);
20903 break;
20904 case NM_ADDQ_S_PH:
20905 check_dsp(ctx);
20906 switch (extract32(ctx->opcode, 10, 1)) {
20907 case 0:
20908 /* ADDQ_PH */
20909 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20910 gen_store_gpr(v1_t, ret);
20911 break;
20912 case 1:
20913 /* ADDQ_S_PH */
20914 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20915 gen_store_gpr(v1_t, ret);
20916 break;
20917 }
20918 break;
20919 case NM_ADDQH_R_PH:
908f6be1 20920 check_dsp_r2(ctx);
3285a3e4
SM
20921 switch (extract32(ctx->opcode, 10, 1)) {
20922 case 0:
20923 /* ADDQH_PH */
20924 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20925 gen_store_gpr(v1_t, ret);
20926 break;
20927 case 1:
20928 /* ADDQH_R_PH */
20929 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20930 gen_store_gpr(v1_t, ret);
20931 break;
20932 }
20933 break;
20934 case NM_ADDQH_R_W:
908f6be1 20935 check_dsp_r2(ctx);
3285a3e4
SM
20936 switch (extract32(ctx->opcode, 10, 1)) {
20937 case 0:
20938 /* ADDQH_W */
20939 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20940 gen_store_gpr(v1_t, ret);
20941 break;
20942 case 1:
20943 /* ADDQH_R_W */
20944 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20945 gen_store_gpr(v1_t, ret);
20946 break;
20947 }
20948 break;
20949 case NM_ADDU_S_QB:
20950 check_dsp(ctx);
20951 switch (extract32(ctx->opcode, 10, 1)) {
20952 case 0:
20953 /* ADDU_QB */
20954 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20955 gen_store_gpr(v1_t, ret);
20956 break;
20957 case 1:
20958 /* ADDU_S_QB */
20959 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20960 gen_store_gpr(v1_t, ret);
20961 break;
20962 }
20963 break;
20964 case NM_ADDU_S_PH:
908f6be1 20965 check_dsp_r2(ctx);
3285a3e4
SM
20966 switch (extract32(ctx->opcode, 10, 1)) {
20967 case 0:
20968 /* ADDU_PH */
20969 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20970 gen_store_gpr(v1_t, ret);
20971 break;
20972 case 1:
20973 /* ADDU_S_PH */
20974 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20975 gen_store_gpr(v1_t, ret);
20976 break;
20977 }
20978 break;
20979 case NM_ADDUH_R_QB:
908f6be1 20980 check_dsp_r2(ctx);
3285a3e4
SM
20981 switch (extract32(ctx->opcode, 10, 1)) {
20982 case 0:
20983 /* ADDUH_QB */
20984 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20985 gen_store_gpr(v1_t, ret);
20986 break;
20987 case 1:
20988 /* ADDUH_R_QB */
20989 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20990 gen_store_gpr(v1_t, ret);
20991 break;
20992 }
20993 break;
20994 case NM_SHRAV_R_PH:
20995 check_dsp(ctx);
20996 switch (extract32(ctx->opcode, 10, 1)) {
20997 case 0:
20998 /* SHRAV_PH */
20999 gen_helper_shra_ph(v1_t, v1_t, v2_t);
21000 gen_store_gpr(v1_t, ret);
21001 break;
21002 case 1:
21003 /* SHRAV_R_PH */
21004 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
21005 gen_store_gpr(v1_t, ret);
21006 break;
21007 }
21008 break;
21009 case NM_SHRAV_R_QB:
908f6be1 21010 check_dsp_r2(ctx);
3285a3e4
SM
21011 switch (extract32(ctx->opcode, 10, 1)) {
21012 case 0:
21013 /* SHRAV_QB */
21014 gen_helper_shra_qb(v1_t, v1_t, v2_t);
21015 gen_store_gpr(v1_t, ret);
21016 break;
21017 case 1:
21018 /* SHRAV_R_QB */
21019 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
21020 gen_store_gpr(v1_t, ret);
21021 break;
21022 }
21023 break;
21024 case NM_SUBQ_S_PH:
21025 check_dsp(ctx);
21026 switch (extract32(ctx->opcode, 10, 1)) {
21027 case 0:
21028 /* SUBQ_PH */
21029 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
21030 gen_store_gpr(v1_t, ret);
21031 break;
21032 case 1:
21033 /* SUBQ_S_PH */
21034 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21035 gen_store_gpr(v1_t, ret);
21036 break;
21037 }
21038 break;
21039 case NM_SUBQH_R_PH:
908f6be1 21040 check_dsp_r2(ctx);
3285a3e4
SM
21041 switch (extract32(ctx->opcode, 10, 1)) {
21042 case 0:
21043 /* SUBQH_PH */
21044 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
21045 gen_store_gpr(v1_t, ret);
21046 break;
21047 case 1:
21048 /* SUBQH_R_PH */
21049 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
21050 gen_store_gpr(v1_t, ret);
21051 break;
21052 }
21053 break;
21054 case NM_SUBQH_R_W:
908f6be1 21055 check_dsp_r2(ctx);
3285a3e4
SM
21056 switch (extract32(ctx->opcode, 10, 1)) {
21057 case 0:
21058 /* SUBQH_W */
21059 gen_helper_subqh_w(v1_t, v1_t, v2_t);
21060 gen_store_gpr(v1_t, ret);
21061 break;
21062 case 1:
21063 /* SUBQH_R_W */
21064 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
21065 gen_store_gpr(v1_t, ret);
21066 break;
21067 }
21068 break;
21069 case NM_SUBU_S_QB:
21070 check_dsp(ctx);
21071 switch (extract32(ctx->opcode, 10, 1)) {
21072 case 0:
21073 /* SUBU_QB */
21074 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
21075 gen_store_gpr(v1_t, ret);
21076 break;
21077 case 1:
21078 /* SUBU_S_QB */
21079 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
21080 gen_store_gpr(v1_t, ret);
21081 break;
21082 }
21083 break;
21084 case NM_SUBU_S_PH:
908f6be1 21085 check_dsp_r2(ctx);
3285a3e4
SM
21086 switch (extract32(ctx->opcode, 10, 1)) {
21087 case 0:
21088 /* SUBU_PH */
21089 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
21090 gen_store_gpr(v1_t, ret);
21091 break;
21092 case 1:
21093 /* SUBU_S_PH */
21094 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
21095 gen_store_gpr(v1_t, ret);
21096 break;
21097 }
21098 break;
21099 case NM_SUBUH_R_QB:
908f6be1 21100 check_dsp_r2(ctx);
3285a3e4
SM
21101 switch (extract32(ctx->opcode, 10, 1)) {
21102 case 0:
21103 /* SUBUH_QB */
21104 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
21105 gen_store_gpr(v1_t, ret);
21106 break;
21107 case 1:
21108 /* SUBUH_R_QB */
21109 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
21110 gen_store_gpr(v1_t, ret);
21111 break;
21112 }
21113 break;
21114 case NM_SHLLV_S_PH:
21115 check_dsp(ctx);
21116 switch (extract32(ctx->opcode, 10, 1)) {
21117 case 0:
21118 /* SHLLV_PH */
21119 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
21120 gen_store_gpr(v1_t, ret);
21121 break;
21122 case 1:
21123 /* SHLLV_S_PH */
21124 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
21125 gen_store_gpr(v1_t, ret);
21126 break;
21127 }
21128 break;
21129 case NM_PRECR_SRA_R_PH_W:
908f6be1 21130 check_dsp_r2(ctx);
3285a3e4
SM
21131 switch (extract32(ctx->opcode, 10, 1)) {
21132 case 0:
21133 /* PRECR_SRA_PH_W */
21134 {
21135 TCGv_i32 sa_t = tcg_const_i32(rd);
21136 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
21137 cpu_gpr[rt]);
21138 gen_store_gpr(v1_t, rt);
21139 tcg_temp_free_i32(sa_t);
21140 }
21141 break;
21142 case 1:
21143 /* PRECR_SRA_R_PH_W */
21144 {
21145 TCGv_i32 sa_t = tcg_const_i32(rd);
21146 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
21147 cpu_gpr[rt]);
21148 gen_store_gpr(v1_t, rt);
21149 tcg_temp_free_i32(sa_t);
21150 }
21151 break;
21152 }
21153 break;
21154 case NM_MULEU_S_PH_QBL:
21155 check_dsp(ctx);
21156 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
21157 gen_store_gpr(v1_t, ret);
21158 break;
21159 case NM_MULEU_S_PH_QBR:
21160 check_dsp(ctx);
21161 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
21162 gen_store_gpr(v1_t, ret);
21163 break;
21164 case NM_MULQ_RS_PH:
21165 check_dsp(ctx);
21166 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
21167 gen_store_gpr(v1_t, ret);
21168 break;
21169 case NM_MULQ_S_PH:
908f6be1 21170 check_dsp_r2(ctx);
3285a3e4
SM
21171 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21172 gen_store_gpr(v1_t, ret);
21173 break;
21174 case NM_MULQ_RS_W:
908f6be1 21175 check_dsp_r2(ctx);
3285a3e4
SM
21176 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
21177 gen_store_gpr(v1_t, ret);
21178 break;
21179 case NM_MULQ_S_W:
908f6be1 21180 check_dsp_r2(ctx);
3285a3e4
SM
21181 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
21182 gen_store_gpr(v1_t, ret);
21183 break;
21184 case NM_APPEND:
908f6be1 21185 check_dsp_r2(ctx);
3285a3e4
SM
21186 gen_load_gpr(t0, rs);
21187 if (rd != 0) {
21188 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
21189 }
21190 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21191 break;
21192 case NM_MODSUB:
21193 check_dsp(ctx);
21194 gen_helper_modsub(v1_t, v1_t, v2_t);
21195 gen_store_gpr(v1_t, ret);
21196 break;
21197 case NM_SHRAV_R_W:
21198 check_dsp(ctx);
21199 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
21200 gen_store_gpr(v1_t, ret);
21201 break;
21202 case NM_SHRLV_PH:
908f6be1 21203 check_dsp_r2(ctx);
3285a3e4
SM
21204 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
21205 gen_store_gpr(v1_t, ret);
21206 break;
21207 case NM_SHRLV_QB:
21208 check_dsp(ctx);
21209 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
21210 gen_store_gpr(v1_t, ret);
21211 break;
21212 case NM_SHLLV_QB:
21213 check_dsp(ctx);
21214 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
21215 gen_store_gpr(v1_t, ret);
21216 break;
21217 case NM_SHLLV_S_W:
21218 check_dsp(ctx);
21219 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
21220 gen_store_gpr(v1_t, ret);
21221 break;
21222 case NM_SHILO:
21223 check_dsp(ctx);
21224 {
21225 TCGv tv0 = tcg_temp_new();
21226 TCGv tv1 = tcg_temp_new();
21227 int16_t imm = extract32(ctx->opcode, 16, 7);
21228
21229 tcg_gen_movi_tl(tv0, rd >> 3);
21230 tcg_gen_movi_tl(tv1, imm);
21231 gen_helper_shilo(tv0, tv1, cpu_env);
21232 }
21233 break;
21234 case NM_MULEQ_S_W_PHL:
21235 check_dsp(ctx);
21236 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
21237 gen_store_gpr(v1_t, ret);
21238 break;
21239 case NM_MULEQ_S_W_PHR:
21240 check_dsp(ctx);
21241 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
21242 gen_store_gpr(v1_t, ret);
21243 break;
21244 case NM_MUL_S_PH:
908f6be1 21245 check_dsp_r2(ctx);
3285a3e4
SM
21246 switch (extract32(ctx->opcode, 10, 1)) {
21247 case 0:
21248 /* MUL_PH */
21249 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21250 gen_store_gpr(v1_t, ret);
21251 break;
21252 case 1:
21253 /* MUL_S_PH */
21254 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21255 gen_store_gpr(v1_t, ret);
21256 break;
21257 }
21258 break;
21259 case NM_PRECR_QB_PH:
908f6be1 21260 check_dsp_r2(ctx);
3285a3e4
SM
21261 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21262 gen_store_gpr(v1_t, ret);
21263 break;
21264 case NM_PRECRQ_QB_PH:
21265 check_dsp(ctx);
21266 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21267 gen_store_gpr(v1_t, ret);
21268 break;
21269 case NM_PRECRQ_PH_W:
21270 check_dsp(ctx);
21271 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21272 gen_store_gpr(v1_t, ret);
21273 break;
21274 case NM_PRECRQ_RS_PH_W:
21275 check_dsp(ctx);
21276 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21277 gen_store_gpr(v1_t, ret);
21278 break;
21279 case NM_PRECRQU_S_QB_PH:
21280 check_dsp(ctx);
21281 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21282 gen_store_gpr(v1_t, ret);
21283 break;
21284 case NM_SHRA_R_W:
21285 check_dsp(ctx);
21286 tcg_gen_movi_tl(t0, rd);
21287 gen_helper_shra_r_w(v1_t, t0, v1_t);
21288 gen_store_gpr(v1_t, rt);
21289 break;
21290 case NM_SHRA_R_PH:
21291 check_dsp(ctx);
21292 tcg_gen_movi_tl(t0, rd >> 1);
21293 switch (extract32(ctx->opcode, 10, 1)) {
21294 case 0:
21295 /* SHRA_PH */
21296 gen_helper_shra_ph(v1_t, t0, v1_t);
3285a3e4 21297 gen_store_gpr(v1_t, rt);
d5ebcbaf 21298 break;
3285a3e4
SM
21299 case 1:
21300 /* SHRA_R_PH */
21301 gen_helper_shra_r_ph(v1_t, t0, v1_t);
21302 gen_store_gpr(v1_t, rt);
21303 break;
21304 }
21305 break;
21306 case NM_SHLL_S_PH:
21307 check_dsp(ctx);
21308 tcg_gen_movi_tl(t0, rd >> 1);
21309 switch (extract32(ctx->opcode, 10, 2)) {
21310 case 0:
21311 /* SHLL_PH */
21312 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21313 gen_store_gpr(v1_t, rt);
21314 break;
21315 case 2:
21316 /* SHLL_S_PH */
21317 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21318 gen_store_gpr(v1_t, rt);
21319 break;
21320 default:
3a4ef3b7 21321 gen_reserved_instruction(ctx);
3285a3e4
SM
21322 break;
21323 }
21324 break;
21325 case NM_SHLL_S_W:
21326 check_dsp(ctx);
21327 tcg_gen_movi_tl(t0, rd);
21328 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21329 gen_store_gpr(v1_t, rt);
21330 break;
21331 case NM_REPL_PH:
21332 check_dsp(ctx);
21333 {
21334 int16_t imm;
21335 imm = sextract32(ctx->opcode, 11, 11);
21336 imm = (int16_t)(imm << 6) >> 6;
21337 if (rt != 0) {
21338 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21339 }
21340 }
21341 break;
21342 default:
3a4ef3b7 21343 gen_reserved_instruction(ctx);
3285a3e4
SM
21344 break;
21345 }
21346}
21347
c0280983
YK
21348static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21349{
21350 uint16_t insn;
21351 uint32_t op;
eac52664 21352 int rt, rs, rd;
c0280983
YK
21353 int offset;
21354 int imm;
21355
21356 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21357 ctx->opcode = (ctx->opcode << 16) | insn;
21358
21359 rt = extract32(ctx->opcode, 21, 5);
21360 rs = extract32(ctx->opcode, 16, 5);
eac52664 21361 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
21362
21363 op = extract32(ctx->opcode, 26, 6);
21364 switch (op) {
21365 case NM_P_ADDIU:
21366 if (rt == 0) {
21367 /* P.RI */
21368 switch (extract32(ctx->opcode, 19, 2)) {
21369 case NM_SIGRIE:
21370 default:
3a4ef3b7 21371 gen_reserved_instruction(ctx);
c0280983
YK
21372 break;
21373 case NM_P_SYSCALL:
21374 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21375 generate_exception_end(ctx, EXCP_SYSCALL);
21376 } else {
3a4ef3b7 21377 gen_reserved_instruction(ctx);
c0280983
YK
21378 }
21379 break;
21380 case NM_BREAK:
21381 generate_exception_end(ctx, EXCP_BREAK);
21382 break;
21383 case NM_SDBBP:
21384 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21385 gen_helper_do_semihosting(cpu_env);
21386 } else {
21387 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 21388 gen_reserved_instruction(ctx);
c0280983
YK
21389 } else {
21390 generate_exception_end(ctx, EXCP_DBp);
21391 }
21392 }
21393 break;
21394 }
21395 } else {
21396 /* NM_ADDIU */
21397 imm = extract32(ctx->opcode, 0, 16);
21398 if (rs != 0) {
21399 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21400 } else {
21401 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21402 }
21403 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21404 }
21405 break;
21406 case NM_ADDIUPC:
21407 if (rt != 0) {
21408 offset = sextract32(ctx->opcode, 0, 1) << 21 |
21409 extract32(ctx->opcode, 1, 20) << 1;
21410 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21411 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21412 }
21413 break;
21414 case NM_POOL32A:
e0cf0e65
YK
21415 switch (ctx->opcode & 0x07) {
21416 case NM_POOL32A0:
0a1a6ed7 21417 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 21418 break;
3285a3e4
SM
21419 case NM_POOL32A5:
21420 {
21421 int32_t op1 = extract32(ctx->opcode, 3, 7);
21422 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21423 }
21424 break;
e0cf0e65 21425 case NM_POOL32A7:
64224187 21426 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
21427 case NM_P_LSX:
21428 gen_p_lsx(ctx, rd, rs, rt);
21429 break;
21430 case NM_LSA:
7480515f
AM
21431 /*
21432 * In nanoMIPS, the shift field directly encodes the shift
eac52664 21433 * amount, meaning that the supported shift values are in
7480515f
AM
21434 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21435 */
a685f7d0 21436 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1);
eac52664 21437 break;
821f2008
JH
21438 case NM_EXTW:
21439 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21440 break;
64224187
YK
21441 case NM_POOL32AXF:
21442 gen_pool32axf_nanomips_insn(env, ctx);
21443 break;
21444 default:
3a4ef3b7 21445 gen_reserved_instruction(ctx);
64224187
YK
21446 break;
21447 }
e0cf0e65
YK
21448 break;
21449 default:
3a4ef3b7 21450 gen_reserved_instruction(ctx);
e0cf0e65
YK
21451 break;
21452 }
c0280983
YK
21453 break;
21454 case NM_P_GP_W:
21455 switch (ctx->opcode & 0x03) {
21456 case NM_ADDIUGP_W:
21457 if (rt != 0) {
21458 offset = extract32(ctx->opcode, 0, 21);
21459 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21460 }
21461 break;
21462 case NM_LWGP:
21463 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21464 break;
21465 case NM_SWGP:
21466 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21467 break;
21468 default:
3a4ef3b7 21469 gen_reserved_instruction(ctx);
c0280983
YK
21470 break;
21471 }
21472 break;
21473 case NM_P48I:
7ef009b2
YK
21474 {
21475 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21476 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21477 switch (extract32(ctx->opcode, 16, 5)) {
21478 case NM_LI48:
fb32f8c8 21479 check_nms(ctx);
7ef009b2
YK
21480 if (rt != 0) {
21481 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21482 }
21483 break;
21484 case NM_ADDIU48:
fb32f8c8 21485 check_nms(ctx);
7ef009b2
YK
21486 if (rt != 0) {
21487 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21488 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21489 }
21490 break;
21491 case NM_ADDIUGP48:
fb32f8c8 21492 check_nms(ctx);
7ef009b2
YK
21493 if (rt != 0) {
21494 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21495 }
21496 break;
21497 case NM_ADDIUPC48:
fb32f8c8 21498 check_nms(ctx);
7ef009b2
YK
21499 if (rt != 0) {
21500 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21501 addr_off);
21502
21503 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21504 }
21505 break;
21506 case NM_LWPC48:
fb32f8c8 21507 check_nms(ctx);
7ef009b2
YK
21508 if (rt != 0) {
21509 TCGv t0;
21510 t0 = tcg_temp_new();
21511
21512 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21513 addr_off);
21514
21515 tcg_gen_movi_tl(t0, addr);
21516 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21517 tcg_temp_free(t0);
21518 }
21519 break;
21520 case NM_SWPC48:
fb32f8c8 21521 check_nms(ctx);
7ef009b2
YK
21522 {
21523 TCGv t0, t1;
21524 t0 = tcg_temp_new();
21525 t1 = tcg_temp_new();
21526
21527 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21528 addr_off);
21529
21530 tcg_gen_movi_tl(t0, addr);
21531 gen_load_gpr(t1, rt);
21532
21533 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21534
21535 tcg_temp_free(t0);
21536 tcg_temp_free(t1);
21537 }
21538 break;
21539 default:
3a4ef3b7 21540 gen_reserved_instruction(ctx);
7ef009b2
YK
21541 break;
21542 }
21543 return 6;
21544 }
c0280983
YK
21545 case NM_P_U12:
21546 switch (extract32(ctx->opcode, 12, 4)) {
21547 case NM_ORI:
21548 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21549 break;
21550 case NM_XORI:
21551 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21552 break;
21553 case NM_ANDI:
21554 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21555 break;
21556 case NM_P_SR:
21557 switch (extract32(ctx->opcode, 20, 1)) {
21558 case NM_PP_SR:
21559 switch (ctx->opcode & 3) {
21560 case NM_SAVE:
21561 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21562 extract32(ctx->opcode, 2, 1),
21563 extract32(ctx->opcode, 3, 9) << 3);
21564 break;
21565 case NM_RESTORE:
21566 case NM_RESTORE_JRC:
21567 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21568 extract32(ctx->opcode, 2, 1),
21569 extract32(ctx->opcode, 3, 9) << 3);
21570 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21571 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21572 }
21573 break;
21574 default:
3a4ef3b7 21575 gen_reserved_instruction(ctx);
c0280983
YK
21576 break;
21577 }
21578 break;
21579 case NM_P_SR_F:
3a4ef3b7 21580 gen_reserved_instruction(ctx);
c0280983
YK
21581 break;
21582 }
21583 break;
21584 case NM_SLTI:
21585 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21586 break;
21587 case NM_SLTIU:
21588 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21589 break;
21590 case NM_SEQI:
21591 {
21592 TCGv t0 = tcg_temp_new();
21593
21594 imm = extract32(ctx->opcode, 0, 12);
21595 gen_load_gpr(t0, rs);
21596 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21597 gen_store_gpr(t0, rt);
21598
21599 tcg_temp_free(t0);
21600 }
21601 break;
21602 case NM_ADDIUNEG:
21603 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21604 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21605 break;
21606 case NM_P_SHIFT:
21607 {
21608 int shift = extract32(ctx->opcode, 0, 5);
21609 switch (extract32(ctx->opcode, 5, 4)) {
21610 case NM_P_SLL:
21611 if (rt == 0 && shift == 0) {
21612 /* NOP */
21613 } else if (rt == 0 && shift == 3) {
21614 /* EHB - treat as NOP */
21615 } else if (rt == 0 && shift == 5) {
21616 /* PAUSE - treat as NOP */
21617 } else if (rt == 0 && shift == 6) {
21618 /* SYNC */
21619 gen_sync(extract32(ctx->opcode, 16, 5));
21620 } else {
21621 /* SLL */
21622 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21623 extract32(ctx->opcode, 0, 5));
21624 }
21625 break;
21626 case NM_SRL:
21627 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21628 extract32(ctx->opcode, 0, 5));
21629 break;
21630 case NM_SRA:
21631 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21632 extract32(ctx->opcode, 0, 5));
21633 break;
21634 case NM_ROTR:
21635 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21636 extract32(ctx->opcode, 0, 5));
21637 break;
21638 }
21639 }
21640 break;
21641 case NM_P_ROTX:
fb32f8c8 21642 check_nms(ctx);
e222f506
MF
21643 if (rt != 0) {
21644 TCGv t0 = tcg_temp_new();
21645 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21646 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21647 << 1);
21648 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21649
21650 gen_load_gpr(t0, rs);
21651 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21652 tcg_temp_free(t0);
21653
21654 tcg_temp_free_i32(shift);
21655 tcg_temp_free_i32(shiftx);
21656 tcg_temp_free_i32(stripe);
21657 }
c0280983
YK
21658 break;
21659 case NM_P_INS:
21660 switch (((ctx->opcode >> 10) & 2) |
21661 (extract32(ctx->opcode, 5, 1))) {
21662 case NM_INS:
fb32f8c8 21663 check_nms(ctx);
c0280983
YK
21664 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21665 extract32(ctx->opcode, 6, 5));
21666 break;
21667 default:
3a4ef3b7 21668 gen_reserved_instruction(ctx);
c0280983
YK
21669 break;
21670 }
21671 break;
21672 case NM_P_EXT:
21673 switch (((ctx->opcode >> 10) & 2) |
21674 (extract32(ctx->opcode, 5, 1))) {
21675 case NM_EXT:
fb32f8c8 21676 check_nms(ctx);
c0280983
YK
21677 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21678 extract32(ctx->opcode, 6, 5));
21679 break;
21680 default:
3a4ef3b7 21681 gen_reserved_instruction(ctx);
c0280983
YK
21682 break;
21683 }
21684 break;
21685 default:
3a4ef3b7 21686 gen_reserved_instruction(ctx);
c0280983
YK
21687 break;
21688 }
21689 break;
21690 case NM_POOL32F:
579b8ea9 21691 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
21692 break;
21693 case NM_POOL32S:
21694 break;
21695 case NM_P_LUI:
21696 switch (extract32(ctx->opcode, 1, 1)) {
21697 case NM_LUI:
21698 if (rt != 0) {
21699 tcg_gen_movi_tl(cpu_gpr[rt],
21700 sextract32(ctx->opcode, 0, 1) << 31 |
21701 extract32(ctx->opcode, 2, 10) << 21 |
21702 extract32(ctx->opcode, 12, 9) << 12);
21703 }
21704 break;
21705 case NM_ALUIPC:
21706 if (rt != 0) {
21707 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21708 extract32(ctx->opcode, 2, 10) << 21 |
21709 extract32(ctx->opcode, 12, 9) << 12;
21710 target_long addr;
21711 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21712 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21713 }
21714 break;
21715 }
21716 break;
21717 case NM_P_GP_BH:
8f1d9b6d
YK
21718 {
21719 uint32_t u = extract32(ctx->opcode, 0, 18);
21720
21721 switch (extract32(ctx->opcode, 18, 3)) {
21722 case NM_LBGP:
21723 gen_ld(ctx, OPC_LB, rt, 28, u);
21724 break;
21725 case NM_SBGP:
21726 gen_st(ctx, OPC_SB, rt, 28, u);
21727 break;
21728 case NM_LBUGP:
21729 gen_ld(ctx, OPC_LBU, rt, 28, u);
21730 break;
21731 case NM_ADDIUGP_B:
21732 if (rt != 0) {
21733 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21734 }
21735 break;
21736 case NM_P_GP_LH:
21737 u &= ~1;
21738 switch (ctx->opcode & 1) {
21739 case NM_LHGP:
21740 gen_ld(ctx, OPC_LH, rt, 28, u);
21741 break;
21742 case NM_LHUGP:
21743 gen_ld(ctx, OPC_LHU, rt, 28, u);
21744 break;
21745 }
21746 break;
21747 case NM_P_GP_SH:
21748 u &= ~1;
21749 switch (ctx->opcode & 1) {
21750 case NM_SHGP:
21751 gen_st(ctx, OPC_SH, rt, 28, u);
21752 break;
21753 default:
3a4ef3b7 21754 gen_reserved_instruction(ctx);
8f1d9b6d
YK
21755 break;
21756 }
21757 break;
21758 case NM_P_GP_CP1:
21759 u &= ~0x3;
21760 switch (ctx->opcode & 0x3) {
21761 case NM_LWC1GP:
21762 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21763 break;
21764 case NM_LDC1GP:
21765 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21766 break;
21767 case NM_SWC1GP:
21768 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21769 break;
21770 case NM_SDC1GP:
21771 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21772 break;
21773 }
21774 break;
21775 default:
3a4ef3b7 21776 gen_reserved_instruction(ctx);
8f1d9b6d
YK
21777 break;
21778 }
21779 }
c0280983
YK
21780 break;
21781 case NM_P_LS_U12:
8f1d9b6d
YK
21782 {
21783 uint32_t u = extract32(ctx->opcode, 0, 12);
21784
21785 switch (extract32(ctx->opcode, 12, 4)) {
21786 case NM_P_PREFU12:
21787 if (rt == 31) {
21788 /* SYNCI */
7480515f
AM
21789 /*
21790 * Break the TB to be able to sync copied instructions
21791 * immediately.
21792 */
8f1d9b6d
YK
21793 ctx->base.is_jmp = DISAS_STOP;
21794 } else {
21795 /* PREF */
21796 /* Treat as NOP. */
21797 }
21798 break;
21799 case NM_LB:
21800 gen_ld(ctx, OPC_LB, rt, rs, u);
21801 break;
21802 case NM_LH:
21803 gen_ld(ctx, OPC_LH, rt, rs, u);
21804 break;
21805 case NM_LW:
21806 gen_ld(ctx, OPC_LW, rt, rs, u);
21807 break;
21808 case NM_LBU:
21809 gen_ld(ctx, OPC_LBU, rt, rs, u);
21810 break;
21811 case NM_LHU:
21812 gen_ld(ctx, OPC_LHU, rt, rs, u);
21813 break;
21814 case NM_SB:
21815 gen_st(ctx, OPC_SB, rt, rs, u);
21816 break;
21817 case NM_SH:
21818 gen_st(ctx, OPC_SH, rt, rs, u);
21819 break;
21820 case NM_SW:
21821 gen_st(ctx, OPC_SW, rt, rs, u);
21822 break;
21823 case NM_LWC1:
21824 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21825 break;
21826 case NM_LDC1:
21827 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21828 break;
21829 case NM_SWC1:
21830 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21831 break;
21832 case NM_SDC1:
21833 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21834 break;
21835 default:
3a4ef3b7 21836 gen_reserved_instruction(ctx);
8f1d9b6d
YK
21837 break;
21838 }
21839 }
c0280983
YK
21840 break;
21841 case NM_P_LS_S9:
8f1d9b6d
YK
21842 {
21843 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21844 extract32(ctx->opcode, 0, 8);
21845
21846 switch (extract32(ctx->opcode, 8, 3)) {
21847 case NM_P_LS_S0:
21848 switch (extract32(ctx->opcode, 11, 4)) {
21849 case NM_LBS9:
21850 gen_ld(ctx, OPC_LB, rt, rs, s);
21851 break;
21852 case NM_LHS9:
21853 gen_ld(ctx, OPC_LH, rt, rs, s);
21854 break;
21855 case NM_LWS9:
21856 gen_ld(ctx, OPC_LW, rt, rs, s);
21857 break;
21858 case NM_LBUS9:
21859 gen_ld(ctx, OPC_LBU, rt, rs, s);
21860 break;
21861 case NM_LHUS9:
21862 gen_ld(ctx, OPC_LHU, rt, rs, s);
21863 break;
21864 case NM_SBS9:
21865 gen_st(ctx, OPC_SB, rt, rs, s);
21866 break;
21867 case NM_SHS9:
21868 gen_st(ctx, OPC_SH, rt, rs, s);
21869 break;
21870 case NM_SWS9:
21871 gen_st(ctx, OPC_SW, rt, rs, s);
21872 break;
21873 case NM_LWC1S9:
21874 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21875 break;
21876 case NM_LDC1S9:
21877 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21878 break;
21879 case NM_SWC1S9:
21880 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21881 break;
21882 case NM_SDC1S9:
21883 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21884 break;
21885 case NM_P_PREFS9:
21886 if (rt == 31) {
21887 /* SYNCI */
7480515f
AM
21888 /*
21889 * Break the TB to be able to sync copied instructions
21890 * immediately.
21891 */
8f1d9b6d
YK
21892 ctx->base.is_jmp = DISAS_STOP;
21893 } else {
21894 /* PREF */
21895 /* Treat as NOP. */
21896 }
21897 break;
21898 default:
3a4ef3b7 21899 gen_reserved_instruction(ctx);
8f1d9b6d
YK
21900 break;
21901 }
21902 break;
21903 case NM_P_LS_S1:
21904 switch (extract32(ctx->opcode, 11, 4)) {
21905 case NM_UALH:
21906 case NM_UASH:
fb32f8c8 21907 check_nms(ctx);
8f1d9b6d
YK
21908 {
21909 TCGv t0 = tcg_temp_new();
21910 TCGv t1 = tcg_temp_new();
21911
21912 gen_base_offset_addr(ctx, t0, rs, s);
21913
21914 switch (extract32(ctx->opcode, 11, 4)) {
21915 case NM_UALH:
21916 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21917 MO_UNALN);
21918 gen_store_gpr(t0, rt);
21919 break;
21920 case NM_UASH:
21921 gen_load_gpr(t1, rt);
21922 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21923 MO_UNALN);
21924 break;
21925 }
21926 tcg_temp_free(t0);
21927 tcg_temp_free(t1);
21928 }
21929 break;
21930 case NM_P_LL:
21931 switch (ctx->opcode & 0x03) {
21932 case NM_LL:
21933 gen_ld(ctx, OPC_LL, rt, rs, s);
21934 break;
21935 case NM_LLWP:
0b16dcd1
AR
21936 check_xnp(ctx);
21937 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21938 break;
21939 }
21940 break;
21941 case NM_P_SC:
21942 switch (ctx->opcode & 0x03) {
21943 case NM_SC:
33a07fa2 21944 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
8f1d9b6d
YK
21945 break;
21946 case NM_SCWP:
0b16dcd1 21947 check_xnp(ctx);
8d5388c1
AM
21948 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21949 false);
8f1d9b6d
YK
21950 break;
21951 }
21952 break;
21953 case NM_CACHE:
21954 check_cp0_enabled(ctx);
21955 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21956 gen_cache_operation(ctx, rt, rs, s);
21957 }
21958 break;
21959 }
21960 break;
d046a9ea
DN
21961 case NM_P_LS_E0:
21962 switch (extract32(ctx->opcode, 11, 4)) {
21963 case NM_LBE:
21964 check_eva(ctx);
21965 check_cp0_enabled(ctx);
21966 gen_ld(ctx, OPC_LBE, rt, rs, s);
21967 break;
21968 case NM_SBE:
21969 check_eva(ctx);
21970 check_cp0_enabled(ctx);
21971 gen_st(ctx, OPC_SBE, rt, rs, s);
21972 break;
21973 case NM_LBUE:
21974 check_eva(ctx);
21975 check_cp0_enabled(ctx);
21976 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21977 break;
21978 case NM_P_PREFE:
21979 if (rt == 31) {
21980 /* case NM_SYNCIE */
21981 check_eva(ctx);
21982 check_cp0_enabled(ctx);
7480515f
AM
21983 /*
21984 * Break the TB to be able to sync copied instructions
21985 * immediately.
21986 */
d046a9ea
DN
21987 ctx->base.is_jmp = DISAS_STOP;
21988 } else {
21989 /* case NM_PREFE */
21990 check_eva(ctx);
21991 check_cp0_enabled(ctx);
21992 /* Treat as NOP. */
21993 }
21994 break;
21995 case NM_LHE:
21996 check_eva(ctx);
21997 check_cp0_enabled(ctx);
21998 gen_ld(ctx, OPC_LHE, rt, rs, s);
21999 break;
22000 case NM_SHE:
22001 check_eva(ctx);
22002 check_cp0_enabled(ctx);
22003 gen_st(ctx, OPC_SHE, rt, rs, s);
22004 break;
22005 case NM_LHUE:
22006 check_eva(ctx);
22007 check_cp0_enabled(ctx);
22008 gen_ld(ctx, OPC_LHUE, rt, rs, s);
22009 break;
22010 case NM_CACHEE:
22011 check_nms_dl_il_sl_tl_l2c(ctx);
22012 gen_cache_operation(ctx, rt, rs, s);
22013 break;
22014 case NM_LWE:
22015 check_eva(ctx);
22016 check_cp0_enabled(ctx);
22017 gen_ld(ctx, OPC_LWE, rt, rs, s);
22018 break;
22019 case NM_SWE:
22020 check_eva(ctx);
22021 check_cp0_enabled(ctx);
22022 gen_st(ctx, OPC_SWE, rt, rs, s);
22023 break;
22024 case NM_P_LLE:
22025 switch (extract32(ctx->opcode, 2, 2)) {
22026 case NM_LLE:
22027 check_xnp(ctx);
22028 check_eva(ctx);
22029 check_cp0_enabled(ctx);
22030 gen_ld(ctx, OPC_LLE, rt, rs, s);
22031 break;
22032 case NM_LLWPE:
22033 check_xnp(ctx);
22034 check_eva(ctx);
22035 check_cp0_enabled(ctx);
22036 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 22037 break;
d046a9ea 22038 default:
3a4ef3b7 22039 gen_reserved_instruction(ctx);
d046a9ea
DN
22040 break;
22041 }
22042 break;
22043 case NM_P_SCE:
22044 switch (extract32(ctx->opcode, 2, 2)) {
22045 case NM_SCE:
22046 check_xnp(ctx);
22047 check_eva(ctx);
22048 check_cp0_enabled(ctx);
33a07fa2 22049 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
d046a9ea
DN
22050 break;
22051 case NM_SCWPE:
22052 check_xnp(ctx);
22053 check_eva(ctx);
22054 check_cp0_enabled(ctx);
8d5388c1
AM
22055 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
22056 true);
2431a422 22057 break;
d046a9ea 22058 default:
3a4ef3b7 22059 gen_reserved_instruction(ctx);
d046a9ea
DN
22060 break;
22061 }
22062 break;
22063 }
22064 break;
8f1d9b6d
YK
22065 case NM_P_LS_WM:
22066 case NM_P_LS_UAWM:
fb32f8c8 22067 check_nms(ctx);
8f1d9b6d
YK
22068 {
22069 int count = extract32(ctx->opcode, 12, 3);
22070 int counter = 0;
22071
22072 offset = sextract32(ctx->opcode, 15, 1) << 8 |
22073 extract32(ctx->opcode, 0, 8);
22074 TCGv va = tcg_temp_new();
22075 TCGv t1 = tcg_temp_new();
14776ab5 22076 MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
8f1d9b6d
YK
22077 NM_P_LS_UAWM ? MO_UNALN : 0;
22078
22079 count = (count == 0) ? 8 : count;
22080 while (counter != count) {
22081 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
22082 int this_offset = offset + (counter << 2);
22083
22084 gen_base_offset_addr(ctx, va, rs, this_offset);
22085
22086 switch (extract32(ctx->opcode, 11, 1)) {
22087 case NM_LWM:
22088 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
22089 memop | MO_TESL);
22090 gen_store_gpr(t1, this_rt);
22091 if ((this_rt == rs) &&
22092 (counter != (count - 1))) {
22093 /* UNPREDICTABLE */
22094 }
22095 break;
22096 case NM_SWM:
22097 this_rt = (rt == 0) ? 0 : this_rt;
22098 gen_load_gpr(t1, this_rt);
22099 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
22100 memop | MO_TEUL);
22101 break;
22102 }
22103 counter++;
22104 }
22105 tcg_temp_free(va);
22106 tcg_temp_free(t1);
22107 }
22108 break;
22109 default:
3a4ef3b7 22110 gen_reserved_instruction(ctx);
8f1d9b6d
YK
22111 break;
22112 }
22113 }
c0280983
YK
22114 break;
22115 case NM_MOVE_BALC:
fb32f8c8 22116 check_nms(ctx);
11d0fc10
SM
22117 {
22118 TCGv t0 = tcg_temp_new();
22119 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
22120 extract32(ctx->opcode, 1, 20) << 1;
22121 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
22122 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
22123 extract32(ctx->opcode, 21, 3));
22124 gen_load_gpr(t0, rt);
22125 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22126 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22127 tcg_temp_free(t0);
22128 }
c0280983
YK
22129 break;
22130 case NM_P_BAL:
11d0fc10
SM
22131 {
22132 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
22133 extract32(ctx->opcode, 1, 24) << 1;
22134
22135 if ((extract32(ctx->opcode, 25, 1)) == 0) {
22136 /* BC */
22137 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
22138 } else {
22139 /* BALC */
22140 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22141 }
22142 }
c0280983
YK
22143 break;
22144 case NM_P_J:
11d0fc10
SM
22145 switch (extract32(ctx->opcode, 12, 4)) {
22146 case NM_JALRC:
22147 case NM_JALRC_HB:
22148 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
22149 break;
22150 case NM_P_BALRSC:
22151 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
22152 break;
22153 default:
3a4ef3b7 22154 gen_reserved_instruction(ctx);
11d0fc10
SM
22155 break;
22156 }
c0280983
YK
22157 break;
22158 case NM_P_BR1:
11d0fc10
SM
22159 {
22160 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22161 extract32(ctx->opcode, 1, 13) << 1;
22162 switch (extract32(ctx->opcode, 14, 2)) {
22163 case NM_BEQC:
fb32f8c8 22164 check_nms(ctx);
11d0fc10
SM
22165 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
22166 break;
22167 case NM_P_BR3A:
22168 s = sextract32(ctx->opcode, 0, 1) << 14 |
22169 extract32(ctx->opcode, 1, 13) << 1;
22170 check_cp1_enabled(ctx);
22171 switch (extract32(ctx->opcode, 16, 5)) {
22172 case NM_BC1EQZC:
22173 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
22174 break;
22175 case NM_BC1NEZC:
22176 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
22177 break;
6d033ca7 22178 case NM_BPOSGE32C:
908f6be1 22179 check_dsp_r3(ctx);
6d033ca7
SM
22180 {
22181 int32_t imm = extract32(ctx->opcode, 1, 13) |
22182 extract32(ctx->opcode, 0, 1) << 13;
22183
22184 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
22185 imm);
22186 }
22187 break;
11d0fc10 22188 default:
3a4ef3b7 22189 gen_reserved_instruction(ctx);
11d0fc10
SM
22190 break;
22191 }
22192 break;
22193 case NM_BGEC:
22194 if (rs == rt) {
22195 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
22196 } else {
22197 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
22198 }
22199 break;
22200 case NM_BGEUC:
22201 if (rs == rt || rt == 0) {
22202 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
22203 } else if (rs == 0) {
22204 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
22205 } else {
22206 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
22207 }
22208 break;
22209 }
22210 }
c0280983
YK
22211 break;
22212 case NM_P_BR2:
11d0fc10
SM
22213 {
22214 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22215 extract32(ctx->opcode, 1, 13) << 1;
22216 switch (extract32(ctx->opcode, 14, 2)) {
22217 case NM_BNEC:
fb32f8c8 22218 check_nms(ctx);
11d0fc10
SM
22219 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
22220 break;
22221 case NM_BLTC:
22222 if (rs != 0 && rt != 0 && rs == rt) {
22223 /* NOP */
22224 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22225 } else {
22226 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
22227 }
22228 break;
22229 case NM_BLTUC:
22230 if (rs == 0 || rs == rt) {
22231 /* NOP */
22232 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22233 } else {
22234 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
22235 }
22236 break;
22237 default:
3a4ef3b7 22238 gen_reserved_instruction(ctx);
11d0fc10
SM
22239 break;
22240 }
22241 }
c0280983
YK
22242 break;
22243 case NM_P_BRI:
11d0fc10
SM
22244 {
22245 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22246 extract32(ctx->opcode, 1, 10) << 1;
22247 uint32_t u = extract32(ctx->opcode, 11, 7);
22248
22249 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22250 rt, u, s);
22251 }
c0280983
YK
22252 break;
22253 default:
3a4ef3b7 22254 gen_reserved_instruction(ctx);
c0280983
YK
22255 break;
22256 }
22257 return 4;
22258}
22259
c533c0f4
AM
22260static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22261{
ea4ca3c2 22262 uint32_t op;
99e49abf
AM
22263 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22264 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22265 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
8bdb7029 22266 int offset;
ea4ca3c2
YK
22267 int imm;
22268
22269 /* make sure instructions are on a halfword boundary */
22270 if (ctx->base.pc_next & 0x1) {
22271 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22272 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22273 tcg_temp_free(tmp);
22274 generate_exception_end(ctx, EXCP_AdEL);
22275 return 2;
22276 }
22277
22278 op = extract32(ctx->opcode, 10, 6);
22279 switch (op) {
22280 case NM_P16_MV:
8869ad02
YK
22281 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22282 if (rt != 0) {
22283 /* MOVE */
22284 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22285 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22286 } else {
22287 /* P16.RI */
22288 switch (extract32(ctx->opcode, 3, 2)) {
22289 case NM_P16_SYSCALL:
22290 if (extract32(ctx->opcode, 2, 1) == 0) {
22291 generate_exception_end(ctx, EXCP_SYSCALL);
22292 } else {
3a4ef3b7 22293 gen_reserved_instruction(ctx);
8869ad02
YK
22294 }
22295 break;
22296 case NM_BREAK16:
22297 generate_exception_end(ctx, EXCP_BREAK);
22298 break;
22299 case NM_SDBBP16:
22300 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22301 gen_helper_do_semihosting(cpu_env);
22302 } else {
22303 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 22304 gen_reserved_instruction(ctx);
8869ad02
YK
22305 } else {
22306 generate_exception_end(ctx, EXCP_DBp);
22307 }
22308 }
22309 break;
22310 default:
3a4ef3b7 22311 gen_reserved_instruction(ctx);
8869ad02
YK
22312 break;
22313 }
22314 }
ea4ca3c2
YK
22315 break;
22316 case NM_P16_SHIFT:
c46562fb
YK
22317 {
22318 int shift = extract32(ctx->opcode, 0, 3);
22319 uint32_t opc = 0;
22320 shift = (shift == 0) ? 8 : shift;
22321
22322 switch (extract32(ctx->opcode, 3, 1)) {
22323 case NM_SLL16:
22324 opc = OPC_SLL;
22325 break;
22326 case NM_SRL16:
22327 opc = OPC_SRL;
22328 break;
22329 }
22330 gen_shift_imm(ctx, opc, rt, rs, shift);
22331 }
ea4ca3c2
YK
22332 break;
22333 case NM_P16C:
8bdb7029
YK
22334 switch (ctx->opcode & 1) {
22335 case NM_POOL16C_0:
80845edf 22336 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
22337 break;
22338 case NM_LWXS16:
22339 gen_ldxs(ctx, rt, rs, rd);
22340 break;
22341 }
ea4ca3c2
YK
22342 break;
22343 case NM_P16_A1:
22344 switch (extract32(ctx->opcode, 6, 1)) {
22345 case NM_ADDIUR1SP:
22346 imm = extract32(ctx->opcode, 0, 6) << 2;
22347 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22348 break;
22349 default:
3a4ef3b7 22350 gen_reserved_instruction(ctx);
ea4ca3c2
YK
22351 break;
22352 }
22353 break;
22354 case NM_P16_A2:
22355 switch (extract32(ctx->opcode, 3, 1)) {
22356 case NM_ADDIUR2:
22357 imm = extract32(ctx->opcode, 0, 3) << 2;
22358 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22359 break;
22360 case NM_P_ADDIURS5:
22361 rt = extract32(ctx->opcode, 5, 5);
22362 if (rt != 0) {
22363 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22364 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22365 (extract32(ctx->opcode, 0, 3));
22366 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22367 }
22368 break;
22369 }
22370 break;
22371 case NM_P16_ADDU:
22372 switch (ctx->opcode & 0x1) {
22373 case NM_ADDU16:
22374 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22375 break;
22376 case NM_SUBU16:
22377 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22378 break;
22379 }
22380 break;
22381 case NM_P16_4X4:
22382 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22383 extract32(ctx->opcode, 5, 3);
22384 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22385 extract32(ctx->opcode, 0, 3);
22386 rt = decode_gpr_gpr4(rt);
22387 rs = decode_gpr_gpr4(rs);
22388 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22389 (extract32(ctx->opcode, 3, 1))) {
22390 case NM_ADDU4X4:
fb32f8c8 22391 check_nms(ctx);
ea4ca3c2
YK
22392 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22393 break;
22394 case NM_MUL4X4:
fb32f8c8 22395 check_nms(ctx);
ea4ca3c2
YK
22396 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22397 break;
22398 default:
3a4ef3b7 22399 gen_reserved_instruction(ctx);
ea4ca3c2
YK
22400 break;
22401 }
22402 break;
22403 case NM_LI16:
8869ad02
YK
22404 {
22405 int imm = extract32(ctx->opcode, 0, 7);
22406 imm = (imm == 0x7f ? -1 : imm);
22407 if (rt != 0) {
22408 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22409 }
22410 }
ea4ca3c2
YK
22411 break;
22412 case NM_ANDI16:
80845edf
YK
22413 {
22414 uint32_t u = extract32(ctx->opcode, 0, 4);
22415 u = (u == 12) ? 0xff :
22416 (u == 13) ? 0xffff : u;
22417 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22418 }
ea4ca3c2
YK
22419 break;
22420 case NM_P16_LB:
8bdb7029
YK
22421 offset = extract32(ctx->opcode, 0, 2);
22422 switch (extract32(ctx->opcode, 2, 2)) {
22423 case NM_LB16:
22424 gen_ld(ctx, OPC_LB, rt, rs, offset);
22425 break;
22426 case NM_SB16:
22427 rt = decode_gpr_gpr3_src_store(
99e49abf 22428 NANOMIPS_EXTRACT_RT3(ctx->opcode));
8bdb7029
YK
22429 gen_st(ctx, OPC_SB, rt, rs, offset);
22430 break;
22431 case NM_LBU16:
22432 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22433 break;
22434 default:
3a4ef3b7 22435 gen_reserved_instruction(ctx);
8bdb7029
YK
22436 break;
22437 }
ea4ca3c2
YK
22438 break;
22439 case NM_P16_LH:
8bdb7029
YK
22440 offset = extract32(ctx->opcode, 1, 2) << 1;
22441 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22442 case NM_LH16:
22443 gen_ld(ctx, OPC_LH, rt, rs, offset);
22444 break;
22445 case NM_SH16:
22446 rt = decode_gpr_gpr3_src_store(
99e49abf 22447 NANOMIPS_EXTRACT_RT3(ctx->opcode));
8bdb7029
YK
22448 gen_st(ctx, OPC_SH, rt, rs, offset);
22449 break;
22450 case NM_LHU16:
22451 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22452 break;
22453 default:
3a4ef3b7 22454 gen_reserved_instruction(ctx);
8bdb7029
YK
22455 break;
22456 }
ea4ca3c2
YK
22457 break;
22458 case NM_LW16:
8bdb7029
YK
22459 offset = extract32(ctx->opcode, 0, 4) << 2;
22460 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
22461 break;
22462 case NM_LWSP16:
8bdb7029
YK
22463 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22464 offset = extract32(ctx->opcode, 0, 5) << 2;
22465 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
22466 break;
22467 case NM_LW4X4:
fb32f8c8 22468 check_nms(ctx);
8bdb7029
YK
22469 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22470 extract32(ctx->opcode, 5, 3);
22471 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22472 extract32(ctx->opcode, 0, 3);
22473 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22474 (extract32(ctx->opcode, 8, 1) << 2);
22475 rt = decode_gpr_gpr4(rt);
22476 rs = decode_gpr_gpr4(rs);
22477 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
22478 break;
22479 case NM_SW4X4:
fb32f8c8 22480 check_nms(ctx);
8bdb7029
YK
22481 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22482 extract32(ctx->opcode, 5, 3);
22483 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22484 extract32(ctx->opcode, 0, 3);
22485 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22486 (extract32(ctx->opcode, 8, 1) << 2);
22487 rt = decode_gpr_gpr4_zero(rt);
22488 rs = decode_gpr_gpr4(rs);
22489 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
22490 break;
22491 case NM_LWGP16:
8bdb7029
YK
22492 offset = extract32(ctx->opcode, 0, 7) << 2;
22493 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
22494 break;
22495 case NM_SWSP16:
8bdb7029
YK
22496 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22497 offset = extract32(ctx->opcode, 0, 5) << 2;
22498 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
22499 break;
22500 case NM_SW16:
8bdb7029 22501 rt = decode_gpr_gpr3_src_store(
99e49abf
AM
22502 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22503 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
8bdb7029
YK
22504 offset = extract32(ctx->opcode, 0, 4) << 2;
22505 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
22506 break;
22507 case NM_SWGP16:
8bdb7029 22508 rt = decode_gpr_gpr3_src_store(
99e49abf 22509 NANOMIPS_EXTRACT_RT3(ctx->opcode));
8bdb7029
YK
22510 offset = extract32(ctx->opcode, 0, 7) << 2;
22511 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
22512 break;
22513 case NM_BC16:
764371d2
SM
22514 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22515 (sextract32(ctx->opcode, 0, 1) << 10) |
22516 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
22517 break;
22518 case NM_BALC16:
764371d2
SM
22519 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22520 (sextract32(ctx->opcode, 0, 1) << 10) |
22521 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
22522 break;
22523 case NM_BEQZC16:
764371d2
SM
22524 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22525 (sextract32(ctx->opcode, 0, 1) << 7) |
22526 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
22527 break;
22528 case NM_BNEZC16:
764371d2
SM
22529 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22530 (sextract32(ctx->opcode, 0, 1) << 7) |
22531 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
22532 break;
22533 case NM_P16_BR:
764371d2
SM
22534 switch (ctx->opcode & 0xf) {
22535 case 0:
22536 /* P16.JRC */
22537 switch (extract32(ctx->opcode, 4, 1)) {
22538 case NM_JRC:
22539 gen_compute_branch_nm(ctx, OPC_JR, 2,
22540 extract32(ctx->opcode, 5, 5), 0, 0);
22541 break;
22542 case NM_JALRC16:
22543 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22544 extract32(ctx->opcode, 5, 5), 31, 0);
22545 break;
22546 }
22547 break;
22548 default:
22549 {
22550 /* P16.BRI */
22551 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22552 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22553 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22554 extract32(ctx->opcode, 0, 4) << 1);
22555 }
22556 break;
22557 }
ea4ca3c2
YK
22558 break;
22559 case NM_P16_SR:
bf0718c5
SM
22560 {
22561 int count = extract32(ctx->opcode, 0, 4);
22562 int u = extract32(ctx->opcode, 4, 4) << 4;
22563
22564 rt = 30 + extract32(ctx->opcode, 9, 1);
22565 switch (extract32(ctx->opcode, 8, 1)) {
22566 case NM_SAVE16:
22567 gen_save(ctx, rt, count, 0, u);
22568 break;
22569 case NM_RESTORE_JRC16:
22570 gen_restore(ctx, rt, count, 0, u);
22571 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22572 break;
22573 }
22574 }
ea4ca3c2
YK
22575 break;
22576 case NM_MOVEP:
ea4ca3c2 22577 case NM_MOVEPREV:
fb32f8c8 22578 check_nms(ctx);
4d18232c
YK
22579 {
22580 static const int gpr2reg1[] = {4, 5, 6, 7};
22581 static const int gpr2reg2[] = {5, 6, 7, 8};
22582 int re;
22583 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22584 extract32(ctx->opcode, 8, 1);
22585 int r1 = gpr2reg1[rd2];
22586 int r2 = gpr2reg2[rd2];
22587 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22588 extract32(ctx->opcode, 0, 3);
22589 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22590 extract32(ctx->opcode, 5, 3);
22591 TCGv t0 = tcg_temp_new();
22592 TCGv t1 = tcg_temp_new();
22593 if (op == NM_MOVEP) {
22594 rd = r1;
22595 re = r2;
22596 rs = decode_gpr_gpr4_zero(r3);
22597 rt = decode_gpr_gpr4_zero(r4);
22598 } else {
22599 rd = decode_gpr_gpr4(r3);
22600 re = decode_gpr_gpr4(r4);
22601 rs = r1;
22602 rt = r2;
22603 }
22604 gen_load_gpr(t0, rs);
22605 gen_load_gpr(t1, rt);
22606 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22607 tcg_gen_mov_tl(cpu_gpr[re], t1);
22608 tcg_temp_free(t0);
22609 tcg_temp_free(t1);
22610 }
ea4ca3c2
YK
22611 break;
22612 default:
c0280983 22613 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
22614 }
22615
c533c0f4
AM
22616 return 2;
22617}
22618
22619
3c824109
NF
22620/* SmartMIPS extension to MIPS32 */
22621
22622#if defined(TARGET_MIPS64)
22623
22624/* MDMX extension to MIPS64 */
22625
22626#endif
22627
9b1a1d68 22628/* MIPSDSP functions. */
d75c135e 22629static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
22630 int rd, int base, int offset)
22631{
9b1a1d68
JL
22632 TCGv t0;
22633
9b1a1d68
JL
22634 check_dsp(ctx);
22635 t0 = tcg_temp_new();
22636
22637 if (base == 0) {
22638 gen_load_gpr(t0, offset);
22639 } else if (offset == 0) {
22640 gen_load_gpr(t0, base);
22641 } else {
22642 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22643 }
22644
9b1a1d68
JL
22645 switch (opc) {
22646 case OPC_LBUX:
5f68f5ae 22647 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 22648 gen_store_gpr(t0, rd);
9b1a1d68
JL
22649 break;
22650 case OPC_LHX:
5f68f5ae 22651 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 22652 gen_store_gpr(t0, rd);
9b1a1d68
JL
22653 break;
22654 case OPC_LWX:
5f68f5ae 22655 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 22656 gen_store_gpr(t0, rd);
9b1a1d68
JL
22657 break;
22658#if defined(TARGET_MIPS64)
22659 case OPC_LDX:
5f68f5ae 22660 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 22661 gen_store_gpr(t0, rd);
9b1a1d68
JL
22662 break;
22663#endif
22664 }
9b1a1d68
JL
22665 tcg_temp_free(t0);
22666}
22667
461c08df
JL
22668static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22669 int ret, int v1, int v2)
22670{
461c08df
JL
22671 TCGv v1_t;
22672 TCGv v2_t;
22673
22674 if (ret == 0) {
22675 /* Treat as NOP. */
461c08df
JL
22676 return;
22677 }
22678
22679 v1_t = tcg_temp_new();
22680 v2_t = tcg_temp_new();
22681
22682 gen_load_gpr(v1_t, v1);
22683 gen_load_gpr(v2_t, v2);
22684
22685 switch (op1) {
22686 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22687 case OPC_MULT_G_2E:
908f6be1 22688 check_dsp_r2(ctx);
461c08df
JL
22689 switch (op2) {
22690 case OPC_ADDUH_QB:
22691 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22692 break;
22693 case OPC_ADDUH_R_QB:
22694 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22695 break;
22696 case OPC_ADDQH_PH:
22697 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22698 break;
22699 case OPC_ADDQH_R_PH:
22700 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22701 break;
22702 case OPC_ADDQH_W:
22703 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22704 break;
22705 case OPC_ADDQH_R_W:
22706 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22707 break;
22708 case OPC_SUBUH_QB:
22709 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22710 break;
22711 case OPC_SUBUH_R_QB:
22712 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22713 break;
22714 case OPC_SUBQH_PH:
22715 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22716 break;
22717 case OPC_SUBQH_R_PH:
22718 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22719 break;
22720 case OPC_SUBQH_W:
22721 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22722 break;
22723 case OPC_SUBQH_R_W:
22724 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22725 break;
22726 }
22727 break;
22728 case OPC_ABSQ_S_PH_DSP:
22729 switch (op2) {
22730 case OPC_ABSQ_S_QB:
908f6be1 22731 check_dsp_r2(ctx);
461c08df
JL
22732 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22733 break;
22734 case OPC_ABSQ_S_PH:
22735 check_dsp(ctx);
22736 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22737 break;
22738 case OPC_ABSQ_S_W:
22739 check_dsp(ctx);
22740 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22741 break;
22742 case OPC_PRECEQ_W_PHL:
22743 check_dsp(ctx);
22744 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22746 break;
22747 case OPC_PRECEQ_W_PHR:
22748 check_dsp(ctx);
22749 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22750 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22751 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22752 break;
22753 case OPC_PRECEQU_PH_QBL:
22754 check_dsp(ctx);
22755 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22756 break;
22757 case OPC_PRECEQU_PH_QBR:
22758 check_dsp(ctx);
22759 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22760 break;
22761 case OPC_PRECEQU_PH_QBLA:
22762 check_dsp(ctx);
22763 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22764 break;
22765 case OPC_PRECEQU_PH_QBRA:
22766 check_dsp(ctx);
22767 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22768 break;
22769 case OPC_PRECEU_PH_QBL:
22770 check_dsp(ctx);
22771 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22772 break;
22773 case OPC_PRECEU_PH_QBR:
22774 check_dsp(ctx);
22775 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22776 break;
22777 case OPC_PRECEU_PH_QBLA:
22778 check_dsp(ctx);
22779 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22780 break;
22781 case OPC_PRECEU_PH_QBRA:
22782 check_dsp(ctx);
22783 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22784 break;
22785 }
22786 break;
22787 case OPC_ADDU_QB_DSP:
22788 switch (op2) {
22789 case OPC_ADDQ_PH:
22790 check_dsp(ctx);
22791 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22792 break;
22793 case OPC_ADDQ_S_PH:
22794 check_dsp(ctx);
22795 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22796 break;
22797 case OPC_ADDQ_S_W:
22798 check_dsp(ctx);
22799 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22800 break;
22801 case OPC_ADDU_QB:
22802 check_dsp(ctx);
22803 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22804 break;
22805 case OPC_ADDU_S_QB:
22806 check_dsp(ctx);
22807 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22808 break;
22809 case OPC_ADDU_PH:
908f6be1 22810 check_dsp_r2(ctx);
461c08df
JL
22811 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22812 break;
22813 case OPC_ADDU_S_PH:
908f6be1 22814 check_dsp_r2(ctx);
461c08df
JL
22815 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22816 break;
22817 case OPC_SUBQ_PH:
22818 check_dsp(ctx);
22819 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22820 break;
22821 case OPC_SUBQ_S_PH:
22822 check_dsp(ctx);
22823 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22824 break;
22825 case OPC_SUBQ_S_W:
22826 check_dsp(ctx);
22827 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22828 break;
22829 case OPC_SUBU_QB:
22830 check_dsp(ctx);
22831 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22832 break;
22833 case OPC_SUBU_S_QB:
22834 check_dsp(ctx);
22835 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22836 break;
22837 case OPC_SUBU_PH:
908f6be1 22838 check_dsp_r2(ctx);
461c08df
JL
22839 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22840 break;
22841 case OPC_SUBU_S_PH:
908f6be1 22842 check_dsp_r2(ctx);
461c08df
JL
22843 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22844 break;
22845 case OPC_ADDSC:
22846 check_dsp(ctx);
22847 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22848 break;
22849 case OPC_ADDWC:
22850 check_dsp(ctx);
22851 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22852 break;
22853 case OPC_MODSUB:
22854 check_dsp(ctx);
22855 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22856 break;
22857 case OPC_RADDU_W_QB:
22858 check_dsp(ctx);
22859 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22860 break;
22861 }
22862 break;
22863 case OPC_CMPU_EQ_QB_DSP:
22864 switch (op2) {
22865 case OPC_PRECR_QB_PH:
908f6be1 22866 check_dsp_r2(ctx);
461c08df
JL
22867 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22868 break;
22869 case OPC_PRECRQ_QB_PH:
22870 check_dsp(ctx);
22871 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22872 break;
22873 case OPC_PRECR_SRA_PH_W:
908f6be1 22874 check_dsp_r2(ctx);
461c08df
JL
22875 {
22876 TCGv_i32 sa_t = tcg_const_i32(v2);
22877 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22878 cpu_gpr[ret]);
22879 tcg_temp_free_i32(sa_t);
22880 break;
22881 }
22882 case OPC_PRECR_SRA_R_PH_W:
908f6be1 22883 check_dsp_r2(ctx);
461c08df
JL
22884 {
22885 TCGv_i32 sa_t = tcg_const_i32(v2);
22886 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22887 cpu_gpr[ret]);
22888 tcg_temp_free_i32(sa_t);
22889 break;
22890 }
22891 case OPC_PRECRQ_PH_W:
22892 check_dsp(ctx);
22893 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22894 break;
22895 case OPC_PRECRQ_RS_PH_W:
22896 check_dsp(ctx);
22897 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22898 break;
22899 case OPC_PRECRQU_S_QB_PH:
22900 check_dsp(ctx);
22901 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22902 break;
22903 }
22904 break;
22905#ifdef TARGET_MIPS64
22906 case OPC_ABSQ_S_QH_DSP:
22907 switch (op2) {
22908 case OPC_PRECEQ_L_PWL:
22909 check_dsp(ctx);
22910 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22911 break;
22912 case OPC_PRECEQ_L_PWR:
22913 check_dsp(ctx);
22914 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22915 break;
22916 case OPC_PRECEQ_PW_QHL:
22917 check_dsp(ctx);
22918 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22919 break;
22920 case OPC_PRECEQ_PW_QHR:
22921 check_dsp(ctx);
22922 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22923 break;
22924 case OPC_PRECEQ_PW_QHLA:
22925 check_dsp(ctx);
22926 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22927 break;
22928 case OPC_PRECEQ_PW_QHRA:
22929 check_dsp(ctx);
22930 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22931 break;
22932 case OPC_PRECEQU_QH_OBL:
22933 check_dsp(ctx);
22934 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22935 break;
22936 case OPC_PRECEQU_QH_OBR:
22937 check_dsp(ctx);
22938 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22939 break;
22940 case OPC_PRECEQU_QH_OBLA:
22941 check_dsp(ctx);
22942 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22943 break;
22944 case OPC_PRECEQU_QH_OBRA:
22945 check_dsp(ctx);
22946 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22947 break;
22948 case OPC_PRECEU_QH_OBL:
22949 check_dsp(ctx);
22950 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22951 break;
22952 case OPC_PRECEU_QH_OBR:
22953 check_dsp(ctx);
22954 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22955 break;
22956 case OPC_PRECEU_QH_OBLA:
22957 check_dsp(ctx);
22958 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22959 break;
22960 case OPC_PRECEU_QH_OBRA:
22961 check_dsp(ctx);
22962 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22963 break;
22964 case OPC_ABSQ_S_OB:
908f6be1 22965 check_dsp_r2(ctx);
461c08df
JL
22966 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22967 break;
22968 case OPC_ABSQ_S_PW:
22969 check_dsp(ctx);
22970 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22971 break;
22972 case OPC_ABSQ_S_QH:
22973 check_dsp(ctx);
22974 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22975 break;
22976 }
22977 break;
22978 case OPC_ADDU_OB_DSP:
22979 switch (op2) {
22980 case OPC_RADDU_L_OB:
22981 check_dsp(ctx);
22982 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22983 break;
22984 case OPC_SUBQ_PW:
22985 check_dsp(ctx);
22986 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22987 break;
22988 case OPC_SUBQ_S_PW:
22989 check_dsp(ctx);
22990 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22991 break;
22992 case OPC_SUBQ_QH:
22993 check_dsp(ctx);
22994 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22995 break;
22996 case OPC_SUBQ_S_QH:
22997 check_dsp(ctx);
22998 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22999 break;
23000 case OPC_SUBU_OB:
23001 check_dsp(ctx);
23002 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23003 break;
23004 case OPC_SUBU_S_OB:
23005 check_dsp(ctx);
23006 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23007 break;
23008 case OPC_SUBU_QH:
908f6be1 23009 check_dsp_r2(ctx);
461c08df
JL
23010 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23011 break;
23012 case OPC_SUBU_S_QH:
908f6be1 23013 check_dsp_r2(ctx);
461c08df
JL
23014 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23015 break;
23016 case OPC_SUBUH_OB:
908f6be1 23017 check_dsp_r2(ctx);
461c08df
JL
23018 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
23019 break;
23020 case OPC_SUBUH_R_OB:
908f6be1 23021 check_dsp_r2(ctx);
461c08df
JL
23022 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23023 break;
23024 case OPC_ADDQ_PW:
23025 check_dsp(ctx);
23026 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23027 break;
23028 case OPC_ADDQ_S_PW:
23029 check_dsp(ctx);
23030 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23031 break;
23032 case OPC_ADDQ_QH:
23033 check_dsp(ctx);
23034 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23035 break;
23036 case OPC_ADDQ_S_QH:
23037 check_dsp(ctx);
23038 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23039 break;
23040 case OPC_ADDU_OB:
23041 check_dsp(ctx);
23042 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23043 break;
23044 case OPC_ADDU_S_OB:
23045 check_dsp(ctx);
23046 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23047 break;
23048 case OPC_ADDU_QH:
908f6be1 23049 check_dsp_r2(ctx);
461c08df
JL
23050 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23051 break;
23052 case OPC_ADDU_S_QH:
908f6be1 23053 check_dsp_r2(ctx);
461c08df
JL
23054 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23055 break;
23056 case OPC_ADDUH_OB:
908f6be1 23057 check_dsp_r2(ctx);
461c08df
JL
23058 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
23059 break;
23060 case OPC_ADDUH_R_OB:
908f6be1 23061 check_dsp_r2(ctx);
461c08df
JL
23062 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23063 break;
23064 }
23065 break;
23066 case OPC_CMPU_EQ_OB_DSP:
23067 switch (op2) {
23068 case OPC_PRECR_OB_QH:
908f6be1 23069 check_dsp_r2(ctx);
461c08df
JL
23070 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23071 break;
23072 case OPC_PRECR_SRA_QH_PW:
908f6be1 23073 check_dsp_r2(ctx);
461c08df
JL
23074 {
23075 TCGv_i32 ret_t = tcg_const_i32(ret);
23076 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
23077 tcg_temp_free_i32(ret_t);
23078 break;
23079 }
23080 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 23081 check_dsp_r2(ctx);
461c08df
JL
23082 {
23083 TCGv_i32 sa_v = tcg_const_i32(ret);
23084 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
23085 tcg_temp_free_i32(sa_v);
23086 break;
23087 }
23088 case OPC_PRECRQ_OB_QH:
23089 check_dsp(ctx);
23090 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23091 break;
23092 case OPC_PRECRQ_PW_L:
23093 check_dsp(ctx);
23094 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
23095 break;
23096 case OPC_PRECRQ_QH_PW:
23097 check_dsp(ctx);
23098 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
23099 break;
23100 case OPC_PRECRQ_RS_QH_PW:
23101 check_dsp(ctx);
23102 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23103 break;
23104 case OPC_PRECRQU_S_OB_QH:
23105 check_dsp(ctx);
23106 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23107 break;
23108 }
23109 break;
23110#endif
23111 }
23112
23113 tcg_temp_free(v1_t);
23114 tcg_temp_free(v2_t);
461c08df 23115}
9b1a1d68 23116
77c5fa8b
JL
23117static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
23118 int ret, int v1, int v2)
23119{
23120 uint32_t op2;
77c5fa8b
JL
23121 TCGv t0;
23122 TCGv v1_t;
23123 TCGv v2_t;
23124
23125 if (ret == 0) {
23126 /* Treat as NOP. */
77c5fa8b
JL
23127 return;
23128 }
23129
23130 t0 = tcg_temp_new();
23131 v1_t = tcg_temp_new();
23132 v2_t = tcg_temp_new();
23133
23134 tcg_gen_movi_tl(t0, v1);
23135 gen_load_gpr(v1_t, v1);
23136 gen_load_gpr(v2_t, v2);
23137
23138 switch (opc) {
23139 case OPC_SHLL_QB_DSP:
23140 {
23141 op2 = MASK_SHLL_QB(ctx->opcode);
23142 switch (op2) {
23143 case OPC_SHLL_QB:
23144 check_dsp(ctx);
23145 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
23146 break;
23147 case OPC_SHLLV_QB:
23148 check_dsp(ctx);
23149 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23150 break;
23151 case OPC_SHLL_PH:
23152 check_dsp(ctx);
23153 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23154 break;
23155 case OPC_SHLLV_PH:
23156 check_dsp(ctx);
23157 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23158 break;
23159 case OPC_SHLL_S_PH:
23160 check_dsp(ctx);
23161 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23162 break;
23163 case OPC_SHLLV_S_PH:
23164 check_dsp(ctx);
23165 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23166 break;
23167 case OPC_SHLL_S_W:
23168 check_dsp(ctx);
23169 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
23170 break;
23171 case OPC_SHLLV_S_W:
23172 check_dsp(ctx);
23173 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23174 break;
23175 case OPC_SHRL_QB:
23176 check_dsp(ctx);
23177 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
23178 break;
23179 case OPC_SHRLV_QB:
23180 check_dsp(ctx);
23181 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
23182 break;
23183 case OPC_SHRL_PH:
908f6be1 23184 check_dsp_r2(ctx);
77c5fa8b
JL
23185 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
23186 break;
23187 case OPC_SHRLV_PH:
908f6be1 23188 check_dsp_r2(ctx);
77c5fa8b
JL
23189 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
23190 break;
23191 case OPC_SHRA_QB:
908f6be1 23192 check_dsp_r2(ctx);
77c5fa8b
JL
23193 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
23194 break;
23195 case OPC_SHRA_R_QB:
908f6be1 23196 check_dsp_r2(ctx);
77c5fa8b
JL
23197 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
23198 break;
23199 case OPC_SHRAV_QB:
908f6be1 23200 check_dsp_r2(ctx);
77c5fa8b
JL
23201 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
23202 break;
23203 case OPC_SHRAV_R_QB:
908f6be1 23204 check_dsp_r2(ctx);
77c5fa8b
JL
23205 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
23206 break;
23207 case OPC_SHRA_PH:
23208 check_dsp(ctx);
23209 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
23210 break;
23211 case OPC_SHRA_R_PH:
23212 check_dsp(ctx);
23213 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
23214 break;
23215 case OPC_SHRAV_PH:
23216 check_dsp(ctx);
23217 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
23218 break;
23219 case OPC_SHRAV_R_PH:
23220 check_dsp(ctx);
23221 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
23222 break;
23223 case OPC_SHRA_R_W:
23224 check_dsp(ctx);
23225 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
23226 break;
23227 case OPC_SHRAV_R_W:
23228 check_dsp(ctx);
23229 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
23230 break;
23231 default: /* Invalid */
23232 MIPS_INVAL("MASK SHLL.QB");
3a4ef3b7 23233 gen_reserved_instruction(ctx);
77c5fa8b
JL
23234 break;
23235 }
23236 break;
23237 }
23238#ifdef TARGET_MIPS64
23239 case OPC_SHLL_OB_DSP:
23240 op2 = MASK_SHLL_OB(ctx->opcode);
23241 switch (op2) {
23242 case OPC_SHLL_PW:
23243 check_dsp(ctx);
23244 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23245 break;
23246 case OPC_SHLLV_PW:
23247 check_dsp(ctx);
23248 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23249 break;
23250 case OPC_SHLL_S_PW:
23251 check_dsp(ctx);
23252 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23253 break;
23254 case OPC_SHLLV_S_PW:
23255 check_dsp(ctx);
23256 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23257 break;
23258 case OPC_SHLL_OB:
23259 check_dsp(ctx);
23260 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23261 break;
23262 case OPC_SHLLV_OB:
23263 check_dsp(ctx);
23264 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23265 break;
23266 case OPC_SHLL_QH:
23267 check_dsp(ctx);
23268 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23269 break;
23270 case OPC_SHLLV_QH:
23271 check_dsp(ctx);
23272 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23273 break;
23274 case OPC_SHLL_S_QH:
23275 check_dsp(ctx);
23276 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23277 break;
23278 case OPC_SHLLV_S_QH:
23279 check_dsp(ctx);
23280 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23281 break;
23282 case OPC_SHRA_OB:
908f6be1 23283 check_dsp_r2(ctx);
77c5fa8b
JL
23284 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23285 break;
23286 case OPC_SHRAV_OB:
908f6be1 23287 check_dsp_r2(ctx);
77c5fa8b
JL
23288 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23289 break;
23290 case OPC_SHRA_R_OB:
908f6be1 23291 check_dsp_r2(ctx);
77c5fa8b
JL
23292 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23293 break;
23294 case OPC_SHRAV_R_OB:
908f6be1 23295 check_dsp_r2(ctx);
77c5fa8b
JL
23296 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23297 break;
23298 case OPC_SHRA_PW:
23299 check_dsp(ctx);
23300 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23301 break;
23302 case OPC_SHRAV_PW:
23303 check_dsp(ctx);
23304 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23305 break;
23306 case OPC_SHRA_R_PW:
23307 check_dsp(ctx);
23308 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23309 break;
23310 case OPC_SHRAV_R_PW:
23311 check_dsp(ctx);
23312 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23313 break;
23314 case OPC_SHRA_QH:
23315 check_dsp(ctx);
23316 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23317 break;
23318 case OPC_SHRAV_QH:
23319 check_dsp(ctx);
23320 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23321 break;
23322 case OPC_SHRA_R_QH:
23323 check_dsp(ctx);
23324 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23325 break;
23326 case OPC_SHRAV_R_QH:
23327 check_dsp(ctx);
23328 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23329 break;
23330 case OPC_SHRL_OB:
23331 check_dsp(ctx);
23332 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23333 break;
23334 case OPC_SHRLV_OB:
23335 check_dsp(ctx);
23336 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23337 break;
23338 case OPC_SHRL_QH:
908f6be1 23339 check_dsp_r2(ctx);
77c5fa8b
JL
23340 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23341 break;
23342 case OPC_SHRLV_QH:
908f6be1 23343 check_dsp_r2(ctx);
77c5fa8b
JL
23344 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23345 break;
23346 default: /* Invalid */
23347 MIPS_INVAL("MASK SHLL.OB");
3a4ef3b7 23348 gen_reserved_instruction(ctx);
77c5fa8b
JL
23349 break;
23350 }
23351 break;
23352#endif
23353 }
23354
23355 tcg_temp_free(t0);
23356 tcg_temp_free(v1_t);
23357 tcg_temp_free(v2_t);
77c5fa8b
JL
23358}
23359
a22260ae
JL
23360static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23361 int ret, int v1, int v2, int check_ret)
23362{
a22260ae
JL
23363 TCGv_i32 t0;
23364 TCGv v1_t;
23365 TCGv v2_t;
23366
23367 if ((ret == 0) && (check_ret == 1)) {
23368 /* Treat as NOP. */
a22260ae
JL
23369 return;
23370 }
23371
23372 t0 = tcg_temp_new_i32();
23373 v1_t = tcg_temp_new();
23374 v2_t = tcg_temp_new();
23375
23376 tcg_gen_movi_i32(t0, ret);
23377 gen_load_gpr(v1_t, v1);
23378 gen_load_gpr(v2_t, v2);
23379
23380 switch (op1) {
7480515f
AM
23381 /*
23382 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23383 * the same mask and op1.
23384 */
a22260ae 23385 case OPC_MULT_G_2E:
908f6be1 23386 check_dsp_r2(ctx);
a22260ae
JL
23387 switch (op2) {
23388 case OPC_MUL_PH:
23389 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23390 break;
23391 case OPC_MUL_S_PH:
23392 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23393 break;
23394 case OPC_MULQ_S_W:
23395 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23396 break;
23397 case OPC_MULQ_RS_W:
23398 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23399 break;
23400 }
23401 break;
23402 case OPC_DPA_W_PH_DSP:
23403 switch (op2) {
23404 case OPC_DPAU_H_QBL:
23405 check_dsp(ctx);
23406 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23407 break;
23408 case OPC_DPAU_H_QBR:
23409 check_dsp(ctx);
23410 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23411 break;
23412 case OPC_DPSU_H_QBL:
23413 check_dsp(ctx);
23414 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23415 break;
23416 case OPC_DPSU_H_QBR:
23417 check_dsp(ctx);
23418 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23419 break;
23420 case OPC_DPA_W_PH:
908f6be1 23421 check_dsp_r2(ctx);
a22260ae
JL
23422 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23423 break;
23424 case OPC_DPAX_W_PH:
908f6be1 23425 check_dsp_r2(ctx);
a22260ae
JL
23426 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23427 break;
23428 case OPC_DPAQ_S_W_PH:
23429 check_dsp(ctx);
23430 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23431 break;
23432 case OPC_DPAQX_S_W_PH:
908f6be1 23433 check_dsp_r2(ctx);
a22260ae
JL
23434 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23435 break;
23436 case OPC_DPAQX_SA_W_PH:
908f6be1 23437 check_dsp_r2(ctx);
a22260ae
JL
23438 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23439 break;
23440 case OPC_DPS_W_PH:
908f6be1 23441 check_dsp_r2(ctx);
a22260ae
JL
23442 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23443 break;
23444 case OPC_DPSX_W_PH:
908f6be1 23445 check_dsp_r2(ctx);
a22260ae
JL
23446 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23447 break;
23448 case OPC_DPSQ_S_W_PH:
23449 check_dsp(ctx);
23450 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23451 break;
23452 case OPC_DPSQX_S_W_PH:
908f6be1 23453 check_dsp_r2(ctx);
a22260ae
JL
23454 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23455 break;
23456 case OPC_DPSQX_SA_W_PH:
908f6be1 23457 check_dsp_r2(ctx);
a22260ae
JL
23458 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23459 break;
23460 case OPC_MULSAQ_S_W_PH:
23461 check_dsp(ctx);
23462 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23463 break;
23464 case OPC_DPAQ_SA_L_W:
23465 check_dsp(ctx);
23466 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23467 break;
23468 case OPC_DPSQ_SA_L_W:
23469 check_dsp(ctx);
23470 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23471 break;
23472 case OPC_MAQ_S_W_PHL:
23473 check_dsp(ctx);
23474 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23475 break;
23476 case OPC_MAQ_S_W_PHR:
23477 check_dsp(ctx);
23478 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23479 break;
23480 case OPC_MAQ_SA_W_PHL:
23481 check_dsp(ctx);
23482 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23483 break;
23484 case OPC_MAQ_SA_W_PHR:
23485 check_dsp(ctx);
23486 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23487 break;
23488 case OPC_MULSA_W_PH:
908f6be1 23489 check_dsp_r2(ctx);
a22260ae
JL
23490 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23491 break;
23492 }
23493 break;
23494#ifdef TARGET_MIPS64
23495 case OPC_DPAQ_W_QH_DSP:
23496 {
23497 int ac = ret & 0x03;
23498 tcg_gen_movi_i32(t0, ac);
23499
23500 switch (op2) {
23501 case OPC_DMADD:
23502 check_dsp(ctx);
23503 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23504 break;
23505 case OPC_DMADDU:
23506 check_dsp(ctx);
23507 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23508 break;
23509 case OPC_DMSUB:
23510 check_dsp(ctx);
23511 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23512 break;
23513 case OPC_DMSUBU:
23514 check_dsp(ctx);
23515 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23516 break;
23517 case OPC_DPA_W_QH:
908f6be1 23518 check_dsp_r2(ctx);
a22260ae
JL
23519 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23520 break;
23521 case OPC_DPAQ_S_W_QH:
23522 check_dsp(ctx);
23523 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23524 break;
23525 case OPC_DPAQ_SA_L_PW:
23526 check_dsp(ctx);
23527 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23528 break;
23529 case OPC_DPAU_H_OBL:
23530 check_dsp(ctx);
23531 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23532 break;
23533 case OPC_DPAU_H_OBR:
23534 check_dsp(ctx);
23535 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23536 break;
23537 case OPC_DPS_W_QH:
908f6be1 23538 check_dsp_r2(ctx);
a22260ae
JL
23539 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23540 break;
23541 case OPC_DPSQ_S_W_QH:
23542 check_dsp(ctx);
23543 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23544 break;
23545 case OPC_DPSQ_SA_L_PW:
23546 check_dsp(ctx);
23547 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23548 break;
23549 case OPC_DPSU_H_OBL:
23550 check_dsp(ctx);
23551 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23552 break;
23553 case OPC_DPSU_H_OBR:
23554 check_dsp(ctx);
23555 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23556 break;
23557 case OPC_MAQ_S_L_PWL:
23558 check_dsp(ctx);
23559 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23560 break;
23561 case OPC_MAQ_S_L_PWR:
23562 check_dsp(ctx);
23563 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23564 break;
23565 case OPC_MAQ_S_W_QHLL:
23566 check_dsp(ctx);
23567 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23568 break;
23569 case OPC_MAQ_SA_W_QHLL:
23570 check_dsp(ctx);
23571 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23572 break;
23573 case OPC_MAQ_S_W_QHLR:
23574 check_dsp(ctx);
23575 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23576 break;
23577 case OPC_MAQ_SA_W_QHLR:
23578 check_dsp(ctx);
23579 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23580 break;
23581 case OPC_MAQ_S_W_QHRL:
23582 check_dsp(ctx);
23583 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23584 break;
23585 case OPC_MAQ_SA_W_QHRL:
23586 check_dsp(ctx);
23587 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23588 break;
23589 case OPC_MAQ_S_W_QHRR:
23590 check_dsp(ctx);
23591 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23592 break;
23593 case OPC_MAQ_SA_W_QHRR:
23594 check_dsp(ctx);
23595 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23596 break;
23597 case OPC_MULSAQ_S_L_PW:
23598 check_dsp(ctx);
23599 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23600 break;
23601 case OPC_MULSAQ_S_W_QH:
23602 check_dsp(ctx);
23603 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23604 break;
23605 }
23606 }
23607 break;
23608#endif
23609 case OPC_ADDU_QB_DSP:
23610 switch (op2) {
23611 case OPC_MULEU_S_PH_QBL:
23612 check_dsp(ctx);
23613 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23614 break;
23615 case OPC_MULEU_S_PH_QBR:
23616 check_dsp(ctx);
23617 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23618 break;
23619 case OPC_MULQ_RS_PH:
23620 check_dsp(ctx);
23621 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23622 break;
23623 case OPC_MULEQ_S_W_PHL:
23624 check_dsp(ctx);
23625 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23626 break;
23627 case OPC_MULEQ_S_W_PHR:
23628 check_dsp(ctx);
23629 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23630 break;
23631 case OPC_MULQ_S_PH:
908f6be1 23632 check_dsp_r2(ctx);
a22260ae
JL
23633 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23634 break;
23635 }
23636 break;
23637#ifdef TARGET_MIPS64
23638 case OPC_ADDU_OB_DSP:
23639 switch (op2) {
23640 case OPC_MULEQ_S_PW_QHL:
23641 check_dsp(ctx);
23642 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23643 break;
23644 case OPC_MULEQ_S_PW_QHR:
23645 check_dsp(ctx);
23646 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23647 break;
23648 case OPC_MULEU_S_QH_OBL:
23649 check_dsp(ctx);
23650 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23651 break;
23652 case OPC_MULEU_S_QH_OBR:
23653 check_dsp(ctx);
23654 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23655 break;
23656 case OPC_MULQ_RS_QH:
23657 check_dsp(ctx);
23658 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23659 break;
23660 }
23661 break;
23662#endif
23663 }
23664
23665 tcg_temp_free_i32(t0);
23666 tcg_temp_free(v1_t);
23667 tcg_temp_free(v2_t);
a22260ae
JL
23668}
23669
d75c135e 23670static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
23671 int ret, int val)
23672{
1cb6686c
JL
23673 int16_t imm;
23674 TCGv t0;
23675 TCGv val_t;
23676
23677 if (ret == 0) {
23678 /* Treat as NOP. */
1cb6686c
JL
23679 return;
23680 }
23681
23682 t0 = tcg_temp_new();
23683 val_t = tcg_temp_new();
23684 gen_load_gpr(val_t, val);
23685
23686 switch (op1) {
23687 case OPC_ABSQ_S_PH_DSP:
23688 switch (op2) {
23689 case OPC_BITREV:
23690 check_dsp(ctx);
23691 gen_helper_bitrev(cpu_gpr[ret], val_t);
23692 break;
23693 case OPC_REPL_QB:
23694 check_dsp(ctx);
23695 {
23696 target_long result;
23697 imm = (ctx->opcode >> 16) & 0xFF;
23698 result = (uint32_t)imm << 24 |
23699 (uint32_t)imm << 16 |
23700 (uint32_t)imm << 8 |
23701 (uint32_t)imm;
23702 result = (int32_t)result;
23703 tcg_gen_movi_tl(cpu_gpr[ret], result);
23704 }
23705 break;
23706 case OPC_REPLV_QB:
23707 check_dsp(ctx);
23708 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23709 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23710 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23711 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23712 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23713 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23714 break;
23715 case OPC_REPL_PH:
23716 check_dsp(ctx);
23717 {
23718 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 23719 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
23720 tcg_gen_movi_tl(cpu_gpr[ret], \
23721 (target_long)((int32_t)imm << 16 | \
c4aaba92 23722 (uint16_t)imm));
1cb6686c
JL
23723 }
23724 break;
23725 case OPC_REPLV_PH:
23726 check_dsp(ctx);
23727 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23728 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23729 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23730 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23731 break;
23732 }
23733 break;
23734#ifdef TARGET_MIPS64
23735 case OPC_ABSQ_S_QH_DSP:
23736 switch (op2) {
23737 case OPC_REPL_OB:
23738 check_dsp(ctx);
23739 {
23740 target_long temp;
23741
23742 imm = (ctx->opcode >> 16) & 0xFF;
23743 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23744 temp = (temp << 16) | temp;
23745 temp = (temp << 32) | temp;
23746 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23747 break;
23748 }
23749 case OPC_REPL_PW:
23750 check_dsp(ctx);
23751 {
23752 target_long temp;
23753
23754 imm = (ctx->opcode >> 16) & 0x03FF;
23755 imm = (int16_t)(imm << 6) >> 6;
23756 temp = ((target_long)imm << 32) \
23757 | ((target_long)imm & 0xFFFFFFFF);
23758 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23759 break;
23760 }
23761 case OPC_REPL_QH:
23762 check_dsp(ctx);
23763 {
23764 target_long temp;
23765
23766 imm = (ctx->opcode >> 16) & 0x03FF;
23767 imm = (int16_t)(imm << 6) >> 6;
23768
23769 temp = ((uint64_t)(uint16_t)imm << 48) |
23770 ((uint64_t)(uint16_t)imm << 32) |
23771 ((uint64_t)(uint16_t)imm << 16) |
23772 (uint64_t)(uint16_t)imm;
23773 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23774 break;
23775 }
23776 case OPC_REPLV_OB:
23777 check_dsp(ctx);
23778 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23779 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23780 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23781 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23782 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23783 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23784 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23785 break;
23786 case OPC_REPLV_PW:
23787 check_dsp(ctx);
23788 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23789 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23790 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23791 break;
23792 case OPC_REPLV_QH:
23793 check_dsp(ctx);
23794 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23795 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23796 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23797 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23798 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23799 break;
23800 }
23801 break;
23802#endif
23803 }
23804 tcg_temp_free(t0);
23805 tcg_temp_free(val_t);
1cb6686c
JL
23806}
23807
26690560
JL
23808static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23809 uint32_t op1, uint32_t op2,
23810 int ret, int v1, int v2, int check_ret)
23811{
26690560
JL
23812 TCGv t1;
23813 TCGv v1_t;
23814 TCGv v2_t;
23815
23816 if ((ret == 0) && (check_ret == 1)) {
23817 /* Treat as NOP. */
26690560
JL
23818 return;
23819 }
23820
26690560
JL
23821 t1 = tcg_temp_new();
23822 v1_t = tcg_temp_new();
23823 v2_t = tcg_temp_new();
23824
23825 gen_load_gpr(v1_t, v1);
23826 gen_load_gpr(v2_t, v2);
23827
23828 switch (op1) {
26690560
JL
23829 case OPC_CMPU_EQ_QB_DSP:
23830 switch (op2) {
23831 case OPC_CMPU_EQ_QB:
23832 check_dsp(ctx);
23833 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23834 break;
23835 case OPC_CMPU_LT_QB:
23836 check_dsp(ctx);
23837 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23838 break;
23839 case OPC_CMPU_LE_QB:
23840 check_dsp(ctx);
23841 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23842 break;
23843 case OPC_CMPGU_EQ_QB:
23844 check_dsp(ctx);
23845 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23846 break;
23847 case OPC_CMPGU_LT_QB:
23848 check_dsp(ctx);
23849 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23850 break;
23851 case OPC_CMPGU_LE_QB:
23852 check_dsp(ctx);
23853 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23854 break;
23855 case OPC_CMPGDU_EQ_QB:
908f6be1 23856 check_dsp_r2(ctx);
26690560
JL
23857 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23858 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23859 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23860 tcg_gen_shli_tl(t1, t1, 24);
23861 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23862 break;
23863 case OPC_CMPGDU_LT_QB:
908f6be1 23864 check_dsp_r2(ctx);
26690560
JL
23865 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23866 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23867 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23868 tcg_gen_shli_tl(t1, t1, 24);
23869 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23870 break;
23871 case OPC_CMPGDU_LE_QB:
908f6be1 23872 check_dsp_r2(ctx);
26690560
JL
23873 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23874 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23875 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23876 tcg_gen_shli_tl(t1, t1, 24);
23877 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23878 break;
23879 case OPC_CMP_EQ_PH:
23880 check_dsp(ctx);
23881 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23882 break;
23883 case OPC_CMP_LT_PH:
23884 check_dsp(ctx);
23885 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23886 break;
23887 case OPC_CMP_LE_PH:
23888 check_dsp(ctx);
23889 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23890 break;
23891 case OPC_PICK_QB:
23892 check_dsp(ctx);
23893 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23894 break;
23895 case OPC_PICK_PH:
23896 check_dsp(ctx);
23897 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23898 break;
23899 case OPC_PACKRL_PH:
23900 check_dsp(ctx);
23901 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23902 break;
23903 }
23904 break;
23905#ifdef TARGET_MIPS64
23906 case OPC_CMPU_EQ_OB_DSP:
23907 switch (op2) {
23908 case OPC_CMP_EQ_PW:
23909 check_dsp(ctx);
23910 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23911 break;
23912 case OPC_CMP_LT_PW:
23913 check_dsp(ctx);
23914 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23915 break;
23916 case OPC_CMP_LE_PW:
23917 check_dsp(ctx);
23918 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23919 break;
23920 case OPC_CMP_EQ_QH:
23921 check_dsp(ctx);
23922 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23923 break;
23924 case OPC_CMP_LT_QH:
23925 check_dsp(ctx);
23926 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23927 break;
23928 case OPC_CMP_LE_QH:
23929 check_dsp(ctx);
23930 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23931 break;
23932 case OPC_CMPGDU_EQ_OB:
908f6be1 23933 check_dsp_r2(ctx);
26690560
JL
23934 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23935 break;
23936 case OPC_CMPGDU_LT_OB:
908f6be1 23937 check_dsp_r2(ctx);
26690560
JL
23938 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23939 break;
23940 case OPC_CMPGDU_LE_OB:
908f6be1 23941 check_dsp_r2(ctx);
26690560
JL
23942 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23943 break;
23944 case OPC_CMPGU_EQ_OB:
23945 check_dsp(ctx);
23946 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23947 break;
23948 case OPC_CMPGU_LT_OB:
23949 check_dsp(ctx);
23950 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23951 break;
23952 case OPC_CMPGU_LE_OB:
23953 check_dsp(ctx);
23954 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23955 break;
23956 case OPC_CMPU_EQ_OB:
23957 check_dsp(ctx);
23958 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23959 break;
23960 case OPC_CMPU_LT_OB:
23961 check_dsp(ctx);
23962 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23963 break;
23964 case OPC_CMPU_LE_OB:
23965 check_dsp(ctx);
23966 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23967 break;
23968 case OPC_PACKRL_PW:
23969 check_dsp(ctx);
23970 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23971 break;
23972 case OPC_PICK_OB:
23973 check_dsp(ctx);
23974 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23975 break;
23976 case OPC_PICK_PW:
23977 check_dsp(ctx);
23978 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23979 break;
23980 case OPC_PICK_QH:
23981 check_dsp(ctx);
23982 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23983 break;
23984 }
23985 break;
df6126a7
AJ
23986#endif
23987 }
23988
23989 tcg_temp_free(t1);
23990 tcg_temp_free(v1_t);
23991 tcg_temp_free(v2_t);
df6126a7
AJ
23992}
23993
23994static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23995 uint32_t op1, int rt, int rs, int sa)
23996{
df6126a7
AJ
23997 TCGv t0;
23998
908f6be1 23999 check_dsp_r2(ctx);
df6126a7
AJ
24000
24001 if (rt == 0) {
24002 /* Treat as NOP. */
df6126a7
AJ
24003 return;
24004 }
24005
24006 t0 = tcg_temp_new();
24007 gen_load_gpr(t0, rs);
24008
24009 switch (op1) {
24010 case OPC_APPEND_DSP:
24011 switch (MASK_APPEND(ctx->opcode)) {
24012 case OPC_APPEND:
24013 if (sa != 0) {
24014 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
24015 }
24016 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24017 break;
24018 case OPC_PREPEND:
24019 if (sa != 0) {
24020 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
24021 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24022 tcg_gen_shli_tl(t0, t0, 32 - sa);
24023 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24024 }
24025 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24026 break;
24027 case OPC_BALIGN:
24028 sa &= 3;
24029 if (sa != 0 && sa != 2) {
24030 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24031 tcg_gen_ext32u_tl(t0, t0);
24032 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
24033 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24034 }
24035 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24036 break;
24037 default: /* Invalid */
24038 MIPS_INVAL("MASK APPEND");
3a4ef3b7 24039 gen_reserved_instruction(ctx);
df6126a7
AJ
24040 break;
24041 }
24042 break;
24043#ifdef TARGET_MIPS64
26690560 24044 case OPC_DAPPEND_DSP:
df6126a7 24045 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 24046 case OPC_DAPPEND:
df6126a7
AJ
24047 if (sa != 0) {
24048 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
24049 }
26690560
JL
24050 break;
24051 case OPC_PREPENDD:
df6126a7
AJ
24052 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
24053 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
24054 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
24055 break;
24056 case OPC_PREPENDW:
df6126a7
AJ
24057 if (sa != 0) {
24058 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24059 tcg_gen_shli_tl(t0, t0, 64 - sa);
24060 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24061 }
26690560
JL
24062 break;
24063 case OPC_DBALIGN:
df6126a7
AJ
24064 sa &= 7;
24065 if (sa != 0 && sa != 2 && sa != 4) {
24066 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24067 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
24068 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24069 }
26690560
JL
24070 break;
24071 default: /* Invalid */
24072 MIPS_INVAL("MASK DAPPEND");
3a4ef3b7 24073 gen_reserved_instruction(ctx);
26690560
JL
24074 break;
24075 }
24076 break;
24077#endif
24078 }
df6126a7 24079 tcg_temp_free(t0);
26690560
JL
24080}
24081
b53371ed
JL
24082static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
24083 int ret, int v1, int v2, int check_ret)
24084
24085{
b53371ed
JL
24086 TCGv t0;
24087 TCGv t1;
24088 TCGv v1_t;
24089 TCGv v2_t;
24090 int16_t imm;
24091
24092 if ((ret == 0) && (check_ret == 1)) {
24093 /* Treat as NOP. */
b53371ed
JL
24094 return;
24095 }
24096
24097 t0 = tcg_temp_new();
24098 t1 = tcg_temp_new();
24099 v1_t = tcg_temp_new();
24100 v2_t = tcg_temp_new();
24101
24102 gen_load_gpr(v1_t, v1);
24103 gen_load_gpr(v2_t, v2);
24104
24105 switch (op1) {
24106 case OPC_EXTR_W_DSP:
24107 check_dsp(ctx);
24108 switch (op2) {
24109 case OPC_EXTR_W:
24110 tcg_gen_movi_tl(t0, v2);
24111 tcg_gen_movi_tl(t1, v1);
24112 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
24113 break;
24114 case OPC_EXTR_R_W:
24115 tcg_gen_movi_tl(t0, v2);
24116 tcg_gen_movi_tl(t1, v1);
24117 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24118 break;
24119 case OPC_EXTR_RS_W:
24120 tcg_gen_movi_tl(t0, v2);
24121 tcg_gen_movi_tl(t1, v1);
24122 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24123 break;
24124 case OPC_EXTR_S_H:
24125 tcg_gen_movi_tl(t0, v2);
24126 tcg_gen_movi_tl(t1, v1);
24127 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24128 break;
24129 case OPC_EXTRV_S_H:
24130 tcg_gen_movi_tl(t0, v2);
24131 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
24132 break;
24133 case OPC_EXTRV_W:
24134 tcg_gen_movi_tl(t0, v2);
24135 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24136 break;
24137 case OPC_EXTRV_R_W:
24138 tcg_gen_movi_tl(t0, v2);
24139 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24140 break;
24141 case OPC_EXTRV_RS_W:
24142 tcg_gen_movi_tl(t0, v2);
24143 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24144 break;
24145 case OPC_EXTP:
24146 tcg_gen_movi_tl(t0, v2);
24147 tcg_gen_movi_tl(t1, v1);
24148 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
24149 break;
24150 case OPC_EXTPV:
24151 tcg_gen_movi_tl(t0, v2);
24152 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
24153 break;
24154 case OPC_EXTPDP:
24155 tcg_gen_movi_tl(t0, v2);
24156 tcg_gen_movi_tl(t1, v1);
24157 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
24158 break;
24159 case OPC_EXTPDPV:
24160 tcg_gen_movi_tl(t0, v2);
24161 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24162 break;
24163 case OPC_SHILO:
24164 imm = (ctx->opcode >> 20) & 0x3F;
24165 tcg_gen_movi_tl(t0, ret);
24166 tcg_gen_movi_tl(t1, imm);
24167 gen_helper_shilo(t0, t1, cpu_env);
24168 break;
24169 case OPC_SHILOV:
24170 tcg_gen_movi_tl(t0, ret);
24171 gen_helper_shilo(t0, v1_t, cpu_env);
24172 break;
24173 case OPC_MTHLIP:
24174 tcg_gen_movi_tl(t0, ret);
24175 gen_helper_mthlip(t0, v1_t, cpu_env);
24176 break;
24177 case OPC_WRDSP:
24178 imm = (ctx->opcode >> 11) & 0x3FF;
24179 tcg_gen_movi_tl(t0, imm);
24180 gen_helper_wrdsp(v1_t, t0, cpu_env);
24181 break;
24182 case OPC_RDDSP:
24183 imm = (ctx->opcode >> 16) & 0x03FF;
24184 tcg_gen_movi_tl(t0, imm);
24185 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
24186 break;
24187 }
24188 break;
24189#ifdef TARGET_MIPS64
24190 case OPC_DEXTR_W_DSP:
24191 check_dsp(ctx);
24192 switch (op2) {
24193 case OPC_DMTHLIP:
24194 tcg_gen_movi_tl(t0, ret);
24195 gen_helper_dmthlip(v1_t, t0, cpu_env);
24196 break;
24197 case OPC_DSHILO:
24198 {
24199 int shift = (ctx->opcode >> 19) & 0x7F;
24200 int ac = (ctx->opcode >> 11) & 0x03;
24201 tcg_gen_movi_tl(t0, shift);
24202 tcg_gen_movi_tl(t1, ac);
24203 gen_helper_dshilo(t0, t1, cpu_env);
24204 break;
24205 }
24206 case OPC_DSHILOV:
24207 {
24208 int ac = (ctx->opcode >> 11) & 0x03;
24209 tcg_gen_movi_tl(t0, ac);
24210 gen_helper_dshilo(v1_t, t0, cpu_env);
24211 break;
24212 }
24213 case OPC_DEXTP:
24214 tcg_gen_movi_tl(t0, v2);
24215 tcg_gen_movi_tl(t1, v1);
24216
24217 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
24218 break;
24219 case OPC_DEXTPV:
24220 tcg_gen_movi_tl(t0, v2);
24221 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
24222 break;
24223 case OPC_DEXTPDP:
24224 tcg_gen_movi_tl(t0, v2);
24225 tcg_gen_movi_tl(t1, v1);
24226 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
24227 break;
24228 case OPC_DEXTPDPV:
24229 tcg_gen_movi_tl(t0, v2);
24230 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24231 break;
24232 case OPC_DEXTR_L:
24233 tcg_gen_movi_tl(t0, v2);
24234 tcg_gen_movi_tl(t1, v1);
24235 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
24236 break;
24237 case OPC_DEXTR_R_L:
24238 tcg_gen_movi_tl(t0, v2);
24239 tcg_gen_movi_tl(t1, v1);
24240 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
24241 break;
24242 case OPC_DEXTR_RS_L:
24243 tcg_gen_movi_tl(t0, v2);
24244 tcg_gen_movi_tl(t1, v1);
24245 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24246 break;
24247 case OPC_DEXTR_W:
24248 tcg_gen_movi_tl(t0, v2);
24249 tcg_gen_movi_tl(t1, v1);
24250 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24251 break;
24252 case OPC_DEXTR_R_W:
24253 tcg_gen_movi_tl(t0, v2);
24254 tcg_gen_movi_tl(t1, v1);
24255 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24256 break;
24257 case OPC_DEXTR_RS_W:
24258 tcg_gen_movi_tl(t0, v2);
24259 tcg_gen_movi_tl(t1, v1);
24260 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24261 break;
24262 case OPC_DEXTR_S_H:
24263 tcg_gen_movi_tl(t0, v2);
24264 tcg_gen_movi_tl(t1, v1);
24265 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24266 break;
24267 case OPC_DEXTRV_S_H:
24268 tcg_gen_movi_tl(t0, v2);
24269 tcg_gen_movi_tl(t1, v1);
24270 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24271 break;
24272 case OPC_DEXTRV_L:
24273 tcg_gen_movi_tl(t0, v2);
24274 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24275 break;
24276 case OPC_DEXTRV_R_L:
24277 tcg_gen_movi_tl(t0, v2);
24278 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24279 break;
24280 case OPC_DEXTRV_RS_L:
24281 tcg_gen_movi_tl(t0, v2);
24282 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24283 break;
24284 case OPC_DEXTRV_W:
24285 tcg_gen_movi_tl(t0, v2);
24286 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24287 break;
24288 case OPC_DEXTRV_R_W:
24289 tcg_gen_movi_tl(t0, v2);
24290 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24291 break;
24292 case OPC_DEXTRV_RS_W:
24293 tcg_gen_movi_tl(t0, v2);
24294 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24295 break;
24296 }
24297 break;
24298#endif
24299 }
24300
24301 tcg_temp_free(t0);
24302 tcg_temp_free(t1);
24303 tcg_temp_free(v1_t);
24304 tcg_temp_free(v2_t);
b53371ed
JL
24305}
24306
9b1a1d68
JL
24307/* End MIPSDSP functions. */
24308
10dc65db
LA
24309static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24310{
4267d3e6 24311 int rs, rt, rd, sa;
b42ee5e1 24312 uint32_t op1, op2;
10dc65db
LA
24313
24314 rs = (ctx->opcode >> 21) & 0x1f;
24315 rt = (ctx->opcode >> 16) & 0x1f;
24316 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 24317 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
24318
24319 op1 = MASK_SPECIAL(ctx->opcode);
24320 switch (op1) {
d4ea6acd 24321 case OPC_LSA:
a685f7d0 24322 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 6, 2));
d4ea6acd 24323 break;
c2e19f3c
AM
24324 case OPC_MULT:
24325 case OPC_MULTU:
24326 case OPC_DIV:
24327 case OPC_DIVU:
b42ee5e1
LA
24328 op2 = MASK_R6_MULDIV(ctx->opcode);
24329 switch (op2) {
24330 case R6_OPC_MUL:
24331 case R6_OPC_MUH:
24332 case R6_OPC_MULU:
24333 case R6_OPC_MUHU:
24334 case R6_OPC_DIV:
24335 case R6_OPC_MOD:
24336 case R6_OPC_DIVU:
24337 case R6_OPC_MODU:
24338 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24339 break;
24340 default:
24341 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 24342 gen_reserved_instruction(ctx);
b42ee5e1
LA
24343 break;
24344 }
24345 break;
10dc65db
LA
24346 case OPC_SELEQZ:
24347 case OPC_SELNEZ:
24348 gen_cond_move(ctx, op1, rd, rs, rt);
24349 break;
4267d3e6
LA
24350 case R6_OPC_CLO:
24351 case R6_OPC_CLZ:
24352 if (rt == 0 && sa == 1) {
7480515f
AM
24353 /*
24354 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24355 * We need additionally to check other fields.
24356 */
4267d3e6
LA
24357 gen_cl(ctx, op1, rd, rs);
24358 } else {
3a4ef3b7 24359 gen_reserved_instruction(ctx);
4267d3e6
LA
24360 }
24361 break;
24362 case R6_OPC_SDBBP:
3b3c1694
LA
24363 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24364 gen_helper_do_semihosting(cpu_env);
faf1f68b 24365 } else {
3b3c1694 24366 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 24367 gen_reserved_instruction(ctx);
3b3c1694 24368 } else {
9c708c7f 24369 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 24370 }
faf1f68b 24371 }
4267d3e6 24372 break;
b42ee5e1 24373#if defined(TARGET_MIPS64)
d4ea6acd 24374 case OPC_DLSA:
a685f7d0 24375 gen_dlsa(ctx, rd, rt, rs, extract32(ctx->opcode, 6, 2));
d4ea6acd 24376 break;
4267d3e6
LA
24377 case R6_OPC_DCLO:
24378 case R6_OPC_DCLZ:
24379 if (rt == 0 && sa == 1) {
7480515f
AM
24380 /*
24381 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24382 * We need additionally to check other fields.
24383 */
4267d3e6
LA
24384 check_mips_64(ctx);
24385 gen_cl(ctx, op1, rd, rs);
24386 } else {
3a4ef3b7 24387 gen_reserved_instruction(ctx);
4267d3e6
LA
24388 }
24389 break;
c2e19f3c
AM
24390 case OPC_DMULT:
24391 case OPC_DMULTU:
24392 case OPC_DDIV:
24393 case OPC_DDIVU:
24394
b42ee5e1
LA
24395 op2 = MASK_R6_MULDIV(ctx->opcode);
24396 switch (op2) {
24397 case R6_OPC_DMUL:
24398 case R6_OPC_DMUH:
24399 case R6_OPC_DMULU:
24400 case R6_OPC_DMUHU:
24401 case R6_OPC_DDIV:
24402 case R6_OPC_DMOD:
24403 case R6_OPC_DDIVU:
24404 case R6_OPC_DMODU:
24405 check_mips_64(ctx);
24406 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24407 break;
24408 default:
24409 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 24410 gen_reserved_instruction(ctx);
b42ee5e1
LA
24411 break;
24412 }
24413 break;
24414#endif
10dc65db
LA
24415 default: /* Invalid */
24416 MIPS_INVAL("special_r6");
3a4ef3b7 24417 gen_reserved_instruction(ctx);
10dc65db
LA
24418 break;
24419 }
24420}
24421
9dc324ce
FN
24422static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24423{
24424 int rs = extract32(ctx->opcode, 21, 5);
24425 int rt = extract32(ctx->opcode, 16, 5);
24426 int rd = extract32(ctx->opcode, 11, 5);
24427 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24428
24429 switch (op1) {
24430 case OPC_MOVN: /* Conditional move */
24431 case OPC_MOVZ:
24432 gen_cond_move(ctx, op1, rd, rs, rt);
24433 break;
24434 case OPC_MFHI: /* Move from HI/LO */
24435 case OPC_MFLO:
24436 gen_HILO(ctx, op1, 0, rd);
24437 break;
24438 case OPC_MTHI:
24439 case OPC_MTLO: /* Move to HI/LO */
24440 gen_HILO(ctx, op1, 0, rs);
24441 break;
24442 case OPC_MULT:
24443 case OPC_MULTU:
24444 gen_mul_txx9(ctx, op1, rd, rs, rt);
24445 break;
24446 case OPC_DIV:
24447 case OPC_DIVU:
24448 gen_muldiv(ctx, op1, 0, rs, rt);
24449 break;
24450#if defined(TARGET_MIPS64)
24451 case OPC_DMULT:
24452 case OPC_DMULTU:
24453 case OPC_DDIV:
24454 case OPC_DDIVU:
24455 check_insn_opc_user_only(ctx, INSN_R5900);
24456 gen_muldiv(ctx, op1, 0, rs, rt);
24457 break;
24458#endif
24459 case OPC_JR:
24460 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24461 break;
24462 default: /* Invalid */
24463 MIPS_INVAL("special_tx79");
3a4ef3b7 24464 gen_reserved_instruction(ctx);
9dc324ce
FN
24465 break;
24466 }
24467}
24468
10dc65db
LA
24469static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24470{
b42ee5e1 24471 int rs, rt, rd, sa;
10dc65db
LA
24472 uint32_t op1;
24473
24474 rs = (ctx->opcode >> 21) & 0x1f;
24475 rt = (ctx->opcode >> 16) & 0x1f;
24476 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 24477 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
24478
24479 op1 = MASK_SPECIAL(ctx->opcode);
24480 switch (op1) {
24481 case OPC_MOVN: /* Conditional move */
24482 case OPC_MOVZ:
bbd5e4a2 24483 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
9dc324ce 24484 INSN_LOONGSON2E | INSN_LOONGSON2F);
10dc65db
LA
24485 gen_cond_move(ctx, op1, rd, rs, rt);
24486 break;
24487 case OPC_MFHI: /* Move from HI/LO */
24488 case OPC_MFLO:
24489 gen_HILO(ctx, op1, rs & 3, rd);
24490 break;
24491 case OPC_MTHI:
24492 case OPC_MTLO: /* Move to HI/LO */
24493 gen_HILO(ctx, op1, rd & 3, rs);
24494 break;
24495 case OPC_MOVCI:
bbd5e4a2 24496 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
10dc65db
LA
24497 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24498 check_cp1_enabled(ctx);
24499 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24500 (ctx->opcode >> 16) & 1);
24501 } else {
24502 generate_exception_err(ctx, EXCP_CpU, 1);
24503 }
24504 break;
b42ee5e1
LA
24505 case OPC_MULT:
24506 case OPC_MULTU:
24507 if (sa) {
24508 check_insn(ctx, INSN_VR54XX);
24509 op1 = MASK_MUL_VR54XX(ctx->opcode);
24510 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24511 } else {
24512 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24513 }
24514 break;
24515 case OPC_DIV:
24516 case OPC_DIVU:
24517 gen_muldiv(ctx, op1, 0, rs, rt);
24518 break;
24519#if defined(TARGET_MIPS64)
c2e19f3c
AM
24520 case OPC_DMULT:
24521 case OPC_DMULTU:
24522 case OPC_DDIV:
24523 case OPC_DDIVU:
b42ee5e1
LA
24524 check_insn(ctx, ISA_MIPS3);
24525 check_mips_64(ctx);
24526 gen_muldiv(ctx, op1, 0, rs, rt);
24527 break;
24528#endif
0aefa333 24529 case OPC_JR:
b231c103 24530 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 24531 break;
4267d3e6
LA
24532 case OPC_SPIM:
24533#ifdef MIPS_STRICT_STANDARD
24534 MIPS_INVAL("SPIM");
3a4ef3b7 24535 gen_reserved_instruction(ctx);
4267d3e6
LA
24536#else
24537 /* Implemented as RI exception for now. */
24538 MIPS_INVAL("spim (unofficial)");
3a4ef3b7 24539 gen_reserved_instruction(ctx);
4267d3e6
LA
24540#endif
24541 break;
10dc65db
LA
24542 default: /* Invalid */
24543 MIPS_INVAL("special_legacy");
3a4ef3b7 24544 gen_reserved_instruction(ctx);
10dc65db
LA
24545 break;
24546 }
24547}
24548
099e5b4d 24549static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 24550{
3c824109 24551 int rs, rt, rd, sa;
099e5b4d 24552 uint32_t op1;
3c824109 24553
3c824109
NF
24554 rs = (ctx->opcode >> 21) & 0x1f;
24555 rt = (ctx->opcode >> 16) & 0x1f;
24556 rd = (ctx->opcode >> 11) & 0x1f;
24557 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
24558
24559 op1 = MASK_SPECIAL(ctx->opcode);
24560 switch (op1) {
24561 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
24562 if (sa == 5 && rd == 0 &&
24563 rs == 0 && rt == 0) { /* PAUSE */
2e211e0a 24564 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 24565 (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 24566 gen_reserved_instruction(ctx);
339cd2a8
LA
24567 break;
24568 }
24569 }
24570 /* Fallthrough */
099e5b4d
LA
24571 case OPC_SRA:
24572 gen_shift_imm(ctx, op1, rd, rt, sa);
24573 break;
24574 case OPC_SRL:
24575 switch ((ctx->opcode >> 21) & 0x1f) {
24576 case 1:
24577 /* rotr is decoded as srl on non-R2 CPUs */
7a47bae5 24578 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 24579 op1 = OPC_ROTR;
ea63e2c3 24580 }
099e5b4d
LA
24581 /* Fallthrough */
24582 case 0:
24583 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 24584 break;
099e5b4d 24585 default:
3a4ef3b7 24586 gen_reserved_instruction(ctx);
ea63e2c3 24587 break;
099e5b4d
LA
24588 }
24589 break;
c2e19f3c
AM
24590 case OPC_ADD:
24591 case OPC_ADDU:
24592 case OPC_SUB:
24593 case OPC_SUBU:
099e5b4d
LA
24594 gen_arith(ctx, op1, rd, rs, rt);
24595 break;
24596 case OPC_SLLV: /* Shifts */
24597 case OPC_SRAV:
24598 gen_shift(ctx, op1, rd, rs, rt);
24599 break;
24600 case OPC_SRLV:
24601 switch ((ctx->opcode >> 6) & 0x1f) {
24602 case 1:
24603 /* rotrv is decoded as srlv on non-R2 CPUs */
7a47bae5 24604 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 24605 op1 = OPC_ROTRV;
26135ead 24606 }
099e5b4d
LA
24607 /* Fallthrough */
24608 case 0:
24609 gen_shift(ctx, op1, rd, rs, rt);
26135ead 24610 break;
099e5b4d 24611 default:
3a4ef3b7 24612 gen_reserved_instruction(ctx);
6af0bf9c 24613 break;
099e5b4d
LA
24614 }
24615 break;
24616 case OPC_SLT: /* Set on less than */
24617 case OPC_SLTU:
24618 gen_slt(ctx, op1, rd, rs, rt);
24619 break;
24620 case OPC_AND: /* Logic*/
24621 case OPC_OR:
24622 case OPC_NOR:
24623 case OPC_XOR:
24624 gen_logic(ctx, op1, rd, rs, rt);
24625 break;
0aefa333 24626 case OPC_JALR:
b231c103 24627 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 24628 break;
c2e19f3c
AM
24629 case OPC_TGE: /* Traps */
24630 case OPC_TGEU:
24631 case OPC_TLT:
24632 case OPC_TLTU:
24633 case OPC_TEQ:
099e5b4d 24634 case OPC_TNE:
d9224450 24635 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
24636 gen_trap(ctx, op1, rs, rt, -1);
24637 break;
d4ea6acd 24638 case OPC_LSA: /* OPC_PMON */
25a13628 24639 if ((ctx->insn_flags & ISA_MIPS_R6) || ase_msa_available(env)) {
d4ea6acd
LA
24640 decode_opc_special_r6(env, ctx);
24641 } else {
24642 /* Pmon entry point, also R4010 selsl */
b48cfdff 24643#ifdef MIPS_STRICT_STANDARD
d4ea6acd 24644 MIPS_INVAL("PMON / selsl");
3a4ef3b7 24645 gen_reserved_instruction(ctx);
b48cfdff 24646#else
d4ea6acd 24647 gen_helper_0e0i(pmon, sa);
b48cfdff 24648#endif
d4ea6acd 24649 }
099e5b4d
LA
24650 break;
24651 case OPC_SYSCALL:
9c708c7f 24652 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
24653 break;
24654 case OPC_BREAK:
9c708c7f 24655 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 24656 break;
099e5b4d 24657 case OPC_SYNC:
d9224450 24658 check_insn(ctx, ISA_MIPS2);
d208ac0c 24659 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 24660 break;
4ad40f36 24661
d26bc211 24662#if defined(TARGET_MIPS64)
099e5b4d
LA
24663 /* MIPS64 specific opcodes */
24664 case OPC_DSLL:
24665 case OPC_DSRA:
24666 case OPC_DSLL32:
24667 case OPC_DSRA32:
24668 check_insn(ctx, ISA_MIPS3);
24669 check_mips_64(ctx);
24670 gen_shift_imm(ctx, op1, rd, rt, sa);
24671 break;
24672 case OPC_DSRL:
24673 switch ((ctx->opcode >> 21) & 0x1f) {
24674 case 1:
24675 /* drotr is decoded as dsrl on non-R2 CPUs */
7a47bae5 24676 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 24677 op1 = OPC_DROTR;
ea63e2c3 24678 }
099e5b4d
LA
24679 /* Fallthrough */
24680 case 0:
d75c135e 24681 check_insn(ctx, ISA_MIPS3);
e189e748 24682 check_mips_64(ctx);
099e5b4d 24683 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24684 break;
099e5b4d 24685 default:
3a4ef3b7 24686 gen_reserved_instruction(ctx);
460f00c4 24687 break;
099e5b4d
LA
24688 }
24689 break;
24690 case OPC_DSRL32:
24691 switch ((ctx->opcode >> 21) & 0x1f) {
24692 case 1:
24693 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
7a47bae5 24694 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 24695 op1 = OPC_DROTR32;
ea63e2c3 24696 }
099e5b4d
LA
24697 /* Fallthrough */
24698 case 0:
d75c135e 24699 check_insn(ctx, ISA_MIPS3);
e189e748 24700 check_mips_64(ctx);
099e5b4d 24701 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24702 break;
099e5b4d 24703 default:
3a4ef3b7 24704 gen_reserved_instruction(ctx);
6af0bf9c
FB
24705 break;
24706 }
24707 break;
c2e19f3c
AM
24708 case OPC_DADD:
24709 case OPC_DADDU:
24710 case OPC_DSUB:
24711 case OPC_DSUBU:
099e5b4d
LA
24712 check_insn(ctx, ISA_MIPS3);
24713 check_mips_64(ctx);
24714 gen_arith(ctx, op1, rd, rs, rt);
24715 break;
24716 case OPC_DSLLV:
24717 case OPC_DSRAV:
24718 check_insn(ctx, ISA_MIPS3);
24719 check_mips_64(ctx);
24720 gen_shift(ctx, op1, rd, rs, rt);
24721 break;
24722 case OPC_DSRLV:
24723 switch ((ctx->opcode >> 6) & 0x1f) {
24724 case 1:
24725 /* drotrv is decoded as dsrlv on non-R2 CPUs */
7a47bae5 24726 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 24727 op1 = OPC_DROTRV;
6af0bf9c 24728 }
099e5b4d
LA
24729 /* Fallthrough */
24730 case 0:
24731 check_insn(ctx, ISA_MIPS3);
e189e748 24732 check_mips_64(ctx);
099e5b4d 24733 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 24734 break;
099e5b4d 24735 default:
3a4ef3b7 24736 gen_reserved_instruction(ctx);
6af0bf9c
FB
24737 break;
24738 }
24739 break;
f7685877 24740 case OPC_DLSA:
25a13628 24741 if ((ctx->insn_flags & ISA_MIPS_R6) || ase_msa_available(env)) {
f7685877
YK
24742 decode_opc_special_r6(env, ctx);
24743 }
24744 break;
099e5b4d 24745#endif
10dc65db 24746 default:
2e211e0a 24747 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db 24748 decode_opc_special_r6(env, ctx);
9dc324ce
FN
24749 } else if (ctx->insn_flags & INSN_R5900) {
24750 decode_opc_special_tx79(env, ctx);
10dc65db
LA
24751 } else {
24752 decode_opc_special_legacy(env, ctx);
24753 }
24754 }
24755}
24756
d67da337 24757
37b9aae2
MM
24758#if defined(TARGET_MIPS64)
24759
24760/*
24761 *
24762 * MMI (MultiMedia Interface) ASE instructions
24763 * ===========================================
24764 */
24765
24766/*
24767 * MMI instructions category: data communication
24768 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24769 *
24770 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24771 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24772 * PCPYUD PEXEH PEXTLW PPACW
24773 * PEXEW PEXTUB
24774 * PEXTUH
24775 * PEXTUW
24776 */
24777
d3434d9f
MM
24778/*
24779 * PCPYH rd, rt
24780 *
24781 * Parallel Copy Halfword
24782 *
24783 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24784 * +-----------+---------+---------+---------+---------+-----------+
24785 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24786 * +-----------+---------+---------+---------+---------+-----------+
24787 */
24788static void gen_mmi_pcpyh(DisasContext *ctx)
24789{
24790 uint32_t pd, rt, rd;
24791 uint32_t opcode;
24792
24793 opcode = ctx->opcode;
24794
24795 pd = extract32(opcode, 21, 5);
24796 rt = extract32(opcode, 16, 5);
24797 rd = extract32(opcode, 11, 5);
24798
24799 if (unlikely(pd != 0)) {
3a4ef3b7 24800 gen_reserved_instruction(ctx);
d3434d9f
MM
24801 } else if (rd == 0) {
24802 /* nop */
24803 } else if (rt == 0) {
24804 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24805 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24806 } else {
24807 TCGv_i64 t0 = tcg_temp_new();
24808 TCGv_i64 t1 = tcg_temp_new();
24809 uint64_t mask = (1ULL << 16) - 1;
24810
24811 tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24812 tcg_gen_movi_i64(t1, 0);
24813 tcg_gen_or_i64(t1, t0, t1);
24814 tcg_gen_shli_i64(t0, t0, 16);
24815 tcg_gen_or_i64(t1, t0, t1);
24816 tcg_gen_shli_i64(t0, t0, 16);
24817 tcg_gen_or_i64(t1, t0, t1);
24818 tcg_gen_shli_i64(t0, t0, 16);
24819 tcg_gen_or_i64(t1, t0, t1);
24820
24821 tcg_gen_mov_i64(cpu_gpr[rd], t1);
24822
24823 tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24824 tcg_gen_movi_i64(t1, 0);
24825 tcg_gen_or_i64(t1, t0, t1);
24826 tcg_gen_shli_i64(t0, t0, 16);
24827 tcg_gen_or_i64(t1, t0, t1);
24828 tcg_gen_shli_i64(t0, t0, 16);
24829 tcg_gen_or_i64(t1, t0, t1);
24830 tcg_gen_shli_i64(t0, t0, 16);
24831 tcg_gen_or_i64(t1, t0, t1);
24832
24833 tcg_gen_mov_i64(cpu_mmr[rd], t1);
24834
24835 tcg_temp_free(t0);
24836 tcg_temp_free(t1);
24837 }
24838}
24839
b87eef31
MM
24840/*
24841 * PCPYLD rd, rs, rt
24842 *
24843 * Parallel Copy Lower Doubleword
24844 *
24845 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24846 * +-----------+---------+---------+---------+---------+-----------+
24847 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24848 * +-----------+---------+---------+---------+---------+-----------+
24849 */
24850static void gen_mmi_pcpyld(DisasContext *ctx)
24851{
24852 uint32_t rs, rt, rd;
24853 uint32_t opcode;
24854
24855 opcode = ctx->opcode;
24856
24857 rs = extract32(opcode, 21, 5);
24858 rt = extract32(opcode, 16, 5);
24859 rd = extract32(opcode, 11, 5);
24860
24861 if (rd == 0) {
24862 /* nop */
24863 } else {
24864 if (rs == 0) {
24865 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24866 } else {
24867 tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24868 }
24869 if (rt == 0) {
24870 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24871 } else {
24872 if (rd != rt) {
24873 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24874 }
24875 }
24876 }
24877}
24878
fd487f83
MM
24879/*
24880 * PCPYUD rd, rs, rt
24881 *
24882 * Parallel Copy Upper Doubleword
24883 *
24884 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24885 * +-----------+---------+---------+---------+---------+-----------+
24886 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24887 * +-----------+---------+---------+---------+---------+-----------+
24888 */
24889static void gen_mmi_pcpyud(DisasContext *ctx)
24890{
24891 uint32_t rs, rt, rd;
24892 uint32_t opcode;
24893
24894 opcode = ctx->opcode;
24895
24896 rs = extract32(opcode, 21, 5);
24897 rt = extract32(opcode, 16, 5);
24898 rd = extract32(opcode, 11, 5);
24899
24900 if (rd == 0) {
24901 /* nop */
24902 } else {
24903 if (rs == 0) {
24904 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24905 } else {
24906 tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24907 }
24908 if (rt == 0) {
24909 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24910 } else {
24911 if (rd != rt) {
24912 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24913 }
24914 }
24915 }
24916}
24917
37b9aae2
MM
24918#endif
24919
24920
b621f018
AM
24921#if !defined(TARGET_MIPS64)
24922
d67da337
AM
24923/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24924#define MXU_APTN1_A 0
24925#define MXU_APTN1_S 1
24926
b70bb918
CJ
24927/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24928#define MXU_APTN2_AA 0
24929#define MXU_APTN2_AS 1
24930#define MXU_APTN2_SA 2
24931#define MXU_APTN2_SS 3
24932
5bb29992
AM
24933/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24934#define MXU_EPTN2_AA 0
24935#define MXU_EPTN2_AS 1
24936#define MXU_EPTN2_SA 2
24937#define MXU_EPTN2_SS 3
24938
a35723f4 24939/* MXU operand getting pattern 'optn2' */
16fef5b2
AM
24940#define MXU_OPTN2_PTN0 0
24941#define MXU_OPTN2_PTN1 1
24942#define MXU_OPTN2_PTN2 2
24943#define MXU_OPTN2_PTN3 3
24944/* alternative naming scheme for 'optn2' */
a35723f4
CJ
24945#define MXU_OPTN2_WW 0
24946#define MXU_OPTN2_LW 1
24947#define MXU_OPTN2_HW 2
24948#define MXU_OPTN2_XW 3
24949
53f1131f
CJ
24950/* MXU operand getting pattern 'optn3' */
24951#define MXU_OPTN3_PTN0 0
24952#define MXU_OPTN3_PTN1 1
24953#define MXU_OPTN3_PTN2 2
24954#define MXU_OPTN3_PTN3 3
24955#define MXU_OPTN3_PTN4 4
24956#define MXU_OPTN3_PTN5 5
24957#define MXU_OPTN3_PTN6 6
24958#define MXU_OPTN3_PTN7 7
24959
d67da337 24960
96992d1a
CJ
24961/*
24962 * S32I2M XRa, rb - Register move from GRF to XRF
24963 */
24964static void gen_mxu_s32i2m(DisasContext *ctx)
24965{
24966 TCGv t0;
24967 uint32_t XRa, Rb;
24968
24969 t0 = tcg_temp_new();
24970
24971 XRa = extract32(ctx->opcode, 6, 5);
24972 Rb = extract32(ctx->opcode, 16, 5);
24973
24974 gen_load_gpr(t0, Rb);
24975 if (XRa <= 15) {
24976 gen_store_mxu_gpr(t0, XRa);
24977 } else if (XRa == 16) {
24978 gen_store_mxu_cr(t0);
24979 }
24980
24981 tcg_temp_free(t0);
24982}
24983
24984/*
24985 * S32M2I XRa, rb - Register move from XRF to GRF
24986 */
24987static void gen_mxu_s32m2i(DisasContext *ctx)
24988{
24989 TCGv t0;
24990 uint32_t XRa, Rb;
24991
24992 t0 = tcg_temp_new();
24993
24994 XRa = extract32(ctx->opcode, 6, 5);
24995 Rb = extract32(ctx->opcode, 16, 5);
24996
24997 if (XRa <= 15) {
24998 gen_load_mxu_gpr(t0, XRa);
24999 } else if (XRa == 16) {
25000 gen_load_mxu_cr(t0);
25001 }
25002
25003 gen_store_gpr(t0, Rb);
25004
25005 tcg_temp_free(t0);
25006}
25007
be57bcdb
CJ
25008/*
25009 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25010 */
25011static void gen_mxu_s8ldd(DisasContext *ctx)
25012{
25013 TCGv t0, t1;
be57bcdb
CJ
25014 uint32_t XRa, Rb, s8, optn3;
25015
25016 t0 = tcg_temp_new();
25017 t1 = tcg_temp_new();
25018
be57bcdb
CJ
25019 XRa = extract32(ctx->opcode, 6, 4);
25020 s8 = extract32(ctx->opcode, 10, 8);
25021 optn3 = extract32(ctx->opcode, 18, 3);
25022 Rb = extract32(ctx->opcode, 21, 5);
25023
be57bcdb
CJ
25024 gen_load_gpr(t0, Rb);
25025 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
25026
25027 switch (optn3) {
25028 /* XRa[7:0] = tmp8 */
25029 case MXU_OPTN3_PTN0:
25030 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25031 gen_load_mxu_gpr(t0, XRa);
25032 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
25033 break;
25034 /* XRa[15:8] = tmp8 */
25035 case MXU_OPTN3_PTN1:
25036 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25037 gen_load_mxu_gpr(t0, XRa);
25038 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
25039 break;
25040 /* XRa[23:16] = tmp8 */
25041 case MXU_OPTN3_PTN2:
25042 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25043 gen_load_mxu_gpr(t0, XRa);
25044 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
25045 break;
25046 /* XRa[31:24] = tmp8 */
25047 case MXU_OPTN3_PTN3:
25048 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25049 gen_load_mxu_gpr(t0, XRa);
25050 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
25051 break;
25052 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25053 case MXU_OPTN3_PTN4:
25054 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25055 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25056 break;
25057 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25058 case MXU_OPTN3_PTN5:
25059 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25060 tcg_gen_shli_tl(t1, t1, 8);
25061 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25062 break;
25063 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25064 case MXU_OPTN3_PTN6:
25065 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
25066 tcg_gen_mov_tl(t0, t1);
25067 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
25068 tcg_gen_shli_tl(t1, t1, 16);
25069 tcg_gen_or_tl(t0, t0, t1);
25070 break;
25071 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25072 case MXU_OPTN3_PTN7:
25073 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25074 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
25075 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25076 break;
25077 }
25078
25079 gen_store_mxu_gpr(t0, XRa);
25080
be57bcdb
CJ
25081 tcg_temp_free(t0);
25082 tcg_temp_free(t1);
25083}
25084
72c9bcf8
CJ
25085/*
25086 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25087 */
25088static void gen_mxu_d16mul(DisasContext *ctx)
25089{
25090 TCGv t0, t1, t2, t3;
72c9bcf8
CJ
25091 uint32_t XRa, XRb, XRc, XRd, optn2;
25092
25093 t0 = tcg_temp_new();
25094 t1 = tcg_temp_new();
25095 t2 = tcg_temp_new();
25096 t3 = tcg_temp_new();
25097
72c9bcf8
CJ
25098 XRa = extract32(ctx->opcode, 6, 4);
25099 XRb = extract32(ctx->opcode, 10, 4);
25100 XRc = extract32(ctx->opcode, 14, 4);
25101 XRd = extract32(ctx->opcode, 18, 4);
25102 optn2 = extract32(ctx->opcode, 22, 2);
25103
72c9bcf8
CJ
25104 gen_load_mxu_gpr(t1, XRb);
25105 tcg_gen_sextract_tl(t0, t1, 0, 16);
25106 tcg_gen_sextract_tl(t1, t1, 16, 16);
25107 gen_load_mxu_gpr(t3, XRc);
25108 tcg_gen_sextract_tl(t2, t3, 0, 16);
25109 tcg_gen_sextract_tl(t3, t3, 16, 16);
25110
25111 switch (optn2) {
25112 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25113 tcg_gen_mul_tl(t3, t1, t3);
25114 tcg_gen_mul_tl(t2, t0, t2);
25115 break;
25116 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25117 tcg_gen_mul_tl(t3, t0, t3);
25118 tcg_gen_mul_tl(t2, t0, t2);
25119 break;
25120 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25121 tcg_gen_mul_tl(t3, t1, t3);
25122 tcg_gen_mul_tl(t2, t1, t2);
25123 break;
25124 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25125 tcg_gen_mul_tl(t3, t0, t3);
25126 tcg_gen_mul_tl(t2, t1, t2);
25127 break;
25128 }
25129 gen_store_mxu_gpr(t3, XRa);
25130 gen_store_mxu_gpr(t2, XRd);
25131
72c9bcf8
CJ
25132 tcg_temp_free(t0);
25133 tcg_temp_free(t1);
25134 tcg_temp_free(t2);
25135 tcg_temp_free(t3);
25136}
25137
e67915b4
CJ
25138/*
25139 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25140 * and accumulate
25141 */
25142static void gen_mxu_d16mac(DisasContext *ctx)
25143{
25144 TCGv t0, t1, t2, t3;
e67915b4
CJ
25145 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
25146
25147 t0 = tcg_temp_new();
25148 t1 = tcg_temp_new();
25149 t2 = tcg_temp_new();
25150 t3 = tcg_temp_new();
25151
e67915b4
CJ
25152 XRa = extract32(ctx->opcode, 6, 4);
25153 XRb = extract32(ctx->opcode, 10, 4);
25154 XRc = extract32(ctx->opcode, 14, 4);
25155 XRd = extract32(ctx->opcode, 18, 4);
25156 optn2 = extract32(ctx->opcode, 22, 2);
25157 aptn2 = extract32(ctx->opcode, 24, 2);
25158
e67915b4
CJ
25159 gen_load_mxu_gpr(t1, XRb);
25160 tcg_gen_sextract_tl(t0, t1, 0, 16);
25161 tcg_gen_sextract_tl(t1, t1, 16, 16);
25162
25163 gen_load_mxu_gpr(t3, XRc);
25164 tcg_gen_sextract_tl(t2, t3, 0, 16);
25165 tcg_gen_sextract_tl(t3, t3, 16, 16);
25166
25167 switch (optn2) {
25168 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25169 tcg_gen_mul_tl(t3, t1, t3);
25170 tcg_gen_mul_tl(t2, t0, t2);
25171 break;
25172 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25173 tcg_gen_mul_tl(t3, t0, t3);
25174 tcg_gen_mul_tl(t2, t0, t2);
25175 break;
25176 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25177 tcg_gen_mul_tl(t3, t1, t3);
25178 tcg_gen_mul_tl(t2, t1, t2);
25179 break;
25180 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25181 tcg_gen_mul_tl(t3, t0, t3);
25182 tcg_gen_mul_tl(t2, t1, t2);
25183 break;
25184 }
25185 gen_load_mxu_gpr(t0, XRa);
25186 gen_load_mxu_gpr(t1, XRd);
25187
25188 switch (aptn2) {
25189 case MXU_APTN2_AA:
25190 tcg_gen_add_tl(t3, t0, t3);
25191 tcg_gen_add_tl(t2, t1, t2);
25192 break;
25193 case MXU_APTN2_AS:
25194 tcg_gen_add_tl(t3, t0, t3);
25195 tcg_gen_sub_tl(t2, t1, t2);
25196 break;
25197 case MXU_APTN2_SA:
25198 tcg_gen_sub_tl(t3, t0, t3);
25199 tcg_gen_add_tl(t2, t1, t2);
25200 break;
25201 case MXU_APTN2_SS:
25202 tcg_gen_sub_tl(t3, t0, t3);
25203 tcg_gen_sub_tl(t2, t1, t2);
25204 break;
25205 }
25206 gen_store_mxu_gpr(t3, XRa);
25207 gen_store_mxu_gpr(t2, XRd);
25208
e67915b4
CJ
25209 tcg_temp_free(t0);
25210 tcg_temp_free(t1);
25211 tcg_temp_free(t2);
25212 tcg_temp_free(t3);
25213}
25214
a9a4181b
CJ
25215/*
25216 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25217 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25218 */
25219static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
25220{
25221 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
a9a4181b
CJ
25222 uint32_t XRa, XRb, XRc, XRd, sel;
25223
25224 t0 = tcg_temp_new();
25225 t1 = tcg_temp_new();
25226 t2 = tcg_temp_new();
25227 t3 = tcg_temp_new();
25228 t4 = tcg_temp_new();
25229 t5 = tcg_temp_new();
25230 t6 = tcg_temp_new();
25231 t7 = tcg_temp_new();
25232
a9a4181b
CJ
25233 XRa = extract32(ctx->opcode, 6, 4);
25234 XRb = extract32(ctx->opcode, 10, 4);
25235 XRc = extract32(ctx->opcode, 14, 4);
25236 XRd = extract32(ctx->opcode, 18, 4);
25237 sel = extract32(ctx->opcode, 22, 2);
25238
a9a4181b
CJ
25239 gen_load_mxu_gpr(t3, XRb);
25240 gen_load_mxu_gpr(t7, XRc);
25241
25242 if (sel == 0x2) {
25243 /* Q8MULSU */
25244 tcg_gen_ext8s_tl(t0, t3);
25245 tcg_gen_shri_tl(t3, t3, 8);
25246 tcg_gen_ext8s_tl(t1, t3);
25247 tcg_gen_shri_tl(t3, t3, 8);
25248 tcg_gen_ext8s_tl(t2, t3);
25249 tcg_gen_shri_tl(t3, t3, 8);
25250 tcg_gen_ext8s_tl(t3, t3);
25251 } else {
25252 /* Q8MUL */
25253 tcg_gen_ext8u_tl(t0, t3);
25254 tcg_gen_shri_tl(t3, t3, 8);
25255 tcg_gen_ext8u_tl(t1, t3);
25256 tcg_gen_shri_tl(t3, t3, 8);
25257 tcg_gen_ext8u_tl(t2, t3);
25258 tcg_gen_shri_tl(t3, t3, 8);
25259 tcg_gen_ext8u_tl(t3, t3);
25260 }
25261
25262 tcg_gen_ext8u_tl(t4, t7);
25263 tcg_gen_shri_tl(t7, t7, 8);
25264 tcg_gen_ext8u_tl(t5, t7);
25265 tcg_gen_shri_tl(t7, t7, 8);
25266 tcg_gen_ext8u_tl(t6, t7);
25267 tcg_gen_shri_tl(t7, t7, 8);
25268 tcg_gen_ext8u_tl(t7, t7);
25269
25270 tcg_gen_mul_tl(t0, t0, t4);
25271 tcg_gen_mul_tl(t1, t1, t5);
25272 tcg_gen_mul_tl(t2, t2, t6);
25273 tcg_gen_mul_tl(t3, t3, t7);
25274
25275 tcg_gen_andi_tl(t0, t0, 0xFFFF);
25276 tcg_gen_andi_tl(t1, t1, 0xFFFF);
25277 tcg_gen_andi_tl(t2, t2, 0xFFFF);
25278 tcg_gen_andi_tl(t3, t3, 0xFFFF);
25279
25280 tcg_gen_shli_tl(t1, t1, 16);
25281 tcg_gen_shli_tl(t3, t3, 16);
25282
25283 tcg_gen_or_tl(t0, t0, t1);
25284 tcg_gen_or_tl(t1, t2, t3);
25285
25286 gen_store_mxu_gpr(t0, XRd);
25287 gen_store_mxu_gpr(t1, XRa);
25288
a9a4181b
CJ
25289 tcg_temp_free(t0);
25290 tcg_temp_free(t1);
25291 tcg_temp_free(t2);
25292 tcg_temp_free(t3);
25293 tcg_temp_free(t4);
25294 tcg_temp_free(t5);
25295 tcg_temp_free(t6);
25296 tcg_temp_free(t7);
25297}
25298
4ca83721
CJ
25299/*
25300 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25301 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25302 */
25303static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25304{
25305 TCGv t0, t1;
4ca83721
CJ
25306 uint32_t XRa, Rb, s12, sel;
25307
25308 t0 = tcg_temp_new();
25309 t1 = tcg_temp_new();
25310
4ca83721
CJ
25311 XRa = extract32(ctx->opcode, 6, 4);
25312 s12 = extract32(ctx->opcode, 10, 10);
25313 sel = extract32(ctx->opcode, 20, 1);
25314 Rb = extract32(ctx->opcode, 21, 5);
25315
4ca83721
CJ
25316 gen_load_gpr(t0, Rb);
25317
25318 tcg_gen_movi_tl(t1, s12);
25319 tcg_gen_shli_tl(t1, t1, 2);
25320 if (s12 & 0x200) {
25321 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25322 }
25323 tcg_gen_add_tl(t1, t0, t1);
25324 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25325
25326 if (sel == 1) {
25327 /* S32LDDR */
25328 tcg_gen_bswap32_tl(t1, t1);
25329 }
25330 gen_store_mxu_gpr(t1, XRa);
25331
4ca83721
CJ
25332 tcg_temp_free(t0);
25333 tcg_temp_free(t1);
25334}
25335
96992d1a 25336
b621f018
AM
25337/*
25338 * MXU instruction category: logic
25339 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25340 *
25341 * S32NOR S32AND S32OR S32XOR
25342 */
25343
25344/*
25345 * S32NOR XRa, XRb, XRc
25346 * Update XRa with the result of logical bitwise 'nor' operation
25347 * applied to the content of XRb and XRc.
25348 *
25349 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25350 * +-----------+---------+-----+-------+-------+-------+-----------+
25351 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25352 * +-----------+---------+-----+-------+-------+-------+-----------+
25353 */
25354static void gen_mxu_S32NOR(DisasContext *ctx)
25355{
25356 uint32_t pad, XRc, XRb, XRa;
25357
25358 pad = extract32(ctx->opcode, 21, 5);
25359 XRc = extract32(ctx->opcode, 14, 4);
25360 XRb = extract32(ctx->opcode, 10, 4);
25361 XRa = extract32(ctx->opcode, 6, 4);
25362
25363 if (unlikely(pad != 0)) {
25364 /* opcode padding incorrect -> do nothing */
25365 } else if (unlikely(XRa == 0)) {
25366 /* destination is zero register -> do nothing */
25367 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25368 /* both operands zero registers -> just set destination to all 1s */
25369 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25370 } else if (unlikely(XRb == 0)) {
25371 /* XRb zero register -> just set destination to the negation of XRc */
25372 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25373 } else if (unlikely(XRc == 0)) {
25374 /* XRa zero register -> just set destination to the negation of XRb */
25375 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25376 } else if (unlikely(XRb == XRc)) {
25377 /* both operands same -> just set destination to the negation of XRb */
25378 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25379 } else {
25380 /* the most general case */
25381 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25382 }
25383}
25384
25385/*
25386 * S32AND XRa, XRb, XRc
25387 * Update XRa with the result of logical bitwise 'and' operation
25388 * applied to the content of XRb and XRc.
25389 *
25390 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25391 * +-----------+---------+-----+-------+-------+-------+-----------+
25392 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25393 * +-----------+---------+-----+-------+-------+-------+-----------+
25394 */
25395static void gen_mxu_S32AND(DisasContext *ctx)
25396{
25397 uint32_t pad, XRc, XRb, XRa;
25398
25399 pad = extract32(ctx->opcode, 21, 5);
25400 XRc = extract32(ctx->opcode, 14, 4);
25401 XRb = extract32(ctx->opcode, 10, 4);
25402 XRa = extract32(ctx->opcode, 6, 4);
25403
25404 if (unlikely(pad != 0)) {
25405 /* opcode padding incorrect -> do nothing */
25406 } else if (unlikely(XRa == 0)) {
25407 /* destination is zero register -> do nothing */
25408 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25409 /* one of operands zero register -> just set destination to all 0s */
25410 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25411 } else if (unlikely(XRb == XRc)) {
25412 /* both operands same -> just set destination to one of them */
25413 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25414 } else {
25415 /* the most general case */
25416 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25417 }
25418}
25419
25420/*
25421 * S32OR XRa, XRb, XRc
25422 * Update XRa with the result of logical bitwise 'or' operation
25423 * applied to the content of XRb and XRc.
25424 *
25425 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25426 * +-----------+---------+-----+-------+-------+-------+-----------+
25427 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25428 * +-----------+---------+-----+-------+-------+-------+-----------+
25429 */
25430static void gen_mxu_S32OR(DisasContext *ctx)
25431{
25432 uint32_t pad, XRc, XRb, XRa;
25433
25434 pad = extract32(ctx->opcode, 21, 5);
25435 XRc = extract32(ctx->opcode, 14, 4);
25436 XRb = extract32(ctx->opcode, 10, 4);
25437 XRa = extract32(ctx->opcode, 6, 4);
25438
25439 if (unlikely(pad != 0)) {
25440 /* opcode padding incorrect -> do nothing */
25441 } else if (unlikely(XRa == 0)) {
25442 /* destination is zero register -> do nothing */
25443 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25444 /* both operands zero registers -> just set destination to all 0s */
25445 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25446 } else if (unlikely(XRb == 0)) {
25447 /* XRb zero register -> just set destination to the content of XRc */
25448 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25449 } else if (unlikely(XRc == 0)) {
25450 /* XRc zero register -> just set destination to the content of XRb */
25451 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25452 } else if (unlikely(XRb == XRc)) {
25453 /* both operands same -> just set destination to one of them */
25454 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25455 } else {
25456 /* the most general case */
25457 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25458 }
25459}
25460
25461/*
25462 * S32XOR XRa, XRb, XRc
25463 * Update XRa with the result of logical bitwise 'xor' operation
25464 * applied to the content of XRb and XRc.
25465 *
25466 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25467 * +-----------+---------+-----+-------+-------+-------+-----------+
25468 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25469 * +-----------+---------+-----+-------+-------+-------+-----------+
25470 */
25471static void gen_mxu_S32XOR(DisasContext *ctx)
25472{
25473 uint32_t pad, XRc, XRb, XRa;
25474
25475 pad = extract32(ctx->opcode, 21, 5);
25476 XRc = extract32(ctx->opcode, 14, 4);
25477 XRb = extract32(ctx->opcode, 10, 4);
25478 XRa = extract32(ctx->opcode, 6, 4);
25479
25480 if (unlikely(pad != 0)) {
25481 /* opcode padding incorrect -> do nothing */
25482 } else if (unlikely(XRa == 0)) {
25483 /* destination is zero register -> do nothing */
25484 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25485 /* both operands zero registers -> just set destination to all 0s */
25486 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25487 } else if (unlikely(XRb == 0)) {
25488 /* XRb zero register -> just set destination to the content of XRc */
25489 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25490 } else if (unlikely(XRc == 0)) {
25491 /* XRc zero register -> just set destination to the content of XRb */
25492 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25493 } else if (unlikely(XRb == XRc)) {
25494 /* both operands same -> just set destination to all 0s */
25495 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25496 } else {
25497 /* the most general case */
25498 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25499 }
25500}
25501
25502
bb84cbf3
AM
25503/*
25504 * MXU instruction category max/min
25505 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25506 *
25507 * S32MAX D16MAX Q8MAX
25508 * S32MIN D16MIN Q8MIN
25509 */
25510
25511/*
25512 * S32MAX XRa, XRb, XRc
25513 * Update XRa with the maximum of signed 32-bit integers contained
25514 * in XRb and XRc.
25515 *
25516 * S32MIN XRa, XRb, XRc
25517 * Update XRa with the minimum of signed 32-bit integers contained
25518 * in XRb and XRc.
25519 *
25520 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25521 * +-----------+---------+-----+-------+-------+-------+-----------+
25522 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25523 * +-----------+---------+-----+-------+-------+-------+-----------+
25524 */
25525static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25526{
25527 uint32_t pad, opc, XRc, XRb, XRa;
25528
25529 pad = extract32(ctx->opcode, 21, 5);
25530 opc = extract32(ctx->opcode, 18, 3);
25531 XRc = extract32(ctx->opcode, 14, 4);
25532 XRb = extract32(ctx->opcode, 10, 4);
25533 XRa = extract32(ctx->opcode, 6, 4);
25534
25535 if (unlikely(pad != 0)) {
25536 /* opcode padding incorrect -> do nothing */
25537 } else if (unlikely(XRa == 0)) {
25538 /* destination is zero register -> do nothing */
25539 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25540 /* both operands zero registers -> just set destination to zero */
25541 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25542 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25543 /* exactly one operand is zero register - find which one is not...*/
25544 uint32_t XRx = XRb ? XRb : XRc;
25545 /* ...and do max/min operation with one operand 0 */
25546 if (opc == OPC_MXU_S32MAX) {
25547 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25548 } else {
25549 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25550 }
25551 } else if (unlikely(XRb == XRc)) {
25552 /* both operands same -> just set destination to one of them */
25553 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25554 } else {
25555 /* the most general case */
25556 if (opc == OPC_MXU_S32MAX) {
25557 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25558 mxu_gpr[XRc - 1]);
25559 } else {
25560 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25561 mxu_gpr[XRc - 1]);
25562 }
25563 }
25564}
25565
25566/*
25567 * D16MAX
25568 * Update XRa with the 16-bit-wise maximums of signed integers
25569 * contained in XRb and XRc.
25570 *
25571 * D16MIN
25572 * Update XRa with the 16-bit-wise minimums of signed integers
25573 * contained in XRb and XRc.
25574 *
25575 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25576 * +-----------+---------+-----+-------+-------+-------+-----------+
25577 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25578 * +-----------+---------+-----+-------+-------+-------+-----------+
25579 */
25580static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25581{
25582 uint32_t pad, opc, XRc, XRb, XRa;
25583
25584 pad = extract32(ctx->opcode, 21, 5);
25585 opc = extract32(ctx->opcode, 18, 3);
25586 XRc = extract32(ctx->opcode, 14, 4);
25587 XRb = extract32(ctx->opcode, 10, 4);
25588 XRa = extract32(ctx->opcode, 6, 4);
25589
25590 if (unlikely(pad != 0)) {
25591 /* opcode padding incorrect -> do nothing */
25592 } else if (unlikely(XRc == 0)) {
25593 /* destination is zero register -> do nothing */
25594 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25595 /* both operands zero registers -> just set destination to zero */
25596 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25597 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25598 /* exactly one operand is zero register - find which one is not...*/
25599 uint32_t XRx = XRb ? XRb : XRc;
25600 /* ...and do half-word-wise max/min with one operand 0 */
25601 TCGv_i32 t0 = tcg_temp_new();
25602 TCGv_i32 t1 = tcg_const_i32(0);
25603
25604 /* the left half-word first */
25605 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25606 if (opc == OPC_MXU_D16MAX) {
25607 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25608 } else {
25609 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25610 }
25611
25612 /* the right half-word */
25613 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25614 /* move half-words to the leftmost position */
25615 tcg_gen_shli_i32(t0, t0, 16);
25616 /* t0 will be max/min of t0 and t1 */
25617 if (opc == OPC_MXU_D16MAX) {
25618 tcg_gen_smax_i32(t0, t0, t1);
25619 } else {
25620 tcg_gen_smin_i32(t0, t0, t1);
25621 }
25622 /* return resulting half-words to its original position */
25623 tcg_gen_shri_i32(t0, t0, 16);
8cdf8869 25624 /* finally update the destination */
bb84cbf3
AM
25625 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25626
25627 tcg_temp_free(t1);
25628 tcg_temp_free(t0);
25629 } else if (unlikely(XRb == XRc)) {
25630 /* both operands same -> just set destination to one of them */
25631 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25632 } else {
25633 /* the most general case */
25634 TCGv_i32 t0 = tcg_temp_new();
25635 TCGv_i32 t1 = tcg_temp_new();
25636
25637 /* the left half-word first */
25638 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25639 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25640 if (opc == OPC_MXU_D16MAX) {
25641 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25642 } else {
25643 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25644 }
25645
25646 /* the right half-word */
25647 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25648 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25649 /* move half-words to the leftmost position */
25650 tcg_gen_shli_i32(t0, t0, 16);
25651 tcg_gen_shli_i32(t1, t1, 16);
25652 /* t0 will be max/min of t0 and t1 */
25653 if (opc == OPC_MXU_D16MAX) {
25654 tcg_gen_smax_i32(t0, t0, t1);
25655 } else {
25656 tcg_gen_smin_i32(t0, t0, t1);
25657 }
25658 /* return resulting half-words to its original position */
25659 tcg_gen_shri_i32(t0, t0, 16);
8cdf8869 25660 /* finally update the destination */
bb84cbf3
AM
25661 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25662
25663 tcg_temp_free(t1);
25664 tcg_temp_free(t0);
25665 }
25666}
25667
25668/*
25669 * Q8MAX
25670 * Update XRa with the 8-bit-wise maximums of signed integers
25671 * contained in XRb and XRc.
25672 *
25673 * Q8MIN
25674 * Update XRa with the 8-bit-wise minimums of signed integers
25675 * contained in XRb and XRc.
25676 *
25677 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25678 * +-----------+---------+-----+-------+-------+-------+-----------+
25679 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25680 * +-----------+---------+-----+-------+-------+-------+-----------+
25681 */
25682static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25683{
25684 uint32_t pad, opc, XRc, XRb, XRa;
25685
25686 pad = extract32(ctx->opcode, 21, 5);
25687 opc = extract32(ctx->opcode, 18, 3);
25688 XRc = extract32(ctx->opcode, 14, 4);
25689 XRb = extract32(ctx->opcode, 10, 4);
25690 XRa = extract32(ctx->opcode, 6, 4);
25691
25692 if (unlikely(pad != 0)) {
25693 /* opcode padding incorrect -> do nothing */
25694 } else if (unlikely(XRa == 0)) {
25695 /* destination is zero register -> do nothing */
25696 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25697 /* both operands zero registers -> just set destination to zero */
25698 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25699 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25700 /* exactly one operand is zero register - make it be the first...*/
25701 uint32_t XRx = XRb ? XRb : XRc;
25702 /* ...and do byte-wise max/min with one operand 0 */
25703 TCGv_i32 t0 = tcg_temp_new();
25704 TCGv_i32 t1 = tcg_const_i32(0);
25705 int32_t i;
25706
25707 /* the leftmost byte (byte 3) first */
25708 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25709 if (opc == OPC_MXU_Q8MAX) {
25710 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25711 } else {
25712 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25713 }
25714
25715 /* bytes 2, 1, 0 */
25716 for (i = 2; i >= 0; i--) {
25717 /* extract the byte */
25718 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25719 /* move the byte to the leftmost position */
25720 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25721 /* t0 will be max/min of t0 and t1 */
25722 if (opc == OPC_MXU_Q8MAX) {
25723 tcg_gen_smax_i32(t0, t0, t1);
25724 } else {
25725 tcg_gen_smin_i32(t0, t0, t1);
25726 }
25727 /* return resulting byte to its original position */
25728 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
8cdf8869 25729 /* finally update the destination */
bb84cbf3
AM
25730 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25731 }
25732
25733 tcg_temp_free(t1);
25734 tcg_temp_free(t0);
25735 } else if (unlikely(XRb == XRc)) {
25736 /* both operands same -> just set destination to one of them */
25737 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25738 } else {
25739 /* the most general case */
25740 TCGv_i32 t0 = tcg_temp_new();
25741 TCGv_i32 t1 = tcg_temp_new();
25742 int32_t i;
25743
25744 /* the leftmost bytes (bytes 3) first */
25745 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25746 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25747 if (opc == OPC_MXU_Q8MAX) {
25748 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25749 } else {
25750 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25751 }
25752
25753 /* bytes 2, 1, 0 */
25754 for (i = 2; i >= 0; i--) {
25755 /* extract corresponding bytes */
25756 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25757 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25758 /* move the bytes to the leftmost position */
25759 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25760 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25761 /* t0 will be max/min of t0 and t1 */
25762 if (opc == OPC_MXU_Q8MAX) {
25763 tcg_gen_smax_i32(t0, t0, t1);
25764 } else {
25765 tcg_gen_smin_i32(t0, t0, t1);
25766 }
25767 /* return resulting byte to its original position */
25768 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
8cdf8869 25769 /* finally update the destination */
bb84cbf3
AM
25770 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25771 }
25772
25773 tcg_temp_free(t1);
25774 tcg_temp_free(t0);
25775 }
25776}
25777
25778
79f5fee7
AM
25779/*
25780 * MXU instruction category: align
25781 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25782 *
25783 * S32ALN S32ALNI
25784 */
25785
25786/*
25787 * S32ALNI XRc, XRb, XRa, optn3
25788 * Arrange bytes from XRb and XRc according to one of five sets of
25789 * rules determined by optn3, and place the result in XRa.
25790 *
25791 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25792 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25793 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25794 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25795 *
25796 */
25797static void gen_mxu_S32ALNI(DisasContext *ctx)
25798{
25799 uint32_t optn3, pad, XRc, XRb, XRa;
25800
25801 optn3 = extract32(ctx->opcode, 23, 3);
25802 pad = extract32(ctx->opcode, 21, 2);
25803 XRc = extract32(ctx->opcode, 14, 4);
25804 XRb = extract32(ctx->opcode, 10, 4);
25805 XRa = extract32(ctx->opcode, 6, 4);
25806
25807 if (unlikely(pad != 0)) {
25808 /* opcode padding incorrect -> do nothing */
25809 } else if (unlikely(XRa == 0)) {
25810 /* destination is zero register -> do nothing */
25811 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25812 /* both operands zero registers -> just set destination to all 0s */
25813 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25814 } else if (unlikely(XRb == 0)) {
25815 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25816 switch (optn3) {
25817 case MXU_OPTN3_PTN0:
25818 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25819 break;
25820 case MXU_OPTN3_PTN1:
25821 case MXU_OPTN3_PTN2:
25822 case MXU_OPTN3_PTN3:
25823 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25824 8 * (4 - optn3));
25825 break;
25826 case MXU_OPTN3_PTN4:
25827 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25828 break;
25829 }
25830 } else if (unlikely(XRc == 0)) {
25831 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25832 switch (optn3) {
25833 case MXU_OPTN3_PTN0:
25834 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25835 break;
25836 case MXU_OPTN3_PTN1:
25837 case MXU_OPTN3_PTN2:
25838 case MXU_OPTN3_PTN3:
25839 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25840 break;
25841 case MXU_OPTN3_PTN4:
25842 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25843 break;
25844 }
25845 } else if (unlikely(XRb == XRc)) {
25846 /* both operands same -> just rotation or moving from any of them */
25847 switch (optn3) {
25848 case MXU_OPTN3_PTN0:
25849 case MXU_OPTN3_PTN4:
25850 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25851 break;
25852 case MXU_OPTN3_PTN1:
25853 case MXU_OPTN3_PTN2:
25854 case MXU_OPTN3_PTN3:
25855 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25856 break;
25857 }
25858 } else {
25859 /* the most general case */
25860 switch (optn3) {
25861 case MXU_OPTN3_PTN0:
25862 {
25863 /* */
25864 /* XRb XRc */
25865 /* +---------------+ */
25866 /* | A B C D | E F G H */
25867 /* +-------+-------+ */
25868 /* | */
25869 /* XRa */
25870 /* */
25871
25872 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25873 }
25874 break;
25875 case MXU_OPTN3_PTN1:
25876 {
25877 /* */
25878 /* XRb XRc */
25879 /* +-------------------+ */
25880 /* A | B C D E | F G H */
25881 /* +---------+---------+ */
25882 /* | */
25883 /* XRa */
25884 /* */
25885
25886 TCGv_i32 t0 = tcg_temp_new();
25887 TCGv_i32 t1 = tcg_temp_new();
25888
25889 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25890 tcg_gen_shli_i32(t0, t0, 8);
25891
25892 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25893 tcg_gen_shri_i32(t1, t1, 24);
25894
25895 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25896
25897 tcg_temp_free(t1);
25898 tcg_temp_free(t0);
25899 }
25900 break;
25901 case MXU_OPTN3_PTN2:
25902 {
25903 /* */
25904 /* XRb XRc */
25905 /* +-------------------+ */
25906 /* A B | C D E F | G H */
25907 /* +---------+---------+ */
25908 /* | */
25909 /* XRa */
25910 /* */
25911
25912 TCGv_i32 t0 = tcg_temp_new();
25913 TCGv_i32 t1 = tcg_temp_new();
25914
25915 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25916 tcg_gen_shli_i32(t0, t0, 16);
25917
25918 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25919 tcg_gen_shri_i32(t1, t1, 16);
25920
25921 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25922
25923 tcg_temp_free(t1);
25924 tcg_temp_free(t0);
25925 }
25926 break;
25927 case MXU_OPTN3_PTN3:
25928 {
25929 /* */
25930 /* XRb XRc */
25931 /* +-------------------+ */
25932 /* A B C | D E F G | H */
25933 /* +---------+---------+ */
25934 /* | */
25935 /* XRa */
25936 /* */
25937
25938 TCGv_i32 t0 = tcg_temp_new();
25939 TCGv_i32 t1 = tcg_temp_new();
25940
25941 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25942 tcg_gen_shli_i32(t0, t0, 24);
25943
25944 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25945 tcg_gen_shri_i32(t1, t1, 8);
25946
25947 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25948
25949 tcg_temp_free(t1);
25950 tcg_temp_free(t0);
25951 }
25952 break;
25953 case MXU_OPTN3_PTN4:
25954 {
25955 /* */
25956 /* XRb XRc */
25957 /* +---------------+ */
25958 /* A B C D | E F G H | */
25959 /* +-------+-------+ */
25960 /* | */
25961 /* XRa */
25962 /* */
25963
25964 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25965 }
25966 break;
25967 }
25968 }
25969}
25970
25971
96992d1a
CJ
25972/*
25973 * Decoding engine for MXU
25974 * =======================
25975 */
25976
03f40088
AM
25977/*
25978 *
25979 * Decode MXU pool00
25980 *
25981 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25982 * +-----------+---------+-----+-------+-------+-------+-----------+
25983 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25984 * +-----------+---------+-----+-------+-------+-------+-----------+
25985 *
25986 */
25987static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25988{
25989 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25990
25991 switch (opcode) {
25992 case OPC_MXU_S32MAX:
03f40088 25993 case OPC_MXU_S32MIN:
bb84cbf3 25994 gen_mxu_S32MAX_S32MIN(ctx);
03f40088
AM
25995 break;
25996 case OPC_MXU_D16MAX:
03f40088 25997 case OPC_MXU_D16MIN:
bb84cbf3 25998 gen_mxu_D16MAX_D16MIN(ctx);
03f40088
AM
25999 break;
26000 case OPC_MXU_Q8MAX:
03f40088 26001 case OPC_MXU_Q8MIN:
bb84cbf3 26002 gen_mxu_Q8MAX_Q8MIN(ctx);
03f40088
AM
26003 break;
26004 case OPC_MXU_Q8SLT:
26005 /* TODO: Implement emulation of Q8SLT instruction. */
26006 MIPS_INVAL("OPC_MXU_Q8SLT");
3a4ef3b7 26007 gen_reserved_instruction(ctx);
03f40088
AM
26008 break;
26009 case OPC_MXU_Q8SLTU:
26010 /* TODO: Implement emulation of Q8SLTU instruction. */
26011 MIPS_INVAL("OPC_MXU_Q8SLTU");
3a4ef3b7 26012 gen_reserved_instruction(ctx);
03f40088
AM
26013 break;
26014 default:
26015 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26016 gen_reserved_instruction(ctx);
03f40088
AM
26017 break;
26018 }
26019}
26020
26021/*
26022 *
26023 * Decode MXU pool01
26024 *
26025 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26026 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26027 * +-----------+---------+-----+-------+-------+-------+-----------+
26028 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26029 * +-----------+---------+-----+-------+-------+-------+-----------+
26030 *
26031 * Q8ADD:
26032 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26033 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26034 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26035 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26036 *
26037 */
26038static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
26039{
26040 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26041
26042 switch (opcode) {
26043 case OPC_MXU_S32SLT:
26044 /* TODO: Implement emulation of S32SLT instruction. */
26045 MIPS_INVAL("OPC_MXU_S32SLT");
3a4ef3b7 26046 gen_reserved_instruction(ctx);
03f40088
AM
26047 break;
26048 case OPC_MXU_D16SLT:
26049 /* TODO: Implement emulation of D16SLT instruction. */
26050 MIPS_INVAL("OPC_MXU_D16SLT");
3a4ef3b7 26051 gen_reserved_instruction(ctx);
03f40088
AM
26052 break;
26053 case OPC_MXU_D16AVG:
26054 /* TODO: Implement emulation of D16AVG instruction. */
26055 MIPS_INVAL("OPC_MXU_D16AVG");
3a4ef3b7 26056 gen_reserved_instruction(ctx);
03f40088
AM
26057 break;
26058 case OPC_MXU_D16AVGR:
26059 /* TODO: Implement emulation of D16AVGR instruction. */
26060 MIPS_INVAL("OPC_MXU_D16AVGR");
3a4ef3b7 26061 gen_reserved_instruction(ctx);
03f40088
AM
26062 break;
26063 case OPC_MXU_Q8AVG:
26064 /* TODO: Implement emulation of Q8AVG instruction. */
26065 MIPS_INVAL("OPC_MXU_Q8AVG");
3a4ef3b7 26066 gen_reserved_instruction(ctx);
03f40088
AM
26067 break;
26068 case OPC_MXU_Q8AVGR:
26069 /* TODO: Implement emulation of Q8AVGR instruction. */
26070 MIPS_INVAL("OPC_MXU_Q8AVGR");
3a4ef3b7 26071 gen_reserved_instruction(ctx);
03f40088
AM
26072 break;
26073 case OPC_MXU_Q8ADD:
26074 /* TODO: Implement emulation of Q8ADD instruction. */
26075 MIPS_INVAL("OPC_MXU_Q8ADD");
3a4ef3b7 26076 gen_reserved_instruction(ctx);
03f40088
AM
26077 break;
26078 default:
26079 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26080 gen_reserved_instruction(ctx);
03f40088
AM
26081 break;
26082 }
26083}
26084
26085/*
26086 *
26087 * Decode MXU pool02
26088 *
26089 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26090 * +-----------+---------+-----+-------+-------+-------+-----------+
26091 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26092 * +-----------+---------+-----+-------+-------+-------+-----------+
26093 *
26094 */
26095static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
26096{
26097 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26098
26099 switch (opcode) {
26100 case OPC_MXU_S32CPS:
26101 /* TODO: Implement emulation of S32CPS instruction. */
26102 MIPS_INVAL("OPC_MXU_S32CPS");
3a4ef3b7 26103 gen_reserved_instruction(ctx);
03f40088
AM
26104 break;
26105 case OPC_MXU_D16CPS:
26106 /* TODO: Implement emulation of D16CPS instruction. */
26107 MIPS_INVAL("OPC_MXU_D16CPS");
3a4ef3b7 26108 gen_reserved_instruction(ctx);
03f40088
AM
26109 break;
26110 case OPC_MXU_Q8ABD:
26111 /* TODO: Implement emulation of Q8ABD instruction. */
26112 MIPS_INVAL("OPC_MXU_Q8ABD");
3a4ef3b7 26113 gen_reserved_instruction(ctx);
03f40088
AM
26114 break;
26115 case OPC_MXU_Q16SAT:
26116 /* TODO: Implement emulation of Q16SAT instruction. */
26117 MIPS_INVAL("OPC_MXU_Q16SAT");
3a4ef3b7 26118 gen_reserved_instruction(ctx);
03f40088
AM
26119 break;
26120 default:
26121 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26122 gen_reserved_instruction(ctx);
03f40088
AM
26123 break;
26124 }
26125}
26126
26127/*
26128 *
26129 * Decode MXU pool03
26130 *
26131 * D16MULF:
26132 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26133 * +-----------+---+---+-------+-------+-------+-------+-----------+
26134 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26135 * +-----------+---+---+-------+-------+-------+-------+-----------+
26136 *
26137 * D16MULE:
26138 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26139 * +-----------+---+---+-------+-------+-------+-------+-----------+
26140 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26141 * +-----------+---+---+-------+-------+-------+-------+-----------+
26142 *
26143 */
26144static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
26145{
26146 uint32_t opcode = extract32(ctx->opcode, 24, 2);
26147
26148 switch (opcode) {
26149 case OPC_MXU_D16MULF:
26150 /* TODO: Implement emulation of D16MULF instruction. */
26151 MIPS_INVAL("OPC_MXU_D16MULF");
3a4ef3b7 26152 gen_reserved_instruction(ctx);
03f40088
AM
26153 break;
26154 case OPC_MXU_D16MULE:
26155 /* TODO: Implement emulation of D16MULE instruction. */
26156 MIPS_INVAL("OPC_MXU_D16MULE");
3a4ef3b7 26157 gen_reserved_instruction(ctx);
03f40088
AM
26158 break;
26159 default:
26160 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26161 gen_reserved_instruction(ctx);
03f40088
AM
26162 break;
26163 }
26164}
26165
26166/*
26167 *
26168 * Decode MXU pool04
26169 *
26170 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26171 * +-----------+---------+-+-------------------+-------+-----------+
26172 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26173 * +-----------+---------+-+-------------------+-------+-----------+
26174 *
26175 */
26176static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
26177{
26178 uint32_t opcode = extract32(ctx->opcode, 20, 1);
26179
26180 switch (opcode) {
26181 case OPC_MXU_S32LDD:
03f40088 26182 case OPC_MXU_S32LDDR:
4ca83721 26183 gen_mxu_s32ldd_s32lddr(ctx);
03f40088
AM
26184 break;
26185 default:
26186 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26187 gen_reserved_instruction(ctx);
03f40088
AM
26188 break;
26189 }
26190}
26191
26192/*
26193 *
26194 * Decode MXU pool05
26195 *
26196 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26197 * +-----------+---------+-+-------------------+-------+-----------+
26198 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26199 * +-----------+---------+-+-------------------+-------+-----------+
26200 *
26201 */
26202static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
26203{
26204 uint32_t opcode = extract32(ctx->opcode, 20, 1);
26205
26206 switch (opcode) {
26207 case OPC_MXU_S32STD:
26208 /* TODO: Implement emulation of S32STD instruction. */
26209 MIPS_INVAL("OPC_MXU_S32STD");
3a4ef3b7 26210 gen_reserved_instruction(ctx);
03f40088
AM
26211 break;
26212 case OPC_MXU_S32STDR:
26213 /* TODO: Implement emulation of S32STDR instruction. */
26214 MIPS_INVAL("OPC_MXU_S32STDR");
3a4ef3b7 26215 gen_reserved_instruction(ctx);
03f40088
AM
26216 break;
26217 default:
26218 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26219 gen_reserved_instruction(ctx);
03f40088
AM
26220 break;
26221 }
26222}
26223
26224/*
26225 *
26226 * Decode MXU pool06
26227 *
26228 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26229 * +-----------+---------+---------+---+-------+-------+-----------+
26230 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26231 * +-----------+---------+---------+---+-------+-------+-----------+
26232 *
26233 */
26234static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
26235{
26236 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26237
26238 switch (opcode) {
26239 case OPC_MXU_S32LDDV:
26240 /* TODO: Implement emulation of S32LDDV instruction. */
26241 MIPS_INVAL("OPC_MXU_S32LDDV");
3a4ef3b7 26242 gen_reserved_instruction(ctx);
03f40088
AM
26243 break;
26244 case OPC_MXU_S32LDDVR:
26245 /* TODO: Implement emulation of S32LDDVR instruction. */
26246 MIPS_INVAL("OPC_MXU_S32LDDVR");
3a4ef3b7 26247 gen_reserved_instruction(ctx);
03f40088
AM
26248 break;
26249 default:
26250 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26251 gen_reserved_instruction(ctx);
03f40088
AM
26252 break;
26253 }
26254}
26255
26256/*
26257 *
26258 * Decode MXU pool07
26259 *
26260 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26261 * +-----------+---------+---------+---+-------+-------+-----------+
26262 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26263 * +-----------+---------+---------+---+-------+-------+-----------+
26264 *
26265 */
26266static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26267{
26268 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26269
26270 switch (opcode) {
26271 case OPC_MXU_S32STDV:
26272 /* TODO: Implement emulation of S32TDV instruction. */
26273 MIPS_INVAL("OPC_MXU_S32TDV");
3a4ef3b7 26274 gen_reserved_instruction(ctx);
03f40088
AM
26275 break;
26276 case OPC_MXU_S32STDVR:
26277 /* TODO: Implement emulation of S32TDVR instruction. */
26278 MIPS_INVAL("OPC_MXU_S32TDVR");
3a4ef3b7 26279 gen_reserved_instruction(ctx);
03f40088
AM
26280 break;
26281 default:
26282 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26283 gen_reserved_instruction(ctx);
03f40088
AM
26284 break;
26285 }
26286}
26287
26288/*
26289 *
26290 * Decode MXU pool08
26291 *
26292 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26293 * +-----------+---------+-+-------------------+-------+-----------+
26294 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26295 * +-----------+---------+-+-------------------+-------+-----------+
26296 *
7480515f 26297 */
03f40088
AM
26298static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26299{
26300 uint32_t opcode = extract32(ctx->opcode, 20, 1);
26301
26302 switch (opcode) {
26303 case OPC_MXU_S32LDI:
26304 /* TODO: Implement emulation of S32LDI instruction. */
26305 MIPS_INVAL("OPC_MXU_S32LDI");
3a4ef3b7 26306 gen_reserved_instruction(ctx);
03f40088
AM
26307 break;
26308 case OPC_MXU_S32LDIR:
26309 /* TODO: Implement emulation of S32LDIR instruction. */
26310 MIPS_INVAL("OPC_MXU_S32LDIR");
3a4ef3b7 26311 gen_reserved_instruction(ctx);
03f40088
AM
26312 break;
26313 default:
26314 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26315 gen_reserved_instruction(ctx);
03f40088
AM
26316 break;
26317 }
26318}
26319
26320/*
26321 *
26322 * Decode MXU pool09
26323 *
26324 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26325 * +-----------+---------+-+-------------------+-------+-----------+
26326 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26327 * +-----------+---------+-+-------------------+-------+-----------+
26328 *
26329 */
26330static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26331{
26332 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26333
26334 switch (opcode) {
26335 case OPC_MXU_S32SDI:
26336 /* TODO: Implement emulation of S32SDI instruction. */
26337 MIPS_INVAL("OPC_MXU_S32SDI");
3a4ef3b7 26338 gen_reserved_instruction(ctx);
03f40088
AM
26339 break;
26340 case OPC_MXU_S32SDIR:
26341 /* TODO: Implement emulation of S32SDIR instruction. */
26342 MIPS_INVAL("OPC_MXU_S32SDIR");
3a4ef3b7 26343 gen_reserved_instruction(ctx);
03f40088
AM
26344 break;
26345 default:
26346 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26347 gen_reserved_instruction(ctx);
03f40088
AM
26348 break;
26349 }
26350}
26351
26352/*
26353 *
26354 * Decode MXU pool10
26355 *
26356 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26357 * +-----------+---------+---------+---+-------+-------+-----------+
26358 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26359 * +-----------+---------+---------+---+-------+-------+-----------+
26360 *
26361 */
26362static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26363{
26364 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26365
26366 switch (opcode) {
26367 case OPC_MXU_S32LDIV:
26368 /* TODO: Implement emulation of S32LDIV instruction. */
26369 MIPS_INVAL("OPC_MXU_S32LDIV");
3a4ef3b7 26370 gen_reserved_instruction(ctx);
03f40088
AM
26371 break;
26372 case OPC_MXU_S32LDIVR:
26373 /* TODO: Implement emulation of S32LDIVR instruction. */
26374 MIPS_INVAL("OPC_MXU_S32LDIVR");
3a4ef3b7 26375 gen_reserved_instruction(ctx);
03f40088
AM
26376 break;
26377 default:
26378 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26379 gen_reserved_instruction(ctx);
03f40088
AM
26380 break;
26381 }
26382}
26383
26384/*
26385 *
26386 * Decode MXU pool11
26387 *
26388 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26389 * +-----------+---------+---------+---+-------+-------+-----------+
26390 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26391 * +-----------+---------+---------+---+-------+-------+-----------+
26392 *
26393 */
26394static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26395{
26396 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26397
26398 switch (opcode) {
26399 case OPC_MXU_S32SDIV:
26400 /* TODO: Implement emulation of S32SDIV instruction. */
26401 MIPS_INVAL("OPC_MXU_S32SDIV");
3a4ef3b7 26402 gen_reserved_instruction(ctx);
03f40088
AM
26403 break;
26404 case OPC_MXU_S32SDIVR:
26405 /* TODO: Implement emulation of S32SDIVR instruction. */
26406 MIPS_INVAL("OPC_MXU_S32SDIVR");
3a4ef3b7 26407 gen_reserved_instruction(ctx);
03f40088
AM
26408 break;
26409 default:
26410 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26411 gen_reserved_instruction(ctx);
03f40088
AM
26412 break;
26413 }
26414}
26415
26416/*
26417 *
26418 * Decode MXU pool12
26419 *
26420 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26421 * +-----------+---+---+-------+-------+-------+-------+-----------+
26422 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26423 * +-----------+---+---+-------+-------+-------+-------+-----------+
26424 *
26425 */
26426static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26427{
26428 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26429
26430 switch (opcode) {
26431 case OPC_MXU_D32ACC:
26432 /* TODO: Implement emulation of D32ACC instruction. */
26433 MIPS_INVAL("OPC_MXU_D32ACC");
3a4ef3b7 26434 gen_reserved_instruction(ctx);
03f40088
AM
26435 break;
26436 case OPC_MXU_D32ACCM:
26437 /* TODO: Implement emulation of D32ACCM instruction. */
26438 MIPS_INVAL("OPC_MXU_D32ACCM");
3a4ef3b7 26439 gen_reserved_instruction(ctx);
03f40088
AM
26440 break;
26441 case OPC_MXU_D32ASUM:
26442 /* TODO: Implement emulation of D32ASUM instruction. */
26443 MIPS_INVAL("OPC_MXU_D32ASUM");
3a4ef3b7 26444 gen_reserved_instruction(ctx);
03f40088
AM
26445 break;
26446 default:
26447 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26448 gen_reserved_instruction(ctx);
03f40088
AM
26449 break;
26450 }
26451}
26452
26453/*
26454 *
26455 * Decode MXU pool13
26456 *
26457 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26458 * +-----------+---+---+-------+-------+-------+-------+-----------+
26459 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26460 * +-----------+---+---+-------+-------+-------+-------+-----------+
26461 *
26462 */
26463static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26464{
26465 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26466
26467 switch (opcode) {
26468 case OPC_MXU_Q16ACC:
26469 /* TODO: Implement emulation of Q16ACC instruction. */
26470 MIPS_INVAL("OPC_MXU_Q16ACC");
3a4ef3b7 26471 gen_reserved_instruction(ctx);
03f40088
AM
26472 break;
26473 case OPC_MXU_Q16ACCM:
26474 /* TODO: Implement emulation of Q16ACCM instruction. */
26475 MIPS_INVAL("OPC_MXU_Q16ACCM");
3a4ef3b7 26476 gen_reserved_instruction(ctx);
03f40088
AM
26477 break;
26478 case OPC_MXU_Q16ASUM:
26479 /* TODO: Implement emulation of Q16ASUM instruction. */
26480 MIPS_INVAL("OPC_MXU_Q16ASUM");
3a4ef3b7 26481 gen_reserved_instruction(ctx);
03f40088
AM
26482 break;
26483 default:
26484 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26485 gen_reserved_instruction(ctx);
03f40088
AM
26486 break;
26487 }
26488}
26489
26490/*
26491 *
26492 * Decode MXU pool14
26493 *
26494 * Q8ADDE, Q8ACCE:
26495 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26496 * +-----------+---+---+-------+-------+-------+-------+-----------+
26497 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26498 * +-----------+---+---+-------+-------+-------+-------+-----------+
26499 *
26500 * D8SUM, D8SUMC:
26501 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26502 * +-----------+---+---+-------+-------+-------+-------+-----------+
26503 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26504 * +-----------+---+---+-------+-------+-------+-------+-----------+
26505 *
26506 */
26507static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26508{
26509 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26510
26511 switch (opcode) {
26512 case OPC_MXU_Q8ADDE:
26513 /* TODO: Implement emulation of Q8ADDE instruction. */
26514 MIPS_INVAL("OPC_MXU_Q8ADDE");
3a4ef3b7 26515 gen_reserved_instruction(ctx);
03f40088
AM
26516 break;
26517 case OPC_MXU_D8SUM:
26518 /* TODO: Implement emulation of D8SUM instruction. */
26519 MIPS_INVAL("OPC_MXU_D8SUM");
3a4ef3b7 26520 gen_reserved_instruction(ctx);
03f40088
AM
26521 break;
26522 case OPC_MXU_D8SUMC:
26523 /* TODO: Implement emulation of D8SUMC instruction. */
26524 MIPS_INVAL("OPC_MXU_D8SUMC");
3a4ef3b7 26525 gen_reserved_instruction(ctx);
03f40088
AM
26526 break;
26527 default:
26528 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26529 gen_reserved_instruction(ctx);
03f40088
AM
26530 break;
26531 }
26532}
26533
26534/*
26535 *
26536 * Decode MXU pool15
26537 *
26538 * S32MUL, S32MULU, S32EXTRV:
26539 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26540 * +-----------+---------+---------+---+-------+-------+-----------+
26541 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26542 * +-----------+---------+---------+---+-------+-------+-----------+
26543 *
26544 * S32EXTR:
26545 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26546 * +-----------+---------+---------+---+-------+-------+-----------+
26547 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26548 * +-----------+---------+---------+---+-------+-------+-----------+
26549 *
26550 */
26551static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26552{
26553 uint32_t opcode = extract32(ctx->opcode, 14, 2);
26554
26555 switch (opcode) {
26556 case OPC_MXU_S32MUL:
26557 /* TODO: Implement emulation of S32MUL instruction. */
26558 MIPS_INVAL("OPC_MXU_S32MUL");
3a4ef3b7 26559 gen_reserved_instruction(ctx);
03f40088
AM
26560 break;
26561 case OPC_MXU_S32MULU:
26562 /* TODO: Implement emulation of S32MULU instruction. */
26563 MIPS_INVAL("OPC_MXU_S32MULU");
3a4ef3b7 26564 gen_reserved_instruction(ctx);
03f40088
AM
26565 break;
26566 case OPC_MXU_S32EXTR:
26567 /* TODO: Implement emulation of S32EXTR instruction. */
26568 MIPS_INVAL("OPC_MXU_S32EXTR");
3a4ef3b7 26569 gen_reserved_instruction(ctx);
03f40088
AM
26570 break;
26571 case OPC_MXU_S32EXTRV:
26572 /* TODO: Implement emulation of S32EXTRV instruction. */
26573 MIPS_INVAL("OPC_MXU_S32EXTRV");
3a4ef3b7 26574 gen_reserved_instruction(ctx);
03f40088
AM
26575 break;
26576 default:
26577 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26578 gen_reserved_instruction(ctx);
03f40088
AM
26579 break;
26580 }
26581}
26582
26583/*
26584 *
26585 * Decode MXU pool16
26586 *
26587 * D32SARW:
26588 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26589 * +-----------+---------+-----+-------+-------+-------+-----------+
26590 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26591 * +-----------+---------+-----+-------+-------+-------+-----------+
26592 *
26593 * S32ALN:
26594 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26595 * +-----------+---------+-----+-------+-------+-------+-----------+
26596 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26597 * +-----------+---------+-----+-------+-------+-------+-----------+
26598 *
26599 * S32ALNI:
26600 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26601 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26602 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26603 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26604 *
03f40088
AM
26605 * S32LUI:
26606 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26607 * +-----------+-----+---+-----+-------+---------------+-----------+
26608 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26609 * +-----------+-----+---+-----+-------+---------------+-----------+
26610 *
b621f018
AM
26611 * S32NOR, S32AND, S32OR, S32XOR:
26612 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26613 * +-----------+---------+-----+-------+-------+-------+-----------+
26614 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26615 * +-----------+---------+-----+-------+-------+-------+-----------+
26616 *
03f40088
AM
26617 */
26618static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26619{
26620 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26621
26622 switch (opcode) {
26623 case OPC_MXU_D32SARW:
26624 /* TODO: Implement emulation of D32SARW instruction. */
26625 MIPS_INVAL("OPC_MXU_D32SARW");
3a4ef3b7 26626 gen_reserved_instruction(ctx);
03f40088
AM
26627 break;
26628 case OPC_MXU_S32ALN:
26629 /* TODO: Implement emulation of S32ALN instruction. */
26630 MIPS_INVAL("OPC_MXU_S32ALN");
3a4ef3b7 26631 gen_reserved_instruction(ctx);
03f40088
AM
26632 break;
26633 case OPC_MXU_S32ALNI:
79f5fee7 26634 gen_mxu_S32ALNI(ctx);
03f40088 26635 break;
b621f018
AM
26636 case OPC_MXU_S32LUI:
26637 /* TODO: Implement emulation of S32LUI instruction. */
26638 MIPS_INVAL("OPC_MXU_S32LUI");
3a4ef3b7 26639 gen_reserved_instruction(ctx);
03f40088 26640 break;
b621f018
AM
26641 case OPC_MXU_S32NOR:
26642 gen_mxu_S32NOR(ctx);
26643 break;
03f40088 26644 case OPC_MXU_S32AND:
b621f018 26645 gen_mxu_S32AND(ctx);
03f40088
AM
26646 break;
26647 case OPC_MXU_S32OR:
b621f018 26648 gen_mxu_S32OR(ctx);
03f40088
AM
26649 break;
26650 case OPC_MXU_S32XOR:
b621f018 26651 gen_mxu_S32XOR(ctx);
03f40088
AM
26652 break;
26653 default:
26654 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26655 gen_reserved_instruction(ctx);
03f40088
AM
26656 break;
26657 }
26658}
26659
26660/*
26661 *
26662 * Decode MXU pool17
26663 *
26664 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
c233bf07
AM
26665 * +-----------+---------+---------+---+---------+-----+-----------+
26666 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26667 * +-----------+---------+---------+---+---------+-----+-----------+
26668 *
26669 */
26670static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26671{
26672 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26673
26674 switch (opcode) {
26675 case OPC_MXU_LXW:
26676 /* TODO: Implement emulation of LXW instruction. */
26677 MIPS_INVAL("OPC_MXU_LXW");
3a4ef3b7 26678 gen_reserved_instruction(ctx);
c233bf07
AM
26679 break;
26680 case OPC_MXU_LXH:
26681 /* TODO: Implement emulation of LXH instruction. */
26682 MIPS_INVAL("OPC_MXU_LXH");
3a4ef3b7 26683 gen_reserved_instruction(ctx);
c233bf07
AM
26684 break;
26685 case OPC_MXU_LXHU:
26686 /* TODO: Implement emulation of LXHU instruction. */
26687 MIPS_INVAL("OPC_MXU_LXHU");
3a4ef3b7 26688 gen_reserved_instruction(ctx);
c233bf07
AM
26689 break;
26690 case OPC_MXU_LXB:
26691 /* TODO: Implement emulation of LXB instruction. */
26692 MIPS_INVAL("OPC_MXU_LXB");
3a4ef3b7 26693 gen_reserved_instruction(ctx);
c233bf07
AM
26694 break;
26695 case OPC_MXU_LXBU:
26696 /* TODO: Implement emulation of LXBU instruction. */
26697 MIPS_INVAL("OPC_MXU_LXBU");
3a4ef3b7 26698 gen_reserved_instruction(ctx);
c233bf07
AM
26699 break;
26700 default:
26701 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26702 gen_reserved_instruction(ctx);
c233bf07
AM
26703 break;
26704 }
26705}
26706/*
26707 *
26708 * Decode MXU pool18
26709 *
26710 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
03f40088 26711 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 26712 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
03f40088
AM
26713 * +-----------+---------+-----+-------+-------+-------+-----------+
26714 *
26715 */
c233bf07 26716static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26717{
26718 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26719
26720 switch (opcode) {
26721 case OPC_MXU_D32SLLV:
26722 /* TODO: Implement emulation of D32SLLV instruction. */
26723 MIPS_INVAL("OPC_MXU_D32SLLV");
3a4ef3b7 26724 gen_reserved_instruction(ctx);
03f40088
AM
26725 break;
26726 case OPC_MXU_D32SLRV:
26727 /* TODO: Implement emulation of D32SLRV instruction. */
26728 MIPS_INVAL("OPC_MXU_D32SLRV");
3a4ef3b7 26729 gen_reserved_instruction(ctx);
03f40088
AM
26730 break;
26731 case OPC_MXU_D32SARV:
26732 /* TODO: Implement emulation of D32SARV instruction. */
26733 MIPS_INVAL("OPC_MXU_D32SARV");
3a4ef3b7 26734 gen_reserved_instruction(ctx);
03f40088
AM
26735 break;
26736 case OPC_MXU_Q16SLLV:
26737 /* TODO: Implement emulation of Q16SLLV instruction. */
26738 MIPS_INVAL("OPC_MXU_Q16SLLV");
3a4ef3b7 26739 gen_reserved_instruction(ctx);
03f40088
AM
26740 break;
26741 case OPC_MXU_Q16SLRV:
26742 /* TODO: Implement emulation of Q16SLRV instruction. */
26743 MIPS_INVAL("OPC_MXU_Q16SLRV");
3a4ef3b7 26744 gen_reserved_instruction(ctx);
03f40088
AM
26745 break;
26746 case OPC_MXU_Q16SARV:
26747 /* TODO: Implement emulation of Q16SARV instruction. */
26748 MIPS_INVAL("OPC_MXU_Q16SARV");
3a4ef3b7 26749 gen_reserved_instruction(ctx);
03f40088
AM
26750 break;
26751 default:
26752 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26753 gen_reserved_instruction(ctx);
03f40088
AM
26754 break;
26755 }
26756}
26757
26758/*
26759 *
c233bf07 26760 * Decode MXU pool19
03f40088
AM
26761 *
26762 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26763 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 26764 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
03f40088
AM
26765 * +-----------+---+---+-------+-------+-------+-------+-----------+
26766 *
26767 */
c233bf07 26768static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26769{
26770 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26771
26772 switch (opcode) {
26773 case OPC_MXU_Q8MUL:
03f40088 26774 case OPC_MXU_Q8MULSU:
a9a4181b 26775 gen_mxu_q8mul_q8mulsu(ctx);
03f40088
AM
26776 break;
26777 default:
26778 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26779 gen_reserved_instruction(ctx);
03f40088
AM
26780 break;
26781 }
26782}
26783
26784/*
26785 *
c233bf07 26786 * Decode MXU pool20
03f40088
AM
26787 *
26788 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26789 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 26790 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
03f40088
AM
26791 * +-----------+---------+-----+-------+-------+-------+-----------+
26792 *
26793 */
c233bf07 26794static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26795{
26796 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26797
26798 switch (opcode) {
26799 case OPC_MXU_Q8MOVZ:
26800 /* TODO: Implement emulation of Q8MOVZ instruction. */
26801 MIPS_INVAL("OPC_MXU_Q8MOVZ");
3a4ef3b7 26802 gen_reserved_instruction(ctx);
03f40088
AM
26803 break;
26804 case OPC_MXU_Q8MOVN:
26805 /* TODO: Implement emulation of Q8MOVN instruction. */
26806 MIPS_INVAL("OPC_MXU_Q8MOVN");
3a4ef3b7 26807 gen_reserved_instruction(ctx);
03f40088
AM
26808 break;
26809 case OPC_MXU_D16MOVZ:
26810 /* TODO: Implement emulation of D16MOVZ instruction. */
26811 MIPS_INVAL("OPC_MXU_D16MOVZ");
3a4ef3b7 26812 gen_reserved_instruction(ctx);
03f40088
AM
26813 break;
26814 case OPC_MXU_D16MOVN:
26815 /* TODO: Implement emulation of D16MOVN instruction. */
26816 MIPS_INVAL("OPC_MXU_D16MOVN");
3a4ef3b7 26817 gen_reserved_instruction(ctx);
03f40088
AM
26818 break;
26819 case OPC_MXU_S32MOVZ:
26820 /* TODO: Implement emulation of S32MOVZ instruction. */
26821 MIPS_INVAL("OPC_MXU_S32MOVZ");
3a4ef3b7 26822 gen_reserved_instruction(ctx);
03f40088
AM
26823 break;
26824 case OPC_MXU_S32MOVN:
26825 /* TODO: Implement emulation of S32MOVN instruction. */
26826 MIPS_INVAL("OPC_MXU_S32MOVN");
3a4ef3b7 26827 gen_reserved_instruction(ctx);
03f40088
AM
26828 break;
26829 default:
26830 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26831 gen_reserved_instruction(ctx);
03f40088
AM
26832 break;
26833 }
26834}
26835
26836/*
26837 *
c233bf07 26838 * Decode MXU pool21
03f40088
AM
26839 *
26840 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26841 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 26842 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
03f40088
AM
26843 * +-----------+---+---+-------+-------+-------+-------+-----------+
26844 *
26845 */
c233bf07 26846static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26847{
26848 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26849
26850 switch (opcode) {
26851 case OPC_MXU_Q8MAC:
26852 /* TODO: Implement emulation of Q8MAC instruction. */
26853 MIPS_INVAL("OPC_MXU_Q8MAC");
3a4ef3b7 26854 gen_reserved_instruction(ctx);
03f40088
AM
26855 break;
26856 case OPC_MXU_Q8MACSU:
26857 /* TODO: Implement emulation of Q8MACSU instruction. */
26858 MIPS_INVAL("OPC_MXU_Q8MACSU");
3a4ef3b7 26859 gen_reserved_instruction(ctx);
03f40088
AM
26860 break;
26861 default:
26862 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 26863 gen_reserved_instruction(ctx);
03f40088
AM
26864 break;
26865 }
26866}
26867
26868
26869/*
26870 * Main MXU decoding function
26871 *
26872 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26873 * +-----------+---------------------------------------+-----------+
26874 * | SPECIAL2 | |x x x x x x|
26875 * +-----------+---------------------------------------+-----------+
26876 *
26877 */
0a348b9a
AM
26878static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26879{
11d56f61
CJ
26880 /*
26881 * TODO: Investigate necessity of including handling of
26882 * CLZ, CLO, SDBB in this function, as they belong to
26883 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26884 */
03f40088
AM
26885 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26886
87860df5
AM
26887 if (opcode == OPC__MXU_MUL) {
26888 uint32_t rs, rt, rd, op1;
26889
26890 rs = extract32(ctx->opcode, 21, 5);
26891 rt = extract32(ctx->opcode, 16, 5);
26892 rd = extract32(ctx->opcode, 11, 5);
26893 op1 = MASK_SPECIAL2(ctx->opcode);
26894
26895 gen_arith(ctx, op1, rd, rs, rt);
26896
26897 return;
26898 }
26899
26900 if (opcode == OPC_MXU_S32M2I) {
26901 gen_mxu_s32m2i(ctx);
26902 return;
26903 }
26904
26905 if (opcode == OPC_MXU_S32I2M) {
26906 gen_mxu_s32i2m(ctx);
26907 return;
26908 }
26909
e5bf8a08
AM
26910 {
26911 TCGv t_mxu_cr = tcg_temp_new();
26912 TCGLabel *l_exit = gen_new_label();
26913
26914 gen_load_mxu_cr(t_mxu_cr);
26915 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26916 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26917
26918 switch (opcode) {
26919 case OPC_MXU_S32MADD:
26920 /* TODO: Implement emulation of S32MADD instruction. */
26921 MIPS_INVAL("OPC_MXU_S32MADD");
3a4ef3b7 26922 gen_reserved_instruction(ctx);
e5bf8a08
AM
26923 break;
26924 case OPC_MXU_S32MADDU:
26925 /* TODO: Implement emulation of S32MADDU instruction. */
26926 MIPS_INVAL("OPC_MXU_S32MADDU");
3a4ef3b7 26927 gen_reserved_instruction(ctx);
e5bf8a08
AM
26928 break;
26929 case OPC_MXU__POOL00:
26930 decode_opc_mxu__pool00(env, ctx);
26931 break;
26932 case OPC_MXU_S32MSUB:
26933 /* TODO: Implement emulation of S32MSUB instruction. */
26934 MIPS_INVAL("OPC_MXU_S32MSUB");
3a4ef3b7 26935 gen_reserved_instruction(ctx);
e5bf8a08
AM
26936 break;
26937 case OPC_MXU_S32MSUBU:
26938 /* TODO: Implement emulation of S32MSUBU instruction. */
26939 MIPS_INVAL("OPC_MXU_S32MSUBU");
3a4ef3b7 26940 gen_reserved_instruction(ctx);
e5bf8a08
AM
26941 break;
26942 case OPC_MXU__POOL01:
26943 decode_opc_mxu__pool01(env, ctx);
26944 break;
26945 case OPC_MXU__POOL02:
26946 decode_opc_mxu__pool02(env, ctx);
26947 break;
26948 case OPC_MXU_D16MUL:
26949 gen_mxu_d16mul(ctx);
26950 break;
26951 case OPC_MXU__POOL03:
26952 decode_opc_mxu__pool03(env, ctx);
26953 break;
26954 case OPC_MXU_D16MAC:
26955 gen_mxu_d16mac(ctx);
26956 break;
26957 case OPC_MXU_D16MACF:
26958 /* TODO: Implement emulation of D16MACF instruction. */
26959 MIPS_INVAL("OPC_MXU_D16MACF");
3a4ef3b7 26960 gen_reserved_instruction(ctx);
e5bf8a08
AM
26961 break;
26962 case OPC_MXU_D16MADL:
26963 /* TODO: Implement emulation of D16MADL instruction. */
26964 MIPS_INVAL("OPC_MXU_D16MADL");
3a4ef3b7 26965 gen_reserved_instruction(ctx);
e5bf8a08
AM
26966 break;
26967 case OPC_MXU_S16MAD:
26968 /* TODO: Implement emulation of S16MAD instruction. */
26969 MIPS_INVAL("OPC_MXU_S16MAD");
3a4ef3b7 26970 gen_reserved_instruction(ctx);
e5bf8a08
AM
26971 break;
26972 case OPC_MXU_Q16ADD:
26973 /* TODO: Implement emulation of Q16ADD instruction. */
26974 MIPS_INVAL("OPC_MXU_Q16ADD");
3a4ef3b7 26975 gen_reserved_instruction(ctx);
e5bf8a08
AM
26976 break;
26977 case OPC_MXU_D16MACE:
26978 /* TODO: Implement emulation of D16MACE instruction. */
26979 MIPS_INVAL("OPC_MXU_D16MACE");
3a4ef3b7 26980 gen_reserved_instruction(ctx);
e5bf8a08
AM
26981 break;
26982 case OPC_MXU__POOL04:
26983 decode_opc_mxu__pool04(env, ctx);
26984 break;
26985 case OPC_MXU__POOL05:
26986 decode_opc_mxu__pool05(env, ctx);
26987 break;
26988 case OPC_MXU__POOL06:
26989 decode_opc_mxu__pool06(env, ctx);
26990 break;
26991 case OPC_MXU__POOL07:
26992 decode_opc_mxu__pool07(env, ctx);
26993 break;
26994 case OPC_MXU__POOL08:
26995 decode_opc_mxu__pool08(env, ctx);
26996 break;
26997 case OPC_MXU__POOL09:
26998 decode_opc_mxu__pool09(env, ctx);
26999 break;
27000 case OPC_MXU__POOL10:
27001 decode_opc_mxu__pool10(env, ctx);
27002 break;
27003 case OPC_MXU__POOL11:
27004 decode_opc_mxu__pool11(env, ctx);
27005 break;
27006 case OPC_MXU_D32ADD:
27007 /* TODO: Implement emulation of D32ADD instruction. */
27008 MIPS_INVAL("OPC_MXU_D32ADD");
3a4ef3b7 27009 gen_reserved_instruction(ctx);
e5bf8a08
AM
27010 break;
27011 case OPC_MXU__POOL12:
27012 decode_opc_mxu__pool12(env, ctx);
27013 break;
27014 case OPC_MXU__POOL13:
27015 decode_opc_mxu__pool13(env, ctx);
27016 break;
27017 case OPC_MXU__POOL14:
27018 decode_opc_mxu__pool14(env, ctx);
27019 break;
27020 case OPC_MXU_Q8ACCE:
27021 /* TODO: Implement emulation of Q8ACCE instruction. */
27022 MIPS_INVAL("OPC_MXU_Q8ACCE");
3a4ef3b7 27023 gen_reserved_instruction(ctx);
e5bf8a08
AM
27024 break;
27025 case OPC_MXU_S8LDD:
27026 gen_mxu_s8ldd(ctx);
27027 break;
27028 case OPC_MXU_S8STD:
27029 /* TODO: Implement emulation of S8STD instruction. */
27030 MIPS_INVAL("OPC_MXU_S8STD");
3a4ef3b7 27031 gen_reserved_instruction(ctx);
e5bf8a08
AM
27032 break;
27033 case OPC_MXU_S8LDI:
27034 /* TODO: Implement emulation of S8LDI instruction. */
27035 MIPS_INVAL("OPC_MXU_S8LDI");
3a4ef3b7 27036 gen_reserved_instruction(ctx);
e5bf8a08
AM
27037 break;
27038 case OPC_MXU_S8SDI:
27039 /* TODO: Implement emulation of S8SDI instruction. */
27040 MIPS_INVAL("OPC_MXU_S8SDI");
3a4ef3b7 27041 gen_reserved_instruction(ctx);
e5bf8a08
AM
27042 break;
27043 case OPC_MXU__POOL15:
27044 decode_opc_mxu__pool15(env, ctx);
27045 break;
27046 case OPC_MXU__POOL16:
27047 decode_opc_mxu__pool16(env, ctx);
27048 break;
c233bf07
AM
27049 case OPC_MXU__POOL17:
27050 decode_opc_mxu__pool17(env, ctx);
e5bf8a08
AM
27051 break;
27052 case OPC_MXU_S16LDD:
27053 /* TODO: Implement emulation of S16LDD instruction. */
27054 MIPS_INVAL("OPC_MXU_S16LDD");
3a4ef3b7 27055 gen_reserved_instruction(ctx);
e5bf8a08
AM
27056 break;
27057 case OPC_MXU_S16STD:
27058 /* TODO: Implement emulation of S16STD instruction. */
27059 MIPS_INVAL("OPC_MXU_S16STD");
3a4ef3b7 27060 gen_reserved_instruction(ctx);
e5bf8a08
AM
27061 break;
27062 case OPC_MXU_S16LDI:
27063 /* TODO: Implement emulation of S16LDI instruction. */
27064 MIPS_INVAL("OPC_MXU_S16LDI");
3a4ef3b7 27065 gen_reserved_instruction(ctx);
e5bf8a08
AM
27066 break;
27067 case OPC_MXU_S16SDI:
27068 /* TODO: Implement emulation of S16SDI instruction. */
27069 MIPS_INVAL("OPC_MXU_S16SDI");
3a4ef3b7 27070 gen_reserved_instruction(ctx);
e5bf8a08
AM
27071 break;
27072 case OPC_MXU_D32SLL:
27073 /* TODO: Implement emulation of D32SLL instruction. */
27074 MIPS_INVAL("OPC_MXU_D32SLL");
3a4ef3b7 27075 gen_reserved_instruction(ctx);
e5bf8a08
AM
27076 break;
27077 case OPC_MXU_D32SLR:
27078 /* TODO: Implement emulation of D32SLR instruction. */
27079 MIPS_INVAL("OPC_MXU_D32SLR");
3a4ef3b7 27080 gen_reserved_instruction(ctx);
e5bf8a08
AM
27081 break;
27082 case OPC_MXU_D32SARL:
27083 /* TODO: Implement emulation of D32SARL instruction. */
27084 MIPS_INVAL("OPC_MXU_D32SARL");
3a4ef3b7 27085 gen_reserved_instruction(ctx);
e5bf8a08
AM
27086 break;
27087 case OPC_MXU_D32SAR:
27088 /* TODO: Implement emulation of D32SAR instruction. */
27089 MIPS_INVAL("OPC_MXU_D32SAR");
3a4ef3b7 27090 gen_reserved_instruction(ctx);
e5bf8a08
AM
27091 break;
27092 case OPC_MXU_Q16SLL:
27093 /* TODO: Implement emulation of Q16SLL instruction. */
27094 MIPS_INVAL("OPC_MXU_Q16SLL");
3a4ef3b7 27095 gen_reserved_instruction(ctx);
e5bf8a08
AM
27096 break;
27097 case OPC_MXU_Q16SLR:
27098 /* TODO: Implement emulation of Q16SLR instruction. */
27099 MIPS_INVAL("OPC_MXU_Q16SLR");
3a4ef3b7 27100 gen_reserved_instruction(ctx);
e5bf8a08 27101 break;
c233bf07
AM
27102 case OPC_MXU__POOL18:
27103 decode_opc_mxu__pool18(env, ctx);
e5bf8a08
AM
27104 break;
27105 case OPC_MXU_Q16SAR:
27106 /* TODO: Implement emulation of Q16SAR instruction. */
27107 MIPS_INVAL("OPC_MXU_Q16SAR");
3a4ef3b7 27108 gen_reserved_instruction(ctx);
e5bf8a08 27109 break;
e5bf8a08
AM
27110 case OPC_MXU__POOL19:
27111 decode_opc_mxu__pool19(env, ctx);
27112 break;
27113 case OPC_MXU__POOL20:
27114 decode_opc_mxu__pool20(env, ctx);
27115 break;
c233bf07
AM
27116 case OPC_MXU__POOL21:
27117 decode_opc_mxu__pool21(env, ctx);
27118 break;
e5bf8a08
AM
27119 case OPC_MXU_Q16SCOP:
27120 /* TODO: Implement emulation of Q16SCOP instruction. */
27121 MIPS_INVAL("OPC_MXU_Q16SCOP");
3a4ef3b7 27122 gen_reserved_instruction(ctx);
e5bf8a08
AM
27123 break;
27124 case OPC_MXU_Q8MADL:
27125 /* TODO: Implement emulation of Q8MADL instruction. */
27126 MIPS_INVAL("OPC_MXU_Q8MADL");
3a4ef3b7 27127 gen_reserved_instruction(ctx);
e5bf8a08
AM
27128 break;
27129 case OPC_MXU_S32SFL:
27130 /* TODO: Implement emulation of S32SFL instruction. */
27131 MIPS_INVAL("OPC_MXU_S32SFL");
3a4ef3b7 27132 gen_reserved_instruction(ctx);
e5bf8a08
AM
27133 break;
27134 case OPC_MXU_Q8SAD:
27135 /* TODO: Implement emulation of Q8SAD instruction. */
27136 MIPS_INVAL("OPC_MXU_Q8SAD");
3a4ef3b7 27137 gen_reserved_instruction(ctx);
e5bf8a08
AM
27138 break;
27139 default:
27140 MIPS_INVAL("decode_opc_mxu");
3a4ef3b7 27141 gen_reserved_instruction(ctx);
e5bf8a08
AM
27142 }
27143
27144 gen_set_label(l_exit);
27145 tcg_temp_free(t_mxu_cr);
03f40088 27146 }
0a348b9a
AM
27147}
27148
b621f018
AM
27149#endif /* !defined(TARGET_MIPS64) */
27150
03f40088 27151
10dc65db 27152static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
27153{
27154 int rs, rt, rd;
27155 uint32_t op1;
6c5c1e20 27156
2e211e0a 27157 check_insn_opc_removed(ctx, ISA_MIPS_R6);
4267d3e6 27158
099e5b4d
LA
27159 rs = (ctx->opcode >> 21) & 0x1f;
27160 rt = (ctx->opcode >> 16) & 0x1f;
27161 rd = (ctx->opcode >> 11) & 0x1f;
27162
27163 op1 = MASK_SPECIAL2(ctx->opcode);
27164 switch (op1) {
c2e19f3c
AM
27165 case OPC_MADD: /* Multiply and add/sub */
27166 case OPC_MADDU:
27167 case OPC_MSUB:
27168 case OPC_MSUBU:
bbd5e4a2 27169 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
27170 gen_muldiv(ctx, op1, rd & 3, rs, rt);
27171 break;
27172 case OPC_MUL:
099e5b4d
LA
27173 gen_arith(ctx, op1, rd, rs, rt);
27174 break;
fac5a073
LA
27175 case OPC_DIV_G_2F:
27176 case OPC_DIVU_G_2F:
27177 case OPC_MULT_G_2F:
27178 case OPC_MULTU_G_2F:
27179 case OPC_MOD_G_2F:
27180 case OPC_MODU_G_2F:
8e2d5831 27181 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
fac5a073
LA
27182 gen_loongson_integer(ctx, op1, rd, rs, rt);
27183 break;
099e5b4d
LA
27184 case OPC_CLO:
27185 case OPC_CLZ:
bbd5e4a2 27186 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
27187 gen_cl(ctx, op1, rd, rs);
27188 break;
27189 case OPC_SDBBP:
3b3c1694
LA
27190 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
27191 gen_helper_do_semihosting(cpu_env);
27192 } else {
7480515f
AM
27193 /*
27194 * XXX: not clear which exception should be raised
3b3c1694
LA
27195 * when in debug mode...
27196 */
bbd5e4a2 27197 check_insn(ctx, ISA_MIPS_R1);
9c708c7f 27198 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 27199 }
099e5b4d 27200 break;
9b1a1d68 27201#if defined(TARGET_MIPS64)
099e5b4d
LA
27202 case OPC_DCLO:
27203 case OPC_DCLZ:
bbd5e4a2 27204 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
27205 check_mips_64(ctx);
27206 gen_cl(ctx, op1, rd, rs);
27207 break;
4267d3e6
LA
27208 case OPC_DMULT_G_2F:
27209 case OPC_DMULTU_G_2F:
27210 case OPC_DDIV_G_2F:
27211 case OPC_DDIVU_G_2F:
27212 case OPC_DMOD_G_2F:
27213 case OPC_DMODU_G_2F:
8e2d5831 27214 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
4267d3e6
LA
27215 gen_loongson_integer(ctx, op1, rd, rs, rt);
27216 break;
10dc65db 27217#endif
4267d3e6
LA
27218 default: /* Invalid */
27219 MIPS_INVAL("special2_legacy");
3a4ef3b7 27220 gen_reserved_instruction(ctx);
4267d3e6 27221 break;
10dc65db
LA
27222 }
27223}
27224
27225static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
27226{
15eacb9b
YK
27227 int rs, rt, rd, sa;
27228 uint32_t op1, op2;
10dc65db
LA
27229 int16_t imm;
27230
27231 rs = (ctx->opcode >> 21) & 0x1f;
27232 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
27233 rd = (ctx->opcode >> 11) & 0x1f;
27234 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
27235 imm = (int16_t)ctx->opcode >> 7;
27236
27237 op1 = MASK_SPECIAL3(ctx->opcode);
27238 switch (op1) {
bf7910c6
LA
27239 case R6_OPC_PREF:
27240 if (rt >= 24) {
27241 /* hint codes 24-31 are reserved and signal RI */
3a4ef3b7 27242 gen_reserved_instruction(ctx);
bf7910c6
LA
27243 }
27244 /* Treat as NOP. */
27245 break;
27246 case R6_OPC_CACHE:
40d48212 27247 check_cp0_enabled(ctx);
0d74a222
LA
27248 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27249 gen_cache_operation(ctx, rt, rs, imm);
27250 }
bf7910c6 27251 break;
10dc65db 27252 case R6_OPC_SC:
33a07fa2 27253 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
10dc65db
LA
27254 break;
27255 case R6_OPC_LL:
27256 gen_ld(ctx, op1, rt, rs, imm);
27257 break;
15eacb9b
YK
27258 case OPC_BSHFL:
27259 {
27260 if (rd == 0) {
27261 /* Treat as NOP. */
27262 break;
27263 }
15eacb9b
YK
27264 op2 = MASK_BSHFL(ctx->opcode);
27265 switch (op2) {
c2e19f3c 27266 case OPC_ALIGN:
373ecd38
AM
27267 case OPC_ALIGN_1:
27268 case OPC_ALIGN_2:
27269 case OPC_ALIGN_3:
821f2008 27270 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
27271 break;
27272 case OPC_BITSWAP:
1f1b4c00 27273 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
27274 break;
27275 }
15eacb9b
YK
27276 }
27277 break;
99029be1
YK
27278#ifndef CONFIG_USER_ONLY
27279 case OPC_GINV:
27280 if (unlikely(ctx->gi <= 1)) {
3a4ef3b7 27281 gen_reserved_instruction(ctx);
99029be1
YK
27282 }
27283 check_cp0_enabled(ctx);
27284 switch ((ctx->opcode >> 6) & 3) {
27285 case 0: /* GINVI */
27286 /* Treat as NOP. */
27287 break;
27288 case 2: /* GINVT */
27289 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
27290 break;
27291 default:
3a4ef3b7 27292 gen_reserved_instruction(ctx);
99029be1
YK
27293 break;
27294 }
27295 break;
27296#endif
bf7910c6
LA
27297#if defined(TARGET_MIPS64)
27298 case R6_OPC_SCD:
33a07fa2 27299 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
bf7910c6
LA
27300 break;
27301 case R6_OPC_LLD:
27302 gen_ld(ctx, op1, rt, rs, imm);
27303 break;
15eacb9b
YK
27304 case OPC_DBSHFL:
27305 check_mips_64(ctx);
27306 {
27307 if (rd == 0) {
27308 /* Treat as NOP. */
27309 break;
27310 }
15eacb9b
YK
27311 op2 = MASK_DBSHFL(ctx->opcode);
27312 switch (op2) {
c2e19f3c 27313 case OPC_DALIGN:
373ecd38
AM
27314 case OPC_DALIGN_1:
27315 case OPC_DALIGN_2:
27316 case OPC_DALIGN_3:
27317 case OPC_DALIGN_4:
27318 case OPC_DALIGN_5:
27319 case OPC_DALIGN_6:
27320 case OPC_DALIGN_7:
821f2008 27321 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
27322 break;
27323 case OPC_DBITSWAP:
1f1b4c00 27324 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
27325 break;
27326 }
1f1b4c00 27327
15eacb9b
YK
27328 }
27329 break;
bf7910c6 27330#endif
10dc65db
LA
27331 default: /* Invalid */
27332 MIPS_INVAL("special3_r6");
3a4ef3b7 27333 gen_reserved_instruction(ctx);
10dc65db
LA
27334 break;
27335 }
27336}
27337
27338static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27339{
fac5a073 27340 int rs, rt, rd;
099e5b4d 27341 uint32_t op1, op2;
099e5b4d
LA
27342
27343 rs = (ctx->opcode >> 21) & 0x1f;
27344 rt = (ctx->opcode >> 16) & 0x1f;
27345 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
27346
27347 op1 = MASK_SPECIAL3(ctx->opcode);
27348 switch (op1) {
c2e19f3c
AM
27349 case OPC_DIV_G_2E:
27350 case OPC_DIVU_G_2E:
27351 case OPC_MOD_G_2E:
27352 case OPC_MODU_G_2E:
27353 case OPC_MULT_G_2E:
27354 case OPC_MULTU_G_2E:
7480515f
AM
27355 /*
27356 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27357 * the same mask and op1.
27358 */
908f6be1 27359 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 27360 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 27361 switch (op2) {
099e5b4d
LA
27362 case OPC_ADDUH_QB:
27363 case OPC_ADDUH_R_QB:
27364 case OPC_ADDQH_PH:
27365 case OPC_ADDQH_R_PH:
27366 case OPC_ADDQH_W:
27367 case OPC_ADDQH_R_W:
27368 case OPC_SUBUH_QB:
27369 case OPC_SUBUH_R_QB:
27370 case OPC_SUBQH_PH:
27371 case OPC_SUBQH_R_PH:
27372 case OPC_SUBQH_W:
27373 case OPC_SUBQH_R_W:
461c08df
JL
27374 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27375 break;
099e5b4d
LA
27376 case OPC_MUL_PH:
27377 case OPC_MUL_S_PH:
27378 case OPC_MULQ_S_W:
27379 case OPC_MULQ_RS_W:
27380 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 27381 break;
461c08df 27382 default:
099e5b4d 27383 MIPS_INVAL("MASK ADDUH.QB");
3a4ef3b7 27384 gen_reserved_instruction(ctx);
461c08df
JL
27385 break;
27386 }
099e5b4d
LA
27387 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27388 gen_loongson_integer(ctx, op1, rd, rs, rt);
27389 } else {
3a4ef3b7 27390 gen_reserved_instruction(ctx);
099e5b4d
LA
27391 }
27392 break;
27393 case OPC_LX_DSP:
27394 op2 = MASK_LX(ctx->opcode);
27395 switch (op2) {
27396#if defined(TARGET_MIPS64)
27397 case OPC_LDX:
27398#endif
27399 case OPC_LBUX:
27400 case OPC_LHX:
27401 case OPC_LWX:
27402 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27403 break;
27404 default: /* Invalid */
27405 MIPS_INVAL("MASK LX");
3a4ef3b7 27406 gen_reserved_instruction(ctx);
099e5b4d
LA
27407 break;
27408 }
27409 break;
27410 case OPC_ABSQ_S_PH_DSP:
27411 op2 = MASK_ABSQ_S_PH(ctx->opcode);
27412 switch (op2) {
27413 case OPC_ABSQ_S_QB:
27414 case OPC_ABSQ_S_PH:
27415 case OPC_ABSQ_S_W:
27416 case OPC_PRECEQ_W_PHL:
27417 case OPC_PRECEQ_W_PHR:
27418 case OPC_PRECEQU_PH_QBL:
27419 case OPC_PRECEQU_PH_QBR:
27420 case OPC_PRECEQU_PH_QBLA:
27421 case OPC_PRECEQU_PH_QBRA:
27422 case OPC_PRECEU_PH_QBL:
27423 case OPC_PRECEU_PH_QBR:
27424 case OPC_PRECEU_PH_QBLA:
27425 case OPC_PRECEU_PH_QBRA:
27426 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27427 break;
27428 case OPC_BITREV:
27429 case OPC_REPL_QB:
27430 case OPC_REPLV_QB:
27431 case OPC_REPL_PH:
27432 case OPC_REPLV_PH:
27433 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27434 break;
27435 default:
27436 MIPS_INVAL("MASK ABSQ_S.PH");
3a4ef3b7 27437 gen_reserved_instruction(ctx);
099e5b4d
LA
27438 break;
27439 }
27440 break;
27441 case OPC_ADDU_QB_DSP:
27442 op2 = MASK_ADDU_QB(ctx->opcode);
27443 switch (op2) {
27444 case OPC_ADDQ_PH:
27445 case OPC_ADDQ_S_PH:
27446 case OPC_ADDQ_S_W:
27447 case OPC_ADDU_QB:
27448 case OPC_ADDU_S_QB:
27449 case OPC_ADDU_PH:
27450 case OPC_ADDU_S_PH:
27451 case OPC_SUBQ_PH:
27452 case OPC_SUBQ_S_PH:
27453 case OPC_SUBQ_S_W:
27454 case OPC_SUBU_QB:
27455 case OPC_SUBU_S_QB:
27456 case OPC_SUBU_PH:
27457 case OPC_SUBU_S_PH:
27458 case OPC_ADDSC:
27459 case OPC_ADDWC:
27460 case OPC_MODSUB:
27461 case OPC_RADDU_W_QB:
27462 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27463 break;
27464 case OPC_MULEU_S_PH_QBL:
27465 case OPC_MULEU_S_PH_QBR:
27466 case OPC_MULQ_RS_PH:
27467 case OPC_MULEQ_S_W_PHL:
27468 case OPC_MULEQ_S_W_PHR:
27469 case OPC_MULQ_S_PH:
27470 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27471 break;
27472 default: /* Invalid */
27473 MIPS_INVAL("MASK ADDU.QB");
3a4ef3b7 27474 gen_reserved_instruction(ctx);
461c08df 27475 break;
461c08df 27476
099e5b4d
LA
27477 }
27478 break;
27479 case OPC_CMPU_EQ_QB_DSP:
27480 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27481 switch (op2) {
27482 case OPC_PRECR_SRA_PH_W:
27483 case OPC_PRECR_SRA_R_PH_W:
27484 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 27485 break;
099e5b4d
LA
27486 case OPC_PRECR_QB_PH:
27487 case OPC_PRECRQ_QB_PH:
27488 case OPC_PRECRQ_PH_W:
27489 case OPC_PRECRQ_RS_PH_W:
27490 case OPC_PRECRQU_S_QB_PH:
27491 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 27492 break;
099e5b4d
LA
27493 case OPC_CMPU_EQ_QB:
27494 case OPC_CMPU_LT_QB:
27495 case OPC_CMPU_LE_QB:
27496 case OPC_CMP_EQ_PH:
27497 case OPC_CMP_LT_PH:
27498 case OPC_CMP_LE_PH:
27499 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 27500 break;
099e5b4d
LA
27501 case OPC_CMPGU_EQ_QB:
27502 case OPC_CMPGU_LT_QB:
27503 case OPC_CMPGU_LE_QB:
27504 case OPC_CMPGDU_EQ_QB:
27505 case OPC_CMPGDU_LT_QB:
27506 case OPC_CMPGDU_LE_QB:
27507 case OPC_PICK_QB:
27508 case OPC_PICK_PH:
27509 case OPC_PACKRL_PH:
27510 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27511 break;
27512 default: /* Invalid */
27513 MIPS_INVAL("MASK CMPU.EQ.QB");
3a4ef3b7 27514 gen_reserved_instruction(ctx);
099e5b4d
LA
27515 break;
27516 }
27517 break;
27518 case OPC_SHLL_QB_DSP:
27519 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27520 break;
27521 case OPC_DPA_W_PH_DSP:
27522 op2 = MASK_DPA_W_PH(ctx->opcode);
27523 switch (op2) {
27524 case OPC_DPAU_H_QBL:
27525 case OPC_DPAU_H_QBR:
27526 case OPC_DPSU_H_QBL:
27527 case OPC_DPSU_H_QBR:
27528 case OPC_DPA_W_PH:
27529 case OPC_DPAX_W_PH:
27530 case OPC_DPAQ_S_W_PH:
27531 case OPC_DPAQX_S_W_PH:
27532 case OPC_DPAQX_SA_W_PH:
27533 case OPC_DPS_W_PH:
27534 case OPC_DPSX_W_PH:
27535 case OPC_DPSQ_S_W_PH:
27536 case OPC_DPSQX_S_W_PH:
27537 case OPC_DPSQX_SA_W_PH:
27538 case OPC_MULSAQ_S_W_PH:
27539 case OPC_DPAQ_SA_L_W:
27540 case OPC_DPSQ_SA_L_W:
27541 case OPC_MAQ_S_W_PHL:
27542 case OPC_MAQ_S_W_PHR:
27543 case OPC_MAQ_SA_W_PHL:
27544 case OPC_MAQ_SA_W_PHR:
27545 case OPC_MULSA_W_PH:
27546 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27547 break;
27548 default: /* Invalid */
27549 MIPS_INVAL("MASK DPAW.PH");
3a4ef3b7 27550 gen_reserved_instruction(ctx);
099e5b4d
LA
27551 break;
27552 }
27553 break;
27554 case OPC_INSV_DSP:
27555 op2 = MASK_INSV(ctx->opcode);
27556 switch (op2) {
27557 case OPC_INSV:
27558 check_dsp(ctx);
27559 {
27560 TCGv t0, t1;
27561
27562 if (rt == 0) {
099e5b4d
LA
27563 break;
27564 }
27565
27566 t0 = tcg_temp_new();
27567 t1 = tcg_temp_new();
27568
27569 gen_load_gpr(t0, rt);
27570 gen_load_gpr(t1, rs);
27571
27572 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27573
27574 tcg_temp_free(t0);
27575 tcg_temp_free(t1);
a22260ae
JL
27576 break;
27577 }
099e5b4d
LA
27578 default: /* Invalid */
27579 MIPS_INVAL("MASK INSV");
3a4ef3b7 27580 gen_reserved_instruction(ctx);
099e5b4d
LA
27581 break;
27582 }
27583 break;
27584 case OPC_APPEND_DSP:
27585 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27586 break;
27587 case OPC_EXTR_W_DSP:
27588 op2 = MASK_EXTR_W(ctx->opcode);
27589 switch (op2) {
27590 case OPC_EXTR_W:
27591 case OPC_EXTR_R_W:
27592 case OPC_EXTR_RS_W:
27593 case OPC_EXTR_S_H:
27594 case OPC_EXTRV_S_H:
27595 case OPC_EXTRV_W:
27596 case OPC_EXTRV_R_W:
27597 case OPC_EXTRV_RS_W:
27598 case OPC_EXTP:
27599 case OPC_EXTPV:
27600 case OPC_EXTPDP:
27601 case OPC_EXTPDPV:
27602 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27603 break;
27604 case OPC_RDDSP:
27605 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27606 break;
27607 case OPC_SHILO:
27608 case OPC_SHILOV:
27609 case OPC_MTHLIP:
27610 case OPC_WRDSP:
27611 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27612 break;
27613 default: /* Invalid */
27614 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 27615 gen_reserved_instruction(ctx);
099e5b4d
LA
27616 break;
27617 }
27618 break;
099e5b4d 27619#if defined(TARGET_MIPS64)
c2e19f3c
AM
27620 case OPC_DDIV_G_2E:
27621 case OPC_DDIVU_G_2E:
27622 case OPC_DMULT_G_2E:
27623 case OPC_DMULTU_G_2E:
27624 case OPC_DMOD_G_2E:
27625 case OPC_DMODU_G_2E:
fac5a073
LA
27626 check_insn(ctx, INSN_LOONGSON2E);
27627 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 27628 break;
099e5b4d
LA
27629 case OPC_ABSQ_S_QH_DSP:
27630 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27631 switch (op2) {
27632 case OPC_PRECEQ_L_PWL:
27633 case OPC_PRECEQ_L_PWR:
27634 case OPC_PRECEQ_PW_QHL:
27635 case OPC_PRECEQ_PW_QHR:
27636 case OPC_PRECEQ_PW_QHLA:
27637 case OPC_PRECEQ_PW_QHRA:
27638 case OPC_PRECEQU_QH_OBL:
27639 case OPC_PRECEQU_QH_OBR:
27640 case OPC_PRECEQU_QH_OBLA:
27641 case OPC_PRECEQU_QH_OBRA:
27642 case OPC_PRECEU_QH_OBL:
27643 case OPC_PRECEU_QH_OBR:
27644 case OPC_PRECEU_QH_OBLA:
27645 case OPC_PRECEU_QH_OBRA:
27646 case OPC_ABSQ_S_OB:
27647 case OPC_ABSQ_S_PW:
27648 case OPC_ABSQ_S_QH:
27649 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27650 break;
27651 case OPC_REPL_OB:
27652 case OPC_REPL_PW:
27653 case OPC_REPL_QH:
27654 case OPC_REPLV_OB:
27655 case OPC_REPLV_PW:
27656 case OPC_REPLV_QH:
27657 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27658 break;
27659 default: /* Invalid */
27660 MIPS_INVAL("MASK ABSQ_S.QH");
3a4ef3b7 27661 gen_reserved_instruction(ctx);
099e5b4d
LA
27662 break;
27663 }
27664 break;
27665 case OPC_ADDU_OB_DSP:
27666 op2 = MASK_ADDU_OB(ctx->opcode);
27667 switch (op2) {
27668 case OPC_RADDU_L_OB:
27669 case OPC_SUBQ_PW:
27670 case OPC_SUBQ_S_PW:
27671 case OPC_SUBQ_QH:
27672 case OPC_SUBQ_S_QH:
27673 case OPC_SUBU_OB:
27674 case OPC_SUBU_S_OB:
27675 case OPC_SUBU_QH:
27676 case OPC_SUBU_S_QH:
27677 case OPC_SUBUH_OB:
27678 case OPC_SUBUH_R_OB:
27679 case OPC_ADDQ_PW:
27680 case OPC_ADDQ_S_PW:
27681 case OPC_ADDQ_QH:
27682 case OPC_ADDQ_S_QH:
27683 case OPC_ADDU_OB:
27684 case OPC_ADDU_S_OB:
27685 case OPC_ADDU_QH:
27686 case OPC_ADDU_S_QH:
27687 case OPC_ADDUH_OB:
27688 case OPC_ADDUH_R_OB:
27689 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 27690 break;
099e5b4d
LA
27691 case OPC_MULEQ_S_PW_QHL:
27692 case OPC_MULEQ_S_PW_QHR:
27693 case OPC_MULEU_S_QH_OBL:
27694 case OPC_MULEU_S_QH_OBR:
27695 case OPC_MULQ_RS_QH:
27696 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 27697 break;
099e5b4d
LA
27698 default: /* Invalid */
27699 MIPS_INVAL("MASK ADDU.OB");
3a4ef3b7 27700 gen_reserved_instruction(ctx);
26690560 27701 break;
099e5b4d
LA
27702 }
27703 break;
27704 case OPC_CMPU_EQ_OB_DSP:
27705 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27706 switch (op2) {
27707 case OPC_PRECR_SRA_QH_PW:
27708 case OPC_PRECR_SRA_R_QH_PW:
27709 /* Return value is rt. */
27710 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 27711 break;
099e5b4d
LA
27712 case OPC_PRECR_OB_QH:
27713 case OPC_PRECRQ_OB_QH:
27714 case OPC_PRECRQ_PW_L:
27715 case OPC_PRECRQ_QH_PW:
27716 case OPC_PRECRQ_RS_QH_PW:
27717 case OPC_PRECRQU_S_OB_QH:
27718 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 27719 break;
099e5b4d
LA
27720 case OPC_CMPU_EQ_OB:
27721 case OPC_CMPU_LT_OB:
27722 case OPC_CMPU_LE_OB:
27723 case OPC_CMP_EQ_QH:
27724 case OPC_CMP_LT_QH:
27725 case OPC_CMP_LE_QH:
27726 case OPC_CMP_EQ_PW:
27727 case OPC_CMP_LT_PW:
27728 case OPC_CMP_LE_PW:
27729 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 27730 break;
099e5b4d
LA
27731 case OPC_CMPGDU_EQ_OB:
27732 case OPC_CMPGDU_LT_OB:
27733 case OPC_CMPGDU_LE_OB:
27734 case OPC_CMPGU_EQ_OB:
27735 case OPC_CMPGU_LT_OB:
27736 case OPC_CMPGU_LE_OB:
27737 case OPC_PACKRL_PW:
27738 case OPC_PICK_OB:
27739 case OPC_PICK_PW:
27740 case OPC_PICK_QH:
27741 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 27742 break;
099e5b4d
LA
27743 default: /* Invalid */
27744 MIPS_INVAL("MASK CMPU_EQ.OB");
3a4ef3b7 27745 gen_reserved_instruction(ctx);
161f85e6 27746 break;
099e5b4d
LA
27747 }
27748 break;
27749 case OPC_DAPPEND_DSP:
27750 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27751 break;
27752 case OPC_DEXTR_W_DSP:
27753 op2 = MASK_DEXTR_W(ctx->opcode);
27754 switch (op2) {
27755 case OPC_DEXTP:
27756 case OPC_DEXTPDP:
27757 case OPC_DEXTPDPV:
27758 case OPC_DEXTPV:
27759 case OPC_DEXTR_L:
27760 case OPC_DEXTR_R_L:
27761 case OPC_DEXTR_RS_L:
27762 case OPC_DEXTR_W:
27763 case OPC_DEXTR_R_W:
27764 case OPC_DEXTR_RS_W:
27765 case OPC_DEXTR_S_H:
27766 case OPC_DEXTRV_L:
27767 case OPC_DEXTRV_R_L:
27768 case OPC_DEXTRV_RS_L:
27769 case OPC_DEXTRV_S_H:
27770 case OPC_DEXTRV_W:
27771 case OPC_DEXTRV_R_W:
27772 case OPC_DEXTRV_RS_W:
27773 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 27774 break;
099e5b4d
LA
27775 case OPC_DMTHLIP:
27776 case OPC_DSHILO:
27777 case OPC_DSHILOV:
27778 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 27779 break;
099e5b4d
LA
27780 default: /* Invalid */
27781 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 27782 gen_reserved_instruction(ctx);
461c08df 27783 break;
099e5b4d
LA
27784 }
27785 break;
27786 case OPC_DPAQ_W_QH_DSP:
27787 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27788 switch (op2) {
27789 case OPC_DPAU_H_OBL:
27790 case OPC_DPAU_H_OBR:
27791 case OPC_DPSU_H_OBL:
27792 case OPC_DPSU_H_OBR:
27793 case OPC_DPA_W_QH:
27794 case OPC_DPAQ_S_W_QH:
27795 case OPC_DPS_W_QH:
27796 case OPC_DPSQ_S_W_QH:
27797 case OPC_MULSAQ_S_W_QH:
27798 case OPC_DPAQ_SA_L_PW:
27799 case OPC_DPSQ_SA_L_PW:
27800 case OPC_MULSAQ_S_L_PW:
27801 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27802 break;
27803 case OPC_MAQ_S_W_QHLL:
27804 case OPC_MAQ_S_W_QHLR:
27805 case OPC_MAQ_S_W_QHRL:
27806 case OPC_MAQ_S_W_QHRR:
27807 case OPC_MAQ_SA_W_QHLL:
27808 case OPC_MAQ_SA_W_QHLR:
27809 case OPC_MAQ_SA_W_QHRL:
27810 case OPC_MAQ_SA_W_QHRR:
27811 case OPC_MAQ_S_L_PWL:
27812 case OPC_MAQ_S_L_PWR:
27813 case OPC_DMADD:
27814 case OPC_DMADDU:
27815 case OPC_DMSUB:
27816 case OPC_DMSUBU:
27817 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 27818 break;
099e5b4d
LA
27819 default: /* Invalid */
27820 MIPS_INVAL("MASK DPAQ.W.QH");
3a4ef3b7 27821 gen_reserved_instruction(ctx);
b53371ed 27822 break;
099e5b4d
LA
27823 }
27824 break;
27825 case OPC_DINSV_DSP:
27826 op2 = MASK_INSV(ctx->opcode);
27827 switch (op2) {
27828 case OPC_DINSV:
27829 {
27830 TCGv t0, t1;
27831
27832 if (rt == 0) {
a22260ae
JL
27833 break;
27834 }
099e5b4d 27835 check_dsp(ctx);
1cb6686c 27836
099e5b4d
LA
27837 t0 = tcg_temp_new();
27838 t1 = tcg_temp_new();
1cb6686c 27839
099e5b4d
LA
27840 gen_load_gpr(t0, rt);
27841 gen_load_gpr(t1, rs);
1cb6686c 27842
099e5b4d 27843 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 27844
099e5b4d
LA
27845 tcg_temp_free(t0);
27846 tcg_temp_free(t1);
77c5fa8b 27847 break;
099e5b4d 27848 }
7a387fff 27849 default: /* Invalid */
099e5b4d 27850 MIPS_INVAL("MASK DINSV");
3a4ef3b7 27851 gen_reserved_instruction(ctx);
7a387fff
TS
27852 break;
27853 }
27854 break;
099e5b4d
LA
27855 case OPC_SHLL_OB_DSP:
27856 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27857 break;
27858#endif
fac5a073
LA
27859 default: /* Invalid */
27860 MIPS_INVAL("special3_legacy");
3a4ef3b7 27861 gen_reserved_instruction(ctx);
fac5a073
LA
27862 break;
27863 }
27864}
27865
37b9aae2
MM
27866
27867#if defined(TARGET_MIPS64)
27868
874b2879 27869static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
88eafe0b 27870{
c8341e00 27871 uint32_t opc = MASK_MMI0(ctx->opcode);
88eafe0b
FN
27872
27873 switch (opc) {
baa609db
AM
27874 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27875 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27876 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27877 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27878 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27879 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27880 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27881 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27882 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27883 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27884 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27885 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27886 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27887 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27888 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27889 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27890 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27891 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27892 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27893 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27894 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27895 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27896 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27897 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27898 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
3a4ef3b7 27899 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI0 */
88eafe0b
FN
27900 break;
27901 default:
27902 MIPS_INVAL("TX79 MMI class MMI0");
3a4ef3b7 27903 gen_reserved_instruction(ctx);
88eafe0b
FN
27904 break;
27905 }
27906}
27907
874b2879 27908static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
7a803ca2 27909{
c8341e00 27910 uint32_t opc = MASK_MMI1(ctx->opcode);
7a803ca2
FN
27911
27912 switch (opc) {
baa609db
AM
27913 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27914 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27915 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27916 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27917 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27918 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27919 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27920 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27921 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27922 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27923 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27924 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27925 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27926 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27927 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27928 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27929 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27930 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
3a4ef3b7 27931 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI1 */
7a803ca2
FN
27932 break;
27933 default:
27934 MIPS_INVAL("TX79 MMI class MMI1");
3a4ef3b7 27935 gen_reserved_instruction(ctx);
7a803ca2
FN
27936 break;
27937 }
27938}
27939
874b2879 27940static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
6c1e48d3 27941{
c8341e00 27942 uint32_t opc = MASK_MMI2(ctx->opcode);
6c1e48d3
FN
27943
27944 switch (opc) {
baa609db
AM
27945 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27946 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27947 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27948 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27949 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27950 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27951 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27952 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27953 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
baa609db
AM
27954 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27955 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27956 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27957 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27958 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27959 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27960 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27961 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27962 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27963 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27964 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27965 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
3a4ef3b7 27966 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI2 */
6c1e48d3 27967 break;
b87eef31
MM
27968 case MMI_OPC_2_PCPYLD:
27969 gen_mmi_pcpyld(ctx);
27970 break;
6c1e48d3
FN
27971 default:
27972 MIPS_INVAL("TX79 MMI class MMI2");
3a4ef3b7 27973 gen_reserved_instruction(ctx);
6c1e48d3
FN
27974 break;
27975 }
27976}
27977
874b2879 27978static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
ec1944fc 27979{
c8341e00 27980 uint32_t opc = MASK_MMI3(ctx->opcode);
ec1944fc
FN
27981
27982 switch (opc) {
baa609db
AM
27983 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27984 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27985 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27986 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27987 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27988 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27989 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
baa609db
AM
27990 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27991 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27992 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
baa609db 27993 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
3a4ef3b7 27994 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI3 */
ec1944fc 27995 break;
d3434d9f
MM
27996 case MMI_OPC_3_PCPYH:
27997 gen_mmi_pcpyh(ctx);
27998 break;
fd487f83
MM
27999 case MMI_OPC_3_PCPYUD:
28000 gen_mmi_pcpyud(ctx);
28001 break;
ec1944fc
FN
28002 default:
28003 MIPS_INVAL("TX79 MMI class MMI3");
3a4ef3b7 28004 gen_reserved_instruction(ctx);
ec1944fc
FN
28005 break;
28006 }
28007}
28008
874b2879 28009static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
71b8a6b3 28010{
c8341e00 28011 uint32_t opc = MASK_MMI(ctx->opcode);
06de726b
FN
28012 int rs = extract32(ctx->opcode, 21, 5);
28013 int rt = extract32(ctx->opcode, 16, 5);
28014 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
28015
28016 switch (opc) {
baa609db 28017 case MMI_OPC_CLASS_MMI0:
874b2879 28018 decode_mmi0(env, ctx);
88eafe0b 28019 break;
baa609db 28020 case MMI_OPC_CLASS_MMI1:
874b2879 28021 decode_mmi1(env, ctx);
7a803ca2 28022 break;
baa609db 28023 case MMI_OPC_CLASS_MMI2:
874b2879 28024 decode_mmi2(env, ctx);
6c1e48d3 28025 break;
baa609db 28026 case MMI_OPC_CLASS_MMI3:
874b2879 28027 decode_mmi3(env, ctx);
ec1944fc 28028 break;
baa609db
AM
28029 case MMI_OPC_MULT1:
28030 case MMI_OPC_MULTU1:
3b948f05
PMD
28031 case MMI_OPC_MADD:
28032 case MMI_OPC_MADDU:
a95c4c26
FN
28033 case MMI_OPC_MADD1:
28034 case MMI_OPC_MADDU1:
06de726b
FN
28035 gen_mul_txx9(ctx, opc, rd, rs, rt);
28036 break;
baa609db
AM
28037 case MMI_OPC_DIV1:
28038 case MMI_OPC_DIVU1:
c42171c3 28039 gen_div1_tx79(ctx, opc, rs, rt);
be9c42c9 28040 break;
baa609db
AM
28041 case MMI_OPC_MTLO1:
28042 case MMI_OPC_MTHI1:
86efbfb6 28043 gen_HILO1_tx79(ctx, opc, rs);
8d927f7c 28044 break;
baa609db
AM
28045 case MMI_OPC_MFLO1:
28046 case MMI_OPC_MFHI1:
86efbfb6 28047 gen_HILO1_tx79(ctx, opc, rd);
8d927f7c 28048 break;
baa609db 28049 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
baa609db
AM
28050 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
28051 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
28052 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
28053 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
28054 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
28055 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
28056 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
28057 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
3a4ef3b7 28058 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI */
71b8a6b3
FN
28059 break;
28060 default:
28061 MIPS_INVAL("TX79 MMI class");
3a4ef3b7 28062 gen_reserved_instruction(ctx);
71b8a6b3
FN
28063 break;
28064 }
28065}
28066
874b2879 28067static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
f08099ad 28068{
3a4ef3b7 28069 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_LQ */
f08099ad
FN
28070}
28071
874b2879 28072static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
bb41e74b 28073{
3a4ef3b7 28074 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */
bb41e74b
FN
28075}
28076
28077/*
28078 * The TX79-specific instruction Store Quadword
28079 *
28080 * +--------+-------+-------+------------------------+
28081 * | 011111 | base | rt | offset | SQ
28082 * +--------+-------+-------+------------------------+
28083 * 6 5 5 16
28084 *
28085 * has the same opcode as the Read Hardware Register instruction
28086 *
28087 * +--------+-------+-------+-------+-------+--------+
28088 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28089 * +--------+-------+-------+-------+-------+--------+
28090 * 6 5 5 5 5 6
28091 *
28092 * that is required, trapped and emulated by the Linux kernel. However, all
28093 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28094 * offset is odd. Therefore all valid SQ instructions can execute normally.
28095 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28096 * between SQ and RDHWR, as the Linux kernel does.
28097 */
874b2879 28098static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
bb41e74b
FN
28099{
28100 int base = extract32(ctx->opcode, 21, 5);
28101 int rt = extract32(ctx->opcode, 16, 5);
28102 int offset = extract32(ctx->opcode, 0, 16);
28103
28104#ifdef CONFIG_USER_ONLY
28105 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
28106 uint32_t op2 = extract32(ctx->opcode, 6, 5);
28107
28108 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
28109 int rd = extract32(ctx->opcode, 11, 5);
28110
28111 gen_rdhwr(ctx, rt, rd, 0);
28112 return;
28113 }
28114#endif
28115
874b2879 28116 gen_mmi_sq(ctx, base, rt, offset);
bb41e74b
FN
28117}
28118
37b9aae2
MM
28119#endif
28120
fac5a073
LA
28121static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
28122{
28123 int rs, rt, rd, sa;
28124 uint32_t op1, op2;
76964147 28125 int16_t imm;
fac5a073
LA
28126
28127 rs = (ctx->opcode >> 21) & 0x1f;
28128 rt = (ctx->opcode >> 16) & 0x1f;
28129 rd = (ctx->opcode >> 11) & 0x1f;
28130 sa = (ctx->opcode >> 6) & 0x1f;
76964147 28131 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
28132
28133 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
28134
28135 /*
28136 * EVA loads and stores overlap Loongson 2E instructions decoded by
28137 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28138 * EVA is absent.
28139 */
28140 if (ctx->eva) {
28141 switch (op1) {
c2e19f3c
AM
28142 case OPC_LWLE:
28143 case OPC_LWRE:
2e211e0a 28144 check_insn_opc_removed(ctx, ISA_MIPS_R6);
76964147 28145 /* fall through */
c2e19f3c
AM
28146 case OPC_LBUE:
28147 case OPC_LHUE:
28148 case OPC_LBE:
28149 case OPC_LHE:
28150 case OPC_LLE:
28151 case OPC_LWE:
76964147
JH
28152 check_cp0_enabled(ctx);
28153 gen_ld(ctx, op1, rt, rs, imm);
28154 return;
c2e19f3c
AM
28155 case OPC_SWLE:
28156 case OPC_SWRE:
2e211e0a 28157 check_insn_opc_removed(ctx, ISA_MIPS_R6);
76964147 28158 /* fall through */
c2e19f3c
AM
28159 case OPC_SBE:
28160 case OPC_SHE:
76964147
JH
28161 case OPC_SWE:
28162 check_cp0_enabled(ctx);
28163 gen_st(ctx, op1, rt, rs, imm);
28164 return;
28165 case OPC_SCE:
28166 check_cp0_enabled(ctx);
33a07fa2 28167 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
76964147
JH
28168 return;
28169 case OPC_CACHEE:
28170 check_cp0_enabled(ctx);
28171 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28172 gen_cache_operation(ctx, rt, rs, imm);
28173 }
28174 /* Treat as NOP. */
28175 return;
28176 case OPC_PREFE:
28177 check_cp0_enabled(ctx);
28178 /* Treat as NOP. */
28179 return;
28180 }
28181 }
28182
fac5a073
LA
28183 switch (op1) {
28184 case OPC_EXT:
28185 case OPC_INS:
7a47bae5 28186 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
28187 gen_bitops(ctx, op1, rt, rs, sa, rd);
28188 break;
28189 case OPC_BSHFL:
fac5a073 28190 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 28191 switch (op2) {
c2e19f3c 28192 case OPC_ALIGN:
373ecd38
AM
28193 case OPC_ALIGN_1:
28194 case OPC_ALIGN_2:
28195 case OPC_ALIGN_3:
15eacb9b 28196 case OPC_BITSWAP:
2e211e0a 28197 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
28198 decode_opc_special3_r6(env, ctx);
28199 break;
28200 default:
7a47bae5 28201 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
28202 gen_bshfl(ctx, op2, rt, rd);
28203 break;
28204 }
fac5a073
LA
28205 break;
28206#if defined(TARGET_MIPS64)
c2e19f3c
AM
28207 case OPC_DEXTM:
28208 case OPC_DEXTU:
28209 case OPC_DEXT:
28210 case OPC_DINSM:
28211 case OPC_DINSU:
28212 case OPC_DINS:
7a47bae5 28213 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
28214 check_mips_64(ctx);
28215 gen_bitops(ctx, op1, rt, rs, sa, rd);
28216 break;
28217 case OPC_DBSHFL:
fac5a073 28218 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 28219 switch (op2) {
c2e19f3c 28220 case OPC_DALIGN:
373ecd38
AM
28221 case OPC_DALIGN_1:
28222 case OPC_DALIGN_2:
28223 case OPC_DALIGN_3:
28224 case OPC_DALIGN_4:
28225 case OPC_DALIGN_5:
28226 case OPC_DALIGN_6:
28227 case OPC_DALIGN_7:
15eacb9b 28228 case OPC_DBITSWAP:
2e211e0a 28229 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
28230 decode_opc_special3_r6(env, ctx);
28231 break;
28232 default:
7a47bae5 28233 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
28234 check_mips_64(ctx);
28235 op2 = MASK_DBSHFL(ctx->opcode);
28236 gen_bshfl(ctx, op2, rt, rd);
28237 break;
28238 }
fac5a073
LA
28239 break;
28240#endif
28241 case OPC_RDHWR:
b00c7218 28242 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
28243 break;
28244 case OPC_FORK:
9affc1c5 28245 check_mt(ctx);
fac5a073
LA
28246 {
28247 TCGv t0 = tcg_temp_new();
28248 TCGv t1 = tcg_temp_new();
28249
28250 gen_load_gpr(t0, rt);
28251 gen_load_gpr(t1, rs);
28252 gen_helper_fork(t0, t1);
28253 tcg_temp_free(t0);
28254 tcg_temp_free(t1);
28255 }
28256 break;
28257 case OPC_YIELD:
9affc1c5 28258 check_mt(ctx);
fac5a073
LA
28259 {
28260 TCGv t0 = tcg_temp_new();
28261
fac5a073
LA
28262 gen_load_gpr(t0, rs);
28263 gen_helper_yield(t0, cpu_env, t0);
28264 gen_store_gpr(t0, rd);
28265 tcg_temp_free(t0);
28266 }
28267 break;
10dc65db 28268 default:
2e211e0a 28269 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db
LA
28270 decode_opc_special3_r6(env, ctx);
28271 } else {
28272 decode_opc_special3_legacy(env, ctx);
28273 }
099e5b4d
LA
28274 }
28275}
28276
80e64a38 28277static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
4c789546 28278{
80e64a38
PMD
28279 int32_t offset;
28280 int rs, rt, rd, sa;
28281 uint32_t op, op1;
28282 int16_t imm;
4c789546 28283
80e64a38
PMD
28284 op = MASK_OP_MAJOR(ctx->opcode);
28285 rs = (ctx->opcode >> 21) & 0x1f;
28286 rt = (ctx->opcode >> 16) & 0x1f;
28287 rd = (ctx->opcode >> 11) & 0x1f;
28288 sa = (ctx->opcode >> 6) & 0x1f;
28289 imm = (int16_t)ctx->opcode;
28290 switch (op) {
28291 case OPC_SPECIAL:
28292 decode_opc_special(env, ctx);
4c789546 28293 break;
80e64a38
PMD
28294 case OPC_SPECIAL2:
28295#if defined(TARGET_MIPS64)
28296 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28297 decode_mmi(env, ctx);
28298#else
28299 if (ctx->insn_flags & ASE_MXU) {
28300 decode_opc_mxu(env, ctx);
28301#endif
28302 } else {
28303 decode_opc_special2_legacy(env, ctx);
4c789546
YK
28304 }
28305 break;
80e64a38
PMD
28306 case OPC_SPECIAL3:
28307#if defined(TARGET_MIPS64)
28308 if (ctx->insn_flags & INSN_R5900) {
28309 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
28310 } else {
28311 decode_opc_special3(env, ctx);
80e71591 28312 }
80e64a38
PMD
28313#else
28314 decode_opc_special3(env, ctx);
28315#endif
80e71591 28316 break;
80e64a38
PMD
28317 case OPC_REGIMM:
28318 op1 = MASK_REGIMM(ctx->opcode);
28319 switch (op1) {
28320 case OPC_BLTZL: /* REGIMM branches */
28321 case OPC_BGEZL:
28322 case OPC_BLTZALL:
28323 case OPC_BGEZALL:
28324 check_insn(ctx, ISA_MIPS2);
28325 check_insn_opc_removed(ctx, ISA_MIPS_R6);
28326 /* Fallthrough */
28327 case OPC_BLTZ:
28328 case OPC_BGEZ:
28329 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
2e3eddb0 28330 break;
80e64a38
PMD
28331 case OPC_BLTZAL:
28332 case OPC_BGEZAL:
28333 if (ctx->insn_flags & ISA_MIPS_R6) {
28334 if (rs == 0) {
28335 /* OPC_NAL, OPC_BAL */
28336 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28337 } else {
28338 gen_reserved_instruction(ctx);
28339 }
28340 } else {
28341 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28342 }
2e3eddb0 28343 break;
80e64a38
PMD
28344 case OPC_TGEI: /* REGIMM traps */
28345 case OPC_TGEIU:
28346 case OPC_TLTI:
28347 case OPC_TLTIU:
28348 case OPC_TEQI:
28349
28350 case OPC_TNEI:
28351 check_insn(ctx, ISA_MIPS2);
28352 check_insn_opc_removed(ctx, ISA_MIPS_R6);
28353 gen_trap(ctx, op1, rs, -1, imm);
2e3eddb0 28354 break;
80e64a38
PMD
28355 case OPC_SIGRIE:
28356 check_insn(ctx, ISA_MIPS_R6);
28357 gen_reserved_instruction(ctx);
2e3eddb0 28358 break;
80e64a38
PMD
28359 case OPC_SYNCI:
28360 check_insn(ctx, ISA_MIPS_R2);
28361 /*
28362 * Break the TB to be able to sync copied instructions
28363 * immediately.
28364 */
28365 ctx->base.is_jmp = DISAS_STOP;
2e3eddb0 28366 break;
80e64a38
PMD
28367 case OPC_BPOSGE32: /* MIPS DSP branch */
28368#if defined(TARGET_MIPS64)
28369 case OPC_BPOSGE64:
28370#endif
28371 check_dsp(ctx);
28372 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
a44d6d14 28373 break;
80e64a38
PMD
28374#if defined(TARGET_MIPS64)
28375 case OPC_DAHI:
28376 check_insn(ctx, ISA_MIPS_R6);
28377 check_mips_64(ctx);
28378 if (rs != 0) {
28379 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28380 }
a44d6d14 28381 break;
80e64a38
PMD
28382 case OPC_DATI:
28383 check_insn(ctx, ISA_MIPS_R6);
28384 check_mips_64(ctx);
28385 if (rs != 0) {
28386 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28387 }
a44d6d14 28388 break;
80e64a38
PMD
28389#endif
28390 default: /* Invalid */
28391 MIPS_INVAL("regimm");
28392 gen_reserved_instruction(ctx);
a44d6d14
AM
28393 break;
28394 }
28395 break;
80e64a38
PMD
28396 case OPC_CP0:
28397 check_cp0_enabled(ctx);
28398 op1 = MASK_CP0(ctx->opcode);
28399 switch (op1) {
28400 case OPC_MFC0:
28401 case OPC_MTC0:
28402 case OPC_MFTR:
28403 case OPC_MTTR:
28404 case OPC_MFHC0:
28405 case OPC_MTHC0:
28406#if defined(TARGET_MIPS64)
28407 case OPC_DMFC0:
28408 case OPC_DMTC0:
28409#endif
28410#ifndef CONFIG_USER_ONLY
28411 gen_cp0(env, ctx, op1, rt, rd);
28412#endif /* !CONFIG_USER_ONLY */
7a387fff 28413 break;
c38a1d52
AR
28414 case OPC_C0:
28415 case OPC_C0_1:
28416 case OPC_C0_2:
28417 case OPC_C0_3:
28418 case OPC_C0_4:
28419 case OPC_C0_5:
28420 case OPC_C0_6:
28421 case OPC_C0_7:
28422 case OPC_C0_8:
28423 case OPC_C0_9:
28424 case OPC_C0_A:
28425 case OPC_C0_B:
28426 case OPC_C0_C:
28427 case OPC_C0_D:
28428 case OPC_C0_E:
28429 case OPC_C0_F:
f1aa6320 28430#ifndef CONFIG_USER_ONLY
932e71cd 28431 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 28432#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
28433 break;
28434 case OPC_MFMC0:
8706c382 28435#ifndef CONFIG_USER_ONLY
932e71cd 28436 {
099e5b4d 28437 uint32_t op2;
35fbce2c 28438 TCGv t0 = tcg_temp_new();
6c5c1e20 28439
0eaef5aa 28440 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
28441 switch (op2) {
28442 case OPC_DMT:
9affc1c5 28443 check_cp0_mt(ctx);
9ed5726c 28444 gen_helper_dmt(t0);
35fbce2c 28445 gen_store_gpr(t0, rt);
6c5c1e20
TS
28446 break;
28447 case OPC_EMT:
9affc1c5 28448 check_cp0_mt(ctx);
9ed5726c 28449 gen_helper_emt(t0);
35fbce2c 28450 gen_store_gpr(t0, rt);
da80682b 28451 break;
6c5c1e20 28452 case OPC_DVPE:
9affc1c5 28453 check_cp0_mt(ctx);
895c2d04 28454 gen_helper_dvpe(t0, cpu_env);
35fbce2c 28455 gen_store_gpr(t0, rt);
6c5c1e20
TS
28456 break;
28457 case OPC_EVPE:
9affc1c5 28458 check_cp0_mt(ctx);
895c2d04 28459 gen_helper_evpe(t0, cpu_env);
35fbce2c 28460 gen_store_gpr(t0, rt);
6c5c1e20 28461 break;
01bc435b 28462 case OPC_DVP:
2e211e0a 28463 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
28464 if (ctx->vp) {
28465 gen_helper_dvp(t0, cpu_env);
28466 gen_store_gpr(t0, rt);
28467 }
28468 break;
28469 case OPC_EVP:
2e211e0a 28470 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
28471 if (ctx->vp) {
28472 gen_helper_evp(t0, cpu_env);
28473 gen_store_gpr(t0, rt);
28474 }
28475 break;
6c5c1e20 28476 case OPC_DI:
7a47bae5 28477 check_insn(ctx, ISA_MIPS_R2);
867abc7e 28478 save_cpu_state(ctx, 1);
895c2d04 28479 gen_helper_di(t0, cpu_env);
35fbce2c 28480 gen_store_gpr(t0, rt);
7480515f
AM
28481 /*
28482 * Stop translation as we may have switched
28483 * the execution mode.
28484 */
eeb3bba8 28485 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
28486 break;
28487 case OPC_EI:
7a47bae5 28488 check_insn(ctx, ISA_MIPS_R2);
867abc7e 28489 save_cpu_state(ctx, 1);
895c2d04 28490 gen_helper_ei(t0, cpu_env);
35fbce2c 28491 gen_store_gpr(t0, rt);
7480515f
AM
28492 /*
28493 * DISAS_STOP isn't sufficient, we need to ensure we break
28494 * out of translated code to check for pending interrupts.
28495 */
eeb3bba8
EC
28496 gen_save_pc(ctx->base.pc_next + 4);
28497 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
28498 break;
28499 default: /* Invalid */
28500 MIPS_INVAL("mfmc0");
3a4ef3b7 28501 gen_reserved_instruction(ctx);
6c5c1e20
TS
28502 break;
28503 }
6c5c1e20 28504 tcg_temp_free(t0);
7a387fff 28505 }
0eaef5aa 28506#endif /* !CONFIG_USER_ONLY */
6af0bf9c 28507 break;
7a387fff 28508 case OPC_RDPGPR:
7a47bae5 28509 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 28510 gen_load_srsgpr(rt, rd);
ead9360e 28511 break;
7a387fff 28512 case OPC_WRPGPR:
7a47bae5 28513 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 28514 gen_store_srsgpr(rt, rd);
38121543 28515 break;
6af0bf9c 28516 default:
923617a3 28517 MIPS_INVAL("cp0");
3a4ef3b7 28518 gen_reserved_instruction(ctx);
6af0bf9c
FB
28519 break;
28520 }
28521 break;
31837be3 28522 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
2e211e0a 28523 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
28524 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28525 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28526 } else {
28527 /* OPC_ADDI */
28528 /* Arithmetic with immediate opcode */
28529 gen_arith_imm(ctx, op, rt, rs, imm);
28530 }
28531 break;
324d9e32 28532 case OPC_ADDIU:
d75c135e 28533 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28534 break;
324d9e32
AJ
28535 case OPC_SLTI: /* Set on less than with immediate opcode */
28536 case OPC_SLTIU:
d75c135e 28537 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
28538 break;
28539 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 28540 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
28541 case OPC_ORI:
28542 case OPC_XORI:
d75c135e 28543 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 28544 break;
c2e19f3c
AM
28545 case OPC_J: /* Jump */
28546 case OPC_JAL:
7a387fff 28547 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 28548 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 28549 break;
31837be3
YK
28550 /* Branch */
28551 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
2e211e0a 28552 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 28553 if (rt == 0) {
3a4ef3b7 28554 gen_reserved_instruction(ctx);
31837be3
YK
28555 break;
28556 }
28557 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28558 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28559 } else {
28560 /* OPC_BLEZL */
b231c103 28561 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28562 }
28563 break;
28564 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
2e211e0a 28565 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 28566 if (rt == 0) {
3a4ef3b7 28567 gen_reserved_instruction(ctx);
31837be3
YK
28568 break;
28569 }
28570 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28571 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28572 } else {
28573 /* OPC_BGTZL */
b231c103 28574 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28575 }
28576 break;
28577 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28578 if (rt == 0) {
28579 /* OPC_BLEZ */
b231c103 28580 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 28581 } else {
2e211e0a 28582 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
28583 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28584 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28585 }
28586 break;
28587 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28588 if (rt == 0) {
28589 /* OPC_BGTZ */
b231c103 28590 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 28591 } else {
2e211e0a 28592 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
28593 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28594 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28595 }
28596 break;
28597 case OPC_BEQL:
28598 case OPC_BNEL:
d9224450 28599 check_insn(ctx, ISA_MIPS2);
2e211e0a 28600 check_insn_opc_removed(ctx, ISA_MIPS_R6);
d9224450 28601 /* Fallthrough */
31837be3
YK
28602 case OPC_BEQ:
28603 case OPC_BNE:
b231c103 28604 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 28605 break;
d9224450
MR
28606 case OPC_LL: /* Load and stores */
28607 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
28608 if (ctx->insn_flags & INSN_R5900) {
28609 check_insn_opc_user_only(ctx, INSN_R5900);
28610 }
d9224450
MR
28611 /* Fallthrough */
28612 case OPC_LWL:
fecd2646 28613 case OPC_LWR:
2e211e0a 28614 check_insn_opc_removed(ctx, ISA_MIPS_R6);
d9224450 28615 /* Fallthrough */
c2e19f3c
AM
28616 case OPC_LB:
28617 case OPC_LH:
28618 case OPC_LW:
28619 case OPC_LWPC:
28620 case OPC_LBU:
28621 case OPC_LHU:
d75c135e 28622 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 28623 break;
fecd2646 28624 case OPC_SWL:
7a387fff 28625 case OPC_SWR:
2e211e0a 28626 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6f3b233 28627 /* fall through */
c2e19f3c
AM
28628 case OPC_SB:
28629 case OPC_SH:
fecd2646 28630 case OPC_SW:
5c13fdfd 28631 gen_st(ctx, op, rt, rs, imm);
7a387fff 28632 break;
d66c7132 28633 case OPC_SC:
d9224450 28634 check_insn(ctx, ISA_MIPS2);
2e211e0a 28635 check_insn_opc_removed(ctx, ISA_MIPS_R6);
55fc7a69
FN
28636 if (ctx->insn_flags & INSN_R5900) {
28637 check_insn_opc_user_only(ctx, INSN_R5900);
28638 }
33a07fa2
LA
28639 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
28640 break;
7a387fff 28641 case OPC_CACHE:
2e211e0a 28642 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2e15497c 28643 check_cp0_enabled(ctx);
bbd5e4a2 28644 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
0d74a222
LA
28645 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28646 gen_cache_operation(ctx, rt, rs, imm);
28647 }
ead9360e 28648 /* Treat as NOP. */
34ae7b51 28649 break;
7a387fff 28650 case OPC_PREF:
2e211e0a 28651 check_insn_opc_removed(ctx, ISA_MIPS_R6);
992e8176
FN
28652 if (ctx->insn_flags & INSN_R5900) {
28653 /* Treat as NOP. */
28654 } else {
bbd5e4a2 28655 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
992e8176
FN
28656 /* Treat as NOP. */
28657 }
6af0bf9c 28658 break;
4ad40f36 28659
923617a3 28660 /* Floating point (COP1). */
7a387fff
TS
28661 case OPC_LWC1:
28662 case OPC_LDC1:
28663 case OPC_SWC1:
28664 case OPC_SDC1:
5ab5c041 28665 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
28666 break;
28667
7a387fff 28668 case OPC_CP1:
5692c6e1
YK
28669 op1 = MASK_CP1(ctx->opcode);
28670
28671 switch (op1) {
28672 case OPC_MFHC1:
28673 case OPC_MTHC1:
5e755519 28674 check_cp1_enabled(ctx);
7a47bae5 28675 check_insn(ctx, ISA_MIPS_R2);
146dd620 28676 /* fall through */
5692c6e1
YK
28677 case OPC_MFC1:
28678 case OPC_CFC1:
28679 case OPC_MTC1:
28680 case OPC_CTC1:
28681 check_cp1_enabled(ctx);
28682 gen_cp1(ctx, op1, rt, rd);
28683 break;
d26bc211 28684#if defined(TARGET_MIPS64)
5692c6e1
YK
28685 case OPC_DMFC1:
28686 case OPC_DMTC1:
28687 check_cp1_enabled(ctx);
28688 check_insn(ctx, ISA_MIPS3);
d9224450 28689 check_mips_64(ctx);
5692c6e1
YK
28690 gen_cp1(ctx, op1, rt, rd);
28691 break;
e189e748 28692#endif
5692c6e1
YK
28693 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
28694 check_cp1_enabled(ctx);
2e211e0a 28695 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1 28696 /* OPC_BC1EQZ */
31837be3 28697 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 28698 rt, imm << 2, 4);
5692c6e1
YK
28699 } else {
28700 /* OPC_BC1ANY2 */
b8aa4598 28701 check_cop1x(ctx);
d75c135e 28702 check_insn(ctx, ASE_MIPS3D);
d75c135e 28703 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 28704 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
28705 }
28706 break;
28707 case OPC_BC1NEZ:
28708 check_cp1_enabled(ctx);
2e211e0a 28709 check_insn(ctx, ISA_MIPS_R6);
5692c6e1 28710 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 28711 rt, imm << 2, 4);
5692c6e1
YK
28712 break;
28713 case OPC_BC1ANY4:
28714 check_cp1_enabled(ctx);
2e211e0a 28715 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
28716 check_cop1x(ctx);
28717 check_insn(ctx, ASE_MIPS3D);
28718 /* fall through */
28719 case OPC_BC1:
28720 check_cp1_enabled(ctx);
2e211e0a 28721 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
28722 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28723 (rt >> 2) & 0x7, imm << 2);
28724 break;
28725 case OPC_PS_FMT:
e29c9628 28726 check_ps(ctx);
b6f3b233 28727 /* fall through */
5692c6e1
YK
28728 case OPC_S_FMT:
28729 case OPC_D_FMT:
28730 check_cp1_enabled(ctx);
28731 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28732 (imm >> 8) & 0x7);
28733 break;
28734 case OPC_W_FMT:
28735 case OPC_L_FMT:
28736 {
28737 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
28738 check_cp1_enabled(ctx);
2e211e0a 28739 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1
YK
28740 switch (r6_op) {
28741 case R6_OPC_CMP_AF_S:
28742 case R6_OPC_CMP_UN_S:
28743 case R6_OPC_CMP_EQ_S:
28744 case R6_OPC_CMP_UEQ_S:
28745 case R6_OPC_CMP_LT_S:
28746 case R6_OPC_CMP_ULT_S:
28747 case R6_OPC_CMP_LE_S:
28748 case R6_OPC_CMP_ULE_S:
28749 case R6_OPC_CMP_SAF_S:
28750 case R6_OPC_CMP_SUN_S:
28751 case R6_OPC_CMP_SEQ_S:
28752 case R6_OPC_CMP_SEUQ_S:
28753 case R6_OPC_CMP_SLT_S:
28754 case R6_OPC_CMP_SULT_S:
28755 case R6_OPC_CMP_SLE_S:
28756 case R6_OPC_CMP_SULE_S:
28757 case R6_OPC_CMP_OR_S:
28758 case R6_OPC_CMP_UNE_S:
28759 case R6_OPC_CMP_NE_S:
28760 case R6_OPC_CMP_SOR_S:
28761 case R6_OPC_CMP_SUNE_S:
28762 case R6_OPC_CMP_SNE_S:
28763 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28764 break;
28765 case R6_OPC_CMP_AF_D:
28766 case R6_OPC_CMP_UN_D:
28767 case R6_OPC_CMP_EQ_D:
28768 case R6_OPC_CMP_UEQ_D:
28769 case R6_OPC_CMP_LT_D:
28770 case R6_OPC_CMP_ULT_D:
28771 case R6_OPC_CMP_LE_D:
28772 case R6_OPC_CMP_ULE_D:
28773 case R6_OPC_CMP_SAF_D:
28774 case R6_OPC_CMP_SUN_D:
28775 case R6_OPC_CMP_SEQ_D:
28776 case R6_OPC_CMP_SEUQ_D:
28777 case R6_OPC_CMP_SLT_D:
28778 case R6_OPC_CMP_SULT_D:
28779 case R6_OPC_CMP_SLE_D:
28780 case R6_OPC_CMP_SULE_D:
28781 case R6_OPC_CMP_OR_D:
28782 case R6_OPC_CMP_UNE_D:
28783 case R6_OPC_CMP_NE_D:
28784 case R6_OPC_CMP_SOR_D:
28785 case R6_OPC_CMP_SUNE_D:
28786 case R6_OPC_CMP_SNE_D:
28787 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28788 break;
28789 default:
d2bfa6e6
MR
28790 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
28791 rt, rd, sa, (imm >> 8) & 0x7);
28792
5692c6e1 28793 break;
3f493883 28794 }
5692c6e1
YK
28795 } else {
28796 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28797 (imm >> 8) & 0x7);
36d23958 28798 }
5692c6e1
YK
28799 break;
28800 }
5692c6e1
YK
28801 default:
28802 MIPS_INVAL("cp1");
3a4ef3b7 28803 gen_reserved_instruction(ctx);
5692c6e1 28804 break;
6ea83fed 28805 }
4ad40f36
FB
28806 break;
28807
31837be3
YK
28808 /* Compact branches [R6] and COP2 [non-R6] */
28809 case OPC_BC: /* OPC_LWC2 */
28810 case OPC_BALC: /* OPC_SWC2 */
2e211e0a 28811 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
28812 /* OPC_BC, OPC_BALC */
28813 gen_compute_compact_branch(ctx, op, 0, 0,
28814 sextract32(ctx->opcode << 2, 0, 28));
e10a0ca1
JY
28815 } else if (ctx->insn_flags & ASE_LEXT) {
28816 gen_loongson_lswc2(ctx, rt, rs, rd);
31837be3
YK
28817 } else {
28818 /* OPC_LWC2, OPC_SWC2 */
28819 /* COP2: Not implemented. */
28820 generate_exception_err(ctx, EXCP_CpU, 2);
28821 }
28822 break;
28823 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28824 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
2e211e0a 28825 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
28826 if (rs != 0) {
28827 /* OPC_BEQZC, OPC_BNEZC */
28828 gen_compute_compact_branch(ctx, op, rs, 0,
28829 sextract32(ctx->opcode << 2, 0, 23));
28830 } else {
28831 /* OPC_JIC, OPC_JIALC */
28832 gen_compute_compact_branch(ctx, op, 0, rt, imm);
28833 }
90e22a57
JY
28834 } else if (ctx->insn_flags & ASE_LEXT) {
28835 gen_loongson_lsdc2(ctx, rt, rs, rd);
31837be3
YK
28836 } else {
28837 /* OPC_LWC2, OPC_SWC2 */
28838 /* COP2: Not implemented. */
28839 generate_exception_err(ctx, EXCP_CpU, 2);
28840 }
4ad40f36 28841 break;
bd277fa1 28842 case OPC_CP2:
8e2d5831 28843 check_insn(ctx, ASE_LMMI);
bd277fa1
RH
28844 /* Note that these instructions use different fields. */
28845 gen_loongson_multimedia(ctx, sa, rd, rt);
28846 break;
4ad40f36 28847
7a387fff 28848 case OPC_CP3:
2e211e0a 28849 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5ab5c041 28850 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 28851 check_cp1_enabled(ctx);
36d23958
TS
28852 op1 = MASK_CP3(ctx->opcode);
28853 switch (op1) {
d9224450
MR
28854 case OPC_LUXC1:
28855 case OPC_SUXC1:
7a47bae5 28856 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 28857 /* Fallthrough */
5a5012ec
TS
28858 case OPC_LWXC1:
28859 case OPC_LDXC1:
5a5012ec
TS
28860 case OPC_SWXC1:
28861 case OPC_SDXC1:
7a47bae5 28862 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
93b12ccc 28863 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 28864 break;
e0c84da7 28865 case OPC_PREFX:
7a47bae5 28866 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
ead9360e 28867 /* Treat as NOP. */
e0c84da7 28868 break;
5a5012ec 28869 case OPC_ALNV_PS:
7a47bae5 28870 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 28871 /* Fallthrough */
5a5012ec
TS
28872 case OPC_MADD_S:
28873 case OPC_MADD_D:
28874 case OPC_MADD_PS:
28875 case OPC_MSUB_S:
28876 case OPC_MSUB_D:
28877 case OPC_MSUB_PS:
28878 case OPC_NMADD_S:
28879 case OPC_NMADD_D:
28880 case OPC_NMADD_PS:
28881 case OPC_NMSUB_S:
28882 case OPC_NMSUB_D:
28883 case OPC_NMSUB_PS:
7a47bae5 28884 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
5a5012ec
TS
28885 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28886 break;
36d23958 28887 default:
923617a3 28888 MIPS_INVAL("cp3");
3a4ef3b7 28889 gen_reserved_instruction(ctx);
36d23958
TS
28890 break;
28891 }
28892 } else {
e397ee33 28893 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 28894 }
4ad40f36
FB
28895 break;
28896
d26bc211 28897#if defined(TARGET_MIPS64)
7a387fff 28898 /* MIPS64 opcodes */
96631327 28899 case OPC_LLD:
55fc7a69
FN
28900 if (ctx->insn_flags & INSN_R5900) {
28901 check_insn_opc_user_only(ctx, INSN_R5900);
28902 }
96631327 28903 /* fall through */
c2e19f3c
AM
28904 case OPC_LDL:
28905 case OPC_LDR:
2e211e0a 28906 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6f3b233 28907 /* fall through */
fecd2646 28908 case OPC_LWU:
7a387fff 28909 case OPC_LD:
d75c135e 28910 check_insn(ctx, ISA_MIPS3);
5c13fdfd 28911 check_mips_64(ctx);
d75c135e 28912 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 28913 break;
c2e19f3c
AM
28914 case OPC_SDL:
28915 case OPC_SDR:
2e211e0a 28916 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6f3b233 28917 /* fall through */
7a387fff 28918 case OPC_SD:
d75c135e 28919 check_insn(ctx, ISA_MIPS3);
e189e748 28920 check_mips_64(ctx);
5c13fdfd 28921 gen_st(ctx, op, rt, rs, imm);
7a387fff 28922 break;
d66c7132 28923 case OPC_SCD:
2e211e0a 28924 check_insn_opc_removed(ctx, ISA_MIPS_R6);
d75c135e 28925 check_insn(ctx, ISA_MIPS3);
55fc7a69
FN
28926 if (ctx->insn_flags & INSN_R5900) {
28927 check_insn_opc_user_only(ctx, INSN_R5900);
28928 }
d66c7132 28929 check_mips_64(ctx);
33a07fa2 28930 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
d66c7132 28931 break;
31837be3 28932 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
2e211e0a 28933 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
28934 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28935 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28936 } else {
28937 /* OPC_DADDI */
28938 check_insn(ctx, ISA_MIPS3);
28939 check_mips_64(ctx);
28940 gen_arith_imm(ctx, op, rt, rs, imm);
28941 }
28942 break;
324d9e32 28943 case OPC_DADDIU:
d75c135e 28944 check_insn(ctx, ISA_MIPS3);
e189e748 28945 check_mips_64(ctx);
d75c135e 28946 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28947 break;
31837be3
YK
28948#else
28949 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
2e211e0a 28950 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
28951 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28952 } else {
28953 MIPS_INVAL("major opcode");
3a4ef3b7 28954 gen_reserved_instruction(ctx);
31837be3
YK
28955 }
28956 break;
6af0bf9c 28957#endif
d4ea6acd 28958 case OPC_DAUI: /* OPC_JALX */
2e211e0a 28959 if (ctx->insn_flags & ISA_MIPS_R6) {
d4ea6acd
LA
28960#if defined(TARGET_MIPS64)
28961 /* OPC_DAUI */
28962 check_mips_64(ctx);
db77d852
LA
28963 if (rs == 0) {
28964 generate_exception(ctx, EXCP_RI);
28965 } else if (rt != 0) {
d4ea6acd
LA
28966 TCGv t0 = tcg_temp_new();
28967 gen_load_gpr(t0, rs);
28968 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28969 tcg_temp_free(t0);
28970 }
d4ea6acd 28971#else
3a4ef3b7 28972 gen_reserved_instruction(ctx);
d4ea6acd
LA
28973 MIPS_INVAL("major opcode");
28974#endif
28975 } else {
28976 /* OPC_JALX */
28977 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28978 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 28979 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 28980 }
364d4831 28981 break;
96e5b4c7 28982 case OPC_MDMX: /* MMI_OPC_LQ */
f08099ad 28983 if (ctx->insn_flags & INSN_R5900) {
37b9aae2 28984#if defined(TARGET_MIPS64)
96e5b4c7 28985 gen_mmi_lq(env, ctx);
37b9aae2 28986#endif
f08099ad
FN
28987 } else {
28988 /* MDMX: Not implemented. */
f08099ad 28989 }
d4ea6acd
LA
28990 break;
28991 case OPC_PCREL:
2e211e0a 28992 check_insn(ctx, ISA_MIPS_R6);
eeb3bba8 28993 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 28994 break;
6af0bf9c 28995 default: /* Invalid */
923617a3 28996 MIPS_INVAL("major opcode");
311edee7 28997 return false;
6af0bf9c 28998 }
311edee7
PMD
28999 return true;
29000}
29001
29002static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29003{
29004 /* make sure instructions are on a word boundary */
29005 if (ctx->base.pc_next & 0x3) {
29006 env->CP0_BadVAddr = ctx->base.pc_next;
29007 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29008 return;
29009 }
29010
29011 /* Handle blikely not taken case */
29012 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29013 TCGLabel *l1 = gen_new_label();
29014
29015 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29016 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29017 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29018 gen_set_label(l1);
29019 }
29020
96e5b4c7
PMD
29021 /* Transition to the auto-generated decoder. */
29022
29023 /* ISA extensions */
29024 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
29025 return;
29026 }
29027
3f7a9278
PMD
29028 /* ISA (from latest to oldest) */
29029 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
29030 return;
29031 }
29032
311edee7
PMD
29033 if (decode_opc_legacy(env, ctx)) {
29034 return;
29035 }
29036
29037 gen_reserved_instruction(ctx);
6af0bf9c
FB
29038}
29039
18f440ed 29040static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 29041{
18f440ed 29042 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 29043 CPUMIPSState *env = cs->env_ptr;
12be9258 29044
18f440ed 29045 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
29046 ctx->saved_pc = -1;
29047 ctx->insn_flags = env->insn_flags;
29048 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 29049 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
29050 ctx->CP0_Config3 = env->CP0_Config3;
29051 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
29052 ctx->btarget = 0;
29053 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29054 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29055 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29056 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29057 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29058 ctx->PAMask = env->PAMask;
29059 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29060 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29061 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29062 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29063 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 29064 /* Restore delay slot state from the tb context. */
12be9258
EC
29065 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29066 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29067 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 29068 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
29069 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29070 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29071 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29072 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
feafe82c 29073 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
99029be1 29074 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
12be9258 29075 restore_cpu_state(env, ctx);
932e71cd 29076#ifdef CONFIG_USER_ONLY
12be9258 29077 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 29078#else
12be9258 29079 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 29080#endif
2e211e0a 29081 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
8a805609 29082 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
190ce7fb 29083
18f440ed
EC
29084 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29085 ctx->hflags);
29086}
12be9258 29087
18f440ed
EC
29088static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29089{
29090}
b933066a 29091
18f440ed
EC
29092static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29093{
29094 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 29095
18f440ed
EC
29096 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29097 ctx->btarget);
29098}
31837be3 29099
18f440ed
EC
29100static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29101 const CPUBreakpoint *bp)
29102{
29103 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 29104
18f440ed
EC
29105 save_cpu_state(ctx, 1);
29106 ctx->base.is_jmp = DISAS_NORETURN;
29107 gen_helper_raise_exception_debug(cpu_env);
7480515f
AM
29108 /*
29109 * The address covered by the breakpoint must be included in
29110 * [tb->pc, tb->pc + tb->size) in order to for it to be
29111 * properly cleared -- thus we increment the PC here so that
29112 * the logic setting tb->size below does the right thing.
29113 */
18f440ed
EC
29114 ctx->base.pc_next += 4;
29115 return true;
29116}
4ad40f36 29117
18f440ed
EC
29118static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29119{
29120 CPUMIPSState *env = cs->env_ptr;
29121 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29122 int insn_bytes;
29123 int is_slot;
4ad40f36 29124
18f440ed 29125 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
29126 if (ctx->insn_flags & ISA_NANOMIPS32) {
29127 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29128 insn_bytes = decode_nanomips_opc(env, ctx);
29129 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
29130 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29131 insn_bytes = 4;
29132 decode_opc(env, ctx);
29133 } else if (ctx->insn_flags & ASE_MICROMIPS) {
29134 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29135 insn_bytes = decode_micromips_opc(env, ctx);
29136 } else if (ctx->insn_flags & ASE_MIPS16) {
29137 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29138 insn_bytes = decode_mips16_opc(env, ctx);
29139 } else {
3a4ef3b7 29140 gen_reserved_instruction(ctx);
18f440ed
EC
29141 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29142 return;
29143 }
faf7aaa9 29144
18f440ed
EC
29145 if (ctx->hflags & MIPS_HFLAG_BMASK) {
29146 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29147 MIPS_HFLAG_FBNSLOT))) {
7480515f
AM
29148 /*
29149 * Force to generate branch as there is neither delay nor
29150 * forbidden slot.
29151 */
18f440ed
EC
29152 is_slot = 1;
29153 }
29154 if ((ctx->hflags & MIPS_HFLAG_M16) &&
29155 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
7480515f
AM
29156 /*
29157 * Force to generate branch as microMIPS R6 doesn't restrict
29158 * branches in the forbidden slot.
29159 */
18f440ed 29160 is_slot = 1;
eeb3bba8 29161 }
18f440ed
EC
29162 }
29163 if (is_slot) {
29164 gen_branch(ctx, insn_bytes);
29165 }
29166 ctx->base.pc_next += insn_bytes;
1b530a6d 29167
18f440ed
EC
29168 if (ctx->base.is_jmp != DISAS_NEXT) {
29169 return;
6af0bf9c 29170 }
7480515f
AM
29171 /*
29172 * Execute a branch and its delay slot as a single instruction.
29173 * This is what GDB expects and is consistent with what the
29174 * hardware does (e.g. if a delay slot instruction faults, the
29175 * reported PC is the PC of the branch).
29176 */
18f440ed
EC
29177 if (ctx->base.singlestep_enabled &&
29178 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29179 ctx->base.is_jmp = DISAS_TOO_MANY;
29180 }
29181 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29182 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 29183 }
18f440ed
EC
29184}
29185
29186static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29187{
29188 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29189
12be9258
EC
29190 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29191 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 29192 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 29193 } else {
12be9258 29194 switch (ctx->base.is_jmp) {
b28425ba 29195 case DISAS_STOP:
12be9258 29196 gen_save_pc(ctx->base.pc_next);
cd314a7d 29197 tcg_gen_lookup_and_goto_ptr();
df1561e2 29198 break;
b28425ba 29199 case DISAS_NEXT:
18f440ed 29200 case DISAS_TOO_MANY:
12be9258
EC
29201 save_cpu_state(ctx, 0);
29202 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 29203 break;
b28425ba 29204 case DISAS_EXIT:
07ea28b4 29205 tcg_gen_exit_tb(NULL, 0);
16c00cb2 29206 break;
b28425ba 29207 case DISAS_NORETURN:
5a5012ec 29208 break;
18f440ed
EC
29209 default:
29210 g_assert_not_reached();
6958549d 29211 }
6af0bf9c 29212 }
18f440ed
EC
29213}
29214
29215static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29216{
29217 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29218 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29219}
29220
29221static const TranslatorOps mips_tr_ops = {
29222 .init_disas_context = mips_tr_init_disas_context,
29223 .tb_start = mips_tr_tb_start,
29224 .insn_start = mips_tr_insn_start,
29225 .breakpoint_check = mips_tr_breakpoint_check,
29226 .translate_insn = mips_tr_translate_insn,
29227 .tb_stop = mips_tr_tb_stop,
29228 .disas_log = mips_tr_disas_log,
29229};
29230
8b86d6d2 29231void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
18f440ed
EC
29232{
29233 DisasContext ctx;
29234
8b86d6d2 29235 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
6af0bf9c
FB
29236}
29237
71375b59 29238static void fpu_dump_state(CPUMIPSState *env, FILE * f, int flags)
6ea83fed
FB
29239{
29240 int i;
5e755519 29241 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 29242
2a5612e6
SW
29243#define printfpr(fp) \
29244 do { \
29245 if (is_fpu64) \
90c84c56
MA
29246 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29247 " fd:%13g fs:%13g psu: %13g\n", \
29248 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29249 (double)(fp)->fd, \
29250 (double)(fp)->fs[FP_ENDIAN_IDX], \
29251 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
2a5612e6
SW
29252 else { \
29253 fpr_t tmp; \
29254 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29255 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
90c84c56
MA
29256 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29257 " fd:%13g fs:%13g psu:%13g\n", \
29258 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29259 (double)tmp.fd, \
29260 (double)tmp.fs[FP_ENDIAN_IDX], \
29261 (double)tmp.fs[!FP_ENDIAN_IDX]); \
2a5612e6 29262 } \
71375b59 29263 } while (0)
6ea83fed 29264
5a5012ec 29265
90c84c56
MA
29266 qemu_fprintf(f,
29267 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29268 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29269 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec 29270 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
90c84c56 29271 qemu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 29272 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
29273 }
29274
29275#undef printfpr
29276}
29277
90c84c56 29278void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
6af0bf9c 29279{
878096ee
AF
29280 MIPSCPU *cpu = MIPS_CPU(cs);
29281 CPUMIPSState *env = &cpu->env;
6af0bf9c 29282 int i;
3b46e624 29283
90c84c56
MA
29284 qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29285 " LO=0x" TARGET_FMT_lx " ds %04x "
29286 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29287 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29288 env->hflags, env->btarget, env->bcond);
6af0bf9c 29289 for (i = 0; i < 32; i++) {
1f8929d2 29290 if ((i & 3) == 0) {
90c84c56 29291 qemu_fprintf(f, "GPR%02d:", i);
1f8929d2 29292 }
90c84c56
MA
29293 qemu_fprintf(f, " %s " TARGET_FMT_lx,
29294 regnames[i], env->active_tc.gpr[i]);
1f8929d2 29295 if ((i & 3) == 3) {
90c84c56 29296 qemu_fprintf(f, "\n");
1f8929d2 29297 }
90c84c56
MA
29298 }
29299
71375b59
AM
29300 qemu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
29301 TARGET_FMT_lx "\n",
90c84c56
MA
29302 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29303 qemu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29304 PRIx64 "\n",
29305 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
29306 qemu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
29307 env->CP0_Config2, env->CP0_Config3);
29308 qemu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
29309 env->CP0_Config4, env->CP0_Config5);
1cc5af69 29310 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
90c84c56 29311 fpu_dump_state(env, f, flags);
1cc5af69 29312 }
6af0bf9c
FB
29313}
29314
959c5da2
PMD
29315void mips_tcg_init(void)
29316{
29317 int i;
29318
29319 cpu_gpr[0] = NULL;
29320 for (i = 1; i < 32; i++)
29321 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29322 offsetof(CPUMIPSState,
29323 active_tc.gpr[i]),
29324 regnames[i]);
29325 for (i = 0; i < 32; i++) {
29326 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
863f264d 29327
959c5da2
PMD
29328 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
29329 }
29330 msa_translate_init();
e1ccc054 29331 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 29332 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 29333 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 29334 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 29335 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 29336 regnames_HI[i]);
e1ccc054 29337 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 29338 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 29339 regnames_LO[i]);
4b2eb8d2 29340 }
e1ccc054 29341 cpu_dspctrl = tcg_global_mem_new(cpu_env,
71375b59
AM
29342 offsetof(CPUMIPSState,
29343 active_tc.DSPControl),
4b2eb8d2 29344 "DSPControl");
e1ccc054 29345 bcond = tcg_global_mem_new(cpu_env,
7db13fae 29346 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 29347 btarget = tcg_global_mem_new(cpu_env,
7db13fae 29348 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 29349 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 29350 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 29351
e1ccc054 29352 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29353 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 29354 "fcr0");
e1ccc054 29355 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29356 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 29357 "fcr31");
33a07fa2
LA
29358 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
29359 "lladdr");
29360 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
29361 "llval");
a168a796
FN
29362
29363#if defined(TARGET_MIPS64)
29364 cpu_mmr[0] = NULL;
29365 for (i = 1; i < 32; i++) {
29366 cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
29367 offsetof(CPUMIPSState,
29368 active_tc.mmr[i]),
29369 regnames[i]);
29370 }
29371#endif
29372
b621f018 29373#if !defined(TARGET_MIPS64)
eb5559f6
CJ
29374 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29375 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29376 offsetof(CPUMIPSState,
29377 active_tc.mxu_gpr[i]),
29378 mxuregnames[i]);
29379 }
29380
29381 mxu_CR = tcg_global_mem_new(cpu_env,
29382 offsetof(CPUMIPSState, active_tc.mxu_cr),
29383 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
b621f018 29384#endif
39454628
TS
29385}
29386
bad729e2
RH
29387void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
29388 target_ulong *data)
d2856f1a 29389{
bad729e2 29390 env->active_tc.PC = data[0];
d2856f1a 29391 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 29392 env->hflags |= data[1];
4636401d
AJ
29393 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
29394 case MIPS_HFLAG_BR:
29395 break;
29396 case MIPS_HFLAG_BC:
29397 case MIPS_HFLAG_BL:
29398 case MIPS_HFLAG_B:
bad729e2 29399 env->btarget = data[2];
4636401d
AJ
29400 break;
29401 }
d2856f1a 29402}