]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
avoid TABs in files that only contain a few
[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)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
c684822a 24#include "qemu/osdep.h"
6af0bf9c 25#include "cpu.h"
26aa3d9a 26#include "internal.h"
76cad711 27#include "disas/disas.h"
63c91552 28#include "exec/exec-all.h"
57fec1fe 29#include "tcg-op.h"
f08b6170 30#include "exec/cpu_ldst.h"
d3d93c6c 31#include "hw/mips/cpudevs.h"
6af0bf9c 32
2ef6175a
RH
33#include "exec/helper-proto.h"
34#include "exec/helper-gen.h"
3b3c1694 35#include "exec/semihost.h"
a7812ae4 36
b44a7fb1 37#include "target/mips/trace.h"
a7e30d84 38#include "trace-tcg.h"
b28425ba 39#include "exec/translator.h"
508127e2 40#include "exec/log.h"
a7e30d84 41
fb7729e2 42#define MIPS_DEBUG_DISAS 0
6af0bf9c 43
7a387fff
TS
44/* MIPS major opcodes */
45#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
46
47enum {
48 /* indirect opcode tables */
7a387fff
TS
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 57 /* arithmetic with immediate */
7a387fff
TS
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
324d9e32 62 /* logic with immediate */
7a387fff
TS
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
324d9e32 67 /* arithmetic with immediate */
7a387fff
TS
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
e37e863f 70 /* Jump and branches */
7a387fff
TS
71 OPC_J = (0x02 << 26),
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
b231c103 81 OPC_JALX = (0x1D << 26),
d4ea6acd 82 OPC_DAUI = (0x1D << 26),
e37e863f 83 /* Load and stores */
7a387fff
TS
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
364d4831 90 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
364d4831 105 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
e37e863f 109 /* Floating point load/store */
7a387fff
TS
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
31837be3
YK
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
7a387fff
TS
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
239dfebe
YK
145 /* MSA ASE, same as MDMX */
146 OPC_MSA = OPC_MDMX,
e37e863f 147 /* Cache and prefetch */
7a387fff
TS
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
152};
153
154/* PC-relative address computation / loads */
155#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157enum {
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
162
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
166
167 /* Other */
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
169};
170
171/* MIPS special opcodes */
7a387fff
TS
172#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173
e37e863f
FB
174enum {
175 /* Shifts */
7a387fff 176 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 181 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 185 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 193 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 199 /* Multiplication / division */
7a387fff
TS
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 208
e37e863f 209 /* 2 registers arithmetic / logic */
7a387fff
TS
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 224 /* Jumps */
7a387fff
TS
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 227 /* Traps */
7a387fff
TS
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 234 /* HI / LO registers load & stores */
7a387fff
TS
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 239 /* Conditional moves */
7a387fff
TS
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 242
b691d9d2
LA
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
245
7a387fff 246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
247
248 /* Special */
a0d700e4 249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
254
7a387fff
TS
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259};
260
b42ee5e1
LA
261/* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265enum {
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
274
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
283
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
289
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
292};
293
e9c71dd1
TS
294/* Multiplication variants of the vr54xx. */
295#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297enum {
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312};
313
7a387fff
TS
314/* REGIMM (rt field) opcodes */
315#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317enum {
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
334
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
337};
338
7a387fff
TS
339/* Special2 opcodes */
340#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
341
e37e863f 342enum {
7a387fff
TS
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
349 /* Loongson 2F */
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 362 /* Misc */
7a387fff
TS
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 367 /* Special */
7a387fff
TS
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
369};
370
371/* Special3 opcodes */
372#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
373
374enum {
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
388
389 /* Loongson 2E */
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
402
403 /* MIPS DSP Load */
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 425 /* MIPS DSP Append Sub-class */
26690560 426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 431
76964147
JH
432 /* EVA */
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
449
4368b29a 450 /* R6 */
bf7910c6
LA
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
457};
458
7a387fff
TS
459/* BSHFL opcodes */
460#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
e37e863f 462enum {
15eacb9b
YK
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
373ecd38
AM
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
467 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
468 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
469 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
15eacb9b 470 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
471};
472
7a387fff
TS
473/* DBSHFL opcodes */
474#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
475
e37e863f 476enum {
15eacb9b
YK
477 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
478 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
373ecd38
AM
479 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
481 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
482 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
483 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
484 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
485 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
486 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
15eacb9b 487 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
488};
489
e45a93e2
JL
490/* MIPS DSP REGIMM opcodes */
491enum {
492 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 493 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
494};
495
9b1a1d68
JL
496#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497/* MIPS DSP Load */
498enum {
499 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
501 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 502 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
503};
504
461c08df
JL
505#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506enum {
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
509 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
511 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
515 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
522 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
523 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
524 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
525 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
526 /* MIPS DSP Multiply Sub-class insns */
527 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
530 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
533};
534
535#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
537enum {
538 /* MIPS DSP Arithmetic Sub-class */
539 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
556};
557
558#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
559enum {
560 /* MIPS DSP Arithmetic Sub-class */
561 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
574 /* DSP Bit/Manipulation Sub-class */
575 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
580};
581
582#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
584 /* MIPS DSP Arithmetic Sub-class */
585 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
592 /* DSP Compare-Pick Sub-class */
593 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 608};
a22260ae 609
77c5fa8b
JL
610#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
611enum {
612 /* MIPS DSP GPR-Based Shift Sub-class */
613 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
635};
461c08df 636
a22260ae
JL
637#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638enum {
639 /* MIPS DSP Multiply Sub-class insns */
640 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
662};
663
1cb6686c
JL
664#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
665enum {
666 /* DSP Bit/Manipulation Sub-class */
667 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
668};
669
26690560
JL
670#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
df6126a7 672 /* MIPS DSP Append Sub-class */
26690560
JL
673 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
674 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
676};
677
b53371ed
JL
678#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679enum {
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
693 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
694 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
695 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
696 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
697 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
698};
699
461c08df
JL
700#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701enum {
702 /* MIPS DSP Arithmetic Sub-class */
703 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
720 /* DSP Bit/Manipulation Sub-class */
721 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 727};
461c08df 728
461c08df
JL
729#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730enum {
a22260ae
JL
731 /* MIPS DSP Multiply Sub-class insns */
732 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
737 /* MIPS DSP Arithmetic Sub-class */
738 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
759};
461c08df 760
461c08df
JL
761#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762enum {
26690560
JL
763 /* DSP Compare-Pick Sub-class */
764 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
783 /* MIPS DSP Arithmetic Sub-class */
784 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
792};
461c08df 793
26690560
JL
794#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
795enum {
df6126a7 796 /* DSP Append Sub-class */
26690560
JL
797 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
798 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
801};
26690560 802
b53371ed
JL
803#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804enum {
805 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
807 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
827};
828
1cb6686c
JL
829#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830enum {
831 /* DSP Bit/Manipulation Sub-class */
832 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
833};
1cb6686c 834
a22260ae
JL
835#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836enum {
837 /* MIPS DSP Multiply Sub-class insns */
838 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
864};
a22260ae 865
77c5fa8b
JL
866#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
867enum {
868 /* MIPS DSP GPR-Based Shift Sub-class */
869 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
895};
77c5fa8b 896
7a387fff
TS
897/* Coprocessor 0 (rs field) */
898#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
899
6ea83fed 900enum {
7a387fff
TS
901 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
902 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 903 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
904 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
905 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 906 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 907 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
908 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
909 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 910 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
911 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
912 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
913 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
914 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
915 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
916 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
917 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
918 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
919 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
920 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
921 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
922 OPC_C0_A = (0x1A << 21) | OPC_CP0,
923 OPC_C0_B = (0x1B << 21) | OPC_CP0,
924 OPC_C0_C = (0x1C << 21) | OPC_CP0,
925 OPC_C0_D = (0x1D << 21) | OPC_CP0,
926 OPC_C0_E = (0x1E << 21) | OPC_CP0,
927 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 928};
7a387fff
TS
929
930/* MFMC0 opcodes */
b48cfdff 931#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
932
933enum {
ead9360e
TS
934 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
937 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
938 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
940 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
942};
943
944/* Coprocessor 0 (with rs == C0) */
945#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
946
947enum {
948 OPC_TLBR = 0x01 | OPC_C0,
949 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
950 OPC_TLBINV = 0x03 | OPC_C0,
951 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
952 OPC_TLBWR = 0x06 | OPC_C0,
953 OPC_TLBP = 0x08 | OPC_C0,
954 OPC_RFE = 0x10 | OPC_C0,
955 OPC_ERET = 0x18 | OPC_C0,
956 OPC_DERET = 0x1F | OPC_C0,
957 OPC_WAIT = 0x20 | OPC_C0,
958};
959
960/* Coprocessor 1 (rs field) */
961#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
962
bf4120ad
NF
963/* Values for the fmt field in FP instructions */
964enum {
965 /* 0 - 15 are reserved */
e459440a
AJ
966 FMT_S = 16, /* single fp */
967 FMT_D = 17, /* double fp */
968 FMT_E = 18, /* extended fp */
969 FMT_Q = 19, /* quad fp */
970 FMT_W = 20, /* 32-bit fixed */
971 FMT_L = 21, /* 64-bit fixed */
972 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
973 /* 23 - 31 are reserved */
974};
975
7a387fff
TS
976enum {
977 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
978 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
979 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 980 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
981 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
982 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
983 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 984 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 985 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
986 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
987 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
988 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
989 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
990 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
991 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
992 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
993 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
994 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
995 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
996 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
997 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
998 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
999 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1000 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1001 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1002 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1003 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1004 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1005 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1006 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
1007};
1008
5a5012ec
TS
1009#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1010#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1011
7a387fff
TS
1012enum {
1013 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1014 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1015 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1016 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1017};
1018
5a5012ec
TS
1019enum {
1020 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1021 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1022};
1023
1024enum {
1025 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1026 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1027};
7a387fff
TS
1028
1029#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1030
1031enum {
1032 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1033 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1034 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1035 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1036 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1037 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1038 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1039 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1040 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1041 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1042 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1043};
1044
bd277fa1
RH
1045#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047enum {
1048 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1049 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1051 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1056
1057 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1058 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1060 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1065
1066 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1067 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1071 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1072 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1073 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1074
1075 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1080 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1081 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1083
1084 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1085 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1086 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1087 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1088 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1090
1091 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1099 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1100 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1101 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1106 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1107 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1108 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1114 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1115 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1121 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1122 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1127 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1129 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1130 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1134 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1136 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1138 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139};
1140
1141
e0c84da7
TS
1142#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144enum {
1145 OPC_LWXC1 = 0x00 | OPC_CP3,
1146 OPC_LDXC1 = 0x01 | OPC_CP3,
1147 OPC_LUXC1 = 0x05 | OPC_CP3,
1148 OPC_SWXC1 = 0x08 | OPC_CP3,
1149 OPC_SDXC1 = 0x09 | OPC_CP3,
1150 OPC_SUXC1 = 0x0D | OPC_CP3,
1151 OPC_PREFX = 0x0F | OPC_CP3,
1152 OPC_ALNV_PS = 0x1E | OPC_CP3,
1153 OPC_MADD_S = 0x20 | OPC_CP3,
1154 OPC_MADD_D = 0x21 | OPC_CP3,
1155 OPC_MADD_PS = 0x26 | OPC_CP3,
1156 OPC_MSUB_S = 0x28 | OPC_CP3,
1157 OPC_MSUB_D = 0x29 | OPC_CP3,
1158 OPC_MSUB_PS = 0x2E | OPC_CP3,
1159 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1160 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1161 OPC_NMADD_PS= 0x36 | OPC_CP3,
1162 OPC_NMSUB_S = 0x38 | OPC_CP3,
1163 OPC_NMSUB_D = 0x39 | OPC_CP3,
1164 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165};
1166
239dfebe
YK
1167/* MSA Opcodes */
1168#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1169enum {
1170 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1171 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1172 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1173 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1174 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1175 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1176 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1177 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1178 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1179 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1180 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1181 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1182 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1183 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1184 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1185 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1186 OPC_MSA_ELM = 0x19 | OPC_MSA,
1187 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1188 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1189 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1190 OPC_MSA_VEC = 0x1E | OPC_MSA,
1191
1192 /* MI10 instruction */
1193 OPC_LD_B = (0x20) | OPC_MSA,
1194 OPC_LD_H = (0x21) | OPC_MSA,
1195 OPC_LD_W = (0x22) | OPC_MSA,
1196 OPC_LD_D = (0x23) | OPC_MSA,
1197 OPC_ST_B = (0x24) | OPC_MSA,
1198 OPC_ST_H = (0x25) | OPC_MSA,
1199 OPC_ST_W = (0x26) | OPC_MSA,
1200 OPC_ST_D = (0x27) | OPC_MSA,
1201};
1202
1203enum {
1204 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1206 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1207 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1208 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1209 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1210 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1211 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1212 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1213 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1214 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1215 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1216 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218 /* I8 instruction */
1219 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1220 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1222 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1223 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1225 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1226 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1228 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230 /* VEC/2R/2RF instruction */
1231 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1232 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1233 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1234 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1235 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1236 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1237 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1238
1239 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1240 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1241
1242 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248 /* 2RF instruction df(bit 16) = _w, _d */
1249 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1250 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1253 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1254 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1255 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1256 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1257 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1258 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1259 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1260 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1261 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1262 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1263 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1264 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1265
1266 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1268 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1269 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1270 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1272 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1274 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1275 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1276 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1277 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1278 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1279 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1280 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1281 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1282 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1283 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1284 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1285 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1286 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1287 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1288 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1290 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1292 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1293 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1294 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1295 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1296 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1297 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1299 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1300 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1301 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1302 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1303 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1304 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1305 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1306 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1307 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1308 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1309 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1310 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1311 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1312 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1313 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1314 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1315 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1316 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1317 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1318 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1319 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1320 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1321 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1322 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1323 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1324 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1325 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1326 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1327 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1328 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1329 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342 /* 3RF instruction _df(bit 21) = _w, _d */
1343 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1346 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1347 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1348 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1356 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1361 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1362 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1363 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1364 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1365 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1366 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1367 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1369 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1370 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1372 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1373 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1374 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1375 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1378 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1381 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1387 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1388 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1389 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1390 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1391 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1392 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1393 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1394 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1395 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1396 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1397 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1398};
1399
b158d449
AM
1400
1401/*
b158d449 1402 *
84e2c895
AM
1403 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1404 * ============================================
1405 *
1406 *
1407 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
b158d449
AM
1408 * instructions set. It is designed to fit the needs of signal, graphical and
1409 * video processing applications. MXU instruction set is used in Xburst family
1410 * of microprocessors by Ingenic.
1411 *
1412 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1413 * the control register.
1414 *
093ade12 1415 *
84e2c895
AM
1416 * The notation used in MXU assembler mnemonics
1417 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1418 *
1419 * Register operands:
1d0e663c
AM
1420 *
1421 * XRa, XRb, XRc, XRd - MXU registers
1422 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
093ade12 1423 *
84e2c895 1424 * Non-register operands:
093ade12 1425 *
84e2c895
AM
1426 * aptn1 - 1-bit accumulate add/subtract pattern
1427 * aptn2 - 2-bit accumulate add/subtract pattern
1428 * eptn2 - 2-bit execute add/subtract pattern
1429 * optn2 - 2-bit operand pattern
1430 * optn3 - 3-bit operand pattern
1431 * sft4 - 4-bit shift amount
1432 * strd2 - 2-bit stride amount
093ade12
AM
1433 *
1434 * Prefixes:
1435 *
84e2c895
AM
1436 * Level of parallelism: Operand size:
1437 * S - single operation at a time 32 - word
1438 * D - two operations in parallel 16 - half word
1439 * Q - four operations in parallel 8 - byte
093ade12
AM
1440 *
1441 * Operations:
1442 *
1443 * ADD - Add or subtract
1444 * ADDC - Add with carry-in
1445 * ACC - Accumulate
1446 * ASUM - Sum together then accumulate (add or subtract)
1447 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1448 * AVG - Average between 2 operands
1449 * ABD - Absolute difference
1450 * ALN - Align data
1451 * AND - Logical bitwise 'and' operation
1452 * CPS - Copy sign
1453 * EXTR - Extract bits
1454 * I2M - Move from GPR register to MXU register
1455 * LDD - Load data from memory to XRF
1456 * LDI - Load data from memory to XRF (and increase the address base)
1457 * LUI - Load unsigned immediate
1458 * MUL - Multiply
1459 * MULU - Unsigned multiply
1460 * MADD - 64-bit operand add 32x32 product
1461 * MSUB - 64-bit operand subtract 32x32 product
1462 * MAC - Multiply and accumulate (add or subtract)
1463 * MAD - Multiply and add or subtract
1464 * MAX - Maximum between 2 operands
1465 * MIN - Minimum between 2 operands
1466 * M2I - Move from MXU register to GPR register
1467 * MOVZ - Move if zero
1468 * MOVN - Move if non-zero
1469 * NOR - Logical bitwise 'nor' operation
1470 * OR - Logical bitwise 'or' operation
1471 * STD - Store data from XRF to memory
1472 * SDI - Store data from XRF to memory (and increase the address base)
1473 * SLT - Set of less than comparison
1474 * SAD - Sum of absolute differences
1475 * SLL - Logical shift left
1476 * SLR - Logical shift right
1477 * SAR - Arithmetic shift right
1478 * SAT - Saturation
1479 * SFL - Shuffle
1480 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1481 * XOR - Logical bitwise 'exclusive or' operation
1d0e663c 1482 *
84e2c895
AM
1483 * Suffixes:
1484 *
1485 * E - Expand results
1486 * F - Fixed point multiplication
1487 * L - Low part result
1488 * R - Doing rounding
1489 * V - Variable instead of immediate
1490 * W - Combine above L and V
1491 *
1492 *
1493 * The list of MXU instructions grouped by functionality
1494 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1495 *
1d0e663c
AM
1496 * Load/Store instructions Multiplication instructions
1497 * ----------------------- ---------------------------
1498 *
1499 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1500 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
093ade12
AM
1501 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1502 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1d0e663c
AM
1503 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1504 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1505 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1506 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1507 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1508 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1509 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1510 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1511 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1512 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1513 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1514 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1515 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1516 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1517 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1518 * S16SDI XRa, Rb, s10, eptn2
1519 * S8LDD XRa, Rb, s8, eptn3
1520 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1521 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1522 * S8SDI XRa, Rb, s8, eptn3
1523 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1524 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1525 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1526 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1527 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1528 * S32CPS XRa, XRb, XRc
1529 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1530 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1531 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1532 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1533 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1534 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1535 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1536 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1537 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1538 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1539 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1540 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1541 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1542 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1543 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1544 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1545 * Q8SLT XRa, XRb, XRc
1546 * Q8SLTU XRa, XRb, XRc
1547 * Q8MOVZ XRa, XRb, XRc Shift instructions
1548 * Q8MOVN XRa, XRb, XRc ------------------
1549 *
1550 * D32SLL XRa, XRb, XRc, XRd, sft4
1551 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1552 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1553 * D32SARL XRa, XRb, XRc, sft4
1554 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1555 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1556 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1557 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1558 * Q16SLL XRa, XRb, XRc, XRd, sft4
1559 * Q16SLR XRa, XRb, XRc, XRd, sft4
eab0bdb0 1560 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1d0e663c
AM
1561 * ------------------------- Q16SLLV XRa, XRb, Rb
1562 * Q16SLRV XRa, XRb, Rb
1563 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1564 * S32ALN XRa, XRb, XRc, Rb
1565 * S32ALNI XRa, XRb, XRc, s3
1566 * S32LUI XRa, s8, optn3 Move instructions
1567 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1568 * S32EXTRV XRa, XRb, Rs, Rt
1569 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1570 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1571 *
9ef5bff9 1572 *
84e2c895
AM
1573 * The opcode organization of MXU instructions
1574 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1575 *
1576 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1577 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1578 * other bits up to the instruction level is as follows:
1579 *
9ef5bff9
AM
1580 * bits
1581 * 05..00
1582 *
1583 * ┌─ 000000 ─ OPC_MXU_S32MADD
1584 * ├─ 000001 ─ OPC_MXU_S32MADDU
eab0bdb0
AM
1585 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1586 * │
9ef5bff9
AM
1587 * │ 20..18
1588 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1589 * │ ├─ 001 ─ OPC_MXU_S32MIN
1590 * │ ├─ 010 ─ OPC_MXU_D16MAX
1591 * │ ├─ 011 ─ OPC_MXU_D16MIN
1592 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1593 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1594 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1595 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1596 * ├─ 000100 ─ OPC_MXU_S32MSUB
1597 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1598 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1599 * │ ├─ 001 ─ OPC_MXU_D16SLT
1600 * │ ├─ 010 ─ OPC_MXU_D16AVG
1601 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1602 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1603 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1604 * │ └─ 111 ─ OPC_MXU_Q8ADD
1605 * │
1606 * │ 20..18
1607 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1608 * │ ├─ 010 ─ OPC_MXU_D16CPS
1609 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1610 * │ └─ 110 ─ OPC_MXU_Q16SAT
1611 * ├─ 001000 ─ OPC_MXU_D16MUL
1612 * │ 25..24
1613 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1614 * │ └─ 01 ─ OPC_MXU_D16MULE
1615 * ├─ 001010 ─ OPC_MXU_D16MAC
1616 * ├─ 001011 ─ OPC_MXU_D16MACF
1617 * ├─ 001100 ─ OPC_MXU_D16MADL
eab0bdb0 1618 * ├─ 001101 ─ OPC_MXU_S16MAD
9ef5bff9 1619 * ├─ 001110 ─ OPC_MXU_Q16ADD
eab0bdb0
AM
1620 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1621 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1622 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
9ef5bff9
AM
1623 * │
1624 * │ 23
eab0bdb0 1625 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
9ef5bff9
AM
1626 * │ └─ 1 ─ OPC_MXU_S32STDR
1627 * │
1628 * │ 13..10
eab0bdb0 1629 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
9ef5bff9
AM
1630 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1631 * │
1632 * │ 13..10
eab0bdb0 1633 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
9ef5bff9
AM
1634 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1635 * │
1636 * │ 23
eab0bdb0 1637 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
9ef5bff9
AM
1638 * │ └─ 1 ─ OPC_MXU_S32LDIR
1639 * │
1640 * │ 23
eab0bdb0 1641 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
9ef5bff9
AM
1642 * │ └─ 1 ─ OPC_MXU_S32SDIR
1643 * │
1644 * │ 13..10
eab0bdb0 1645 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
9ef5bff9
AM
1646 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1647 * │
1648 * │ 13..10
eab0bdb0 1649 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
9ef5bff9
AM
1650 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1651 * ├─ 011000 ─ OPC_MXU_D32ADD
1652 * │ 23..22
eab0bdb0 1653 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
9ef5bff9
AM
1654 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1655 * │ └─ 10 ─ OPC_MXU_D32ASUM
1656 * ├─ 011010 ─ <not assigned>
1657 * │ 23..22
eab0bdb0 1658 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
9ef5bff9
AM
1659 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1660 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1661 * │
1662 * │ 23..22
eab0bdb0 1663 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
9ef5bff9
AM
1664 * │ ├─ 01 ─ OPC_MXU_D8SUM
1665 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1666 * ├─ 011110 ─ <not assigned>
1667 * ├─ 011111 ─ <not assigned>
eab0bdb0
AM
1668 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1669 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
9ef5bff9 1670 * ├─ 100010 ─ OPC_MXU_S8LDD
eab0bdb0
AM
1671 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1672 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1673 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
9ef5bff9 1674 * │ ├─ 00 ─ OPC_MXU_S32EXTR
eab0bdb0 1675 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
9ef5bff9
AM
1676 * │
1677 * │ 20..18
eab0bdb0 1678 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
9ef5bff9 1679 * │ ├─ 001 ─ OPC_MXU_S32ALN
c233bf07 1680 * │ ├─ 010 ─ OPC_MXU_S32ALNI
b621f018
AM
1681 * │ ├─ 011 ─ OPC_MXU_S32LUI
1682 * │ ├─ 100 ─ OPC_MXU_S32NOR
1683 * │ ├─ 101 ─ OPC_MXU_S32AND
1684 * │ ├─ 110 ─ OPC_MXU_S32OR
1685 * │ └─ 111 ─ OPC_MXU_S32XOR
c233bf07
AM
1686 * │
1687 * │ 7..5
1688 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1689 * │ ├─ 001 ─ OPC_MXU_LXH
1690 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1691 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1692 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1693 * ├─ 101100 ─ OPC_MXU_S16LDI
1694 * ├─ 101101 ─ OPC_MXU_S16SDI
9ef5bff9
AM
1695 * ├─ 101110 ─ OPC_MXU_S32M2I
1696 * ├─ 101111 ─ OPC_MXU_S32I2M
1697 * ├─ 110000 ─ OPC_MXU_D32SLL
eab0bdb0
AM
1698 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1699 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1700 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1701 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1702 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
9ef5bff9 1703 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
c233bf07 1704 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
eab0bdb0 1705 * │
9ef5bff9
AM
1706 * ├─ 110111 ─ OPC_MXU_Q16SAR
1707 * │ 23..22
c233bf07 1708 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
9ef5bff9
AM
1709 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1710 * │
1711 * │ 20..18
c233bf07 1712 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
9ef5bff9
AM
1713 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1714 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1715 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1716 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
84e2c895 1717 * │ └─ 101 ─ OPC_MXU_S32MOVN
9ef5bff9
AM
1718 * │
1719 * │ 23..22
c233bf07 1720 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
9ef5bff9
AM
1721 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1722 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1723 * ├─ 111100 ─ OPC_MXU_Q8MADL
1724 * ├─ 111101 ─ OPC_MXU_S32SFL
1725 * ├─ 111110 ─ OPC_MXU_Q8SAD
eab0bdb0 1726 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
9ef5bff9
AM
1727 *
1728 *
84e2c895 1729 * Compiled after:
b158d449
AM
1730 *
1731 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
84e2c895 1732 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
b158d449
AM
1733 */
1734
8bacd1ff
AM
1735enum {
1736 OPC_MXU_S32MADD = 0x00,
1737 OPC_MXU_S32MADDU = 0x01,
11d56f61 1738 OPC__MXU_MUL = 0x02,
8bacd1ff
AM
1739 OPC_MXU__POOL00 = 0x03,
1740 OPC_MXU_S32MSUB = 0x04,
1741 OPC_MXU_S32MSUBU = 0x05,
1742 OPC_MXU__POOL01 = 0x06,
1743 OPC_MXU__POOL02 = 0x07,
1744 OPC_MXU_D16MUL = 0x08,
1745 OPC_MXU__POOL03 = 0x09,
1746 OPC_MXU_D16MAC = 0x0A,
1747 OPC_MXU_D16MACF = 0x0B,
1748 OPC_MXU_D16MADL = 0x0C,
eab0bdb0 1749 OPC_MXU_S16MAD = 0x0D,
8bacd1ff
AM
1750 OPC_MXU_Q16ADD = 0x0E,
1751 OPC_MXU_D16MACE = 0x0F,
eab0bdb0
AM
1752 OPC_MXU__POOL04 = 0x10,
1753 OPC_MXU__POOL05 = 0x11,
1754 OPC_MXU__POOL06 = 0x12,
1755 OPC_MXU__POOL07 = 0x13,
1756 OPC_MXU__POOL08 = 0x14,
1757 OPC_MXU__POOL09 = 0x15,
1758 OPC_MXU__POOL10 = 0x16,
1759 OPC_MXU__POOL11 = 0x17,
8bacd1ff 1760 OPC_MXU_D32ADD = 0x18,
eab0bdb0 1761 OPC_MXU__POOL12 = 0x19,
8bacd1ff 1762 /* not assigned 0x1A */
eab0bdb0
AM
1763 OPC_MXU__POOL13 = 0x1B,
1764 OPC_MXU__POOL14 = 0x1C,
8bacd1ff
AM
1765 OPC_MXU_Q8ACCE = 0x1D,
1766 /* not assigned 0x1E */
1767 /* not assigned 0x1F */
1768 /* not assigned 0x20 */
1769 /* not assigned 0x21 */
1770 OPC_MXU_S8LDD = 0x22,
1771 OPC_MXU_S8STD = 0x23,
1772 OPC_MXU_S8LDI = 0x24,
1773 OPC_MXU_S8SDI = 0x25,
eab0bdb0
AM
1774 OPC_MXU__POOL15 = 0x26,
1775 OPC_MXU__POOL16 = 0x27,
c233bf07 1776 OPC_MXU__POOL17 = 0x28,
8bacd1ff
AM
1777 /* not assigned 0x29 */
1778 OPC_MXU_S16LDD = 0x2A,
1779 OPC_MXU_S16STD = 0x2B,
1780 OPC_MXU_S16LDI = 0x2C,
1781 OPC_MXU_S16SDI = 0x2D,
1782 OPC_MXU_S32M2I = 0x2E,
1783 OPC_MXU_S32I2M = 0x2F,
1784 OPC_MXU_D32SLL = 0x30,
1785 OPC_MXU_D32SLR = 0x31,
1786 OPC_MXU_D32SARL = 0x32,
1787 OPC_MXU_D32SAR = 0x33,
1788 OPC_MXU_Q16SLL = 0x34,
1789 OPC_MXU_Q16SLR = 0x35,
c233bf07 1790 OPC_MXU__POOL18 = 0x36,
8bacd1ff 1791 OPC_MXU_Q16SAR = 0x37,
c233bf07
AM
1792 OPC_MXU__POOL19 = 0x38,
1793 OPC_MXU__POOL20 = 0x39,
1794 OPC_MXU__POOL21 = 0x3A,
8bacd1ff
AM
1795 OPC_MXU_Q16SCOP = 0x3B,
1796 OPC_MXU_Q8MADL = 0x3C,
1797 OPC_MXU_S32SFL = 0x3D,
1798 OPC_MXU_Q8SAD = 0x3E,
1799 /* not assigned 0x3F */
1800};
1801
1802
1803/*
1804 * MXU pool 00
1805 */
1806enum {
1807 OPC_MXU_S32MAX = 0x00,
1808 OPC_MXU_S32MIN = 0x01,
1809 OPC_MXU_D16MAX = 0x02,
1810 OPC_MXU_D16MIN = 0x03,
1811 OPC_MXU_Q8MAX = 0x04,
1812 OPC_MXU_Q8MIN = 0x05,
1813 OPC_MXU_Q8SLT = 0x06,
1814 OPC_MXU_Q8SLTU = 0x07,
1815};
1816
1817/*
1818 * MXU pool 01
1819 */
1820enum {
1821 OPC_MXU_S32SLT = 0x00,
1822 OPC_MXU_D16SLT = 0x01,
1823 OPC_MXU_D16AVG = 0x02,
1824 OPC_MXU_D16AVGR = 0x03,
1825 OPC_MXU_Q8AVG = 0x04,
1826 OPC_MXU_Q8AVGR = 0x05,
1827 OPC_MXU_Q8ADD = 0x07,
1828};
1829
1830/*
1831 * MXU pool 02
1832 */
1833enum {
1834 OPC_MXU_S32CPS = 0x00,
1835 OPC_MXU_D16CPS = 0x02,
1836 OPC_MXU_Q8ABD = 0x04,
1837 OPC_MXU_Q16SAT = 0x06,
1838};
1839
1840/*
1841 * MXU pool 03
1842 */
1843enum {
1844 OPC_MXU_D16MULF = 0x00,
1845 OPC_MXU_D16MULE = 0x01,
1846};
1847
1848/*
1849 * MXU pool 04
1850 */
8bacd1ff
AM
1851enum {
1852 OPC_MXU_S32LDD = 0x00,
1853 OPC_MXU_S32LDDR = 0x01,
1854};
1855
1856/*
eab0bdb0 1857 * MXU pool 05
8bacd1ff
AM
1858 */
1859enum {
1860 OPC_MXU_S32STD = 0x00,
1861 OPC_MXU_S32STDR = 0x01,
1862};
1863
1864/*
eab0bdb0 1865 * MXU pool 06
8bacd1ff
AM
1866 */
1867enum {
1868 OPC_MXU_S32LDDV = 0x00,
1869 OPC_MXU_S32LDDVR = 0x01,
1870};
1871
1872/*
eab0bdb0 1873 * MXU pool 07
8bacd1ff
AM
1874 */
1875enum {
1876 OPC_MXU_S32STDV = 0x00,
1877 OPC_MXU_S32STDVR = 0x01,
1878};
1879
1880/*
eab0bdb0 1881 * MXU pool 08
8bacd1ff
AM
1882 */
1883enum {
1884 OPC_MXU_S32LDI = 0x00,
1885 OPC_MXU_S32LDIR = 0x01,
1886};
1887
1888/*
eab0bdb0 1889 * MXU pool 09
8bacd1ff
AM
1890 */
1891enum {
1892 OPC_MXU_S32SDI = 0x00,
1893 OPC_MXU_S32SDIR = 0x01,
1894};
1895
1896/*
eab0bdb0 1897 * MXU pool 10
8bacd1ff
AM
1898 */
1899enum {
1900 OPC_MXU_S32LDIV = 0x00,
1901 OPC_MXU_S32LDIVR = 0x01,
1902};
1903
1904/*
eab0bdb0 1905 * MXU pool 11
8bacd1ff
AM
1906 */
1907enum {
1908 OPC_MXU_S32SDIV = 0x00,
1909 OPC_MXU_S32SDIVR = 0x01,
1910};
1911
1912/*
eab0bdb0 1913 * MXU pool 12
8bacd1ff
AM
1914 */
1915enum {
1916 OPC_MXU_D32ACC = 0x00,
1917 OPC_MXU_D32ACCM = 0x01,
1918 OPC_MXU_D32ASUM = 0x02,
1919};
1920
1921/*
eab0bdb0 1922 * MXU pool 13
8bacd1ff
AM
1923 */
1924enum {
1925 OPC_MXU_Q16ACC = 0x00,
1926 OPC_MXU_Q16ACCM = 0x01,
1927 OPC_MXU_Q16ASUM = 0x02,
1928};
1929
1930/*
eab0bdb0 1931 * MXU pool 14
8bacd1ff
AM
1932 */
1933enum {
1934 OPC_MXU_Q8ADDE = 0x00,
1935 OPC_MXU_D8SUM = 0x01,
1936 OPC_MXU_D8SUMC = 0x02,
1937};
1938
1939/*
eab0bdb0 1940 * MXU pool 15
8bacd1ff
AM
1941 */
1942enum {
1943 OPC_MXU_S32MUL = 0x00,
1944 OPC_MXU_S32MULU = 0x01,
1945 OPC_MXU_S32EXTR = 0x02,
1946 OPC_MXU_S32EXTRV = 0x03,
1947};
1948
1949/*
eab0bdb0 1950 * MXU pool 16
8bacd1ff
AM
1951 */
1952enum {
1953 OPC_MXU_D32SARW = 0x00,
1954 OPC_MXU_S32ALN = 0x01,
1955 OPC_MXU_S32ALNI = 0x02,
b621f018
AM
1956 OPC_MXU_S32LUI = 0x03,
1957 OPC_MXU_S32NOR = 0x04,
1958 OPC_MXU_S32AND = 0x05,
1959 OPC_MXU_S32OR = 0x06,
1960 OPC_MXU_S32XOR = 0x07,
8bacd1ff
AM
1961};
1962
1963/*
eab0bdb0 1964 * MXU pool 17
8bacd1ff 1965 */
c233bf07
AM
1966enum {
1967 OPC_MXU_LXB = 0x00,
1968 OPC_MXU_LXH = 0x01,
1969 OPC_MXU_LXW = 0x03,
1970 OPC_MXU_LXBU = 0x04,
1971 OPC_MXU_LXHU = 0x05,
1972};
1973
1974/*
1975 * MXU pool 18
1976 */
8bacd1ff
AM
1977enum {
1978 OPC_MXU_D32SLLV = 0x00,
1979 OPC_MXU_D32SLRV = 0x01,
1980 OPC_MXU_D32SARV = 0x03,
1981 OPC_MXU_Q16SLLV = 0x04,
1982 OPC_MXU_Q16SLRV = 0x05,
1983 OPC_MXU_Q16SARV = 0x07,
1984};
1985
1986/*
c233bf07 1987 * MXU pool 19
8bacd1ff
AM
1988 */
1989enum {
1990 OPC_MXU_Q8MUL = 0x00,
1991 OPC_MXU_Q8MULSU = 0x01,
1992};
1993
1994/*
c233bf07 1995 * MXU pool 20
8bacd1ff
AM
1996 */
1997enum {
1998 OPC_MXU_Q8MOVZ = 0x00,
1999 OPC_MXU_Q8MOVN = 0x01,
2000 OPC_MXU_D16MOVZ = 0x02,
2001 OPC_MXU_D16MOVN = 0x03,
2002 OPC_MXU_S32MOVZ = 0x04,
2003 OPC_MXU_S32MOVN = 0x05,
2004};
2005
2006/*
c233bf07 2007 * MXU pool 21
8bacd1ff
AM
2008 */
2009enum {
2010 OPC_MXU_Q8MAC = 0x00,
2011 OPC_MXU_Q8MACSU = 0x01,
2012};
2013
497f072b
FN
2014/*
2015 * Overview of the TX79-specific instruction set
2016 * =============================================
2017 *
2018 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2019 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2020 * instructions and certain multimedia instructions (MMIs). These MMIs
2021 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2022 * or sixteen 8-bit paths.
2023 *
2024 * Reference:
2025 *
2026 * The Toshiba TX System RISC TX79 Core Architecture manual,
2027 * https://wiki.qemu.org/File:C790.pdf
2028 *
2029 * Three-Operand Multiply and Multiply-Add (4 instructions)
2030 * --------------------------------------------------------
2031 * MADD [rd,] rs, rt Multiply/Add
2032 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2033 * MULT [rd,] rs, rt Multiply (3-operand)
2034 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2035 *
2036 * Multiply Instructions for Pipeline 1 (10 instructions)
2037 * ------------------------------------------------------
2038 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2039 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2040 * DIV1 rs, rt Divide Pipeline 1
2041 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2042 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2043 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2044 * MFHI1 rd Move From HI1 Register
2045 * MFLO1 rd Move From LO1 Register
2046 * MTHI1 rs Move To HI1 Register
2047 * MTLO1 rs Move To LO1 Register
2048 *
2049 * Arithmetic (19 instructions)
2050 * ----------------------------
2051 * PADDB rd, rs, rt Parallel Add Byte
2052 * PSUBB rd, rs, rt Parallel Subtract Byte
2053 * PADDH rd, rs, rt Parallel Add Halfword
2054 * PSUBH rd, rs, rt Parallel Subtract Halfword
2055 * PADDW rd, rs, rt Parallel Add Word
2056 * PSUBW rd, rs, rt Parallel Subtract Word
2057 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2058 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2059 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2060 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2061 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2062 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2063 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2064 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2065 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2066 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2067 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2068 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2069 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2070 *
2071 * Min/Max (4 instructions)
2072 * ------------------------
2073 * PMAXH rd, rs, rt Parallel Maximum Halfword
2074 * PMINH rd, rs, rt Parallel Minimum Halfword
2075 * PMAXW rd, rs, rt Parallel Maximum Word
2076 * PMINW rd, rs, rt Parallel Minimum Word
2077 *
2078 * Absolute (2 instructions)
2079 * -------------------------
2080 * PABSH rd, rt Parallel Absolute Halfword
2081 * PABSW rd, rt Parallel Absolute Word
2082 *
2083 * Logical (4 instructions)
2084 * ------------------------
2085 * PAND rd, rs, rt Parallel AND
2086 * POR rd, rs, rt Parallel OR
2087 * PXOR rd, rs, rt Parallel XOR
2088 * PNOR rd, rs, rt Parallel NOR
2089 *
2090 * Shift (9 instructions)
2091 * ----------------------
2092 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2093 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2094 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2095 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2096 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2097 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2098 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2099 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2100 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2101 *
2102 * Compare (6 instructions)
2103 * ------------------------
2104 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2105 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2106 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2107 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2108 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2109 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2110 *
2111 * LZC (1 instruction)
2112 * -------------------
2113 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2114 *
2115 * Quadword Load and Store (2 instructions)
2116 * ----------------------------------------
2117 * LQ rt, offset(base) Load Quadword
2118 * SQ rt, offset(base) Store Quadword
2119 *
2120 * Multiply and Divide (19 instructions)
2121 * -------------------------------------
2122 * PMULTW rd, rs, rt Parallel Multiply Word
2123 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2124 * PDIVW rs, rt Parallel Divide Word
2125 * PDIVUW rs, rt Parallel Divide Unsigned Word
2126 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2127 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2128 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2129 * PMULTH rd, rs, rt Parallel Multiply Halfword
2130 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2131 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2132 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2133 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2134 * PDIVBW rs, rt Parallel Divide Broadcast Word
2135 * PMFHI rd Parallel Move From HI Register
2136 * PMFLO rd Parallel Move From LO Register
2137 * PMTHI rs Parallel Move To HI Register
2138 * PMTLO rs Parallel Move To LO Register
2139 * PMFHL rd Parallel Move From HI/LO Register
2140 * PMTHL rs Parallel Move To HI/LO Register
2141 *
2142 * Pack/Extend (11 instructions)
2143 * -----------------------------
2144 * PPAC5 rd, rt Parallel Pack to 5 bits
2145 * PPACB rd, rs, rt Parallel Pack to Byte
2146 * PPACH rd, rs, rt Parallel Pack to Halfword
2147 * PPACW rd, rs, rt Parallel Pack to Word
2148 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2149 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2150 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2151 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2152 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2153 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2154 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2155 *
2156 * Others (16 instructions)
2157 * ------------------------
2158 * PCPYH rd, rt Parallel Copy Halfword
2159 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2160 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2161 * PREVH rd, rt Parallel Reverse Halfword
2162 * PINTH rd, rs, rt Parallel Interleave Halfword
2163 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2164 * PEXEH rd, rt Parallel Exchange Even Halfword
2165 * PEXCH rd, rt Parallel Exchange Center Halfword
2166 * PEXEW rd, rt Parallel Exchange Even Word
2167 * PEXCW rd, rt Parallel Exchange Center Word
2168 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2169 * MFSA rd Move from Shift Amount Register
2170 * MTSA rs Move to Shift Amount Register
2171 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2172 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2173 * PROT3W rd, rt Parallel Rotate 3 Words
f99c0d6d 2174 *
baa609db
AM
2175 * MMI (MultiMedia Instruction) encodings
2176 * ======================================
f99c0d6d 2177 *
baa609db 2178 * MMI instructions encoding table keys:
f99c0d6d
FN
2179 *
2180 * * This code is reserved for future use. An attempt to execute it
2181 * causes a Reserved Instruction exception.
2182 * % This code indicates an instruction class. The instruction word
2183 * must be further decoded by examining additional tables that show
2184 * the values for other instruction fields.
2185 * # This code is reserved for the unsupported instructions DMULT,
2186 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2187 * to execute it causes a Reserved Instruction exception.
2188 *
baa609db 2189 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
f99c0d6d
FN
2190 *
2191 * 31 26 0
2192 * +--------+----------------------------------------+
2193 * | opcode | |
2194 * +--------+----------------------------------------+
2195 *
2196 * opcode bits 28..26
2197 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2198 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2199 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2200 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2201 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2202 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2203 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2204 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2205 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2206 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2207 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 2208 */
b158d449 2209
f99c0d6d 2210enum {
baa609db
AM
2211 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2212 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2213 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
f99c0d6d
FN
2214};
2215
d3297211 2216/*
baa609db 2217 * MMI instructions with opcode field = MMI:
d3297211
FN
2218 *
2219 * 31 26 5 0
2220 * +--------+-------------------------------+--------+
2221 * | MMI | |function|
2222 * +--------+-------------------------------+--------+
2223 *
2224 * function bits 2..0
2225 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2226 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2227 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2228 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2229 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2230 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2231 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2232 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2233 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2234 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2235 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2236 */
2237
c8341e00 2238#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
d3297211 2239enum {
baa609db
AM
2240 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2241 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2242 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2243 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2244 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2245 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2246 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2247 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2248 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2249 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2250 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2251 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2252 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2253 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2254 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2255 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2256 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2257 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2258 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2259 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2260 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2261 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2262 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2263 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2264 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
d3297211
FN
2265};
2266
3ef65697 2267/*
baa609db 2268 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
3ef65697
FN
2269 *
2270 * 31 26 10 6 5 0
2271 * +--------+----------------------+--------+--------+
2272 * | MMI | |function| MMI0 |
2273 * +--------+----------------------+--------+--------+
2274 *
2275 * function bits 7..6
2276 * bits | 0 | 1 | 2 | 3
2277 * 10..8 | 00 | 01 | 10 | 11
2278 * -------+-------+-------+-------+-------
2279 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2280 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2281 * 2 010 | PADDB | PSUBB | PCGTB | *
2282 * 3 011 | * | * | * | *
2283 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2284 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2285 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2286 * 7 111 | * | * | PEXT5 | PPAC5
2287 */
2288
c8341e00 2289#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
3ef65697 2290enum {
baa609db
AM
2291 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2292 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2293 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2294 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2302 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2303 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2304 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2305 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2306 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2307 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2308 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2309 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2310 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2311 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2312 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2313 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2314 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2315 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
3ef65697
FN
2316};
2317
77596541 2318/*
baa609db 2319 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
77596541
FN
2320 *
2321 * 31 26 10 6 5 0
2322 * +--------+----------------------+--------+--------+
2323 * | MMI | |function| MMI1 |
2324 * +--------+----------------------+--------+--------+
2325 *
2326 * function bits 7..6
2327 * bits | 0 | 1 | 2 | 3
2328 * 10..8 | 00 | 01 | 10 | 11
2329 * -------+-------+-------+-------+-------
2330 * 0 000 | * | PABSW | PCEQW | PMINW
2331 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2332 * 2 010 | * | * | PCEQB | *
2333 * 3 011 | * | * | * | *
2334 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2335 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2336 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2337 * 7 111 | * | * | * | *
2338 */
2339
c8341e00 2340#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
77596541 2341enum {
baa609db
AM
2342 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2343 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2344 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2345 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2346 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2347 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2348 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2349 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2350 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2351 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2352 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2353 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2354 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2355 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2356 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2357 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2358 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2359 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
77596541
FN
2360};
2361
6c03ef6a 2362/*
baa609db 2363 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
6c03ef6a
FN
2364 *
2365 * 31 26 10 6 5 0
2366 * +--------+----------------------+--------+--------+
2367 * | MMI | |function| MMI2 |
2368 * +--------+----------------------+--------+--------+
2369 *
2370 * function bits 7..6
2371 * bits | 0 | 1 | 2 | 3
2372 * 10..8 | 00 | 01 | 10 | 11
2373 * -------+-------+-------+-------+-------
2374 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2375 * 1 001 | PMSUBW| * | * | *
2376 * 2 010 | PMFHI | PMFLO | PINTH | *
2377 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2378 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2379 * 5 101 | PMSUBH| PHMSBH| * | *
2380 * 6 110 | * | * | PEXEH | PREVH
2381 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2382 */
2383
c8341e00 2384#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
6c03ef6a 2385enum {
baa609db
AM
2386 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2387 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2388 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2389 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2394 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2395 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2396 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2397 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2398 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2399 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2400 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2401 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2402 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2403 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2404 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2405 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2406 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2407 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
6c03ef6a
FN
2408};
2409
dd581bf9 2410/*
baa609db 2411 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
dd581bf9
FN
2412 *
2413 * 31 26 10 6 5 0
2414 * +--------+----------------------+--------+--------+
2415 * | MMI | |function| MMI3 |
2416 * +--------+----------------------+--------+--------+
2417 *
2418 * function bits 7..6
2419 * bits | 0 | 1 | 2 | 3
2420 * 10..8 | 00 | 01 | 10 | 11
2421 * -------+-------+-------+-------+-------
2422 * 0 000 |PMADDUW| * | * | PSRAVW
2423 * 1 001 | * | * | * | *
2424 * 2 010 | PMTHI | PMTLO | PINTEH| *
2425 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2426 * 4 100 | * | * | POR | PNOR
2427 * 5 101 | * | * | * | *
2428 * 6 110 | * | * | PEXCH | PCPYH
2429 * 7 111 | * | * | PEXCW | *
2430 */
2431
c8341e00 2432#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
dd581bf9 2433enum {
baa609db
AM
2434 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2435 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2436 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2437 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2438 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2439 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2440 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2441 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2442 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2443 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2444 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2445 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2446 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
dd581bf9
FN
2447};
2448
39454628 2449/* global register indices */
a7812ae4 2450static TCGv cpu_gpr[32], cpu_PC;
340fff72 2451static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
2452static TCGv cpu_dspctrl, btarget, bcond;
2453static TCGv_i32 hflags;
a7812ae4 2454static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 2455static TCGv_i64 fpu_f64[32];
863f264d 2456static TCGv_i64 msa_wr_d[64];
aa0bf00b 2457
b621f018 2458#if !defined(TARGET_MIPS64)
eb5559f6
CJ
2459/* MXU registers */
2460static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2461static TCGv mxu_CR;
b621f018 2462#endif
eb5559f6 2463
022c62cb 2464#include "exec/gen-icount.h"
2e70f6ef 2465
895c2d04 2466#define gen_helper_0e0i(name, arg) do { \
a7812ae4 2467 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 2468 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
2469 tcg_temp_free_i32(helper_tmp); \
2470 } while(0)
be24bb4f 2471
895c2d04 2472#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 2473 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 2474 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
2475 tcg_temp_free_i32(helper_tmp); \
2476 } while(0)
be24bb4f 2477
895c2d04
BS
2478#define gen_helper_1e0i(name, ret, arg1) do { \
2479 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2480 gen_helper_##name(ret, cpu_env, helper_tmp); \
2481 tcg_temp_free_i32(helper_tmp); \
2482 } while(0)
2483
2484#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2485 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2486 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2487 tcg_temp_free_i32(helper_tmp); \
2488 } while(0)
2489
2490#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2491 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2492 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2493 tcg_temp_free_i32(helper_tmp); \
2494 } while(0)
2495
2496#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 2497 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 2498 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
2499 tcg_temp_free_i32(helper_tmp); \
2500 } while(0)
be24bb4f 2501
895c2d04 2502#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 2503 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 2504 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
2505 tcg_temp_free_i32(helper_tmp); \
2506 } while(0)
c239529e 2507
8e9ade68 2508typedef struct DisasContext {
eeb3bba8
EC
2509 DisasContextBase base;
2510 target_ulong saved_pc;
18f440ed 2511 target_ulong page_start;
8e9ade68 2512 uint32_t opcode;
f9c9cd63 2513 uint64_t insn_flags;
5ab5c041 2514 int32_t CP0_Config1;
49735f76 2515 int32_t CP0_Config2;
ab77fc61
DN
2516 int32_t CP0_Config3;
2517 int32_t CP0_Config5;
8e9ade68
TS
2518 /* Routine used to access memory */
2519 int mem_idx;
be3a8c53 2520 TCGMemOp default_tcg_memop_mask;
8e9ade68 2521 uint32_t hflags, saved_hflags;
8e9ade68 2522 target_ulong btarget;
d279279e 2523 bool ulri;
e98c0d17 2524 int kscrexist;
7207c7f9 2525 bool rxi;
9456c2fb 2526 int ie;
aea14095
LA
2527 bool bi;
2528 bool bp;
5204ea79
LA
2529 uint64_t PAMask;
2530 bool mvh;
76964147 2531 bool eva;
cec56a73 2532 bool sc;
5204ea79 2533 int CP0_LLAddr_shift;
e29c9628 2534 bool ps;
01bc435b 2535 bool vp;
c870e3f5 2536 bool cmgcr;
f6d4dd81 2537 bool mrp;
87552089 2538 bool nan2008;
6be77480 2539 bool abs2008;
8e9ade68
TS
2540} DisasContext;
2541
b28425ba
EC
2542#define DISAS_STOP DISAS_TARGET_0
2543#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2544
d73ee8a2
RH
2545static const char * const regnames[] = {
2546 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2547 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2548 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2549 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2550};
6af0bf9c 2551
d73ee8a2
RH
2552static const char * const regnames_HI[] = {
2553 "HI0", "HI1", "HI2", "HI3",
2554};
4b2eb8d2 2555
d73ee8a2
RH
2556static const char * const regnames_LO[] = {
2557 "LO0", "LO1", "LO2", "LO3",
2558};
4b2eb8d2 2559
d73ee8a2
RH
2560static const char * const fregnames[] = {
2561 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2562 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2563 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2564 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2565};
958fb4a9 2566
863f264d
YK
2567static const char * const msaregnames[] = {
2568 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2569 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2570 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2571 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2572 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2573 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2574 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2575 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2576 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2577 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2578 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2579 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2580 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2581 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2582 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2583 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2584};
2585
b621f018 2586#if !defined(TARGET_MIPS64)
eb5559f6
CJ
2587static const char * const mxuregnames[] = {
2588 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2589 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2590};
b621f018 2591#endif
eb5559f6 2592
9d68ac14 2593#define LOG_DISAS(...) \
fb7729e2
RH
2594 do { \
2595 if (MIPS_DEBUG_DISAS) { \
9d68ac14 2596 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
2597 } \
2598 } while (0)
2599
9d68ac14 2600#define MIPS_INVAL(op) \
fb7729e2
RH
2601 do { \
2602 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
2603 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2604 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
2605 ctx->base.pc_next, ctx->opcode, op, \
2606 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2607 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
2608 } \
2609 } while (0)
958fb4a9 2610
8e9ade68
TS
2611/* General purpose registers moves. */
2612static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 2613{
8e9ade68
TS
2614 if (reg == 0)
2615 tcg_gen_movi_tl(t, 0);
2616 else
4b2eb8d2 2617 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
2618}
2619
8e9ade68 2620static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 2621{
8e9ade68 2622 if (reg != 0)
4b2eb8d2 2623 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
2624}
2625
8e9ade68 2626/* Moves to/from shadow registers. */
be24bb4f 2627static inline void gen_load_srsgpr (int from, int to)
aaa9128a 2628{
d9bea114 2629 TCGv t0 = tcg_temp_new();
be24bb4f
TS
2630
2631 if (from == 0)
d9bea114 2632 tcg_gen_movi_tl(t0, 0);
8e9ade68 2633 else {
d9bea114 2634 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2635 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2636
7db13fae 2637 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2638 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2639 tcg_gen_andi_i32(t2, t2, 0xf);
2640 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2641 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2642 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2643
d9bea114 2644 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2645 tcg_temp_free_ptr(addr);
d9bea114 2646 tcg_temp_free_i32(t2);
8e9ade68 2647 }
d9bea114
AJ
2648 gen_store_gpr(t0, to);
2649 tcg_temp_free(t0);
aaa9128a
TS
2650}
2651
be24bb4f 2652static inline void gen_store_srsgpr (int from, int to)
aaa9128a 2653{
be24bb4f 2654 if (to != 0) {
d9bea114
AJ
2655 TCGv t0 = tcg_temp_new();
2656 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2657 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2658
d9bea114 2659 gen_load_gpr(t0, from);
7db13fae 2660 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2661 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2662 tcg_gen_andi_i32(t2, t2, 0xf);
2663 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2664 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2665 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2666
d9bea114 2667 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2668 tcg_temp_free_ptr(addr);
d9bea114
AJ
2669 tcg_temp_free_i32(t2);
2670 tcg_temp_free(t0);
8e9ade68 2671 }
aaa9128a
TS
2672}
2673
b621f018 2674#if !defined(TARGET_MIPS64)
96992d1a
CJ
2675/* MXU General purpose registers moves. */
2676static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2677{
2678 if (reg == 0) {
2679 tcg_gen_movi_tl(t, 0);
2680 } else if (reg <= 15) {
2681 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2682 }
2683}
2684
2685static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2686{
2687 if (reg > 0 && reg <= 15) {
2688 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2689 }
2690}
2691
2692/* MXU control register moves. */
2693static inline void gen_load_mxu_cr(TCGv t)
2694{
2695 tcg_gen_mov_tl(t, mxu_CR);
2696}
2697
2698static inline void gen_store_mxu_cr(TCGv t)
2699{
2700 /* TODO: Add handling of RW rules for MXU_CR. */
2701 tcg_gen_mov_tl(mxu_CR, t);
2702}
b621f018 2703#endif
96992d1a
CJ
2704
2705
eab9944c
LA
2706/* Tests */
2707static inline void gen_save_pc(target_ulong pc)
2708{
2709 tcg_gen_movi_tl(cpu_PC, pc);
2710}
2711
2712static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2713{
2714 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2715 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2716 gen_save_pc(ctx->base.pc_next);
2717 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2718 }
2719 if (ctx->hflags != ctx->saved_hflags) {
2720 tcg_gen_movi_i32(hflags, ctx->hflags);
2721 ctx->saved_hflags = ctx->hflags;
2722 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2723 case MIPS_HFLAG_BR:
2724 break;
2725 case MIPS_HFLAG_BC:
2726 case MIPS_HFLAG_BL:
2727 case MIPS_HFLAG_B:
2728 tcg_gen_movi_tl(btarget, ctx->btarget);
2729 break;
2730 }
2731 }
2732}
2733
2734static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2735{
2736 ctx->saved_hflags = ctx->hflags;
2737 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2738 case MIPS_HFLAG_BR:
2739 break;
2740 case MIPS_HFLAG_BC:
2741 case MIPS_HFLAG_BL:
2742 case MIPS_HFLAG_B:
2743 ctx->btarget = env->btarget;
2744 break;
2745 }
2746}
2747
2748static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2749{
2750 TCGv_i32 texcp = tcg_const_i32(excp);
2751 TCGv_i32 terr = tcg_const_i32(err);
2752 save_cpu_state(ctx, 1);
2753 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2754 tcg_temp_free_i32(terr);
2755 tcg_temp_free_i32(texcp);
eeb3bba8 2756 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2757}
2758
2759static inline void generate_exception(DisasContext *ctx, int excp)
2760{
eab9944c
LA
2761 gen_helper_0e0i(raise_exception, excp);
2762}
2763
9c708c7f
PD
2764static inline void generate_exception_end(DisasContext *ctx, int excp)
2765{
2766 generate_exception_err(ctx, excp, 0);
2767}
2768
aaa9128a 2769/* Floating point register moves. */
7c979afd 2770static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2771{
7c979afd
LA
2772 if (ctx->hflags & MIPS_HFLAG_FRE) {
2773 generate_exception(ctx, EXCP_RI);
2774 }
ecc7b3aa 2775 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2776}
2777
7c979afd 2778static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2779{
7c979afd
LA
2780 TCGv_i64 t64;
2781 if (ctx->hflags & MIPS_HFLAG_FRE) {
2782 generate_exception(ctx, EXCP_RI);
2783 }
2784 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2785 tcg_gen_extu_i32_i64(t64, t);
2786 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2787 tcg_temp_free_i64(t64);
6d066274
AJ
2788}
2789
7f6613ce 2790static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2791{
7f6613ce 2792 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2793 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2794 } else {
7c979afd 2795 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2796 }
6d066274
AJ
2797}
2798
7f6613ce 2799static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2800{
7f6613ce
PJ
2801 if (ctx->hflags & MIPS_HFLAG_F64) {
2802 TCGv_i64 t64 = tcg_temp_new_i64();
2803 tcg_gen_extu_i32_i64(t64, t);
2804 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2805 tcg_temp_free_i64(t64);
2806 } else {
7c979afd 2807 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2808 }
aa0bf00b 2809}
6ea83fed 2810
d73ee8a2 2811static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2812{
f364515c 2813 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2814 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2815 } else {
d73ee8a2 2816 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2817 }
2818}
6ea83fed 2819
d73ee8a2 2820static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2821{
f364515c 2822 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2823 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2824 } else {
d73ee8a2
RH
2825 TCGv_i64 t0;
2826 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2827 t0 = tcg_temp_new_i64();
6d066274 2828 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2829 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2830 tcg_temp_free_i64(t0);
aa0bf00b
TS
2831 }
2832}
6ea83fed 2833
d94536f4 2834static inline int get_fp_bit (int cc)
a16336e4 2835{
d94536f4
AJ
2836 if (cc)
2837 return 24 + cc;
2838 else
2839 return 23;
a16336e4
TS
2840}
2841
48d38ca5 2842/* Addresses computation */
941694d0 2843static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2844{
941694d0 2845 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2846
2847#if defined(TARGET_MIPS64)
01f72885 2848 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2849 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2850 }
2851#endif
4ad40f36
FB
2852}
2853
bf0718c5
SM
2854static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2855 target_long ofs)
2856{
2857 tcg_gen_addi_tl(ret, base, ofs);
2858
2859#if defined(TARGET_MIPS64)
2860 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2861 tcg_gen_ext32s_i64(ret, ret);
2862 }
2863#endif
2864}
2865
31837be3
YK
2866/* Addresses computation (translation time) */
2867static target_long addr_add(DisasContext *ctx, target_long base,
2868 target_long offset)
2869{
2870 target_long sum = base + offset;
2871
2872#if defined(TARGET_MIPS64)
2873 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2874 sum = (int32_t)sum;
2875 }
2876#endif
2877 return sum;
2878}
2879
71f303cd 2880/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
2881static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2882{
2883#if defined(TARGET_MIPS64)
71f303cd
RH
2884 tcg_gen_ext32s_i64(ret, arg);
2885#else
2886 tcg_gen_extrl_i64_i32(ret, arg);
2887#endif
2888}
2889
2890/* Sign-extract the high 32-bits to a target_long. */
2891static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2892{
2893#if defined(TARGET_MIPS64)
2894 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2895#else
71f303cd 2896 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2897#endif
2898}
2899
356265ae 2900static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2901{
fe253235 2902 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 2903 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
2904}
2905
356265ae 2906static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 2907{
fe253235 2908 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
2909 generate_exception_err(ctx, EXCP_CpU, 1);
2910}
2911
b8aa4598
TS
2912/* Verify that the processor is running with COP1X instructions enabled.
2913 This is associated with the nabla symbol in the MIPS32 and MIPS64
2914 opcode tables. */
2915
356265ae 2916static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
2917{
2918 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 2919 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
2920}
2921
2922/* Verify that the processor is running with 64-bit floating-point
2923 operations enabled. */
2924
356265ae 2925static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2926{
b8aa4598 2927 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 2928 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2929}
2930
2931/*
2932 * Verify if floating point register is valid; an operation is not defined
2933 * if bit 0 of any register specification is set and the FR bit in the
2934 * Status register equals zero, since the register numbers specify an
2935 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2936 * in the Status register equals one, both even and odd register numbers
2937 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2938 *
2939 * Multiple 64 bit wide registers can be checked by calling
2940 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2941 */
356265ae 2942static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2943{
fe253235 2944 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 2945 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2946}
2947
853c3240
JL
2948/* Verify that the processor is running with DSP instructions enabled.
2949 This is enabled by CP0 Status register MX(24) bit.
2950 */
2951
2952static inline void check_dsp(DisasContext *ctx)
2953{
2954 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2955 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2956 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2957 } else {
9c708c7f 2958 generate_exception_end(ctx, EXCP_RI);
ad153f15 2959 }
853c3240
JL
2960 }
2961}
2962
908f6be1 2963static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2964{
908f6be1 2965 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2966 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2967 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2968 } else {
9c708c7f 2969 generate_exception_end(ctx, EXCP_RI);
ad153f15 2970 }
853c3240
JL
2971 }
2972}
2973
908f6be1 2974static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2975{
908f6be1 2976 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2977 if (ctx->insn_flags & ASE_DSP) {
2978 generate_exception_end(ctx, EXCP_DSPDIS);
2979 } else {
2980 generate_exception_end(ctx, EXCP_RI);
2981 }
2982 }
2983}
2984
3a95e3a7 2985/* This code generates a "reserved instruction" exception if the
e189e748 2986 CPU does not support the instruction set corresponding to flags. */
f9c9cd63 2987static inline void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2988{
d75c135e 2989 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 2990 generate_exception_end(ctx, EXCP_RI);
d75c135e 2991 }
3a95e3a7
TS
2992}
2993
fecd2646
LA
2994/* This code generates a "reserved instruction" exception if the
2995 CPU has corresponding flag set which indicates that the instruction
2996 has been removed. */
f9c9cd63 2997static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2998{
2999 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 3000 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
3001 }
3002}
3003
96631327
FN
3004/*
3005 * The Linux kernel traps certain reserved instruction exceptions to
3006 * emulate the corresponding instructions. QEMU is the kernel in user
3007 * mode, so those traps are emulated by accepting the instructions.
3008 *
3009 * A reserved instruction exception is generated for flagged CPUs if
3010 * QEMU runs in system mode.
3011 */
3012static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3013{
3014#ifndef CONFIG_USER_ONLY
3015 check_insn_opc_removed(ctx, flags);
3016#endif
3017}
3018
e29c9628
YK
3019/* This code generates a "reserved instruction" exception if the
3020 CPU does not support 64-bit paired-single (PS) floating point data type */
3021static inline void check_ps(DisasContext *ctx)
3022{
3023 if (unlikely(!ctx->ps)) {
3024 generate_exception(ctx, EXCP_RI);
3025 }
3026 check_cp1_64bitmode(ctx);
3027}
3028
c7986fd6 3029#ifdef TARGET_MIPS64
e189e748
TS
3030/* This code generates a "reserved instruction" exception if 64-bit
3031 instructions are not enabled. */
356265ae 3032static inline void check_mips_64(DisasContext *ctx)
e189e748 3033{
fe253235 3034 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 3035 generate_exception_end(ctx, EXCP_RI);
e189e748 3036}
c7986fd6 3037#endif
e189e748 3038
5204ea79
LA
3039#ifndef CONFIG_USER_ONLY
3040static inline void check_mvh(DisasContext *ctx)
3041{
3042 if (unlikely(!ctx->mvh)) {
3043 generate_exception(ctx, EXCP_RI);
3044 }
3045}
3046#endif
3047
0b16dcd1
AR
3048/*
3049 * This code generates a "reserved instruction" exception if the
3050 * Config5 XNP bit is set.
3051 */
3052static inline void check_xnp(DisasContext *ctx)
3053{
3054 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3055 generate_exception_end(ctx, EXCP_RI);
3056 }
3057}
3058
5e31fdd5
YK
3059#ifndef CONFIG_USER_ONLY
3060/*
3061 * This code generates a "reserved instruction" exception if the
3062 * Config3 PW bit is NOT set.
3063 */
3064static inline void check_pw(DisasContext *ctx)
3065{
3066 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3067 generate_exception_end(ctx, EXCP_RI);
3068 }
3069}
3070#endif
3071
9affc1c5
AR
3072/*
3073 * This code generates a "reserved instruction" exception if the
3074 * Config3 MT bit is NOT set.
3075 */
3076static inline void check_mt(DisasContext *ctx)
3077{
3078 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3079 generate_exception_end(ctx, EXCP_RI);
3080 }
3081}
3082
3083#ifndef CONFIG_USER_ONLY
3084/*
3085 * This code generates a "coprocessor unusable" exception if CP0 is not
3086 * available, and, if that is not the case, generates a "reserved instruction"
3087 * exception if the Config5 MT bit is NOT set. This is needed for availability
3088 * control of some of MT ASE instructions.
3089 */
3090static inline void check_cp0_mt(DisasContext *ctx)
3091{
3092 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3093 generate_exception_err(ctx, EXCP_CpU, 0);
3094 } else {
3095 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3096 generate_exception_err(ctx, EXCP_RI, 0);
3097 }
3098 }
3099}
3100#endif
3101
fb32f8c8
DN
3102/*
3103 * This code generates a "reserved instruction" exception if the
3104 * Config5 NMS bit is set.
3105 */
3106static inline void check_nms(DisasContext *ctx)
3107{
3108 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3109 generate_exception_end(ctx, EXCP_RI);
3110 }
3111}
3112
d046a9ea
DN
3113/*
3114 * This code generates a "reserved instruction" exception if the
3115 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3116 * Config2 TL, and Config5 L2C are unset.
3117 */
3118static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3119{
3120 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3121 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3122 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3123 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3124 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3125 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3126 {
3127 generate_exception_end(ctx, EXCP_RI);
3128 }
3129}
3130
3131/*
3132 * This code generates a "reserved instruction" exception if the
3133 * Config5 EVA bit is NOT set.
3134 */
3135static inline void check_eva(DisasContext *ctx)
3136{
3137 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3138 generate_exception_end(ctx, EXCP_RI);
3139 }
3140}
3141
0b16dcd1 3142
8153667c
NF
3143/* Define small wrappers for gen_load_fpr* so that we have a uniform
3144 calling interface for 32 and 64-bit FPRs. No sense in changing
3145 all callers for gen_load_fpr32 when we need the CTX parameter for
3146 this one use. */
7c979afd 3147#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
3148#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3149#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3150static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3151 int ft, int fs, int cc) \
3152{ \
3153 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3154 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3155 switch (ifmt) { \
3156 case FMT_PS: \
e29c9628 3157 check_ps(ctx); \
8153667c
NF
3158 break; \
3159 case FMT_D: \
3160 if (abs) { \
3161 check_cop1x(ctx); \
3162 } \
3163 check_cp1_registers(ctx, fs | ft); \
3164 break; \
3165 case FMT_S: \
3166 if (abs) { \
3167 check_cop1x(ctx); \
3168 } \
3169 break; \
3170 } \
3171 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3172 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3173 switch (n) { \
895c2d04
BS
3174 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3175 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3176 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3177 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3178 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3179 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3180 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3181 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3182 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3183 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3184 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3185 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3186 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3187 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3188 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3189 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
3190 default: abort(); \
3191 } \
3192 tcg_temp_free_i##bits (fp0); \
3193 tcg_temp_free_i##bits (fp1); \
3194}
3195
3196FOP_CONDS(, 0, d, FMT_D, 64)
3197FOP_CONDS(abs, 1, d, FMT_D, 64)
3198FOP_CONDS(, 0, s, FMT_S, 32)
3199FOP_CONDS(abs, 1, s, FMT_S, 32)
3200FOP_CONDS(, 0, ps, FMT_PS, 64)
3201FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3202#undef FOP_CONDS
3f493883
YK
3203
3204#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3205static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3206 int ft, int fs, int fd) \
3207{ \
3208 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3209 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 3210 if (ifmt == FMT_D) { \
3f493883 3211 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
3212 } \
3213 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3214 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3215 switch (n) { \
3216 case 0: \
3217 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3218 break; \
3219 case 1: \
3220 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3221 break; \
3222 case 2: \
3223 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3224 break; \
3225 case 3: \
3226 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3227 break; \
3228 case 4: \
3229 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3230 break; \
3231 case 5: \
3232 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3233 break; \
3234 case 6: \
3235 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3236 break; \
3237 case 7: \
3238 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3239 break; \
3240 case 8: \
3241 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3242 break; \
3243 case 9: \
3244 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3245 break; \
3246 case 10: \
3247 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3248 break; \
3249 case 11: \
3250 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3251 break; \
3252 case 12: \
3253 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3254 break; \
3255 case 13: \
3256 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3257 break; \
3258 case 14: \
3259 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3260 break; \
3261 case 15: \
3262 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3263 break; \
3264 case 17: \
3265 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3266 break; \
3267 case 18: \
3268 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3269 break; \
3270 case 19: \
3271 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3272 break; \
3273 case 25: \
3274 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3275 break; \
3276 case 26: \
3277 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3278 break; \
3279 case 27: \
3280 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3281 break; \
3282 default: \
3283 abort(); \
3284 } \
3285 STORE; \
3286 tcg_temp_free_i ## bits (fp0); \
3287 tcg_temp_free_i ## bits (fp1); \
3288}
3289
3290FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 3291FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 3292#undef FOP_CONDNS
8153667c
NF
3293#undef gen_ldcmp_fpr32
3294#undef gen_ldcmp_fpr64
3295
958fb4a9 3296/* load/store instructions. */
e7139c44 3297#ifdef CONFIG_USER_ONLY
d9bea114 3298#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3299static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3300 DisasContext *ctx) \
d9bea114
AJ
3301{ \
3302 TCGv t0 = tcg_temp_new(); \
3303 tcg_gen_mov_tl(t0, arg1); \
3304 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
3305 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3306 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 3307 tcg_temp_free(t0); \
aaa9128a 3308}
e7139c44
AJ
3309#else
3310#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3311static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3312 DisasContext *ctx) \
e7139c44 3313{ \
dd4096cd 3314 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
3315}
3316#endif
aaa9128a
TS
3317OP_LD_ATOMIC(ll,ld32s);
3318#if defined(TARGET_MIPS64)
3319OP_LD_ATOMIC(lld,ld64);
3320#endif
3321#undef OP_LD_ATOMIC
3322
590bc601
PB
3323#ifdef CONFIG_USER_ONLY
3324#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3325static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3326 DisasContext *ctx) \
590bc601
PB
3327{ \
3328 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
3329 TCGLabel *l1 = gen_new_label(); \
3330 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
3331 \
3332 tcg_gen_andi_tl(t0, arg2, almask); \
3333 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 3334 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
3335 generate_exception(ctx, EXCP_AdES); \
3336 gen_set_label(l1); \
7db13fae 3337 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
3338 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3339 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
3340 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3341 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 3342 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
3343 gen_set_label(l2); \
3344 tcg_gen_movi_tl(t0, 0); \
3345 gen_store_gpr(t0, rt); \
3346 tcg_temp_free(t0); \
3347}
3348#else
3349#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3350static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3351 DisasContext *ctx) \
590bc601
PB
3352{ \
3353 TCGv t0 = tcg_temp_new(); \
dd4096cd 3354 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 3355 gen_store_gpr(t0, rt); \
590bc601
PB
3356 tcg_temp_free(t0); \
3357}
3358#endif
590bc601 3359OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 3360#if defined(TARGET_MIPS64)
590bc601 3361OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
3362#endif
3363#undef OP_ST_ATOMIC
3364
662d7485 3365static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 3366 int base, int offset)
662d7485
NF
3367{
3368 if (base == 0) {
3369 tcg_gen_movi_tl(addr, offset);
3370 } else if (offset == 0) {
3371 gen_load_gpr(addr, base);
3372 } else {
3373 tcg_gen_movi_tl(addr, offset);
3374 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3375 }
3376}
3377
364d4831
NF
3378static target_ulong pc_relative_pc (DisasContext *ctx)
3379{
eeb3bba8 3380 target_ulong pc = ctx->base.pc_next;
364d4831
NF
3381
3382 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3383 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3384
3385 pc -= branch_bytes;
3386 }
3387
3388 pc &= ~(target_ulong)3;
3389 return pc;
3390}
3391
5c13fdfd 3392/* Load */
d75c135e 3393static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 3394 int rt, int base, int offset)
6af0bf9c 3395{
fc40787a 3396 TCGv t0, t1, t2;
dd4096cd 3397 int mem_idx = ctx->mem_idx;
afa88c3a 3398
d75c135e 3399 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
3400 /* Loongson CPU uses a load to zero register for prefetch.
3401 We emulate it as a NOP. On other CPU we must perform the
3402 actual memory access. */
afa88c3a
AJ
3403 return;
3404 }
6af0bf9c 3405
afa88c3a 3406 t0 = tcg_temp_new();
662d7485 3407 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 3408
6af0bf9c 3409 switch (opc) {
d26bc211 3410#if defined(TARGET_MIPS64)
6e473128 3411 case OPC_LWU:
dd4096cd 3412 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 3413 ctx->default_tcg_memop_mask);
78723684 3414 gen_store_gpr(t0, rt);
6e473128 3415 break;
6af0bf9c 3416 case OPC_LD:
dd4096cd 3417 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 3418 ctx->default_tcg_memop_mask);
78723684 3419 gen_store_gpr(t0, rt);
6af0bf9c 3420 break;
7a387fff 3421 case OPC_LLD:
bf7910c6 3422 case R6_OPC_LLD:
dd4096cd 3423 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 3424 gen_store_gpr(t0, rt);
7a387fff 3425 break;
6af0bf9c 3426 case OPC_LDL:
3cee3050 3427 t1 = tcg_temp_new();
908680c6
AJ
3428 /* Do a byte access to possibly trigger a page
3429 fault with the unaligned address. */
dd4096cd 3430 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3431 tcg_gen_andi_tl(t1, t0, 7);
3432#ifndef TARGET_WORDS_BIGENDIAN
3433 tcg_gen_xori_tl(t1, t1, 7);
3434#endif
3435 tcg_gen_shli_tl(t1, t1, 3);
3436 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3437 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 3438 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3439 t2 = tcg_const_tl(-1);
3440 tcg_gen_shl_tl(t2, t2, t1);
78723684 3441 gen_load_gpr(t1, rt);
eb02cc3f 3442 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3443 tcg_temp_free(t2);
3444 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3445 tcg_temp_free(t1);
fc40787a 3446 gen_store_gpr(t0, rt);
6af0bf9c 3447 break;
6af0bf9c 3448 case OPC_LDR:
3cee3050 3449 t1 = tcg_temp_new();
908680c6
AJ
3450 /* Do a byte access to possibly trigger a page
3451 fault with the unaligned address. */
dd4096cd 3452 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3453 tcg_gen_andi_tl(t1, t0, 7);
3454#ifdef TARGET_WORDS_BIGENDIAN
3455 tcg_gen_xori_tl(t1, t1, 7);
3456#endif
3457 tcg_gen_shli_tl(t1, t1, 3);
3458 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3459 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
3460 tcg_gen_shr_tl(t0, t0, t1);
3461 tcg_gen_xori_tl(t1, t1, 63);
3462 t2 = tcg_const_tl(0xfffffffffffffffeull);
3463 tcg_gen_shl_tl(t2, t2, t1);
78723684 3464 gen_load_gpr(t1, rt);
fc40787a
AJ
3465 tcg_gen_and_tl(t1, t1, t2);
3466 tcg_temp_free(t2);
3467 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3468 tcg_temp_free(t1);
fc40787a 3469 gen_store_gpr(t0, rt);
6af0bf9c 3470 break;
364d4831 3471 case OPC_LDPC:
3cee3050 3472 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3473 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3474 tcg_temp_free(t1);
dd4096cd 3475 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
3476 gen_store_gpr(t0, rt);
3477 break;
6af0bf9c 3478#endif
364d4831 3479 case OPC_LWPC:
3cee3050 3480 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3481 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3482 tcg_temp_free(t1);
dd4096cd 3483 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
3484 gen_store_gpr(t0, rt);
3485 break;
76964147
JH
3486 case OPC_LWE:
3487 mem_idx = MIPS_HFLAG_UM;
3488 /* fall through */
6af0bf9c 3489 case OPC_LW:
dd4096cd 3490 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 3491 ctx->default_tcg_memop_mask);
78723684 3492 gen_store_gpr(t0, rt);
6af0bf9c 3493 break;
76964147
JH
3494 case OPC_LHE:
3495 mem_idx = MIPS_HFLAG_UM;
3496 /* fall through */
6af0bf9c 3497 case OPC_LH:
dd4096cd 3498 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 3499 ctx->default_tcg_memop_mask);
78723684 3500 gen_store_gpr(t0, rt);
6af0bf9c 3501 break;
76964147
JH
3502 case OPC_LHUE:
3503 mem_idx = MIPS_HFLAG_UM;
3504 /* fall through */
6af0bf9c 3505 case OPC_LHU:
dd4096cd 3506 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 3507 ctx->default_tcg_memop_mask);
78723684 3508 gen_store_gpr(t0, rt);
6af0bf9c 3509 break;
76964147
JH
3510 case OPC_LBE:
3511 mem_idx = MIPS_HFLAG_UM;
3512 /* fall through */
6af0bf9c 3513 case OPC_LB:
dd4096cd 3514 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 3515 gen_store_gpr(t0, rt);
6af0bf9c 3516 break;
76964147
JH
3517 case OPC_LBUE:
3518 mem_idx = MIPS_HFLAG_UM;
3519 /* fall through */
6af0bf9c 3520 case OPC_LBU:
dd4096cd 3521 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 3522 gen_store_gpr(t0, rt);
6af0bf9c 3523 break;
76964147
JH
3524 case OPC_LWLE:
3525 mem_idx = MIPS_HFLAG_UM;
3526 /* fall through */
6af0bf9c 3527 case OPC_LWL:
3cee3050 3528 t1 = tcg_temp_new();
908680c6
AJ
3529 /* Do a byte access to possibly trigger a page
3530 fault with the unaligned address. */
dd4096cd 3531 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3532 tcg_gen_andi_tl(t1, t0, 3);
3533#ifndef TARGET_WORDS_BIGENDIAN
3534 tcg_gen_xori_tl(t1, t1, 3);
3535#endif
3536 tcg_gen_shli_tl(t1, t1, 3);
3537 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3538 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 3539 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3540 t2 = tcg_const_tl(-1);
3541 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3542 gen_load_gpr(t1, rt);
eb02cc3f 3543 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3544 tcg_temp_free(t2);
3545 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3546 tcg_temp_free(t1);
fc40787a
AJ
3547 tcg_gen_ext32s_tl(t0, t0);
3548 gen_store_gpr(t0, rt);
6af0bf9c 3549 break;
76964147
JH
3550 case OPC_LWRE:
3551 mem_idx = MIPS_HFLAG_UM;
3552 /* fall through */
6af0bf9c 3553 case OPC_LWR:
3cee3050 3554 t1 = tcg_temp_new();
908680c6
AJ
3555 /* Do a byte access to possibly trigger a page
3556 fault with the unaligned address. */
dd4096cd 3557 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3558 tcg_gen_andi_tl(t1, t0, 3);
3559#ifdef TARGET_WORDS_BIGENDIAN
3560 tcg_gen_xori_tl(t1, t1, 3);
3561#endif
3562 tcg_gen_shli_tl(t1, t1, 3);
3563 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3564 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
3565 tcg_gen_shr_tl(t0, t0, t1);
3566 tcg_gen_xori_tl(t1, t1, 31);
3567 t2 = tcg_const_tl(0xfffffffeull);
3568 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3569 gen_load_gpr(t1, rt);
fc40787a
AJ
3570 tcg_gen_and_tl(t1, t1, t2);
3571 tcg_temp_free(t2);
3572 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3573 tcg_temp_free(t1);
c728154b 3574 tcg_gen_ext32s_tl(t0, t0);
fc40787a 3575 gen_store_gpr(t0, rt);
6af0bf9c 3576 break;
76964147
JH
3577 case OPC_LLE:
3578 mem_idx = MIPS_HFLAG_UM;
3579 /* fall through */
6af0bf9c 3580 case OPC_LL:
4368b29a 3581 case R6_OPC_LL:
dd4096cd 3582 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 3583 gen_store_gpr(t0, rt);
6af0bf9c 3584 break;
d66c7132 3585 }
d66c7132 3586 tcg_temp_free(t0);
d66c7132
AJ
3587}
3588
0b16dcd1
AR
3589static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3590 uint32_t reg1, uint32_t reg2)
3591{
3592 TCGv taddr = tcg_temp_new();
3593 TCGv_i64 tval = tcg_temp_new_i64();
3594 TCGv tmp1 = tcg_temp_new();
3595 TCGv tmp2 = tcg_temp_new();
3596
3597 gen_base_offset_addr(ctx, taddr, base, offset);
3598 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3599#ifdef TARGET_WORDS_BIGENDIAN
3600 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3601#else
3602 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3603#endif
3604 gen_store_gpr(tmp1, reg1);
3605 tcg_temp_free(tmp1);
3606 gen_store_gpr(tmp2, reg2);
3607 tcg_temp_free(tmp2);
3608 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3609 tcg_temp_free_i64(tval);
3610 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3611 tcg_temp_free(taddr);
3612}
3613
5c13fdfd
AJ
3614/* Store */
3615static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 3616 int base, int offset)
5c13fdfd 3617{
5c13fdfd
AJ
3618 TCGv t0 = tcg_temp_new();
3619 TCGv t1 = tcg_temp_new();
dd4096cd 3620 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3621
3622 gen_base_offset_addr(ctx, t0, base, offset);
3623 gen_load_gpr(t1, rt);
3624 switch (opc) {
3625#if defined(TARGET_MIPS64)
3626 case OPC_SD:
dd4096cd 3627 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3628 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3629 break;
3630 case OPC_SDL:
dd4096cd 3631 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3632 break;
3633 case OPC_SDR:
dd4096cd 3634 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3635 break;
3636#endif
76964147
JH
3637 case OPC_SWE:
3638 mem_idx = MIPS_HFLAG_UM;
3639 /* fall through */
5c13fdfd 3640 case OPC_SW:
dd4096cd 3641 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3642 ctx->default_tcg_memop_mask);
5c13fdfd 3643 break;
76964147
JH
3644 case OPC_SHE:
3645 mem_idx = MIPS_HFLAG_UM;
3646 /* fall through */
5c13fdfd 3647 case OPC_SH:
dd4096cd 3648 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3649 ctx->default_tcg_memop_mask);
5c13fdfd 3650 break;
76964147
JH
3651 case OPC_SBE:
3652 mem_idx = MIPS_HFLAG_UM;
3653 /* fall through */
5c13fdfd 3654 case OPC_SB:
dd4096cd 3655 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3656 break;
76964147
JH
3657 case OPC_SWLE:
3658 mem_idx = MIPS_HFLAG_UM;
3659 /* fall through */
5c13fdfd 3660 case OPC_SWL:
dd4096cd 3661 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3662 break;
76964147
JH
3663 case OPC_SWRE:
3664 mem_idx = MIPS_HFLAG_UM;
3665 /* fall through */
5c13fdfd 3666 case OPC_SWR:
dd4096cd 3667 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3668 break;
3669 }
5c13fdfd
AJ
3670 tcg_temp_free(t0);
3671 tcg_temp_free(t1);
3672}
3673
3674
d66c7132
AJ
3675/* Store conditional */
3676static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3677 int base, int16_t offset)
3678{
d66c7132 3679 TCGv t0, t1;
dd4096cd 3680 int mem_idx = ctx->mem_idx;
d66c7132 3681
2d2826b9 3682#ifdef CONFIG_USER_ONLY
d66c7132 3683 t0 = tcg_temp_local_new();
d66c7132 3684 t1 = tcg_temp_local_new();
2d2826b9
AJ
3685#else
3686 t0 = tcg_temp_new();
3687 t1 = tcg_temp_new();
3688#endif
3689 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
3690 gen_load_gpr(t1, rt);
3691 switch (opc) {
3692#if defined(TARGET_MIPS64)
3693 case OPC_SCD:
bf7910c6 3694 case R6_OPC_SCD:
dd4096cd 3695 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
3696 break;
3697#endif
76964147
JH
3698 case OPC_SCE:
3699 mem_idx = MIPS_HFLAG_UM;
3700 /* fall through */
6af0bf9c 3701 case OPC_SC:
4368b29a 3702 case R6_OPC_SC:
dd4096cd 3703 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 3704 break;
6af0bf9c 3705 }
78723684 3706 tcg_temp_free(t1);
d66c7132 3707 tcg_temp_free(t0);
6af0bf9c
FB
3708}
3709
0b16dcd1
AR
3710static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3711 uint32_t reg1, uint32_t reg2)
3712{
3713 TCGv taddr = tcg_temp_local_new();
3714 TCGv lladdr = tcg_temp_local_new();
3715 TCGv_i64 tval = tcg_temp_new_i64();
3716 TCGv_i64 llval = tcg_temp_new_i64();
3717 TCGv_i64 val = tcg_temp_new_i64();
3718 TCGv tmp1 = tcg_temp_new();
3719 TCGv tmp2 = tcg_temp_new();
3720 TCGLabel *lab_fail = gen_new_label();
3721 TCGLabel *lab_done = gen_new_label();
3722
3723 gen_base_offset_addr(ctx, taddr, base, offset);
3724
3725 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3726 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3727
3728 gen_load_gpr(tmp1, reg1);
3729 gen_load_gpr(tmp2, reg2);
3730
3731#ifdef TARGET_WORDS_BIGENDIAN
3732 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3733#else
3734 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3735#endif
3736
3737 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3738 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3739 ctx->mem_idx, MO_64);
3740 if (reg1 != 0) {
3741 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3742 }
3743 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3744
3745 gen_set_label(lab_fail);
3746
3747 if (reg1 != 0) {
3748 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3749 }
3750 gen_set_label(lab_done);
3751 tcg_gen_movi_tl(lladdr, -1);
3752 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3753}
3754
6ea83fed 3755/* Load and store */
7a387fff 3756static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 3757 TCGv t0)
6ea83fed 3758{
6ea83fed 3759 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 3760 memory access. */
6ea83fed
FB
3761 switch (opc) {
3762 case OPC_LWC1:
b6d96bed 3763 {
a7812ae4 3764 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3765 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3766 ctx->default_tcg_memop_mask);
7c979afd 3767 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3768 tcg_temp_free_i32(fp0);
b6d96bed 3769 }
6ea83fed
FB
3770 break;
3771 case OPC_SWC1:
b6d96bed 3772 {
a7812ae4 3773 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3774 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3775 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3776 ctx->default_tcg_memop_mask);
a7812ae4 3777 tcg_temp_free_i32(fp0);
b6d96bed 3778 }
6ea83fed
FB
3779 break;
3780 case OPC_LDC1:
b6d96bed 3781 {
a7812ae4 3782 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3783 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3784 ctx->default_tcg_memop_mask);
b6d96bed 3785 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3786 tcg_temp_free_i64(fp0);
b6d96bed 3787 }
6ea83fed
FB
3788 break;
3789 case OPC_SDC1:
b6d96bed 3790 {
a7812ae4 3791 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3792 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3793 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3794 ctx->default_tcg_memop_mask);
a7812ae4 3795 tcg_temp_free_i64(fp0);
b6d96bed 3796 }
6ea83fed
FB
3797 break;
3798 default:
9d68ac14 3799 MIPS_INVAL("flt_ldst");
9c708c7f 3800 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 3801 break;
6ea83fed 3802 }
6ea83fed 3803}
6ea83fed 3804
5ab5c041
AJ
3805static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3806 int rs, int16_t imm)
26ebe468 3807{
b52d3bfa
YK
3808 TCGv t0 = tcg_temp_new();
3809
5ab5c041 3810 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3811 check_cp1_enabled(ctx);
d9224450
MR
3812 switch (op) {
3813 case OPC_LDC1:
3814 case OPC_SDC1:
3815 check_insn(ctx, ISA_MIPS2);
3816 /* Fallthrough */
3817 default:
b52d3bfa
YK
3818 gen_base_offset_addr(ctx, t0, rs, imm);
3819 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3820 }
26ebe468
NF
3821 } else {
3822 generate_exception_err(ctx, EXCP_CpU, 1);
3823 }
b52d3bfa 3824 tcg_temp_free(t0);
26ebe468
NF
3825}
3826
6af0bf9c 3827/* Arithmetic with immediate operand */
d75c135e 3828static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3829 int rt, int rs, int imm)
6af0bf9c 3830{
324d9e32 3831 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3832
7a387fff 3833 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
3834 /* If no destination, treat it as a NOP.
3835 For addi, we must generate the overflow exception when needed. */
324d9e32 3836 return;
6af0bf9c
FB
3837 }
3838 switch (opc) {
3839 case OPC_ADDI:
48d38ca5 3840 {
324d9e32
AJ
3841 TCGv t0 = tcg_temp_local_new();
3842 TCGv t1 = tcg_temp_new();
3843 TCGv t2 = tcg_temp_new();
42a268c2 3844 TCGLabel *l1 = gen_new_label();
48d38ca5 3845
324d9e32
AJ
3846 gen_load_gpr(t1, rs);
3847 tcg_gen_addi_tl(t0, t1, uimm);
3848 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3849
324d9e32
AJ
3850 tcg_gen_xori_tl(t1, t1, ~uimm);
3851 tcg_gen_xori_tl(t2, t0, uimm);
3852 tcg_gen_and_tl(t1, t1, t2);
3853 tcg_temp_free(t2);
3854 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3855 tcg_temp_free(t1);
48d38ca5
TS
3856 /* operands of same sign, result different sign */
3857 generate_exception(ctx, EXCP_OVERFLOW);
3858 gen_set_label(l1);
78723684 3859 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3860 gen_store_gpr(t0, rt);
3861 tcg_temp_free(t0);
48d38ca5 3862 }
6af0bf9c
FB
3863 break;
3864 case OPC_ADDIU:
324d9e32
AJ
3865 if (rs != 0) {
3866 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3867 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3868 } else {
3869 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3870 }
6af0bf9c 3871 break;
d26bc211 3872#if defined(TARGET_MIPS64)
7a387fff 3873 case OPC_DADDI:
48d38ca5 3874 {
324d9e32
AJ
3875 TCGv t0 = tcg_temp_local_new();
3876 TCGv t1 = tcg_temp_new();
3877 TCGv t2 = tcg_temp_new();
42a268c2 3878 TCGLabel *l1 = gen_new_label();
48d38ca5 3879
324d9e32
AJ
3880 gen_load_gpr(t1, rs);
3881 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3882
324d9e32
AJ
3883 tcg_gen_xori_tl(t1, t1, ~uimm);
3884 tcg_gen_xori_tl(t2, t0, uimm);
3885 tcg_gen_and_tl(t1, t1, t2);
3886 tcg_temp_free(t2);
3887 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3888 tcg_temp_free(t1);
48d38ca5
TS
3889 /* operands of same sign, result different sign */
3890 generate_exception(ctx, EXCP_OVERFLOW);
3891 gen_set_label(l1);
324d9e32
AJ
3892 gen_store_gpr(t0, rt);
3893 tcg_temp_free(t0);
48d38ca5 3894 }
7a387fff
TS
3895 break;
3896 case OPC_DADDIU:
324d9e32
AJ
3897 if (rs != 0) {
3898 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3899 } else {
3900 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3901 }
7a387fff
TS
3902 break;
3903#endif
324d9e32 3904 }
324d9e32
AJ
3905}
3906
3907/* Logic with immediate operand */
d75c135e 3908static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3909 int rt, int rs, int16_t imm)
324d9e32
AJ
3910{
3911 target_ulong uimm;
324d9e32
AJ
3912
3913 if (rt == 0) {
3914 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3915 return;
3916 }
3917 uimm = (uint16_t)imm;
3918 switch (opc) {
6af0bf9c 3919 case OPC_ANDI:
324d9e32
AJ
3920 if (likely(rs != 0))
3921 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3922 else
3923 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
3924 break;
3925 case OPC_ORI:
324d9e32
AJ
3926 if (rs != 0)
3927 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3928 else
3929 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3930 break;
3931 case OPC_XORI:
324d9e32
AJ
3932 if (likely(rs != 0))
3933 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3934 else
3935 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3936 break;
3937 case OPC_LUI:
d4ea6acd
LA
3938 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3939 /* OPC_AUI */
3940 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3941 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3942 } else {
3943 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3944 }
7c2c3ea3
EJ
3945 break;
3946
3947 default:
6af0bf9c 3948 break;
324d9e32 3949 }
324d9e32
AJ
3950}
3951
3952/* Set on less than with immediate operand */
d75c135e 3953static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3954 int rt, int rs, int16_t imm)
324d9e32
AJ
3955{
3956 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3957 TCGv t0;
3958
3959 if (rt == 0) {
3960 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3961 return;
3962 }
3963 t0 = tcg_temp_new();
3964 gen_load_gpr(t0, rs);
3965 switch (opc) {
3966 case OPC_SLTI:
e68dd28f 3967 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3968 break;
3969 case OPC_SLTIU:
e68dd28f 3970 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3971 break;
3972 }
324d9e32
AJ
3973 tcg_temp_free(t0);
3974}
3975
3976/* Shifts with immediate operand */
d75c135e 3977static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3978 int rt, int rs, int16_t imm)
3979{
3980 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3981 TCGv t0;
3982
3983 if (rt == 0) {
3984 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3985 return;
3986 }
3987
3988 t0 = tcg_temp_new();
3989 gen_load_gpr(t0, rs);
3990 switch (opc) {
6af0bf9c 3991 case OPC_SLL:
78723684 3992 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3993 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3994 break;
3995 case OPC_SRA:
324d9e32 3996 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3997 break;
3998 case OPC_SRL:
ea63e2c3
NF
3999 if (uimm != 0) {
4000 tcg_gen_ext32u_tl(t0, t0);
4001 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4002 } else {
4003 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 4004 }
ea63e2c3
NF
4005 break;
4006 case OPC_ROTR:
4007 if (uimm != 0) {
4008 TCGv_i32 t1 = tcg_temp_new_i32();
4009
4010 tcg_gen_trunc_tl_i32(t1, t0);
4011 tcg_gen_rotri_i32(t1, t1, uimm);
4012 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4013 tcg_temp_free_i32(t1);
3399e30f
NF
4014 } else {
4015 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 4016 }
7a387fff 4017 break;
d26bc211 4018#if defined(TARGET_MIPS64)
7a387fff 4019 case OPC_DSLL:
324d9e32 4020 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
4021 break;
4022 case OPC_DSRA:
324d9e32 4023 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
4024 break;
4025 case OPC_DSRL:
ea63e2c3 4026 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
4027 break;
4028 case OPC_DROTR:
4029 if (uimm != 0) {
4030 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
4031 } else {
4032 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 4033 }
7a387fff
TS
4034 break;
4035 case OPC_DSLL32:
324d9e32 4036 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
4037 break;
4038 case OPC_DSRA32:
324d9e32 4039 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
4040 break;
4041 case OPC_DSRL32:
ea63e2c3 4042 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
4043 break;
4044 case OPC_DROTR32:
4045 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 4046 break;
7a387fff 4047#endif
6af0bf9c 4048 }
78723684 4049 tcg_temp_free(t0);
6af0bf9c
FB
4050}
4051
4052/* Arithmetic */
d75c135e
AJ
4053static void gen_arith(DisasContext *ctx, uint32_t opc,
4054 int rd, int rs, int rt)
6af0bf9c 4055{
7a387fff
TS
4056 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4057 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
4058 /* If no destination, treat it as a NOP.
4059 For add & sub, we must generate the overflow exception when needed. */
460f00c4 4060 return;
185f0762 4061 }
460f00c4 4062
6af0bf9c
FB
4063 switch (opc) {
4064 case OPC_ADD:
48d38ca5 4065 {
460f00c4
AJ
4066 TCGv t0 = tcg_temp_local_new();
4067 TCGv t1 = tcg_temp_new();
4068 TCGv t2 = tcg_temp_new();
42a268c2 4069 TCGLabel *l1 = gen_new_label();
48d38ca5 4070
460f00c4
AJ
4071 gen_load_gpr(t1, rs);
4072 gen_load_gpr(t2, rt);
4073 tcg_gen_add_tl(t0, t1, t2);
4074 tcg_gen_ext32s_tl(t0, t0);
4075 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 4076 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 4077 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
4078 tcg_temp_free(t2);
4079 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4080 tcg_temp_free(t1);
48d38ca5
TS
4081 /* operands of same sign, result different sign */
4082 generate_exception(ctx, EXCP_OVERFLOW);
4083 gen_set_label(l1);
460f00c4
AJ
4084 gen_store_gpr(t0, rd);
4085 tcg_temp_free(t0);
48d38ca5 4086 }
6af0bf9c
FB
4087 break;
4088 case OPC_ADDU:
460f00c4
AJ
4089 if (rs != 0 && rt != 0) {
4090 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4091 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4092 } else if (rs == 0 && rt != 0) {
4093 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4094 } else if (rs != 0 && rt == 0) {
4095 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4096 } else {
4097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4098 }
6af0bf9c
FB
4099 break;
4100 case OPC_SUB:
48d38ca5 4101 {
460f00c4
AJ
4102 TCGv t0 = tcg_temp_local_new();
4103 TCGv t1 = tcg_temp_new();
4104 TCGv t2 = tcg_temp_new();
42a268c2 4105 TCGLabel *l1 = gen_new_label();
48d38ca5 4106
460f00c4
AJ
4107 gen_load_gpr(t1, rs);
4108 gen_load_gpr(t2, rt);
4109 tcg_gen_sub_tl(t0, t1, t2);
4110 tcg_gen_ext32s_tl(t0, t0);
4111 tcg_gen_xor_tl(t2, t1, t2);
4112 tcg_gen_xor_tl(t1, t0, t1);
4113 tcg_gen_and_tl(t1, t1, t2);
4114 tcg_temp_free(t2);
4115 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4116 tcg_temp_free(t1);
31e3104f 4117 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4118 generate_exception(ctx, EXCP_OVERFLOW);
4119 gen_set_label(l1);
460f00c4
AJ
4120 gen_store_gpr(t0, rd);
4121 tcg_temp_free(t0);
48d38ca5 4122 }
6af0bf9c
FB
4123 break;
4124 case OPC_SUBU:
460f00c4
AJ
4125 if (rs != 0 && rt != 0) {
4126 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4127 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4128 } else if (rs == 0 && rt != 0) {
4129 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 4130 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
4131 } else if (rs != 0 && rt == 0) {
4132 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4133 } else {
4134 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4135 }
6af0bf9c 4136 break;
d26bc211 4137#if defined(TARGET_MIPS64)
7a387fff 4138 case OPC_DADD:
48d38ca5 4139 {
460f00c4
AJ
4140 TCGv t0 = tcg_temp_local_new();
4141 TCGv t1 = tcg_temp_new();
4142 TCGv t2 = tcg_temp_new();
42a268c2 4143 TCGLabel *l1 = gen_new_label();
48d38ca5 4144
460f00c4
AJ
4145 gen_load_gpr(t1, rs);
4146 gen_load_gpr(t2, rt);
4147 tcg_gen_add_tl(t0, t1, t2);
4148 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 4149 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 4150 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
4151 tcg_temp_free(t2);
4152 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4153 tcg_temp_free(t1);
48d38ca5
TS
4154 /* operands of same sign, result different sign */
4155 generate_exception(ctx, EXCP_OVERFLOW);
4156 gen_set_label(l1);
460f00c4
AJ
4157 gen_store_gpr(t0, rd);
4158 tcg_temp_free(t0);
48d38ca5 4159 }
7a387fff
TS
4160 break;
4161 case OPC_DADDU:
460f00c4
AJ
4162 if (rs != 0 && rt != 0) {
4163 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4164 } else if (rs == 0 && rt != 0) {
4165 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4166 } else if (rs != 0 && rt == 0) {
4167 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4168 } else {
4169 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4170 }
7a387fff
TS
4171 break;
4172 case OPC_DSUB:
48d38ca5 4173 {
460f00c4
AJ
4174 TCGv t0 = tcg_temp_local_new();
4175 TCGv t1 = tcg_temp_new();
4176 TCGv t2 = tcg_temp_new();
42a268c2 4177 TCGLabel *l1 = gen_new_label();
48d38ca5 4178
460f00c4
AJ
4179 gen_load_gpr(t1, rs);
4180 gen_load_gpr(t2, rt);
4181 tcg_gen_sub_tl(t0, t1, t2);
4182 tcg_gen_xor_tl(t2, t1, t2);
4183 tcg_gen_xor_tl(t1, t0, t1);
4184 tcg_gen_and_tl(t1, t1, t2);
4185 tcg_temp_free(t2);
4186 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4187 tcg_temp_free(t1);
31e3104f 4188 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4189 generate_exception(ctx, EXCP_OVERFLOW);
4190 gen_set_label(l1);
460f00c4
AJ
4191 gen_store_gpr(t0, rd);
4192 tcg_temp_free(t0);
48d38ca5 4193 }
7a387fff
TS
4194 break;
4195 case OPC_DSUBU:
460f00c4
AJ
4196 if (rs != 0 && rt != 0) {
4197 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4198 } else if (rs == 0 && rt != 0) {
4199 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4200 } else if (rs != 0 && rt == 0) {
4201 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4202 } else {
4203 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4204 }
7a387fff
TS
4205 break;
4206#endif
460f00c4
AJ
4207 case OPC_MUL:
4208 if (likely(rs != 0 && rt != 0)) {
4209 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4210 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4211 } else {
4212 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4213 }
6af0bf9c 4214 break;
460f00c4 4215 }
460f00c4
AJ
4216}
4217
4218/* Conditional move */
d75c135e 4219static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 4220 int rd, int rs, int rt)
460f00c4 4221{
acf12465 4222 TCGv t0, t1, t2;
460f00c4
AJ
4223
4224 if (rd == 0) {
acf12465 4225 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4226 return;
4227 }
4228
acf12465
AJ
4229 t0 = tcg_temp_new();
4230 gen_load_gpr(t0, rt);
4231 t1 = tcg_const_tl(0);
4232 t2 = tcg_temp_new();
4233 gen_load_gpr(t2, rs);
460f00c4
AJ
4234 switch (opc) {
4235 case OPC_MOVN:
acf12465 4236 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 4237 break;
460f00c4 4238 case OPC_MOVZ:
acf12465 4239 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 4240 break;
b691d9d2
LA
4241 case OPC_SELNEZ:
4242 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
4243 break;
4244 case OPC_SELEQZ:
4245 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 4246 break;
460f00c4 4247 }
acf12465
AJ
4248 tcg_temp_free(t2);
4249 tcg_temp_free(t1);
4250 tcg_temp_free(t0);
460f00c4
AJ
4251}
4252
4253/* Logic */
d75c135e 4254static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 4255 int rd, int rs, int rt)
460f00c4 4256{
460f00c4
AJ
4257 if (rd == 0) {
4258 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4259 return;
4260 }
4261
4262 switch (opc) {
6af0bf9c 4263 case OPC_AND:
460f00c4
AJ
4264 if (likely(rs != 0 && rt != 0)) {
4265 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4266 } else {
4267 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4268 }
6af0bf9c
FB
4269 break;
4270 case OPC_NOR:
460f00c4
AJ
4271 if (rs != 0 && rt != 0) {
4272 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4273 } else if (rs == 0 && rt != 0) {
4274 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4275 } else if (rs != 0 && rt == 0) {
4276 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4277 } else {
4278 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4279 }
6af0bf9c
FB
4280 break;
4281 case OPC_OR:
460f00c4
AJ
4282 if (likely(rs != 0 && rt != 0)) {
4283 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4284 } else if (rs == 0 && rt != 0) {
4285 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4286 } else if (rs != 0 && rt == 0) {
4287 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4288 } else {
4289 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4290 }
6af0bf9c
FB
4291 break;
4292 case OPC_XOR:
460f00c4
AJ
4293 if (likely(rs != 0 && rt != 0)) {
4294 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4295 } else if (rs == 0 && rt != 0) {
4296 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4297 } else if (rs != 0 && rt == 0) {
4298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4299 } else {
4300 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4301 }
6af0bf9c 4302 break;
460f00c4 4303 }
460f00c4
AJ
4304}
4305
4306/* Set on lower than */
d75c135e 4307static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 4308 int rd, int rs, int rt)
460f00c4 4309{
460f00c4
AJ
4310 TCGv t0, t1;
4311
4312 if (rd == 0) {
4313 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4314 return;
4315 }
4316
4317 t0 = tcg_temp_new();
4318 t1 = tcg_temp_new();
4319 gen_load_gpr(t0, rs);
4320 gen_load_gpr(t1, rt);
4321 switch (opc) {
4322 case OPC_SLT:
e68dd28f 4323 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 4324 break;
460f00c4 4325 case OPC_SLTU:
e68dd28f 4326 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
4327 break;
4328 }
460f00c4
AJ
4329 tcg_temp_free(t0);
4330 tcg_temp_free(t1);
4331}
20c4c97c 4332
460f00c4 4333/* Shifts */
d75c135e
AJ
4334static void gen_shift(DisasContext *ctx, uint32_t opc,
4335 int rd, int rs, int rt)
460f00c4 4336{
460f00c4 4337 TCGv t0, t1;
20c4c97c 4338
460f00c4
AJ
4339 if (rd == 0) {
4340 /* If no destination, treat it as a NOP.
4341 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
4342 return;
4343 }
4344
4345 t0 = tcg_temp_new();
4346 t1 = tcg_temp_new();
4347 gen_load_gpr(t0, rs);
4348 gen_load_gpr(t1, rt);
4349 switch (opc) {
6af0bf9c 4350 case OPC_SLLV:
78723684
TS
4351 tcg_gen_andi_tl(t0, t0, 0x1f);
4352 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 4353 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
4354 break;
4355 case OPC_SRAV:
78723684 4356 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 4357 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
4358 break;
4359 case OPC_SRLV:
ea63e2c3
NF
4360 tcg_gen_ext32u_tl(t1, t1);
4361 tcg_gen_andi_tl(t0, t0, 0x1f);
4362 tcg_gen_shr_tl(t0, t1, t0);
4363 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
4364 break;
4365 case OPC_ROTRV:
4366 {
4367 TCGv_i32 t2 = tcg_temp_new_i32();
4368 TCGv_i32 t3 = tcg_temp_new_i32();
4369
4370 tcg_gen_trunc_tl_i32(t2, t0);
4371 tcg_gen_trunc_tl_i32(t3, t1);
4372 tcg_gen_andi_i32(t2, t2, 0x1f);
4373 tcg_gen_rotr_i32(t2, t3, t2);
4374 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4375 tcg_temp_free_i32(t2);
4376 tcg_temp_free_i32(t3);
5a63bcb2 4377 }
7a387fff 4378 break;
d26bc211 4379#if defined(TARGET_MIPS64)
7a387fff 4380 case OPC_DSLLV:
78723684 4381 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4382 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4383 break;
4384 case OPC_DSRAV:
78723684 4385 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4386 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4387 break;
4388 case OPC_DSRLV:
ea63e2c3
NF
4389 tcg_gen_andi_tl(t0, t0, 0x3f);
4390 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
4391 break;
4392 case OPC_DROTRV:
4393 tcg_gen_andi_tl(t0, t0, 0x3f);
4394 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 4395 break;
7a387fff 4396#endif
6af0bf9c 4397 }
78723684
TS
4398 tcg_temp_free(t0);
4399 tcg_temp_free(t1);
6af0bf9c
FB
4400}
4401
86efbfb6
FN
4402/* Copy GPR to and from TX79 HI1/LO1 register. */
4403static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4404{
baa609db 4405 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
86efbfb6
FN
4406 /* Treat as NOP. */
4407 return;
4408 }
4409
4410 switch (opc) {
baa609db 4411 case MMI_OPC_MFHI1:
86efbfb6
FN
4412 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4413 break;
baa609db 4414 case MMI_OPC_MFLO1:
86efbfb6
FN
4415 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4416 break;
baa609db 4417 case MMI_OPC_MTHI1:
86efbfb6
FN
4418 if (reg != 0) {
4419 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4420 } else {
4421 tcg_gen_movi_tl(cpu_HI[1], 0);
4422 }
4423 break;
baa609db 4424 case MMI_OPC_MTLO1:
86efbfb6
FN
4425 if (reg != 0) {
4426 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4427 } else {
4428 tcg_gen_movi_tl(cpu_LO[1], 0);
4429 }
4430 break;
4431 default:
4432 MIPS_INVAL("mfthilo1 TX79");
4433 generate_exception_end(ctx, EXCP_RI);
4434 break;
4435 }
4436}
4437
6af0bf9c 4438/* Arithmetic on HI/LO registers */
26135ead 4439static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 4440{
86efbfb6 4441 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 4442 /* Treat as NOP. */
a1f6684d 4443 return;
6af0bf9c 4444 }
4133498f 4445
4133498f 4446 if (acc != 0) {
86efbfb6 4447 check_dsp(ctx);
4133498f
JL
4448 }
4449
6af0bf9c
FB
4450 switch (opc) {
4451 case OPC_MFHI:
4133498f
JL
4452#if defined(TARGET_MIPS64)
4453 if (acc != 0) {
4454 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4455 } else
4456#endif
4457 {
4458 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4459 }
6af0bf9c
FB
4460 break;
4461 case OPC_MFLO:
4133498f
JL
4462#if defined(TARGET_MIPS64)
4463 if (acc != 0) {
4464 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4465 } else
4466#endif
4467 {
4468 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4469 }
6af0bf9c
FB
4470 break;
4471 case OPC_MTHI:
4133498f
JL
4472 if (reg != 0) {
4473#if defined(TARGET_MIPS64)
4474 if (acc != 0) {
4475 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4476 } else
4477#endif
4478 {
4479 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4480 }
4481 } else {
4482 tcg_gen_movi_tl(cpu_HI[acc], 0);
4483 }
6af0bf9c
FB
4484 break;
4485 case OPC_MTLO:
4133498f
JL
4486 if (reg != 0) {
4487#if defined(TARGET_MIPS64)
4488 if (acc != 0) {
4489 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4490 } else
4491#endif
4492 {
4493 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4494 }
4495 } else {
4496 tcg_gen_movi_tl(cpu_LO[acc], 0);
4497 }
6af0bf9c 4498 break;
6af0bf9c 4499 }
6af0bf9c
FB
4500}
4501
d4ea6acd
LA
4502static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4503 TCGMemOp memop)
4504{
4505 TCGv t0 = tcg_const_tl(addr);
4506 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4507 gen_store_gpr(t0, reg);
4508 tcg_temp_free(t0);
4509}
4510
ab39ee45
YK
4511static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4512 int rs)
d4ea6acd
LA
4513{
4514 target_long offset;
4515 target_long addr;
4516
ab39ee45 4517 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
4518 case OPC_ADDIUPC:
4519 if (rs != 0) {
4520 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4521 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4522 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4523 }
4524 break;
4525 case R6_OPC_LWPC:
4526 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4527 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4528 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4529 break;
4530#if defined(TARGET_MIPS64)
4531 case OPC_LWUPC:
4532 check_mips_64(ctx);
4533 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4534 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4535 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4536 break;
4537#endif
4538 default:
ab39ee45 4539 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
4540 case OPC_AUIPC:
4541 if (rs != 0) {
ab39ee45
YK
4542 offset = sextract32(ctx->opcode, 0, 16) << 16;
4543 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4544 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4545 }
4546 break;
4547 case OPC_ALUIPC:
4548 if (rs != 0) {
ab39ee45
YK
4549 offset = sextract32(ctx->opcode, 0, 16) << 16;
4550 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
4551 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4552 }
4553 break;
4554#if defined(TARGET_MIPS64)
4555 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4556 case R6_OPC_LDPC + (1 << 16):
4557 case R6_OPC_LDPC + (2 << 16):
4558 case R6_OPC_LDPC + (3 << 16):
4559 check_mips_64(ctx);
4560 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 4561 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
4562 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4563 break;
4564#endif
4565 default:
4566 MIPS_INVAL("OPC_PCREL");
9c708c7f 4567 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
4568 break;
4569 }
4570 break;
4571 }
4572}
4573
b42ee5e1
LA
4574static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4575{
b42ee5e1
LA
4576 TCGv t0, t1;
4577
4578 if (rd == 0) {
4579 /* Treat as NOP. */
b42ee5e1
LA
4580 return;
4581 }
4582
4583 t0 = tcg_temp_new();
4584 t1 = tcg_temp_new();
4585
4586 gen_load_gpr(t0, rs);
4587 gen_load_gpr(t1, rt);
4588
4589 switch (opc) {
4590 case R6_OPC_DIV:
4591 {
4592 TCGv t2 = tcg_temp_new();
4593 TCGv t3 = tcg_temp_new();
4594 tcg_gen_ext32s_tl(t0, t0);
4595 tcg_gen_ext32s_tl(t1, t1);
4596 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4597 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4598 tcg_gen_and_tl(t2, t2, t3);
4599 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4600 tcg_gen_or_tl(t2, t2, t3);
4601 tcg_gen_movi_tl(t3, 0);
4602 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4603 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4604 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4605 tcg_temp_free(t3);
4606 tcg_temp_free(t2);
4607 }
b42ee5e1
LA
4608 break;
4609 case R6_OPC_MOD:
4610 {
4611 TCGv t2 = tcg_temp_new();
4612 TCGv t3 = tcg_temp_new();
4613 tcg_gen_ext32s_tl(t0, t0);
4614 tcg_gen_ext32s_tl(t1, t1);
4615 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4616 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4617 tcg_gen_and_tl(t2, t2, t3);
4618 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4619 tcg_gen_or_tl(t2, t2, t3);
4620 tcg_gen_movi_tl(t3, 0);
4621 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4622 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4623 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4624 tcg_temp_free(t3);
4625 tcg_temp_free(t2);
4626 }
b42ee5e1
LA
4627 break;
4628 case R6_OPC_DIVU:
4629 {
4630 TCGv t2 = tcg_const_tl(0);
4631 TCGv t3 = tcg_const_tl(1);
4632 tcg_gen_ext32u_tl(t0, t0);
4633 tcg_gen_ext32u_tl(t1, t1);
4634 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4635 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4636 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4637 tcg_temp_free(t3);
4638 tcg_temp_free(t2);
4639 }
b42ee5e1
LA
4640 break;
4641 case R6_OPC_MODU:
4642 {
4643 TCGv t2 = tcg_const_tl(0);
4644 TCGv t3 = tcg_const_tl(1);
4645 tcg_gen_ext32u_tl(t0, t0);
4646 tcg_gen_ext32u_tl(t1, t1);
4647 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4648 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4649 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4650 tcg_temp_free(t3);
4651 tcg_temp_free(t2);
4652 }
b42ee5e1
LA
4653 break;
4654 case R6_OPC_MUL:
4655 {
4656 TCGv_i32 t2 = tcg_temp_new_i32();
4657 TCGv_i32 t3 = tcg_temp_new_i32();
4658 tcg_gen_trunc_tl_i32(t2, t0);
4659 tcg_gen_trunc_tl_i32(t3, t1);
4660 tcg_gen_mul_i32(t2, t2, t3);
4661 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4662 tcg_temp_free_i32(t2);
4663 tcg_temp_free_i32(t3);
4664 }
b42ee5e1
LA
4665 break;
4666 case R6_OPC_MUH:
4667 {
4668 TCGv_i32 t2 = tcg_temp_new_i32();
4669 TCGv_i32 t3 = tcg_temp_new_i32();
4670 tcg_gen_trunc_tl_i32(t2, t0);
4671 tcg_gen_trunc_tl_i32(t3, t1);
4672 tcg_gen_muls2_i32(t2, t3, t2, t3);
4673 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4674 tcg_temp_free_i32(t2);
4675 tcg_temp_free_i32(t3);
4676 }
b42ee5e1
LA
4677 break;
4678 case R6_OPC_MULU:
4679 {
4680 TCGv_i32 t2 = tcg_temp_new_i32();
4681 TCGv_i32 t3 = tcg_temp_new_i32();
4682 tcg_gen_trunc_tl_i32(t2, t0);
4683 tcg_gen_trunc_tl_i32(t3, t1);
4684 tcg_gen_mul_i32(t2, t2, t3);
4685 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4686 tcg_temp_free_i32(t2);
4687 tcg_temp_free_i32(t3);
4688 }
b42ee5e1
LA
4689 break;
4690 case R6_OPC_MUHU:
4691 {
4692 TCGv_i32 t2 = tcg_temp_new_i32();
4693 TCGv_i32 t3 = tcg_temp_new_i32();
4694 tcg_gen_trunc_tl_i32(t2, t0);
4695 tcg_gen_trunc_tl_i32(t3, t1);
4696 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4697 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4698 tcg_temp_free_i32(t2);
4699 tcg_temp_free_i32(t3);
4700 }
b42ee5e1
LA
4701 break;
4702#if defined(TARGET_MIPS64)
4703 case R6_OPC_DDIV:
4704 {
4705 TCGv t2 = tcg_temp_new();
4706 TCGv t3 = tcg_temp_new();
4707 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4708 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4709 tcg_gen_and_tl(t2, t2, t3);
4710 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4711 tcg_gen_or_tl(t2, t2, t3);
4712 tcg_gen_movi_tl(t3, 0);
4713 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4714 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4715 tcg_temp_free(t3);
4716 tcg_temp_free(t2);
4717 }
b42ee5e1
LA
4718 break;
4719 case R6_OPC_DMOD:
4720 {
4721 TCGv t2 = tcg_temp_new();
4722 TCGv t3 = tcg_temp_new();
4723 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4724 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4725 tcg_gen_and_tl(t2, t2, t3);
4726 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4727 tcg_gen_or_tl(t2, t2, t3);
4728 tcg_gen_movi_tl(t3, 0);
4729 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4730 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4731 tcg_temp_free(t3);
4732 tcg_temp_free(t2);
4733 }
b42ee5e1
LA
4734 break;
4735 case R6_OPC_DDIVU:
4736 {
4737 TCGv t2 = tcg_const_tl(0);
4738 TCGv t3 = tcg_const_tl(1);
4739 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4740 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4741 tcg_temp_free(t3);
4742 tcg_temp_free(t2);
4743 }
b42ee5e1
LA
4744 break;
4745 case R6_OPC_DMODU:
4746 {
4747 TCGv t2 = tcg_const_tl(0);
4748 TCGv t3 = tcg_const_tl(1);
4749 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4750 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4751 tcg_temp_free(t3);
4752 tcg_temp_free(t2);
4753 }
b42ee5e1
LA
4754 break;
4755 case R6_OPC_DMUL:
4756 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4757 break;
4758 case R6_OPC_DMUH:
4759 {
4760 TCGv t2 = tcg_temp_new();
4761 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4762 tcg_temp_free(t2);
4763 }
b42ee5e1
LA
4764 break;
4765 case R6_OPC_DMULU:
4766 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4767 break;
4768 case R6_OPC_DMUHU:
4769 {
4770 TCGv t2 = tcg_temp_new();
4771 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4772 tcg_temp_free(t2);
4773 }
b42ee5e1
LA
4774 break;
4775#endif
4776 default:
9d68ac14 4777 MIPS_INVAL("r6 mul/div");
9c708c7f 4778 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
4779 goto out;
4780 }
b42ee5e1
LA
4781 out:
4782 tcg_temp_free(t0);
4783 tcg_temp_free(t1);
4784}
4785
c42171c3
FN
4786static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4787{
4788 TCGv t0, t1;
4789
4790 t0 = tcg_temp_new();
4791 t1 = tcg_temp_new();
4792
4793 gen_load_gpr(t0, rs);
4794 gen_load_gpr(t1, rt);
4795
4796 switch (opc) {
baa609db 4797 case MMI_OPC_DIV1:
c42171c3
FN
4798 {
4799 TCGv t2 = tcg_temp_new();
4800 TCGv t3 = tcg_temp_new();
4801 tcg_gen_ext32s_tl(t0, t0);
4802 tcg_gen_ext32s_tl(t1, t1);
4803 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4804 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4805 tcg_gen_and_tl(t2, t2, t3);
4806 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4807 tcg_gen_or_tl(t2, t2, t3);
4808 tcg_gen_movi_tl(t3, 0);
4809 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4810 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4811 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4812 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4813 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4814 tcg_temp_free(t3);
4815 tcg_temp_free(t2);
4816 }
4817 break;
baa609db 4818 case MMI_OPC_DIVU1:
c42171c3
FN
4819 {
4820 TCGv t2 = tcg_const_tl(0);
4821 TCGv t3 = tcg_const_tl(1);
4822 tcg_gen_ext32u_tl(t0, t0);
4823 tcg_gen_ext32u_tl(t1, t1);
4824 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4825 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4826 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4827 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4828 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4829 tcg_temp_free(t3);
4830 tcg_temp_free(t2);
4831 }
4832 break;
4833 default:
4834 MIPS_INVAL("div1 TX79");
4835 generate_exception_end(ctx, EXCP_RI);
4836 goto out;
4837 }
4838 out:
4839 tcg_temp_free(t0);
4840 tcg_temp_free(t1);
4841}
4842
26135ead
RS
4843static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4844 int acc, int rs, int rt)
6af0bf9c 4845{
d45f89f4
AJ
4846 TCGv t0, t1;
4847
51127181
AJ
4848 t0 = tcg_temp_new();
4849 t1 = tcg_temp_new();
6af0bf9c 4850
78723684
TS
4851 gen_load_gpr(t0, rs);
4852 gen_load_gpr(t1, rt);
51127181 4853
26135ead 4854 if (acc != 0) {
c42171c3 4855 check_dsp(ctx);
26135ead
RS
4856 }
4857
6af0bf9c
FB
4858 switch (opc) {
4859 case OPC_DIV:
48d38ca5 4860 {
51127181
AJ
4861 TCGv t2 = tcg_temp_new();
4862 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4863 tcg_gen_ext32s_tl(t0, t0);
4864 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4865 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4866 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4867 tcg_gen_and_tl(t2, t2, t3);
4868 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4869 tcg_gen_or_tl(t2, t2, t3);
4870 tcg_gen_movi_tl(t3, 0);
4871 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4872 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4873 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4874 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4875 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4876 tcg_temp_free(t3);
4877 tcg_temp_free(t2);
48d38ca5 4878 }
6af0bf9c
FB
4879 break;
4880 case OPC_DIVU:
48d38ca5 4881 {
51127181
AJ
4882 TCGv t2 = tcg_const_tl(0);
4883 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4884 tcg_gen_ext32u_tl(t0, t0);
4885 tcg_gen_ext32u_tl(t1, t1);
51127181 4886 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4887 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4888 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4889 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4890 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4891 tcg_temp_free(t3);
4892 tcg_temp_free(t2);
48d38ca5 4893 }
6af0bf9c
FB
4894 break;
4895 case OPC_MULT:
214c465f 4896 {
ce1dd5d1
RH
4897 TCGv_i32 t2 = tcg_temp_new_i32();
4898 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4899 tcg_gen_trunc_tl_i32(t2, t0);
4900 tcg_gen_trunc_tl_i32(t3, t1);
4901 tcg_gen_muls2_i32(t2, t3, t2, t3);
4902 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4903 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4904 tcg_temp_free_i32(t2);
4905 tcg_temp_free_i32(t3);
214c465f 4906 }
6af0bf9c
FB
4907 break;
4908 case OPC_MULTU:
214c465f 4909 {
ce1dd5d1
RH
4910 TCGv_i32 t2 = tcg_temp_new_i32();
4911 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4912 tcg_gen_trunc_tl_i32(t2, t0);
4913 tcg_gen_trunc_tl_i32(t3, t1);
4914 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4915 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4916 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4917 tcg_temp_free_i32(t2);
4918 tcg_temp_free_i32(t3);
214c465f 4919 }
6af0bf9c 4920 break;
d26bc211 4921#if defined(TARGET_MIPS64)
7a387fff 4922 case OPC_DDIV:
48d38ca5 4923 {
51127181
AJ
4924 TCGv t2 = tcg_temp_new();
4925 TCGv t3 = tcg_temp_new();
4926 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4927 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4928 tcg_gen_and_tl(t2, t2, t3);
4929 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4930 tcg_gen_or_tl(t2, t2, t3);
4931 tcg_gen_movi_tl(t3, 0);
4932 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4933 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4934 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4935 tcg_temp_free(t3);
4936 tcg_temp_free(t2);
48d38ca5 4937 }
7a387fff
TS
4938 break;
4939 case OPC_DDIVU:
48d38ca5 4940 {
51127181
AJ
4941 TCGv t2 = tcg_const_tl(0);
4942 TCGv t3 = tcg_const_tl(1);
4943 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4944 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4945 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4946 tcg_temp_free(t3);
4947 tcg_temp_free(t2);
48d38ca5 4948 }
7a387fff
TS
4949 break;
4950 case OPC_DMULT:
26135ead 4951 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4952 break;
4953 case OPC_DMULTU:
26135ead 4954 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4955 break;
4956#endif
6af0bf9c 4957 case OPC_MADD:
214c465f 4958 {
d45f89f4
AJ
4959 TCGv_i64 t2 = tcg_temp_new_i64();
4960 TCGv_i64 t3 = tcg_temp_new_i64();
4961
4962 tcg_gen_ext_tl_i64(t2, t0);
4963 tcg_gen_ext_tl_i64(t3, t1);
4964 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4965 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4966 tcg_gen_add_i64(t2, t2, t3);
4967 tcg_temp_free_i64(t3);
71f303cd
RH
4968 gen_move_low32(cpu_LO[acc], t2);
4969 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4970 tcg_temp_free_i64(t2);
214c465f 4971 }
6af0bf9c
FB
4972 break;
4973 case OPC_MADDU:
4133498f 4974 {
d45f89f4
AJ
4975 TCGv_i64 t2 = tcg_temp_new_i64();
4976 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4977
78723684
TS
4978 tcg_gen_ext32u_tl(t0, t0);
4979 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4980 tcg_gen_extu_tl_i64(t2, t0);
4981 tcg_gen_extu_tl_i64(t3, t1);
4982 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4983 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4984 tcg_gen_add_i64(t2, t2, t3);
4985 tcg_temp_free_i64(t3);
71f303cd
RH
4986 gen_move_low32(cpu_LO[acc], t2);
4987 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4988 tcg_temp_free_i64(t2);
214c465f 4989 }
6af0bf9c
FB
4990 break;
4991 case OPC_MSUB:
214c465f 4992 {
d45f89f4
AJ
4993 TCGv_i64 t2 = tcg_temp_new_i64();
4994 TCGv_i64 t3 = tcg_temp_new_i64();
4995
4996 tcg_gen_ext_tl_i64(t2, t0);
4997 tcg_gen_ext_tl_i64(t3, t1);
4998 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4999 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 5000 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 5001 tcg_temp_free_i64(t3);
71f303cd
RH
5002 gen_move_low32(cpu_LO[acc], t2);
5003 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 5004 tcg_temp_free_i64(t2);
214c465f 5005 }
6af0bf9c
FB
5006 break;
5007 case OPC_MSUBU:
214c465f 5008 {
d45f89f4
AJ
5009 TCGv_i64 t2 = tcg_temp_new_i64();
5010 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 5011
78723684
TS
5012 tcg_gen_ext32u_tl(t0, t0);
5013 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
5014 tcg_gen_extu_tl_i64(t2, t0);
5015 tcg_gen_extu_tl_i64(t3, t1);
5016 tcg_gen_mul_i64(t2, t2, t3);
4133498f 5017 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 5018 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 5019 tcg_temp_free_i64(t3);
71f303cd
RH
5020 gen_move_low32(cpu_LO[acc], t2);
5021 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 5022 tcg_temp_free_i64(t2);
214c465f 5023 }
6af0bf9c
FB
5024 break;
5025 default:
9d68ac14 5026 MIPS_INVAL("mul/div");
9c708c7f 5027 generate_exception_end(ctx, EXCP_RI);
78723684 5028 goto out;
6af0bf9c 5029 }
78723684
TS
5030 out:
5031 tcg_temp_free(t0);
5032 tcg_temp_free(t1);
6af0bf9c
FB
5033}
5034
21e8e8b2 5035/*
3b948f05
PMD
5036 * These MULT[U] and MADD[U] instructions implemented in for example
5037 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
21e8e8b2
FN
5038 * architectures are special three-operand variants with the syntax
5039 *
06de726b 5040 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
5041 *
5042 * such that
5043 *
5044 * (rd, LO, HI) <- rs * rt
5045 *
3b948f05
PMD
5046 * and
5047 *
a95c4c26 5048 * MADD[U][1] rd, rs, rt
3b948f05
PMD
5049 *
5050 * such that
5051 *
5052 * (rd, LO, HI) <- (LO, HI) + rs * rt
5053 *
21e8e8b2
FN
5054 * where the low-order 32-bits of the result is placed into both the
5055 * GPR rd and the special register LO. The high-order 32-bits of the
5056 * result is placed into the special register HI.
5057 *
5058 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5059 * which is the zero register that always reads as 0.
5060 */
5061static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5062 int rd, int rs, int rt)
5063{
5064 TCGv t0 = tcg_temp_new();
5065 TCGv t1 = tcg_temp_new();
5066 int acc = 0;
5067
5068 gen_load_gpr(t0, rs);
5069 gen_load_gpr(t1, rt);
5070
5071 switch (opc) {
baa609db 5072 case MMI_OPC_MULT1:
06de726b
FN
5073 acc = 1;
5074 /* Fall through */
21e8e8b2
FN
5075 case OPC_MULT:
5076 {
5077 TCGv_i32 t2 = tcg_temp_new_i32();
5078 TCGv_i32 t3 = tcg_temp_new_i32();
5079 tcg_gen_trunc_tl_i32(t2, t0);
5080 tcg_gen_trunc_tl_i32(t3, t1);
5081 tcg_gen_muls2_i32(t2, t3, t2, t3);
5082 if (rd) {
5083 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5084 }
5085 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5086 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5087 tcg_temp_free_i32(t2);
5088 tcg_temp_free_i32(t3);
5089 }
5090 break;
baa609db 5091 case MMI_OPC_MULTU1:
06de726b
FN
5092 acc = 1;
5093 /* Fall through */
21e8e8b2
FN
5094 case OPC_MULTU:
5095 {
5096 TCGv_i32 t2 = tcg_temp_new_i32();
5097 TCGv_i32 t3 = tcg_temp_new_i32();
5098 tcg_gen_trunc_tl_i32(t2, t0);
5099 tcg_gen_trunc_tl_i32(t3, t1);
5100 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5101 if (rd) {
5102 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5103 }
5104 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5105 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5106 tcg_temp_free_i32(t2);
5107 tcg_temp_free_i32(t3);
5108 }
5109 break;
a95c4c26
FN
5110 case MMI_OPC_MADD1:
5111 acc = 1;
5112 /* Fall through */
3b948f05
PMD
5113 case MMI_OPC_MADD:
5114 {
5115 TCGv_i64 t2 = tcg_temp_new_i64();
5116 TCGv_i64 t3 = tcg_temp_new_i64();
5117
5118 tcg_gen_ext_tl_i64(t2, t0);
5119 tcg_gen_ext_tl_i64(t3, t1);
5120 tcg_gen_mul_i64(t2, t2, t3);
5121 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5122 tcg_gen_add_i64(t2, t2, t3);
5123 tcg_temp_free_i64(t3);
5124 gen_move_low32(cpu_LO[acc], t2);
5125 gen_move_high32(cpu_HI[acc], t2);
5126 if (rd) {
5127 gen_move_low32(cpu_gpr[rd], t2);
5128 }
5129 tcg_temp_free_i64(t2);
5130 }
5131 break;
a95c4c26
FN
5132 case MMI_OPC_MADDU1:
5133 acc = 1;
5134 /* Fall through */
3b948f05
PMD
5135 case MMI_OPC_MADDU:
5136 {
5137 TCGv_i64 t2 = tcg_temp_new_i64();
5138 TCGv_i64 t3 = tcg_temp_new_i64();
5139
5140 tcg_gen_ext32u_tl(t0, t0);
5141 tcg_gen_ext32u_tl(t1, t1);
5142 tcg_gen_extu_tl_i64(t2, t0);
5143 tcg_gen_extu_tl_i64(t3, t1);
5144 tcg_gen_mul_i64(t2, t2, t3);
5145 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5146 tcg_gen_add_i64(t2, t2, t3);
5147 tcg_temp_free_i64(t3);
5148 gen_move_low32(cpu_LO[acc], t2);
5149 gen_move_high32(cpu_HI[acc], t2);
5150 if (rd) {
5151 gen_move_low32(cpu_gpr[rd], t2);
5152 }
5153 tcg_temp_free_i64(t2);
5154 }
5155 break;
21e8e8b2 5156 default:
3b948f05 5157 MIPS_INVAL("mul/madd TXx9");
21e8e8b2
FN
5158 generate_exception_end(ctx, EXCP_RI);
5159 goto out;
5160 }
5161
5162 out:
5163 tcg_temp_free(t0);
5164 tcg_temp_free(t1);
5165}
5166
e9c71dd1
TS
5167static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5168 int rd, int rs, int rt)
5169{
f157bfe1
AJ
5170 TCGv t0 = tcg_temp_new();
5171 TCGv t1 = tcg_temp_new();
e9c71dd1 5172
6c5c1e20
TS
5173 gen_load_gpr(t0, rs);
5174 gen_load_gpr(t1, rt);
e9c71dd1
TS
5175
5176 switch (opc) {
5177 case OPC_VR54XX_MULS:
895c2d04 5178 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 5179 break;
e9c71dd1 5180 case OPC_VR54XX_MULSU:
895c2d04 5181 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 5182 break;
e9c71dd1 5183 case OPC_VR54XX_MACC:
895c2d04 5184 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 5185 break;
e9c71dd1 5186 case OPC_VR54XX_MACCU:
895c2d04 5187 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 5188 break;
e9c71dd1 5189 case OPC_VR54XX_MSAC:
895c2d04 5190 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 5191 break;
e9c71dd1 5192 case OPC_VR54XX_MSACU:
895c2d04 5193 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 5194 break;
e9c71dd1 5195 case OPC_VR54XX_MULHI:
895c2d04 5196 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 5197 break;
e9c71dd1 5198 case OPC_VR54XX_MULHIU:
895c2d04 5199 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 5200 break;
e9c71dd1 5201 case OPC_VR54XX_MULSHI:
895c2d04 5202 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 5203 break;
e9c71dd1 5204 case OPC_VR54XX_MULSHIU:
895c2d04 5205 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 5206 break;
e9c71dd1 5207 case OPC_VR54XX_MACCHI:
895c2d04 5208 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 5209 break;
e9c71dd1 5210 case OPC_VR54XX_MACCHIU:
895c2d04 5211 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 5212 break;
e9c71dd1 5213 case OPC_VR54XX_MSACHI:
895c2d04 5214 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 5215 break;
e9c71dd1 5216 case OPC_VR54XX_MSACHIU:
895c2d04 5217 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 5218 break;
e9c71dd1
TS
5219 default:
5220 MIPS_INVAL("mul vr54xx");
9c708c7f 5221 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5222 goto out;
e9c71dd1 5223 }
6c5c1e20 5224 gen_store_gpr(t0, rd);
6c5c1e20
TS
5225
5226 out:
5227 tcg_temp_free(t0);
5228 tcg_temp_free(t1);
e9c71dd1
TS
5229}
5230
7a387fff 5231static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5232 int rd, int rs)
5233{
20e1fb52 5234 TCGv t0;
6c5c1e20 5235
6af0bf9c 5236 if (rd == 0) {
ead9360e 5237 /* Treat as NOP. */
20e1fb52 5238 return;
6af0bf9c 5239 }
1a0196c5 5240 t0 = cpu_gpr[rd];
6c5c1e20 5241 gen_load_gpr(t0, rs);
1a0196c5 5242
6af0bf9c
FB
5243 switch (opc) {
5244 case OPC_CLO:
4267d3e6 5245 case R6_OPC_CLO:
1a0196c5
RH
5246#if defined(TARGET_MIPS64)
5247 case OPC_DCLO:
5248 case R6_OPC_DCLO:
5249#endif
5250 tcg_gen_not_tl(t0, t0);
6af0bf9c 5251 break;
1a0196c5
RH
5252 }
5253
5254 switch (opc) {
5255 case OPC_CLO:
5256 case R6_OPC_CLO:
6af0bf9c 5257 case OPC_CLZ:
4267d3e6 5258 case R6_OPC_CLZ:
1a0196c5
RH
5259 tcg_gen_ext32u_tl(t0, t0);
5260 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5261 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 5262 break;
d26bc211 5263#if defined(TARGET_MIPS64)
7a387fff 5264 case OPC_DCLO:
4267d3e6 5265 case R6_OPC_DCLO:
7a387fff 5266 case OPC_DCLZ:
4267d3e6 5267 case R6_OPC_DCLZ:
1a0196c5 5268 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
5269 break;
5270#endif
6af0bf9c 5271 }
6af0bf9c
FB
5272}
5273
161f85e6 5274/* Godson integer instructions */
bd277fa1
RH
5275static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5276 int rd, int rs, int rt)
161f85e6 5277{
161f85e6
AJ
5278 TCGv t0, t1;
5279
5280 if (rd == 0) {
5281 /* Treat as NOP. */
161f85e6
AJ
5282 return;
5283 }
5284
5285 switch (opc) {
5286 case OPC_MULT_G_2E:
5287 case OPC_MULT_G_2F:
5288 case OPC_MULTU_G_2E:
5289 case OPC_MULTU_G_2F:
5290#if defined(TARGET_MIPS64)
5291 case OPC_DMULT_G_2E:
5292 case OPC_DMULT_G_2F:
5293 case OPC_DMULTU_G_2E:
5294 case OPC_DMULTU_G_2F:
5295#endif
5296 t0 = tcg_temp_new();
5297 t1 = tcg_temp_new();
5298 break;
5299 default:
5300 t0 = tcg_temp_local_new();
5301 t1 = tcg_temp_local_new();
5302 break;
5303 }
5304
5305 gen_load_gpr(t0, rs);
5306 gen_load_gpr(t1, rt);
5307
5308 switch (opc) {
5309 case OPC_MULT_G_2E:
5310 case OPC_MULT_G_2F:
5311 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5312 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5313 break;
5314 case OPC_MULTU_G_2E:
5315 case OPC_MULTU_G_2F:
5316 tcg_gen_ext32u_tl(t0, t0);
5317 tcg_gen_ext32u_tl(t1, t1);
5318 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5319 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5320 break;
5321 case OPC_DIV_G_2E:
5322 case OPC_DIV_G_2F:
5323 {
42a268c2
RH
5324 TCGLabel *l1 = gen_new_label();
5325 TCGLabel *l2 = gen_new_label();
5326 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5327 tcg_gen_ext32s_tl(t0, t0);
5328 tcg_gen_ext32s_tl(t1, t1);
5329 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5330 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5331 tcg_gen_br(l3);
5332 gen_set_label(l1);
5333 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5334 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5335 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5336 tcg_gen_br(l3);
5337 gen_set_label(l2);
5338 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5339 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5340 gen_set_label(l3);
5341 }
161f85e6
AJ
5342 break;
5343 case OPC_DIVU_G_2E:
5344 case OPC_DIVU_G_2F:
5345 {
42a268c2
RH
5346 TCGLabel *l1 = gen_new_label();
5347 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5348 tcg_gen_ext32u_tl(t0, t0);
5349 tcg_gen_ext32u_tl(t1, t1);
5350 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5351 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5352 tcg_gen_br(l2);
5353 gen_set_label(l1);
5354 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5355 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5356 gen_set_label(l2);
5357 }
161f85e6
AJ
5358 break;
5359 case OPC_MOD_G_2E:
5360 case OPC_MOD_G_2F:
5361 {
42a268c2
RH
5362 TCGLabel *l1 = gen_new_label();
5363 TCGLabel *l2 = gen_new_label();
5364 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5365 tcg_gen_ext32u_tl(t0, t0);
5366 tcg_gen_ext32u_tl(t1, t1);
5367 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5368 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5369 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5370 gen_set_label(l1);
5371 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5372 tcg_gen_br(l3);
5373 gen_set_label(l2);
5374 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5375 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5376 gen_set_label(l3);
5377 }
161f85e6
AJ
5378 break;
5379 case OPC_MODU_G_2E:
5380 case OPC_MODU_G_2F:
5381 {
42a268c2
RH
5382 TCGLabel *l1 = gen_new_label();
5383 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5384 tcg_gen_ext32u_tl(t0, t0);
5385 tcg_gen_ext32u_tl(t1, t1);
5386 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5387 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5388 tcg_gen_br(l2);
5389 gen_set_label(l1);
5390 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5391 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5392 gen_set_label(l2);
5393 }
161f85e6
AJ
5394 break;
5395#if defined(TARGET_MIPS64)
5396 case OPC_DMULT_G_2E:
5397 case OPC_DMULT_G_2F:
5398 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5399 break;
5400 case OPC_DMULTU_G_2E:
5401 case OPC_DMULTU_G_2F:
5402 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5403 break;
5404 case OPC_DDIV_G_2E:
5405 case OPC_DDIV_G_2F:
5406 {
42a268c2
RH
5407 TCGLabel *l1 = gen_new_label();
5408 TCGLabel *l2 = gen_new_label();
5409 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5410 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5411 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5412 tcg_gen_br(l3);
5413 gen_set_label(l1);
5414 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5415 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5416 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5417 tcg_gen_br(l3);
5418 gen_set_label(l2);
5419 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5420 gen_set_label(l3);
5421 }
161f85e6
AJ
5422 break;
5423 case OPC_DDIVU_G_2E:
5424 case OPC_DDIVU_G_2F:
5425 {
42a268c2
RH
5426 TCGLabel *l1 = gen_new_label();
5427 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5428 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5429 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5430 tcg_gen_br(l2);
5431 gen_set_label(l1);
5432 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5433 gen_set_label(l2);
5434 }
161f85e6
AJ
5435 break;
5436 case OPC_DMOD_G_2E:
5437 case OPC_DMOD_G_2F:
5438 {
42a268c2
RH
5439 TCGLabel *l1 = gen_new_label();
5440 TCGLabel *l2 = gen_new_label();
5441 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5442 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5443 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5444 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5445 gen_set_label(l1);
5446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5447 tcg_gen_br(l3);
5448 gen_set_label(l2);
5449 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5450 gen_set_label(l3);
5451 }
161f85e6
AJ
5452 break;
5453 case OPC_DMODU_G_2E:
5454 case OPC_DMODU_G_2F:
5455 {
42a268c2
RH
5456 TCGLabel *l1 = gen_new_label();
5457 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5458 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5459 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5460 tcg_gen_br(l2);
5461 gen_set_label(l1);
5462 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5463 gen_set_label(l2);
5464 }
161f85e6
AJ
5465 break;
5466#endif
5467 }
5468
161f85e6
AJ
5469 tcg_temp_free(t0);
5470 tcg_temp_free(t1);
5471}
5472
bd277fa1
RH
5473/* Loongson multimedia instructions */
5474static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5475{
bd277fa1
RH
5476 uint32_t opc, shift_max;
5477 TCGv_i64 t0, t1;
5478
5479 opc = MASK_LMI(ctx->opcode);
5480 switch (opc) {
5481 case OPC_ADD_CP2:
5482 case OPC_SUB_CP2:
5483 case OPC_DADD_CP2:
5484 case OPC_DSUB_CP2:
5485 t0 = tcg_temp_local_new_i64();
5486 t1 = tcg_temp_local_new_i64();
5487 break;
5488 default:
5489 t0 = tcg_temp_new_i64();
5490 t1 = tcg_temp_new_i64();
5491 break;
5492 }
5493
b5a587b6 5494 check_cp1_enabled(ctx);
bd277fa1
RH
5495 gen_load_fpr64(ctx, t0, rs);
5496 gen_load_fpr64(ctx, t1, rt);
5497
5498#define LMI_HELPER(UP, LO) \
9d68ac14 5499 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 5500#define LMI_HELPER_1(UP, LO) \
9d68ac14 5501 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 5502#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 5503 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
5504
5505 switch (opc) {
5506 LMI_HELPER(PADDSH, paddsh);
5507 LMI_HELPER(PADDUSH, paddush);
5508 LMI_HELPER(PADDH, paddh);
5509 LMI_HELPER(PADDW, paddw);
5510 LMI_HELPER(PADDSB, paddsb);
5511 LMI_HELPER(PADDUSB, paddusb);
5512 LMI_HELPER(PADDB, paddb);
5513
5514 LMI_HELPER(PSUBSH, psubsh);
5515 LMI_HELPER(PSUBUSH, psubush);
5516 LMI_HELPER(PSUBH, psubh);
5517 LMI_HELPER(PSUBW, psubw);
5518 LMI_HELPER(PSUBSB, psubsb);
5519 LMI_HELPER(PSUBUSB, psubusb);
5520 LMI_HELPER(PSUBB, psubb);
5521
5522 LMI_HELPER(PSHUFH, pshufh);
5523 LMI_HELPER(PACKSSWH, packsswh);
5524 LMI_HELPER(PACKSSHB, packsshb);
5525 LMI_HELPER(PACKUSHB, packushb);
5526
5527 LMI_HELPER(PUNPCKLHW, punpcklhw);
5528 LMI_HELPER(PUNPCKHHW, punpckhhw);
5529 LMI_HELPER(PUNPCKLBH, punpcklbh);
5530 LMI_HELPER(PUNPCKHBH, punpckhbh);
5531 LMI_HELPER(PUNPCKLWD, punpcklwd);
5532 LMI_HELPER(PUNPCKHWD, punpckhwd);
5533
5534 LMI_HELPER(PAVGH, pavgh);
5535 LMI_HELPER(PAVGB, pavgb);
5536 LMI_HELPER(PMAXSH, pmaxsh);
5537 LMI_HELPER(PMINSH, pminsh);
5538 LMI_HELPER(PMAXUB, pmaxub);
5539 LMI_HELPER(PMINUB, pminub);
5540
5541 LMI_HELPER(PCMPEQW, pcmpeqw);
5542 LMI_HELPER(PCMPGTW, pcmpgtw);
5543 LMI_HELPER(PCMPEQH, pcmpeqh);
5544 LMI_HELPER(PCMPGTH, pcmpgth);
5545 LMI_HELPER(PCMPEQB, pcmpeqb);
5546 LMI_HELPER(PCMPGTB, pcmpgtb);
5547
5548 LMI_HELPER(PSLLW, psllw);
5549 LMI_HELPER(PSLLH, psllh);
5550 LMI_HELPER(PSRLW, psrlw);
5551 LMI_HELPER(PSRLH, psrlh);
5552 LMI_HELPER(PSRAW, psraw);
5553 LMI_HELPER(PSRAH, psrah);
5554
5555 LMI_HELPER(PMULLH, pmullh);
5556 LMI_HELPER(PMULHH, pmulhh);
5557 LMI_HELPER(PMULHUH, pmulhuh);
5558 LMI_HELPER(PMADDHW, pmaddhw);
5559
5560 LMI_HELPER(PASUBUB, pasubub);
5561 LMI_HELPER_1(BIADD, biadd);
5562 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5563
5564 LMI_DIRECT(PADDD, paddd, add);
5565 LMI_DIRECT(PSUBD, psubd, sub);
5566 LMI_DIRECT(XOR_CP2, xor, xor);
5567 LMI_DIRECT(NOR_CP2, nor, nor);
5568 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 5569 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 5570
9099a36b
H
5571 case OPC_PANDN:
5572 tcg_gen_andc_i64(t0, t1, t0);
5573 break;
5574
bd277fa1
RH
5575 case OPC_PINSRH_0:
5576 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
5577 break;
5578 case OPC_PINSRH_1:
5579 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
5580 break;
5581 case OPC_PINSRH_2:
5582 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
5583 break;
5584 case OPC_PINSRH_3:
5585 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
5586 break;
5587
5588 case OPC_PEXTRH:
5589 tcg_gen_andi_i64(t1, t1, 3);
5590 tcg_gen_shli_i64(t1, t1, 4);
5591 tcg_gen_shr_i64(t0, t0, t1);
5592 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
5593 break;
5594
5595 case OPC_ADDU_CP2:
5596 tcg_gen_add_i64(t0, t0, t1);
5597 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5598 break;
5599 case OPC_SUBU_CP2:
5600 tcg_gen_sub_i64(t0, t0, t1);
5601 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5602 break;
5603
5604 case OPC_SLL_CP2:
bd277fa1
RH
5605 shift_max = 32;
5606 goto do_shift;
5607 case OPC_SRL_CP2:
bd277fa1
RH
5608 shift_max = 32;
5609 goto do_shift;
5610 case OPC_SRA_CP2:
bd277fa1
RH
5611 shift_max = 32;
5612 goto do_shift;
5613 case OPC_DSLL_CP2:
bd277fa1
RH
5614 shift_max = 64;
5615 goto do_shift;
5616 case OPC_DSRL_CP2:
bd277fa1
RH
5617 shift_max = 64;
5618 goto do_shift;
5619 case OPC_DSRA_CP2:
bd277fa1
RH
5620 shift_max = 64;
5621 goto do_shift;
5622 do_shift:
5623 /* Make sure shift count isn't TCG undefined behaviour. */
5624 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5625
5626 switch (opc) {
5627 case OPC_SLL_CP2:
5628 case OPC_DSLL_CP2:
5629 tcg_gen_shl_i64(t0, t0, t1);
5630 break;
5631 case OPC_SRA_CP2:
5632 case OPC_DSRA_CP2:
5633 /* Since SRA is UndefinedResult without sign-extended inputs,
5634 we can treat SRA and DSRA the same. */
5635 tcg_gen_sar_i64(t0, t0, t1);
5636 break;
5637 case OPC_SRL_CP2:
5638 /* We want to shift in zeros for SRL; zero-extend first. */
5639 tcg_gen_ext32u_i64(t0, t0);
5640 /* FALLTHRU */
5641 case OPC_DSRL_CP2:
5642 tcg_gen_shr_i64(t0, t0, t1);
5643 break;
5644 }
5645
5646 if (shift_max == 32) {
5647 tcg_gen_ext32s_i64(t0, t0);
5648 }
5649
5650 /* Shifts larger than MAX produce zero. */
5651 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5652 tcg_gen_neg_i64(t1, t1);
5653 tcg_gen_and_i64(t0, t0, t1);
5654 break;
5655
5656 case OPC_ADD_CP2:
5657 case OPC_DADD_CP2:
5658 {
5659 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5660 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5661
5662 tcg_gen_mov_i64(t2, t0);
5663 tcg_gen_add_i64(t0, t1, t2);
5664 if (opc == OPC_ADD_CP2) {
5665 tcg_gen_ext32s_i64(t0, t0);
5666 }
5667 tcg_gen_xor_i64(t1, t1, t2);
5668 tcg_gen_xor_i64(t2, t2, t0);
5669 tcg_gen_andc_i64(t1, t2, t1);
5670 tcg_temp_free_i64(t2);
5671 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5672 generate_exception(ctx, EXCP_OVERFLOW);
5673 gen_set_label(lab);
bd277fa1
RH
5674 break;
5675 }
5676
5677 case OPC_SUB_CP2:
5678 case OPC_DSUB_CP2:
5679 {
5680 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5681 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5682
5683 tcg_gen_mov_i64(t2, t0);
5684 tcg_gen_sub_i64(t0, t1, t2);
5685 if (opc == OPC_SUB_CP2) {
5686 tcg_gen_ext32s_i64(t0, t0);
5687 }
5688 tcg_gen_xor_i64(t1, t1, t2);
5689 tcg_gen_xor_i64(t2, t2, t0);
5690 tcg_gen_and_i64(t1, t1, t2);
5691 tcg_temp_free_i64(t2);
5692 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5693 generate_exception(ctx, EXCP_OVERFLOW);
5694 gen_set_label(lab);
bd277fa1
RH
5695 break;
5696 }
5697
5698 case OPC_PMULUW:
5699 tcg_gen_ext32u_i64(t0, t0);
5700 tcg_gen_ext32u_i64(t1, t1);
5701 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
5702 break;
5703
5704 case OPC_SEQU_CP2:
5705 case OPC_SEQ_CP2:
5706 case OPC_SLTU_CP2:
5707 case OPC_SLT_CP2:
5708 case OPC_SLEU_CP2:
5709 case OPC_SLE_CP2:
5710 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5711 FD field is the CC field? */
5712 default:
9d68ac14 5713 MIPS_INVAL("loongson_cp2");
9c708c7f 5714 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
5715 return;
5716 }
5717
5718#undef LMI_HELPER
5719#undef LMI_DIRECT
5720
5721 gen_store_fpr64(ctx, t0, rd);
5722
bd277fa1
RH
5723 tcg_temp_free_i64(t0);
5724 tcg_temp_free_i64(t1);
5725}
5726
6af0bf9c 5727/* Traps */
7a387fff 5728static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5729 int rs, int rt, int16_t imm)
5730{
5731 int cond;
cdc0faa6 5732 TCGv t0 = tcg_temp_new();
1ba74fb8 5733 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
5734
5735 cond = 0;
5736 /* Load needed operands */
5737 switch (opc) {
5738 case OPC_TEQ:
5739 case OPC_TGE:
5740 case OPC_TGEU:
5741 case OPC_TLT:
5742 case OPC_TLTU:
5743 case OPC_TNE:
5744 /* Compare two registers */
5745 if (rs != rt) {
be24bb4f
TS
5746 gen_load_gpr(t0, rs);
5747 gen_load_gpr(t1, rt);
6af0bf9c
FB
5748 cond = 1;
5749 }
179e32bb 5750 break;
6af0bf9c
FB
5751 case OPC_TEQI:
5752 case OPC_TGEI:
5753 case OPC_TGEIU:
5754 case OPC_TLTI:
5755 case OPC_TLTIU:
5756 case OPC_TNEI:
5757 /* Compare register to immediate */
5758 if (rs != 0 || imm != 0) {
be24bb4f
TS
5759 gen_load_gpr(t0, rs);
5760 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
5761 cond = 1;
5762 }
5763 break;
5764 }
5765 if (cond == 0) {
5766 switch (opc) {
5767 case OPC_TEQ: /* rs == rs */
5768 case OPC_TEQI: /* r0 == 0 */
5769 case OPC_TGE: /* rs >= rs */
5770 case OPC_TGEI: /* r0 >= 0 */
5771 case OPC_TGEU: /* rs >= rs unsigned */
5772 case OPC_TGEIU: /* r0 >= 0 unsigned */
5773 /* Always trap */
9c708c7f 5774 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
5775 break;
5776 case OPC_TLT: /* rs < rs */
5777 case OPC_TLTI: /* r0 < 0 */
5778 case OPC_TLTU: /* rs < rs unsigned */
5779 case OPC_TLTIU: /* r0 < 0 unsigned */
5780 case OPC_TNE: /* rs != rs */
5781 case OPC_TNEI: /* r0 != 0 */
ead9360e 5782 /* Never trap: treat as NOP. */
cdc0faa6 5783 break;
6af0bf9c
FB
5784 }
5785 } else {
42a268c2 5786 TCGLabel *l1 = gen_new_label();
cdc0faa6 5787
6af0bf9c
FB
5788 switch (opc) {
5789 case OPC_TEQ:
5790 case OPC_TEQI:
cdc0faa6 5791 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
5792 break;
5793 case OPC_TGE:
5794 case OPC_TGEI:
cdc0faa6 5795 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
5796 break;
5797 case OPC_TGEU:
5798 case OPC_TGEIU:
cdc0faa6 5799 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
5800 break;
5801 case OPC_TLT:
5802 case OPC_TLTI:
cdc0faa6 5803 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
5804 break;
5805 case OPC_TLTU:
5806 case OPC_TLTIU:
cdc0faa6 5807 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
5808 break;
5809 case OPC_TNE:
5810 case OPC_TNEI:
cdc0faa6 5811 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 5812 break;
6af0bf9c 5813 }
cdc0faa6 5814 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
5815 gen_set_label(l1);
5816 }
be24bb4f
TS
5817 tcg_temp_free(t0);
5818 tcg_temp_free(t1);
6af0bf9c
FB
5819}
5820
90aa39a1
SF
5821static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5822{
eeb3bba8 5823 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
5824 return false;
5825 }
5826
5827#ifndef CONFIG_USER_ONLY
eeb3bba8 5828 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
5829#else
5830 return true;
5831#endif
5832}
5833
356265ae 5834static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 5835{
90aa39a1 5836 if (use_goto_tb(ctx, dest)) {
57fec1fe 5837 tcg_gen_goto_tb(n);
9b9e4393 5838 gen_save_pc(dest);
07ea28b4 5839 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 5840 } else {
9b9e4393 5841 gen_save_pc(dest);
eeb3bba8 5842 if (ctx->base.singlestep_enabled) {
7b270ef2 5843 save_cpu_state(ctx, 0);
9c708c7f 5844 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 5845 }
7f11636d 5846 tcg_gen_lookup_and_goto_ptr();
6e256c93 5847 }
c53be334
FB
5848}
5849
6af0bf9c 5850/* Branches (before delay slot) */
7a387fff 5851static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 5852 int insn_bytes,
b231c103
YK
5853 int rs, int rt, int32_t offset,
5854 int delayslot_size)
6af0bf9c 5855{
d077b6f7 5856 target_ulong btgt = -1;
3ad4bb2d 5857 int blink = 0;
2fdbad25 5858 int bcond_compute = 0;
1ba74fb8
AJ
5859 TCGv t0 = tcg_temp_new();
5860 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
5861
5862 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 5863#ifdef MIPS_DEBUG_DISAS
339cd2a8 5864 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 5865 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 5866#endif
9c708c7f 5867 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5868 goto out;
3ad4bb2d 5869 }
6af0bf9c 5870
6af0bf9c
FB
5871 /* Load needed operands */
5872 switch (opc) {
5873 case OPC_BEQ:
5874 case OPC_BEQL:
5875 case OPC_BNE:
5876 case OPC_BNEL:
5877 /* Compare two registers */
5878 if (rs != rt) {
6c5c1e20
TS
5879 gen_load_gpr(t0, rs);
5880 gen_load_gpr(t1, rt);
2fdbad25 5881 bcond_compute = 1;
6af0bf9c 5882 }
eeb3bba8 5883 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
5884 break;
5885 case OPC_BGEZ:
5886 case OPC_BGEZAL:
5887 case OPC_BGEZALL:
5888 case OPC_BGEZL:
5889 case OPC_BGTZ:
5890 case OPC_BGTZL:
5891 case OPC_BLEZ:
5892 case OPC_BLEZL:
5893 case OPC_BLTZ:
5894 case OPC_BLTZAL:
5895 case OPC_BLTZALL:
5896 case OPC_BLTZL:
5897 /* Compare to zero */
5898 if (rs != 0) {
6c5c1e20 5899 gen_load_gpr(t0, rs);
2fdbad25 5900 bcond_compute = 1;
6af0bf9c 5901 }
eeb3bba8 5902 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 5903 break;
e45a93e2
JL
5904 case OPC_BPOSGE32:
5905#if defined(TARGET_MIPS64)
5906 case OPC_BPOSGE64:
5907 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5908#else
5909 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5910#endif
5911 bcond_compute = 1;
eeb3bba8 5912 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 5913 break;
6af0bf9c
FB
5914 case OPC_J:
5915 case OPC_JAL:
364d4831 5916 case OPC_JALX:
6af0bf9c 5917 /* Jump to immediate */
eeb3bba8
EC
5918 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5919 (uint32_t)offset;
6af0bf9c
FB
5920 break;
5921 case OPC_JR:
5922 case OPC_JALR:
5923 /* Jump to register */
7a387fff
TS
5924 if (offset != 0 && offset != 16) {
5925 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 5926 others are reserved. */
923617a3 5927 MIPS_INVAL("jump hint");
9c708c7f 5928 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5929 goto out;
6af0bf9c 5930 }
d077b6f7 5931 gen_load_gpr(btarget, rs);
6af0bf9c
FB
5932 break;
5933 default:
5934 MIPS_INVAL("branch/jump");
9c708c7f 5935 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5936 goto out;
6af0bf9c 5937 }
2fdbad25 5938 if (bcond_compute == 0) {
6af0bf9c
FB
5939 /* No condition to be computed */
5940 switch (opc) {
5941 case OPC_BEQ: /* rx == rx */
5942 case OPC_BEQL: /* rx == rx likely */
5943 case OPC_BGEZ: /* 0 >= 0 */
5944 case OPC_BGEZL: /* 0 >= 0 likely */
5945 case OPC_BLEZ: /* 0 <= 0 */
5946 case OPC_BLEZL: /* 0 <= 0 likely */
5947 /* Always take */
4ad40f36 5948 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5949 break;
5950 case OPC_BGEZAL: /* 0 >= 0 */
5951 case OPC_BGEZALL: /* 0 >= 0 likely */
5952 /* Always take and link */
5953 blink = 31;
4ad40f36 5954 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5955 break;
5956 case OPC_BNE: /* rx != rx */
5957 case OPC_BGTZ: /* 0 > 0 */
5958 case OPC_BLTZ: /* 0 < 0 */
ead9360e 5959 /* Treat as NOP. */
6c5c1e20 5960 goto out;
eeef26cd 5961 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
5962 /* Handle as an unconditional branch to get correct delay
5963 slot checking. */
5964 blink = 31;
eeb3bba8 5965 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 5966 ctx->hflags |= MIPS_HFLAG_B;
3c824109 5967 break;
eeef26cd 5968 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 5969 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 5970 /* Skip the instruction in the delay slot */
eeb3bba8 5971 ctx->base.pc_next += 4;
6c5c1e20 5972 goto out;
6af0bf9c
FB
5973 case OPC_BNEL: /* rx != rx likely */
5974 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
5975 case OPC_BLTZL: /* 0 < 0 likely */
5976 /* Skip the instruction in the delay slot */
eeb3bba8 5977 ctx->base.pc_next += 4;
6c5c1e20 5978 goto out;
6af0bf9c 5979 case OPC_J:
4ad40f36 5980 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5981 break;
364d4831
NF
5982 case OPC_JALX:
5983 ctx->hflags |= MIPS_HFLAG_BX;
5984 /* Fallthrough */
6af0bf9c
FB
5985 case OPC_JAL:
5986 blink = 31;
4ad40f36 5987 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5988 break;
5989 case OPC_JR:
4ad40f36 5990 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5991 break;
5992 case OPC_JALR:
5993 blink = rt;
4ad40f36 5994 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5995 break;
5996 default:
5997 MIPS_INVAL("branch/jump");
9c708c7f 5998 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5999 goto out;
6af0bf9c
FB
6000 }
6001 } else {
6002 switch (opc) {
6003 case OPC_BEQ:
e68dd28f 6004 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
6005 goto not_likely;
6006 case OPC_BEQL:
e68dd28f 6007 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
6008 goto likely;
6009 case OPC_BNE:
e68dd28f 6010 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
6011 goto not_likely;
6012 case OPC_BNEL:
e68dd28f 6013 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
6014 goto likely;
6015 case OPC_BGEZ:
e68dd28f 6016 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6017 goto not_likely;
6018 case OPC_BGEZL:
e68dd28f 6019 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6020 goto likely;
6021 case OPC_BGEZAL:
e68dd28f 6022 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
6023 blink = 31;
6024 goto not_likely;
6025 case OPC_BGEZALL:
e68dd28f 6026 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 6027 blink = 31;
6af0bf9c
FB
6028 goto likely;
6029 case OPC_BGTZ:
e68dd28f 6030 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
6031 goto not_likely;
6032 case OPC_BGTZL:
e68dd28f 6033 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
6034 goto likely;
6035 case OPC_BLEZ:
e68dd28f 6036 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
6037 goto not_likely;
6038 case OPC_BLEZL:
e68dd28f 6039 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
6040 goto likely;
6041 case OPC_BLTZ:
e68dd28f 6042 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
6043 goto not_likely;
6044 case OPC_BLTZL:
e68dd28f 6045 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6046 goto likely;
e45a93e2
JL
6047 case OPC_BPOSGE32:
6048 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
6049 goto not_likely;
6050#if defined(TARGET_MIPS64)
6051 case OPC_BPOSGE64:
6052 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
6053 goto not_likely;
6054#endif
6af0bf9c 6055 case OPC_BLTZAL:
e68dd28f 6056 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6057 blink = 31;
6af0bf9c 6058 not_likely:
4ad40f36 6059 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
6060 break;
6061 case OPC_BLTZALL:
e68dd28f 6062 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 6063 blink = 31;
6af0bf9c 6064 likely:
4ad40f36 6065 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 6066 break;
c53f4a62
TS
6067 default:
6068 MIPS_INVAL("conditional branch/jump");
9c708c7f 6069 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 6070 goto out;
6af0bf9c 6071 }
6af0bf9c 6072 }
9b9e4393 6073
d077b6f7 6074 ctx->btarget = btgt;
b231c103
YK
6075
6076 switch (delayslot_size) {
6077 case 2:
6078 ctx->hflags |= MIPS_HFLAG_BDS16;
6079 break;
6080 case 4:
6081 ctx->hflags |= MIPS_HFLAG_BDS32;
6082 break;
6083 }
6084
6af0bf9c 6085 if (blink > 0) {
b231c103 6086 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
6087 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6088
eeb3bba8
EC
6089 tcg_gen_movi_tl(cpu_gpr[blink],
6090 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 6091 }
6c5c1e20
TS
6092
6093 out:
364d4831
NF
6094 if (insn_bytes == 2)
6095 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
6096 tcg_temp_free(t0);
6097 tcg_temp_free(t1);
6af0bf9c
FB
6098}
6099
764371d2
SM
6100
6101/* nanoMIPS Branches */
6102static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6103 int insn_bytes,
6104 int rs, int rt, int32_t offset)
6105{
6106 target_ulong btgt = -1;
6107 int bcond_compute = 0;
6108 TCGv t0 = tcg_temp_new();
6109 TCGv t1 = tcg_temp_new();
6110
6111 /* Load needed operands */
6112 switch (opc) {
6113 case OPC_BEQ:
6114 case OPC_BNE:
6115 /* Compare two registers */
6116 if (rs != rt) {
6117 gen_load_gpr(t0, rs);
6118 gen_load_gpr(t1, rt);
6119 bcond_compute = 1;
6120 }
6121 btgt = ctx->base.pc_next + insn_bytes + offset;
6122 break;
6123 case OPC_BGEZAL:
6124 /* Compare to zero */
6125 if (rs != 0) {
6126 gen_load_gpr(t0, rs);
6127 bcond_compute = 1;
6128 }
6129 btgt = ctx->base.pc_next + insn_bytes + offset;
6130 break;
6131 case OPC_BPOSGE32:
6132 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6133 bcond_compute = 1;
6134 btgt = ctx->base.pc_next + insn_bytes + offset;
6135 break;
6136 case OPC_JR:
6137 case OPC_JALR:
6138 /* Jump to register */
6139 if (offset != 0 && offset != 16) {
6140 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6141 others are reserved. */
6142 MIPS_INVAL("jump hint");
6143 generate_exception_end(ctx, EXCP_RI);
6144 goto out;
6145 }
6146 gen_load_gpr(btarget, rs);
6147 break;
6148 default:
6149 MIPS_INVAL("branch/jump");
6150 generate_exception_end(ctx, EXCP_RI);
6151 goto out;
6152 }
6153 if (bcond_compute == 0) {
6154 /* No condition to be computed */
6155 switch (opc) {
6156 case OPC_BEQ: /* rx == rx */
6157 /* Always take */
6158 ctx->hflags |= MIPS_HFLAG_B;
6159 break;
6160 case OPC_BGEZAL: /* 0 >= 0 */
6161 /* Always take and link */
6162 tcg_gen_movi_tl(cpu_gpr[31],
6163 ctx->base.pc_next + insn_bytes);
6164 ctx->hflags |= MIPS_HFLAG_B;
6165 break;
6166 case OPC_BNE: /* rx != rx */
6167 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6168 /* Skip the instruction in the delay slot */
6169 ctx->base.pc_next += 4;
6170 goto out;
6171 case OPC_JR:
6172 ctx->hflags |= MIPS_HFLAG_BR;
6173 break;
6174 case OPC_JALR:
6175 if (rt > 0) {
6176 tcg_gen_movi_tl(cpu_gpr[rt],
6177 ctx->base.pc_next + insn_bytes);
6178 }
6179 ctx->hflags |= MIPS_HFLAG_BR;
6180 break;
6181 default:
6182 MIPS_INVAL("branch/jump");
6183 generate_exception_end(ctx, EXCP_RI);
6184 goto out;
6185 }
6186 } else {
6187 switch (opc) {
6188 case OPC_BEQ:
6189 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6190 goto not_likely;
6191 case OPC_BNE:
6192 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6193 goto not_likely;
6194 case OPC_BGEZAL:
6195 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6196 tcg_gen_movi_tl(cpu_gpr[31],
6197 ctx->base.pc_next + insn_bytes);
6198 goto not_likely;
6199 case OPC_BPOSGE32:
6200 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6201 not_likely:
6202 ctx->hflags |= MIPS_HFLAG_BC;
6203 break;
6204 default:
6205 MIPS_INVAL("conditional branch/jump");
6206 generate_exception_end(ctx, EXCP_RI);
6207 goto out;
6208 }
6209 }
6210
6211 ctx->btarget = btgt;
6212
6213 out:
6214 if (insn_bytes == 2) {
6215 ctx->hflags |= MIPS_HFLAG_B16;
6216 }
6217 tcg_temp_free(t0);
6218 tcg_temp_free(t1);
6219}
6220
6221
7a387fff
TS
6222/* special3 bitfield operations */
6223static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 6224 int rs, int lsb, int msb)
7a387fff 6225{
a7812ae4
PB
6226 TCGv t0 = tcg_temp_new();
6227 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
6228
6229 gen_load_gpr(t1, rs);
7a387fff
TS
6230 switch (opc) {
6231 case OPC_EXT:
b7f26e52 6232 if (lsb + msb > 31) {
7a387fff 6233 goto fail;
b7f26e52 6234 }
505ad7c2 6235 if (msb != 31) {
6eebb7a4 6236 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 6237 } else {
6eebb7a4
RH
6238 /* The two checks together imply that lsb == 0,
6239 so this is a simple sign-extension. */
6240 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 6241 }
7a387fff 6242 break;
c6d6dd7c 6243#if defined(TARGET_MIPS64)
7a387fff 6244 case OPC_DEXTU:
b7f26e52
RH
6245 lsb += 32;
6246 goto do_dext;
6247 case OPC_DEXTM:
6248 msb += 32;
6249 goto do_dext;
7a387fff 6250 case OPC_DEXT:
b7f26e52
RH
6251 do_dext:
6252 if (lsb + msb > 63) {
6253 goto fail;
6254 }
6eebb7a4 6255 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 6256 break;
c6d6dd7c 6257#endif
7a387fff 6258 case OPC_INS:
b7f26e52 6259 if (lsb > msb) {
7a387fff 6260 goto fail;
b7f26e52 6261 }
6c5c1e20 6262 gen_load_gpr(t0, rt);
e0d002f1 6263 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 6264 tcg_gen_ext32s_tl(t0, t0);
7a387fff 6265 break;
c6d6dd7c 6266#if defined(TARGET_MIPS64)
7a387fff 6267 case OPC_DINSU:
b7f26e52
RH
6268 lsb += 32;
6269 /* FALLTHRU */
6270 case OPC_DINSM:
6271 msb += 32;
6272 /* FALLTHRU */
7a387fff 6273 case OPC_DINS:
b7f26e52
RH
6274 if (lsb > msb) {
6275 goto fail;
6276 }
6c5c1e20 6277 gen_load_gpr(t0, rt);
e0d002f1 6278 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 6279 break;
c6d6dd7c 6280#endif
7a387fff
TS
6281 default:
6282fail:
6283 MIPS_INVAL("bitops");
9c708c7f 6284 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
6285 tcg_temp_free(t0);
6286 tcg_temp_free(t1);
7a387fff
TS
6287 return;
6288 }
6c5c1e20
TS
6289 gen_store_gpr(t0, rt);
6290 tcg_temp_free(t0);
6291 tcg_temp_free(t1);
7a387fff
TS
6292}
6293
49bcf33c
AJ
6294static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6295{
3a55fa47 6296 TCGv t0;
49bcf33c 6297
3a55fa47
AJ
6298 if (rd == 0) {
6299 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
6300 return;
6301 }
6302
6303 t0 = tcg_temp_new();
6304 gen_load_gpr(t0, rt);
49bcf33c
AJ
6305 switch (op2) {
6306 case OPC_WSBH:
3a55fa47
AJ
6307 {
6308 TCGv t1 = tcg_temp_new();
06a57e5c 6309 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
6310
6311 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6312 tcg_gen_and_tl(t1, t1, t2);
6313 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6314 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6315 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 6316 tcg_temp_free(t2);
3a55fa47
AJ
6317 tcg_temp_free(t1);
6318 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6319 }
49bcf33c
AJ
6320 break;
6321 case OPC_SEB:
3a55fa47 6322 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6323 break;
6324 case OPC_SEH:
3a55fa47 6325 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6326 break;
6327#if defined(TARGET_MIPS64)
6328 case OPC_DSBH:
3a55fa47
AJ
6329 {
6330 TCGv t1 = tcg_temp_new();
06a57e5c 6331 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
6332
6333 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6334 tcg_gen_and_tl(t1, t1, t2);
6335 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6336 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6337 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6338 tcg_temp_free(t2);
3a55fa47
AJ
6339 tcg_temp_free(t1);
6340 }
49bcf33c
AJ
6341 break;
6342 case OPC_DSHD:
3a55fa47
AJ
6343 {
6344 TCGv t1 = tcg_temp_new();
06a57e5c 6345 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
6346
6347 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
6348 tcg_gen_and_tl(t1, t1, t2);
6349 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6350 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
6351 tcg_gen_or_tl(t0, t0, t1);
6352 tcg_gen_shri_tl(t1, t0, 32);
6353 tcg_gen_shli_tl(t0, t0, 32);
6354 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6355 tcg_temp_free(t2);
3a55fa47
AJ
6356 tcg_temp_free(t1);
6357 }
49bcf33c
AJ
6358 break;
6359#endif
6360 default:
6361 MIPS_INVAL("bsfhl");
9c708c7f 6362 generate_exception_end(ctx, EXCP_RI);
49bcf33c 6363 tcg_temp_free(t0);
49bcf33c
AJ
6364 return;
6365 }
49bcf33c 6366 tcg_temp_free(t0);
49bcf33c
AJ
6367}
6368
1f1b4c00
YK
6369static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6370 int imm2)
6371{
6372 TCGv t0;
6373 TCGv t1;
6374 if (rd == 0) {
6375 /* Treat as NOP. */
6376 return;
6377 }
6378 t0 = tcg_temp_new();
6379 t1 = tcg_temp_new();
6380 gen_load_gpr(t0, rs);
6381 gen_load_gpr(t1, rt);
6382 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6383 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6384 if (opc == OPC_LSA) {
6385 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6386 }
6387
6388 tcg_temp_free(t1);
6389 tcg_temp_free(t0);
6390
6391 return;
6392}
6393
821f2008
JH
6394static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6395 int rt, int bits)
284b731a 6396{
1f1b4c00
YK
6397 TCGv t0;
6398 if (rd == 0) {
6399 /* Treat as NOP. */
6400 return;
6401 }
6402 t0 = tcg_temp_new();
821f2008
JH
6403 if (bits == 0 || bits == wordsz) {
6404 if (bits == 0) {
6405 gen_load_gpr(t0, rt);
6406 } else {
6407 gen_load_gpr(t0, rs);
6408 }
6409 switch (wordsz) {
6410 case 32:
51243852
MD
6411 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6412 break;
6413#if defined(TARGET_MIPS64)
821f2008 6414 case 64:
51243852
MD
6415 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6416 break;
6417#endif
6418 }
1f1b4c00
YK
6419 } else {
6420 TCGv t1 = tcg_temp_new();
821f2008 6421 gen_load_gpr(t0, rt);
1f1b4c00 6422 gen_load_gpr(t1, rs);
821f2008
JH
6423 switch (wordsz) {
6424 case 32:
1f1b4c00
YK
6425 {
6426 TCGv_i64 t2 = tcg_temp_new_i64();
6427 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 6428 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
6429 gen_move_low32(cpu_gpr[rd], t2);
6430 tcg_temp_free_i64(t2);
6431 }
6432 break;
284b731a 6433#if defined(TARGET_MIPS64)
821f2008
JH
6434 case 64:
6435 tcg_gen_shli_tl(t0, t0, bits);
6436 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
6437 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6438 break;
284b731a 6439#endif
1f1b4c00
YK
6440 }
6441 tcg_temp_free(t1);
6442 }
6443
6444 tcg_temp_free(t0);
6445}
6446
821f2008
JH
6447static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6448 int bp)
6449{
6450 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6451}
6452
6453static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6454 int shift)
6455{
6456 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6457}
6458
1f1b4c00
YK
6459static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6460{
6461 TCGv t0;
6462 if (rd == 0) {
6463 /* Treat as NOP. */
6464 return;
6465 }
6466 t0 = tcg_temp_new();
6467 gen_load_gpr(t0, rt);
6468 switch (opc) {
6469 case OPC_BITSWAP:
6470 gen_helper_bitswap(cpu_gpr[rd], t0);
6471 break;
6472#if defined(TARGET_MIPS64)
6473 case OPC_DBITSWAP:
6474 gen_helper_dbitswap(cpu_gpr[rd], t0);
6475 break;
6476#endif
6477 }
6478 tcg_temp_free(t0);
284b731a
LA
6479}
6480
1f1b4c00
YK
6481#ifndef CONFIG_USER_ONLY
6482/* CP0 (MMU and control) */
5204ea79
LA
6483static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6484{
6485 TCGv_i64 t0 = tcg_temp_new_i64();
6486 TCGv_i64 t1 = tcg_temp_new_i64();
6487
6488 tcg_gen_ext_tl_i64(t0, arg);
6489 tcg_gen_ld_i64(t1, cpu_env, off);
6490#if defined(TARGET_MIPS64)
6491 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6492#else
6493 tcg_gen_concat32_i64(t1, t1, t0);
6494#endif
6495 tcg_gen_st_i64(t1, cpu_env, off);
6496 tcg_temp_free_i64(t1);
6497 tcg_temp_free_i64(t0);
6498}
6499
6500static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6501{
6502 TCGv_i64 t0 = tcg_temp_new_i64();
6503 TCGv_i64 t1 = tcg_temp_new_i64();
6504
6505 tcg_gen_ext_tl_i64(t0, arg);
6506 tcg_gen_ld_i64(t1, cpu_env, off);
6507 tcg_gen_concat32_i64(t1, t1, t0);
6508 tcg_gen_st_i64(t1, cpu_env, off);
6509 tcg_temp_free_i64(t1);
6510 tcg_temp_free_i64(t0);
6511}
6512
6513static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6514{
6515 TCGv_i64 t0 = tcg_temp_new_i64();
6516
6517 tcg_gen_ld_i64(t0, cpu_env, off);
6518#if defined(TARGET_MIPS64)
6519 tcg_gen_shri_i64(t0, t0, 30);
6520#else
6521 tcg_gen_shri_i64(t0, t0, 32);
6522#endif
6523 gen_move_low32(arg, t0);
6524 tcg_temp_free_i64(t0);
6525}
6526
6527static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6528{
6529 TCGv_i64 t0 = tcg_temp_new_i64();
6530
6531 tcg_gen_ld_i64(t0, cpu_env, off);
6532 tcg_gen_shri_i64(t0, t0, 32 + shift);
6533 gen_move_low32(arg, t0);
6534 tcg_temp_free_i64(t0);
6535}
6536
d9bea114 6537static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 6538{
d9bea114 6539 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 6540
d9bea114
AJ
6541 tcg_gen_ld_i32(t0, cpu_env, off);
6542 tcg_gen_ext_i32_tl(arg, t0);
6543 tcg_temp_free_i32(t0);
4f57689a
TS
6544}
6545
d9bea114 6546static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 6547{
d9bea114
AJ
6548 tcg_gen_ld_tl(arg, cpu_env, off);
6549 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
6550}
6551
d9bea114 6552static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 6553{
d9bea114 6554 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 6555
d9bea114
AJ
6556 tcg_gen_trunc_tl_i32(t0, arg);
6557 tcg_gen_st_i32(t0, cpu_env, off);
6558 tcg_temp_free_i32(t0);
f1aa6320
TS
6559}
6560
c98d3d79
YK
6561#define CP0_CHECK(c) \
6562 do { \
6563 if (!(c)) { \
6564 goto cp0_unimplemented; \
6565 } \
6566 } while (0)
6567
5204ea79
LA
6568static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6569{
6570 const char *rn = "invalid";
6571
5204ea79
LA
6572 switch (reg) {
6573 case 2:
6574 switch (sel) {
6575 case 0:
59488dda 6576 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6577 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6578 rn = "EntryLo0";
6579 break;
6580 default:
c98d3d79 6581 goto cp0_unimplemented;
5204ea79
LA
6582 }
6583 break;
6584 case 3:
6585 switch (sel) {
6586 case 0:
59488dda 6587 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6588 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6589 rn = "EntryLo1";
6590 break;
6591 default:
c98d3d79 6592 goto cp0_unimplemented;
5204ea79
LA
6593 }
6594 break;
6595 case 17:
6596 switch (sel) {
6597 case 0:
6598 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6599 ctx->CP0_LLAddr_shift);
6600 rn = "LLAddr";
6601 break;
f6d4dd81
YK
6602 case 1:
6603 CP0_CHECK(ctx->mrp);
6604 gen_helper_mfhc0_maar(arg, cpu_env);
6605 rn = "MAAR";
6606 break;
5204ea79 6607 default:
c98d3d79 6608 goto cp0_unimplemented;
5204ea79
LA
6609 }
6610 break;
6611 case 28:
6612 switch (sel) {
6613 case 0:
6614 case 2:
6615 case 4:
6616 case 6:
6617 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6618 rn = "TagLo";
6619 break;
6620 default:
c98d3d79 6621 goto cp0_unimplemented;
5204ea79
LA
6622 }
6623 break;
6624 default:
c98d3d79 6625 goto cp0_unimplemented;
5204ea79 6626 }
b44a7fb1 6627 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
6628 return;
6629
c98d3d79 6630cp0_unimplemented:
965447ee 6631 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6632 tcg_gen_movi_tl(arg, 0);
6633}
6634
6635static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6636{
6637 const char *rn = "invalid";
6638 uint64_t mask = ctx->PAMask >> 36;
6639
5204ea79
LA
6640 switch (reg) {
6641 case 2:
6642 switch (sel) {
6643 case 0:
59488dda 6644 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6645 tcg_gen_andi_tl(arg, arg, mask);
6646 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6647 rn = "EntryLo0";
6648 break;
6649 default:
c98d3d79 6650 goto cp0_unimplemented;
5204ea79
LA
6651 }
6652 break;
6653 case 3:
6654 switch (sel) {
6655 case 0:
59488dda 6656 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6657 tcg_gen_andi_tl(arg, arg, mask);
6658 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6659 rn = "EntryLo1";
6660 break;
6661 default:
c98d3d79 6662 goto cp0_unimplemented;
5204ea79
LA
6663 }
6664 break;
6665 case 17:
6666 switch (sel) {
6667 case 0:
6668 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6669 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6670 relevant for modern MIPS cores supporting MTHC0, therefore
6671 treating MTHC0 to LLAddr as NOP. */
6672 rn = "LLAddr";
6673 break;
f6d4dd81
YK
6674 case 1:
6675 CP0_CHECK(ctx->mrp);
6676 gen_helper_mthc0_maar(cpu_env, arg);
6677 rn = "MAAR";
6678 break;
5204ea79 6679 default:
c98d3d79 6680 goto cp0_unimplemented;
5204ea79
LA
6681 }
6682 break;
6683 case 28:
6684 switch (sel) {
6685 case 0:
6686 case 2:
6687 case 4:
6688 case 6:
6689 tcg_gen_andi_tl(arg, arg, mask);
6690 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6691 rn = "TagLo";
6692 break;
6693 default:
c98d3d79 6694 goto cp0_unimplemented;
5204ea79
LA
6695 }
6696 break;
6697 default:
c98d3d79 6698 goto cp0_unimplemented;
5204ea79 6699 }
b44a7fb1 6700 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 6701
c98d3d79 6702cp0_unimplemented:
965447ee 6703 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6704}
6705
e98c0d17
LA
6706static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6707{
6708 if (ctx->insn_flags & ISA_MIPS32R6) {
6709 tcg_gen_movi_tl(arg, 0);
6710 } else {
6711 tcg_gen_movi_tl(arg, ~0);
6712 }
6713}
6714
d75c135e 6715static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 6716{
7a387fff 6717 const char *rn = "invalid";
873eb012 6718
e189e748 6719 if (sel != 0)
d75c135e 6720 check_insn(ctx, ISA_MIPS32);
e189e748 6721
873eb012
TS
6722 switch (reg) {
6723 case 0:
7a387fff
TS
6724 switch (sel) {
6725 case 0:
7db13fae 6726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
6727 rn = "Index";
6728 break;
6729 case 1:
f31b035a 6730 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6731 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 6732 rn = "MVPControl";
ead9360e 6733 break;
7a387fff 6734 case 2:
f31b035a 6735 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6736 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 6737 rn = "MVPConf0";
ead9360e 6738 break;
7a387fff 6739 case 3:
f31b035a 6740 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6741 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 6742 rn = "MVPConf1";
ead9360e 6743 break;
01bc435b
YK
6744 case 4:
6745 CP0_CHECK(ctx->vp);
6746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6747 rn = "VPControl";
6748 break;
7a387fff 6749 default:
f31b035a 6750 goto cp0_unimplemented;
7a387fff 6751 }
873eb012
TS
6752 break;
6753 case 1:
7a387fff
TS
6754 switch (sel) {
6755 case 0:
f31b035a 6756 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6757 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 6758 rn = "Random";
2423f660 6759 break;
7a387fff 6760 case 1:
f31b035a 6761 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6762 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 6763 rn = "VPEControl";
ead9360e 6764 break;
7a387fff 6765 case 2:
f31b035a 6766 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6767 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 6768 rn = "VPEConf0";
ead9360e 6769 break;
7a387fff 6770 case 3:
f31b035a 6771 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 6773 rn = "VPEConf1";
ead9360e 6774 break;
7a387fff 6775 case 4:
f31b035a 6776 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6777 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 6778 rn = "YQMask";
ead9360e 6779 break;
7a387fff 6780 case 5:
f31b035a 6781 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6782 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 6783 rn = "VPESchedule";
ead9360e 6784 break;
7a387fff 6785 case 6:
f31b035a 6786 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6787 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 6788 rn = "VPEScheFBack";
ead9360e 6789 break;
7a387fff 6790 case 7:
f31b035a 6791 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 6793 rn = "VPEOpt";
ead9360e 6794 break;
7a387fff 6795 default:
f31b035a 6796 goto cp0_unimplemented;
7a387fff 6797 }
873eb012
TS
6798 break;
6799 case 2:
7a387fff
TS
6800 switch (sel) {
6801 case 0:
284b731a
LA
6802 {
6803 TCGv_i64 tmp = tcg_temp_new_i64();
6804 tcg_gen_ld_i64(tmp, cpu_env,
6805 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 6806#if defined(TARGET_MIPS64)
284b731a
LA
6807 if (ctx->rxi) {
6808 /* Move RI/XI fields to bits 31:30 */
6809 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6810 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6811 }
7207c7f9 6812#endif
284b731a
LA
6813 gen_move_low32(arg, tmp);
6814 tcg_temp_free_i64(tmp);
6815 }
2423f660
TS
6816 rn = "EntryLo0";
6817 break;
7a387fff 6818 case 1:
f31b035a 6819 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6820 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6821 rn = "TCStatus";
ead9360e 6822 break;
7a387fff 6823 case 2:
f31b035a 6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6825 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6826 rn = "TCBind";
ead9360e 6827 break;
7a387fff 6828 case 3:
f31b035a 6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6830 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 6831 rn = "TCRestart";
ead9360e 6832 break;
7a387fff 6833 case 4:
f31b035a 6834 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6835 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 6836 rn = "TCHalt";
ead9360e 6837 break;
7a387fff 6838 case 5:
f31b035a 6839 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6840 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 6841 rn = "TCContext";
ead9360e 6842 break;
7a387fff 6843 case 6:
f31b035a 6844 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6845 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 6846 rn = "TCSchedule";
ead9360e 6847 break;
7a387fff 6848 case 7:
f31b035a 6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6850 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 6851 rn = "TCScheFBack";
ead9360e 6852 break;
7a387fff 6853 default:
f31b035a 6854 goto cp0_unimplemented;
7a387fff 6855 }
873eb012
TS
6856 break;
6857 case 3:
7a387fff
TS
6858 switch (sel) {
6859 case 0:
284b731a
LA
6860 {
6861 TCGv_i64 tmp = tcg_temp_new_i64();
6862 tcg_gen_ld_i64(tmp, cpu_env,
6863 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 6864#if defined(TARGET_MIPS64)
284b731a
LA
6865 if (ctx->rxi) {
6866 /* Move RI/XI fields to bits 31:30 */
6867 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6868 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6869 }
7207c7f9 6870#endif
284b731a
LA
6871 gen_move_low32(arg, tmp);
6872 tcg_temp_free_i64(tmp);
6873 }
2423f660
TS
6874 rn = "EntryLo1";
6875 break;
01bc435b
YK
6876 case 1:
6877 CP0_CHECK(ctx->vp);
6878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6879 rn = "GlobalNumber";
6880 break;
7a387fff 6881 default:
f31b035a 6882 goto cp0_unimplemented;
1579a72e 6883 }
873eb012
TS
6884 break;
6885 case 4:
7a387fff
TS
6886 switch (sel) {
6887 case 0:
7db13fae 6888 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 6889 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6890 rn = "Context";
6891 break;
7a387fff 6892 case 1:
d9bea114 6893// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6894 rn = "ContextConfig";
f31b035a 6895 goto cp0_unimplemented;
d279279e 6896 case 2:
f31b035a 6897 CP0_CHECK(ctx->ulri);
e40df9a8
JH
6898 tcg_gen_ld_tl(arg, cpu_env,
6899 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6900 tcg_gen_ext32s_tl(arg, arg);
f31b035a 6901 rn = "UserLocal";
d279279e 6902 break;
7a387fff 6903 default:
f31b035a 6904 goto cp0_unimplemented;
1579a72e 6905 }
873eb012
TS
6906 break;
6907 case 5:
7a387fff
TS
6908 switch (sel) {
6909 case 0:
7db13fae 6910 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6911 rn = "PageMask";
6912 break;
7a387fff 6913 case 1:
d75c135e 6914 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6916 rn = "PageGrain";
6917 break;
cec56a73
JH
6918 case 2:
6919 CP0_CHECK(ctx->sc);
6920 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6921 tcg_gen_ext32s_tl(arg, arg);
6922 rn = "SegCtl0";
6923 break;
6924 case 3:
6925 CP0_CHECK(ctx->sc);
6926 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6927 tcg_gen_ext32s_tl(arg, arg);
6928 rn = "SegCtl1";
6929 break;
6930 case 4:
6931 CP0_CHECK(ctx->sc);
6932 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6933 tcg_gen_ext32s_tl(arg, arg);
6934 rn = "SegCtl2";
6935 break;
5e31fdd5
YK
6936 case 5:
6937 check_pw(ctx);
6938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6939 rn = "PWBase";
6940 break;
fa75ad14
YK
6941 case 6:
6942 check_pw(ctx);
6943 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6944 rn = "PWField";
6945 break;
20b28ebc
YK
6946 case 7:
6947 check_pw(ctx);
6948 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6949 rn = "PWSize";
6950 break;
7a387fff 6951 default:
f31b035a 6952 goto cp0_unimplemented;
1579a72e 6953 }
873eb012
TS
6954 break;
6955 case 6:
7a387fff
TS
6956 switch (sel) {
6957 case 0:
7db13fae 6958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6959 rn = "Wired";
6960 break;
7a387fff 6961 case 1:
d75c135e 6962 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6963 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6964 rn = "SRSConf0";
ead9360e 6965 break;
7a387fff 6966 case 2:
d75c135e 6967 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6968 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6969 rn = "SRSConf1";
ead9360e 6970 break;
7a387fff 6971 case 3:
d75c135e 6972 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6973 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6974 rn = "SRSConf2";
ead9360e 6975 break;
7a387fff 6976 case 4:
d75c135e 6977 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6979 rn = "SRSConf3";
ead9360e 6980 break;
7a387fff 6981 case 5:
d75c135e 6982 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6983 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6984 rn = "SRSConf4";
ead9360e 6985 break;
103be64c
YK
6986 case 6:
6987 check_pw(ctx);
6988 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6989 rn = "PWCtl";
6990 break;
7a387fff 6991 default:
f31b035a 6992 goto cp0_unimplemented;
1579a72e 6993 }
873eb012 6994 break;
8c0fdd85 6995 case 7:
7a387fff
TS
6996 switch (sel) {
6997 case 0:
d75c135e 6998 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6999 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
7000 rn = "HWREna";
7001 break;
7a387fff 7002 default:
f31b035a 7003 goto cp0_unimplemented;
1579a72e 7004 }
8c0fdd85 7005 break;
873eb012 7006 case 8:
7a387fff
TS
7007 switch (sel) {
7008 case 0:
7db13fae 7009 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 7010 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 7011 rn = "BadVAddr";
2423f660 7012 break;
aea14095 7013 case 1:
f31b035a
LA
7014 CP0_CHECK(ctx->bi);
7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7016 rn = "BadInstr";
aea14095
LA
7017 break;
7018 case 2:
f31b035a
LA
7019 CP0_CHECK(ctx->bp);
7020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7021 rn = "BadInstrP";
aea14095 7022 break;
25beba9b
SM
7023 case 3:
7024 CP0_CHECK(ctx->bi);
7025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7026 tcg_gen_andi_tl(arg, arg, ~0xffff);
7027 rn = "BadInstrX";
7028 break;
7029 default:
f31b035a 7030 goto cp0_unimplemented;
aea14095 7031 }
873eb012
TS
7032 break;
7033 case 9:
7a387fff
TS
7034 switch (sel) {
7035 case 0:
2e70f6ef 7036 /* Mark as an IO operation because we read the time. */
eeb3bba8 7037 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7038 gen_io_start();
7d37435b 7039 }
895c2d04 7040 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 7041 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7042 gen_io_end();
2e70f6ef 7043 }
55807224 7044 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
7045 after reading count. DISAS_STOP isn't sufficient, we need to
7046 ensure we break completely out of translated code. */
eeb3bba8
EC
7047 gen_save_pc(ctx->base.pc_next + 4);
7048 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7049 rn = "Count";
7050 break;
7051 /* 6,7 are implementation dependent */
7a387fff 7052 default:
f31b035a 7053 goto cp0_unimplemented;
2423f660 7054 }
873eb012
TS
7055 break;
7056 case 10:
7a387fff
TS
7057 switch (sel) {
7058 case 0:
7db13fae 7059 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 7060 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7061 rn = "EntryHi";
7062 break;
7a387fff 7063 default:
f31b035a 7064 goto cp0_unimplemented;
1579a72e 7065 }
873eb012
TS
7066 break;
7067 case 11:
7a387fff
TS
7068 switch (sel) {
7069 case 0:
7db13fae 7070 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
7071 rn = "Compare";
7072 break;
7073 /* 6,7 are implementation dependent */
7a387fff 7074 default:
f31b035a 7075 goto cp0_unimplemented;
2423f660 7076 }
873eb012
TS
7077 break;
7078 case 12:
7a387fff
TS
7079 switch (sel) {
7080 case 0:
7db13fae 7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
7082 rn = "Status";
7083 break;
7a387fff 7084 case 1:
d75c135e 7085 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
7087 rn = "IntCtl";
7088 break;
7a387fff 7089 case 2:
d75c135e 7090 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
7092 rn = "SRSCtl";
7093 break;
7a387fff 7094 case 3:
d75c135e 7095 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 7097 rn = "SRSMap";
fd88b6ab 7098 break;
7a387fff 7099 default:
f31b035a 7100 goto cp0_unimplemented;
7a387fff 7101 }
873eb012
TS
7102 break;
7103 case 13:
7a387fff
TS
7104 switch (sel) {
7105 case 0:
7db13fae 7106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
7107 rn = "Cause";
7108 break;
7a387fff 7109 default:
f31b035a 7110 goto cp0_unimplemented;
7a387fff 7111 }
873eb012
TS
7112 break;
7113 case 14:
7a387fff
TS
7114 switch (sel) {
7115 case 0:
7db13fae 7116 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 7117 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7118 rn = "EPC";
7119 break;
7a387fff 7120 default:
f31b035a 7121 goto cp0_unimplemented;
1579a72e 7122 }
873eb012
TS
7123 break;
7124 case 15:
7a387fff
TS
7125 switch (sel) {
7126 case 0:
7db13fae 7127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
7128 rn = "PRid";
7129 break;
7a387fff 7130 case 1:
d75c135e 7131 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
7132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7133 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7134 rn = "EBase";
7135 break;
c870e3f5
YK
7136 case 3:
7137 check_insn(ctx, ISA_MIPS32R2);
7138 CP0_CHECK(ctx->cmgcr);
7139 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7140 tcg_gen_ext32s_tl(arg, arg);
7141 rn = "CMGCRBase";
7142 break;
7a387fff 7143 default:
f31b035a 7144 goto cp0_unimplemented;
7a387fff 7145 }
873eb012
TS
7146 break;
7147 case 16:
7148 switch (sel) {
7149 case 0:
7db13fae 7150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
7151 rn = "Config";
7152 break;
7153 case 1:
7db13fae 7154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
7155 rn = "Config1";
7156 break;
7a387fff 7157 case 2:
7db13fae 7158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
7159 rn = "Config2";
7160 break;
7161 case 3:
7db13fae 7162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
7163 rn = "Config3";
7164 break;
b4160af1
PJ
7165 case 4:
7166 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7167 rn = "Config4";
7168 break;
b4dd99a3
PJ
7169 case 5:
7170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7171 rn = "Config5";
7172 break;
e397ee33
TS
7173 /* 6,7 are implementation dependent */
7174 case 6:
7db13fae 7175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
7176 rn = "Config6";
7177 break;
7178 case 7:
7db13fae 7179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
7180 rn = "Config7";
7181 break;
873eb012 7182 default:
f31b035a 7183 goto cp0_unimplemented;
873eb012
TS
7184 }
7185 break;
7186 case 17:
7a387fff
TS
7187 switch (sel) {
7188 case 0:
895c2d04 7189 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
7190 rn = "LLAddr";
7191 break;
f6d4dd81
YK
7192 case 1:
7193 CP0_CHECK(ctx->mrp);
7194 gen_helper_mfc0_maar(arg, cpu_env);
7195 rn = "MAAR";
7196 break;
7197 case 2:
7198 CP0_CHECK(ctx->mrp);
7199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7200 rn = "MAARI";
7201 break;
7a387fff 7202 default:
f31b035a 7203 goto cp0_unimplemented;
7a387fff 7204 }
873eb012
TS
7205 break;
7206 case 18:
7a387fff 7207 switch (sel) {
c2e19f3c
AM
7208 case 0:
7209 case 1:
7210 case 2:
7211 case 3:
7212 case 4:
7213 case 5:
7214 case 6:
7215 case 7:
fa192d49 7216 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7217 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
7218 rn = "WatchLo";
7219 break;
7a387fff 7220 default:
f31b035a 7221 goto cp0_unimplemented;
7a387fff 7222 }
873eb012
TS
7223 break;
7224 case 19:
7a387fff 7225 switch (sel) {
c2e19f3c
AM
7226 case 0:
7227 case 1:
7228 case 2:
7229 case 3:
7230 case 4:
7231 case 5:
7232 case 6:
7233 case 7:
fa192d49 7234 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7235 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
7236 rn = "WatchHi";
7237 break;
7a387fff 7238 default:
f31b035a 7239 goto cp0_unimplemented;
7a387fff 7240 }
873eb012 7241 break;
8c0fdd85 7242 case 20:
7a387fff
TS
7243 switch (sel) {
7244 case 0:
d26bc211 7245#if defined(TARGET_MIPS64)
d75c135e 7246 check_insn(ctx, ISA_MIPS3);
7db13fae 7247 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 7248 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7249 rn = "XContext";
7250 break;
703eaf37 7251#endif
7a387fff 7252 default:
f31b035a 7253 goto cp0_unimplemented;
7a387fff 7254 }
8c0fdd85
TS
7255 break;
7256 case 21:
7a387fff 7257 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7258 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7259 switch (sel) {
7260 case 0:
7db13fae 7261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
7262 rn = "Framemask";
7263 break;
7a387fff 7264 default:
f31b035a 7265 goto cp0_unimplemented;
7a387fff 7266 }
8c0fdd85
TS
7267 break;
7268 case 22:
d9bea114 7269 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7270 rn = "'Diagnostic"; /* implementation dependent */
7271 break;
873eb012 7272 case 23:
7a387fff
TS
7273 switch (sel) {
7274 case 0:
895c2d04 7275 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
7276 rn = "Debug";
7277 break;
7a387fff 7278 case 1:
d9bea114 7279// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 7280 rn = "TraceControl";
3570d7f6 7281 goto cp0_unimplemented;
7a387fff 7282 case 2:
d9bea114 7283// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 7284 rn = "TraceControl2";
3570d7f6 7285 goto cp0_unimplemented;
7a387fff 7286 case 3:
d9bea114 7287// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 7288 rn = "UserTraceData";
3570d7f6 7289 goto cp0_unimplemented;
7a387fff 7290 case 4:
d9bea114 7291// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 7292 rn = "TraceBPC";
3570d7f6 7293 goto cp0_unimplemented;
7a387fff 7294 default:
f31b035a 7295 goto cp0_unimplemented;
7a387fff 7296 }
873eb012
TS
7297 break;
7298 case 24:
7a387fff
TS
7299 switch (sel) {
7300 case 0:
f0b3f3ae 7301 /* EJTAG support */
7db13fae 7302 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 7303 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7304 rn = "DEPC";
7305 break;
7a387fff 7306 default:
f31b035a 7307 goto cp0_unimplemented;
7a387fff 7308 }
873eb012 7309 break;
8c0fdd85 7310 case 25:
7a387fff
TS
7311 switch (sel) {
7312 case 0:
7db13fae 7313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7314 rn = "Performance0";
7a387fff
TS
7315 break;
7316 case 1:
d9bea114 7317// gen_helper_mfc0_performance1(arg);
2423f660 7318 rn = "Performance1";
3570d7f6 7319 goto cp0_unimplemented;
7a387fff 7320 case 2:
d9bea114 7321// gen_helper_mfc0_performance2(arg);
2423f660 7322 rn = "Performance2";
3570d7f6 7323 goto cp0_unimplemented;
7a387fff 7324 case 3:
d9bea114 7325// gen_helper_mfc0_performance3(arg);
2423f660 7326 rn = "Performance3";
3570d7f6 7327 goto cp0_unimplemented;
7a387fff 7328 case 4:
d9bea114 7329// gen_helper_mfc0_performance4(arg);
2423f660 7330 rn = "Performance4";
3570d7f6 7331 goto cp0_unimplemented;
7a387fff 7332 case 5:
d9bea114 7333// gen_helper_mfc0_performance5(arg);
2423f660 7334 rn = "Performance5";
3570d7f6 7335 goto cp0_unimplemented;
7a387fff 7336 case 6:
d9bea114 7337// gen_helper_mfc0_performance6(arg);
2423f660 7338 rn = "Performance6";
3570d7f6 7339 goto cp0_unimplemented;
7a387fff 7340 case 7:
d9bea114 7341// gen_helper_mfc0_performance7(arg);
2423f660 7342 rn = "Performance7";
3570d7f6 7343 goto cp0_unimplemented;
7a387fff 7344 default:
f31b035a 7345 goto cp0_unimplemented;
7a387fff 7346 }
8c0fdd85
TS
7347 break;
7348 case 26:
0d74a222
LA
7349 switch (sel) {
7350 case 0:
7351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7352 rn = "ErrCtl";
7353 break;
7354 default:
7355 goto cp0_unimplemented;
7356 }
da80682b 7357 break;
8c0fdd85 7358 case 27:
7a387fff 7359 switch (sel) {
c2e19f3c
AM
7360 case 0:
7361 case 1:
7362 case 2:
7363 case 3:
d9bea114 7364 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7365 rn = "CacheErr";
7366 break;
7a387fff 7367 default:
f31b035a 7368 goto cp0_unimplemented;
7a387fff 7369 }
8c0fdd85 7370 break;
873eb012
TS
7371 case 28:
7372 switch (sel) {
7373 case 0:
7a387fff
TS
7374 case 2:
7375 case 4:
7376 case 6:
284b731a
LA
7377 {
7378 TCGv_i64 tmp = tcg_temp_new_i64();
7379 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7380 gen_move_low32(arg, tmp);
7381 tcg_temp_free_i64(tmp);
7382 }
873eb012
TS
7383 rn = "TagLo";
7384 break;
7385 case 1:
7a387fff
TS
7386 case 3:
7387 case 5:
7388 case 7:
7db13fae 7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
7390 rn = "DataLo";
7391 break;
7392 default:
f31b035a 7393 goto cp0_unimplemented;
873eb012
TS
7394 }
7395 break;
8c0fdd85 7396 case 29:
7a387fff
TS
7397 switch (sel) {
7398 case 0:
7399 case 2:
7400 case 4:
7401 case 6:
7db13fae 7402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
7403 rn = "TagHi";
7404 break;
7405 case 1:
7406 case 3:
7407 case 5:
7408 case 7:
7db13fae 7409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
7410 rn = "DataHi";
7411 break;
7412 default:
f31b035a 7413 goto cp0_unimplemented;
7a387fff 7414 }
8c0fdd85 7415 break;
873eb012 7416 case 30:
7a387fff
TS
7417 switch (sel) {
7418 case 0:
7db13fae 7419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 7420 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7421 rn = "ErrorEPC";
7422 break;
7a387fff 7423 default:
f31b035a 7424 goto cp0_unimplemented;
7a387fff 7425 }
873eb012
TS
7426 break;
7427 case 31:
7a387fff
TS
7428 switch (sel) {
7429 case 0:
f0b3f3ae 7430 /* EJTAG support */
7db13fae 7431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7432 rn = "DESAVE";
7433 break;
c2e19f3c
AM
7434 case 2:
7435 case 3:
7436 case 4:
7437 case 5:
7438 case 6:
7439 case 7:
f31b035a
LA
7440 CP0_CHECK(ctx->kscrexist & (1 << sel));
7441 tcg_gen_ld_tl(arg, cpu_env,
7442 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7443 tcg_gen_ext32s_tl(arg, arg);
7444 rn = "KScratch";
e98c0d17 7445 break;
7a387fff 7446 default:
f31b035a 7447 goto cp0_unimplemented;
7a387fff 7448 }
873eb012
TS
7449 break;
7450 default:
f31b035a 7451 goto cp0_unimplemented;
873eb012 7452 }
b44a7fb1 7453 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
7454 return;
7455
f31b035a 7456cp0_unimplemented:
965447ee 7457 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7458 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
7459}
7460
d75c135e 7461static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 7462{
7a387fff
TS
7463 const char *rn = "invalid";
7464
e189e748 7465 if (sel != 0)
d75c135e 7466 check_insn(ctx, ISA_MIPS32);
e189e748 7467
eeb3bba8 7468 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7469 gen_io_start();
bd79255d 7470 }
2e70f6ef 7471
8c0fdd85
TS
7472 switch (reg) {
7473 case 0:
7a387fff
TS
7474 switch (sel) {
7475 case 0:
895c2d04 7476 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
7477 rn = "Index";
7478 break;
7479 case 1:
f31b035a 7480 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7481 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 7482 rn = "MVPControl";
ead9360e 7483 break;
7a387fff 7484 case 2:
f31b035a 7485 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7486 /* ignored */
7a387fff 7487 rn = "MVPConf0";
ead9360e 7488 break;
7a387fff 7489 case 3:
f31b035a 7490 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7491 /* ignored */
7a387fff 7492 rn = "MVPConf1";
ead9360e 7493 break;
01bc435b
YK
7494 case 4:
7495 CP0_CHECK(ctx->vp);
7496 /* ignored */
7497 rn = "VPControl";
7498 break;
7a387fff 7499 default:
f31b035a 7500 goto cp0_unimplemented;
7a387fff 7501 }
8c0fdd85
TS
7502 break;
7503 case 1:
7a387fff
TS
7504 switch (sel) {
7505 case 0:
2423f660 7506 /* ignored */
7a387fff 7507 rn = "Random";
2423f660 7508 break;
7a387fff 7509 case 1:
f31b035a 7510 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7511 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 7512 rn = "VPEControl";
ead9360e 7513 break;
7a387fff 7514 case 2:
f31b035a 7515 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7516 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 7517 rn = "VPEConf0";
ead9360e 7518 break;
7a387fff 7519 case 3:
f31b035a 7520 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7521 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 7522 rn = "VPEConf1";
ead9360e 7523 break;
7a387fff 7524 case 4:
f31b035a 7525 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7526 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 7527 rn = "YQMask";
ead9360e 7528 break;
7a387fff 7529 case 5:
f31b035a 7530 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7531 tcg_gen_st_tl(arg, cpu_env,
7532 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 7533 rn = "VPESchedule";
ead9360e 7534 break;
7a387fff 7535 case 6:
f31b035a 7536 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7537 tcg_gen_st_tl(arg, cpu_env,
7538 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 7539 rn = "VPEScheFBack";
ead9360e 7540 break;
7a387fff 7541 case 7:
f31b035a 7542 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7543 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 7544 rn = "VPEOpt";
ead9360e 7545 break;
7a387fff 7546 default:
f31b035a 7547 goto cp0_unimplemented;
7a387fff 7548 }
8c0fdd85
TS
7549 break;
7550 case 2:
7a387fff
TS
7551 switch (sel) {
7552 case 0:
895c2d04 7553 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
7554 rn = "EntryLo0";
7555 break;
7a387fff 7556 case 1:
f31b035a 7557 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7558 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7559 rn = "TCStatus";
ead9360e 7560 break;
7a387fff 7561 case 2:
f31b035a 7562 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7563 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7564 rn = "TCBind";
ead9360e 7565 break;
7a387fff 7566 case 3:
f31b035a 7567 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7568 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7569 rn = "TCRestart";
ead9360e 7570 break;
7a387fff 7571 case 4:
f31b035a 7572 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7573 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7574 rn = "TCHalt";
ead9360e 7575 break;
7a387fff 7576 case 5:
f31b035a 7577 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7578 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7579 rn = "TCContext";
ead9360e 7580 break;
7a387fff 7581 case 6:
f31b035a 7582 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7583 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7584 rn = "TCSchedule";
ead9360e 7585 break;
7a387fff 7586 case 7:
f31b035a 7587 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7588 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7589 rn = "TCScheFBack";
ead9360e 7590 break;
7a387fff 7591 default:
f31b035a 7592 goto cp0_unimplemented;
7a387fff 7593 }
8c0fdd85
TS
7594 break;
7595 case 3:
7a387fff
TS
7596 switch (sel) {
7597 case 0:
895c2d04 7598 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
7599 rn = "EntryLo1";
7600 break;
01bc435b
YK
7601 case 1:
7602 CP0_CHECK(ctx->vp);
7603 /* ignored */
7604 rn = "GlobalNumber";
7605 break;
7a387fff 7606 default:
f31b035a 7607 goto cp0_unimplemented;
876d4b07 7608 }
8c0fdd85
TS
7609 break;
7610 case 4:
7a387fff
TS
7611 switch (sel) {
7612 case 0:
895c2d04 7613 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7614 rn = "Context";
7615 break;
7a387fff 7616 case 1:
895c2d04 7617// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7618 rn = "ContextConfig";
f31b035a 7619 goto cp0_unimplemented;
d279279e 7620 case 2:
f31b035a
LA
7621 CP0_CHECK(ctx->ulri);
7622 tcg_gen_st_tl(arg, cpu_env,
7623 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7624 rn = "UserLocal";
d279279e 7625 break;
7a387fff 7626 default:
f31b035a 7627 goto cp0_unimplemented;
876d4b07 7628 }
8c0fdd85
TS
7629 break;
7630 case 5:
7a387fff
TS
7631 switch (sel) {
7632 case 0:
895c2d04 7633 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7634 rn = "PageMask";
7635 break;
7a387fff 7636 case 1:
d75c135e 7637 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7638 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 7639 rn = "PageGrain";
eeb3bba8 7640 ctx->base.is_jmp = DISAS_STOP;
2423f660 7641 break;
cec56a73
JH
7642 case 2:
7643 CP0_CHECK(ctx->sc);
7644 gen_helper_mtc0_segctl0(cpu_env, arg);
7645 rn = "SegCtl0";
7646 break;
7647 case 3:
7648 CP0_CHECK(ctx->sc);
7649 gen_helper_mtc0_segctl1(cpu_env, arg);
7650 rn = "SegCtl1";
7651 break;
7652 case 4:
7653 CP0_CHECK(ctx->sc);
7654 gen_helper_mtc0_segctl2(cpu_env, arg);
7655 rn = "SegCtl2";
7656 break;
5e31fdd5
YK
7657 case 5:
7658 check_pw(ctx);
7659 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7660 rn = "PWBase";
7661 break;
fa75ad14
YK
7662 case 6:
7663 check_pw(ctx);
7664 gen_helper_mtc0_pwfield(cpu_env, arg);
7665 rn = "PWField";
7666 break;
20b28ebc
YK
7667 case 7:
7668 check_pw(ctx);
7669 gen_helper_mtc0_pwsize(cpu_env, arg);
7670 rn = "PWSize";
7671 break;
7a387fff 7672 default:
f31b035a 7673 goto cp0_unimplemented;
876d4b07 7674 }
8c0fdd85
TS
7675 break;
7676 case 6:
7a387fff
TS
7677 switch (sel) {
7678 case 0:
895c2d04 7679 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7680 rn = "Wired";
7681 break;
7a387fff 7682 case 1:
d75c135e 7683 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7684 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7685 rn = "SRSConf0";
ead9360e 7686 break;
7a387fff 7687 case 2:
d75c135e 7688 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7689 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7690 rn = "SRSConf1";
ead9360e 7691 break;
7a387fff 7692 case 3:
d75c135e 7693 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7694 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7695 rn = "SRSConf2";
ead9360e 7696 break;
7a387fff 7697 case 4:
d75c135e 7698 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7699 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7700 rn = "SRSConf3";
ead9360e 7701 break;
7a387fff 7702 case 5:
d75c135e 7703 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7704 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7705 rn = "SRSConf4";
ead9360e 7706 break;
103be64c
YK
7707 case 6:
7708 check_pw(ctx);
7709 gen_helper_mtc0_pwctl(cpu_env, arg);
7710 rn = "PWCtl";
7711 break;
7a387fff 7712 default:
f31b035a 7713 goto cp0_unimplemented;
876d4b07 7714 }
8c0fdd85
TS
7715 break;
7716 case 7:
7a387fff
TS
7717 switch (sel) {
7718 case 0:
d75c135e 7719 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7720 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7721 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7722 rn = "HWREna";
7723 break;
7a387fff 7724 default:
f31b035a 7725 goto cp0_unimplemented;
876d4b07 7726 }
8c0fdd85
TS
7727 break;
7728 case 8:
aea14095
LA
7729 switch (sel) {
7730 case 0:
7731 /* ignored */
7732 rn = "BadVAddr";
7733 break;
7734 case 1:
7735 /* ignored */
7736 rn = "BadInstr";
7737 break;
7738 case 2:
7739 /* ignored */
7740 rn = "BadInstrP";
7741 break;
25beba9b
SM
7742 case 3:
7743 /* ignored */
7744 rn = "BadInstrX";
7745 break;
aea14095 7746 default:
f31b035a 7747 goto cp0_unimplemented;
aea14095 7748 }
8c0fdd85
TS
7749 break;
7750 case 9:
7a387fff
TS
7751 switch (sel) {
7752 case 0:
895c2d04 7753 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7754 rn = "Count";
7755 break;
876d4b07 7756 /* 6,7 are implementation dependent */
7a387fff 7757 default:
f31b035a 7758 goto cp0_unimplemented;
876d4b07 7759 }
8c0fdd85
TS
7760 break;
7761 case 10:
7a387fff
TS
7762 switch (sel) {
7763 case 0:
895c2d04 7764 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7765 rn = "EntryHi";
7766 break;
7a387fff 7767 default:
f31b035a 7768 goto cp0_unimplemented;
876d4b07 7769 }
8c0fdd85
TS
7770 break;
7771 case 11:
7a387fff
TS
7772 switch (sel) {
7773 case 0:
895c2d04 7774 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7775 rn = "Compare";
7776 break;
7777 /* 6,7 are implementation dependent */
7a387fff 7778 default:
f31b035a 7779 goto cp0_unimplemented;
876d4b07 7780 }
8c0fdd85
TS
7781 break;
7782 case 12:
7a387fff
TS
7783 switch (sel) {
7784 case 0:
867abc7e 7785 save_cpu_state(ctx, 1);
895c2d04 7786 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7787 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7788 gen_save_pc(ctx->base.pc_next + 4);
7789 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7790 rn = "Status";
7791 break;
7a387fff 7792 case 1:
d75c135e 7793 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7794 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7795 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7796 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7797 rn = "IntCtl";
7798 break;
7a387fff 7799 case 2:
d75c135e 7800 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7801 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7802 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7803 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7804 rn = "SRSCtl";
7805 break;
7a387fff 7806 case 3:
d75c135e 7807 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7808 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7809 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7810 ctx->base.is_jmp = DISAS_STOP;
2423f660 7811 rn = "SRSMap";
fd88b6ab 7812 break;
7a387fff 7813 default:
f31b035a 7814 goto cp0_unimplemented;
876d4b07 7815 }
8c0fdd85
TS
7816 break;
7817 case 13:
7a387fff
TS
7818 switch (sel) {
7819 case 0:
867abc7e 7820 save_cpu_state(ctx, 1);
895c2d04 7821 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7822 /* Stop translation as we may have triggered an interrupt.
7823 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7824 * translated code to check for pending interrupts. */
eeb3bba8
EC
7825 gen_save_pc(ctx->base.pc_next + 4);
7826 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7827 rn = "Cause";
7828 break;
7a387fff 7829 default:
f31b035a 7830 goto cp0_unimplemented;
876d4b07 7831 }
8c0fdd85
TS
7832 break;
7833 case 14:
7a387fff
TS
7834 switch (sel) {
7835 case 0:
d54a299b 7836 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7837 rn = "EPC";
7838 break;
7a387fff 7839 default:
f31b035a 7840 goto cp0_unimplemented;
876d4b07 7841 }
8c0fdd85
TS
7842 break;
7843 case 15:
7a387fff
TS
7844 switch (sel) {
7845 case 0:
2423f660
TS
7846 /* ignored */
7847 rn = "PRid";
7848 break;
7a387fff 7849 case 1:
d75c135e 7850 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7851 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7852 rn = "EBase";
7853 break;
7a387fff 7854 default:
f31b035a 7855 goto cp0_unimplemented;
1579a72e 7856 }
8c0fdd85
TS
7857 break;
7858 case 16:
7859 switch (sel) {
7860 case 0:
895c2d04 7861 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 7862 rn = "Config";
2423f660 7863 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7864 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
7865 break;
7866 case 1:
e397ee33 7867 /* ignored, read only */
7a387fff
TS
7868 rn = "Config1";
7869 break;
7870 case 2:
895c2d04 7871 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 7872 rn = "Config2";
2423f660 7873 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7874 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 7875 break;
7a387fff 7876 case 3:
90f12d73 7877 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 7878 rn = "Config3";
90f12d73 7879 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7880 ctx->base.is_jmp = DISAS_STOP;
7a387fff 7881 break;
b4160af1
PJ
7882 case 4:
7883 gen_helper_mtc0_config4(cpu_env, arg);
7884 rn = "Config4";
eeb3bba8 7885 ctx->base.is_jmp = DISAS_STOP;
b4160af1 7886 break;
b4dd99a3
PJ
7887 case 5:
7888 gen_helper_mtc0_config5(cpu_env, arg);
7889 rn = "Config5";
7890 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7891 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 7892 break;
e397ee33
TS
7893 /* 6,7 are implementation dependent */
7894 case 6:
7895 /* ignored */
7896 rn = "Config6";
7897 break;
7898 case 7:
7899 /* ignored */
7900 rn = "Config7";
7901 break;
8c0fdd85
TS
7902 default:
7903 rn = "Invalid config selector";
f31b035a 7904 goto cp0_unimplemented;
8c0fdd85
TS
7905 }
7906 break;
7907 case 17:
7a387fff
TS
7908 switch (sel) {
7909 case 0:
895c2d04 7910 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7911 rn = "LLAddr";
7912 break;
f6d4dd81
YK
7913 case 1:
7914 CP0_CHECK(ctx->mrp);
7915 gen_helper_mtc0_maar(cpu_env, arg);
7916 rn = "MAAR";
7917 break;
7918 case 2:
7919 CP0_CHECK(ctx->mrp);
7920 gen_helper_mtc0_maari(cpu_env, arg);
7921 rn = "MAARI";
7922 break;
7a387fff 7923 default:
f31b035a 7924 goto cp0_unimplemented;
7a387fff 7925 }
8c0fdd85
TS
7926 break;
7927 case 18:
7a387fff 7928 switch (sel) {
c2e19f3c
AM
7929 case 0:
7930 case 1:
7931 case 2:
7932 case 3:
7933 case 4:
7934 case 5:
7935 case 6:
7936 case 7:
fa192d49 7937 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7938 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7939 rn = "WatchLo";
7940 break;
7a387fff 7941 default:
f31b035a 7942 goto cp0_unimplemented;
7a387fff 7943 }
8c0fdd85
TS
7944 break;
7945 case 19:
7a387fff 7946 switch (sel) {
c2e19f3c
AM
7947 case 0:
7948 case 1:
7949 case 2:
7950 case 3:
7951 case 4:
7952 case 5:
7953 case 6:
7954 case 7:
fa192d49 7955 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7956 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7957 rn = "WatchHi";
7958 break;
7a387fff 7959 default:
f31b035a 7960 goto cp0_unimplemented;
7a387fff 7961 }
8c0fdd85
TS
7962 break;
7963 case 20:
7a387fff
TS
7964 switch (sel) {
7965 case 0:
d26bc211 7966#if defined(TARGET_MIPS64)
d75c135e 7967 check_insn(ctx, ISA_MIPS3);
895c2d04 7968 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7969 rn = "XContext";
7970 break;
703eaf37 7971#endif
7a387fff 7972 default:
f31b035a 7973 goto cp0_unimplemented;
7a387fff 7974 }
8c0fdd85
TS
7975 break;
7976 case 21:
7a387fff 7977 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7978 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7979 switch (sel) {
7980 case 0:
895c2d04 7981 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7982 rn = "Framemask";
7983 break;
7a387fff 7984 default:
f31b035a 7985 goto cp0_unimplemented;
7a387fff
TS
7986 }
7987 break;
8c0fdd85 7988 case 22:
7a387fff
TS
7989 /* ignored */
7990 rn = "Diagnostic"; /* implementation dependent */
2423f660 7991 break;
8c0fdd85 7992 case 23:
7a387fff
TS
7993 switch (sel) {
7994 case 0:
895c2d04 7995 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7996 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7997 gen_save_pc(ctx->base.pc_next + 4);
7998 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7999 rn = "Debug";
8000 break;
7a387fff 8001 case 1:
895c2d04 8002// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 8003 rn = "TraceControl";
8487327a 8004 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8005 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8006 goto cp0_unimplemented;
7a387fff 8007 case 2:
895c2d04 8008// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 8009 rn = "TraceControl2";
8487327a 8010 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8011 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8012 goto cp0_unimplemented;
7a387fff 8013 case 3:
8487327a 8014 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8015 ctx->base.is_jmp = DISAS_STOP;
895c2d04 8016// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 8017 rn = "UserTraceData";
8487327a 8018 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8019 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 8020 goto cp0_unimplemented;
7a387fff 8021 case 4:
895c2d04 8022// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 8023 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8024 ctx->base.is_jmp = DISAS_STOP;
2423f660 8025 rn = "TraceBPC";
3570d7f6 8026 goto cp0_unimplemented;
7a387fff 8027 default:
f31b035a 8028 goto cp0_unimplemented;
7a387fff 8029 }
8c0fdd85
TS
8030 break;
8031 case 24:
7a387fff
TS
8032 switch (sel) {
8033 case 0:
f1aa6320 8034 /* EJTAG support */
d54a299b 8035 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8036 rn = "DEPC";
8037 break;
7a387fff 8038 default:
f31b035a 8039 goto cp0_unimplemented;
7a387fff 8040 }
8c0fdd85
TS
8041 break;
8042 case 25:
7a387fff
TS
8043 switch (sel) {
8044 case 0:
895c2d04 8045 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
8046 rn = "Performance0";
8047 break;
7a387fff 8048 case 1:
d9bea114 8049// gen_helper_mtc0_performance1(arg);
2423f660 8050 rn = "Performance1";
3570d7f6 8051 goto cp0_unimplemented;
7a387fff 8052 case 2:
d9bea114 8053// gen_helper_mtc0_performance2(arg);
2423f660 8054 rn = "Performance2";
3570d7f6 8055 goto cp0_unimplemented;
7a387fff 8056 case 3:
d9bea114 8057// gen_helper_mtc0_performance3(arg);
2423f660 8058 rn = "Performance3";
3570d7f6 8059 goto cp0_unimplemented;
7a387fff 8060 case 4:
d9bea114 8061// gen_helper_mtc0_performance4(arg);
2423f660 8062 rn = "Performance4";
3570d7f6 8063 goto cp0_unimplemented;
7a387fff 8064 case 5:
d9bea114 8065// gen_helper_mtc0_performance5(arg);
2423f660 8066 rn = "Performance5";
3570d7f6 8067 goto cp0_unimplemented;
7a387fff 8068 case 6:
d9bea114 8069// gen_helper_mtc0_performance6(arg);
2423f660 8070 rn = "Performance6";
3570d7f6 8071 goto cp0_unimplemented;
7a387fff 8072 case 7:
d9bea114 8073// gen_helper_mtc0_performance7(arg);
2423f660 8074 rn = "Performance7";
3570d7f6 8075 goto cp0_unimplemented;
7a387fff 8076 default:
f31b035a 8077 goto cp0_unimplemented;
7a387fff 8078 }
8c0fdd85
TS
8079 break;
8080 case 26:
0d74a222
LA
8081 switch (sel) {
8082 case 0:
8083 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8084 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
8085 rn = "ErrCtl";
8086 break;
8087 default:
8088 goto cp0_unimplemented;
8089 }
2423f660 8090 break;
8c0fdd85 8091 case 27:
7a387fff 8092 switch (sel) {
c2e19f3c
AM
8093 case 0:
8094 case 1:
8095 case 2:
8096 case 3:
2423f660
TS
8097 /* ignored */
8098 rn = "CacheErr";
8099 break;
7a387fff 8100 default:
f31b035a 8101 goto cp0_unimplemented;
7a387fff 8102 }
8c0fdd85
TS
8103 break;
8104 case 28:
8105 switch (sel) {
8106 case 0:
7a387fff
TS
8107 case 2:
8108 case 4:
8109 case 6:
895c2d04 8110 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
8111 rn = "TagLo";
8112 break;
7a387fff
TS
8113 case 1:
8114 case 3:
8115 case 5:
8116 case 7:
895c2d04 8117 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
8118 rn = "DataLo";
8119 break;
8c0fdd85 8120 default:
f31b035a 8121 goto cp0_unimplemented;
8c0fdd85
TS
8122 }
8123 break;
8124 case 29:
7a387fff
TS
8125 switch (sel) {
8126 case 0:
8127 case 2:
8128 case 4:
8129 case 6:
895c2d04 8130 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
8131 rn = "TagHi";
8132 break;
8133 case 1:
8134 case 3:
8135 case 5:
8136 case 7:
895c2d04 8137 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
8138 rn = "DataHi";
8139 break;
8140 default:
8141 rn = "invalid sel";
f31b035a 8142 goto cp0_unimplemented;
7a387fff 8143 }
8c0fdd85
TS
8144 break;
8145 case 30:
7a387fff
TS
8146 switch (sel) {
8147 case 0:
d54a299b 8148 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8149 rn = "ErrorEPC";
8150 break;
7a387fff 8151 default:
f31b035a 8152 goto cp0_unimplemented;
7a387fff 8153 }
8c0fdd85
TS
8154 break;
8155 case 31:
7a387fff
TS
8156 switch (sel) {
8157 case 0:
f1aa6320 8158 /* EJTAG support */
7db13fae 8159 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8160 rn = "DESAVE";
8161 break;
c2e19f3c
AM
8162 case 2:
8163 case 3:
8164 case 4:
8165 case 5:
8166 case 6:
8167 case 7:
f31b035a
LA
8168 CP0_CHECK(ctx->kscrexist & (1 << sel));
8169 tcg_gen_st_tl(arg, cpu_env,
8170 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8171 rn = "KScratch";
e98c0d17 8172 break;
7a387fff 8173 default:
f31b035a 8174 goto cp0_unimplemented;
7a387fff 8175 }
8c0fdd85
TS
8176 break;
8177 default:
f31b035a 8178 goto cp0_unimplemented;
8c0fdd85 8179 }
b44a7fb1
PMD
8180 trace_mips_translate_c0("mtc0", rn, reg, sel);
8181
bf20dc07 8182 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8183 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8184 gen_io_end();
b28425ba 8185 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 8186 * translated code to check for pending interrupts. */
eeb3bba8
EC
8187 gen_save_pc(ctx->base.pc_next + 4);
8188 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8189 }
8c0fdd85
TS
8190 return;
8191
f31b035a 8192cp0_unimplemented:
965447ee 8193 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
8194}
8195
d26bc211 8196#if defined(TARGET_MIPS64)
d75c135e 8197static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8198{
8199 const char *rn = "invalid";
8200
e189e748 8201 if (sel != 0)
d75c135e 8202 check_insn(ctx, ISA_MIPS64);
e189e748 8203
9c2149c8
TS
8204 switch (reg) {
8205 case 0:
8206 switch (sel) {
8207 case 0:
7db13fae 8208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
8209 rn = "Index";
8210 break;
8211 case 1:
f31b035a 8212 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8213 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 8214 rn = "MVPControl";
ead9360e 8215 break;
9c2149c8 8216 case 2:
f31b035a 8217 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8218 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 8219 rn = "MVPConf0";
ead9360e 8220 break;
9c2149c8 8221 case 3:
f31b035a 8222 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8223 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 8224 rn = "MVPConf1";
ead9360e 8225 break;
01bc435b
YK
8226 case 4:
8227 CP0_CHECK(ctx->vp);
8228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8229 rn = "VPControl";
8230 break;
9c2149c8 8231 default:
f31b035a 8232 goto cp0_unimplemented;
9c2149c8
TS
8233 }
8234 break;
8235 case 1:
8236 switch (sel) {
8237 case 0:
f31b035a 8238 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 8239 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 8240 rn = "Random";
2423f660 8241 break;
9c2149c8 8242 case 1:
f31b035a 8243 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8244 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 8245 rn = "VPEControl";
ead9360e 8246 break;
9c2149c8 8247 case 2:
f31b035a 8248 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 8250 rn = "VPEConf0";
ead9360e 8251 break;
9c2149c8 8252 case 3:
f31b035a 8253 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 8255 rn = "VPEConf1";
ead9360e 8256 break;
9c2149c8 8257 case 4:
f31b035a 8258 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8259 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 8260 rn = "YQMask";
ead9360e 8261 break;
9c2149c8 8262 case 5:
f31b035a 8263 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8264 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8265 rn = "VPESchedule";
ead9360e 8266 break;
9c2149c8 8267 case 6:
f31b035a 8268 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8270 rn = "VPEScheFBack";
ead9360e 8271 break;
9c2149c8 8272 case 7:
f31b035a 8273 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 8275 rn = "VPEOpt";
ead9360e 8276 break;
9c2149c8 8277 default:
f31b035a 8278 goto cp0_unimplemented;
9c2149c8
TS
8279 }
8280 break;
8281 case 2:
8282 switch (sel) {
8283 case 0:
7db13fae 8284 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
8285 rn = "EntryLo0";
8286 break;
9c2149c8 8287 case 1:
f31b035a 8288 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8289 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 8290 rn = "TCStatus";
ead9360e 8291 break;
9c2149c8 8292 case 2:
f31b035a 8293 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8294 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 8295 rn = "TCBind";
ead9360e 8296 break;
9c2149c8 8297 case 3:
f31b035a 8298 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8299 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 8300 rn = "TCRestart";
ead9360e 8301 break;
9c2149c8 8302 case 4:
f31b035a 8303 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8304 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 8305 rn = "TCHalt";
ead9360e 8306 break;
9c2149c8 8307 case 5:
f31b035a 8308 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8309 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 8310 rn = "TCContext";
ead9360e 8311 break;
9c2149c8 8312 case 6:
f31b035a 8313 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8314 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 8315 rn = "TCSchedule";
ead9360e 8316 break;
9c2149c8 8317 case 7:
f31b035a 8318 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8319 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 8320 rn = "TCScheFBack";
ead9360e 8321 break;
9c2149c8 8322 default:
f31b035a 8323 goto cp0_unimplemented;
9c2149c8
TS
8324 }
8325 break;
8326 case 3:
8327 switch (sel) {
8328 case 0:
7db13fae 8329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
8330 rn = "EntryLo1";
8331 break;
01bc435b
YK
8332 case 1:
8333 CP0_CHECK(ctx->vp);
8334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8335 rn = "GlobalNumber";
8336 break;
9c2149c8 8337 default:
f31b035a 8338 goto cp0_unimplemented;
1579a72e 8339 }
9c2149c8
TS
8340 break;
8341 case 4:
8342 switch (sel) {
8343 case 0:
7db13fae 8344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
8345 rn = "Context";
8346 break;
9c2149c8 8347 case 1:
d9bea114 8348// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 8349 rn = "ContextConfig";
f31b035a 8350 goto cp0_unimplemented;
d279279e 8351 case 2:
f31b035a
LA
8352 CP0_CHECK(ctx->ulri);
8353 tcg_gen_ld_tl(arg, cpu_env,
8354 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8355 rn = "UserLocal";
d279279e 8356 break;
9c2149c8 8357 default:
f31b035a 8358 goto cp0_unimplemented;
876d4b07 8359 }
9c2149c8
TS
8360 break;
8361 case 5:
8362 switch (sel) {
8363 case 0:
7db13fae 8364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
8365 rn = "PageMask";
8366 break;
9c2149c8 8367 case 1:
d75c135e 8368 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
8370 rn = "PageGrain";
8371 break;
cec56a73
JH
8372 case 2:
8373 CP0_CHECK(ctx->sc);
8374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8375 rn = "SegCtl0";
8376 break;
8377 case 3:
8378 CP0_CHECK(ctx->sc);
8379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8380 rn = "SegCtl1";
8381 break;
8382 case 4:
8383 CP0_CHECK(ctx->sc);
8384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8385 rn = "SegCtl2";
8386 break;
5e31fdd5
YK
8387 case 5:
8388 check_pw(ctx);
8389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8390 rn = "PWBase";
8391 break;
fa75ad14
YK
8392 case 6:
8393 check_pw(ctx);
8394 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8395 rn = "PWField";
8396 break;
20b28ebc
YK
8397 case 7:
8398 check_pw(ctx);
8399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8400 rn = "PWSize";
8401 break;
9c2149c8 8402 default:
f31b035a 8403 goto cp0_unimplemented;
876d4b07 8404 }
9c2149c8
TS
8405 break;
8406 case 6:
8407 switch (sel) {
8408 case 0:
7db13fae 8409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
8410 rn = "Wired";
8411 break;
9c2149c8 8412 case 1:
d75c135e 8413 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 8415 rn = "SRSConf0";
ead9360e 8416 break;
9c2149c8 8417 case 2:
d75c135e 8418 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 8420 rn = "SRSConf1";
ead9360e 8421 break;
9c2149c8 8422 case 3:
d75c135e 8423 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 8425 rn = "SRSConf2";
ead9360e 8426 break;
9c2149c8 8427 case 4:
d75c135e 8428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 8430 rn = "SRSConf3";
ead9360e 8431 break;
9c2149c8 8432 case 5:
d75c135e 8433 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 8435 rn = "SRSConf4";
ead9360e 8436 break;
103be64c
YK
8437 case 6:
8438 check_pw(ctx);
8439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8440 rn = "PWCtl";
8441 break;
9c2149c8 8442 default:
f31b035a 8443 goto cp0_unimplemented;
876d4b07 8444 }
9c2149c8
TS
8445 break;
8446 case 7:
8447 switch (sel) {
8448 case 0:
d75c135e 8449 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
8451 rn = "HWREna";
8452 break;
9c2149c8 8453 default:
f31b035a 8454 goto cp0_unimplemented;
876d4b07 8455 }
9c2149c8
TS
8456 break;
8457 case 8:
8458 switch (sel) {
8459 case 0:
7db13fae 8460 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 8461 rn = "BadVAddr";
2423f660 8462 break;
aea14095 8463 case 1:
f31b035a
LA
8464 CP0_CHECK(ctx->bi);
8465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8466 rn = "BadInstr";
aea14095
LA
8467 break;
8468 case 2:
f31b035a
LA
8469 CP0_CHECK(ctx->bp);
8470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8471 rn = "BadInstrP";
aea14095 8472 break;
25beba9b
SM
8473 case 3:
8474 CP0_CHECK(ctx->bi);
8475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8476 tcg_gen_andi_tl(arg, arg, ~0xffff);
8477 rn = "BadInstrX";
8478 break;
9c2149c8 8479 default:
f31b035a 8480 goto cp0_unimplemented;
876d4b07 8481 }
9c2149c8
TS
8482 break;
8483 case 9:
8484 switch (sel) {
8485 case 0:
2e70f6ef 8486 /* Mark as an IO operation because we read the time. */
eeb3bba8 8487 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8488 gen_io_start();
bd79255d 8489 }
895c2d04 8490 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 8491 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8492 gen_io_end();
2e70f6ef 8493 }
55807224 8494 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
8495 after reading count. DISAS_STOP isn't sufficient, we need to
8496 ensure we break completely out of translated code. */
eeb3bba8
EC
8497 gen_save_pc(ctx->base.pc_next + 4);
8498 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8499 rn = "Count";
8500 break;
8501 /* 6,7 are implementation dependent */
9c2149c8 8502 default:
f31b035a 8503 goto cp0_unimplemented;
876d4b07 8504 }
9c2149c8
TS
8505 break;
8506 case 10:
8507 switch (sel) {
8508 case 0:
7db13fae 8509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
8510 rn = "EntryHi";
8511 break;
9c2149c8 8512 default:
f31b035a 8513 goto cp0_unimplemented;
876d4b07 8514 }
9c2149c8
TS
8515 break;
8516 case 11:
8517 switch (sel) {
8518 case 0:
7db13fae 8519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
8520 rn = "Compare";
8521 break;
876d4b07 8522 /* 6,7 are implementation dependent */
9c2149c8 8523 default:
f31b035a 8524 goto cp0_unimplemented;
876d4b07 8525 }
9c2149c8
TS
8526 break;
8527 case 12:
8528 switch (sel) {
8529 case 0:
7db13fae 8530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
8531 rn = "Status";
8532 break;
9c2149c8 8533 case 1:
d75c135e 8534 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
8536 rn = "IntCtl";
8537 break;
9c2149c8 8538 case 2:
d75c135e 8539 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
8541 rn = "SRSCtl";
8542 break;
9c2149c8 8543 case 3:
d75c135e 8544 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
8546 rn = "SRSMap";
8547 break;
9c2149c8 8548 default:
f31b035a 8549 goto cp0_unimplemented;
876d4b07 8550 }
9c2149c8
TS
8551 break;
8552 case 13:
8553 switch (sel) {
8554 case 0:
7db13fae 8555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
8556 rn = "Cause";
8557 break;
9c2149c8 8558 default:
f31b035a 8559 goto cp0_unimplemented;
876d4b07 8560 }
9c2149c8
TS
8561 break;
8562 case 14:
8563 switch (sel) {
8564 case 0:
7db13fae 8565 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8566 rn = "EPC";
8567 break;
9c2149c8 8568 default:
f31b035a 8569 goto cp0_unimplemented;
876d4b07 8570 }
9c2149c8
TS
8571 break;
8572 case 15:
8573 switch (sel) {
8574 case 0:
7db13fae 8575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
8576 rn = "PRid";
8577 break;
9c2149c8 8578 case 1:
d75c135e 8579 check_insn(ctx, ISA_MIPS32R2);
74dbf824 8580 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
8581 rn = "EBase";
8582 break;
c870e3f5
YK
8583 case 3:
8584 check_insn(ctx, ISA_MIPS32R2);
8585 CP0_CHECK(ctx->cmgcr);
8586 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8587 rn = "CMGCRBase";
8588 break;
9c2149c8 8589 default:
f31b035a 8590 goto cp0_unimplemented;
876d4b07 8591 }
9c2149c8
TS
8592 break;
8593 case 16:
8594 switch (sel) {
8595 case 0:
7db13fae 8596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
8597 rn = "Config";
8598 break;
8599 case 1:
7db13fae 8600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
8601 rn = "Config1";
8602 break;
8603 case 2:
7db13fae 8604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
8605 rn = "Config2";
8606 break;
8607 case 3:
7db13fae 8608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
8609 rn = "Config3";
8610 break;
faf1f68b
LA
8611 case 4:
8612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8613 rn = "Config4";
8614 break;
8615 case 5:
8616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8617 rn = "Config5";
8618 break;
9c2149c8 8619 /* 6,7 are implementation dependent */
f0b3f3ae 8620 case 6:
7db13fae 8621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
8622 rn = "Config6";
8623 break;
8624 case 7:
7db13fae 8625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
8626 rn = "Config7";
8627 break;
9c2149c8 8628 default:
f31b035a 8629 goto cp0_unimplemented;
9c2149c8
TS
8630 }
8631 break;
8632 case 17:
8633 switch (sel) {
8634 case 0:
895c2d04 8635 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
8636 rn = "LLAddr";
8637 break;
f6d4dd81
YK
8638 case 1:
8639 CP0_CHECK(ctx->mrp);
8640 gen_helper_dmfc0_maar(arg, cpu_env);
8641 rn = "MAAR";
8642 break;
8643 case 2:
8644 CP0_CHECK(ctx->mrp);
8645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8646 rn = "MAARI";
8647 break;
9c2149c8 8648 default:
f31b035a 8649 goto cp0_unimplemented;
9c2149c8
TS
8650 }
8651 break;
8652 case 18:
8653 switch (sel) {
c2e19f3c
AM
8654 case 0:
8655 case 1:
8656 case 2:
8657 case 3:
8658 case 4:
8659 case 5:
8660 case 6:
8661 case 7:
fa192d49 8662 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8663 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
8664 rn = "WatchLo";
8665 break;
9c2149c8 8666 default:
f31b035a 8667 goto cp0_unimplemented;
9c2149c8
TS
8668 }
8669 break;
8670 case 19:
8671 switch (sel) {
c2e19f3c
AM
8672 case 0:
8673 case 1:
8674 case 2:
8675 case 3:
8676 case 4:
8677 case 5:
8678 case 6:
8679 case 7:
fa192d49 8680 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8681 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
8682 rn = "WatchHi";
8683 break;
9c2149c8 8684 default:
f31b035a 8685 goto cp0_unimplemented;
9c2149c8
TS
8686 }
8687 break;
8688 case 20:
8689 switch (sel) {
8690 case 0:
d75c135e 8691 check_insn(ctx, ISA_MIPS3);
7db13fae 8692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
8693 rn = "XContext";
8694 break;
9c2149c8 8695 default:
f31b035a 8696 goto cp0_unimplemented;
9c2149c8
TS
8697 }
8698 break;
8699 case 21:
8700 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 8701 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
8702 switch (sel) {
8703 case 0:
7db13fae 8704 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
8705 rn = "Framemask";
8706 break;
9c2149c8 8707 default:
f31b035a 8708 goto cp0_unimplemented;
9c2149c8
TS
8709 }
8710 break;
8711 case 22:
d9bea114 8712 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8713 rn = "'Diagnostic"; /* implementation dependent */
8714 break;
9c2149c8
TS
8715 case 23:
8716 switch (sel) {
8717 case 0:
895c2d04 8718 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
8719 rn = "Debug";
8720 break;
9c2149c8 8721 case 1:
895c2d04 8722// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 8723 rn = "TraceControl";
3570d7f6 8724 goto cp0_unimplemented;
9c2149c8 8725 case 2:
895c2d04 8726// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 8727 rn = "TraceControl2";
3570d7f6 8728 goto cp0_unimplemented;
9c2149c8 8729 case 3:
895c2d04 8730// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 8731 rn = "UserTraceData";
3570d7f6 8732 goto cp0_unimplemented;
9c2149c8 8733 case 4:
895c2d04 8734// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 8735 rn = "TraceBPC";
3570d7f6 8736 goto cp0_unimplemented;
9c2149c8 8737 default:
f31b035a 8738 goto cp0_unimplemented;
9c2149c8
TS
8739 }
8740 break;
8741 case 24:
8742 switch (sel) {
8743 case 0:
f0b3f3ae 8744 /* EJTAG support */
7db13fae 8745 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8746 rn = "DEPC";
8747 break;
9c2149c8 8748 default:
f31b035a 8749 goto cp0_unimplemented;
9c2149c8
TS
8750 }
8751 break;
8752 case 25:
8753 switch (sel) {
8754 case 0:
7db13fae 8755 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 8756 rn = "Performance0";
9c2149c8
TS
8757 break;
8758 case 1:
d9bea114 8759// gen_helper_dmfc0_performance1(arg);
2423f660 8760 rn = "Performance1";
3570d7f6 8761 goto cp0_unimplemented;
9c2149c8 8762 case 2:
d9bea114 8763// gen_helper_dmfc0_performance2(arg);
2423f660 8764 rn = "Performance2";
3570d7f6 8765 goto cp0_unimplemented;
9c2149c8 8766 case 3:
d9bea114 8767// gen_helper_dmfc0_performance3(arg);
2423f660 8768 rn = "Performance3";
3570d7f6 8769 goto cp0_unimplemented;
9c2149c8 8770 case 4:
d9bea114 8771// gen_helper_dmfc0_performance4(arg);
2423f660 8772 rn = "Performance4";
3570d7f6 8773 goto cp0_unimplemented;
9c2149c8 8774 case 5:
d9bea114 8775// gen_helper_dmfc0_performance5(arg);
2423f660 8776 rn = "Performance5";
3570d7f6 8777 goto cp0_unimplemented;
9c2149c8 8778 case 6:
d9bea114 8779// gen_helper_dmfc0_performance6(arg);
2423f660 8780 rn = "Performance6";
3570d7f6 8781 goto cp0_unimplemented;
9c2149c8 8782 case 7:
d9bea114 8783// gen_helper_dmfc0_performance7(arg);
2423f660 8784 rn = "Performance7";
3570d7f6 8785 goto cp0_unimplemented;
9c2149c8 8786 default:
f31b035a 8787 goto cp0_unimplemented;
9c2149c8
TS
8788 }
8789 break;
8790 case 26:
0d74a222
LA
8791 switch (sel) {
8792 case 0:
8793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8794 rn = "ErrCtl";
8795 break;
8796 default:
8797 goto cp0_unimplemented;
8798 }
da80682b 8799 break;
9c2149c8
TS
8800 case 27:
8801 switch (sel) {
8802 /* ignored */
c2e19f3c
AM
8803 case 0:
8804 case 1:
8805 case 2:
8806 case 3:
d9bea114 8807 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8808 rn = "CacheErr";
8809 break;
9c2149c8 8810 default:
f31b035a 8811 goto cp0_unimplemented;
9c2149c8
TS
8812 }
8813 break;
8814 case 28:
8815 switch (sel) {
8816 case 0:
8817 case 2:
8818 case 4:
8819 case 6:
7db13fae 8820 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
8821 rn = "TagLo";
8822 break;
8823 case 1:
8824 case 3:
8825 case 5:
8826 case 7:
7db13fae 8827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
8828 rn = "DataLo";
8829 break;
8830 default:
f31b035a 8831 goto cp0_unimplemented;
9c2149c8
TS
8832 }
8833 break;
8834 case 29:
8835 switch (sel) {
8836 case 0:
8837 case 2:
8838 case 4:
8839 case 6:
7db13fae 8840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
8841 rn = "TagHi";
8842 break;
8843 case 1:
8844 case 3:
8845 case 5:
8846 case 7:
7db13fae 8847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
8848 rn = "DataHi";
8849 break;
8850 default:
f31b035a 8851 goto cp0_unimplemented;
9c2149c8
TS
8852 }
8853 break;
8854 case 30:
8855 switch (sel) {
8856 case 0:
7db13fae 8857 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8858 rn = "ErrorEPC";
8859 break;
9c2149c8 8860 default:
f31b035a 8861 goto cp0_unimplemented;
9c2149c8
TS
8862 }
8863 break;
8864 case 31:
8865 switch (sel) {
8866 case 0:
f0b3f3ae 8867 /* EJTAG support */
7db13fae 8868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8869 rn = "DESAVE";
8870 break;
c2e19f3c
AM
8871 case 2:
8872 case 3:
8873 case 4:
8874 case 5:
8875 case 6:
8876 case 7:
f31b035a
LA
8877 CP0_CHECK(ctx->kscrexist & (1 << sel));
8878 tcg_gen_ld_tl(arg, cpu_env,
8879 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8880 rn = "KScratch";
e98c0d17 8881 break;
9c2149c8 8882 default:
f31b035a 8883 goto cp0_unimplemented;
9c2149c8
TS
8884 }
8885 break;
8886 default:
f31b035a 8887 goto cp0_unimplemented;
9c2149c8 8888 }
b44a7fb1 8889 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
8890 return;
8891
f31b035a 8892cp0_unimplemented:
965447ee 8893 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 8894 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
8895}
8896
d75c135e 8897static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8898{
8899 const char *rn = "invalid";
8900
e189e748 8901 if (sel != 0)
d75c135e 8902 check_insn(ctx, ISA_MIPS64);
e189e748 8903
eeb3bba8 8904 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8905 gen_io_start();
bd79255d 8906 }
2e70f6ef 8907
9c2149c8
TS
8908 switch (reg) {
8909 case 0:
8910 switch (sel) {
8911 case 0:
895c2d04 8912 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
8913 rn = "Index";
8914 break;
8915 case 1:
f31b035a 8916 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8917 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 8918 rn = "MVPControl";
ead9360e 8919 break;
9c2149c8 8920 case 2:
f31b035a 8921 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8922 /* ignored */
9c2149c8 8923 rn = "MVPConf0";
ead9360e 8924 break;
9c2149c8 8925 case 3:
f31b035a 8926 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8927 /* ignored */
9c2149c8 8928 rn = "MVPConf1";
ead9360e 8929 break;
01bc435b
YK
8930 case 4:
8931 CP0_CHECK(ctx->vp);
8932 /* ignored */
8933 rn = "VPControl";
8934 break;
9c2149c8 8935 default:
f31b035a 8936 goto cp0_unimplemented;
9c2149c8
TS
8937 }
8938 break;
8939 case 1:
8940 switch (sel) {
8941 case 0:
2423f660 8942 /* ignored */
9c2149c8 8943 rn = "Random";
2423f660 8944 break;
9c2149c8 8945 case 1:
f31b035a 8946 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8947 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 8948 rn = "VPEControl";
ead9360e 8949 break;
9c2149c8 8950 case 2:
f31b035a 8951 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8952 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 8953 rn = "VPEConf0";
ead9360e 8954 break;
9c2149c8 8955 case 3:
f31b035a 8956 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8957 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 8958 rn = "VPEConf1";
ead9360e 8959 break;
9c2149c8 8960 case 4:
f31b035a 8961 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8962 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 8963 rn = "YQMask";
ead9360e 8964 break;
9c2149c8 8965 case 5:
f31b035a 8966 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8967 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8968 rn = "VPESchedule";
ead9360e 8969 break;
9c2149c8 8970 case 6:
f31b035a 8971 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8972 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8973 rn = "VPEScheFBack";
ead9360e 8974 break;
9c2149c8 8975 case 7:
f31b035a 8976 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8977 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 8978 rn = "VPEOpt";
ead9360e 8979 break;
9c2149c8 8980 default:
f31b035a 8981 goto cp0_unimplemented;
9c2149c8
TS
8982 }
8983 break;
8984 case 2:
8985 switch (sel) {
8986 case 0:
7207c7f9 8987 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
8988 rn = "EntryLo0";
8989 break;
9c2149c8 8990 case 1:
f31b035a 8991 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8992 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 8993 rn = "TCStatus";
ead9360e 8994 break;
9c2149c8 8995 case 2:
f31b035a 8996 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8997 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 8998 rn = "TCBind";
ead9360e 8999 break;
9c2149c8 9000 case 3:
f31b035a 9001 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9002 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 9003 rn = "TCRestart";
ead9360e 9004 break;
9c2149c8 9005 case 4:
f31b035a 9006 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9007 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 9008 rn = "TCHalt";
ead9360e 9009 break;
9c2149c8 9010 case 5:
f31b035a 9011 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9012 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 9013 rn = "TCContext";
ead9360e 9014 break;
9c2149c8 9015 case 6:
f31b035a 9016 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9017 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 9018 rn = "TCSchedule";
ead9360e 9019 break;
9c2149c8 9020 case 7:
f31b035a 9021 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 9022 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 9023 rn = "TCScheFBack";
ead9360e 9024 break;
9c2149c8 9025 default:
f31b035a 9026 goto cp0_unimplemented;
9c2149c8
TS
9027 }
9028 break;
9029 case 3:
9030 switch (sel) {
9031 case 0:
7207c7f9 9032 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
9033 rn = "EntryLo1";
9034 break;
01bc435b
YK
9035 case 1:
9036 CP0_CHECK(ctx->vp);
9037 /* ignored */
9038 rn = "GlobalNumber";
9039 break;
9c2149c8 9040 default:
f31b035a 9041 goto cp0_unimplemented;
876d4b07 9042 }
9c2149c8
TS
9043 break;
9044 case 4:
9045 switch (sel) {
9046 case 0:
895c2d04 9047 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
9048 rn = "Context";
9049 break;
9c2149c8 9050 case 1:
895c2d04 9051// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 9052 rn = "ContextConfig";
f31b035a 9053 goto cp0_unimplemented;
d279279e 9054 case 2:
f31b035a
LA
9055 CP0_CHECK(ctx->ulri);
9056 tcg_gen_st_tl(arg, cpu_env,
9057 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9058 rn = "UserLocal";
d279279e 9059 break;
9c2149c8 9060 default:
f31b035a 9061 goto cp0_unimplemented;
876d4b07 9062 }
9c2149c8
TS
9063 break;
9064 case 5:
9065 switch (sel) {
9066 case 0:
895c2d04 9067 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
9068 rn = "PageMask";
9069 break;
9c2149c8 9070 case 1:
d75c135e 9071 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9072 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
9073 rn = "PageGrain";
9074 break;
cec56a73
JH
9075 case 2:
9076 CP0_CHECK(ctx->sc);
9077 gen_helper_mtc0_segctl0(cpu_env, arg);
9078 rn = "SegCtl0";
9079 break;
9080 case 3:
9081 CP0_CHECK(ctx->sc);
9082 gen_helper_mtc0_segctl1(cpu_env, arg);
9083 rn = "SegCtl1";
9084 break;
9085 case 4:
9086 CP0_CHECK(ctx->sc);
9087 gen_helper_mtc0_segctl2(cpu_env, arg);
9088 rn = "SegCtl2";
9089 break;
5e31fdd5
YK
9090 case 5:
9091 check_pw(ctx);
9092 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9093 rn = "PWBase";
9094 break;
fa75ad14
YK
9095 case 6:
9096 check_pw(ctx);
9097 gen_helper_mtc0_pwfield(cpu_env, arg);
9098 rn = "PWField";
9099 break;
20b28ebc
YK
9100 case 7:
9101 check_pw(ctx);
9102 gen_helper_mtc0_pwsize(cpu_env, arg);
9103 rn = "PWSize";
9104 break;
9c2149c8 9105 default:
f31b035a 9106 goto cp0_unimplemented;
876d4b07 9107 }
9c2149c8
TS
9108 break;
9109 case 6:
9110 switch (sel) {
9111 case 0:
895c2d04 9112 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
9113 rn = "Wired";
9114 break;
9c2149c8 9115 case 1:
d75c135e 9116 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9117 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 9118 rn = "SRSConf0";
ead9360e 9119 break;
9c2149c8 9120 case 2:
d75c135e 9121 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9122 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 9123 rn = "SRSConf1";
ead9360e 9124 break;
9c2149c8 9125 case 3:
d75c135e 9126 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9127 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 9128 rn = "SRSConf2";
ead9360e 9129 break;
9c2149c8 9130 case 4:
d75c135e 9131 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9132 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 9133 rn = "SRSConf3";
ead9360e 9134 break;
9c2149c8 9135 case 5:
d75c135e 9136 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9137 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 9138 rn = "SRSConf4";
ead9360e 9139 break;
103be64c
YK
9140 case 6:
9141 check_pw(ctx);
9142 gen_helper_mtc0_pwctl(cpu_env, arg);
9143 rn = "PWCtl";
9144 break;
9c2149c8 9145 default:
f31b035a 9146 goto cp0_unimplemented;
876d4b07 9147 }
9c2149c8
TS
9148 break;
9149 case 7:
9150 switch (sel) {
9151 case 0:
d75c135e 9152 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9153 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 9154 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9155 rn = "HWREna";
9156 break;
9c2149c8 9157 default:
f31b035a 9158 goto cp0_unimplemented;
876d4b07 9159 }
9c2149c8
TS
9160 break;
9161 case 8:
aea14095
LA
9162 switch (sel) {
9163 case 0:
9164 /* ignored */
9165 rn = "BadVAddr";
9166 break;
9167 case 1:
9168 /* ignored */
9169 rn = "BadInstr";
9170 break;
9171 case 2:
9172 /* ignored */
9173 rn = "BadInstrP";
9174 break;
25beba9b
SM
9175 case 3:
9176 /* ignored */
9177 rn = "BadInstrX";
9178 break;
aea14095 9179 default:
f31b035a 9180 goto cp0_unimplemented;
aea14095 9181 }
9c2149c8
TS
9182 break;
9183 case 9:
9184 switch (sel) {
9185 case 0:
895c2d04 9186 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
9187 rn = "Count";
9188 break;
876d4b07 9189 /* 6,7 are implementation dependent */
9c2149c8 9190 default:
f31b035a 9191 goto cp0_unimplemented;
876d4b07
TS
9192 }
9193 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9194 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9195 break;
9196 case 10:
9197 switch (sel) {
9198 case 0:
895c2d04 9199 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
9200 rn = "EntryHi";
9201 break;
9c2149c8 9202 default:
f31b035a 9203 goto cp0_unimplemented;
876d4b07 9204 }
9c2149c8
TS
9205 break;
9206 case 11:
9207 switch (sel) {
9208 case 0:
895c2d04 9209 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
9210 rn = "Compare";
9211 break;
876d4b07 9212 /* 6,7 are implementation dependent */
9c2149c8 9213 default:
f31b035a 9214 goto cp0_unimplemented;
876d4b07 9215 }
de9a95f0 9216 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9217 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9218 break;
9219 case 12:
9220 switch (sel) {
9221 case 0:
867abc7e 9222 save_cpu_state(ctx, 1);
895c2d04 9223 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 9224 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9225 gen_save_pc(ctx->base.pc_next + 4);
9226 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9227 rn = "Status";
9228 break;
9c2149c8 9229 case 1:
d75c135e 9230 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9231 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 9232 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9233 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9234 rn = "IntCtl";
9235 break;
9c2149c8 9236 case 2:
d75c135e 9237 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9238 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 9239 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9240 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9241 rn = "SRSCtl";
9242 break;
9c2149c8 9243 case 3:
d75c135e 9244 check_insn(ctx, ISA_MIPS32R2);
7db13fae 9245 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 9246 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9247 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9248 rn = "SRSMap";
9249 break;
9250 default:
f31b035a 9251 goto cp0_unimplemented;
876d4b07 9252 }
9c2149c8
TS
9253 break;
9254 case 13:
9255 switch (sel) {
9256 case 0:
867abc7e 9257 save_cpu_state(ctx, 1);
895c2d04 9258 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
9259 /* Stop translation as we may have triggered an interrupt.
9260 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9261 * translated code to check for pending interrupts. */
eeb3bba8
EC
9262 gen_save_pc(ctx->base.pc_next + 4);
9263 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9264 rn = "Cause";
9265 break;
9c2149c8 9266 default:
f31b035a 9267 goto cp0_unimplemented;
876d4b07 9268 }
9c2149c8
TS
9269 break;
9270 case 14:
9271 switch (sel) {
9272 case 0:
7db13fae 9273 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
9274 rn = "EPC";
9275 break;
9c2149c8 9276 default:
f31b035a 9277 goto cp0_unimplemented;
876d4b07 9278 }
9c2149c8
TS
9279 break;
9280 case 15:
9281 switch (sel) {
9282 case 0:
2423f660
TS
9283 /* ignored */
9284 rn = "PRid";
9285 break;
9c2149c8 9286 case 1:
d75c135e 9287 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9288 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
9289 rn = "EBase";
9290 break;
9c2149c8 9291 default:
f31b035a 9292 goto cp0_unimplemented;
876d4b07 9293 }
9c2149c8
TS
9294 break;
9295 case 16:
9296 switch (sel) {
9297 case 0:
895c2d04 9298 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 9299 rn = "Config";
2423f660 9300 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9301 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9302 break;
9303 case 1:
1fc7bf6e 9304 /* ignored, read only */
9c2149c8
TS
9305 rn = "Config1";
9306 break;
9307 case 2:
895c2d04 9308 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 9309 rn = "Config2";
2423f660 9310 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9311 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9312 break;
9313 case 3:
90f12d73 9314 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 9315 rn = "Config3";
90f12d73 9316 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9317 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9318 break;
faf1f68b
LA
9319 case 4:
9320 /* currently ignored */
9321 rn = "Config4";
9322 break;
9323 case 5:
9324 gen_helper_mtc0_config5(cpu_env, arg);
9325 rn = "Config5";
9326 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9327 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 9328 break;
9c2149c8
TS
9329 /* 6,7 are implementation dependent */
9330 default:
9331 rn = "Invalid config selector";
f31b035a 9332 goto cp0_unimplemented;
9c2149c8 9333 }
9c2149c8
TS
9334 break;
9335 case 17:
9336 switch (sel) {
9337 case 0:
895c2d04 9338 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
9339 rn = "LLAddr";
9340 break;
f6d4dd81
YK
9341 case 1:
9342 CP0_CHECK(ctx->mrp);
9343 gen_helper_mtc0_maar(cpu_env, arg);
9344 rn = "MAAR";
9345 break;
9346 case 2:
9347 CP0_CHECK(ctx->mrp);
9348 gen_helper_mtc0_maari(cpu_env, arg);
9349 rn = "MAARI";
9350 break;
9c2149c8 9351 default:
f31b035a 9352 goto cp0_unimplemented;
9c2149c8
TS
9353 }
9354 break;
9355 case 18:
9356 switch (sel) {
c2e19f3c
AM
9357 case 0:
9358 case 1:
9359 case 2:
9360 case 3:
9361 case 4:
9362 case 5:
9363 case 6:
9364 case 7:
fa192d49 9365 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9366 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
9367 rn = "WatchLo";
9368 break;
9c2149c8 9369 default:
f31b035a 9370 goto cp0_unimplemented;
9c2149c8
TS
9371 }
9372 break;
9373 case 19:
9374 switch (sel) {
c2e19f3c
AM
9375 case 0:
9376 case 1:
9377 case 2:
9378 case 3:
9379 case 4:
9380 case 5:
9381 case 6:
9382 case 7:
fa192d49 9383 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9384 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
9385 rn = "WatchHi";
9386 break;
9c2149c8 9387 default:
f31b035a 9388 goto cp0_unimplemented;
9c2149c8
TS
9389 }
9390 break;
9391 case 20:
9392 switch (sel) {
9393 case 0:
d75c135e 9394 check_insn(ctx, ISA_MIPS3);
895c2d04 9395 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
9396 rn = "XContext";
9397 break;
9c2149c8 9398 default:
f31b035a 9399 goto cp0_unimplemented;
9c2149c8
TS
9400 }
9401 break;
9402 case 21:
9403 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 9404 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
9405 switch (sel) {
9406 case 0:
895c2d04 9407 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
9408 rn = "Framemask";
9409 break;
9c2149c8 9410 default:
f31b035a 9411 goto cp0_unimplemented;
9c2149c8
TS
9412 }
9413 break;
9414 case 22:
9415 /* ignored */
9416 rn = "Diagnostic"; /* implementation dependent */
876d4b07 9417 break;
9c2149c8
TS
9418 case 23:
9419 switch (sel) {
9420 case 0:
895c2d04 9421 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 9422 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9423 gen_save_pc(ctx->base.pc_next + 4);
9424 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9425 rn = "Debug";
9426 break;
9c2149c8 9427 case 1:
895c2d04 9428// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 9429 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9430 ctx->base.is_jmp = DISAS_STOP;
2423f660 9431 rn = "TraceControl";
3570d7f6 9432 goto cp0_unimplemented;
9c2149c8 9433 case 2:
895c2d04 9434// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 9435 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9436 ctx->base.is_jmp = DISAS_STOP;
2423f660 9437 rn = "TraceControl2";
3570d7f6 9438 goto cp0_unimplemented;
9c2149c8 9439 case 3:
895c2d04 9440// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 9441 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9442 ctx->base.is_jmp = DISAS_STOP;
2423f660 9443 rn = "UserTraceData";
3570d7f6 9444 goto cp0_unimplemented;
9c2149c8 9445 case 4:
895c2d04 9446// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 9447 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9448 ctx->base.is_jmp = DISAS_STOP;
2423f660 9449 rn = "TraceBPC";
3570d7f6 9450 goto cp0_unimplemented;
9c2149c8 9451 default:
f31b035a 9452 goto cp0_unimplemented;
9c2149c8 9453 }
9c2149c8
TS
9454 break;
9455 case 24:
9456 switch (sel) {
9457 case 0:
f1aa6320 9458 /* EJTAG support */
7db13fae 9459 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
9460 rn = "DEPC";
9461 break;
9c2149c8 9462 default:
f31b035a 9463 goto cp0_unimplemented;
9c2149c8
TS
9464 }
9465 break;
9466 case 25:
9467 switch (sel) {
9468 case 0:
895c2d04 9469 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
9470 rn = "Performance0";
9471 break;
9c2149c8 9472 case 1:
895c2d04 9473// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 9474 rn = "Performance1";
3570d7f6 9475 goto cp0_unimplemented;
9c2149c8 9476 case 2:
895c2d04 9477// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 9478 rn = "Performance2";
3570d7f6 9479 goto cp0_unimplemented;
9c2149c8 9480 case 3:
895c2d04 9481// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 9482 rn = "Performance3";
3570d7f6 9483 goto cp0_unimplemented;
9c2149c8 9484 case 4:
895c2d04 9485// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 9486 rn = "Performance4";
3570d7f6 9487 goto cp0_unimplemented;
9c2149c8 9488 case 5:
895c2d04 9489// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 9490 rn = "Performance5";
3570d7f6 9491 goto cp0_unimplemented;
9c2149c8 9492 case 6:
895c2d04 9493// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 9494 rn = "Performance6";
3570d7f6 9495 goto cp0_unimplemented;
9c2149c8 9496 case 7:
895c2d04 9497// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 9498 rn = "Performance7";
3570d7f6 9499 goto cp0_unimplemented;
9c2149c8 9500 default:
f31b035a 9501 goto cp0_unimplemented;
9c2149c8 9502 }
876d4b07 9503 break;
9c2149c8 9504 case 26:
0d74a222
LA
9505 switch (sel) {
9506 case 0:
9507 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 9508 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
9509 rn = "ErrCtl";
9510 break;
9511 default:
9512 goto cp0_unimplemented;
9513 }
876d4b07 9514 break;
9c2149c8
TS
9515 case 27:
9516 switch (sel) {
c2e19f3c
AM
9517 case 0:
9518 case 1:
9519 case 2:
9520 case 3:
2423f660
TS
9521 /* ignored */
9522 rn = "CacheErr";
9523 break;
9c2149c8 9524 default:
f31b035a 9525 goto cp0_unimplemented;
9c2149c8 9526 }
876d4b07 9527 break;
9c2149c8
TS
9528 case 28:
9529 switch (sel) {
9530 case 0:
9531 case 2:
9532 case 4:
9533 case 6:
895c2d04 9534 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
9535 rn = "TagLo";
9536 break;
9537 case 1:
9538 case 3:
9539 case 5:
9540 case 7:
895c2d04 9541 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
9542 rn = "DataLo";
9543 break;
9544 default:
f31b035a 9545 goto cp0_unimplemented;
9c2149c8
TS
9546 }
9547 break;
9548 case 29:
9549 switch (sel) {
9550 case 0:
9551 case 2:
9552 case 4:
9553 case 6:
895c2d04 9554 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
9555 rn = "TagHi";
9556 break;
9557 case 1:
9558 case 3:
9559 case 5:
9560 case 7:
895c2d04 9561 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
9562 rn = "DataHi";
9563 break;
9564 default:
9565 rn = "invalid sel";
f31b035a 9566 goto cp0_unimplemented;
9c2149c8 9567 }
876d4b07 9568 break;
9c2149c8
TS
9569 case 30:
9570 switch (sel) {
9571 case 0:
7db13fae 9572 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
9573 rn = "ErrorEPC";
9574 break;
9c2149c8 9575 default:
f31b035a 9576 goto cp0_unimplemented;
9c2149c8
TS
9577 }
9578 break;
9579 case 31:
9580 switch (sel) {
9581 case 0:
f1aa6320 9582 /* EJTAG support */
7db13fae 9583 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
9584 rn = "DESAVE";
9585 break;
c2e19f3c
AM
9586 case 2:
9587 case 3:
9588 case 4:
9589 case 5:
9590 case 6:
9591 case 7:
f31b035a
LA
9592 CP0_CHECK(ctx->kscrexist & (1 << sel));
9593 tcg_gen_st_tl(arg, cpu_env,
9594 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9595 rn = "KScratch";
e98c0d17 9596 break;
9c2149c8 9597 default:
f31b035a 9598 goto cp0_unimplemented;
9c2149c8 9599 }
9c2149c8
TS
9600 break;
9601 default:
f31b035a 9602 goto cp0_unimplemented;
9c2149c8 9603 }
b44a7fb1
PMD
9604 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9605
bf20dc07 9606 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 9607 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 9608 gen_io_end();
b28425ba 9609 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 9610 * translated code to check for pending interrupts. */
eeb3bba8
EC
9611 gen_save_pc(ctx->base.pc_next + 4);
9612 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 9613 }
9c2149c8
TS
9614 return;
9615
f31b035a 9616cp0_unimplemented:
965447ee 9617 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 9618}
d26bc211 9619#endif /* TARGET_MIPS64 */
9c2149c8 9620
7db13fae 9621static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
9622 int u, int sel, int h)
9623{
9624 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9625 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
9626
9627 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9628 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9629 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 9630 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9631 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9632 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 9633 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9634 else if (u == 0) {
9635 switch (rt) {
5a25ce94
EI
9636 case 1:
9637 switch (sel) {
9638 case 1:
895c2d04 9639 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
9640 break;
9641 case 2:
895c2d04 9642 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
9643 break;
9644 default:
9645 goto die;
9646 break;
9647 }
9648 break;
ead9360e
TS
9649 case 2:
9650 switch (sel) {
9651 case 1:
895c2d04 9652 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
9653 break;
9654 case 2:
895c2d04 9655 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
9656 break;
9657 case 3:
895c2d04 9658 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
9659 break;
9660 case 4:
895c2d04 9661 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
9662 break;
9663 case 5:
895c2d04 9664 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
9665 break;
9666 case 6:
895c2d04 9667 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
9668 break;
9669 case 7:
895c2d04 9670 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
9671 break;
9672 default:
d75c135e 9673 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9674 break;
9675 }
9676 break;
9677 case 10:
9678 switch (sel) {
9679 case 0:
895c2d04 9680 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
9681 break;
9682 default:
d75c135e 9683 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9684 break;
9685 }
9686 case 12:
9687 switch (sel) {
9688 case 0:
895c2d04 9689 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
9690 break;
9691 default:
d75c135e 9692 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9693 break;
9694 }
5a25ce94
EI
9695 case 13:
9696 switch (sel) {
9697 case 0:
895c2d04 9698 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
9699 break;
9700 default:
9701 goto die;
9702 break;
9703 }
9704 break;
9705 case 14:
9706 switch (sel) {
9707 case 0:
895c2d04 9708 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
9709 break;
9710 default:
9711 goto die;
9712 break;
9713 }
9714 break;
9715 case 15:
9716 switch (sel) {
9717 case 1:
895c2d04 9718 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
9719 break;
9720 default:
9721 goto die;
9722 break;
9723 }
9724 break;
9725 case 16:
9726 switch (sel) {
c2e19f3c
AM
9727 case 0:
9728 case 1:
9729 case 2:
9730 case 3:
9731 case 4:
9732 case 5:
9733 case 6:
9734 case 7:
895c2d04 9735 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
9736 break;
9737 default:
9738 goto die;
9739 break;
9740 }
9741 break;
ead9360e
TS
9742 case 23:
9743 switch (sel) {
9744 case 0:
895c2d04 9745 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
9746 break;
9747 default:
d75c135e 9748 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9749 break;
9750 }
9751 break;
9752 default:
d75c135e 9753 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9754 }
9755 } else switch (sel) {
9756 /* GPR registers. */
9757 case 0:
895c2d04 9758 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
9759 break;
9760 /* Auxiliary CPU registers */
9761 case 1:
9762 switch (rt) {
9763 case 0:
895c2d04 9764 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
9765 break;
9766 case 1:
895c2d04 9767 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
9768 break;
9769 case 2:
895c2d04 9770 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
9771 break;
9772 case 4:
895c2d04 9773 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
9774 break;
9775 case 5:
895c2d04 9776 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
9777 break;
9778 case 6:
895c2d04 9779 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
9780 break;
9781 case 8:
895c2d04 9782 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
9783 break;
9784 case 9:
895c2d04 9785 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
9786 break;
9787 case 10:
895c2d04 9788 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
9789 break;
9790 case 12:
895c2d04 9791 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
9792 break;
9793 case 13:
895c2d04 9794 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
9795 break;
9796 case 14:
895c2d04 9797 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
9798 break;
9799 case 16:
895c2d04 9800 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
9801 break;
9802 default:
9803 goto die;
9804 }
9805 break;
9806 /* Floating point (COP1). */
9807 case 2:
9808 /* XXX: For now we support only a single FPU context. */
9809 if (h == 0) {
a7812ae4 9810 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9811
7c979afd 9812 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 9813 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9814 tcg_temp_free_i32(fp0);
ead9360e 9815 } else {
a7812ae4 9816 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9817
7f6613ce 9818 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 9819 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9820 tcg_temp_free_i32(fp0);
ead9360e
TS
9821 }
9822 break;
9823 case 3:
9824 /* XXX: For now we support only a single FPU context. */
895c2d04 9825 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
9826 break;
9827 /* COP2: Not implemented. */
9828 case 4:
9829 case 5:
9830 /* fall through */
9831 default:
9832 goto die;
9833 }
b44a7fb1 9834 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
9835 gen_store_gpr(t0, rd);
9836 tcg_temp_free(t0);
ead9360e
TS
9837 return;
9838
9839die:
1a3fd9c3 9840 tcg_temp_free(t0);
d12d51d5 9841 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 9842 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9843}
9844
7db13fae 9845static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
9846 int u, int sel, int h)
9847{
9848 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9849 TCGv t0 = tcg_temp_local_new();
ead9360e 9850
1a3fd9c3 9851 gen_load_gpr(t0, rt);
ead9360e 9852 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9853 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9854 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
9855 /* NOP */ ;
9856 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9857 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9858 /* NOP */ ;
9859 else if (u == 0) {
9860 switch (rd) {
5a25ce94
EI
9861 case 1:
9862 switch (sel) {
9863 case 1:
895c2d04 9864 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
9865 break;
9866 case 2:
895c2d04 9867 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
9868 break;
9869 default:
9870 goto die;
9871 break;
9872 }
9873 break;
ead9360e
TS
9874 case 2:
9875 switch (sel) {
9876 case 1:
895c2d04 9877 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
9878 break;
9879 case 2:
895c2d04 9880 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
9881 break;
9882 case 3:
895c2d04 9883 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
9884 break;
9885 case 4:
895c2d04 9886 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
9887 break;
9888 case 5:
895c2d04 9889 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
9890 break;
9891 case 6:
895c2d04 9892 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
9893 break;
9894 case 7:
895c2d04 9895 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
9896 break;
9897 default:
d75c135e 9898 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9899 break;
9900 }
9901 break;
9902 case 10:
9903 switch (sel) {
9904 case 0:
895c2d04 9905 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
9906 break;
9907 default:
d75c135e 9908 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9909 break;
9910 }
9911 case 12:
9912 switch (sel) {
9913 case 0:
895c2d04 9914 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
9915 break;
9916 default:
d75c135e 9917 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9918 break;
9919 }
5a25ce94
EI
9920 case 13:
9921 switch (sel) {
9922 case 0:
895c2d04 9923 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
9924 break;
9925 default:
9926 goto die;
9927 break;
9928 }
9929 break;
9930 case 15:
9931 switch (sel) {
9932 case 1:
895c2d04 9933 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
9934 break;
9935 default:
9936 goto die;
9937 break;
9938 }
9939 break;
ead9360e
TS
9940 case 23:
9941 switch (sel) {
9942 case 0:
895c2d04 9943 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
9944 break;
9945 default:
d75c135e 9946 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9947 break;
9948 }
9949 break;
9950 default:
d75c135e 9951 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9952 }
9953 } else switch (sel) {
9954 /* GPR registers. */
9955 case 0:
895c2d04 9956 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
9957 break;
9958 /* Auxiliary CPU registers */
9959 case 1:
9960 switch (rd) {
9961 case 0:
895c2d04 9962 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
9963 break;
9964 case 1:
895c2d04 9965 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
9966 break;
9967 case 2:
895c2d04 9968 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
9969 break;
9970 case 4:
895c2d04 9971 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
9972 break;
9973 case 5:
895c2d04 9974 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
9975 break;
9976 case 6:
895c2d04 9977 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
9978 break;
9979 case 8:
895c2d04 9980 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
9981 break;
9982 case 9:
895c2d04 9983 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
9984 break;
9985 case 10:
895c2d04 9986 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
9987 break;
9988 case 12:
895c2d04 9989 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
9990 break;
9991 case 13:
895c2d04 9992 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
9993 break;
9994 case 14:
895c2d04 9995 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
9996 break;
9997 case 16:
895c2d04 9998 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
9999 break;
10000 default:
10001 goto die;
10002 }
10003 break;
10004 /* Floating point (COP1). */
10005 case 2:
10006 /* XXX: For now we support only a single FPU context. */
10007 if (h == 0) {
a7812ae4 10008 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10009
10010 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10011 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 10012 tcg_temp_free_i32(fp0);
ead9360e 10013 } else {
a7812ae4 10014 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10015
10016 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 10017 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 10018 tcg_temp_free_i32(fp0);
ead9360e
TS
10019 }
10020 break;
10021 case 3:
10022 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
10023 {
10024 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10025
10026 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10027 tcg_temp_free_i32(fs_tmp);
10028 }
4cf8a45f 10029 /* Stop translation as we may have changed hflags */
eeb3bba8 10030 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
10031 break;
10032 /* COP2: Not implemented. */
10033 case 4:
10034 case 5:
10035 /* fall through */
10036 default:
10037 goto die;
10038 }
b44a7fb1 10039 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 10040 tcg_temp_free(t0);
ead9360e
TS
10041 return;
10042
10043die:
1a3fd9c3 10044 tcg_temp_free(t0);
d12d51d5 10045 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 10046 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
10047}
10048
7db13fae 10049static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 10050{
287c4b84 10051 const char *opn = "ldst";
6af0bf9c 10052
2e15497c 10053 check_cp0_enabled(ctx);
6af0bf9c
FB
10054 switch (opc) {
10055 case OPC_MFC0:
10056 if (rt == 0) {
ead9360e 10057 /* Treat as NOP. */
6af0bf9c
FB
10058 return;
10059 }
d75c135e 10060 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
10061 opn = "mfc0";
10062 break;
10063 case OPC_MTC0:
1a3fd9c3 10064 {
1fc7bf6e 10065 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
10066
10067 gen_load_gpr(t0, rt);
d75c135e 10068 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
10069 tcg_temp_free(t0);
10070 }
6af0bf9c
FB
10071 opn = "mtc0";
10072 break;
d26bc211 10073#if defined(TARGET_MIPS64)
9c2149c8 10074 case OPC_DMFC0:
d75c135e 10075 check_insn(ctx, ISA_MIPS3);
9c2149c8 10076 if (rt == 0) {
ead9360e 10077 /* Treat as NOP. */
9c2149c8
TS
10078 return;
10079 }
d75c135e 10080 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
10081 opn = "dmfc0";
10082 break;
10083 case OPC_DMTC0:
d75c135e 10084 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 10085 {
1fc7bf6e 10086 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
10087
10088 gen_load_gpr(t0, rt);
d75c135e 10089 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
10090 tcg_temp_free(t0);
10091 }
9c2149c8
TS
10092 opn = "dmtc0";
10093 break;
534ce69f 10094#endif
5204ea79
LA
10095 case OPC_MFHC0:
10096 check_mvh(ctx);
10097 if (rt == 0) {
10098 /* Treat as NOP. */
10099 return;
10100 }
10101 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10102 opn = "mfhc0";
10103 break;
10104 case OPC_MTHC0:
10105 check_mvh(ctx);
10106 {
10107 TCGv t0 = tcg_temp_new();
10108 gen_load_gpr(t0, rt);
10109 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10110 tcg_temp_free(t0);
10111 }
10112 opn = "mthc0";
10113 break;
ead9360e 10114 case OPC_MFTR:
9affc1c5 10115 check_cp0_enabled(ctx);
ead9360e
TS
10116 if (rd == 0) {
10117 /* Treat as NOP. */
10118 return;
10119 }
6c5c1e20 10120 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 10121 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
10122 opn = "mftr";
10123 break;
10124 case OPC_MTTR:
9affc1c5 10125 check_cp0_enabled(ctx);
6c5c1e20 10126 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
10127 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10128 opn = "mttr";
10129 break;
6af0bf9c 10130 case OPC_TLBWI:
6af0bf9c 10131 opn = "tlbwi";
c01fccd2 10132 if (!env->tlb->helper_tlbwi)
29929e34 10133 goto die;
895c2d04 10134 gen_helper_tlbwi(cpu_env);
6af0bf9c 10135 break;
9456c2fb
LA
10136 case OPC_TLBINV:
10137 opn = "tlbinv";
10138 if (ctx->ie >= 2) {
10139 if (!env->tlb->helper_tlbinv) {
10140 goto die;
10141 }
10142 gen_helper_tlbinv(cpu_env);
10143 } /* treat as nop if TLBINV not supported */
10144 break;
10145 case OPC_TLBINVF:
10146 opn = "tlbinvf";
10147 if (ctx->ie >= 2) {
10148 if (!env->tlb->helper_tlbinvf) {
10149 goto die;
10150 }
10151 gen_helper_tlbinvf(cpu_env);
10152 } /* treat as nop if TLBINV not supported */
10153 break;
6af0bf9c 10154 case OPC_TLBWR:
6af0bf9c 10155 opn = "tlbwr";
c01fccd2 10156 if (!env->tlb->helper_tlbwr)
29929e34 10157 goto die;
895c2d04 10158 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
10159 break;
10160 case OPC_TLBP:
6af0bf9c 10161 opn = "tlbp";
c01fccd2 10162 if (!env->tlb->helper_tlbp)
29929e34 10163 goto die;
895c2d04 10164 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
10165 break;
10166 case OPC_TLBR:
6af0bf9c 10167 opn = "tlbr";
c01fccd2 10168 if (!env->tlb->helper_tlbr)
29929e34 10169 goto die;
895c2d04 10170 gen_helper_tlbr(cpu_env);
6af0bf9c 10171 break;
ce9782f4 10172 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
10173 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10174 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 10175 goto die;
ce9782f4
LA
10176 } else {
10177 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10178 if (ctx->opcode & (1 << bit_shift)) {
10179 /* OPC_ERETNC */
10180 opn = "eretnc";
10181 check_insn(ctx, ISA_MIPS32R5);
10182 gen_helper_eretnc(cpu_env);
10183 } else {
10184 /* OPC_ERET */
10185 opn = "eret";
10186 check_insn(ctx, ISA_MIPS2);
10187 gen_helper_eret(cpu_env);
10188 }
eeb3bba8 10189 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 10190 }
6af0bf9c
FB
10191 break;
10192 case OPC_DERET:
10193 opn = "deret";
d75c135e 10194 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
10195 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10196 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10197 goto die;
10198 }
6af0bf9c 10199 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 10200 MIPS_INVAL(opn);
9c708c7f 10201 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 10202 } else {
895c2d04 10203 gen_helper_deret(cpu_env);
eeb3bba8 10204 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
10205 }
10206 break;
4ad40f36
FB
10207 case OPC_WAIT:
10208 opn = "wait";
d75c135e 10209 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
10210 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10211 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10212 goto die;
10213 }
4ad40f36 10214 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 10215 ctx->base.pc_next += 4;
4ad40f36 10216 save_cpu_state(ctx, 1);
eeb3bba8 10217 ctx->base.pc_next -= 4;
895c2d04 10218 gen_helper_wait(cpu_env);
eeb3bba8 10219 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 10220 break;
6af0bf9c 10221 default:
29929e34 10222 die:
923617a3 10223 MIPS_INVAL(opn);
9c708c7f 10224 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
10225 return;
10226 }
2abf314d 10227 (void)opn; /* avoid a compiler warning */
6af0bf9c 10228}
f1aa6320 10229#endif /* !CONFIG_USER_ONLY */
6af0bf9c 10230
6ea83fed 10231/* CP1 Branches (before delay slot) */
d75c135e
AJ
10232static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10233 int32_t cc, int32_t offset)
6ea83fed
FB
10234{
10235 target_ulong btarget;
a7812ae4 10236 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 10237
339cd2a8 10238 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 10239 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
10240 goto out;
10241 }
10242
e189e748 10243 if (cc != 0)
d75c135e 10244 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 10245
eeb3bba8 10246 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 10247
7a387fff
TS
10248 switch (op) {
10249 case OPC_BC1F:
d94536f4
AJ
10250 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10251 tcg_gen_not_i32(t0, t0);
10252 tcg_gen_andi_i32(t0, t0, 1);
10253 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10254 goto not_likely;
7a387fff 10255 case OPC_BC1FL:
d94536f4
AJ
10256 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10257 tcg_gen_not_i32(t0, t0);
10258 tcg_gen_andi_i32(t0, t0, 1);
10259 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10260 goto likely;
7a387fff 10261 case OPC_BC1T:
d94536f4
AJ
10262 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10263 tcg_gen_andi_i32(t0, t0, 1);
10264 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 10265 goto not_likely;
7a387fff 10266 case OPC_BC1TL:
d94536f4
AJ
10267 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10268 tcg_gen_andi_i32(t0, t0, 1);
10269 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
10270 likely:
10271 ctx->hflags |= MIPS_HFLAG_BL;
10272 break;
5a5012ec 10273 case OPC_BC1FANY2:
a16336e4 10274 {
d94536f4
AJ
10275 TCGv_i32 t1 = tcg_temp_new_i32();
10276 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10277 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10278 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10279 tcg_temp_free_i32(t1);
d94536f4
AJ
10280 tcg_gen_andi_i32(t0, t0, 1);
10281 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10282 }
5a5012ec
TS
10283 goto not_likely;
10284 case OPC_BC1TANY2:
a16336e4 10285 {
d94536f4
AJ
10286 TCGv_i32 t1 = tcg_temp_new_i32();
10287 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10288 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10289 tcg_gen_or_i32(t0, t0, t1);
10290 tcg_temp_free_i32(t1);
10291 tcg_gen_andi_i32(t0, t0, 1);
10292 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10293 }
5a5012ec
TS
10294 goto not_likely;
10295 case OPC_BC1FANY4:
a16336e4 10296 {
d94536f4
AJ
10297 TCGv_i32 t1 = tcg_temp_new_i32();
10298 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10299 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10300 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10301 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 10302 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10303 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 10304 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10305 tcg_temp_free_i32(t1);
d94536f4
AJ
10306 tcg_gen_andi_i32(t0, t0, 1);
10307 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10308 }
5a5012ec
TS
10309 goto not_likely;
10310 case OPC_BC1TANY4:
a16336e4 10311 {
d94536f4
AJ
10312 TCGv_i32 t1 = tcg_temp_new_i32();
10313 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10314 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10315 tcg_gen_or_i32(t0, t0, t1);
10316 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10317 tcg_gen_or_i32(t0, t0, t1);
10318 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10319 tcg_gen_or_i32(t0, t0, t1);
10320 tcg_temp_free_i32(t1);
10321 tcg_gen_andi_i32(t0, t0, 1);
10322 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10323 }
5a5012ec
TS
10324 not_likely:
10325 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
10326 break;
10327 default:
9d68ac14 10328 MIPS_INVAL("cp1 cond branch");
9c708c7f 10329 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10330 goto out;
6ea83fed 10331 }
6ea83fed 10332 ctx->btarget = btarget;
b231c103 10333 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 10334 out:
a7812ae4 10335 tcg_temp_free_i32(t0);
6ea83fed
FB
10336}
10337
31837be3
YK
10338/* R6 CP1 Branches */
10339static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
10340 int32_t ft, int32_t offset,
10341 int delayslot_size)
31837be3
YK
10342{
10343 target_ulong btarget;
31837be3
YK
10344 TCGv_i64 t0 = tcg_temp_new_i64();
10345
10346 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10347#ifdef MIPS_DEBUG_DISAS
339cd2a8 10348 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10349 "\n", ctx->base.pc_next);
31837be3 10350#endif
9c708c7f 10351 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10352 goto out;
10353 }
10354
10355 gen_load_fpr64(ctx, t0, ft);
10356 tcg_gen_andi_i64(t0, t0, 1);
10357
eeb3bba8 10358 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
10359
10360 switch (op) {
10361 case OPC_BC1EQZ:
10362 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
10363 ctx->hflags |= MIPS_HFLAG_BC;
10364 break;
10365 case OPC_BC1NEZ:
10366 /* t0 already set */
31837be3
YK
10367 ctx->hflags |= MIPS_HFLAG_BC;
10368 break;
10369 default:
9d68ac14 10370 MIPS_INVAL("cp1 cond branch");
9c708c7f 10371 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10372 goto out;
10373 }
10374
10375 tcg_gen_trunc_i64_tl(bcond, t0);
10376
31837be3 10377 ctx->btarget = btarget;
65935f07
YK
10378
10379 switch (delayslot_size) {
10380 case 2:
10381 ctx->hflags |= MIPS_HFLAG_BDS16;
10382 break;
10383 case 4:
10384 ctx->hflags |= MIPS_HFLAG_BDS32;
10385 break;
10386 }
31837be3
YK
10387
10388out:
10389 tcg_temp_free_i64(t0);
10390}
10391
6af0bf9c 10392/* Coprocessor 1 (FPU) */
5a5012ec 10393
5a5012ec
TS
10394#define FOP(func, fmt) (((fmt) << 21) | (func))
10395
bf4120ad
NF
10396enum fopcode {
10397 OPC_ADD_S = FOP(0, FMT_S),
10398 OPC_SUB_S = FOP(1, FMT_S),
10399 OPC_MUL_S = FOP(2, FMT_S),
10400 OPC_DIV_S = FOP(3, FMT_S),
10401 OPC_SQRT_S = FOP(4, FMT_S),
10402 OPC_ABS_S = FOP(5, FMT_S),
10403 OPC_MOV_S = FOP(6, FMT_S),
10404 OPC_NEG_S = FOP(7, FMT_S),
10405 OPC_ROUND_L_S = FOP(8, FMT_S),
10406 OPC_TRUNC_L_S = FOP(9, FMT_S),
10407 OPC_CEIL_L_S = FOP(10, FMT_S),
10408 OPC_FLOOR_L_S = FOP(11, FMT_S),
10409 OPC_ROUND_W_S = FOP(12, FMT_S),
10410 OPC_TRUNC_W_S = FOP(13, FMT_S),
10411 OPC_CEIL_W_S = FOP(14, FMT_S),
10412 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 10413 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
10414 OPC_MOVCF_S = FOP(17, FMT_S),
10415 OPC_MOVZ_S = FOP(18, FMT_S),
10416 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 10417 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
10418 OPC_RECIP_S = FOP(21, FMT_S),
10419 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
10420 OPC_SELNEZ_S = FOP(23, FMT_S),
10421 OPC_MADDF_S = FOP(24, FMT_S),
10422 OPC_MSUBF_S = FOP(25, FMT_S),
10423 OPC_RINT_S = FOP(26, FMT_S),
10424 OPC_CLASS_S = FOP(27, FMT_S),
10425 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 10426 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 10427 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 10428 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 10429 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 10430 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 10431 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
10432 OPC_RSQRT2_S = FOP(31, FMT_S),
10433 OPC_CVT_D_S = FOP(33, FMT_S),
10434 OPC_CVT_W_S = FOP(36, FMT_S),
10435 OPC_CVT_L_S = FOP(37, FMT_S),
10436 OPC_CVT_PS_S = FOP(38, FMT_S),
10437 OPC_CMP_F_S = FOP (48, FMT_S),
10438 OPC_CMP_UN_S = FOP (49, FMT_S),
10439 OPC_CMP_EQ_S = FOP (50, FMT_S),
10440 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10441 OPC_CMP_OLT_S = FOP (52, FMT_S),
10442 OPC_CMP_ULT_S = FOP (53, FMT_S),
10443 OPC_CMP_OLE_S = FOP (54, FMT_S),
10444 OPC_CMP_ULE_S = FOP (55, FMT_S),
10445 OPC_CMP_SF_S = FOP (56, FMT_S),
10446 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10447 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10448 OPC_CMP_NGL_S = FOP (59, FMT_S),
10449 OPC_CMP_LT_S = FOP (60, FMT_S),
10450 OPC_CMP_NGE_S = FOP (61, FMT_S),
10451 OPC_CMP_LE_S = FOP (62, FMT_S),
10452 OPC_CMP_NGT_S = FOP (63, FMT_S),
10453
10454 OPC_ADD_D = FOP(0, FMT_D),
10455 OPC_SUB_D = FOP(1, FMT_D),
10456 OPC_MUL_D = FOP(2, FMT_D),
10457 OPC_DIV_D = FOP(3, FMT_D),
10458 OPC_SQRT_D = FOP(4, FMT_D),
10459 OPC_ABS_D = FOP(5, FMT_D),
10460 OPC_MOV_D = FOP(6, FMT_D),
10461 OPC_NEG_D = FOP(7, FMT_D),
10462 OPC_ROUND_L_D = FOP(8, FMT_D),
10463 OPC_TRUNC_L_D = FOP(9, FMT_D),
10464 OPC_CEIL_L_D = FOP(10, FMT_D),
10465 OPC_FLOOR_L_D = FOP(11, FMT_D),
10466 OPC_ROUND_W_D = FOP(12, FMT_D),
10467 OPC_TRUNC_W_D = FOP(13, FMT_D),
10468 OPC_CEIL_W_D = FOP(14, FMT_D),
10469 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 10470 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
10471 OPC_MOVCF_D = FOP(17, FMT_D),
10472 OPC_MOVZ_D = FOP(18, FMT_D),
10473 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 10474 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
10475 OPC_RECIP_D = FOP(21, FMT_D),
10476 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
10477 OPC_SELNEZ_D = FOP(23, FMT_D),
10478 OPC_MADDF_D = FOP(24, FMT_D),
10479 OPC_MSUBF_D = FOP(25, FMT_D),
10480 OPC_RINT_D = FOP(26, FMT_D),
10481 OPC_CLASS_D = FOP(27, FMT_D),
10482 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 10483 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 10484 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 10485 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 10486 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 10487 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 10488 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
10489 OPC_RSQRT2_D = FOP(31, FMT_D),
10490 OPC_CVT_S_D = FOP(32, FMT_D),
10491 OPC_CVT_W_D = FOP(36, FMT_D),
10492 OPC_CVT_L_D = FOP(37, FMT_D),
10493 OPC_CMP_F_D = FOP (48, FMT_D),
10494 OPC_CMP_UN_D = FOP (49, FMT_D),
10495 OPC_CMP_EQ_D = FOP (50, FMT_D),
10496 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10497 OPC_CMP_OLT_D = FOP (52, FMT_D),
10498 OPC_CMP_ULT_D = FOP (53, FMT_D),
10499 OPC_CMP_OLE_D = FOP (54, FMT_D),
10500 OPC_CMP_ULE_D = FOP (55, FMT_D),
10501 OPC_CMP_SF_D = FOP (56, FMT_D),
10502 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10503 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10504 OPC_CMP_NGL_D = FOP (59, FMT_D),
10505 OPC_CMP_LT_D = FOP (60, FMT_D),
10506 OPC_CMP_NGE_D = FOP (61, FMT_D),
10507 OPC_CMP_LE_D = FOP (62, FMT_D),
10508 OPC_CMP_NGT_D = FOP (63, FMT_D),
10509
10510 OPC_CVT_S_W = FOP(32, FMT_W),
10511 OPC_CVT_D_W = FOP(33, FMT_W),
10512 OPC_CVT_S_L = FOP(32, FMT_L),
10513 OPC_CVT_D_L = FOP(33, FMT_L),
10514 OPC_CVT_PS_PW = FOP(38, FMT_W),
10515
10516 OPC_ADD_PS = FOP(0, FMT_PS),
10517 OPC_SUB_PS = FOP(1, FMT_PS),
10518 OPC_MUL_PS = FOP(2, FMT_PS),
10519 OPC_DIV_PS = FOP(3, FMT_PS),
10520 OPC_ABS_PS = FOP(5, FMT_PS),
10521 OPC_MOV_PS = FOP(6, FMT_PS),
10522 OPC_NEG_PS = FOP(7, FMT_PS),
10523 OPC_MOVCF_PS = FOP(17, FMT_PS),
10524 OPC_MOVZ_PS = FOP(18, FMT_PS),
10525 OPC_MOVN_PS = FOP(19, FMT_PS),
10526 OPC_ADDR_PS = FOP(24, FMT_PS),
10527 OPC_MULR_PS = FOP(26, FMT_PS),
10528 OPC_RECIP2_PS = FOP(28, FMT_PS),
10529 OPC_RECIP1_PS = FOP(29, FMT_PS),
10530 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10531 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10532
10533 OPC_CVT_S_PU = FOP(32, FMT_PS),
10534 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10535 OPC_CVT_S_PL = FOP(40, FMT_PS),
10536 OPC_PLL_PS = FOP(44, FMT_PS),
10537 OPC_PLU_PS = FOP(45, FMT_PS),
10538 OPC_PUL_PS = FOP(46, FMT_PS),
10539 OPC_PUU_PS = FOP(47, FMT_PS),
10540 OPC_CMP_F_PS = FOP (48, FMT_PS),
10541 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10542 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10543 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10544 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10545 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10546 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10547 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10548 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10549 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10550 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10551 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10552 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10553 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10554 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10555 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10556};
10557
3f493883
YK
10558enum r6_f_cmp_op {
10559 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10560 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10561 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10562 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10563 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10564 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10565 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10566 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10567 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10568 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10569 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10570 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10571 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10572 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10573 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10574 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10575 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10576 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10577 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10578 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10579 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10580 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10581
10582 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10583 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10584 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10585 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10586 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10587 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10588 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10589 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10590 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10591 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10592 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10593 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10594 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10595 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10596 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10597 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10598 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10599 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10600 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10601 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10602 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10603 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10604};
7a387fff 10605static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 10606{
72c3a3ee 10607 TCGv t0 = tcg_temp_new();
6ea83fed
FB
10608
10609 switch (opc) {
10610 case OPC_MFC1:
b6d96bed 10611 {
a7812ae4 10612 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10613
7c979afd 10614 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 10615 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10616 tcg_temp_free_i32(fp0);
6958549d 10617 }
6c5c1e20 10618 gen_store_gpr(t0, rt);
6ea83fed
FB
10619 break;
10620 case OPC_MTC1:
6c5c1e20 10621 gen_load_gpr(t0, rt);
b6d96bed 10622 {
a7812ae4 10623 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10624
10625 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10626 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 10627 tcg_temp_free_i32(fp0);
6958549d 10628 }
6ea83fed
FB
10629 break;
10630 case OPC_CFC1:
895c2d04 10631 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 10632 gen_store_gpr(t0, rt);
6ea83fed
FB
10633 break;
10634 case OPC_CTC1:
6c5c1e20 10635 gen_load_gpr(t0, rt);
9c708c7f 10636 save_cpu_state(ctx, 0);
736d120a
PJ
10637 {
10638 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10639
10640 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10641 tcg_temp_free_i32(fs_tmp);
10642 }
4cf8a45f 10643 /* Stop translation as we may have changed hflags */
eeb3bba8 10644 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 10645 break;
72c3a3ee 10646#if defined(TARGET_MIPS64)
9c2149c8 10647 case OPC_DMFC1:
72c3a3ee 10648 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 10649 gen_store_gpr(t0, rt);
5a5012ec 10650 break;
9c2149c8 10651 case OPC_DMTC1:
6c5c1e20 10652 gen_load_gpr(t0, rt);
72c3a3ee 10653 gen_store_fpr64(ctx, t0, fs);
5a5012ec 10654 break;
72c3a3ee 10655#endif
5a5012ec 10656 case OPC_MFHC1:
b6d96bed 10657 {
a7812ae4 10658 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10659
7f6613ce 10660 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 10661 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10662 tcg_temp_free_i32(fp0);
6958549d 10663 }
6c5c1e20 10664 gen_store_gpr(t0, rt);
5a5012ec
TS
10665 break;
10666 case OPC_MTHC1:
6c5c1e20 10667 gen_load_gpr(t0, rt);
b6d96bed 10668 {
a7812ae4 10669 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10670
10671 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 10672 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 10673 tcg_temp_free_i32(fp0);
6958549d 10674 }
5a5012ec 10675 break;
6ea83fed 10676 default:
9d68ac14 10677 MIPS_INVAL("cp1 move");
9c708c7f 10678 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10679 goto out;
6ea83fed 10680 }
6c5c1e20
TS
10681
10682 out:
10683 tcg_temp_free(t0);
6ea83fed
FB
10684}
10685
5a5012ec
TS
10686static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10687{
42a268c2 10688 TCGLabel *l1;
e214b9bb 10689 TCGCond cond;
af58f9ca
AJ
10690 TCGv_i32 t0;
10691
10692 if (rd == 0) {
10693 /* Treat as NOP. */
10694 return;
10695 }
6ea83fed 10696
e214b9bb 10697 if (tf)
e214b9bb 10698 cond = TCG_COND_EQ;
27848470
TS
10699 else
10700 cond = TCG_COND_NE;
10701
af58f9ca
AJ
10702 l1 = gen_new_label();
10703 t0 = tcg_temp_new_i32();
fa31af0e 10704 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 10705 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10706 tcg_temp_free_i32(t0);
af58f9ca
AJ
10707 if (rs == 0) {
10708 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10709 } else {
10710 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10711 }
e214b9bb 10712 gen_set_label(l1);
5a5012ec
TS
10713}
10714
7c979afd
LA
10715static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10716 int tf)
a16336e4 10717{
a16336e4 10718 int cond;
cbc37b28 10719 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 10720 TCGLabel *l1 = gen_new_label();
a16336e4 10721
a16336e4
TS
10722 if (tf)
10723 cond = TCG_COND_EQ;
10724 else
10725 cond = TCG_COND_NE;
10726
fa31af0e 10727 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10728 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10729 gen_load_fpr32(ctx, t0, fs);
10730 gen_store_fpr32(ctx, t0, fd);
a16336e4 10731 gen_set_label(l1);
cbc37b28 10732 tcg_temp_free_i32(t0);
5a5012ec 10733}
a16336e4 10734
b6d96bed 10735static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 10736{
a16336e4 10737 int cond;
cbc37b28
AJ
10738 TCGv_i32 t0 = tcg_temp_new_i32();
10739 TCGv_i64 fp0;
42a268c2 10740 TCGLabel *l1 = gen_new_label();
a16336e4 10741
a16336e4
TS
10742 if (tf)
10743 cond = TCG_COND_EQ;
10744 else
10745 cond = TCG_COND_NE;
10746
fa31af0e 10747 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10748 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10749 tcg_temp_free_i32(t0);
11f94258 10750 fp0 = tcg_temp_new_i64();
9bf3eb2c 10751 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 10752 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10753 tcg_temp_free_i64(fp0);
cbc37b28 10754 gen_set_label(l1);
a16336e4
TS
10755}
10756
7f6613ce
PJ
10757static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10758 int cc, int tf)
a16336e4
TS
10759{
10760 int cond;
cbc37b28 10761 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
10762 TCGLabel *l1 = gen_new_label();
10763 TCGLabel *l2 = gen_new_label();
a16336e4
TS
10764
10765 if (tf)
10766 cond = TCG_COND_EQ;
10767 else
10768 cond = TCG_COND_NE;
10769
fa31af0e 10770 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10771 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10772 gen_load_fpr32(ctx, t0, fs);
10773 gen_store_fpr32(ctx, t0, fd);
a16336e4 10774 gen_set_label(l1);
9bf3eb2c 10775
fa31af0e 10776 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 10777 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
10778 gen_load_fpr32h(ctx, t0, fs);
10779 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 10780 tcg_temp_free_i32(t0);
a16336e4 10781 gen_set_label(l2);
a16336e4
TS
10782}
10783
e7f16abb
LA
10784static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10785 int fs)
10786{
10787 TCGv_i32 t1 = tcg_const_i32(0);
10788 TCGv_i32 fp0 = tcg_temp_new_i32();
10789 TCGv_i32 fp1 = tcg_temp_new_i32();
10790 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10791 gen_load_fpr32(ctx, fp0, fd);
10792 gen_load_fpr32(ctx, fp1, ft);
10793 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
10794
10795 switch (op1) {
10796 case OPC_SEL_S:
10797 tcg_gen_andi_i32(fp0, fp0, 1);
10798 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10799 break;
10800 case OPC_SELEQZ_S:
10801 tcg_gen_andi_i32(fp1, fp1, 1);
10802 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10803 break;
10804 case OPC_SELNEZ_S:
10805 tcg_gen_andi_i32(fp1, fp1, 1);
10806 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10807 break;
10808 default:
10809 MIPS_INVAL("gen_sel_s");
9c708c7f 10810 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10811 break;
10812 }
10813
7c979afd 10814 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10815 tcg_temp_free_i32(fp2);
10816 tcg_temp_free_i32(fp1);
10817 tcg_temp_free_i32(fp0);
10818 tcg_temp_free_i32(t1);
10819}
10820
10821static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10822 int fs)
10823{
10824 TCGv_i64 t1 = tcg_const_i64(0);
10825 TCGv_i64 fp0 = tcg_temp_new_i64();
10826 TCGv_i64 fp1 = tcg_temp_new_i64();
10827 TCGv_i64 fp2 = tcg_temp_new_i64();
10828 gen_load_fpr64(ctx, fp0, fd);
10829 gen_load_fpr64(ctx, fp1, ft);
10830 gen_load_fpr64(ctx, fp2, fs);
10831
10832 switch (op1) {
10833 case OPC_SEL_D:
10834 tcg_gen_andi_i64(fp0, fp0, 1);
10835 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10836 break;
10837 case OPC_SELEQZ_D:
10838 tcg_gen_andi_i64(fp1, fp1, 1);
10839 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10840 break;
10841 case OPC_SELNEZ_D:
10842 tcg_gen_andi_i64(fp1, fp1, 1);
10843 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10844 break;
10845 default:
10846 MIPS_INVAL("gen_sel_d");
9c708c7f 10847 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10848 break;
10849 }
10850
10851 gen_store_fpr64(ctx, fp0, fd);
10852 tcg_temp_free_i64(fp2);
10853 tcg_temp_free_i64(fp1);
10854 tcg_temp_free_i64(fp0);
10855 tcg_temp_free_i64(t1);
10856}
6ea83fed 10857
bf4120ad 10858static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 10859 int ft, int fs, int fd, int cc)
6ea83fed 10860{
7a387fff 10861 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
10862 switch (op1) {
10863 case OPC_ADD_S:
b6d96bed 10864 {
a7812ae4
PB
10865 TCGv_i32 fp0 = tcg_temp_new_i32();
10866 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10867
7c979afd
LA
10868 gen_load_fpr32(ctx, fp0, fs);
10869 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10870 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10871 tcg_temp_free_i32(fp1);
7c979afd 10872 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10873 tcg_temp_free_i32(fp0);
b6d96bed 10874 }
5a5012ec 10875 break;
bf4120ad 10876 case OPC_SUB_S:
b6d96bed 10877 {
a7812ae4
PB
10878 TCGv_i32 fp0 = tcg_temp_new_i32();
10879 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10880
7c979afd
LA
10881 gen_load_fpr32(ctx, fp0, fs);
10882 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10883 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10884 tcg_temp_free_i32(fp1);
7c979afd 10885 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10886 tcg_temp_free_i32(fp0);
b6d96bed 10887 }
5a5012ec 10888 break;
bf4120ad 10889 case OPC_MUL_S:
b6d96bed 10890 {
a7812ae4
PB
10891 TCGv_i32 fp0 = tcg_temp_new_i32();
10892 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10893
7c979afd
LA
10894 gen_load_fpr32(ctx, fp0, fs);
10895 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10896 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10897 tcg_temp_free_i32(fp1);
7c979afd 10898 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10899 tcg_temp_free_i32(fp0);
b6d96bed 10900 }
5a5012ec 10901 break;
bf4120ad 10902 case OPC_DIV_S:
b6d96bed 10903 {
a7812ae4
PB
10904 TCGv_i32 fp0 = tcg_temp_new_i32();
10905 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10906
7c979afd
LA
10907 gen_load_fpr32(ctx, fp0, fs);
10908 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10909 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10910 tcg_temp_free_i32(fp1);
7c979afd 10911 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10912 tcg_temp_free_i32(fp0);
b6d96bed 10913 }
5a5012ec 10914 break;
bf4120ad 10915 case OPC_SQRT_S:
b6d96bed 10916 {
a7812ae4 10917 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10918
7c979afd 10919 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10920 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 10921 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10922 tcg_temp_free_i32(fp0);
b6d96bed 10923 }
5a5012ec 10924 break;
bf4120ad 10925 case OPC_ABS_S:
b6d96bed 10926 {
a7812ae4 10927 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10928
7c979afd 10929 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10930 if (ctx->abs2008) {
10931 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10932 } else {
10933 gen_helper_float_abs_s(fp0, fp0);
10934 }
7c979afd 10935 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10936 tcg_temp_free_i32(fp0);
b6d96bed 10937 }
5a5012ec 10938 break;
bf4120ad 10939 case OPC_MOV_S:
b6d96bed 10940 {
a7812ae4 10941 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10942
7c979afd
LA
10943 gen_load_fpr32(ctx, fp0, fs);
10944 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10945 tcg_temp_free_i32(fp0);
b6d96bed 10946 }
5a5012ec 10947 break;
bf4120ad 10948 case OPC_NEG_S:
b6d96bed 10949 {
a7812ae4 10950 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10951
7c979afd 10952 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10953 if (ctx->abs2008) {
10954 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10955 } else {
10956 gen_helper_float_chs_s(fp0, fp0);
10957 }
7c979afd 10958 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10959 tcg_temp_free_i32(fp0);
b6d96bed 10960 }
5a5012ec 10961 break;
bf4120ad 10962 case OPC_ROUND_L_S:
5e755519 10963 check_cp1_64bitmode(ctx);
b6d96bed 10964 {
a7812ae4
PB
10965 TCGv_i32 fp32 = tcg_temp_new_i32();
10966 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10967
7c979afd 10968 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10969 if (ctx->nan2008) {
10970 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10971 } else {
10972 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10973 }
a7812ae4 10974 tcg_temp_free_i32(fp32);
b6d96bed 10975 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10976 tcg_temp_free_i64(fp64);
b6d96bed 10977 }
5a5012ec 10978 break;
bf4120ad 10979 case OPC_TRUNC_L_S:
5e755519 10980 check_cp1_64bitmode(ctx);
b6d96bed 10981 {
a7812ae4
PB
10982 TCGv_i32 fp32 = tcg_temp_new_i32();
10983 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10984
7c979afd 10985 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10986 if (ctx->nan2008) {
10987 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10988 } else {
10989 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10990 }
a7812ae4 10991 tcg_temp_free_i32(fp32);
b6d96bed 10992 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10993 tcg_temp_free_i64(fp64);
b6d96bed 10994 }
5a5012ec 10995 break;
bf4120ad 10996 case OPC_CEIL_L_S:
5e755519 10997 check_cp1_64bitmode(ctx);
b6d96bed 10998 {
a7812ae4
PB
10999 TCGv_i32 fp32 = tcg_temp_new_i32();
11000 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11001
7c979afd 11002 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11003 if (ctx->nan2008) {
11004 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11005 } else {
11006 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11007 }
a7812ae4 11008 tcg_temp_free_i32(fp32);
b6d96bed 11009 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11010 tcg_temp_free_i64(fp64);
b6d96bed 11011 }
5a5012ec 11012 break;
bf4120ad 11013 case OPC_FLOOR_L_S:
5e755519 11014 check_cp1_64bitmode(ctx);
b6d96bed 11015 {
a7812ae4
PB
11016 TCGv_i32 fp32 = tcg_temp_new_i32();
11017 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11018
7c979afd 11019 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11020 if (ctx->nan2008) {
11021 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11022 } else {
11023 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11024 }
a7812ae4 11025 tcg_temp_free_i32(fp32);
b6d96bed 11026 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11027 tcg_temp_free_i64(fp64);
b6d96bed 11028 }
5a5012ec 11029 break;
bf4120ad 11030 case OPC_ROUND_W_S:
b6d96bed 11031 {
a7812ae4 11032 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11033
7c979afd 11034 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11035 if (ctx->nan2008) {
11036 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11037 } else {
11038 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11039 }
7c979afd 11040 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11041 tcg_temp_free_i32(fp0);
b6d96bed 11042 }
5a5012ec 11043 break;
bf4120ad 11044 case OPC_TRUNC_W_S:
b6d96bed 11045 {
a7812ae4 11046 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11047
7c979afd 11048 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11049 if (ctx->nan2008) {
11050 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11051 } else {
11052 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11053 }
7c979afd 11054 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11055 tcg_temp_free_i32(fp0);
b6d96bed 11056 }
5a5012ec 11057 break;
bf4120ad 11058 case OPC_CEIL_W_S:
b6d96bed 11059 {
a7812ae4 11060 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11061
7c979afd 11062 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11063 if (ctx->nan2008) {
11064 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11065 } else {
11066 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11067 }
7c979afd 11068 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11069 tcg_temp_free_i32(fp0);
b6d96bed 11070 }
5a5012ec 11071 break;
bf4120ad 11072 case OPC_FLOOR_W_S:
b6d96bed 11073 {
a7812ae4 11074 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11075
7c979afd 11076 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11077 if (ctx->nan2008) {
11078 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11079 } else {
11080 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11081 }
7c979afd 11082 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11083 tcg_temp_free_i32(fp0);
b6d96bed 11084 }
5a5012ec 11085 break;
e7f16abb
LA
11086 case OPC_SEL_S:
11087 check_insn(ctx, ISA_MIPS32R6);
11088 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11089 break;
11090 case OPC_SELEQZ_S:
11091 check_insn(ctx, ISA_MIPS32R6);
11092 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11093 break;
11094 case OPC_SELNEZ_S:
11095 check_insn(ctx, ISA_MIPS32R6);
11096 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 11097 break;
bf4120ad 11098 case OPC_MOVCF_S:
fecd2646 11099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 11100 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 11101 break;
bf4120ad 11102 case OPC_MOVZ_S:
fecd2646 11103 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11104 {
42a268c2 11105 TCGLabel *l1 = gen_new_label();
c9297f4d 11106 TCGv_i32 fp0;
a16336e4 11107
c9297f4d
AJ
11108 if (ft != 0) {
11109 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11110 }
11111 fp0 = tcg_temp_new_i32();
7c979afd
LA
11112 gen_load_fpr32(ctx, fp0, fs);
11113 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11114 tcg_temp_free_i32(fp0);
a16336e4
TS
11115 gen_set_label(l1);
11116 }
5a5012ec 11117 break;
bf4120ad 11118 case OPC_MOVN_S:
fecd2646 11119 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11120 {
42a268c2 11121 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11122 TCGv_i32 fp0;
11123
11124 if (ft != 0) {
11125 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11126 fp0 = tcg_temp_new_i32();
7c979afd
LA
11127 gen_load_fpr32(ctx, fp0, fs);
11128 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
11129 tcg_temp_free_i32(fp0);
11130 gen_set_label(l1);
11131 }
a16336e4 11132 }
5a5012ec 11133 break;
bf4120ad 11134 case OPC_RECIP_S:
b6d96bed 11135 {
a7812ae4 11136 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11137
7c979afd 11138 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11139 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 11140 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11141 tcg_temp_free_i32(fp0);
b6d96bed 11142 }
57fa1fb3 11143 break;
bf4120ad 11144 case OPC_RSQRT_S:
b6d96bed 11145 {
a7812ae4 11146 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11147
7c979afd 11148 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11149 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 11150 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11151 tcg_temp_free_i32(fp0);
b6d96bed 11152 }
57fa1fb3 11153 break;
e7f16abb
LA
11154 case OPC_MADDF_S:
11155 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11156 {
a7812ae4
PB
11157 TCGv_i32 fp0 = tcg_temp_new_i32();
11158 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11159 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11160 gen_load_fpr32(ctx, fp0, fs);
11161 gen_load_fpr32(ctx, fp1, ft);
11162 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11163 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11164 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 11165 tcg_temp_free_i32(fp2);
a7812ae4 11166 tcg_temp_free_i32(fp1);
a7812ae4 11167 tcg_temp_free_i32(fp0);
b6d96bed 11168 }
57fa1fb3 11169 break;
e7f16abb
LA
11170 case OPC_MSUBF_S:
11171 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11172 {
a7812ae4 11173 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
11174 TCGv_i32 fp1 = tcg_temp_new_i32();
11175 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11176 gen_load_fpr32(ctx, fp0, fs);
11177 gen_load_fpr32(ctx, fp1, ft);
11178 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11179 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11180 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11181 tcg_temp_free_i32(fp2);
11182 tcg_temp_free_i32(fp1);
a7812ae4 11183 tcg_temp_free_i32(fp0);
b6d96bed 11184 }
57fa1fb3 11185 break;
e7f16abb
LA
11186 case OPC_RINT_S:
11187 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11188 {
a7812ae4 11189 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11190 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11191 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 11192 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11193 tcg_temp_free_i32(fp0);
b6d96bed 11194 }
57fa1fb3 11195 break;
e7f16abb
LA
11196 case OPC_CLASS_S:
11197 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11198 {
e7f16abb 11199 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11200 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 11201 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 11202 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 11203 tcg_temp_free_i32(fp0);
e7f16abb
LA
11204 }
11205 break;
11206 case OPC_MIN_S: /* OPC_RECIP2_S */
11207 if (ctx->insn_flags & ISA_MIPS32R6) {
11208 /* OPC_MIN_S */
a7812ae4
PB
11209 TCGv_i32 fp0 = tcg_temp_new_i32();
11210 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11211 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11212 gen_load_fpr32(ctx, fp0, fs);
11213 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11214 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 11215 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11216 tcg_temp_free_i32(fp2);
11217 tcg_temp_free_i32(fp1);
11218 tcg_temp_free_i32(fp0);
e7f16abb
LA
11219 } else {
11220 /* OPC_RECIP2_S */
11221 check_cp1_64bitmode(ctx);
11222 {
11223 TCGv_i32 fp0 = tcg_temp_new_i32();
11224 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11225
7c979afd
LA
11226 gen_load_fpr32(ctx, fp0, fs);
11227 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11228 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11229 tcg_temp_free_i32(fp1);
7c979afd 11230 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11231 tcg_temp_free_i32(fp0);
11232 }
e7f16abb
LA
11233 }
11234 break;
11235 case OPC_MINA_S: /* OPC_RECIP1_S */
11236 if (ctx->insn_flags & ISA_MIPS32R6) {
11237 /* OPC_MINA_S */
11238 TCGv_i32 fp0 = tcg_temp_new_i32();
11239 TCGv_i32 fp1 = tcg_temp_new_i32();
11240 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11241 gen_load_fpr32(ctx, fp0, fs);
11242 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11243 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 11244 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11245 tcg_temp_free_i32(fp2);
11246 tcg_temp_free_i32(fp1);
11247 tcg_temp_free_i32(fp0);
e7f16abb
LA
11248 } else {
11249 /* OPC_RECIP1_S */
11250 check_cp1_64bitmode(ctx);
11251 {
11252 TCGv_i32 fp0 = tcg_temp_new_i32();
11253
7c979afd 11254 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11255 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 11256 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11257 tcg_temp_free_i32(fp0);
11258 }
e7f16abb
LA
11259 }
11260 break;
11261 case OPC_MAX_S: /* OPC_RSQRT1_S */
11262 if (ctx->insn_flags & ISA_MIPS32R6) {
11263 /* OPC_MAX_S */
11264 TCGv_i32 fp0 = tcg_temp_new_i32();
11265 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11266 gen_load_fpr32(ctx, fp0, fs);
11267 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11268 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 11269 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
11270 tcg_temp_free_i32(fp1);
11271 tcg_temp_free_i32(fp0);
e7f16abb
LA
11272 } else {
11273 /* OPC_RSQRT1_S */
11274 check_cp1_64bitmode(ctx);
11275 {
11276 TCGv_i32 fp0 = tcg_temp_new_i32();
11277
7c979afd 11278 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11279 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 11280 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11281 tcg_temp_free_i32(fp0);
11282 }
e7f16abb
LA
11283 }
11284 break;
11285 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11286 if (ctx->insn_flags & ISA_MIPS32R6) {
11287 /* OPC_MAXA_S */
11288 TCGv_i32 fp0 = tcg_temp_new_i32();
11289 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11290 gen_load_fpr32(ctx, fp0, fs);
11291 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11292 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 11293 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 11294 tcg_temp_free_i32(fp1);
a7812ae4 11295 tcg_temp_free_i32(fp0);
e7f16abb
LA
11296 } else {
11297 /* OPC_RSQRT2_S */
11298 check_cp1_64bitmode(ctx);
11299 {
11300 TCGv_i32 fp0 = tcg_temp_new_i32();
11301 TCGv_i32 fp1 = tcg_temp_new_i32();
11302
7c979afd
LA
11303 gen_load_fpr32(ctx, fp0, fs);
11304 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11305 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11306 tcg_temp_free_i32(fp1);
7c979afd 11307 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11308 tcg_temp_free_i32(fp0);
11309 }
b6d96bed 11310 }
57fa1fb3 11311 break;
bf4120ad 11312 case OPC_CVT_D_S:
5e755519 11313 check_cp1_registers(ctx, fd);
b6d96bed 11314 {
a7812ae4
PB
11315 TCGv_i32 fp32 = tcg_temp_new_i32();
11316 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11317
7c979afd 11318 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11319 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 11320 tcg_temp_free_i32(fp32);
b6d96bed 11321 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11322 tcg_temp_free_i64(fp64);
b6d96bed 11323 }
5a5012ec 11324 break;
bf4120ad 11325 case OPC_CVT_W_S:
b6d96bed 11326 {
a7812ae4 11327 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11328
7c979afd 11329 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11330 if (ctx->nan2008) {
11331 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11332 } else {
11333 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11334 }
7c979afd 11335 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11336 tcg_temp_free_i32(fp0);
b6d96bed 11337 }
5a5012ec 11338 break;
bf4120ad 11339 case OPC_CVT_L_S:
5e755519 11340 check_cp1_64bitmode(ctx);
b6d96bed 11341 {
a7812ae4
PB
11342 TCGv_i32 fp32 = tcg_temp_new_i32();
11343 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11344
7c979afd 11345 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11346 if (ctx->nan2008) {
11347 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11348 } else {
11349 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11350 }
a7812ae4 11351 tcg_temp_free_i32(fp32);
b6d96bed 11352 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11353 tcg_temp_free_i64(fp64);
b6d96bed 11354 }
5a5012ec 11355 break;
bf4120ad 11356 case OPC_CVT_PS_S:
e29c9628 11357 check_ps(ctx);
b6d96bed 11358 {
a7812ae4
PB
11359 TCGv_i64 fp64 = tcg_temp_new_i64();
11360 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11361 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 11362
7c979afd
LA
11363 gen_load_fpr32(ctx, fp32_0, fs);
11364 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 11365 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
11366 tcg_temp_free_i32(fp32_1);
11367 tcg_temp_free_i32(fp32_0);
36aa55dc 11368 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11369 tcg_temp_free_i64(fp64);
b6d96bed 11370 }
5a5012ec 11371 break;
bf4120ad
NF
11372 case OPC_CMP_F_S:
11373 case OPC_CMP_UN_S:
11374 case OPC_CMP_EQ_S:
11375 case OPC_CMP_UEQ_S:
11376 case OPC_CMP_OLT_S:
11377 case OPC_CMP_ULT_S:
11378 case OPC_CMP_OLE_S:
11379 case OPC_CMP_ULE_S:
11380 case OPC_CMP_SF_S:
11381 case OPC_CMP_NGLE_S:
11382 case OPC_CMP_SEQ_S:
11383 case OPC_CMP_NGL_S:
11384 case OPC_CMP_LT_S:
11385 case OPC_CMP_NGE_S:
11386 case OPC_CMP_LE_S:
11387 case OPC_CMP_NGT_S:
fecd2646 11388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11389 if (ctx->opcode & (1 << 6)) {
11390 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
11391 } else {
11392 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 11393 }
5a5012ec 11394 break;
bf4120ad 11395 case OPC_ADD_D:
5e755519 11396 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11397 {
a7812ae4
PB
11398 TCGv_i64 fp0 = tcg_temp_new_i64();
11399 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11400
11401 gen_load_fpr64(ctx, fp0, fs);
11402 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11403 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11404 tcg_temp_free_i64(fp1);
b6d96bed 11405 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11406 tcg_temp_free_i64(fp0);
b6d96bed 11407 }
6ea83fed 11408 break;
bf4120ad 11409 case OPC_SUB_D:
5e755519 11410 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11411 {
a7812ae4
PB
11412 TCGv_i64 fp0 = tcg_temp_new_i64();
11413 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11414
11415 gen_load_fpr64(ctx, fp0, fs);
11416 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11417 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11418 tcg_temp_free_i64(fp1);
b6d96bed 11419 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11420 tcg_temp_free_i64(fp0);
b6d96bed 11421 }
6ea83fed 11422 break;
bf4120ad 11423 case OPC_MUL_D:
5e755519 11424 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11425 {
a7812ae4
PB
11426 TCGv_i64 fp0 = tcg_temp_new_i64();
11427 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11428
11429 gen_load_fpr64(ctx, fp0, fs);
11430 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11431 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11432 tcg_temp_free_i64(fp1);
b6d96bed 11433 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11434 tcg_temp_free_i64(fp0);
b6d96bed 11435 }
6ea83fed 11436 break;
bf4120ad 11437 case OPC_DIV_D:
5e755519 11438 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11439 {
a7812ae4
PB
11440 TCGv_i64 fp0 = tcg_temp_new_i64();
11441 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11442
11443 gen_load_fpr64(ctx, fp0, fs);
11444 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11445 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11446 tcg_temp_free_i64(fp1);
b6d96bed 11447 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11448 tcg_temp_free_i64(fp0);
b6d96bed 11449 }
6ea83fed 11450 break;
bf4120ad 11451 case OPC_SQRT_D:
5e755519 11452 check_cp1_registers(ctx, fs | fd);
b6d96bed 11453 {
a7812ae4 11454 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11455
11456 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11457 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 11458 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11459 tcg_temp_free_i64(fp0);
b6d96bed 11460 }
6ea83fed 11461 break;
bf4120ad 11462 case OPC_ABS_D:
5e755519 11463 check_cp1_registers(ctx, fs | fd);
b6d96bed 11464 {
a7812ae4 11465 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11466
11467 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11468 if (ctx->abs2008) {
11469 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11470 } else {
11471 gen_helper_float_abs_d(fp0, fp0);
11472 }
b6d96bed 11473 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11474 tcg_temp_free_i64(fp0);
b6d96bed 11475 }
6ea83fed 11476 break;
bf4120ad 11477 case OPC_MOV_D:
5e755519 11478 check_cp1_registers(ctx, fs | fd);
b6d96bed 11479 {
a7812ae4 11480 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11481
11482 gen_load_fpr64(ctx, fp0, fs);
11483 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11484 tcg_temp_free_i64(fp0);
b6d96bed 11485 }
6ea83fed 11486 break;
bf4120ad 11487 case OPC_NEG_D:
5e755519 11488 check_cp1_registers(ctx, fs | fd);
b6d96bed 11489 {
a7812ae4 11490 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11491
11492 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11493 if (ctx->abs2008) {
11494 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11495 } else {
11496 gen_helper_float_chs_d(fp0, fp0);
11497 }
b6d96bed 11498 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11499 tcg_temp_free_i64(fp0);
b6d96bed 11500 }
6ea83fed 11501 break;
bf4120ad 11502 case OPC_ROUND_L_D:
5e755519 11503 check_cp1_64bitmode(ctx);
b6d96bed 11504 {
a7812ae4 11505 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11506
11507 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11508 if (ctx->nan2008) {
11509 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11510 } else {
11511 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11512 }
b6d96bed 11513 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11514 tcg_temp_free_i64(fp0);
b6d96bed 11515 }
5a5012ec 11516 break;
bf4120ad 11517 case OPC_TRUNC_L_D:
5e755519 11518 check_cp1_64bitmode(ctx);
b6d96bed 11519 {
a7812ae4 11520 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11521
11522 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11523 if (ctx->nan2008) {
11524 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11525 } else {
11526 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11527 }
b6d96bed 11528 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11529 tcg_temp_free_i64(fp0);
b6d96bed 11530 }
5a5012ec 11531 break;
bf4120ad 11532 case OPC_CEIL_L_D:
5e755519 11533 check_cp1_64bitmode(ctx);
b6d96bed 11534 {
a7812ae4 11535 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11536
11537 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11538 if (ctx->nan2008) {
11539 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11540 } else {
11541 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11542 }
b6d96bed 11543 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11544 tcg_temp_free_i64(fp0);
b6d96bed 11545 }
5a5012ec 11546 break;
bf4120ad 11547 case OPC_FLOOR_L_D:
5e755519 11548 check_cp1_64bitmode(ctx);
b6d96bed 11549 {
a7812ae4 11550 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11551
11552 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11553 if (ctx->nan2008) {
11554 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11555 } else {
11556 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11557 }
b6d96bed 11558 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11559 tcg_temp_free_i64(fp0);
b6d96bed 11560 }
5a5012ec 11561 break;
bf4120ad 11562 case OPC_ROUND_W_D:
5e755519 11563 check_cp1_registers(ctx, fs);
b6d96bed 11564 {
a7812ae4
PB
11565 TCGv_i32 fp32 = tcg_temp_new_i32();
11566 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11567
11568 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11569 if (ctx->nan2008) {
11570 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11571 } else {
11572 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11573 }
a7812ae4 11574 tcg_temp_free_i64(fp64);
7c979afd 11575 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11576 tcg_temp_free_i32(fp32);
b6d96bed 11577 }
6ea83fed 11578 break;
bf4120ad 11579 case OPC_TRUNC_W_D:
5e755519 11580 check_cp1_registers(ctx, fs);
b6d96bed 11581 {
a7812ae4
PB
11582 TCGv_i32 fp32 = tcg_temp_new_i32();
11583 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11584
11585 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11586 if (ctx->nan2008) {
11587 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11588 } else {
11589 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11590 }
a7812ae4 11591 tcg_temp_free_i64(fp64);
7c979afd 11592 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11593 tcg_temp_free_i32(fp32);
b6d96bed 11594 }
6ea83fed 11595 break;
bf4120ad 11596 case OPC_CEIL_W_D:
5e755519 11597 check_cp1_registers(ctx, fs);
b6d96bed 11598 {
a7812ae4
PB
11599 TCGv_i32 fp32 = tcg_temp_new_i32();
11600 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11601
11602 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11603 if (ctx->nan2008) {
11604 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11605 } else {
11606 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11607 }
a7812ae4 11608 tcg_temp_free_i64(fp64);
7c979afd 11609 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11610 tcg_temp_free_i32(fp32);
b6d96bed 11611 }
6ea83fed 11612 break;
bf4120ad 11613 case OPC_FLOOR_W_D:
5e755519 11614 check_cp1_registers(ctx, fs);
b6d96bed 11615 {
a7812ae4
PB
11616 TCGv_i32 fp32 = tcg_temp_new_i32();
11617 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11618
11619 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11620 if (ctx->nan2008) {
11621 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11622 } else {
11623 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11624 }
a7812ae4 11625 tcg_temp_free_i64(fp64);
7c979afd 11626 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11627 tcg_temp_free_i32(fp32);
b6d96bed 11628 }
6ea83fed 11629 break;
e7f16abb
LA
11630 case OPC_SEL_D:
11631 check_insn(ctx, ISA_MIPS32R6);
11632 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11633 break;
11634 case OPC_SELEQZ_D:
11635 check_insn(ctx, ISA_MIPS32R6);
11636 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11637 break;
11638 case OPC_SELNEZ_D:
11639 check_insn(ctx, ISA_MIPS32R6);
11640 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 11641 break;
bf4120ad 11642 case OPC_MOVCF_D:
fecd2646 11643 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 11644 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 11645 break;
bf4120ad 11646 case OPC_MOVZ_D:
fecd2646 11647 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11648 {
42a268c2 11649 TCGLabel *l1 = gen_new_label();
c9297f4d 11650 TCGv_i64 fp0;
a16336e4 11651
c9297f4d
AJ
11652 if (ft != 0) {
11653 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11654 }
11655 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11656 gen_load_fpr64(ctx, fp0, fs);
11657 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11658 tcg_temp_free_i64(fp0);
a16336e4
TS
11659 gen_set_label(l1);
11660 }
5a5012ec 11661 break;
bf4120ad 11662 case OPC_MOVN_D:
fecd2646 11663 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11664 {
42a268c2 11665 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11666 TCGv_i64 fp0;
11667
11668 if (ft != 0) {
11669 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11670 fp0 = tcg_temp_new_i64();
11671 gen_load_fpr64(ctx, fp0, fs);
11672 gen_store_fpr64(ctx, fp0, fd);
11673 tcg_temp_free_i64(fp0);
11674 gen_set_label(l1);
11675 }
a16336e4 11676 }
6ea83fed 11677 break;
bf4120ad 11678 case OPC_RECIP_D:
ca6c7803 11679 check_cp1_registers(ctx, fs | fd);
b6d96bed 11680 {
a7812ae4 11681 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11682
11683 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11684 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 11685 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11686 tcg_temp_free_i64(fp0);
b6d96bed 11687 }
57fa1fb3 11688 break;
bf4120ad 11689 case OPC_RSQRT_D:
ca6c7803 11690 check_cp1_registers(ctx, fs | fd);
b6d96bed 11691 {
a7812ae4 11692 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11693
11694 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11695 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 11696 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11697 tcg_temp_free_i64(fp0);
b6d96bed 11698 }
57fa1fb3 11699 break;
e7f16abb
LA
11700 case OPC_MADDF_D:
11701 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11702 {
a7812ae4
PB
11703 TCGv_i64 fp0 = tcg_temp_new_i64();
11704 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 11705 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11706 gen_load_fpr64(ctx, fp0, fs);
11707 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11708 gen_load_fpr64(ctx, fp2, fd);
11709 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11710 gen_store_fpr64(ctx, fp2, fd);
11711 tcg_temp_free_i64(fp2);
a7812ae4 11712 tcg_temp_free_i64(fp1);
a7812ae4 11713 tcg_temp_free_i64(fp0);
b6d96bed 11714 }
57fa1fb3 11715 break;
e7f16abb
LA
11716 case OPC_MSUBF_D:
11717 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11718 {
a7812ae4 11719 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
11720 TCGv_i64 fp1 = tcg_temp_new_i64();
11721 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 11722 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
11723 gen_load_fpr64(ctx, fp1, ft);
11724 gen_load_fpr64(ctx, fp2, fd);
11725 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11726 gen_store_fpr64(ctx, fp2, fd);
11727 tcg_temp_free_i64(fp2);
11728 tcg_temp_free_i64(fp1);
a7812ae4 11729 tcg_temp_free_i64(fp0);
b6d96bed 11730 }
57fa1fb3 11731 break;
e7f16abb
LA
11732 case OPC_RINT_D:
11733 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11734 {
a7812ae4 11735 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11736 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 11737 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 11738 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11739 tcg_temp_free_i64(fp0);
b6d96bed 11740 }
57fa1fb3 11741 break;
e7f16abb
LA
11742 case OPC_CLASS_D:
11743 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11744 {
e7f16abb
LA
11745 TCGv_i64 fp0 = tcg_temp_new_i64();
11746 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 11747 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
11748 gen_store_fpr64(ctx, fp0, fd);
11749 tcg_temp_free_i64(fp0);
e7f16abb
LA
11750 }
11751 break;
11752 case OPC_MIN_D: /* OPC_RECIP2_D */
11753 if (ctx->insn_flags & ISA_MIPS32R6) {
11754 /* OPC_MIN_D */
a7812ae4
PB
11755 TCGv_i64 fp0 = tcg_temp_new_i64();
11756 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
11757 gen_load_fpr64(ctx, fp0, fs);
11758 gen_load_fpr64(ctx, fp1, ft);
11759 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11760 gen_store_fpr64(ctx, fp1, fd);
11761 tcg_temp_free_i64(fp1);
11762 tcg_temp_free_i64(fp0);
e7f16abb
LA
11763 } else {
11764 /* OPC_RECIP2_D */
11765 check_cp1_64bitmode(ctx);
11766 {
11767 TCGv_i64 fp0 = tcg_temp_new_i64();
11768 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 11769
e7f16abb
LA
11770 gen_load_fpr64(ctx, fp0, fs);
11771 gen_load_fpr64(ctx, fp1, ft);
11772 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11773 tcg_temp_free_i64(fp1);
11774 gen_store_fpr64(ctx, fp0, fd);
11775 tcg_temp_free_i64(fp0);
11776 }
e7f16abb
LA
11777 }
11778 break;
11779 case OPC_MINA_D: /* OPC_RECIP1_D */
11780 if (ctx->insn_flags & ISA_MIPS32R6) {
11781 /* OPC_MINA_D */
11782 TCGv_i64 fp0 = tcg_temp_new_i64();
11783 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11784 gen_load_fpr64(ctx, fp0, fs);
11785 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11786 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11787 gen_store_fpr64(ctx, fp1, fd);
11788 tcg_temp_free_i64(fp1);
11789 tcg_temp_free_i64(fp0);
e7f16abb
LA
11790 } else {
11791 /* OPC_RECIP1_D */
11792 check_cp1_64bitmode(ctx);
11793 {
11794 TCGv_i64 fp0 = tcg_temp_new_i64();
11795
11796 gen_load_fpr64(ctx, fp0, fs);
11797 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11798 gen_store_fpr64(ctx, fp0, fd);
11799 tcg_temp_free_i64(fp0);
11800 }
e7f16abb
LA
11801 }
11802 break;
11803 case OPC_MAX_D: /* OPC_RSQRT1_D */
11804 if (ctx->insn_flags & ISA_MIPS32R6) {
11805 /* OPC_MAX_D */
11806 TCGv_i64 fp0 = tcg_temp_new_i64();
11807 TCGv_i64 fp1 = tcg_temp_new_i64();
11808 gen_load_fpr64(ctx, fp0, fs);
11809 gen_load_fpr64(ctx, fp1, ft);
11810 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11811 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 11812 tcg_temp_free_i64(fp1);
a7812ae4 11813 tcg_temp_free_i64(fp0);
e7f16abb
LA
11814 } else {
11815 /* OPC_RSQRT1_D */
11816 check_cp1_64bitmode(ctx);
11817 {
11818 TCGv_i64 fp0 = tcg_temp_new_i64();
11819
11820 gen_load_fpr64(ctx, fp0, fs);
11821 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11822 gen_store_fpr64(ctx, fp0, fd);
11823 tcg_temp_free_i64(fp0);
11824 }
e7f16abb
LA
11825 }
11826 break;
11827 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11828 if (ctx->insn_flags & ISA_MIPS32R6) {
11829 /* OPC_MAXA_D */
11830 TCGv_i64 fp0 = tcg_temp_new_i64();
11831 TCGv_i64 fp1 = tcg_temp_new_i64();
11832 gen_load_fpr64(ctx, fp0, fs);
11833 gen_load_fpr64(ctx, fp1, ft);
11834 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11835 gen_store_fpr64(ctx, fp1, fd);
11836 tcg_temp_free_i64(fp1);
11837 tcg_temp_free_i64(fp0);
e7f16abb
LA
11838 } else {
11839 /* OPC_RSQRT2_D */
11840 check_cp1_64bitmode(ctx);
11841 {
11842 TCGv_i64 fp0 = tcg_temp_new_i64();
11843 TCGv_i64 fp1 = tcg_temp_new_i64();
11844
11845 gen_load_fpr64(ctx, fp0, fs);
11846 gen_load_fpr64(ctx, fp1, ft);
11847 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11848 tcg_temp_free_i64(fp1);
11849 gen_store_fpr64(ctx, fp0, fd);
11850 tcg_temp_free_i64(fp0);
11851 }
b6d96bed 11852 }
57fa1fb3 11853 break;
bf4120ad
NF
11854 case OPC_CMP_F_D:
11855 case OPC_CMP_UN_D:
11856 case OPC_CMP_EQ_D:
11857 case OPC_CMP_UEQ_D:
11858 case OPC_CMP_OLT_D:
11859 case OPC_CMP_ULT_D:
11860 case OPC_CMP_OLE_D:
11861 case OPC_CMP_ULE_D:
11862 case OPC_CMP_SF_D:
11863 case OPC_CMP_NGLE_D:
11864 case OPC_CMP_SEQ_D:
11865 case OPC_CMP_NGL_D:
11866 case OPC_CMP_LT_D:
11867 case OPC_CMP_NGE_D:
11868 case OPC_CMP_LE_D:
11869 case OPC_CMP_NGT_D:
fecd2646 11870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11871 if (ctx->opcode & (1 << 6)) {
11872 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
11873 } else {
11874 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 11875 }
6ea83fed 11876 break;
bf4120ad 11877 case OPC_CVT_S_D:
5e755519 11878 check_cp1_registers(ctx, fs);
b6d96bed 11879 {
a7812ae4
PB
11880 TCGv_i32 fp32 = tcg_temp_new_i32();
11881 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11882
11883 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11884 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 11885 tcg_temp_free_i64(fp64);
7c979afd 11886 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11887 tcg_temp_free_i32(fp32);
b6d96bed 11888 }
5a5012ec 11889 break;
bf4120ad 11890 case OPC_CVT_W_D:
5e755519 11891 check_cp1_registers(ctx, fs);
b6d96bed 11892 {
a7812ae4
PB
11893 TCGv_i32 fp32 = tcg_temp_new_i32();
11894 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11895
11896 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11897 if (ctx->nan2008) {
11898 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11899 } else {
11900 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11901 }
a7812ae4 11902 tcg_temp_free_i64(fp64);
7c979afd 11903 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11904 tcg_temp_free_i32(fp32);
b6d96bed 11905 }
5a5012ec 11906 break;
bf4120ad 11907 case OPC_CVT_L_D:
5e755519 11908 check_cp1_64bitmode(ctx);
b6d96bed 11909 {
a7812ae4 11910 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11911
11912 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11913 if (ctx->nan2008) {
11914 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11915 } else {
11916 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11917 }
b6d96bed 11918 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11919 tcg_temp_free_i64(fp0);
b6d96bed 11920 }
5a5012ec 11921 break;
bf4120ad 11922 case OPC_CVT_S_W:
b6d96bed 11923 {
a7812ae4 11924 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11925
7c979afd 11926 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11927 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 11928 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11929 tcg_temp_free_i32(fp0);
b6d96bed 11930 }
6ea83fed 11931 break;
bf4120ad 11932 case OPC_CVT_D_W:
5e755519 11933 check_cp1_registers(ctx, fd);
b6d96bed 11934 {
a7812ae4
PB
11935 TCGv_i32 fp32 = tcg_temp_new_i32();
11936 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11937
7c979afd 11938 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11939 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11940 tcg_temp_free_i32(fp32);
b6d96bed 11941 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11942 tcg_temp_free_i64(fp64);
b6d96bed 11943 }
5a5012ec 11944 break;
bf4120ad 11945 case OPC_CVT_S_L:
5e755519 11946 check_cp1_64bitmode(ctx);
b6d96bed 11947 {
a7812ae4
PB
11948 TCGv_i32 fp32 = tcg_temp_new_i32();
11949 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11950
11951 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11952 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11953 tcg_temp_free_i64(fp64);
7c979afd 11954 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11955 tcg_temp_free_i32(fp32);
b6d96bed 11956 }
5a5012ec 11957 break;
bf4120ad 11958 case OPC_CVT_D_L:
5e755519 11959 check_cp1_64bitmode(ctx);
b6d96bed 11960 {
a7812ae4 11961 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11962
11963 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11964 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11965 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11966 tcg_temp_free_i64(fp0);
b6d96bed 11967 }
5a5012ec 11968 break;
bf4120ad 11969 case OPC_CVT_PS_PW:
e29c9628 11970 check_ps(ctx);
b6d96bed 11971 {
a7812ae4 11972 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11973
11974 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11975 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11976 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11977 tcg_temp_free_i64(fp0);
b6d96bed 11978 }
5a5012ec 11979 break;
bf4120ad 11980 case OPC_ADD_PS:
e29c9628 11981 check_ps(ctx);
b6d96bed 11982 {
a7812ae4
PB
11983 TCGv_i64 fp0 = tcg_temp_new_i64();
11984 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11985
11986 gen_load_fpr64(ctx, fp0, fs);
11987 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11988 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11989 tcg_temp_free_i64(fp1);
b6d96bed 11990 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11991 tcg_temp_free_i64(fp0);
b6d96bed 11992 }
6ea83fed 11993 break;
bf4120ad 11994 case OPC_SUB_PS:
e29c9628 11995 check_ps(ctx);
b6d96bed 11996 {
a7812ae4
PB
11997 TCGv_i64 fp0 = tcg_temp_new_i64();
11998 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11999
12000 gen_load_fpr64(ctx, fp0, fs);
12001 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12002 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12003 tcg_temp_free_i64(fp1);
b6d96bed 12004 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12005 tcg_temp_free_i64(fp0);
b6d96bed 12006 }
6ea83fed 12007 break;
bf4120ad 12008 case OPC_MUL_PS:
e29c9628 12009 check_ps(ctx);
b6d96bed 12010 {
a7812ae4
PB
12011 TCGv_i64 fp0 = tcg_temp_new_i64();
12012 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12013
12014 gen_load_fpr64(ctx, fp0, fs);
12015 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12016 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12017 tcg_temp_free_i64(fp1);
b6d96bed 12018 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12019 tcg_temp_free_i64(fp0);
b6d96bed 12020 }
6ea83fed 12021 break;
bf4120ad 12022 case OPC_ABS_PS:
e29c9628 12023 check_ps(ctx);
b6d96bed 12024 {
a7812ae4 12025 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12026
12027 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 12028 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 12029 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12030 tcg_temp_free_i64(fp0);
b6d96bed 12031 }
6ea83fed 12032 break;
bf4120ad 12033 case OPC_MOV_PS:
e29c9628 12034 check_ps(ctx);
b6d96bed 12035 {
a7812ae4 12036 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12037
12038 gen_load_fpr64(ctx, fp0, fs);
12039 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12040 tcg_temp_free_i64(fp0);
b6d96bed 12041 }
6ea83fed 12042 break;
bf4120ad 12043 case OPC_NEG_PS:
e29c9628 12044 check_ps(ctx);
b6d96bed 12045 {
a7812ae4 12046 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12047
12048 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 12049 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 12050 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12051 tcg_temp_free_i64(fp0);
b6d96bed 12052 }
6ea83fed 12053 break;
bf4120ad 12054 case OPC_MOVCF_PS:
e29c9628 12055 check_ps(ctx);
7f6613ce 12056 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 12057 break;
bf4120ad 12058 case OPC_MOVZ_PS:
e29c9628 12059 check_ps(ctx);
a16336e4 12060 {
42a268c2 12061 TCGLabel *l1 = gen_new_label();
30a3848b 12062 TCGv_i64 fp0;
a16336e4 12063
c9297f4d
AJ
12064 if (ft != 0)
12065 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12066 fp0 = tcg_temp_new_i64();
12067 gen_load_fpr64(ctx, fp0, fs);
12068 gen_store_fpr64(ctx, fp0, fd);
12069 tcg_temp_free_i64(fp0);
a16336e4
TS
12070 gen_set_label(l1);
12071 }
6ea83fed 12072 break;
bf4120ad 12073 case OPC_MOVN_PS:
e29c9628 12074 check_ps(ctx);
a16336e4 12075 {
42a268c2 12076 TCGLabel *l1 = gen_new_label();
30a3848b 12077 TCGv_i64 fp0;
c9297f4d
AJ
12078
12079 if (ft != 0) {
12080 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12081 fp0 = tcg_temp_new_i64();
12082 gen_load_fpr64(ctx, fp0, fs);
12083 gen_store_fpr64(ctx, fp0, fd);
12084 tcg_temp_free_i64(fp0);
12085 gen_set_label(l1);
12086 }
a16336e4 12087 }
6ea83fed 12088 break;
bf4120ad 12089 case OPC_ADDR_PS:
e29c9628 12090 check_ps(ctx);
b6d96bed 12091 {
a7812ae4
PB
12092 TCGv_i64 fp0 = tcg_temp_new_i64();
12093 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12094
12095 gen_load_fpr64(ctx, fp0, ft);
12096 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12097 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12098 tcg_temp_free_i64(fp1);
b6d96bed 12099 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12100 tcg_temp_free_i64(fp0);
b6d96bed 12101 }
fbcc6828 12102 break;
bf4120ad 12103 case OPC_MULR_PS:
e29c9628 12104 check_ps(ctx);
b6d96bed 12105 {
a7812ae4
PB
12106 TCGv_i64 fp0 = tcg_temp_new_i64();
12107 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12108
12109 gen_load_fpr64(ctx, fp0, ft);
12110 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12111 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12112 tcg_temp_free_i64(fp1);
b6d96bed 12113 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12114 tcg_temp_free_i64(fp0);
b6d96bed 12115 }
57fa1fb3 12116 break;
bf4120ad 12117 case OPC_RECIP2_PS:
e29c9628 12118 check_ps(ctx);
b6d96bed 12119 {
a7812ae4
PB
12120 TCGv_i64 fp0 = tcg_temp_new_i64();
12121 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12122
12123 gen_load_fpr64(ctx, fp0, fs);
d22d7289 12124 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12125 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12126 tcg_temp_free_i64(fp1);
b6d96bed 12127 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12128 tcg_temp_free_i64(fp0);
b6d96bed 12129 }
57fa1fb3 12130 break;
bf4120ad 12131 case OPC_RECIP1_PS:
e29c9628 12132 check_ps(ctx);
b6d96bed 12133 {
a7812ae4 12134 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12135
12136 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12137 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 12138 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12139 tcg_temp_free_i64(fp0);
b6d96bed 12140 }
57fa1fb3 12141 break;
bf4120ad 12142 case OPC_RSQRT1_PS:
e29c9628 12143 check_ps(ctx);
b6d96bed 12144 {
a7812ae4 12145 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12146
12147 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12148 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 12149 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12150 tcg_temp_free_i64(fp0);
b6d96bed 12151 }
57fa1fb3 12152 break;
bf4120ad 12153 case OPC_RSQRT2_PS:
e29c9628 12154 check_ps(ctx);
b6d96bed 12155 {
a7812ae4
PB
12156 TCGv_i64 fp0 = tcg_temp_new_i64();
12157 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12158
12159 gen_load_fpr64(ctx, fp0, fs);
12160 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12161 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12162 tcg_temp_free_i64(fp1);
b6d96bed 12163 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12164 tcg_temp_free_i64(fp0);
b6d96bed 12165 }
57fa1fb3 12166 break;
bf4120ad 12167 case OPC_CVT_S_PU:
5e755519 12168 check_cp1_64bitmode(ctx);
b6d96bed 12169 {
a7812ae4 12170 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12171
7f6613ce 12172 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 12173 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 12174 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12175 tcg_temp_free_i32(fp0);
b6d96bed 12176 }
dd016883 12177 break;
bf4120ad 12178 case OPC_CVT_PW_PS:
e29c9628 12179 check_ps(ctx);
b6d96bed 12180 {
a7812ae4 12181 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12182
12183 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12184 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 12185 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12186 tcg_temp_free_i64(fp0);
b6d96bed 12187 }
6ea83fed 12188 break;
bf4120ad 12189 case OPC_CVT_S_PL:
5e755519 12190 check_cp1_64bitmode(ctx);
b6d96bed 12191 {
a7812ae4 12192 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12193
7c979afd 12194 gen_load_fpr32(ctx, fp0, fs);
895c2d04 12195 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 12196 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12197 tcg_temp_free_i32(fp0);
b6d96bed 12198 }
6ea83fed 12199 break;
bf4120ad 12200 case OPC_PLL_PS:
e29c9628 12201 check_ps(ctx);
b6d96bed 12202 {
a7812ae4
PB
12203 TCGv_i32 fp0 = tcg_temp_new_i32();
12204 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12205
7c979afd
LA
12206 gen_load_fpr32(ctx, fp0, fs);
12207 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 12208 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 12209 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
12210 tcg_temp_free_i32(fp0);
12211 tcg_temp_free_i32(fp1);
b6d96bed 12212 }
6ea83fed 12213 break;
bf4120ad 12214 case OPC_PLU_PS:
e29c9628 12215 check_ps(ctx);
b6d96bed 12216 {
a7812ae4
PB
12217 TCGv_i32 fp0 = tcg_temp_new_i32();
12218 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12219
7c979afd 12220 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 12221 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12222 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12223 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12224 tcg_temp_free_i32(fp0);
12225 tcg_temp_free_i32(fp1);
b6d96bed 12226 }
5a5012ec 12227 break;
bf4120ad 12228 case OPC_PUL_PS:
e29c9628 12229 check_ps(ctx);
b6d96bed 12230 {
a7812ae4
PB
12231 TCGv_i32 fp0 = tcg_temp_new_i32();
12232 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12233
7f6613ce 12234 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
12235 gen_load_fpr32(ctx, fp1, ft);
12236 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12237 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12238 tcg_temp_free_i32(fp0);
12239 tcg_temp_free_i32(fp1);
b6d96bed 12240 }
5a5012ec 12241 break;
bf4120ad 12242 case OPC_PUU_PS:
e29c9628 12243 check_ps(ctx);
b6d96bed 12244 {
a7812ae4
PB
12245 TCGv_i32 fp0 = tcg_temp_new_i32();
12246 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12247
7f6613ce
PJ
12248 gen_load_fpr32h(ctx, fp0, fs);
12249 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12250 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12251 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12252 tcg_temp_free_i32(fp0);
12253 tcg_temp_free_i32(fp1);
b6d96bed 12254 }
5a5012ec 12255 break;
bf4120ad
NF
12256 case OPC_CMP_F_PS:
12257 case OPC_CMP_UN_PS:
12258 case OPC_CMP_EQ_PS:
12259 case OPC_CMP_UEQ_PS:
12260 case OPC_CMP_OLT_PS:
12261 case OPC_CMP_ULT_PS:
12262 case OPC_CMP_OLE_PS:
12263 case OPC_CMP_ULE_PS:
12264 case OPC_CMP_SF_PS:
12265 case OPC_CMP_NGLE_PS:
12266 case OPC_CMP_SEQ_PS:
12267 case OPC_CMP_NGL_PS:
12268 case OPC_CMP_LT_PS:
12269 case OPC_CMP_NGE_PS:
12270 case OPC_CMP_LE_PS:
12271 case OPC_CMP_NGT_PS:
8153667c
NF
12272 if (ctx->opcode & (1 << 6)) {
12273 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
12274 } else {
12275 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 12276 }
6ea83fed 12277 break;
5a5012ec 12278 default:
9d68ac14 12279 MIPS_INVAL("farith");
9c708c7f 12280 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
12281 return;
12282 }
6ea83fed 12283}
6af0bf9c 12284
5a5012ec 12285/* Coprocessor 3 (FPU) */
5e755519
TS
12286static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12287 int fd, int fs, int base, int index)
7a387fff 12288{
4e2474d6 12289 TCGv t0 = tcg_temp_new();
7a387fff 12290
93b12ccc 12291 if (base == 0) {
6c5c1e20 12292 gen_load_gpr(t0, index);
93b12ccc 12293 } else if (index == 0) {
6c5c1e20 12294 gen_load_gpr(t0, base);
93b12ccc 12295 } else {
05168674 12296 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 12297 }
5a5012ec 12298 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 12299 memory access. */
5a5012ec
TS
12300 switch (opc) {
12301 case OPC_LWXC1:
8c0ab41f 12302 check_cop1x(ctx);
b6d96bed 12303 {
a7812ae4 12304 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12305
5f68f5ae 12306 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 12307 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 12308 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12309 tcg_temp_free_i32(fp0);
b6d96bed 12310 }
5a5012ec
TS
12311 break;
12312 case OPC_LDXC1:
8c0ab41f
AJ
12313 check_cop1x(ctx);
12314 check_cp1_registers(ctx, fd);
b6d96bed 12315 {
a7812ae4 12316 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 12317 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12318 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12319 tcg_temp_free_i64(fp0);
b6d96bed 12320 }
5a5012ec
TS
12321 break;
12322 case OPC_LUXC1:
8c0ab41f 12323 check_cp1_64bitmode(ctx);
6c5c1e20 12324 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12325 {
a7812ae4 12326 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12327
5f68f5ae 12328 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12329 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12330 tcg_temp_free_i64(fp0);
b6d96bed 12331 }
5a5012ec
TS
12332 break;
12333 case OPC_SWXC1:
8c0ab41f 12334 check_cop1x(ctx);
b6d96bed 12335 {
a7812ae4 12336 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 12337 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 12338 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 12339 tcg_temp_free_i32(fp0);
b6d96bed 12340 }
5a5012ec
TS
12341 break;
12342 case OPC_SDXC1:
8c0ab41f
AJ
12343 check_cop1x(ctx);
12344 check_cp1_registers(ctx, fs);
b6d96bed 12345 {
a7812ae4 12346 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12347 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12348 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12349 tcg_temp_free_i64(fp0);
b6d96bed 12350 }
5a5012ec
TS
12351 break;
12352 case OPC_SUXC1:
8c0ab41f 12353 check_cp1_64bitmode(ctx);
6c5c1e20 12354 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12355 {
a7812ae4 12356 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12357 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12358 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12359 tcg_temp_free_i64(fp0);
b6d96bed 12360 }
5a5012ec 12361 break;
5a5012ec 12362 }
6c5c1e20 12363 tcg_temp_free(t0);
5a5012ec
TS
12364}
12365
5e755519
TS
12366static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12367 int fd, int fr, int fs, int ft)
5a5012ec 12368{
5a5012ec
TS
12369 switch (opc) {
12370 case OPC_ALNV_PS:
e29c9628 12371 check_ps(ctx);
a16336e4 12372 {
a7812ae4 12373 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
12374 TCGv_i32 fp = tcg_temp_new_i32();
12375 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
12376 TCGLabel *l1 = gen_new_label();
12377 TCGLabel *l2 = gen_new_label();
a16336e4 12378
6c5c1e20
TS
12379 gen_load_gpr(t0, fr);
12380 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
12381
12382 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 12383 gen_load_fpr32(ctx, fp, fs);
7f6613ce 12384 gen_load_fpr32h(ctx, fph, fs);
7c979afd 12385 gen_store_fpr32(ctx, fp, fd);
7f6613ce 12386 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
12387 tcg_gen_br(l2);
12388 gen_set_label(l1);
6c5c1e20
TS
12389 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12390 tcg_temp_free(t0);
a16336e4 12391#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 12392 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
12393 gen_load_fpr32h(ctx, fph, ft);
12394 gen_store_fpr32h(ctx, fp, fd);
7c979afd 12395 gen_store_fpr32(ctx, fph, fd);
a16336e4 12396#else
7f6613ce 12397 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
12398 gen_load_fpr32(ctx, fp, ft);
12399 gen_store_fpr32(ctx, fph, fd);
7f6613ce 12400 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
12401#endif
12402 gen_set_label(l2);
c905fdac
AJ
12403 tcg_temp_free_i32(fp);
12404 tcg_temp_free_i32(fph);
a16336e4 12405 }
5a5012ec
TS
12406 break;
12407 case OPC_MADD_S:
b8aa4598 12408 check_cop1x(ctx);
b6d96bed 12409 {
a7812ae4
PB
12410 TCGv_i32 fp0 = tcg_temp_new_i32();
12411 TCGv_i32 fp1 = tcg_temp_new_i32();
12412 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12413
7c979afd
LA
12414 gen_load_fpr32(ctx, fp0, fs);
12415 gen_load_fpr32(ctx, fp1, ft);
12416 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12417 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12418 tcg_temp_free_i32(fp0);
12419 tcg_temp_free_i32(fp1);
7c979afd 12420 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12421 tcg_temp_free_i32(fp2);
b6d96bed 12422 }
5a5012ec
TS
12423 break;
12424 case OPC_MADD_D:
b8aa4598
TS
12425 check_cop1x(ctx);
12426 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12427 {
a7812ae4
PB
12428 TCGv_i64 fp0 = tcg_temp_new_i64();
12429 TCGv_i64 fp1 = tcg_temp_new_i64();
12430 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12431
12432 gen_load_fpr64(ctx, fp0, fs);
12433 gen_load_fpr64(ctx, fp1, ft);
12434 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12435 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12436 tcg_temp_free_i64(fp0);
12437 tcg_temp_free_i64(fp1);
b6d96bed 12438 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12439 tcg_temp_free_i64(fp2);
b6d96bed 12440 }
5a5012ec
TS
12441 break;
12442 case OPC_MADD_PS:
e29c9628 12443 check_ps(ctx);
b6d96bed 12444 {
a7812ae4
PB
12445 TCGv_i64 fp0 = tcg_temp_new_i64();
12446 TCGv_i64 fp1 = tcg_temp_new_i64();
12447 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12448
12449 gen_load_fpr64(ctx, fp0, fs);
12450 gen_load_fpr64(ctx, fp1, ft);
12451 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12452 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12453 tcg_temp_free_i64(fp0);
12454 tcg_temp_free_i64(fp1);
b6d96bed 12455 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12456 tcg_temp_free_i64(fp2);
b6d96bed 12457 }
5a5012ec
TS
12458 break;
12459 case OPC_MSUB_S:
b8aa4598 12460 check_cop1x(ctx);
b6d96bed 12461 {
a7812ae4
PB
12462 TCGv_i32 fp0 = tcg_temp_new_i32();
12463 TCGv_i32 fp1 = tcg_temp_new_i32();
12464 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12465
7c979afd
LA
12466 gen_load_fpr32(ctx, fp0, fs);
12467 gen_load_fpr32(ctx, fp1, ft);
12468 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12469 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12470 tcg_temp_free_i32(fp0);
12471 tcg_temp_free_i32(fp1);
7c979afd 12472 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12473 tcg_temp_free_i32(fp2);
b6d96bed 12474 }
5a5012ec
TS
12475 break;
12476 case OPC_MSUB_D:
b8aa4598
TS
12477 check_cop1x(ctx);
12478 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12479 {
a7812ae4
PB
12480 TCGv_i64 fp0 = tcg_temp_new_i64();
12481 TCGv_i64 fp1 = tcg_temp_new_i64();
12482 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12483
12484 gen_load_fpr64(ctx, fp0, fs);
12485 gen_load_fpr64(ctx, fp1, ft);
12486 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12487 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12488 tcg_temp_free_i64(fp0);
12489 tcg_temp_free_i64(fp1);
b6d96bed 12490 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12491 tcg_temp_free_i64(fp2);
b6d96bed 12492 }
5a5012ec
TS
12493 break;
12494 case OPC_MSUB_PS:
e29c9628 12495 check_ps(ctx);
b6d96bed 12496 {
a7812ae4
PB
12497 TCGv_i64 fp0 = tcg_temp_new_i64();
12498 TCGv_i64 fp1 = tcg_temp_new_i64();
12499 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12500
12501 gen_load_fpr64(ctx, fp0, fs);
12502 gen_load_fpr64(ctx, fp1, ft);
12503 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12504 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12505 tcg_temp_free_i64(fp0);
12506 tcg_temp_free_i64(fp1);
b6d96bed 12507 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12508 tcg_temp_free_i64(fp2);
b6d96bed 12509 }
5a5012ec
TS
12510 break;
12511 case OPC_NMADD_S:
b8aa4598 12512 check_cop1x(ctx);
b6d96bed 12513 {
a7812ae4
PB
12514 TCGv_i32 fp0 = tcg_temp_new_i32();
12515 TCGv_i32 fp1 = tcg_temp_new_i32();
12516 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12517
7c979afd
LA
12518 gen_load_fpr32(ctx, fp0, fs);
12519 gen_load_fpr32(ctx, fp1, ft);
12520 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12521 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12522 tcg_temp_free_i32(fp0);
12523 tcg_temp_free_i32(fp1);
7c979afd 12524 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12525 tcg_temp_free_i32(fp2);
b6d96bed 12526 }
5a5012ec
TS
12527 break;
12528 case OPC_NMADD_D:
b8aa4598
TS
12529 check_cop1x(ctx);
12530 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12531 {
a7812ae4
PB
12532 TCGv_i64 fp0 = tcg_temp_new_i64();
12533 TCGv_i64 fp1 = tcg_temp_new_i64();
12534 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12535
12536 gen_load_fpr64(ctx, fp0, fs);
12537 gen_load_fpr64(ctx, fp1, ft);
12538 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12539 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12540 tcg_temp_free_i64(fp0);
12541 tcg_temp_free_i64(fp1);
b6d96bed 12542 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12543 tcg_temp_free_i64(fp2);
b6d96bed 12544 }
5a5012ec
TS
12545 break;
12546 case OPC_NMADD_PS:
e29c9628 12547 check_ps(ctx);
b6d96bed 12548 {
a7812ae4
PB
12549 TCGv_i64 fp0 = tcg_temp_new_i64();
12550 TCGv_i64 fp1 = tcg_temp_new_i64();
12551 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12552
12553 gen_load_fpr64(ctx, fp0, fs);
12554 gen_load_fpr64(ctx, fp1, ft);
12555 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12556 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12557 tcg_temp_free_i64(fp0);
12558 tcg_temp_free_i64(fp1);
b6d96bed 12559 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12560 tcg_temp_free_i64(fp2);
b6d96bed 12561 }
5a5012ec
TS
12562 break;
12563 case OPC_NMSUB_S:
b8aa4598 12564 check_cop1x(ctx);
b6d96bed 12565 {
a7812ae4
PB
12566 TCGv_i32 fp0 = tcg_temp_new_i32();
12567 TCGv_i32 fp1 = tcg_temp_new_i32();
12568 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12569
7c979afd
LA
12570 gen_load_fpr32(ctx, fp0, fs);
12571 gen_load_fpr32(ctx, fp1, ft);
12572 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12573 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12574 tcg_temp_free_i32(fp0);
12575 tcg_temp_free_i32(fp1);
7c979afd 12576 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12577 tcg_temp_free_i32(fp2);
b6d96bed 12578 }
5a5012ec
TS
12579 break;
12580 case OPC_NMSUB_D:
b8aa4598
TS
12581 check_cop1x(ctx);
12582 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12583 {
a7812ae4
PB
12584 TCGv_i64 fp0 = tcg_temp_new_i64();
12585 TCGv_i64 fp1 = tcg_temp_new_i64();
12586 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12587
12588 gen_load_fpr64(ctx, fp0, fs);
12589 gen_load_fpr64(ctx, fp1, ft);
12590 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12591 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12592 tcg_temp_free_i64(fp0);
12593 tcg_temp_free_i64(fp1);
b6d96bed 12594 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12595 tcg_temp_free_i64(fp2);
b6d96bed 12596 }
5a5012ec
TS
12597 break;
12598 case OPC_NMSUB_PS:
e29c9628 12599 check_ps(ctx);
b6d96bed 12600 {
a7812ae4
PB
12601 TCGv_i64 fp0 = tcg_temp_new_i64();
12602 TCGv_i64 fp1 = tcg_temp_new_i64();
12603 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12604
12605 gen_load_fpr64(ctx, fp0, fs);
12606 gen_load_fpr64(ctx, fp1, ft);
12607 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12608 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12609 tcg_temp_free_i64(fp0);
12610 tcg_temp_free_i64(fp1);
b6d96bed 12611 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12612 tcg_temp_free_i64(fp2);
b6d96bed 12613 }
5a5012ec 12614 break;
923617a3 12615 default:
9d68ac14 12616 MIPS_INVAL("flt3_arith");
9c708c7f 12617 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
12618 return;
12619 }
7a387fff
TS
12620}
12621
b00c7218 12622static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
12623{
12624 TCGv t0;
12625
b3167288
RH
12626#if !defined(CONFIG_USER_ONLY)
12627 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12628 Therefore only check the ISA in system mode. */
d75c135e 12629 check_insn(ctx, ISA_MIPS32R2);
b3167288 12630#endif
26ebe468
NF
12631 t0 = tcg_temp_new();
12632
12633 switch (rd) {
12634 case 0:
895c2d04 12635 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
12636 gen_store_gpr(t0, rt);
12637 break;
12638 case 1:
895c2d04 12639 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
12640 gen_store_gpr(t0, rt);
12641 break;
12642 case 2:
eeb3bba8 12643 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12644 gen_io_start();
12645 }
895c2d04 12646 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 12647 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12648 gen_io_end();
12649 }
26ebe468 12650 gen_store_gpr(t0, rt);
d673a68d 12651 /* Break the TB to be able to take timer interrupts immediately
b28425ba 12652 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 12653 we break completely out of translated code. */
eeb3bba8
EC
12654 gen_save_pc(ctx->base.pc_next + 4);
12655 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
12656 break;
12657 case 3:
895c2d04 12658 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
12659 gen_store_gpr(t0, rt);
12660 break;
b00c7218
YK
12661 case 4:
12662 check_insn(ctx, ISA_MIPS32R6);
12663 if (sel != 0) {
12664 /* Performance counter registers are not implemented other than
12665 * control register 0.
12666 */
12667 generate_exception(ctx, EXCP_RI);
12668 }
12669 gen_helper_rdhwr_performance(t0, cpu_env);
12670 gen_store_gpr(t0, rt);
12671 break;
12672 case 5:
12673 check_insn(ctx, ISA_MIPS32R6);
12674 gen_helper_rdhwr_xnp(t0, cpu_env);
12675 gen_store_gpr(t0, rt);
12676 break;
26ebe468
NF
12677 case 29:
12678#if defined(CONFIG_USER_ONLY)
d279279e
PJ
12679 tcg_gen_ld_tl(t0, cpu_env,
12680 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
12681 gen_store_gpr(t0, rt);
12682 break;
12683#else
d279279e
PJ
12684 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12685 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12686 tcg_gen_ld_tl(t0, cpu_env,
12687 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12688 gen_store_gpr(t0, rt);
12689 } else {
9c708c7f 12690 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
12691 }
12692 break;
26ebe468
NF
12693#endif
12694 default: /* Invalid */
12695 MIPS_INVAL("rdhwr");
9c708c7f 12696 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
12697 break;
12698 }
12699 tcg_temp_free(t0);
12700}
12701
a5f53390
LA
12702static inline void clear_branch_hflags(DisasContext *ctx)
12703{
12704 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 12705 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
12706 save_cpu_state(ctx, 0);
12707 } else {
12708 /* it is not safe to save ctx->hflags as hflags may be changed
12709 in execution time by the instruction in delay / forbidden slot. */
12710 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12711 }
12712}
12713
31837be3 12714static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
12715{
12716 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 12717 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 12718 /* Branches completion */
a5f53390 12719 clear_branch_hflags(ctx);
eeb3bba8 12720 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 12721 /* FIXME: Need to clear can_do_io. */
364d4831 12722 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 12723 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 12724 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 12725 break;
c9602061
NF
12726 case MIPS_HFLAG_B:
12727 /* unconditional branch */
364d4831
NF
12728 if (proc_hflags & MIPS_HFLAG_BX) {
12729 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12730 }
c9602061
NF
12731 gen_goto_tb(ctx, 0, ctx->btarget);
12732 break;
12733 case MIPS_HFLAG_BL:
12734 /* blikely taken case */
c9602061
NF
12735 gen_goto_tb(ctx, 0, ctx->btarget);
12736 break;
12737 case MIPS_HFLAG_BC:
12738 /* Conditional branch */
c9602061 12739 {
42a268c2 12740 TCGLabel *l1 = gen_new_label();
c9602061
NF
12741
12742 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 12743 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
12744 gen_set_label(l1);
12745 gen_goto_tb(ctx, 0, ctx->btarget);
12746 }
12747 break;
12748 case MIPS_HFLAG_BR:
12749 /* unconditional branch to register */
d75c135e 12750 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
12751 TCGv t0 = tcg_temp_new();
12752 TCGv_i32 t1 = tcg_temp_new_i32();
12753
12754 tcg_gen_andi_tl(t0, btarget, 0x1);
12755 tcg_gen_trunc_tl_i32(t1, t0);
12756 tcg_temp_free(t0);
12757 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12758 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12759 tcg_gen_or_i32(hflags, hflags, t1);
12760 tcg_temp_free_i32(t1);
12761
12762 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12763 } else {
12764 tcg_gen_mov_tl(cpu_PC, btarget);
12765 }
eeb3bba8 12766 if (ctx->base.singlestep_enabled) {
c9602061 12767 save_cpu_state(ctx, 0);
9c708c7f 12768 gen_helper_raise_exception_debug(cpu_env);
c9602061 12769 }
7f11636d 12770 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
12771 break;
12772 default:
a5f53390
LA
12773 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12774 abort();
c9602061
NF
12775 }
12776 }
12777}
12778
6893f074
YK
12779/* Compact Branches */
12780static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12781 int rs, int rt, int32_t offset)
12782{
12783 int bcond_compute = 0;
12784 TCGv t0 = tcg_temp_new();
12785 TCGv t1 = tcg_temp_new();
65935f07 12786 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
12787
12788 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12789#ifdef MIPS_DEBUG_DISAS
12790 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 12791 "\n", ctx->base.pc_next);
6893f074 12792#endif
9c708c7f 12793 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12794 goto out;
12795 }
12796
12797 /* Load needed operands and calculate btarget */
12798 switch (opc) {
12799 /* compact branch */
12800 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12801 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12802 gen_load_gpr(t0, rs);
12803 gen_load_gpr(t1, rt);
12804 bcond_compute = 1;
eeb3bba8 12805 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12806 if (rs <= rt && rs == 0) {
12807 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 12808 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12809 }
12810 break;
12811 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12812 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12813 gen_load_gpr(t0, rs);
12814 gen_load_gpr(t1, rt);
12815 bcond_compute = 1;
eeb3bba8 12816 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12817 break;
12818 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12819 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12820 if (rs == 0 || rs == rt) {
12821 /* OPC_BLEZALC, OPC_BGEZALC */
12822 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 12823 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12824 }
12825 gen_load_gpr(t0, rs);
12826 gen_load_gpr(t1, rt);
12827 bcond_compute = 1;
eeb3bba8 12828 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12829 break;
12830 case OPC_BC:
12831 case OPC_BALC:
eeb3bba8 12832 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12833 break;
12834 case OPC_BEQZC:
12835 case OPC_BNEZC:
12836 if (rs != 0) {
12837 /* OPC_BEQZC, OPC_BNEZC */
12838 gen_load_gpr(t0, rs);
12839 bcond_compute = 1;
eeb3bba8 12840 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12841 } else {
12842 /* OPC_JIC, OPC_JIALC */
12843 TCGv tbase = tcg_temp_new();
12844 TCGv toffset = tcg_temp_new();
12845
12846 gen_load_gpr(tbase, rt);
12847 tcg_gen_movi_tl(toffset, offset);
12848 gen_op_addr_add(ctx, btarget, tbase, toffset);
12849 tcg_temp_free(tbase);
12850 tcg_temp_free(toffset);
12851 }
12852 break;
12853 default:
12854 MIPS_INVAL("Compact branch/jump");
9c708c7f 12855 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12856 goto out;
12857 }
12858
12859 if (bcond_compute == 0) {
12860 /* Uncoditional compact branch */
12861 switch (opc) {
12862 case OPC_JIALC:
eeb3bba8 12863 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12864 /* Fallthrough */
12865 case OPC_JIC:
12866 ctx->hflags |= MIPS_HFLAG_BR;
12867 break;
12868 case OPC_BALC:
eeb3bba8 12869 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12870 /* Fallthrough */
12871 case OPC_BC:
12872 ctx->hflags |= MIPS_HFLAG_B;
12873 break;
12874 default:
12875 MIPS_INVAL("Compact branch/jump");
9c708c7f 12876 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12877 goto out;
12878 }
12879
12880 /* Generating branch here as compact branches don't have delay slot */
12881 gen_branch(ctx, 4);
12882 } else {
12883 /* Conditional compact branch */
12884 TCGLabel *fs = gen_new_label();
12885 save_cpu_state(ctx, 0);
12886
12887 switch (opc) {
12888 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12889 if (rs == 0 && rt != 0) {
12890 /* OPC_BLEZALC */
12891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12892 } else if (rs != 0 && rt != 0 && rs == rt) {
12893 /* OPC_BGEZALC */
12894 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12895 } else {
12896 /* OPC_BGEUC */
12897 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12898 }
12899 break;
12900 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12901 if (rs == 0 && rt != 0) {
12902 /* OPC_BGTZALC */
12903 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12904 } else if (rs != 0 && rt != 0 && rs == rt) {
12905 /* OPC_BLTZALC */
12906 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12907 } else {
12908 /* OPC_BLTUC */
12909 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12910 }
12911 break;
12912 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12913 if (rs == 0 && rt != 0) {
12914 /* OPC_BLEZC */
12915 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12916 } else if (rs != 0 && rt != 0 && rs == rt) {
12917 /* OPC_BGEZC */
12918 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12919 } else {
12920 /* OPC_BGEC */
12921 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12922 }
12923 break;
12924 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12925 if (rs == 0 && rt != 0) {
12926 /* OPC_BGTZC */
12927 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12928 } else if (rs != 0 && rt != 0 && rs == rt) {
12929 /* OPC_BLTZC */
12930 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12931 } else {
12932 /* OPC_BLTC */
12933 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12934 }
12935 break;
12936 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12937 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12938 if (rs >= rt) {
12939 /* OPC_BOVC, OPC_BNVC */
12940 TCGv t2 = tcg_temp_new();
12941 TCGv t3 = tcg_temp_new();
12942 TCGv t4 = tcg_temp_new();
12943 TCGv input_overflow = tcg_temp_new();
12944
12945 gen_load_gpr(t0, rs);
12946 gen_load_gpr(t1, rt);
12947 tcg_gen_ext32s_tl(t2, t0);
12948 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12949 tcg_gen_ext32s_tl(t3, t1);
12950 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12951 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12952
12953 tcg_gen_add_tl(t4, t2, t3);
12954 tcg_gen_ext32s_tl(t4, t4);
12955 tcg_gen_xor_tl(t2, t2, t3);
12956 tcg_gen_xor_tl(t3, t4, t3);
12957 tcg_gen_andc_tl(t2, t3, t2);
12958 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12959 tcg_gen_or_tl(t4, t4, input_overflow);
12960 if (opc == OPC_BOVC) {
12961 /* OPC_BOVC */
12962 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12963 } else {
12964 /* OPC_BNVC */
12965 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12966 }
12967 tcg_temp_free(input_overflow);
12968 tcg_temp_free(t4);
12969 tcg_temp_free(t3);
12970 tcg_temp_free(t2);
12971 } else if (rs < rt && rs == 0) {
12972 /* OPC_BEQZALC, OPC_BNEZALC */
12973 if (opc == OPC_BEQZALC) {
12974 /* OPC_BEQZALC */
12975 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12976 } else {
12977 /* OPC_BNEZALC */
12978 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12979 }
12980 } else {
12981 /* OPC_BEQC, OPC_BNEC */
12982 if (opc == OPC_BEQC) {
12983 /* OPC_BEQC */
12984 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12985 } else {
12986 /* OPC_BNEC */
12987 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12988 }
12989 }
12990 break;
12991 case OPC_BEQZC:
12992 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12993 break;
12994 case OPC_BNEZC:
12995 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12996 break;
12997 default:
12998 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 12999 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
13000 goto out;
13001 }
13002
13003 /* Generating branch here as compact branches don't have delay slot */
13004 gen_goto_tb(ctx, 1, ctx->btarget);
13005 gen_set_label(fs);
13006
13007 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
13008 }
13009
13010out:
13011 tcg_temp_free(t0);
13012 tcg_temp_free(t1);
13013}
13014
7a387fff 13015/* ISA extensions (ASEs) */
6af0bf9c 13016/* MIPS16 extension to MIPS32 */
6ea219d0
NF
13017
13018/* MIPS16 major opcodes */
13019enum {
13020 M16_OPC_ADDIUSP = 0x00,
13021 M16_OPC_ADDIUPC = 0x01,
13022 M16_OPC_B = 0x02,
13023 M16_OPC_JAL = 0x03,
13024 M16_OPC_BEQZ = 0x04,
13025 M16_OPC_BNEQZ = 0x05,
13026 M16_OPC_SHIFT = 0x06,
13027 M16_OPC_LD = 0x07,
13028 M16_OPC_RRIA = 0x08,
13029 M16_OPC_ADDIU8 = 0x09,
13030 M16_OPC_SLTI = 0x0a,
13031 M16_OPC_SLTIU = 0x0b,
13032 M16_OPC_I8 = 0x0c,
13033 M16_OPC_LI = 0x0d,
13034 M16_OPC_CMPI = 0x0e,
13035 M16_OPC_SD = 0x0f,
13036 M16_OPC_LB = 0x10,
13037 M16_OPC_LH = 0x11,
13038 M16_OPC_LWSP = 0x12,
13039 M16_OPC_LW = 0x13,
13040 M16_OPC_LBU = 0x14,
13041 M16_OPC_LHU = 0x15,
13042 M16_OPC_LWPC = 0x16,
13043 M16_OPC_LWU = 0x17,
13044 M16_OPC_SB = 0x18,
13045 M16_OPC_SH = 0x19,
13046 M16_OPC_SWSP = 0x1a,
13047 M16_OPC_SW = 0x1b,
13048 M16_OPC_RRR = 0x1c,
13049 M16_OPC_RR = 0x1d,
13050 M16_OPC_EXTEND = 0x1e,
13051 M16_OPC_I64 = 0x1f
13052};
13053
13054/* I8 funct field */
13055enum {
13056 I8_BTEQZ = 0x0,
13057 I8_BTNEZ = 0x1,
13058 I8_SWRASP = 0x2,
13059 I8_ADJSP = 0x3,
13060 I8_SVRS = 0x4,
13061 I8_MOV32R = 0x5,
13062 I8_MOVR32 = 0x7
13063};
13064
13065/* RRR f field */
13066enum {
13067 RRR_DADDU = 0x0,
13068 RRR_ADDU = 0x1,
13069 RRR_DSUBU = 0x2,
13070 RRR_SUBU = 0x3
13071};
13072
13073/* RR funct field */
13074enum {
13075 RR_JR = 0x00,
13076 RR_SDBBP = 0x01,
13077 RR_SLT = 0x02,
13078 RR_SLTU = 0x03,
13079 RR_SLLV = 0x04,
13080 RR_BREAK = 0x05,
13081 RR_SRLV = 0x06,
13082 RR_SRAV = 0x07,
13083 RR_DSRL = 0x08,
13084 RR_CMP = 0x0a,
13085 RR_NEG = 0x0b,
13086 RR_AND = 0x0c,
13087 RR_OR = 0x0d,
13088 RR_XOR = 0x0e,
13089 RR_NOT = 0x0f,
13090 RR_MFHI = 0x10,
13091 RR_CNVT = 0x11,
13092 RR_MFLO = 0x12,
13093 RR_DSRA = 0x13,
13094 RR_DSLLV = 0x14,
13095 RR_DSRLV = 0x16,
13096 RR_DSRAV = 0x17,
13097 RR_MULT = 0x18,
13098 RR_MULTU = 0x19,
13099 RR_DIV = 0x1a,
13100 RR_DIVU = 0x1b,
13101 RR_DMULT = 0x1c,
13102 RR_DMULTU = 0x1d,
13103 RR_DDIV = 0x1e,
13104 RR_DDIVU = 0x1f
13105};
13106
13107/* I64 funct field */
13108enum {
13109 I64_LDSP = 0x0,
13110 I64_SDSP = 0x1,
13111 I64_SDRASP = 0x2,
13112 I64_DADJSP = 0x3,
13113 I64_LDPC = 0x4,
364d4831 13114 I64_DADDIU5 = 0x5,
6ea219d0
NF
13115 I64_DADDIUPC = 0x6,
13116 I64_DADDIUSP = 0x7
13117};
13118
13119/* RR ry field for CNVT */
13120enum {
13121 RR_RY_CNVT_ZEB = 0x0,
13122 RR_RY_CNVT_ZEH = 0x1,
13123 RR_RY_CNVT_ZEW = 0x2,
13124 RR_RY_CNVT_SEB = 0x4,
13125 RR_RY_CNVT_SEH = 0x5,
13126 RR_RY_CNVT_SEW = 0x6,
13127};
13128
364d4831
NF
13129static int xlat (int r)
13130{
13131 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13132
13133 return map[r];
13134}
13135
13136static void gen_mips16_save (DisasContext *ctx,
13137 int xsregs, int aregs,
13138 int do_ra, int do_s0, int do_s1,
13139 int framesize)
13140{
13141 TCGv t0 = tcg_temp_new();
13142 TCGv t1 = tcg_temp_new();
c48245f0 13143 TCGv t2 = tcg_temp_new();
364d4831
NF
13144 int args, astatic;
13145
13146 switch (aregs) {
13147 case 0:
13148 case 1:
13149 case 2:
13150 case 3:
13151 case 11:
13152 args = 0;
13153 break;
13154 case 4:
13155 case 5:
13156 case 6:
13157 case 7:
13158 args = 1;
13159 break;
13160 case 8:
13161 case 9:
13162 case 10:
13163 args = 2;
13164 break;
13165 case 12:
13166 case 13:
13167 args = 3;
13168 break;
13169 case 14:
13170 args = 4;
13171 break;
13172 default:
9c708c7f 13173 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13174 return;
13175 }
13176
13177 switch (args) {
13178 case 4:
13179 gen_base_offset_addr(ctx, t0, 29, 12);
13180 gen_load_gpr(t1, 7);
5f68f5ae 13181 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13182 /* Fall through */
13183 case 3:
13184 gen_base_offset_addr(ctx, t0, 29, 8);
13185 gen_load_gpr(t1, 6);
5f68f5ae 13186 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13187 /* Fall through */
13188 case 2:
13189 gen_base_offset_addr(ctx, t0, 29, 4);
13190 gen_load_gpr(t1, 5);
5f68f5ae 13191 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13192 /* Fall through */
13193 case 1:
13194 gen_base_offset_addr(ctx, t0, 29, 0);
13195 gen_load_gpr(t1, 4);
5f68f5ae 13196 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13197 }
13198
13199 gen_load_gpr(t0, 29);
13200
5f68f5ae 13201#define DECR_AND_STORE(reg) do { \
c48245f0
MR
13202 tcg_gen_movi_tl(t2, -4); \
13203 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13204 gen_load_gpr(t1, reg); \
13205 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
13206 } while (0)
13207
13208 if (do_ra) {
13209 DECR_AND_STORE(31);
13210 }
13211
13212 switch (xsregs) {
13213 case 7:
13214 DECR_AND_STORE(30);
13215 /* Fall through */
13216 case 6:
13217 DECR_AND_STORE(23);
13218 /* Fall through */
13219 case 5:
13220 DECR_AND_STORE(22);
13221 /* Fall through */
13222 case 4:
13223 DECR_AND_STORE(21);
13224 /* Fall through */
13225 case 3:
13226 DECR_AND_STORE(20);
13227 /* Fall through */
13228 case 2:
13229 DECR_AND_STORE(19);
13230 /* Fall through */
13231 case 1:
13232 DECR_AND_STORE(18);
13233 }
13234
13235 if (do_s1) {
13236 DECR_AND_STORE(17);
13237 }
13238 if (do_s0) {
13239 DECR_AND_STORE(16);
13240 }
13241
13242 switch (aregs) {
13243 case 0:
13244 case 4:
13245 case 8:
13246 case 12:
13247 case 14:
13248 astatic = 0;
13249 break;
13250 case 1:
13251 case 5:
13252 case 9:
13253 case 13:
13254 astatic = 1;
13255 break;
13256 case 2:
13257 case 6:
13258 case 10:
13259 astatic = 2;
13260 break;
13261 case 3:
13262 case 7:
13263 astatic = 3;
13264 break;
13265 case 11:
13266 astatic = 4;
13267 break;
13268 default:
9c708c7f 13269 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13270 return;
13271 }
13272
13273 if (astatic > 0) {
13274 DECR_AND_STORE(7);
13275 if (astatic > 1) {
13276 DECR_AND_STORE(6);
13277 if (astatic > 2) {
13278 DECR_AND_STORE(5);
13279 if (astatic > 3) {
13280 DECR_AND_STORE(4);
13281 }
13282 }
13283 }
13284 }
13285#undef DECR_AND_STORE
13286
c48245f0
MR
13287 tcg_gen_movi_tl(t2, -framesize);
13288 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13289 tcg_temp_free(t0);
13290 tcg_temp_free(t1);
c48245f0 13291 tcg_temp_free(t2);
364d4831
NF
13292}
13293
13294static void gen_mips16_restore (DisasContext *ctx,
13295 int xsregs, int aregs,
13296 int do_ra, int do_s0, int do_s1,
13297 int framesize)
13298{
13299 int astatic;
13300 TCGv t0 = tcg_temp_new();
13301 TCGv t1 = tcg_temp_new();
c48245f0 13302 TCGv t2 = tcg_temp_new();
364d4831 13303
c48245f0
MR
13304 tcg_gen_movi_tl(t2, framesize);
13305 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 13306
5f68f5ae 13307#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
13308 tcg_gen_movi_tl(t2, -4); \
13309 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13310 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13311 gen_store_gpr(t1, reg); \
364d4831
NF
13312 } while (0)
13313
13314 if (do_ra) {
13315 DECR_AND_LOAD(31);
13316 }
13317
13318 switch (xsregs) {
13319 case 7:
13320 DECR_AND_LOAD(30);
13321 /* Fall through */
13322 case 6:
13323 DECR_AND_LOAD(23);
13324 /* Fall through */
13325 case 5:
13326 DECR_AND_LOAD(22);
13327 /* Fall through */
13328 case 4:
13329 DECR_AND_LOAD(21);
13330 /* Fall through */
13331 case 3:
13332 DECR_AND_LOAD(20);
13333 /* Fall through */
13334 case 2:
13335 DECR_AND_LOAD(19);
13336 /* Fall through */
13337 case 1:
13338 DECR_AND_LOAD(18);
13339 }
13340
13341 if (do_s1) {
13342 DECR_AND_LOAD(17);
13343 }
13344 if (do_s0) {
13345 DECR_AND_LOAD(16);
13346 }
13347
13348 switch (aregs) {
13349 case 0:
13350 case 4:
13351 case 8:
13352 case 12:
13353 case 14:
13354 astatic = 0;
13355 break;
13356 case 1:
13357 case 5:
13358 case 9:
13359 case 13:
13360 astatic = 1;
13361 break;
13362 case 2:
13363 case 6:
13364 case 10:
13365 astatic = 2;
13366 break;
13367 case 3:
13368 case 7:
13369 astatic = 3;
13370 break;
13371 case 11:
13372 astatic = 4;
13373 break;
13374 default:
9c708c7f 13375 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13376 return;
13377 }
13378
13379 if (astatic > 0) {
13380 DECR_AND_LOAD(7);
13381 if (astatic > 1) {
13382 DECR_AND_LOAD(6);
13383 if (astatic > 2) {
13384 DECR_AND_LOAD(5);
13385 if (astatic > 3) {
13386 DECR_AND_LOAD(4);
13387 }
13388 }
13389 }
13390 }
13391#undef DECR_AND_LOAD
13392
c48245f0
MR
13393 tcg_gen_movi_tl(t2, framesize);
13394 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13395 tcg_temp_free(t0);
13396 tcg_temp_free(t1);
c48245f0 13397 tcg_temp_free(t2);
364d4831
NF
13398}
13399
13400static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13401 int is_64_bit, int extended)
13402{
13403 TCGv t0;
13404
13405 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13406 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13407 return;
13408 }
13409
13410 t0 = tcg_temp_new();
13411
13412 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13413 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13414 if (!is_64_bit) {
13415 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13416 }
13417
13418 tcg_temp_free(t0);
13419}
13420
0d74a222
LA
13421static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13422 int16_t offset)
13423{
13424 TCGv_i32 t0 = tcg_const_i32(op);
13425 TCGv t1 = tcg_temp_new();
13426 gen_base_offset_addr(ctx, t1, base, offset);
13427 gen_helper_cache(cpu_env, t1, t0);
13428}
13429
364d4831 13430#if defined(TARGET_MIPS64)
d75c135e 13431static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
13432 int ry, int funct, int16_t offset,
13433 int extended)
13434{
13435 switch (funct) {
13436 case I64_LDSP:
d9224450 13437 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13438 check_mips_64(ctx);
13439 offset = extended ? offset : offset << 3;
d75c135e 13440 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
13441 break;
13442 case I64_SDSP:
d9224450 13443 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13444 check_mips_64(ctx);
13445 offset = extended ? offset : offset << 3;
5c13fdfd 13446 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
13447 break;
13448 case I64_SDRASP:
d9224450 13449 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13450 check_mips_64(ctx);
13451 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 13452 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
13453 break;
13454 case I64_DADJSP:
d9224450 13455 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13456 check_mips_64(ctx);
13457 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 13458 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
13459 break;
13460 case I64_LDPC:
d9224450
MR
13461 check_insn(ctx, ISA_MIPS3);
13462 check_mips_64(ctx);
364d4831 13463 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13464 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13465 } else {
13466 offset = extended ? offset : offset << 3;
d75c135e 13467 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
13468 }
13469 break;
13470 case I64_DADDIU5:
d9224450 13471 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13472 check_mips_64(ctx);
13473 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 13474 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
13475 break;
13476 case I64_DADDIUPC:
d9224450 13477 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13478 check_mips_64(ctx);
13479 offset = extended ? offset : offset << 2;
13480 gen_addiupc(ctx, ry, offset, 1, extended);
13481 break;
13482 case I64_DADDIUSP:
d9224450 13483 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13484 check_mips_64(ctx);
13485 offset = extended ? offset : offset << 2;
d75c135e 13486 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
13487 break;
13488 }
13489}
13490#endif
13491
240ce26a 13492static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 13493{
eeb3bba8 13494 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13495 int op, rx, ry, funct, sa;
13496 int16_t imm, offset;
13497
13498 ctx->opcode = (ctx->opcode << 16) | extend;
13499 op = (ctx->opcode >> 11) & 0x1f;
13500 sa = (ctx->opcode >> 22) & 0x1f;
13501 funct = (ctx->opcode >> 8) & 0x7;
13502 rx = xlat((ctx->opcode >> 8) & 0x7);
13503 ry = xlat((ctx->opcode >> 5) & 0x7);
13504 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13505 | ((ctx->opcode >> 21) & 0x3f) << 5
13506 | (ctx->opcode & 0x1f));
13507
13508 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13509 counterparts. */
13510 switch (op) {
13511 case M16_OPC_ADDIUSP:
d75c135e 13512 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13513 break;
13514 case M16_OPC_ADDIUPC:
13515 gen_addiupc(ctx, rx, imm, 0, 1);
13516 break;
13517 case M16_OPC_B:
b231c103 13518 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
13519 /* No delay slot, so just process as a normal instruction */
13520 break;
13521 case M16_OPC_BEQZ:
b231c103 13522 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
13523 /* No delay slot, so just process as a normal instruction */
13524 break;
13525 case M16_OPC_BNEQZ:
b231c103 13526 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
13527 /* No delay slot, so just process as a normal instruction */
13528 break;
13529 case M16_OPC_SHIFT:
13530 switch (ctx->opcode & 0x3) {
13531 case 0x0:
d75c135e 13532 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13533 break;
13534 case 0x1:
13535#if defined(TARGET_MIPS64)
13536 check_mips_64(ctx);
d75c135e 13537 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13538#else
9c708c7f 13539 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13540#endif
13541 break;
13542 case 0x2:
d75c135e 13543 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13544 break;
13545 case 0x3:
d75c135e 13546 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13547 break;
13548 }
13549 break;
13550#if defined(TARGET_MIPS64)
13551 case M16_OPC_LD:
d9224450 13552 check_insn(ctx, ISA_MIPS3);
d75de749 13553 check_mips_64(ctx);
d75c135e 13554 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
13555 break;
13556#endif
13557 case M16_OPC_RRIA:
13558 imm = ctx->opcode & 0xf;
13559 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13560 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13561 imm = (int16_t) (imm << 1) >> 1;
13562 if ((ctx->opcode >> 4) & 0x1) {
13563#if defined(TARGET_MIPS64)
13564 check_mips_64(ctx);
d75c135e 13565 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13566#else
9c708c7f 13567 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13568#endif
13569 } else {
d75c135e 13570 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13571 }
13572 break;
13573 case M16_OPC_ADDIU8:
d75c135e 13574 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13575 break;
13576 case M16_OPC_SLTI:
d75c135e 13577 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13578 break;
13579 case M16_OPC_SLTIU:
d75c135e 13580 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13581 break;
13582 case M16_OPC_I8:
13583 switch (funct) {
13584 case I8_BTEQZ:
b231c103 13585 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
13586 break;
13587 case I8_BTNEZ:
b231c103 13588 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
13589 break;
13590 case I8_SWRASP:
5c13fdfd 13591 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
13592 break;
13593 case I8_ADJSP:
d75c135e 13594 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
13595 break;
13596 case I8_SVRS:
d9224450 13597 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13598 {
13599 int xsregs = (ctx->opcode >> 24) & 0x7;
13600 int aregs = (ctx->opcode >> 16) & 0xf;
13601 int do_ra = (ctx->opcode >> 6) & 0x1;
13602 int do_s0 = (ctx->opcode >> 5) & 0x1;
13603 int do_s1 = (ctx->opcode >> 4) & 0x1;
13604 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13605 | (ctx->opcode & 0xf)) << 3;
13606
13607 if (ctx->opcode & (1 << 7)) {
13608 gen_mips16_save(ctx, xsregs, aregs,
13609 do_ra, do_s0, do_s1,
13610 framesize);
13611 } else {
13612 gen_mips16_restore(ctx, xsregs, aregs,
13613 do_ra, do_s0, do_s1,
13614 framesize);
13615 }
13616 }
13617 break;
13618 default:
9c708c7f 13619 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13620 break;
13621 }
13622 break;
13623 case M16_OPC_LI:
13624 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13625 break;
13626 case M16_OPC_CMPI:
13627 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13628 break;
13629#if defined(TARGET_MIPS64)
13630 case M16_OPC_SD:
d9224450
MR
13631 check_insn(ctx, ISA_MIPS3);
13632 check_mips_64(ctx);
5c13fdfd 13633 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
13634 break;
13635#endif
13636 case M16_OPC_LB:
d75c135e 13637 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13638 break;
13639 case M16_OPC_LH:
d75c135e 13640 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
13641 break;
13642 case M16_OPC_LWSP:
d75c135e 13643 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
13644 break;
13645 case M16_OPC_LW:
d75c135e 13646 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
13647 break;
13648 case M16_OPC_LBU:
d75c135e 13649 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13650 break;
13651 case M16_OPC_LHU:
d75c135e 13652 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
13653 break;
13654 case M16_OPC_LWPC:
d75c135e 13655 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
13656 break;
13657#if defined(TARGET_MIPS64)
13658 case M16_OPC_LWU:
d9224450
MR
13659 check_insn(ctx, ISA_MIPS3);
13660 check_mips_64(ctx);
d75c135e 13661 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
13662 break;
13663#endif
13664 case M16_OPC_SB:
5c13fdfd 13665 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13666 break;
13667 case M16_OPC_SH:
5c13fdfd 13668 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
13669 break;
13670 case M16_OPC_SWSP:
5c13fdfd 13671 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
13672 break;
13673 case M16_OPC_SW:
5c13fdfd 13674 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
13675 break;
13676#if defined(TARGET_MIPS64)
13677 case M16_OPC_I64:
d75c135e 13678 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
13679 break;
13680#endif
13681 default:
9c708c7f 13682 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13683 break;
13684 }
13685
13686 return 4;
13687}
13688
3b3c1694
LA
13689static inline bool is_uhi(int sdbbp_code)
13690{
13691#ifdef CONFIG_USER_ONLY
13692 return false;
13693#else
13694 return semihosting_enabled() && sdbbp_code == 1;
13695#endif
13696}
13697
240ce26a 13698static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
13699{
13700 int rx, ry;
13701 int sa;
13702 int op, cnvt_op, op1, offset;
13703 int funct;
13704 int n_bytes;
13705
13706 op = (ctx->opcode >> 11) & 0x1f;
13707 sa = (ctx->opcode >> 2) & 0x7;
13708 sa = sa == 0 ? 8 : sa;
13709 rx = xlat((ctx->opcode >> 8) & 0x7);
13710 cnvt_op = (ctx->opcode >> 5) & 0x7;
13711 ry = xlat((ctx->opcode >> 5) & 0x7);
13712 op1 = offset = ctx->opcode & 0x1f;
13713
13714 n_bytes = 2;
13715
13716 switch (op) {
13717 case M16_OPC_ADDIUSP:
13718 {
13719 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13720
d75c135e 13721 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13722 }
13723 break;
13724 case M16_OPC_ADDIUPC:
13725 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13726 break;
13727 case M16_OPC_B:
13728 offset = (ctx->opcode & 0x7ff) << 1;
13729 offset = (int16_t)(offset << 4) >> 4;
b231c103 13730 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
13731 /* No delay slot, so just process as a normal instruction */
13732 break;
13733 case M16_OPC_JAL:
eeb3bba8 13734 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13735 offset = (((ctx->opcode & 0x1f) << 21)
13736 | ((ctx->opcode >> 5) & 0x1f) << 16
13737 | offset) << 2;
b231c103
YK
13738 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13739 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 13740 n_bytes = 4;
364d4831
NF
13741 break;
13742 case M16_OPC_BEQZ:
b231c103
YK
13743 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13744 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13745 /* No delay slot, so just process as a normal instruction */
13746 break;
13747 case M16_OPC_BNEQZ:
b231c103
YK
13748 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13749 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13750 /* No delay slot, so just process as a normal instruction */
13751 break;
13752 case M16_OPC_SHIFT:
13753 switch (ctx->opcode & 0x3) {
13754 case 0x0:
d75c135e 13755 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13756 break;
13757 case 0x1:
13758#if defined(TARGET_MIPS64)
d9224450 13759 check_insn(ctx, ISA_MIPS3);
364d4831 13760 check_mips_64(ctx);
d75c135e 13761 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13762#else
9c708c7f 13763 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13764#endif
13765 break;
13766 case 0x2:
d75c135e 13767 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13768 break;
13769 case 0x3:
d75c135e 13770 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13771 break;
13772 }
13773 break;
13774#if defined(TARGET_MIPS64)
13775 case M16_OPC_LD:
d9224450 13776 check_insn(ctx, ISA_MIPS3);
364d4831 13777 check_mips_64(ctx);
d75c135e 13778 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
13779 break;
13780#endif
13781 case M16_OPC_RRIA:
13782 {
13783 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13784
13785 if ((ctx->opcode >> 4) & 1) {
13786#if defined(TARGET_MIPS64)
d9224450 13787 check_insn(ctx, ISA_MIPS3);
364d4831 13788 check_mips_64(ctx);
d75c135e 13789 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13790#else
9c708c7f 13791 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13792#endif
13793 } else {
d75c135e 13794 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13795 }
13796 }
13797 break;
13798 case M16_OPC_ADDIU8:
13799 {
13800 int16_t imm = (int8_t) ctx->opcode;
13801
d75c135e 13802 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13803 }
13804 break;
13805 case M16_OPC_SLTI:
13806 {
13807 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13808 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13809 }
13810 break;
13811 case M16_OPC_SLTIU:
13812 {
13813 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13814 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13815 }
13816 break;
13817 case M16_OPC_I8:
13818 {
13819 int reg32;
13820
13821 funct = (ctx->opcode >> 8) & 0x7;
13822 switch (funct) {
13823 case I8_BTEQZ:
13824 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 13825 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13826 break;
13827 case I8_BTNEZ:
13828 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 13829 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13830 break;
13831 case I8_SWRASP:
5c13fdfd 13832 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
13833 break;
13834 case I8_ADJSP:
d75c135e 13835 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
13836 ((int8_t)ctx->opcode) << 3);
13837 break;
13838 case I8_SVRS:
d9224450 13839 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13840 {
13841 int do_ra = ctx->opcode & (1 << 6);
13842 int do_s0 = ctx->opcode & (1 << 5);
13843 int do_s1 = ctx->opcode & (1 << 4);
13844 int framesize = ctx->opcode & 0xf;
13845
13846 if (framesize == 0) {
13847 framesize = 128;
13848 } else {
13849 framesize = framesize << 3;
13850 }
13851
13852 if (ctx->opcode & (1 << 7)) {
13853 gen_mips16_save(ctx, 0, 0,
13854 do_ra, do_s0, do_s1, framesize);
13855 } else {
13856 gen_mips16_restore(ctx, 0, 0,
13857 do_ra, do_s0, do_s1, framesize);
13858 }
13859 }
13860 break;
13861 case I8_MOV32R:
13862 {
13863 int rz = xlat(ctx->opcode & 0x7);
13864
13865 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13866 ((ctx->opcode >> 5) & 0x7);
d75c135e 13867 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
13868 }
13869 break;
13870 case I8_MOVR32:
13871 reg32 = ctx->opcode & 0x1f;
d75c135e 13872 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
13873 break;
13874 default:
9c708c7f 13875 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13876 break;
13877 }
13878 }
13879 break;
13880 case M16_OPC_LI:
13881 {
13882 int16_t imm = (uint8_t) ctx->opcode;
13883
d75c135e 13884 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
13885 }
13886 break;
13887 case M16_OPC_CMPI:
13888 {
13889 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13890 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
13891 }
13892 break;
13893#if defined(TARGET_MIPS64)
13894 case M16_OPC_SD:
d9224450 13895 check_insn(ctx, ISA_MIPS3);
364d4831 13896 check_mips_64(ctx);
5c13fdfd 13897 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
13898 break;
13899#endif
13900 case M16_OPC_LB:
d75c135e 13901 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13902 break;
13903 case M16_OPC_LH:
d75c135e 13904 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
13905 break;
13906 case M16_OPC_LWSP:
d75c135e 13907 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13908 break;
13909 case M16_OPC_LW:
d75c135e 13910 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
13911 break;
13912 case M16_OPC_LBU:
d75c135e 13913 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13914 break;
13915 case M16_OPC_LHU:
d75c135e 13916 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
13917 break;
13918 case M16_OPC_LWPC:
d75c135e 13919 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13920 break;
13921#if defined (TARGET_MIPS64)
13922 case M16_OPC_LWU:
d9224450 13923 check_insn(ctx, ISA_MIPS3);
364d4831 13924 check_mips_64(ctx);
d75c135e 13925 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
13926 break;
13927#endif
13928 case M16_OPC_SB:
5c13fdfd 13929 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13930 break;
13931 case M16_OPC_SH:
5c13fdfd 13932 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
13933 break;
13934 case M16_OPC_SWSP:
5c13fdfd 13935 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13936 break;
13937 case M16_OPC_SW:
5c13fdfd 13938 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
13939 break;
13940 case M16_OPC_RRR:
13941 {
13942 int rz = xlat((ctx->opcode >> 2) & 0x7);
13943 int mips32_op;
13944
13945 switch (ctx->opcode & 0x3) {
13946 case RRR_ADDU:
13947 mips32_op = OPC_ADDU;
13948 break;
13949 case RRR_SUBU:
13950 mips32_op = OPC_SUBU;
13951 break;
13952#if defined(TARGET_MIPS64)
13953 case RRR_DADDU:
13954 mips32_op = OPC_DADDU;
d9224450 13955 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13956 check_mips_64(ctx);
13957 break;
13958 case RRR_DSUBU:
13959 mips32_op = OPC_DSUBU;
d9224450 13960 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13961 check_mips_64(ctx);
13962 break;
13963#endif
13964 default:
9c708c7f 13965 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13966 goto done;
13967 }
13968
d75c135e 13969 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
13970 done:
13971 ;
13972 }
13973 break;
13974 case M16_OPC_RR:
13975 switch (op1) {
13976 case RR_JR:
13977 {
13978 int nd = (ctx->opcode >> 7) & 0x1;
13979 int link = (ctx->opcode >> 6) & 0x1;
13980 int ra = (ctx->opcode >> 5) & 0x1;
13981
d9224450
MR
13982 if (nd) {
13983 check_insn(ctx, ISA_MIPS32);
13984 }
13985
364d4831 13986 if (link) {
b231c103 13987 op = OPC_JALR;
364d4831
NF
13988 } else {
13989 op = OPC_JR;
13990 }
13991
b231c103
YK
13992 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13993 (nd ? 0 : 2));
364d4831
NF
13994 }
13995 break;
13996 case RR_SDBBP:
3b3c1694
LA
13997 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13998 gen_helper_do_semihosting(cpu_env);
13999 } else {
14000 /* XXX: not clear which exception should be raised
14001 * when in debug mode...
14002 */
14003 check_insn(ctx, ISA_MIPS32);
9c708c7f 14004 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14005 }
364d4831
NF
14006 break;
14007 case RR_SLT:
d75c135e 14008 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
14009 break;
14010 case RR_SLTU:
d75c135e 14011 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
14012 break;
14013 case RR_BREAK:
9c708c7f 14014 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
14015 break;
14016 case RR_SLLV:
d75c135e 14017 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
14018 break;
14019 case RR_SRLV:
d75c135e 14020 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
14021 break;
14022 case RR_SRAV:
d75c135e 14023 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
14024 break;
14025#if defined (TARGET_MIPS64)
14026 case RR_DSRL:
d9224450 14027 check_insn(ctx, ISA_MIPS3);
364d4831 14028 check_mips_64(ctx);
d75c135e 14029 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
14030 break;
14031#endif
14032 case RR_CMP:
d75c135e 14033 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
14034 break;
14035 case RR_NEG:
d75c135e 14036 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
14037 break;
14038 case RR_AND:
d75c135e 14039 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
14040 break;
14041 case RR_OR:
d75c135e 14042 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
14043 break;
14044 case RR_XOR:
d75c135e 14045 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
14046 break;
14047 case RR_NOT:
d75c135e 14048 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
14049 break;
14050 case RR_MFHI:
26135ead 14051 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
14052 break;
14053 case RR_CNVT:
d9224450 14054 check_insn(ctx, ISA_MIPS32);
364d4831
NF
14055 switch (cnvt_op) {
14056 case RR_RY_CNVT_ZEB:
14057 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14058 break;
14059 case RR_RY_CNVT_ZEH:
14060 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14061 break;
14062 case RR_RY_CNVT_SEB:
14063 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14064 break;
14065 case RR_RY_CNVT_SEH:
14066 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14067 break;
14068#if defined (TARGET_MIPS64)
14069 case RR_RY_CNVT_ZEW:
d9224450 14070 check_insn(ctx, ISA_MIPS64);
364d4831
NF
14071 check_mips_64(ctx);
14072 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14073 break;
14074 case RR_RY_CNVT_SEW:
d9224450 14075 check_insn(ctx, ISA_MIPS64);
364d4831
NF
14076 check_mips_64(ctx);
14077 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14078 break;
14079#endif
14080 default:
9c708c7f 14081 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14082 break;
14083 }
14084 break;
14085 case RR_MFLO:
26135ead 14086 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
14087 break;
14088#if defined (TARGET_MIPS64)
14089 case RR_DSRA:
d9224450 14090 check_insn(ctx, ISA_MIPS3);
364d4831 14091 check_mips_64(ctx);
d75c135e 14092 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
14093 break;
14094 case RR_DSLLV:
d9224450 14095 check_insn(ctx, ISA_MIPS3);
364d4831 14096 check_mips_64(ctx);
d75c135e 14097 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
14098 break;
14099 case RR_DSRLV:
d9224450 14100 check_insn(ctx, ISA_MIPS3);
364d4831 14101 check_mips_64(ctx);
d75c135e 14102 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
14103 break;
14104 case RR_DSRAV:
d9224450 14105 check_insn(ctx, ISA_MIPS3);
364d4831 14106 check_mips_64(ctx);
d75c135e 14107 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
14108 break;
14109#endif
14110 case RR_MULT:
26135ead 14111 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
14112 break;
14113 case RR_MULTU:
26135ead 14114 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
14115 break;
14116 case RR_DIV:
26135ead 14117 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
14118 break;
14119 case RR_DIVU:
26135ead 14120 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
14121 break;
14122#if defined (TARGET_MIPS64)
14123 case RR_DMULT:
d9224450 14124 check_insn(ctx, ISA_MIPS3);
364d4831 14125 check_mips_64(ctx);
26135ead 14126 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
14127 break;
14128 case RR_DMULTU:
d9224450 14129 check_insn(ctx, ISA_MIPS3);
364d4831 14130 check_mips_64(ctx);
26135ead 14131 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
14132 break;
14133 case RR_DDIV:
d9224450 14134 check_insn(ctx, ISA_MIPS3);
364d4831 14135 check_mips_64(ctx);
26135ead 14136 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
14137 break;
14138 case RR_DDIVU:
d9224450 14139 check_insn(ctx, ISA_MIPS3);
364d4831 14140 check_mips_64(ctx);
26135ead 14141 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
14142 break;
14143#endif
14144 default:
9c708c7f 14145 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14146 break;
14147 }
14148 break;
14149 case M16_OPC_EXTEND:
240ce26a 14150 decode_extended_mips16_opc(env, ctx);
364d4831
NF
14151 n_bytes = 4;
14152 break;
14153#if defined(TARGET_MIPS64)
14154 case M16_OPC_I64:
14155 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 14156 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
14157 break;
14158#endif
14159 default:
9c708c7f 14160 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14161 break;
14162 }
14163
14164 return n_bytes;
14165}
14166
211da992 14167/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 14168
211da992
CWR
14169/*
14170 * microMIPS32/microMIPS64 major opcodes
14171 *
14172 * 1. MIPS Architecture for Programmers Volume II-B:
14173 * The microMIPS32 Instruction Set (Revision 3.05)
14174 *
14175 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14176 *
14177 * 2. MIPS Architecture For Programmers Volume II-A:
14178 * The MIPS64 Instruction Set (Revision 3.51)
14179 */
6af0bf9c 14180
3c824109
NF
14181enum {
14182 POOL32A = 0x00,
14183 POOL16A = 0x01,
14184 LBU16 = 0x02,
14185 MOVE16 = 0x03,
14186 ADDI32 = 0x04,
3a1f4268
YK
14187 R6_LUI = 0x04,
14188 AUI = 0x04,
3c824109
NF
14189 LBU32 = 0x05,
14190 SB32 = 0x06,
14191 LB32 = 0x07,
14192
14193 POOL32B = 0x08,
14194 POOL16B = 0x09,
14195 LHU16 = 0x0a,
14196 ANDI16 = 0x0b,
14197 ADDIU32 = 0x0c,
14198 LHU32 = 0x0d,
14199 SH32 = 0x0e,
14200 LH32 = 0x0f,
14201
14202 POOL32I = 0x10,
14203 POOL16C = 0x11,
14204 LWSP16 = 0x12,
14205 POOL16D = 0x13,
14206 ORI32 = 0x14,
14207 POOL32F = 0x15,
211da992
CWR
14208 POOL32S = 0x16, /* MIPS64 */
14209 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
14210
14211 POOL32C = 0x18,
14212 LWGP16 = 0x19,
14213 LW16 = 0x1a,
14214 POOL16E = 0x1b,
14215 XORI32 = 0x1c,
14216 JALS32 = 0x1d,
3a1f4268
YK
14217 BOVC = 0x1d,
14218 BEQC = 0x1d,
14219 BEQZALC = 0x1d,
3c824109 14220 ADDIUPC = 0x1e,
3a1f4268
YK
14221 PCREL = 0x1e,
14222 BNVC = 0x1f,
14223 BNEC = 0x1f,
14224 BNEZALC = 0x1f,
3c824109 14225
3a1f4268
YK
14226 R6_BEQZC = 0x20,
14227 JIC = 0x20,
3c824109
NF
14228 POOL16F = 0x21,
14229 SB16 = 0x22,
14230 BEQZ16 = 0x23,
3a1f4268 14231 BEQZC16 = 0x23,
3c824109
NF
14232 SLTI32 = 0x24,
14233 BEQ32 = 0x25,
3a1f4268 14234 BC = 0x25,
3c824109
NF
14235 SWC132 = 0x26,
14236 LWC132 = 0x27,
14237
3a1f4268 14238 /* 0x29 is reserved */
3c824109 14239 RES_29 = 0x29,
3a1f4268
YK
14240 R6_BNEZC = 0x28,
14241 JIALC = 0x28,
3c824109
NF
14242 SH16 = 0x2a,
14243 BNEZ16 = 0x2b,
3a1f4268 14244 BNEZC16 = 0x2b,
3c824109
NF
14245 SLTIU32 = 0x2c,
14246 BNE32 = 0x2d,
3a1f4268 14247 BALC = 0x2d,
3c824109
NF
14248 SDC132 = 0x2e,
14249 LDC132 = 0x2f,
14250
3a1f4268 14251 /* 0x31 is reserved */
3c824109 14252 RES_31 = 0x31,
3a1f4268
YK
14253 BLEZALC = 0x30,
14254 BGEZALC = 0x30,
14255 BGEUC = 0x30,
3c824109
NF
14256 SWSP16 = 0x32,
14257 B16 = 0x33,
3a1f4268 14258 BC16 = 0x33,
3c824109
NF
14259 ANDI32 = 0x34,
14260 J32 = 0x35,
3a1f4268
YK
14261 BGTZC = 0x35,
14262 BLTZC = 0x35,
14263 BLTC = 0x35,
211da992
CWR
14264 SD32 = 0x36, /* MIPS64 */
14265 LD32 = 0x37, /* MIPS64 */
3c824109 14266
3a1f4268 14267 /* 0x39 is reserved */
3c824109 14268 RES_39 = 0x39,
3a1f4268
YK
14269 BGTZALC = 0x38,
14270 BLTZALC = 0x38,
14271 BLTUC = 0x38,
3c824109
NF
14272 SW16 = 0x3a,
14273 LI16 = 0x3b,
14274 JALX32 = 0x3c,
14275 JAL32 = 0x3d,
3a1f4268
YK
14276 BLEZC = 0x3d,
14277 BGEZC = 0x3d,
14278 BGEC = 0x3d,
3c824109
NF
14279 SW32 = 0x3e,
14280 LW32 = 0x3f
14281};
14282
3a1f4268
YK
14283/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14284enum {
14285 ADDIUPC_00 = 0x00,
c38a1d52
AR
14286 ADDIUPC_01 = 0x01,
14287 ADDIUPC_02 = 0x02,
14288 ADDIUPC_03 = 0x03,
14289 ADDIUPC_04 = 0x04,
14290 ADDIUPC_05 = 0x05,
14291 ADDIUPC_06 = 0x06,
3a1f4268
YK
14292 ADDIUPC_07 = 0x07,
14293 AUIPC = 0x1e,
14294 ALUIPC = 0x1f,
14295 LWPC_08 = 0x08,
c38a1d52
AR
14296 LWPC_09 = 0x09,
14297 LWPC_0A = 0x0A,
14298 LWPC_0B = 0x0B,
14299 LWPC_0C = 0x0C,
14300 LWPC_0D = 0x0D,
14301 LWPC_0E = 0x0E,
3a1f4268
YK
14302 LWPC_0F = 0x0F,
14303};
14304
3c824109
NF
14305/* POOL32A encoding of minor opcode field */
14306
14307enum {
14308 /* These opcodes are distinguished only by bits 9..6; those bits are
14309 * what are recorded below. */
14310 SLL32 = 0x0,
14311 SRL32 = 0x1,
14312 SRA = 0x2,
14313 ROTR = 0x3,
3a1f4268
YK
14314 SELEQZ = 0x5,
14315 SELNEZ = 0x6,
b00c7218 14316 R6_RDHWR = 0x7,
3c824109
NF
14317
14318 SLLV = 0x0,
14319 SRLV = 0x1,
14320 SRAV = 0x2,
14321 ROTRV = 0x3,
14322 ADD = 0x4,
14323 ADDU32 = 0x5,
14324 SUB = 0x6,
14325 SUBU32 = 0x7,
14326 MUL = 0x8,
14327 AND = 0x9,
14328 OR32 = 0xa,
14329 NOR = 0xb,
14330 XOR32 = 0xc,
14331 SLT = 0xd,
14332 SLTU = 0xe,
14333
14334 MOVN = 0x0,
3a1f4268 14335 R6_MUL = 0x0,
3c824109 14336 MOVZ = 0x1,
3a1f4268
YK
14337 MUH = 0x1,
14338 MULU = 0x2,
14339 MUHU = 0x3,
3c824109 14340 LWXS = 0x4,
3a1f4268
YK
14341 R6_DIV = 0x4,
14342 MOD = 0x5,
14343 R6_DIVU = 0x6,
14344 MODU = 0x7,
3c824109
NF
14345
14346 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 14347 BREAK32 = 0x07,
3c824109 14348 INS = 0x0c,
3a1f4268
YK
14349 LSA = 0x0f,
14350 ALIGN = 0x1f,
3c824109 14351 EXT = 0x2c,
bb238210
YK
14352 POOL32AXF = 0x3c,
14353 SIGRIE = 0x3f
3c824109
NF
14354};
14355
14356/* POOL32AXF encoding of minor opcode field extension */
14357
d132c79f
CWR
14358/*
14359 * 1. MIPS Architecture for Programmers Volume II-B:
14360 * The microMIPS32 Instruction Set (Revision 3.05)
14361 *
14362 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14363 *
14364 * 2. MIPS Architecture for Programmers VolumeIV-e:
14365 * The MIPS DSP Application-Specific Extension
14366 * to the microMIPS32 Architecture (Revision 2.34)
14367 *
14368 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14369 */
14370
3c824109
NF
14371enum {
14372 /* bits 11..6 */
14373 TEQ = 0x00,
14374 TGE = 0x08,
14375 TGEU = 0x10,
14376 TLT = 0x20,
14377 TLTU = 0x28,
14378 TNE = 0x30,
14379
14380 MFC0 = 0x03,
14381 MTC0 = 0x0b,
14382
d132c79f
CWR
14383 /* begin of microMIPS32 DSP */
14384
3c824109
NF
14385 /* bits 13..12 for 0x01 */
14386 MFHI_ACC = 0x0,
14387 MFLO_ACC = 0x1,
14388 MTHI_ACC = 0x2,
14389 MTLO_ACC = 0x3,
14390
14391 /* bits 13..12 for 0x2a */
14392 MADD_ACC = 0x0,
14393 MADDU_ACC = 0x1,
14394 MSUB_ACC = 0x2,
14395 MSUBU_ACC = 0x3,
14396
14397 /* bits 13..12 for 0x32 */
14398 MULT_ACC = 0x0,
6801038b 14399 MULTU_ACC = 0x1,
3c824109 14400
d132c79f
CWR
14401 /* end of microMIPS32 DSP */
14402
3c824109 14403 /* bits 15..12 for 0x2c */
3a1f4268 14404 BITSWAP = 0x0,
3c824109
NF
14405 SEB = 0x2,
14406 SEH = 0x3,
14407 CLO = 0x4,
14408 CLZ = 0x5,
14409 RDHWR = 0x6,
14410 WSBH = 0x7,
14411 MULT = 0x8,
14412 MULTU = 0x9,
14413 DIV = 0xa,
14414 DIVU = 0xb,
14415 MADD = 0xc,
14416 MADDU = 0xd,
14417 MSUB = 0xe,
14418 MSUBU = 0xf,
14419
14420 /* bits 15..12 for 0x34 */
14421 MFC2 = 0x4,
14422 MTC2 = 0x5,
14423 MFHC2 = 0x8,
14424 MTHC2 = 0x9,
14425 CFC2 = 0xc,
14426 CTC2 = 0xd,
14427
14428 /* bits 15..12 for 0x3c */
14429 JALR = 0x0,
14430 JR = 0x0, /* alias */
3a1f4268
YK
14431 JALRC = 0x0,
14432 JRC = 0x0,
3c824109 14433 JALR_HB = 0x1,
3a1f4268 14434 JALRC_HB = 0x1,
3c824109
NF
14435 JALRS = 0x4,
14436 JALRS_HB = 0x5,
14437
14438 /* bits 15..12 for 0x05 */
14439 RDPGPR = 0xe,
14440 WRPGPR = 0xf,
14441
14442 /* bits 15..12 for 0x0d */
14443 TLBP = 0x0,
14444 TLBR = 0x1,
14445 TLBWI = 0x2,
14446 TLBWR = 0x3,
e60ec063
YK
14447 TLBINV = 0x4,
14448 TLBINVF = 0x5,
3c824109
NF
14449 WAIT = 0x9,
14450 IRET = 0xd,
14451 DERET = 0xe,
14452 ERET = 0xf,
14453
14454 /* bits 15..12 for 0x15 */
14455 DMT = 0x0,
14456 DVPE = 0x1,
14457 EMT = 0x2,
14458 EVPE = 0x3,
14459
14460 /* bits 15..12 for 0x1d */
14461 DI = 0x4,
14462 EI = 0x5,
14463
14464 /* bits 15..12 for 0x2d */
14465 SYNC = 0x6,
14466 SYSCALL = 0x8,
14467 SDBBP = 0xd,
14468
14469 /* bits 15..12 for 0x35 */
14470 MFHI32 = 0x0,
14471 MFLO32 = 0x1,
14472 MTHI32 = 0x2,
14473 MTLO32 = 0x3,
14474};
14475
14476/* POOL32B encoding of minor opcode field (bits 15..12) */
14477
14478enum {
14479 LWC2 = 0x0,
14480 LWP = 0x1,
14481 LDP = 0x4,
14482 LWM32 = 0x5,
14483 CACHE = 0x6,
14484 LDM = 0x7,
14485 SWC2 = 0x8,
14486 SWP = 0x9,
14487 SDP = 0xc,
14488 SWM32 = 0xd,
14489 SDM = 0xf
14490};
14491
14492/* POOL32C encoding of minor opcode field (bits 15..12) */
14493
14494enum {
14495 LWL = 0x0,
14496 SWL = 0x8,
14497 LWR = 0x1,
14498 SWR = 0x9,
14499 PREF = 0x2,
8fffc646 14500 ST_EVA = 0xa,
3c824109
NF
14501 LL = 0x3,
14502 SC = 0xb,
14503 LDL = 0x4,
14504 SDL = 0xc,
14505 LDR = 0x5,
14506 SDR = 0xd,
8fffc646 14507 LD_EVA = 0x6,
3c824109
NF
14508 LWU = 0xe,
14509 LLD = 0x7,
14510 SCD = 0xf
14511};
14512
8fffc646
JH
14513/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14514
14515enum {
14516 LBUE = 0x0,
14517 LHUE = 0x1,
14518 LWLE = 0x2,
14519 LWRE = 0x3,
14520 LBE = 0x4,
14521 LHE = 0x5,
14522 LLE = 0x6,
14523 LWE = 0x7,
14524};
14525
14526/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14527
14528enum {
14529 SWLE = 0x0,
14530 SWRE = 0x1,
14531 PREFE = 0x2,
14532 CACHEE = 0x3,
14533 SBE = 0x4,
14534 SHE = 0x5,
14535 SCE = 0x6,
14536 SWE = 0x7,
14537};
14538
3c824109
NF
14539/* POOL32F encoding of minor opcode field (bits 5..0) */
14540
14541enum {
14542 /* These are the bit 7..6 values */
14543 ADD_FMT = 0x0,
3c824109
NF
14544
14545 SUB_FMT = 0x1,
3c824109
NF
14546
14547 MUL_FMT = 0x2,
14548
14549 DIV_FMT = 0x3,
14550
14551 /* These are the bit 8..6 values */
3a1f4268 14552 MOVN_FMT = 0x0,
3c824109
NF
14553 RSQRT2_FMT = 0x0,
14554 MOVF_FMT = 0x0,
3a1f4268
YK
14555 RINT_FMT = 0x0,
14556 SELNEZ_FMT = 0x0,
3c824109 14557
3a1f4268 14558 MOVZ_FMT = 0x1,
3c824109
NF
14559 LWXC1 = 0x1,
14560 MOVT_FMT = 0x1,
3a1f4268
YK
14561 CLASS_FMT = 0x1,
14562 SELEQZ_FMT = 0x1,
3c824109
NF
14563
14564 PLL_PS = 0x2,
14565 SWXC1 = 0x2,
3a1f4268 14566 SEL_FMT = 0x2,
3c824109
NF
14567
14568 PLU_PS = 0x3,
14569 LDXC1 = 0x3,
14570
3a1f4268 14571 MOVN_FMT_04 = 0x4,
3c824109
NF
14572 PUL_PS = 0x4,
14573 SDXC1 = 0x4,
14574 RECIP2_FMT = 0x4,
14575
3a1f4268 14576 MOVZ_FMT_05 = 0x05,
3c824109
NF
14577 PUU_PS = 0x5,
14578 LUXC1 = 0x5,
14579
14580 CVT_PS_S = 0x6,
14581 SUXC1 = 0x6,
14582 ADDR_PS = 0x6,
14583 PREFX = 0x6,
3a1f4268 14584 MADDF_FMT = 0x6,
3c824109
NF
14585
14586 MULR_PS = 0x7,
3a1f4268 14587 MSUBF_FMT = 0x7,
3c824109
NF
14588
14589 MADD_S = 0x01,
14590 MADD_D = 0x09,
14591 MADD_PS = 0x11,
14592 ALNV_PS = 0x19,
14593 MSUB_S = 0x21,
14594 MSUB_D = 0x29,
14595 MSUB_PS = 0x31,
14596
14597 NMADD_S = 0x02,
14598 NMADD_D = 0x0a,
14599 NMADD_PS = 0x12,
14600 NMSUB_S = 0x22,
14601 NMSUB_D = 0x2a,
14602 NMSUB_PS = 0x32,
14603
3a1f4268
YK
14604 MIN_FMT = 0x3,
14605 MAX_FMT = 0xb,
14606 MINA_FMT = 0x23,
14607 MAXA_FMT = 0x2b,
3c824109
NF
14608 POOL32FXF = 0x3b,
14609
14610 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
14611 C_COND_FMT = 0x3c,
14612
14613 CMP_CONDN_S = 0x5,
14614 CMP_CONDN_D = 0x15
3c824109
NF
14615};
14616
14617/* POOL32Fxf encoding of minor opcode extension field */
14618
14619enum {
14620 CVT_L = 0x04,
14621 RSQRT_FMT = 0x08,
14622 FLOOR_L = 0x0c,
14623 CVT_PW_PS = 0x1c,
14624 CVT_W = 0x24,
14625 SQRT_FMT = 0x28,
14626 FLOOR_W = 0x2c,
14627 CVT_PS_PW = 0x3c,
14628 CFC1 = 0x40,
14629 RECIP_FMT = 0x48,
14630 CEIL_L = 0x4c,
14631 CTC1 = 0x60,
14632 CEIL_W = 0x6c,
14633 MFC1 = 0x80,
14634 CVT_S_PL = 0x84,
14635 TRUNC_L = 0x8c,
14636 MTC1 = 0xa0,
14637 CVT_S_PU = 0xa4,
14638 TRUNC_W = 0xac,
14639 MFHC1 = 0xc0,
14640 ROUND_L = 0xcc,
14641 MTHC1 = 0xe0,
14642 ROUND_W = 0xec,
14643
14644 MOV_FMT = 0x01,
14645 MOVF = 0x05,
14646 ABS_FMT = 0x0d,
14647 RSQRT1_FMT = 0x1d,
14648 MOVT = 0x25,
14649 NEG_FMT = 0x2d,
14650 CVT_D = 0x4d,
14651 RECIP1_FMT = 0x5d,
14652 CVT_S = 0x6d
14653};
14654
14655/* POOL32I encoding of minor opcode field (bits 25..21) */
14656
14657enum {
14658 BLTZ = 0x00,
14659 BLTZAL = 0x01,
14660 BGEZ = 0x02,
14661 BGEZAL = 0x03,
14662 BLEZ = 0x04,
14663 BNEZC = 0x05,
14664 BGTZ = 0x06,
14665 BEQZC = 0x07,
14666 TLTI = 0x08,
3a1f4268 14667 BC1EQZC = 0x08,
3c824109 14668 TGEI = 0x09,
3a1f4268 14669 BC1NEZC = 0x09,
3c824109 14670 TLTIU = 0x0a,
3a1f4268 14671 BC2EQZC = 0x0a,
3c824109 14672 TGEIU = 0x0b,
3a1f4268 14673 BC2NEZC = 0x0a,
3c824109 14674 TNEI = 0x0c,
3a1f4268 14675 R6_SYNCI = 0x0c,
3c824109
NF
14676 LUI = 0x0d,
14677 TEQI = 0x0e,
14678 SYNCI = 0x10,
14679 BLTZALS = 0x11,
14680 BGEZALS = 0x13,
14681 BC2F = 0x14,
14682 BC2T = 0x15,
14683 BPOSGE64 = 0x1a,
14684 BPOSGE32 = 0x1b,
14685 /* These overlap and are distinguished by bit16 of the instruction */
14686 BC1F = 0x1c,
14687 BC1T = 0x1d,
14688 BC1ANY2F = 0x1c,
14689 BC1ANY2T = 0x1d,
14690 BC1ANY4F = 0x1e,
14691 BC1ANY4T = 0x1f
14692};
14693
14694/* POOL16A encoding of minor opcode field */
14695
14696enum {
14697 ADDU16 = 0x0,
14698 SUBU16 = 0x1
14699};
14700
14701/* POOL16B encoding of minor opcode field */
14702
14703enum {
14704 SLL16 = 0x0,
14705 SRL16 = 0x1
14706};
14707
14708/* POOL16C encoding of minor opcode field */
14709
14710enum {
14711 NOT16 = 0x00,
14712 XOR16 = 0x04,
14713 AND16 = 0x08,
14714 OR16 = 0x0c,
14715 LWM16 = 0x10,
14716 SWM16 = 0x14,
14717 JR16 = 0x18,
14718 JRC16 = 0x1a,
14719 JALR16 = 0x1c,
14720 JALR16S = 0x1e,
14721 MFHI16 = 0x20,
14722 MFLO16 = 0x24,
14723 BREAK16 = 0x28,
14724 SDBBP16 = 0x2c,
14725 JRADDIUSP = 0x30
14726};
14727
3a1f4268
YK
14728/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14729
14730enum {
14731 R6_NOT16 = 0x00,
14732 R6_AND16 = 0x01,
14733 R6_LWM16 = 0x02,
14734 R6_JRC16 = 0x03,
14735 MOVEP = 0x04,
c38a1d52
AR
14736 MOVEP_05 = 0x05,
14737 MOVEP_06 = 0x06,
3a1f4268
YK
14738 MOVEP_07 = 0x07,
14739 R6_XOR16 = 0x08,
14740 R6_OR16 = 0x09,
14741 R6_SWM16 = 0x0a,
14742 JALRC16 = 0x0b,
14743 MOVEP_0C = 0x0c,
c38a1d52
AR
14744 MOVEP_0D = 0x0d,
14745 MOVEP_0E = 0x0e,
3a1f4268
YK
14746 MOVEP_0F = 0x0f,
14747 JRCADDIUSP = 0x13,
14748 R6_BREAK16 = 0x1b,
14749 R6_SDBBP16 = 0x3b
14750};
14751
3c824109
NF
14752/* POOL16D encoding of minor opcode field */
14753
14754enum {
14755 ADDIUS5 = 0x0,
14756 ADDIUSP = 0x1
14757};
14758
14759/* POOL16E encoding of minor opcode field */
14760
14761enum {
14762 ADDIUR2 = 0x0,
14763 ADDIUR1SP = 0x1
14764};
14765
14766static int mmreg (int r)
14767{
14768 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14769
14770 return map[r];
14771}
14772
14773/* Used for 16-bit store instructions. */
14774static int mmreg2 (int r)
14775{
14776 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14777
14778 return map[r];
14779}
14780
14781#define uMIPS_RD(op) ((op >> 7) & 0x7)
14782#define uMIPS_RS(op) ((op >> 4) & 0x7)
14783#define uMIPS_RS2(op) uMIPS_RS(op)
14784#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14785#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14786#define uMIPS_RS5(op) (op & 0x1f)
14787
14788/* Signed immediate */
14789#define SIMM(op, start, width) \
14790 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14791 << (32-width)) \
14792 >> (32-width))
14793/* Zero-extended immediate */
14794#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14795
d75c135e 14796static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
14797{
14798 int rd = mmreg(uMIPS_RD(ctx->opcode));
14799
d75c135e 14800 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
14801}
14802
d75c135e 14803static void gen_addiur2(DisasContext *ctx)
3c824109
NF
14804{
14805 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14806 int rd = mmreg(uMIPS_RD(ctx->opcode));
14807 int rs = mmreg(uMIPS_RS(ctx->opcode));
14808
d75c135e 14809 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
14810}
14811
d75c135e 14812static void gen_addiusp(DisasContext *ctx)
3c824109
NF
14813{
14814 int encoded = ZIMM(ctx->opcode, 1, 9);
14815 int decoded;
14816
14817 if (encoded <= 1) {
14818 decoded = 256 + encoded;
14819 } else if (encoded <= 255) {
14820 decoded = encoded;
14821 } else if (encoded <= 509) {
14822 decoded = encoded - 512;
14823 } else {
14824 decoded = encoded - 768;
14825 }
14826
d75c135e 14827 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
14828}
14829
d75c135e 14830static void gen_addius5(DisasContext *ctx)
3c824109
NF
14831{
14832 int imm = SIMM(ctx->opcode, 1, 4);
14833 int rd = (ctx->opcode >> 5) & 0x1f;
14834
d75c135e 14835 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
14836}
14837
d75c135e 14838static void gen_andi16(DisasContext *ctx)
3c824109
NF
14839{
14840 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14841 31, 32, 63, 64, 255, 32768, 65535 };
14842 int rd = mmreg(uMIPS_RD(ctx->opcode));
14843 int rs = mmreg(uMIPS_RS(ctx->opcode));
14844 int encoded = ZIMM(ctx->opcode, 0, 4);
14845
d75c135e 14846 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
14847}
14848
14849static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14850 int base, int16_t offset)
14851{
14852 TCGv t0, t1;
14853 TCGv_i32 t2;
14854
14855 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 14856 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14857 return;
14858 }
14859
14860 t0 = tcg_temp_new();
14861
14862 gen_base_offset_addr(ctx, t0, base, offset);
14863
14864 t1 = tcg_const_tl(reglist);
14865 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 14866
3c824109
NF
14867 save_cpu_state(ctx, 1);
14868 switch (opc) {
14869 case LWM32:
895c2d04 14870 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
14871 break;
14872 case SWM32:
895c2d04 14873 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
14874 break;
14875#ifdef TARGET_MIPS64
14876 case LDM:
895c2d04 14877 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
14878 break;
14879 case SDM:
895c2d04 14880 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 14881 break;
6af0bf9c 14882#endif
3c824109 14883 }
3c824109 14884 tcg_temp_free(t0);
33087598 14885 tcg_temp_free(t1);
3c824109
NF
14886 tcg_temp_free_i32(t2);
14887}
6af0bf9c 14888
3c824109 14889
240ce26a 14890static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 14891{
3c824109
NF
14892 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14893 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 14894
3c824109
NF
14895 switch (((ctx->opcode) >> 4) & 0x3f) {
14896 case NOT16 + 0:
14897 case NOT16 + 1:
14898 case NOT16 + 2:
14899 case NOT16 + 3:
d75c135e 14900 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
14901 break;
14902 case XOR16 + 0:
14903 case XOR16 + 1:
14904 case XOR16 + 2:
14905 case XOR16 + 3:
d75c135e 14906 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
14907 break;
14908 case AND16 + 0:
14909 case AND16 + 1:
14910 case AND16 + 2:
14911 case AND16 + 3:
d75c135e 14912 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
14913 break;
14914 case OR16 + 0:
14915 case OR16 + 1:
14916 case OR16 + 2:
14917 case OR16 + 3:
d75c135e 14918 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
14919 break;
14920 case LWM16 + 0:
14921 case LWM16 + 1:
14922 case LWM16 + 2:
14923 case LWM16 + 3:
14924 {
14925 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14926 int offset = ZIMM(ctx->opcode, 0, 4);
14927
14928 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14929 29, offset << 2);
14930 }
14931 break;
14932 case SWM16 + 0:
14933 case SWM16 + 1:
14934 case SWM16 + 2:
14935 case SWM16 + 3:
14936 {
14937 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14938 int offset = ZIMM(ctx->opcode, 0, 4);
14939
14940 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14941 29, offset << 2);
14942 }
14943 break;
14944 case JR16 + 0:
14945 case JR16 + 1:
14946 {
14947 int reg = ctx->opcode & 0x1f;
14948
b231c103 14949 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 14950 }
3c824109
NF
14951 break;
14952 case JRC16 + 0:
14953 case JRC16 + 1:
14954 {
14955 int reg = ctx->opcode & 0x1f;
b231c103 14956 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
14957 /* Let normal delay slot handling in our caller take us
14958 to the branch target. */
14959 }
14960 break;
14961 case JALR16 + 0:
14962 case JALR16 + 1:
b231c103
YK
14963 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14964 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14965 break;
3c824109
NF
14966 case JALR16S + 0:
14967 case JALR16S + 1:
b231c103
YK
14968 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14969 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14970 break;
14971 case MFHI16 + 0:
14972 case MFHI16 + 1:
26135ead 14973 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14974 break;
14975 case MFLO16 + 0:
14976 case MFLO16 + 1:
26135ead 14977 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14978 break;
14979 case BREAK16:
9c708c7f 14980 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
14981 break;
14982 case SDBBP16:
3b3c1694
LA
14983 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14984 gen_helper_do_semihosting(cpu_env);
14985 } else {
14986 /* XXX: not clear which exception should be raised
14987 * when in debug mode...
14988 */
14989 check_insn(ctx, ISA_MIPS32);
9c708c7f 14990 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14991 }
3c824109
NF
14992 break;
14993 case JRADDIUSP + 0:
14994 case JRADDIUSP + 1:
14995 {
14996 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 14997 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 14998 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
14999 /* Let normal delay slot handling in our caller take us
15000 to the branch target. */
15001 }
15002 break;
15003 default:
9c708c7f 15004 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15005 break;
15006 }
15007}
15008
ed7ce6c0
YK
15009static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15010 int enc_rs)
15011{
15012 int rd, rs, re, rt;
15013 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15014 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15015 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15016 rd = rd_enc[enc_dest];
15017 re = re_enc[enc_dest];
15018 rs = rs_rt_enc[enc_rs];
15019 rt = rs_rt_enc[enc_rt];
15020 if (rs) {
15021 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15022 } else {
15023 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15024 }
15025 if (rt) {
15026 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15027 } else {
15028 tcg_gen_movi_tl(cpu_gpr[re], 0);
15029 }
15030}
15031
15032static void gen_pool16c_r6_insn(DisasContext *ctx)
15033{
15034 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15035 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15036
15037 switch (ctx->opcode & 0xf) {
15038 case R6_NOT16:
15039 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15040 break;
15041 case R6_AND16:
15042 gen_logic(ctx, OPC_AND, rt, rt, rs);
15043 break;
15044 case R6_LWM16:
15045 {
15046 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15047 int offset = extract32(ctx->opcode, 4, 4);
15048 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15049 }
15050 break;
15051 case R6_JRC16: /* JRCADDIUSP */
15052 if ((ctx->opcode >> 4) & 1) {
15053 /* JRCADDIUSP */
15054 int imm = extract32(ctx->opcode, 5, 5);
15055 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15056 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15057 } else {
15058 /* JRC16 */
e1555d7d 15059 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
15060 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15061 }
15062 break;
c38a1d52
AR
15063 case MOVEP:
15064 case MOVEP_05:
15065 case MOVEP_06:
15066 case MOVEP_07:
15067 case MOVEP_0C:
15068 case MOVEP_0D:
15069 case MOVEP_0E:
15070 case MOVEP_0F:
ed7ce6c0
YK
15071 {
15072 int enc_dest = uMIPS_RD(ctx->opcode);
15073 int enc_rt = uMIPS_RS2(ctx->opcode);
15074 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15075 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15076 }
15077 break;
15078 case R6_XOR16:
15079 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15080 break;
15081 case R6_OR16:
15082 gen_logic(ctx, OPC_OR, rt, rt, rs);
15083 break;
15084 case R6_SWM16:
15085 {
15086 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15087 int offset = extract32(ctx->opcode, 4, 4);
15088 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15089 }
15090 break;
15091 case JALRC16: /* BREAK16, SDBBP16 */
15092 switch (ctx->opcode & 0x3f) {
15093 case JALRC16:
15094 case JALRC16 + 0x20:
15095 /* JALRC16 */
15096 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15097 31, 0, 0);
15098 break;
15099 case R6_BREAK16:
15100 /* BREAK16 */
15101 generate_exception(ctx, EXCP_BREAK);
15102 break;
15103 case R6_SDBBP16:
15104 /* SDBBP16 */
060ebfef
LA
15105 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15106 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 15107 } else {
060ebfef
LA
15108 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15109 generate_exception(ctx, EXCP_RI);
15110 } else {
15111 generate_exception(ctx, EXCP_DBp);
15112 }
ed7ce6c0
YK
15113 }
15114 break;
15115 }
15116 break;
15117 default:
15118 generate_exception(ctx, EXCP_RI);
15119 break;
15120 }
15121}
15122
3c824109
NF
15123static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15124{
15125 TCGv t0 = tcg_temp_new();
15126 TCGv t1 = tcg_temp_new();
15127
15128 gen_load_gpr(t0, base);
15129
15130 if (index != 0) {
15131 gen_load_gpr(t1, index);
15132 tcg_gen_shli_tl(t1, t1, 2);
15133 gen_op_addr_add(ctx, t0, t1, t0);
15134 }
15135
5f68f5ae 15136 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15137 gen_store_gpr(t1, rd);
15138
15139 tcg_temp_free(t0);
15140 tcg_temp_free(t1);
15141}
15142
15143static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15144 int base, int16_t offset)
15145{
3c824109
NF
15146 TCGv t0, t1;
15147
36c6711b 15148 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 15149 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
15150 return;
15151 }
15152
3c824109
NF
15153 t0 = tcg_temp_new();
15154 t1 = tcg_temp_new();
8e9ade68 15155
3c824109
NF
15156 gen_base_offset_addr(ctx, t0, base, offset);
15157
15158 switch (opc) {
15159 case LWP:
36c6711b 15160 if (rd == base) {
9c708c7f 15161 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
15162 return;
15163 }
5f68f5ae 15164 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15165 gen_store_gpr(t1, rd);
15166 tcg_gen_movi_tl(t1, 4);
15167 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15168 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 15169 gen_store_gpr(t1, rd+1);
3c824109
NF
15170 break;
15171 case SWP:
3c824109 15172 gen_load_gpr(t1, rd);
5f68f5ae 15173 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15174 tcg_gen_movi_tl(t1, 4);
15175 gen_op_addr_add(ctx, t0, t0, t1);
15176 gen_load_gpr(t1, rd+1);
5f68f5ae 15177 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15178 break;
15179#ifdef TARGET_MIPS64
15180 case LDP:
36c6711b 15181 if (rd == base) {
9c708c7f 15182 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
15183 return;
15184 }
5f68f5ae 15185 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15186 gen_store_gpr(t1, rd);
15187 tcg_gen_movi_tl(t1, 8);
15188 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15189 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 15190 gen_store_gpr(t1, rd+1);
3c824109
NF
15191 break;
15192 case SDP:
3c824109 15193 gen_load_gpr(t1, rd);
5f68f5ae 15194 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15195 tcg_gen_movi_tl(t1, 8);
15196 gen_op_addr_add(ctx, t0, t0, t1);
15197 gen_load_gpr(t1, rd+1);
5f68f5ae 15198 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15199 break;
15200#endif
6af0bf9c 15201 }
3c824109
NF
15202 tcg_temp_free(t0);
15203 tcg_temp_free(t1);
15204}
618b0fe9 15205
d208ac0c
LA
15206static void gen_sync(int stype)
15207{
15208 TCGBar tcg_mo = TCG_BAR_SC;
15209
15210 switch (stype) {
15211 case 0x4: /* SYNC_WMB */
15212 tcg_mo |= TCG_MO_ST_ST;
15213 break;
15214 case 0x10: /* SYNC_MB */
15215 tcg_mo |= TCG_MO_ALL;
15216 break;
15217 case 0x11: /* SYNC_ACQUIRE */
15218 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15219 break;
15220 case 0x12: /* SYNC_RELEASE */
15221 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15222 break;
15223 case 0x13: /* SYNC_RMB */
15224 tcg_mo |= TCG_MO_LD_LD;
15225 break;
15226 default:
15227 tcg_mo |= TCG_MO_ALL;
15228 break;
15229 }
15230
15231 tcg_gen_mb(tcg_mo);
15232}
15233
240ce26a 15234static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
15235{
15236 int extension = (ctx->opcode >> 6) & 0x3f;
15237 int minor = (ctx->opcode >> 12) & 0xf;
15238 uint32_t mips32_op;
15239
15240 switch (extension) {
15241 case TEQ:
15242 mips32_op = OPC_TEQ;
15243 goto do_trap;
15244 case TGE:
15245 mips32_op = OPC_TGE;
15246 goto do_trap;
15247 case TGEU:
15248 mips32_op = OPC_TGEU;
15249 goto do_trap;
15250 case TLT:
15251 mips32_op = OPC_TLT;
15252 goto do_trap;
15253 case TLTU:
15254 mips32_op = OPC_TLTU;
15255 goto do_trap;
15256 case TNE:
15257 mips32_op = OPC_TNE;
15258 do_trap:
15259 gen_trap(ctx, mips32_op, rs, rt, -1);
15260 break;
15261#ifndef CONFIG_USER_ONLY
15262 case MFC0:
15263 case MFC0 + 32:
2e15497c 15264 check_cp0_enabled(ctx);
3c824109
NF
15265 if (rt == 0) {
15266 /* Treat as NOP. */
15267 break;
15268 }
d75c135e 15269 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15270 break;
15271 case MTC0:
15272 case MTC0 + 32:
2e15497c 15273 check_cp0_enabled(ctx);
3c824109
NF
15274 {
15275 TCGv t0 = tcg_temp_new();
618b0fe9 15276
3c824109 15277 gen_load_gpr(t0, rt);
d75c135e 15278 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15279 tcg_temp_free(t0);
15280 }
15281 break;
15282#endif
a1fc6246
LA
15283 case 0x2a:
15284 switch (minor & 3) {
15285 case MADD_ACC:
15286 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15287 break;
15288 case MADDU_ACC:
15289 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15290 break;
15291 case MSUB_ACC:
15292 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15293 break;
15294 case MSUBU_ACC:
15295 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15296 break;
15297 default:
15298 goto pool32axf_invalid;
15299 }
15300 break;
15301 case 0x32:
15302 switch (minor & 3) {
15303 case MULT_ACC:
15304 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15305 break;
15306 case MULTU_ACC:
15307 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15308 break;
15309 default:
15310 goto pool32axf_invalid;
15311 }
15312 break;
3c824109
NF
15313 case 0x2c:
15314 switch (minor) {
e0332095
YK
15315 case BITSWAP:
15316 check_insn(ctx, ISA_MIPS32R6);
15317 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15318 break;
3c824109
NF
15319 case SEB:
15320 gen_bshfl(ctx, OPC_SEB, rs, rt);
15321 break;
15322 case SEH:
15323 gen_bshfl(ctx, OPC_SEH, rs, rt);
15324 break;
15325 case CLO:
15326 mips32_op = OPC_CLO;
15327 goto do_cl;
15328 case CLZ:
15329 mips32_op = OPC_CLZ;
15330 do_cl:
d75c135e 15331 check_insn(ctx, ISA_MIPS32);
3c824109
NF
15332 gen_cl(ctx, mips32_op, rt, rs);
15333 break;
15334 case RDHWR:
b00c7218
YK
15335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15336 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
15337 break;
15338 case WSBH:
15339 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15340 break;
15341 case MULT:
9e8f441a 15342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15343 mips32_op = OPC_MULT;
26135ead 15344 goto do_mul;
3c824109 15345 case MULTU:
9e8f441a 15346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15347 mips32_op = OPC_MULTU;
26135ead 15348 goto do_mul;
3c824109 15349 case DIV:
9e8f441a 15350 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15351 mips32_op = OPC_DIV;
26135ead 15352 goto do_div;
3c824109 15353 case DIVU:
9e8f441a 15354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15355 mips32_op = OPC_DIVU;
26135ead
RS
15356 goto do_div;
15357 do_div:
15358 check_insn(ctx, ISA_MIPS32);
15359 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15360 break;
3c824109 15361 case MADD:
9e8f441a 15362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15363 mips32_op = OPC_MADD;
26135ead 15364 goto do_mul;
3c824109 15365 case MADDU:
9e8f441a 15366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15367 mips32_op = OPC_MADDU;
26135ead 15368 goto do_mul;
3c824109 15369 case MSUB:
9e8f441a 15370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15371 mips32_op = OPC_MSUB;
26135ead 15372 goto do_mul;
3c824109 15373 case MSUBU:
9e8f441a 15374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15375 mips32_op = OPC_MSUBU;
26135ead 15376 do_mul:
d75c135e 15377 check_insn(ctx, ISA_MIPS32);
a1fc6246 15378 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
15379 break;
15380 default:
15381 goto pool32axf_invalid;
15382 }
15383 break;
15384 case 0x34:
15385 switch (minor) {
15386 case MFC2:
15387 case MTC2:
15388 case MFHC2:
15389 case MTHC2:
15390 case CFC2:
15391 case CTC2:
15392 generate_exception_err(ctx, EXCP_CpU, 2);
15393 break;
15394 default:
15395 goto pool32axf_invalid;
15396 }
15397 break;
15398 case 0x3c:
15399 switch (minor) {
65935f07
YK
15400 case JALR: /* JALRC */
15401 case JALR_HB: /* JALRC_HB */
15402 if (ctx->insn_flags & ISA_MIPS32R6) {
15403 /* JALRC, JALRC_HB */
15404 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15405 } else {
15406 /* JALR, JALR_HB */
15407 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15408 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15409 }
3c824109
NF
15410 break;
15411 case JALRS:
15412 case JALRS_HB:
9e8f441a 15413 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15414 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15415 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15416 break;
15417 default:
15418 goto pool32axf_invalid;
15419 }
15420 break;
15421 case 0x05:
15422 switch (minor) {
15423 case RDPGPR:
2e15497c 15424 check_cp0_enabled(ctx);
d75c135e 15425 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15426 gen_load_srsgpr(rs, rt);
3c824109
NF
15427 break;
15428 case WRPGPR:
2e15497c 15429 check_cp0_enabled(ctx);
d75c135e 15430 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15431 gen_store_srsgpr(rs, rt);
3c824109
NF
15432 break;
15433 default:
15434 goto pool32axf_invalid;
15435 }
15436 break;
15437#ifndef CONFIG_USER_ONLY
15438 case 0x0d:
15439 switch (minor) {
15440 case TLBP:
15441 mips32_op = OPC_TLBP;
15442 goto do_cp0;
15443 case TLBR:
15444 mips32_op = OPC_TLBR;
15445 goto do_cp0;
15446 case TLBWI:
15447 mips32_op = OPC_TLBWI;
15448 goto do_cp0;
15449 case TLBWR:
15450 mips32_op = OPC_TLBWR;
15451 goto do_cp0;
e60ec063
YK
15452 case TLBINV:
15453 mips32_op = OPC_TLBINV;
15454 goto do_cp0;
15455 case TLBINVF:
15456 mips32_op = OPC_TLBINVF;
15457 goto do_cp0;
3c824109
NF
15458 case WAIT:
15459 mips32_op = OPC_WAIT;
15460 goto do_cp0;
15461 case DERET:
15462 mips32_op = OPC_DERET;
15463 goto do_cp0;
15464 case ERET:
15465 mips32_op = OPC_ERET;
15466 do_cp0:
15467 gen_cp0(env, ctx, mips32_op, rt, rs);
15468 break;
15469 default:
15470 goto pool32axf_invalid;
15471 }
15472 break;
15473 case 0x1d:
15474 switch (minor) {
15475 case DI:
2e15497c 15476 check_cp0_enabled(ctx);
3c824109
NF
15477 {
15478 TCGv t0 = tcg_temp_new();
15479
15480 save_cpu_state(ctx, 1);
895c2d04 15481 gen_helper_di(t0, cpu_env);
3c824109
NF
15482 gen_store_gpr(t0, rs);
15483 /* Stop translation as we may have switched the execution mode */
eeb3bba8 15484 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15485 tcg_temp_free(t0);
15486 }
15487 break;
15488 case EI:
2e15497c 15489 check_cp0_enabled(ctx);
3c824109
NF
15490 {
15491 TCGv t0 = tcg_temp_new();
15492
15493 save_cpu_state(ctx, 1);
895c2d04 15494 gen_helper_ei(t0, cpu_env);
3c824109 15495 gen_store_gpr(t0, rs);
b28425ba 15496 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 15497 of translated code to check for pending interrupts. */
eeb3bba8
EC
15498 gen_save_pc(ctx->base.pc_next + 4);
15499 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
15500 tcg_temp_free(t0);
15501 }
15502 break;
15503 default:
15504 goto pool32axf_invalid;
15505 }
15506 break;
15507#endif
15508 case 0x2d:
15509 switch (minor) {
15510 case SYNC:
d208ac0c 15511 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
15512 break;
15513 case SYSCALL:
9c708c7f 15514 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
15515 break;
15516 case SDBBP:
3b3c1694
LA
15517 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15518 gen_helper_do_semihosting(cpu_env);
15519 } else {
15520 check_insn(ctx, ISA_MIPS32);
e0332095 15521 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 15522 generate_exception_end(ctx, EXCP_RI);
e0332095 15523 } else {
9c708c7f 15524 generate_exception_end(ctx, EXCP_DBp);
e0332095 15525 }
3b3c1694 15526 }
3c824109
NF
15527 break;
15528 default:
15529 goto pool32axf_invalid;
15530 }
15531 break;
a1fc6246 15532 case 0x01:
26135ead 15533 switch (minor & 3) {
a1fc6246 15534 case MFHI_ACC:
26135ead 15535 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 15536 break;
a1fc6246 15537 case MFLO_ACC:
26135ead 15538 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 15539 break;
a1fc6246 15540 case MTHI_ACC:
26135ead 15541 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 15542 break;
a1fc6246 15543 case MTLO_ACC:
26135ead 15544 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
15545 break;
15546 default:
15547 goto pool32axf_invalid;
15548 }
15549 break;
a1fc6246 15550 case 0x35:
9e8f441a 15551 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
15552 switch (minor) {
15553 case MFHI32:
15554 gen_HILO(ctx, OPC_MFHI, 0, rs);
15555 break;
15556 case MFLO32:
15557 gen_HILO(ctx, OPC_MFLO, 0, rs);
15558 break;
15559 case MTHI32:
15560 gen_HILO(ctx, OPC_MTHI, 0, rs);
15561 break;
15562 case MTLO32:
15563 gen_HILO(ctx, OPC_MTLO, 0, rs);
15564 break;
15565 default:
15566 goto pool32axf_invalid;
15567 }
15568 break;
3c824109
NF
15569 default:
15570 pool32axf_invalid:
15571 MIPS_INVAL("pool32axf");
9c708c7f 15572 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15573 break;
15574 }
15575}
15576
15577/* Values for microMIPS fmt field. Variable-width, depending on which
15578 formats the instruction supports. */
15579
15580enum {
15581 FMT_SD_S = 0,
15582 FMT_SD_D = 1,
15583
15584 FMT_SDPS_S = 0,
15585 FMT_SDPS_D = 1,
15586 FMT_SDPS_PS = 2,
15587
15588 FMT_SWL_S = 0,
15589 FMT_SWL_W = 1,
15590 FMT_SWL_L = 2,
15591
15592 FMT_DWL_D = 0,
15593 FMT_DWL_W = 1,
15594 FMT_DWL_L = 2
15595};
15596
d75c135e 15597static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
15598{
15599 int extension = (ctx->opcode >> 6) & 0x3ff;
15600 uint32_t mips32_op;
15601
15602#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15603#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15604#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15605
15606 switch (extension) {
15607 case FLOAT_1BIT_FMT(CFC1, 0):
15608 mips32_op = OPC_CFC1;
15609 goto do_cp1;
15610 case FLOAT_1BIT_FMT(CTC1, 0):
15611 mips32_op = OPC_CTC1;
15612 goto do_cp1;
15613 case FLOAT_1BIT_FMT(MFC1, 0):
15614 mips32_op = OPC_MFC1;
15615 goto do_cp1;
15616 case FLOAT_1BIT_FMT(MTC1, 0):
15617 mips32_op = OPC_MTC1;
15618 goto do_cp1;
15619 case FLOAT_1BIT_FMT(MFHC1, 0):
15620 mips32_op = OPC_MFHC1;
15621 goto do_cp1;
15622 case FLOAT_1BIT_FMT(MTHC1, 0):
15623 mips32_op = OPC_MTHC1;
15624 do_cp1:
15625 gen_cp1(ctx, mips32_op, rt, rs);
15626 break;
15627
15628 /* Reciprocal square root */
15629 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15630 mips32_op = OPC_RSQRT_S;
15631 goto do_unaryfp;
15632 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15633 mips32_op = OPC_RSQRT_D;
15634 goto do_unaryfp;
15635
15636 /* Square root */
15637 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15638 mips32_op = OPC_SQRT_S;
15639 goto do_unaryfp;
15640 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15641 mips32_op = OPC_SQRT_D;
15642 goto do_unaryfp;
15643
15644 /* Reciprocal */
15645 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15646 mips32_op = OPC_RECIP_S;
15647 goto do_unaryfp;
15648 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15649 mips32_op = OPC_RECIP_D;
15650 goto do_unaryfp;
15651
15652 /* Floor */
15653 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15654 mips32_op = OPC_FLOOR_L_S;
15655 goto do_unaryfp;
15656 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15657 mips32_op = OPC_FLOOR_L_D;
15658 goto do_unaryfp;
15659 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15660 mips32_op = OPC_FLOOR_W_S;
15661 goto do_unaryfp;
15662 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15663 mips32_op = OPC_FLOOR_W_D;
15664 goto do_unaryfp;
15665
15666 /* Ceiling */
15667 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15668 mips32_op = OPC_CEIL_L_S;
15669 goto do_unaryfp;
15670 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15671 mips32_op = OPC_CEIL_L_D;
15672 goto do_unaryfp;
15673 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15674 mips32_op = OPC_CEIL_W_S;
15675 goto do_unaryfp;
15676 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15677 mips32_op = OPC_CEIL_W_D;
15678 goto do_unaryfp;
15679
15680 /* Truncation */
15681 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15682 mips32_op = OPC_TRUNC_L_S;
15683 goto do_unaryfp;
15684 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15685 mips32_op = OPC_TRUNC_L_D;
15686 goto do_unaryfp;
15687 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15688 mips32_op = OPC_TRUNC_W_S;
15689 goto do_unaryfp;
15690 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15691 mips32_op = OPC_TRUNC_W_D;
15692 goto do_unaryfp;
15693
15694 /* Round */
15695 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15696 mips32_op = OPC_ROUND_L_S;
15697 goto do_unaryfp;
15698 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15699 mips32_op = OPC_ROUND_L_D;
15700 goto do_unaryfp;
15701 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15702 mips32_op = OPC_ROUND_W_S;
15703 goto do_unaryfp;
15704 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15705 mips32_op = OPC_ROUND_W_D;
15706 goto do_unaryfp;
15707
15708 /* Integer to floating-point conversion */
15709 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15710 mips32_op = OPC_CVT_L_S;
15711 goto do_unaryfp;
15712 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15713 mips32_op = OPC_CVT_L_D;
15714 goto do_unaryfp;
15715 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15716 mips32_op = OPC_CVT_W_S;
15717 goto do_unaryfp;
15718 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15719 mips32_op = OPC_CVT_W_D;
15720 goto do_unaryfp;
15721
15722 /* Paired-foo conversions */
15723 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15724 mips32_op = OPC_CVT_S_PL;
15725 goto do_unaryfp;
15726 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15727 mips32_op = OPC_CVT_S_PU;
15728 goto do_unaryfp;
15729 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15730 mips32_op = OPC_CVT_PW_PS;
15731 goto do_unaryfp;
15732 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15733 mips32_op = OPC_CVT_PS_PW;
15734 goto do_unaryfp;
15735
15736 /* Floating-point moves */
15737 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15738 mips32_op = OPC_MOV_S;
15739 goto do_unaryfp;
15740 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15741 mips32_op = OPC_MOV_D;
15742 goto do_unaryfp;
15743 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15744 mips32_op = OPC_MOV_PS;
15745 goto do_unaryfp;
15746
15747 /* Absolute value */
15748 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15749 mips32_op = OPC_ABS_S;
15750 goto do_unaryfp;
15751 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15752 mips32_op = OPC_ABS_D;
15753 goto do_unaryfp;
15754 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15755 mips32_op = OPC_ABS_PS;
15756 goto do_unaryfp;
15757
15758 /* Negation */
15759 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15760 mips32_op = OPC_NEG_S;
15761 goto do_unaryfp;
15762 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15763 mips32_op = OPC_NEG_D;
15764 goto do_unaryfp;
15765 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15766 mips32_op = OPC_NEG_PS;
15767 goto do_unaryfp;
15768
15769 /* Reciprocal square root step */
15770 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15771 mips32_op = OPC_RSQRT1_S;
15772 goto do_unaryfp;
15773 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15774 mips32_op = OPC_RSQRT1_D;
15775 goto do_unaryfp;
15776 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15777 mips32_op = OPC_RSQRT1_PS;
15778 goto do_unaryfp;
15779
15780 /* Reciprocal step */
15781 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15782 mips32_op = OPC_RECIP1_S;
15783 goto do_unaryfp;
15784 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15785 mips32_op = OPC_RECIP1_S;
15786 goto do_unaryfp;
15787 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15788 mips32_op = OPC_RECIP1_PS;
15789 goto do_unaryfp;
15790
15791 /* Conversions from double */
15792 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15793 mips32_op = OPC_CVT_D_S;
15794 goto do_unaryfp;
15795 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15796 mips32_op = OPC_CVT_D_W;
15797 goto do_unaryfp;
15798 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15799 mips32_op = OPC_CVT_D_L;
15800 goto do_unaryfp;
15801
15802 /* Conversions from single */
15803 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15804 mips32_op = OPC_CVT_S_D;
15805 goto do_unaryfp;
15806 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15807 mips32_op = OPC_CVT_S_W;
15808 goto do_unaryfp;
15809 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15810 mips32_op = OPC_CVT_S_L;
15811 do_unaryfp:
15812 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15813 break;
15814
15815 /* Conditional moves on floating-point codes */
15816 case COND_FLOAT_MOV(MOVT, 0):
15817 case COND_FLOAT_MOV(MOVT, 1):
15818 case COND_FLOAT_MOV(MOVT, 2):
15819 case COND_FLOAT_MOV(MOVT, 3):
15820 case COND_FLOAT_MOV(MOVT, 4):
15821 case COND_FLOAT_MOV(MOVT, 5):
15822 case COND_FLOAT_MOV(MOVT, 6):
15823 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 15824 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15825 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15826 break;
15827 case COND_FLOAT_MOV(MOVF, 0):
15828 case COND_FLOAT_MOV(MOVF, 1):
15829 case COND_FLOAT_MOV(MOVF, 2):
15830 case COND_FLOAT_MOV(MOVF, 3):
15831 case COND_FLOAT_MOV(MOVF, 4):
15832 case COND_FLOAT_MOV(MOVF, 5):
15833 case COND_FLOAT_MOV(MOVF, 6):
15834 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 15835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15836 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15837 break;
15838 default:
15839 MIPS_INVAL("pool32fxf");
9c708c7f 15840 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15841 break;
15842 }
15843}
15844
f60eeb0c 15845static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15846{
15847 int32_t offset;
15848 uint16_t insn;
15849 int rt, rs, rd, rr;
15850 int16_t imm;
8fffc646 15851 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
15852 uint32_t cond, fmt, cc;
15853
eeb3bba8 15854 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
15855 ctx->opcode = (ctx->opcode << 16) | insn;
15856
15857 rt = (ctx->opcode >> 21) & 0x1f;
15858 rs = (ctx->opcode >> 16) & 0x1f;
15859 rd = (ctx->opcode >> 11) & 0x1f;
15860 rr = (ctx->opcode >> 6) & 0x1f;
15861 imm = (int16_t) ctx->opcode;
15862
15863 op = (ctx->opcode >> 26) & 0x3f;
15864 switch (op) {
15865 case POOL32A:
15866 minor = ctx->opcode & 0x3f;
15867 switch (minor) {
15868 case 0x00:
15869 minor = (ctx->opcode >> 6) & 0xf;
15870 switch (minor) {
15871 case SLL32:
15872 mips32_op = OPC_SLL;
15873 goto do_shifti;
15874 case SRA:
15875 mips32_op = OPC_SRA;
15876 goto do_shifti;
15877 case SRL32:
15878 mips32_op = OPC_SRL;
15879 goto do_shifti;
15880 case ROTR:
15881 mips32_op = OPC_ROTR;
15882 do_shifti:
d75c135e 15883 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 15884 break;
e0332095
YK
15885 case SELEQZ:
15886 check_insn(ctx, ISA_MIPS32R6);
15887 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15888 break;
15889 case SELNEZ:
15890 check_insn(ctx, ISA_MIPS32R6);
15891 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15892 break;
b00c7218
YK
15893 case R6_RDHWR:
15894 check_insn(ctx, ISA_MIPS32R6);
15895 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15896 break;
3c824109
NF
15897 default:
15898 goto pool32a_invalid;
15899 }
15900 break;
15901 case 0x10:
15902 minor = (ctx->opcode >> 6) & 0xf;
15903 switch (minor) {
15904 /* Arithmetic */
15905 case ADD:
15906 mips32_op = OPC_ADD;
15907 goto do_arith;
15908 case ADDU32:
15909 mips32_op = OPC_ADDU;
15910 goto do_arith;
15911 case SUB:
15912 mips32_op = OPC_SUB;
15913 goto do_arith;
15914 case SUBU32:
15915 mips32_op = OPC_SUBU;
15916 goto do_arith;
15917 case MUL:
9e8f441a 15918 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15919 mips32_op = OPC_MUL;
15920 do_arith:
d75c135e 15921 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15922 break;
15923 /* Shifts */
15924 case SLLV:
15925 mips32_op = OPC_SLLV;
15926 goto do_shift;
15927 case SRLV:
15928 mips32_op = OPC_SRLV;
15929 goto do_shift;
15930 case SRAV:
15931 mips32_op = OPC_SRAV;
15932 goto do_shift;
15933 case ROTRV:
15934 mips32_op = OPC_ROTRV;
15935 do_shift:
d75c135e 15936 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15937 break;
15938 /* Logical operations */
15939 case AND:
15940 mips32_op = OPC_AND;
15941 goto do_logic;
15942 case OR32:
15943 mips32_op = OPC_OR;
15944 goto do_logic;
15945 case NOR:
15946 mips32_op = OPC_NOR;
15947 goto do_logic;
15948 case XOR32:
15949 mips32_op = OPC_XOR;
15950 do_logic:
d75c135e 15951 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15952 break;
15953 /* Set less than */
15954 case SLT:
15955 mips32_op = OPC_SLT;
15956 goto do_slt;
15957 case SLTU:
15958 mips32_op = OPC_SLTU;
15959 do_slt:
d75c135e 15960 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15961 break;
15962 default:
15963 goto pool32a_invalid;
15964 }
15965 break;
15966 case 0x18:
15967 minor = (ctx->opcode >> 6) & 0xf;
15968 switch (minor) {
15969 /* Conditional moves */
e0332095
YK
15970 case MOVN: /* MUL */
15971 if (ctx->insn_flags & ISA_MIPS32R6) {
15972 /* MUL */
15973 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15974 } else {
15975 /* MOVN */
15976 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15977 }
15978 break;
15979 case MOVZ: /* MUH */
15980 if (ctx->insn_flags & ISA_MIPS32R6) {
15981 /* MUH */
15982 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15983 } else {
15984 /* MOVZ */
15985 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15986 }
15987 break;
15988 case MULU:
15989 check_insn(ctx, ISA_MIPS32R6);
15990 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15991 break;
15992 case MUHU:
15993 check_insn(ctx, ISA_MIPS32R6);
15994 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15995 break;
15996 case LWXS: /* DIV */
15997 if (ctx->insn_flags & ISA_MIPS32R6) {
15998 /* DIV */
15999 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16000 } else {
16001 /* LWXS */
16002 gen_ldxs(ctx, rs, rt, rd);
16003 }
16004 break;
16005 case MOD:
16006 check_insn(ctx, ISA_MIPS32R6);
16007 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16008 break;
16009 case R6_DIVU:
16010 check_insn(ctx, ISA_MIPS32R6);
16011 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 16012 break;
e0332095
YK
16013 case MODU:
16014 check_insn(ctx, ISA_MIPS32R6);
16015 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
16016 break;
16017 default:
16018 goto pool32a_invalid;
16019 }
16020 break;
16021 case INS:
16022 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16023 return;
e0332095
YK
16024 case LSA:
16025 check_insn(ctx, ISA_MIPS32R6);
16026 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16027 extract32(ctx->opcode, 9, 2));
16028 break;
16029 case ALIGN:
16030 check_insn(ctx, ISA_MIPS32R6);
821f2008 16031 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 16032 break;
3c824109
NF
16033 case EXT:
16034 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16035 return;
16036 case POOL32AXF:
240ce26a 16037 gen_pool32axf(env, ctx, rt, rs);
3c824109 16038 break;
dbd8af98 16039 case BREAK32:
9c708c7f 16040 generate_exception_end(ctx, EXCP_BREAK);
3c824109 16041 break;
bb238210
YK
16042 case SIGRIE:
16043 check_insn(ctx, ISA_MIPS32R6);
16044 generate_exception_end(ctx, EXCP_RI);
16045 break;
3c824109
NF
16046 default:
16047 pool32a_invalid:
16048 MIPS_INVAL("pool32a");
9c708c7f 16049 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16050 break;
16051 }
16052 break;
16053 case POOL32B:
16054 minor = (ctx->opcode >> 12) & 0xf;
16055 switch (minor) {
16056 case CACHE:
2e15497c 16057 check_cp0_enabled(ctx);
0d74a222
LA
16058 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16059 gen_cache_operation(ctx, rt, rs, imm);
16060 }
3c824109
NF
16061 break;
16062 case LWC2:
16063 case SWC2:
16064 /* COP2: Not implemented. */
16065 generate_exception_err(ctx, EXCP_CpU, 2);
16066 break;
3c824109
NF
16067#ifdef TARGET_MIPS64
16068 case LDP:
16069 case SDP:
d9224450
MR
16070 check_insn(ctx, ISA_MIPS3);
16071 check_mips_64(ctx);
3c824109 16072#endif
146dd620 16073 /* fall through */
d9224450
MR
16074 case LWP:
16075 case SWP:
3c824109
NF
16076 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16077 break;
3c824109
NF
16078#ifdef TARGET_MIPS64
16079 case LDM:
16080 case SDM:
d9224450
MR
16081 check_insn(ctx, ISA_MIPS3);
16082 check_mips_64(ctx);
3c824109 16083#endif
146dd620 16084 /* fall through */
d9224450
MR
16085 case LWM32:
16086 case SWM32:
3c824109
NF
16087 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16088 break;
16089 default:
16090 MIPS_INVAL("pool32b");
9c708c7f 16091 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16092 break;
16093 }
16094 break;
16095 case POOL32F:
5ab5c041 16096 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
16097 minor = ctx->opcode & 0x3f;
16098 check_cp1_enabled(ctx);
16099 switch (minor) {
16100 case ALNV_PS:
9e8f441a 16101 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16102 mips32_op = OPC_ALNV_PS;
16103 goto do_madd;
16104 case MADD_S:
9e8f441a 16105 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16106 mips32_op = OPC_MADD_S;
16107 goto do_madd;
16108 case MADD_D:
9e8f441a 16109 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16110 mips32_op = OPC_MADD_D;
16111 goto do_madd;
16112 case MADD_PS:
9e8f441a 16113 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16114 mips32_op = OPC_MADD_PS;
16115 goto do_madd;
16116 case MSUB_S:
9e8f441a 16117 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16118 mips32_op = OPC_MSUB_S;
16119 goto do_madd;
16120 case MSUB_D:
9e8f441a 16121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16122 mips32_op = OPC_MSUB_D;
16123 goto do_madd;
16124 case MSUB_PS:
9e8f441a 16125 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16126 mips32_op = OPC_MSUB_PS;
16127 goto do_madd;
16128 case NMADD_S:
9e8f441a 16129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16130 mips32_op = OPC_NMADD_S;
16131 goto do_madd;
16132 case NMADD_D:
9e8f441a 16133 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16134 mips32_op = OPC_NMADD_D;
16135 goto do_madd;
16136 case NMADD_PS:
9e8f441a 16137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16138 mips32_op = OPC_NMADD_PS;
16139 goto do_madd;
16140 case NMSUB_S:
9e8f441a 16141 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16142 mips32_op = OPC_NMSUB_S;
16143 goto do_madd;
16144 case NMSUB_D:
9e8f441a 16145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16146 mips32_op = OPC_NMSUB_D;
16147 goto do_madd;
16148 case NMSUB_PS:
9e8f441a 16149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16150 mips32_op = OPC_NMSUB_PS;
16151 do_madd:
16152 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16153 break;
16154 case CABS_COND_FMT:
9e8f441a 16155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16156 cond = (ctx->opcode >> 6) & 0xf;
16157 cc = (ctx->opcode >> 13) & 0x7;
16158 fmt = (ctx->opcode >> 10) & 0x3;
16159 switch (fmt) {
16160 case 0x0:
16161 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16162 break;
16163 case 0x1:
16164 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16165 break;
16166 case 0x2:
16167 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16168 break;
16169 default:
16170 goto pool32f_invalid;
16171 }
16172 break;
16173 case C_COND_FMT:
9e8f441a 16174 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16175 cond = (ctx->opcode >> 6) & 0xf;
16176 cc = (ctx->opcode >> 13) & 0x7;
16177 fmt = (ctx->opcode >> 10) & 0x3;
16178 switch (fmt) {
16179 case 0x0:
16180 gen_cmp_s(ctx, cond, rt, rs, cc);
16181 break;
16182 case 0x1:
16183 gen_cmp_d(ctx, cond, rt, rs, cc);
16184 break;
16185 case 0x2:
16186 gen_cmp_ps(ctx, cond, rt, rs, cc);
16187 break;
16188 default:
16189 goto pool32f_invalid;
16190 }
16191 break;
2a24a7ba
YK
16192 case CMP_CONDN_S:
16193 check_insn(ctx, ISA_MIPS32R6);
16194 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16195 break;
16196 case CMP_CONDN_D:
16197 check_insn(ctx, ISA_MIPS32R6);
16198 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16199 break;
3c824109 16200 case POOL32FXF:
d75c135e 16201 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
16202 break;
16203 case 0x00:
16204 /* PLL foo */
16205 switch ((ctx->opcode >> 6) & 0x7) {
16206 case PLL_PS:
16207 mips32_op = OPC_PLL_PS;
16208 goto do_ps;
16209 case PLU_PS:
16210 mips32_op = OPC_PLU_PS;
16211 goto do_ps;
16212 case PUL_PS:
16213 mips32_op = OPC_PUL_PS;
16214 goto do_ps;
16215 case PUU_PS:
16216 mips32_op = OPC_PUU_PS;
16217 goto do_ps;
16218 case CVT_PS_S:
9e8f441a 16219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16220 mips32_op = OPC_CVT_PS_S;
16221 do_ps:
16222 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16223 break;
16224 default:
16225 goto pool32f_invalid;
16226 }
16227 break;
2a24a7ba
YK
16228 case MIN_FMT:
16229 check_insn(ctx, ISA_MIPS32R6);
16230 switch ((ctx->opcode >> 9) & 0x3) {
16231 case FMT_SDPS_S:
16232 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16233 break;
16234 case FMT_SDPS_D:
16235 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16236 break;
16237 default:
16238 goto pool32f_invalid;
16239 }
16240 break;
3c824109
NF
16241 case 0x08:
16242 /* [LS][WDU]XC1 */
16243 switch ((ctx->opcode >> 6) & 0x7) {
16244 case LWXC1:
9e8f441a 16245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16246 mips32_op = OPC_LWXC1;
16247 goto do_ldst_cp1;
16248 case SWXC1:
9e8f441a 16249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16250 mips32_op = OPC_SWXC1;
16251 goto do_ldst_cp1;
16252 case LDXC1:
9e8f441a 16253 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16254 mips32_op = OPC_LDXC1;
16255 goto do_ldst_cp1;
16256 case SDXC1:
9e8f441a 16257 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16258 mips32_op = OPC_SDXC1;
16259 goto do_ldst_cp1;
16260 case LUXC1:
9e8f441a 16261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16262 mips32_op = OPC_LUXC1;
16263 goto do_ldst_cp1;
16264 case SUXC1:
9e8f441a 16265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16266 mips32_op = OPC_SUXC1;
16267 do_ldst_cp1:
16268 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16269 break;
16270 default:
16271 goto pool32f_invalid;
16272 }
16273 break;
2a24a7ba
YK
16274 case MAX_FMT:
16275 check_insn(ctx, ISA_MIPS32R6);
16276 switch ((ctx->opcode >> 9) & 0x3) {
16277 case FMT_SDPS_S:
16278 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16279 break;
16280 case FMT_SDPS_D:
16281 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16282 break;
16283 default:
16284 goto pool32f_invalid;
16285 }
16286 break;
3c824109
NF
16287 case 0x18:
16288 /* 3D insns */
9e8f441a 16289 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16290 fmt = (ctx->opcode >> 9) & 0x3;
16291 switch ((ctx->opcode >> 6) & 0x7) {
16292 case RSQRT2_FMT:
16293 switch (fmt) {
16294 case FMT_SDPS_S:
16295 mips32_op = OPC_RSQRT2_S;
16296 goto do_3d;
16297 case FMT_SDPS_D:
16298 mips32_op = OPC_RSQRT2_D;
16299 goto do_3d;
16300 case FMT_SDPS_PS:
16301 mips32_op = OPC_RSQRT2_PS;
16302 goto do_3d;
16303 default:
16304 goto pool32f_invalid;
16305 }
16306 break;
16307 case RECIP2_FMT:
16308 switch (fmt) {
16309 case FMT_SDPS_S:
16310 mips32_op = OPC_RECIP2_S;
16311 goto do_3d;
16312 case FMT_SDPS_D:
16313 mips32_op = OPC_RECIP2_D;
16314 goto do_3d;
16315 case FMT_SDPS_PS:
16316 mips32_op = OPC_RECIP2_PS;
16317 goto do_3d;
16318 default:
16319 goto pool32f_invalid;
16320 }
16321 break;
16322 case ADDR_PS:
16323 mips32_op = OPC_ADDR_PS;
16324 goto do_3d;
16325 case MULR_PS:
16326 mips32_op = OPC_MULR_PS;
16327 do_3d:
16328 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16329 break;
16330 default:
16331 goto pool32f_invalid;
16332 }
16333 break;
16334 case 0x20:
2a24a7ba 16335 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
16336 cc = (ctx->opcode >> 13) & 0x7;
16337 fmt = (ctx->opcode >> 9) & 0x3;
16338 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
16339 case MOVF_FMT: /* RINT_FMT */
16340 if (ctx->insn_flags & ISA_MIPS32R6) {
16341 /* RINT_FMT */
16342 switch (fmt) {
16343 case FMT_SDPS_S:
16344 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16345 break;
16346 case FMT_SDPS_D:
16347 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16348 break;
16349 default:
16350 goto pool32f_invalid;
16351 }
16352 } else {
16353 /* MOVF_FMT */
16354 switch (fmt) {
16355 case FMT_SDPS_S:
16356 gen_movcf_s(ctx, rs, rt, cc, 0);
16357 break;
16358 case FMT_SDPS_D:
16359 gen_movcf_d(ctx, rs, rt, cc, 0);
16360 break;
16361 case FMT_SDPS_PS:
16362 check_ps(ctx);
16363 gen_movcf_ps(ctx, rs, rt, cc, 0);
16364 break;
16365 default:
16366 goto pool32f_invalid;
16367 }
3c824109
NF
16368 }
16369 break;
2a24a7ba
YK
16370 case MOVT_FMT: /* CLASS_FMT */
16371 if (ctx->insn_flags & ISA_MIPS32R6) {
16372 /* CLASS_FMT */
16373 switch (fmt) {
16374 case FMT_SDPS_S:
16375 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16376 break;
16377 case FMT_SDPS_D:
16378 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16379 break;
16380 default:
16381 goto pool32f_invalid;
16382 }
16383 } else {
16384 /* MOVT_FMT */
16385 switch (fmt) {
16386 case FMT_SDPS_S:
16387 gen_movcf_s(ctx, rs, rt, cc, 1);
16388 break;
16389 case FMT_SDPS_D:
16390 gen_movcf_d(ctx, rs, rt, cc, 1);
16391 break;
16392 case FMT_SDPS_PS:
16393 check_ps(ctx);
16394 gen_movcf_ps(ctx, rs, rt, cc, 1);
16395 break;
16396 default:
16397 goto pool32f_invalid;
16398 }
3c824109
NF
16399 }
16400 break;
16401 case PREFX:
9e8f441a 16402 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16403 break;
16404 default:
16405 goto pool32f_invalid;
16406 }
16407 break;
16408#define FINSN_3ARG_SDPS(prfx) \
16409 switch ((ctx->opcode >> 8) & 0x3) { \
16410 case FMT_SDPS_S: \
16411 mips32_op = OPC_##prfx##_S; \
16412 goto do_fpop; \
16413 case FMT_SDPS_D: \
16414 mips32_op = OPC_##prfx##_D; \
16415 goto do_fpop; \
16416 case FMT_SDPS_PS: \
e29c9628 16417 check_ps(ctx); \
3c824109
NF
16418 mips32_op = OPC_##prfx##_PS; \
16419 goto do_fpop; \
16420 default: \
16421 goto pool32f_invalid; \
16422 }
2a24a7ba
YK
16423 case MINA_FMT:
16424 check_insn(ctx, ISA_MIPS32R6);
16425 switch ((ctx->opcode >> 9) & 0x3) {
16426 case FMT_SDPS_S:
16427 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16428 break;
16429 case FMT_SDPS_D:
16430 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16431 break;
16432 default:
16433 goto pool32f_invalid;
16434 }
16435 break;
16436 case MAXA_FMT:
16437 check_insn(ctx, ISA_MIPS32R6);
16438 switch ((ctx->opcode >> 9) & 0x3) {
16439 case FMT_SDPS_S:
16440 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16441 break;
16442 case FMT_SDPS_D:
16443 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16444 break;
16445 default:
16446 goto pool32f_invalid;
16447 }
16448 break;
3c824109
NF
16449 case 0x30:
16450 /* regular FP ops */
16451 switch ((ctx->opcode >> 6) & 0x3) {
16452 case ADD_FMT:
16453 FINSN_3ARG_SDPS(ADD);
16454 break;
16455 case SUB_FMT:
16456 FINSN_3ARG_SDPS(SUB);
16457 break;
16458 case MUL_FMT:
16459 FINSN_3ARG_SDPS(MUL);
16460 break;
16461 case DIV_FMT:
16462 fmt = (ctx->opcode >> 8) & 0x3;
16463 if (fmt == 1) {
16464 mips32_op = OPC_DIV_D;
16465 } else if (fmt == 0) {
16466 mips32_op = OPC_DIV_S;
16467 } else {
16468 goto pool32f_invalid;
16469 }
16470 goto do_fpop;
16471 default:
16472 goto pool32f_invalid;
16473 }
16474 break;
16475 case 0x38:
16476 /* cmovs */
2a24a7ba 16477 switch ((ctx->opcode >> 6) & 0x7) {
fdac60cd 16478 case MOVN_FMT: /* SELEQZ_FMT */
2a24a7ba 16479 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16480 /* SELEQZ_FMT */
2a24a7ba
YK
16481 switch ((ctx->opcode >> 9) & 0x3) {
16482 case FMT_SDPS_S:
fdac60cd 16483 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2a24a7ba
YK
16484 break;
16485 case FMT_SDPS_D:
fdac60cd 16486 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2a24a7ba
YK
16487 break;
16488 default:
16489 goto pool32f_invalid;
16490 }
16491 } else {
16492 /* MOVN_FMT */
16493 FINSN_3ARG_SDPS(MOVN);
16494 }
16495 break;
16496 case MOVN_FMT_04:
16497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16498 FINSN_3ARG_SDPS(MOVN);
16499 break;
fdac60cd 16500 case MOVZ_FMT: /* SELNEZ_FMT */
2a24a7ba 16501 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16502 /* SELNEZ_FMT */
2a24a7ba
YK
16503 switch ((ctx->opcode >> 9) & 0x3) {
16504 case FMT_SDPS_S:
fdac60cd 16505 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2a24a7ba
YK
16506 break;
16507 case FMT_SDPS_D:
fdac60cd 16508 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2a24a7ba
YK
16509 break;
16510 default:
16511 goto pool32f_invalid;
16512 }
16513 } else {
16514 /* MOVZ_FMT */
16515 FINSN_3ARG_SDPS(MOVZ);
16516 }
16517 break;
16518 case MOVZ_FMT_05:
16519 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16520 FINSN_3ARG_SDPS(MOVZ);
16521 break;
2a24a7ba
YK
16522 case SEL_FMT:
16523 check_insn(ctx, ISA_MIPS32R6);
16524 switch ((ctx->opcode >> 9) & 0x3) {
16525 case FMT_SDPS_S:
16526 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16527 break;
16528 case FMT_SDPS_D:
16529 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16530 break;
16531 default:
16532 goto pool32f_invalid;
16533 }
16534 break;
16535 case MADDF_FMT:
16536 check_insn(ctx, ISA_MIPS32R6);
16537 switch ((ctx->opcode >> 9) & 0x3) {
16538 case FMT_SDPS_S:
16539 mips32_op = OPC_MADDF_S;
16540 goto do_fpop;
16541 case FMT_SDPS_D:
16542 mips32_op = OPC_MADDF_D;
16543 goto do_fpop;
16544 default:
16545 goto pool32f_invalid;
16546 }
16547 break;
16548 case MSUBF_FMT:
16549 check_insn(ctx, ISA_MIPS32R6);
16550 switch ((ctx->opcode >> 9) & 0x3) {
16551 case FMT_SDPS_S:
16552 mips32_op = OPC_MSUBF_S;
16553 goto do_fpop;
16554 case FMT_SDPS_D:
16555 mips32_op = OPC_MSUBF_D;
16556 goto do_fpop;
16557 default:
16558 goto pool32f_invalid;
16559 }
16560 break;
3c824109
NF
16561 default:
16562 goto pool32f_invalid;
16563 }
16564 break;
16565 do_fpop:
16566 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16567 break;
16568 default:
16569 pool32f_invalid:
16570 MIPS_INVAL("pool32f");
9c708c7f 16571 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16572 break;
16573 }
16574 } else {
16575 generate_exception_err(ctx, EXCP_CpU, 1);
16576 }
16577 break;
16578 case POOL32I:
16579 minor = (ctx->opcode >> 21) & 0x1f;
16580 switch (minor) {
16581 case BLTZ:
9e8f441a 16582 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16583 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16584 break;
3c824109 16585 case BLTZAL:
9e8f441a 16586 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16587 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16588 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16589 break;
3c824109 16590 case BLTZALS:
9e8f441a 16591 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16592 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16593 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16594 break;
3c824109 16595 case BGEZ:
9e8f441a 16596 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16597 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16598 break;
3c824109 16599 case BGEZAL:
9e8f441a 16600 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16601 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16602 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16603 break;
3c824109 16604 case BGEZALS:
9e8f441a 16605 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16606 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16607 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16608 break;
3c824109 16609 case BLEZ:
9e8f441a 16610 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16611 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16612 break;
3c824109 16613 case BGTZ:
9e8f441a 16614 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 16615 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
16616 break;
16617
16618 /* Traps */
65935f07
YK
16619 case TLTI: /* BC1EQZC */
16620 if (ctx->insn_flags & ISA_MIPS32R6) {
16621 /* BC1EQZC */
16622 check_cp1_enabled(ctx);
16623 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16624 } else {
16625 /* TLTI */
16626 mips32_op = OPC_TLTI;
16627 goto do_trapi;
16628 }
16629 break;
16630 case TGEI: /* BC1NEZC */
16631 if (ctx->insn_flags & ISA_MIPS32R6) {
16632 /* BC1NEZC */
16633 check_cp1_enabled(ctx);
16634 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16635 } else {
16636 /* TGEI */
16637 mips32_op = OPC_TGEI;
16638 goto do_trapi;
16639 }
16640 break;
3c824109 16641 case TLTIU:
9e8f441a 16642 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16643 mips32_op = OPC_TLTIU;
16644 goto do_trapi;
16645 case TGEIU:
9e8f441a 16646 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16647 mips32_op = OPC_TGEIU;
16648 goto do_trapi;
3b4a5489
YK
16649 case TNEI: /* SYNCI */
16650 if (ctx->insn_flags & ISA_MIPS32R6) {
16651 /* SYNCI */
16652 /* Break the TB to be able to sync copied instructions
16653 immediately */
eeb3bba8 16654 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
16655 } else {
16656 /* TNEI */
16657 mips32_op = OPC_TNEI;
16658 goto do_trapi;
16659 }
16660 break;
3c824109 16661 case TEQI:
9e8f441a 16662 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16663 mips32_op = OPC_TEQI;
16664 do_trapi:
16665 gen_trap(ctx, mips32_op, rs, -1, imm);
16666 break;
16667
16668 case BNEZC:
16669 case BEQZC:
9e8f441a 16670 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16671 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 16672 4, rs, 0, imm << 1, 0);
3c824109
NF
16673 /* Compact branches don't have a delay slot, so just let
16674 the normal delay slot handling take us to the branch
16675 target. */
16676 break;
16677 case LUI:
9e8f441a 16678 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 16679 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
16680 break;
16681 case SYNCI:
9e8f441a 16682 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
16683 /* Break the TB to be able to sync copied instructions
16684 immediately */
eeb3bba8 16685 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
16686 break;
16687 case BC2F:
16688 case BC2T:
9e8f441a 16689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16690 /* COP2: Not implemented. */
16691 generate_exception_err(ctx, EXCP_CpU, 2);
16692 break;
16693 case BC1F:
9e8f441a 16694 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16695 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16696 goto do_cp1branch;
16697 case BC1T:
9e8f441a 16698 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16699 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16700 goto do_cp1branch;
16701 case BC1ANY4F:
9e8f441a 16702 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16703 mips32_op = OPC_BC1FANY4;
16704 goto do_cp1mips3d;
16705 case BC1ANY4T:
9e8f441a 16706 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16707 mips32_op = OPC_BC1TANY4;
16708 do_cp1mips3d:
16709 check_cop1x(ctx);
d75c135e 16710 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
16711 /* Fall through */
16712 do_cp1branch:
272f458d
MR
16713 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16714 check_cp1_enabled(ctx);
16715 gen_compute_branch1(ctx, mips32_op,
16716 (ctx->opcode >> 18) & 0x7, imm << 1);
16717 } else {
16718 generate_exception_err(ctx, EXCP_CpU, 1);
16719 }
3c824109
NF
16720 break;
16721 case BPOSGE64:
16722 case BPOSGE32:
16723 /* MIPS DSP: not implemented */
16724 /* Fall through */
16725 default:
16726 MIPS_INVAL("pool32i");
9c708c7f 16727 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16728 break;
16729 }
16730 break;
16731 case POOL32C:
16732 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
16733 offset = sextract32(ctx->opcode, 0,
16734 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
16735 switch (minor) {
16736 case LWL:
9e8f441a 16737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16738 mips32_op = OPC_LWL;
5c13fdfd 16739 goto do_ld_lr;
3c824109 16740 case SWL:
9e8f441a 16741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16742 mips32_op = OPC_SWL;
5c13fdfd 16743 goto do_st_lr;
3c824109 16744 case LWR:
9e8f441a 16745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16746 mips32_op = OPC_LWR;
5c13fdfd 16747 goto do_ld_lr;
3c824109 16748 case SWR:
9e8f441a 16749 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16750 mips32_op = OPC_SWR;
5c13fdfd 16751 goto do_st_lr;
3c824109
NF
16752#if defined(TARGET_MIPS64)
16753 case LDL:
d9224450
MR
16754 check_insn(ctx, ISA_MIPS3);
16755 check_mips_64(ctx);
9e8f441a 16756 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16757 mips32_op = OPC_LDL;
5c13fdfd 16758 goto do_ld_lr;
3c824109 16759 case SDL:
d9224450
MR
16760 check_insn(ctx, ISA_MIPS3);
16761 check_mips_64(ctx);
9e8f441a 16762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16763 mips32_op = OPC_SDL;
5c13fdfd 16764 goto do_st_lr;
3c824109 16765 case LDR:
d9224450
MR
16766 check_insn(ctx, ISA_MIPS3);
16767 check_mips_64(ctx);
9e8f441a 16768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16769 mips32_op = OPC_LDR;
5c13fdfd 16770 goto do_ld_lr;
3c824109 16771 case SDR:
d9224450
MR
16772 check_insn(ctx, ISA_MIPS3);
16773 check_mips_64(ctx);
9e8f441a 16774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16775 mips32_op = OPC_SDR;
5c13fdfd 16776 goto do_st_lr;
3c824109 16777 case LWU:
d9224450
MR
16778 check_insn(ctx, ISA_MIPS3);
16779 check_mips_64(ctx);
3c824109 16780 mips32_op = OPC_LWU;
5c13fdfd 16781 goto do_ld_lr;
3c824109 16782 case LLD:
d9224450
MR
16783 check_insn(ctx, ISA_MIPS3);
16784 check_mips_64(ctx);
3c824109 16785 mips32_op = OPC_LLD;
5c13fdfd 16786 goto do_ld_lr;
3c824109
NF
16787#endif
16788 case LL:
16789 mips32_op = OPC_LL;
5c13fdfd
AJ
16790 goto do_ld_lr;
16791 do_ld_lr:
3b4a5489 16792 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
16793 break;
16794 do_st_lr:
8fffc646 16795 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
16796 break;
16797 case SC:
3b4a5489 16798 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
16799 break;
16800#if defined(TARGET_MIPS64)
16801 case SCD:
d9224450
MR
16802 check_insn(ctx, ISA_MIPS3);
16803 check_mips_64(ctx);
3b4a5489 16804 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
16805 break;
16806#endif
8fffc646
JH
16807 case LD_EVA:
16808 if (!ctx->eva) {
16809 MIPS_INVAL("pool32c ld-eva");
16810 generate_exception_end(ctx, EXCP_RI);
16811 break;
16812 }
16813 check_cp0_enabled(ctx);
16814
16815 minor2 = (ctx->opcode >> 9) & 0x7;
16816 offset = sextract32(ctx->opcode, 0, 9);
16817 switch (minor2) {
16818 case LBUE:
16819 mips32_op = OPC_LBUE;
16820 goto do_ld_lr;
16821 case LHUE:
16822 mips32_op = OPC_LHUE;
16823 goto do_ld_lr;
16824 case LWLE:
16825 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16826 mips32_op = OPC_LWLE;
16827 goto do_ld_lr;
16828 case LWRE:
16829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16830 mips32_op = OPC_LWRE;
16831 goto do_ld_lr;
16832 case LBE:
16833 mips32_op = OPC_LBE;
16834 goto do_ld_lr;
16835 case LHE:
16836 mips32_op = OPC_LHE;
16837 goto do_ld_lr;
16838 case LLE:
16839 mips32_op = OPC_LLE;
16840 goto do_ld_lr;
16841 case LWE:
16842 mips32_op = OPC_LWE;
16843 goto do_ld_lr;
16844 };
16845 break;
16846 case ST_EVA:
16847 if (!ctx->eva) {
16848 MIPS_INVAL("pool32c st-eva");
16849 generate_exception_end(ctx, EXCP_RI);
16850 break;
16851 }
16852 check_cp0_enabled(ctx);
16853
16854 minor2 = (ctx->opcode >> 9) & 0x7;
16855 offset = sextract32(ctx->opcode, 0, 9);
16856 switch (minor2) {
16857 case SWLE:
16858 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16859 mips32_op = OPC_SWLE;
16860 goto do_st_lr;
16861 case SWRE:
16862 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16863 mips32_op = OPC_SWRE;
16864 goto do_st_lr;
16865 case PREFE:
16866 /* Treat as no-op */
16867 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16868 /* hint codes 24-31 are reserved and signal RI */
16869 generate_exception(ctx, EXCP_RI);
16870 }
16871 break;
16872 case CACHEE:
16873 /* Treat as no-op */
16874 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16875 gen_cache_operation(ctx, rt, rs, offset);
16876 }
16877 break;
16878 case SBE:
16879 mips32_op = OPC_SBE;
16880 goto do_st_lr;
16881 case SHE:
16882 mips32_op = OPC_SHE;
16883 goto do_st_lr;
16884 case SCE:
16885 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16886 break;
16887 case SWE:
16888 mips32_op = OPC_SWE;
16889 goto do_st_lr;
16890 };
16891 break;
3c824109
NF
16892 case PREF:
16893 /* Treat as no-op */
3b4a5489
YK
16894 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16895 /* hint codes 24-31 are reserved and signal RI */
16896 generate_exception(ctx, EXCP_RI);
16897 }
3c824109
NF
16898 break;
16899 default:
16900 MIPS_INVAL("pool32c");
9c708c7f 16901 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16902 break;
16903 }
16904 break;
ab39ee45
YK
16905 case ADDI32: /* AUI, LUI */
16906 if (ctx->insn_flags & ISA_MIPS32R6) {
16907 /* AUI, LUI */
16908 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16909 } else {
16910 /* ADDI32 */
16911 mips32_op = OPC_ADDI;
16912 goto do_addi;
16913 }
16914 break;
3c824109
NF
16915 case ADDIU32:
16916 mips32_op = OPC_ADDIU;
16917 do_addi:
d75c135e 16918 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16919 break;
16920
16921 /* Logical operations */
16922 case ORI32:
16923 mips32_op = OPC_ORI;
16924 goto do_logici;
16925 case XORI32:
16926 mips32_op = OPC_XORI;
16927 goto do_logici;
16928 case ANDI32:
16929 mips32_op = OPC_ANDI;
16930 do_logici:
d75c135e 16931 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16932 break;
16933
16934 /* Set less than immediate */
16935 case SLTI32:
16936 mips32_op = OPC_SLTI;
16937 goto do_slti;
16938 case SLTIU32:
16939 mips32_op = OPC_SLTIU;
16940 do_slti:
d75c135e 16941 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16942 break;
16943 case JALX32:
9e8f441a 16944 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16945 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
16946 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16947 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 16948 break;
65935f07
YK
16949 case JALS32: /* BOVC, BEQC, BEQZALC */
16950 if (ctx->insn_flags & ISA_MIPS32R6) {
16951 if (rs >= rt) {
16952 /* BOVC */
16953 mips32_op = OPC_BOVC;
16954 } else if (rs < rt && rs == 0) {
16955 /* BEQZALC */
16956 mips32_op = OPC_BEQZALC;
16957 } else {
16958 /* BEQC */
16959 mips32_op = OPC_BEQC;
16960 }
16961 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16962 } else {
16963 /* JALS32 */
16964 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16965 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16966 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16967 }
3c824109 16968 break;
65935f07
YK
16969 case BEQ32: /* BC */
16970 if (ctx->insn_flags & ISA_MIPS32R6) {
16971 /* BC */
16972 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16973 sextract32(ctx->opcode << 1, 0, 27));
16974 } else {
16975 /* BEQ32 */
16976 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16977 }
3c824109 16978 break;
65935f07
YK
16979 case BNE32: /* BALC */
16980 if (ctx->insn_flags & ISA_MIPS32R6) {
16981 /* BALC */
16982 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16983 sextract32(ctx->opcode << 1, 0, 27));
16984 } else {
16985 /* BNE32 */
16986 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16987 }
3c824109 16988 break;
65935f07
YK
16989 case J32: /* BGTZC, BLTZC, BLTC */
16990 if (ctx->insn_flags & ISA_MIPS32R6) {
16991 if (rs == 0 && rt != 0) {
16992 /* BGTZC */
16993 mips32_op = OPC_BGTZC;
16994 } else if (rs != 0 && rt != 0 && rs == rt) {
16995 /* BLTZC */
16996 mips32_op = OPC_BLTZC;
16997 } else {
16998 /* BLTC */
16999 mips32_op = OPC_BLTC;
17000 }
17001 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17002 } else {
17003 /* J32 */
17004 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17005 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17006 }
3c824109 17007 break;
65935f07
YK
17008 case JAL32: /* BLEZC, BGEZC, BGEC */
17009 if (ctx->insn_flags & ISA_MIPS32R6) {
17010 if (rs == 0 && rt != 0) {
17011 /* BLEZC */
17012 mips32_op = OPC_BLEZC;
17013 } else if (rs != 0 && rt != 0 && rs == rt) {
17014 /* BGEZC */
17015 mips32_op = OPC_BGEZC;
17016 } else {
17017 /* BGEC */
17018 mips32_op = OPC_BGEC;
17019 }
17020 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17021 } else {
17022 /* JAL32 */
17023 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17024 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17025 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17026 }
3c824109
NF
17027 break;
17028 /* Floating point (COP1) */
17029 case LWC132:
17030 mips32_op = OPC_LWC1;
17031 goto do_cop1;
17032 case LDC132:
17033 mips32_op = OPC_LDC1;
17034 goto do_cop1;
17035 case SWC132:
17036 mips32_op = OPC_SWC1;
17037 goto do_cop1;
17038 case SDC132:
17039 mips32_op = OPC_SDC1;
17040 do_cop1:
5ab5c041 17041 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 17042 break;
ab39ee45
YK
17043 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17044 if (ctx->insn_flags & ISA_MIPS32R6) {
17045 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17046 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
17047 case ADDIUPC_00:
17048 case ADDIUPC_01:
17049 case ADDIUPC_02:
17050 case ADDIUPC_03:
17051 case ADDIUPC_04:
17052 case ADDIUPC_05:
17053 case ADDIUPC_06:
17054 case ADDIUPC_07:
eeb3bba8 17055 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
17056 break;
17057 case AUIPC:
eeb3bba8 17058 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
17059 break;
17060 case ALUIPC:
eeb3bba8 17061 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 17062 break;
c38a1d52
AR
17063 case LWPC_08:
17064 case LWPC_09:
17065 case LWPC_0A:
17066 case LWPC_0B:
17067 case LWPC_0C:
17068 case LWPC_0D:
17069 case LWPC_0E:
17070 case LWPC_0F:
eeb3bba8 17071 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
17072 break;
17073 default:
17074 generate_exception(ctx, EXCP_RI);
17075 break;
17076 }
17077 } else {
17078 /* ADDIUPC */
3c824109 17079 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 17080 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
17081
17082 gen_addiupc(ctx, reg, offset, 0, 0);
17083 }
17084 break;
65935f07
YK
17085 case BNVC: /* BNEC, BNEZALC */
17086 check_insn(ctx, ISA_MIPS32R6);
17087 if (rs >= rt) {
17088 /* BNVC */
17089 mips32_op = OPC_BNVC;
17090 } else if (rs < rt && rs == 0) {
17091 /* BNEZALC */
17092 mips32_op = OPC_BNEZALC;
17093 } else {
17094 /* BNEC */
17095 mips32_op = OPC_BNEC;
17096 }
17097 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17098 break;
17099 case R6_BNEZC: /* JIALC */
17100 check_insn(ctx, ISA_MIPS32R6);
17101 if (rt != 0) {
17102 /* BNEZC */
17103 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17104 sextract32(ctx->opcode << 1, 0, 22));
17105 } else {
17106 /* JIALC */
17107 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17108 }
17109 break;
17110 case R6_BEQZC: /* JIC */
17111 check_insn(ctx, ISA_MIPS32R6);
17112 if (rt != 0) {
17113 /* BEQZC */
17114 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17115 sextract32(ctx->opcode << 1, 0, 22));
17116 } else {
17117 /* JIC */
17118 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17119 }
17120 break;
17121 case BLEZALC: /* BGEZALC, BGEUC */
17122 check_insn(ctx, ISA_MIPS32R6);
17123 if (rs == 0 && rt != 0) {
17124 /* BLEZALC */
17125 mips32_op = OPC_BLEZALC;
17126 } else if (rs != 0 && rt != 0 && rs == rt) {
17127 /* BGEZALC */
17128 mips32_op = OPC_BGEZALC;
17129 } else {
17130 /* BGEUC */
17131 mips32_op = OPC_BGEUC;
17132 }
17133 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17134 break;
17135 case BGTZALC: /* BLTZALC, BLTUC */
17136 check_insn(ctx, ISA_MIPS32R6);
17137 if (rs == 0 && rt != 0) {
17138 /* BGTZALC */
17139 mips32_op = OPC_BGTZALC;
17140 } else if (rs != 0 && rt != 0 && rs == rt) {
17141 /* BLTZALC */
17142 mips32_op = OPC_BLTZALC;
17143 } else {
17144 /* BLTUC */
17145 mips32_op = OPC_BLTUC;
17146 }
17147 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17148 break;
3c824109
NF
17149 /* Loads and stores */
17150 case LB32:
17151 mips32_op = OPC_LB;
5c13fdfd 17152 goto do_ld;
3c824109
NF
17153 case LBU32:
17154 mips32_op = OPC_LBU;
5c13fdfd 17155 goto do_ld;
3c824109
NF
17156 case LH32:
17157 mips32_op = OPC_LH;
5c13fdfd 17158 goto do_ld;
3c824109
NF
17159 case LHU32:
17160 mips32_op = OPC_LHU;
5c13fdfd 17161 goto do_ld;
3c824109
NF
17162 case LW32:
17163 mips32_op = OPC_LW;
5c13fdfd 17164 goto do_ld;
3c824109
NF
17165#ifdef TARGET_MIPS64
17166 case LD32:
d9224450
MR
17167 check_insn(ctx, ISA_MIPS3);
17168 check_mips_64(ctx);
3c824109 17169 mips32_op = OPC_LD;
5c13fdfd 17170 goto do_ld;
3c824109 17171 case SD32:
d9224450
MR
17172 check_insn(ctx, ISA_MIPS3);
17173 check_mips_64(ctx);
3c824109 17174 mips32_op = OPC_SD;
5c13fdfd 17175 goto do_st;
3c824109
NF
17176#endif
17177 case SB32:
17178 mips32_op = OPC_SB;
5c13fdfd 17179 goto do_st;
3c824109
NF
17180 case SH32:
17181 mips32_op = OPC_SH;
5c13fdfd 17182 goto do_st;
3c824109
NF
17183 case SW32:
17184 mips32_op = OPC_SW;
5c13fdfd
AJ
17185 goto do_st;
17186 do_ld:
d75c135e 17187 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
17188 break;
17189 do_st:
17190 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17191 break;
17192 default:
9c708c7f 17193 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17194 break;
17195 }
17196}
17197
240ce26a 17198static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
17199{
17200 uint32_t op;
17201
17202 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
17203 if (ctx->base.pc_next & 0x1) {
17204 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 17205 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
17206 return 2;
17207 }
17208
17209 op = (ctx->opcode >> 10) & 0x3f;
17210 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
17211 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17212 switch (op & 0x7) { /* MSB-3..MSB-5 */
17213 case 0:
17214 /* POOL32A, POOL32B, POOL32I, POOL32C */
17215 case 4:
17216 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17217 case 5:
17218 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17219 case 6:
17220 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17221 case 7:
17222 /* LB32, LH32, LWC132, LDC132, LW32 */
17223 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 17224 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17225 return 2;
17226 }
17227 break;
b231c103
YK
17228 case 1:
17229 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17230 case 2:
17231 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17232 case 3:
17233 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17234 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 17235 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17236 return 2;
17237 }
17238 break;
3c824109
NF
17239 }
17240 }
b231c103 17241
3c824109
NF
17242 switch (op) {
17243 case POOL16A:
17244 {
17245 int rd = mmreg(uMIPS_RD(ctx->opcode));
17246 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17247 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17248 uint32_t opc = 0;
17249
17250 switch (ctx->opcode & 0x1) {
17251 case ADDU16:
17252 opc = OPC_ADDU;
17253 break;
17254 case SUBU16:
17255 opc = OPC_SUBU;
17256 break;
17257 }
ed7ce6c0
YK
17258 if (ctx->insn_flags & ISA_MIPS32R6) {
17259 /* In the Release 6 the register number location in
17260 * the instruction encoding has changed.
17261 */
17262 gen_arith(ctx, opc, rs1, rd, rs2);
17263 } else {
17264 gen_arith(ctx, opc, rd, rs1, rs2);
17265 }
3c824109
NF
17266 }
17267 break;
17268 case POOL16B:
17269 {
17270 int rd = mmreg(uMIPS_RD(ctx->opcode));
17271 int rs = mmreg(uMIPS_RS(ctx->opcode));
17272 int amount = (ctx->opcode >> 1) & 0x7;
17273 uint32_t opc = 0;
17274 amount = amount == 0 ? 8 : amount;
17275
17276 switch (ctx->opcode & 0x1) {
17277 case SLL16:
17278 opc = OPC_SLL;
17279 break;
17280 case SRL16:
17281 opc = OPC_SRL;
17282 break;
17283 }
17284
d75c135e 17285 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
17286 }
17287 break;
17288 case POOL16C:
ed7ce6c0
YK
17289 if (ctx->insn_flags & ISA_MIPS32R6) {
17290 gen_pool16c_r6_insn(ctx);
17291 } else {
17292 gen_pool16c_insn(ctx);
17293 }
3c824109
NF
17294 break;
17295 case LWGP16:
17296 {
17297 int rd = mmreg(uMIPS_RD(ctx->opcode));
17298 int rb = 28; /* GP */
17299 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17300
d75c135e 17301 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17302 }
17303 break;
17304 case POOL16F:
9e8f441a 17305 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 17306 if (ctx->opcode & 1) {
9c708c7f 17307 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17308 } else {
17309 /* MOVEP */
17310 int enc_dest = uMIPS_RD(ctx->opcode);
17311 int enc_rt = uMIPS_RS2(ctx->opcode);
17312 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 17313 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
17314 }
17315 break;
17316 case LBU16:
17317 {
17318 int rd = mmreg(uMIPS_RD(ctx->opcode));
17319 int rb = mmreg(uMIPS_RS(ctx->opcode));
17320 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17321 offset = (offset == 0xf ? -1 : offset);
17322
d75c135e 17323 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
17324 }
17325 break;
17326 case LHU16:
17327 {
17328 int rd = mmreg(uMIPS_RD(ctx->opcode));
17329 int rb = mmreg(uMIPS_RS(ctx->opcode));
17330 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17331
d75c135e 17332 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
17333 }
17334 break;
17335 case LWSP16:
17336 {
17337 int rd = (ctx->opcode >> 5) & 0x1f;
17338 int rb = 29; /* SP */
17339 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17340
d75c135e 17341 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17342 }
17343 break;
17344 case LW16:
17345 {
17346 int rd = mmreg(uMIPS_RD(ctx->opcode));
17347 int rb = mmreg(uMIPS_RS(ctx->opcode));
17348 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17349
d75c135e 17350 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17351 }
17352 break;
17353 case SB16:
17354 {
17355 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17356 int rb = mmreg(uMIPS_RS(ctx->opcode));
17357 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17358
5c13fdfd 17359 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
17360 }
17361 break;
17362 case SH16:
17363 {
17364 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17365 int rb = mmreg(uMIPS_RS(ctx->opcode));
17366 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17367
5c13fdfd 17368 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
17369 }
17370 break;
17371 case SWSP16:
17372 {
17373 int rd = (ctx->opcode >> 5) & 0x1f;
17374 int rb = 29; /* SP */
17375 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17376
5c13fdfd 17377 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17378 }
17379 break;
17380 case SW16:
17381 {
17382 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17383 int rb = mmreg(uMIPS_RS(ctx->opcode));
17384 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17385
5c13fdfd 17386 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17387 }
17388 break;
17389 case MOVE16:
17390 {
17391 int rd = uMIPS_RD5(ctx->opcode);
17392 int rs = uMIPS_RS5(ctx->opcode);
17393
7215d7e7 17394 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
17395 }
17396 break;
17397 case ANDI16:
d75c135e 17398 gen_andi16(ctx);
3c824109
NF
17399 break;
17400 case POOL16D:
17401 switch (ctx->opcode & 0x1) {
17402 case ADDIUS5:
d75c135e 17403 gen_addius5(ctx);
3c824109
NF
17404 break;
17405 case ADDIUSP:
d75c135e 17406 gen_addiusp(ctx);
3c824109
NF
17407 break;
17408 }
17409 break;
17410 case POOL16E:
17411 switch (ctx->opcode & 0x1) {
17412 case ADDIUR2:
d75c135e 17413 gen_addiur2(ctx);
3c824109
NF
17414 break;
17415 case ADDIUR1SP:
d75c135e 17416 gen_addiur1sp(ctx);
3c824109
NF
17417 break;
17418 }
17419 break;
65935f07 17420 case B16: /* BC16 */
3c824109 17421 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
17422 sextract32(ctx->opcode, 0, 10) << 1,
17423 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 17424 break;
65935f07
YK
17425 case BNEZ16: /* BNEZC16 */
17426 case BEQZ16: /* BEQZC16 */
3c824109
NF
17427 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17428 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
17429 0, sextract32(ctx->opcode, 0, 7) << 1,
17430 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17431
3c824109
NF
17432 break;
17433 case LI16:
17434 {
17435 int reg = mmreg(uMIPS_RD(ctx->opcode));
17436 int imm = ZIMM(ctx->opcode, 0, 7);
17437
17438 imm = (imm == 0x7f ? -1 : imm);
17439 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17440 }
17441 break;
3c824109 17442 case RES_29:
3c824109 17443 case RES_31:
3c824109 17444 case RES_39:
9c708c7f 17445 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17446 break;
17447 default:
f60eeb0c 17448 decode_micromips32_opc(env, ctx);
3c824109
NF
17449 return 4;
17450 }
17451
17452 return 2;
17453}
17454
261c95a0
YK
17455/*
17456 *
17457 * nanoMIPS opcodes
17458 *
17459 */
17460
17461/* MAJOR, P16, and P32 pools opcodes */
17462enum {
17463 NM_P_ADDIU = 0x00,
17464 NM_ADDIUPC = 0x01,
17465 NM_MOVE_BALC = 0x02,
17466 NM_P16_MV = 0x04,
17467 NM_LW16 = 0x05,
17468 NM_BC16 = 0x06,
17469 NM_P16_SR = 0x07,
17470
17471 NM_POOL32A = 0x08,
17472 NM_P_BAL = 0x0a,
17473 NM_P16_SHIFT = 0x0c,
17474 NM_LWSP16 = 0x0d,
17475 NM_BALC16 = 0x0e,
17476 NM_P16_4X4 = 0x0f,
17477
17478 NM_P_GP_W = 0x10,
17479 NM_P_GP_BH = 0x11,
17480 NM_P_J = 0x12,
17481 NM_P16C = 0x14,
17482 NM_LWGP16 = 0x15,
17483 NM_P16_LB = 0x17,
17484
17485 NM_P48I = 0x18,
17486 NM_P16_A1 = 0x1c,
17487 NM_LW4X4 = 0x1d,
17488 NM_P16_LH = 0x1f,
17489
17490 NM_P_U12 = 0x20,
17491 NM_P_LS_U12 = 0x21,
17492 NM_P_BR1 = 0x22,
17493 NM_P16_A2 = 0x24,
17494 NM_SW16 = 0x25,
17495 NM_BEQZC16 = 0x26,
17496
17497 NM_POOL32F = 0x28,
17498 NM_P_LS_S9 = 0x29,
17499 NM_P_BR2 = 0x2a,
17500
17501 NM_P16_ADDU = 0x2c,
17502 NM_SWSP16 = 0x2d,
17503 NM_BNEZC16 = 0x2e,
17504 NM_MOVEP = 0x2f,
17505
17506 NM_POOL32S = 0x30,
17507 NM_P_BRI = 0x32,
17508 NM_LI16 = 0x34,
17509 NM_SWGP16 = 0x35,
17510 NM_P16_BR = 0x36,
17511
17512 NM_P_LUI = 0x38,
17513 NM_ANDI16 = 0x3c,
17514 NM_SW4X4 = 0x3d,
17515 NM_MOVEPREV = 0x3f,
17516};
17517
17518/* POOL32A instruction pool */
17519enum {
17520 NM_POOL32A0 = 0x00,
17521 NM_SPECIAL2 = 0x01,
17522 NM_COP2_1 = 0x02,
17523 NM_UDI = 0x03,
17524 NM_POOL32A5 = 0x05,
17525 NM_POOL32A7 = 0x07,
17526};
17527
17528/* P.GP.W instruction pool */
17529enum {
17530 NM_ADDIUGP_W = 0x00,
17531 NM_LWGP = 0x02,
17532 NM_SWGP = 0x03,
17533};
17534
17535/* P48I instruction pool */
17536enum {
17537 NM_LI48 = 0x00,
17538 NM_ADDIU48 = 0x01,
17539 NM_ADDIUGP48 = 0x02,
17540 NM_ADDIUPC48 = 0x03,
17541 NM_LWPC48 = 0x0b,
17542 NM_SWPC48 = 0x0f,
17543};
17544
17545/* P.U12 instruction pool */
17546enum {
17547 NM_ORI = 0x00,
17548 NM_XORI = 0x01,
17549 NM_ANDI = 0x02,
17550 NM_P_SR = 0x03,
17551 NM_SLTI = 0x04,
17552 NM_SLTIU = 0x05,
17553 NM_SEQI = 0x06,
17554 NM_ADDIUNEG = 0x08,
17555 NM_P_SHIFT = 0x0c,
17556 NM_P_ROTX = 0x0d,
17557 NM_P_INS = 0x0e,
17558 NM_P_EXT = 0x0f,
17559};
17560
17561/* POOL32F instruction pool */
17562enum {
17563 NM_POOL32F_0 = 0x00,
17564 NM_POOL32F_3 = 0x03,
17565 NM_POOL32F_5 = 0x05,
17566};
17567
17568/* POOL32S instruction pool */
17569enum {
17570 NM_POOL32S_0 = 0x00,
17571 NM_POOL32S_4 = 0x04,
17572};
17573
17574/* P.LUI instruction pool */
17575enum {
17576 NM_LUI = 0x00,
17577 NM_ALUIPC = 0x01,
17578};
17579
17580/* P.GP.BH instruction pool */
17581enum {
17582 NM_LBGP = 0x00,
17583 NM_SBGP = 0x01,
17584 NM_LBUGP = 0x02,
17585 NM_ADDIUGP_B = 0x03,
17586 NM_P_GP_LH = 0x04,
17587 NM_P_GP_SH = 0x05,
17588 NM_P_GP_CP1 = 0x06,
17589};
17590
17591/* P.LS.U12 instruction pool */
17592enum {
17593 NM_LB = 0x00,
17594 NM_SB = 0x01,
17595 NM_LBU = 0x02,
17596 NM_P_PREFU12 = 0x03,
17597 NM_LH = 0x04,
17598 NM_SH = 0x05,
17599 NM_LHU = 0x06,
17600 NM_LWU = 0x07,
17601 NM_LW = 0x08,
17602 NM_SW = 0x09,
17603 NM_LWC1 = 0x0a,
17604 NM_SWC1 = 0x0b,
17605 NM_LDC1 = 0x0e,
17606 NM_SDC1 = 0x0f,
17607};
17608
17609/* P.LS.S9 instruction pool */
17610enum {
17611 NM_P_LS_S0 = 0x00,
17612 NM_P_LS_S1 = 0x01,
17613 NM_P_LS_E0 = 0x02,
17614 NM_P_LS_WM = 0x04,
17615 NM_P_LS_UAWM = 0x05,
17616};
17617
17618/* P.BAL instruction pool */
17619enum {
17620 NM_BC = 0x00,
17621 NM_BALC = 0x01,
17622};
17623
17624/* P.J instruction pool */
17625enum {
17626 NM_JALRC = 0x00,
17627 NM_JALRC_HB = 0x01,
17628 NM_P_BALRSC = 0x08,
17629};
17630
17631/* P.BR1 instruction pool */
17632enum {
17633 NM_BEQC = 0x00,
17634 NM_P_BR3A = 0x01,
17635 NM_BGEC = 0x02,
17636 NM_BGEUC = 0x03,
17637};
17638
17639/* P.BR2 instruction pool */
17640enum {
17641 NM_BNEC = 0x00,
17642 NM_BLTC = 0x02,
17643 NM_BLTUC = 0x03,
17644};
17645
17646/* P.BRI instruction pool */
17647enum {
17648 NM_BEQIC = 0x00,
17649 NM_BBEQZC = 0x01,
17650 NM_BGEIC = 0x02,
17651 NM_BGEIUC = 0x03,
17652 NM_BNEIC = 0x04,
17653 NM_BBNEZC = 0x05,
17654 NM_BLTIC = 0x06,
17655 NM_BLTIUC = 0x07,
17656};
17657
17658/* P16.SHIFT instruction pool */
17659enum {
17660 NM_SLL16 = 0x00,
17661 NM_SRL16 = 0x01,
17662};
17663
17664/* POOL16C instruction pool */
17665enum {
17666 NM_POOL16C_0 = 0x00,
17667 NM_LWXS16 = 0x01,
17668};
17669
17670/* P16.A1 instruction pool */
17671enum {
17672 NM_ADDIUR1SP = 0x01,
17673};
17674
17675/* P16.A2 instruction pool */
17676enum {
17677 NM_ADDIUR2 = 0x00,
17678 NM_P_ADDIURS5 = 0x01,
17679};
17680
17681/* P16.ADDU instruction pool */
17682enum {
17683 NM_ADDU16 = 0x00,
17684 NM_SUBU16 = 0x01,
17685};
17686
17687/* P16.SR instruction pool */
17688enum {
17689 NM_SAVE16 = 0x00,
17690 NM_RESTORE_JRC16 = 0x01,
17691};
17692
17693/* P16.4X4 instruction pool */
17694enum {
17695 NM_ADDU4X4 = 0x00,
17696 NM_MUL4X4 = 0x01,
17697};
17698
17699/* P16.LB instruction pool */
17700enum {
17701 NM_LB16 = 0x00,
17702 NM_SB16 = 0x01,
17703 NM_LBU16 = 0x02,
17704};
17705
17706/* P16.LH instruction pool */
17707enum {
17708 NM_LH16 = 0x00,
17709 NM_SH16 = 0x01,
17710 NM_LHU16 = 0x02,
17711};
17712
17713/* P.RI instruction pool */
17714enum {
17715 NM_SIGRIE = 0x00,
17716 NM_P_SYSCALL = 0x01,
17717 NM_BREAK = 0x02,
17718 NM_SDBBP = 0x03,
17719};
17720
17721/* POOL32A0 instruction pool */
17722enum {
17723 NM_P_TRAP = 0x00,
17724 NM_SEB = 0x01,
17725 NM_SLLV = 0x02,
17726 NM_MUL = 0x03,
17727 NM_MFC0 = 0x06,
17728 NM_MFHC0 = 0x07,
17729 NM_SEH = 0x09,
17730 NM_SRLV = 0x0a,
17731 NM_MUH = 0x0b,
17732 NM_MTC0 = 0x0e,
17733 NM_MTHC0 = 0x0f,
17734 NM_SRAV = 0x12,
17735 NM_MULU = 0x13,
17736 NM_ROTRV = 0x1a,
17737 NM_MUHU = 0x1b,
17738 NM_ADD = 0x22,
17739 NM_DIV = 0x23,
17740 NM_ADDU = 0x2a,
17741 NM_MOD = 0x2b,
17742 NM_SUB = 0x32,
17743 NM_DIVU = 0x33,
17744 NM_RDHWR = 0x38,
17745 NM_SUBU = 0x3a,
17746 NM_MODU = 0x3b,
17747 NM_P_CMOVE = 0x42,
17748 NM_FORK = 0x45,
17749 NM_MFTR = 0x46,
17750 NM_MFHTR = 0x47,
17751 NM_AND = 0x4a,
17752 NM_YIELD = 0x4d,
17753 NM_MTTR = 0x4e,
17754 NM_MTHTR = 0x4f,
17755 NM_OR = 0x52,
17756 NM_D_E_MT_VPE = 0x56,
17757 NM_NOR = 0x5a,
17758 NM_XOR = 0x62,
17759 NM_SLT = 0x6a,
17760 NM_P_SLTU = 0x72,
17761 NM_SOV = 0x7a,
17762};
17763
ba1e8117
AM
17764/* CRC32 instruction pool */
17765enum {
17766 NM_CRC32B = 0x00,
17767 NM_CRC32H = 0x01,
17768 NM_CRC32W = 0x02,
17769 NM_CRC32CB = 0x04,
17770 NM_CRC32CH = 0x05,
17771 NM_CRC32CW = 0x06,
17772};
17773
b3979b6f
SM
17774/* POOL32A5 instruction pool */
17775enum {
17776 NM_CMP_EQ_PH = 0x00,
17777 NM_CMP_LT_PH = 0x08,
17778 NM_CMP_LE_PH = 0x10,
17779 NM_CMPGU_EQ_QB = 0x18,
17780 NM_CMPGU_LT_QB = 0x20,
17781 NM_CMPGU_LE_QB = 0x28,
17782 NM_CMPGDU_EQ_QB = 0x30,
17783 NM_CMPGDU_LT_QB = 0x38,
17784 NM_CMPGDU_LE_QB = 0x40,
17785 NM_CMPU_EQ_QB = 0x48,
17786 NM_CMPU_LT_QB = 0x50,
17787 NM_CMPU_LE_QB = 0x58,
17788 NM_ADDQ_S_W = 0x60,
17789 NM_SUBQ_S_W = 0x68,
17790 NM_ADDSC = 0x70,
17791 NM_ADDWC = 0x78,
17792
17793 NM_ADDQ_S_PH = 0x01,
17794 NM_ADDQH_R_PH = 0x09,
17795 NM_ADDQH_R_W = 0x11,
17796 NM_ADDU_S_QB = 0x19,
17797 NM_ADDU_S_PH = 0x21,
17798 NM_ADDUH_R_QB = 0x29,
17799 NM_SHRAV_R_PH = 0x31,
17800 NM_SHRAV_R_QB = 0x39,
17801 NM_SUBQ_S_PH = 0x41,
17802 NM_SUBQH_R_PH = 0x49,
17803 NM_SUBQH_R_W = 0x51,
17804 NM_SUBU_S_QB = 0x59,
17805 NM_SUBU_S_PH = 0x61,
17806 NM_SUBUH_R_QB = 0x69,
17807 NM_SHLLV_S_PH = 0x71,
17808 NM_PRECR_SRA_R_PH_W = 0x79,
17809
17810 NM_MULEU_S_PH_QBL = 0x12,
17811 NM_MULEU_S_PH_QBR = 0x1a,
17812 NM_MULQ_RS_PH = 0x22,
17813 NM_MULQ_S_PH = 0x2a,
17814 NM_MULQ_RS_W = 0x32,
17815 NM_MULQ_S_W = 0x3a,
17816 NM_APPEND = 0x42,
17817 NM_MODSUB = 0x52,
17818 NM_SHRAV_R_W = 0x5a,
17819 NM_SHRLV_PH = 0x62,
17820 NM_SHRLV_QB = 0x6a,
17821 NM_SHLLV_QB = 0x72,
17822 NM_SHLLV_S_W = 0x7a,
17823
17824 NM_SHILO = 0x03,
17825
17826 NM_MULEQ_S_W_PHL = 0x04,
17827 NM_MULEQ_S_W_PHR = 0x0c,
17828
17829 NM_MUL_S_PH = 0x05,
17830 NM_PRECR_QB_PH = 0x0d,
17831 NM_PRECRQ_QB_PH = 0x15,
17832 NM_PRECRQ_PH_W = 0x1d,
17833 NM_PRECRQ_RS_PH_W = 0x25,
17834 NM_PRECRQU_S_QB_PH = 0x2d,
17835 NM_PACKRL_PH = 0x35,
17836 NM_PICK_QB = 0x3d,
17837 NM_PICK_PH = 0x45,
17838
17839 NM_SHRA_R_W = 0x5e,
17840 NM_SHRA_R_PH = 0x66,
17841 NM_SHLL_S_PH = 0x76,
17842 NM_SHLL_S_W = 0x7e,
17843
17844 NM_REPL_PH = 0x07
17845};
17846
261c95a0
YK
17847/* POOL32A7 instruction pool */
17848enum {
17849 NM_P_LSX = 0x00,
17850 NM_LSA = 0x01,
17851 NM_EXTW = 0x03,
17852 NM_POOL32AXF = 0x07,
17853};
17854
17855/* P.SR instruction pool */
17856enum {
17857 NM_PP_SR = 0x00,
17858 NM_P_SR_F = 0x01,
17859};
17860
17861/* P.SHIFT instruction pool */
17862enum {
17863 NM_P_SLL = 0x00,
17864 NM_SRL = 0x02,
17865 NM_SRA = 0x04,
17866 NM_ROTR = 0x06,
17867};
17868
17869/* P.ROTX instruction pool */
17870enum {
17871 NM_ROTX = 0x00,
17872};
17873
17874/* P.INS instruction pool */
17875enum {
17876 NM_INS = 0x00,
17877};
17878
17879/* P.EXT instruction pool */
17880enum {
17881 NM_EXT = 0x00,
17882};
17883
17884/* POOL32F_0 (fmt) instruction pool */
17885enum {
17886 NM_RINT_S = 0x04,
17887 NM_RINT_D = 0x44,
17888 NM_ADD_S = 0x06,
17889 NM_SELEQZ_S = 0x07,
17890 NM_SELEQZ_D = 0x47,
17891 NM_CLASS_S = 0x0c,
17892 NM_CLASS_D = 0x4c,
17893 NM_SUB_S = 0x0e,
17894 NM_SELNEZ_S = 0x0f,
17895 NM_SELNEZ_D = 0x4f,
17896 NM_MUL_S = 0x16,
17897 NM_SEL_S = 0x17,
17898 NM_SEL_D = 0x57,
17899 NM_DIV_S = 0x1e,
17900 NM_ADD_D = 0x26,
17901 NM_SUB_D = 0x2e,
17902 NM_MUL_D = 0x36,
17903 NM_MADDF_S = 0x37,
17904 NM_MADDF_D = 0x77,
17905 NM_DIV_D = 0x3e,
17906 NM_MSUBF_S = 0x3f,
17907 NM_MSUBF_D = 0x7f,
17908};
17909
17910/* POOL32F_3 instruction pool */
17911enum {
17912 NM_MIN_FMT = 0x00,
17913 NM_MAX_FMT = 0x01,
17914 NM_MINA_FMT = 0x04,
17915 NM_MAXA_FMT = 0x05,
17916 NM_POOL32FXF = 0x07,
17917};
17918
17919/* POOL32F_5 instruction pool */
17920enum {
17921 NM_CMP_CONDN_S = 0x00,
17922 NM_CMP_CONDN_D = 0x02,
17923};
17924
17925/* P.GP.LH instruction pool */
17926enum {
17927 NM_LHGP = 0x00,
17928 NM_LHUGP = 0x01,
17929};
17930
17931/* P.GP.SH instruction pool */
17932enum {
17933 NM_SHGP = 0x00,
17934};
17935
17936/* P.GP.CP1 instruction pool */
17937enum {
17938 NM_LWC1GP = 0x00,
17939 NM_SWC1GP = 0x01,
17940 NM_LDC1GP = 0x02,
17941 NM_SDC1GP = 0x03,
17942};
17943
17944/* P.LS.S0 instruction pool */
17945enum {
17946 NM_LBS9 = 0x00,
17947 NM_LHS9 = 0x04,
17948 NM_LWS9 = 0x08,
17949 NM_LDS9 = 0x0c,
17950
17951 NM_SBS9 = 0x01,
17952 NM_SHS9 = 0x05,
17953 NM_SWS9 = 0x09,
17954 NM_SDS9 = 0x0d,
17955
17956 NM_LBUS9 = 0x02,
17957 NM_LHUS9 = 0x06,
17958 NM_LWC1S9 = 0x0a,
17959 NM_LDC1S9 = 0x0e,
17960
17961 NM_P_PREFS9 = 0x03,
17962 NM_LWUS9 = 0x07,
17963 NM_SWC1S9 = 0x0b,
17964 NM_SDC1S9 = 0x0f,
17965};
17966
17967/* P.LS.S1 instruction pool */
17968enum {
17969 NM_ASET_ACLR = 0x02,
17970 NM_UALH = 0x04,
17971 NM_UASH = 0x05,
17972 NM_CACHE = 0x07,
17973 NM_P_LL = 0x0a,
17974 NM_P_SC = 0x0b,
17975};
17976
0d30b3bb
DN
17977/* P.LS.E0 instruction pool */
17978enum {
17979 NM_LBE = 0x00,
17980 NM_SBE = 0x01,
17981 NM_LBUE = 0x02,
17982 NM_P_PREFE = 0x03,
17983 NM_LHE = 0x04,
17984 NM_SHE = 0x05,
17985 NM_LHUE = 0x06,
17986 NM_CACHEE = 0x07,
17987 NM_LWE = 0x08,
17988 NM_SWE = 0x09,
17989 NM_P_LLE = 0x0a,
17990 NM_P_SCE = 0x0b,
17991};
17992
17993/* P.PREFE instruction pool */
17994enum {
17995 NM_SYNCIE = 0x00,
17996 NM_PREFE = 0x01,
17997};
17998
17999/* P.LLE instruction pool */
18000enum {
18001 NM_LLE = 0x00,
18002 NM_LLWPE = 0x01,
18003};
18004
18005/* P.SCE instruction pool */
18006enum {
18007 NM_SCE = 0x00,
18008 NM_SCWPE = 0x01,
18009};
18010
261c95a0
YK
18011/* P.LS.WM instruction pool */
18012enum {
18013 NM_LWM = 0x00,
18014 NM_SWM = 0x01,
18015};
18016
18017/* P.LS.UAWM instruction pool */
18018enum {
18019 NM_UALWM = 0x00,
18020 NM_UASWM = 0x01,
18021};
18022
18023/* P.BR3A instruction pool */
18024enum {
18025 NM_BC1EQZC = 0x00,
18026 NM_BC1NEZC = 0x01,
18027 NM_BC2EQZC = 0x02,
18028 NM_BC2NEZC = 0x03,
18029 NM_BPOSGE32C = 0x04,
18030};
18031
18032/* P16.RI instruction pool */
18033enum {
18034 NM_P16_SYSCALL = 0x01,
18035 NM_BREAK16 = 0x02,
18036 NM_SDBBP16 = 0x03,
18037};
18038
18039/* POOL16C_0 instruction pool */
18040enum {
18041 NM_POOL16C_00 = 0x00,
18042};
18043
18044/* P16.JRC instruction pool */
18045enum {
18046 NM_JRC = 0x00,
18047 NM_JALRC16 = 0x01,
18048};
18049
18050/* P.SYSCALL instruction pool */
18051enum {
18052 NM_SYSCALL = 0x00,
18053 NM_HYPCALL = 0x01,
18054};
18055
18056/* P.TRAP instruction pool */
18057enum {
18058 NM_TEQ = 0x00,
18059 NM_TNE = 0x01,
18060};
18061
18062/* P.CMOVE instruction pool */
18063enum {
18064 NM_MOVZ = 0x00,
18065 NM_MOVN = 0x01,
18066};
18067
18068/* POOL32Axf instruction pool */
18069enum {
b3979b6f
SM
18070 NM_POOL32AXF_1 = 0x01,
18071 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
18072 NM_POOL32AXF_4 = 0x04,
18073 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
18074 NM_POOL32AXF_7 = 0x07,
18075};
18076
18077/* POOL32Axf_1 instruction pool */
18078enum {
18079 NM_POOL32AXF_1_0 = 0x00,
18080 NM_POOL32AXF_1_1 = 0x01,
18081 NM_POOL32AXF_1_3 = 0x03,
18082 NM_POOL32AXF_1_4 = 0x04,
18083 NM_POOL32AXF_1_5 = 0x05,
18084 NM_POOL32AXF_1_7 = 0x07,
18085};
18086
18087/* POOL32Axf_2 instruction pool */
18088enum {
18089 NM_POOL32AXF_2_0_7 = 0x00,
18090 NM_POOL32AXF_2_8_15 = 0x01,
18091 NM_POOL32AXF_2_16_23 = 0x02,
18092 NM_POOL32AXF_2_24_31 = 0x03,
18093};
18094
18095/* POOL32Axf_7 instruction pool */
18096enum {
18097 NM_SHRA_R_QB = 0x0,
18098 NM_SHRL_PH = 0x1,
18099 NM_REPL_QB = 0x2,
18100};
18101
18102/* POOL32Axf_1_0 instruction pool */
18103enum {
18104 NM_MFHI = 0x0,
18105 NM_MFLO = 0x1,
18106 NM_MTHI = 0x2,
18107 NM_MTLO = 0x3,
18108};
18109
18110/* POOL32Axf_1_1 instruction pool */
18111enum {
18112 NM_MTHLIP = 0x0,
18113 NM_SHILOV = 0x1,
18114};
18115
18116/* POOL32Axf_1_3 instruction pool */
18117enum {
18118 NM_RDDSP = 0x0,
18119 NM_WRDSP = 0x1,
18120 NM_EXTP = 0x2,
18121 NM_EXTPDP = 0x3,
18122};
18123
18124/* POOL32Axf_1_4 instruction pool */
18125enum {
18126 NM_SHLL_QB = 0x0,
18127 NM_SHRL_QB = 0x1,
18128};
18129
18130/* POOL32Axf_1_5 instruction pool */
18131enum {
18132 NM_MAQ_S_W_PHR = 0x0,
18133 NM_MAQ_S_W_PHL = 0x1,
18134 NM_MAQ_SA_W_PHR = 0x2,
18135 NM_MAQ_SA_W_PHL = 0x3,
18136};
18137
18138/* POOL32Axf_1_7 instruction pool */
18139enum {
18140 NM_EXTR_W = 0x0,
18141 NM_EXTR_R_W = 0x1,
18142 NM_EXTR_RS_W = 0x2,
18143 NM_EXTR_S_H = 0x3,
18144};
18145
18146/* POOL32Axf_2_0_7 instruction pool */
18147enum {
18148 NM_DPA_W_PH = 0x0,
18149 NM_DPAQ_S_W_PH = 0x1,
18150 NM_DPS_W_PH = 0x2,
18151 NM_DPSQ_S_W_PH = 0x3,
18152 NM_BALIGN = 0x4,
18153 NM_MADD = 0x5,
18154 NM_MULT = 0x6,
18155 NM_EXTRV_W = 0x7,
18156};
18157
18158/* POOL32Axf_2_8_15 instruction pool */
18159enum {
18160 NM_DPAX_W_PH = 0x0,
18161 NM_DPAQ_SA_L_W = 0x1,
18162 NM_DPSX_W_PH = 0x2,
18163 NM_DPSQ_SA_L_W = 0x3,
18164 NM_MADDU = 0x5,
18165 NM_MULTU = 0x6,
18166 NM_EXTRV_R_W = 0x7,
18167};
18168
18169/* POOL32Axf_2_16_23 instruction pool */
18170enum {
18171 NM_DPAU_H_QBL = 0x0,
18172 NM_DPAQX_S_W_PH = 0x1,
18173 NM_DPSU_H_QBL = 0x2,
18174 NM_DPSQX_S_W_PH = 0x3,
18175 NM_EXTPV = 0x4,
18176 NM_MSUB = 0x5,
18177 NM_MULSA_W_PH = 0x6,
18178 NM_EXTRV_RS_W = 0x7,
18179};
18180
18181/* POOL32Axf_2_24_31 instruction pool */
18182enum {
18183 NM_DPAU_H_QBR = 0x0,
18184 NM_DPAQX_SA_W_PH = 0x1,
18185 NM_DPSU_H_QBR = 0x2,
18186 NM_DPSQX_SA_W_PH = 0x3,
18187 NM_EXTPDPV = 0x4,
18188 NM_MSUBU = 0x5,
18189 NM_MULSAQ_S_W_PH = 0x6,
18190 NM_EXTRV_S_H = 0x7,
261c95a0
YK
18191};
18192
18193/* POOL32Axf_{4, 5} instruction pool */
18194enum {
18195 NM_CLO = 0x25,
18196 NM_CLZ = 0x2d,
18197
18198 NM_TLBP = 0x01,
18199 NM_TLBR = 0x09,
18200 NM_TLBWI = 0x11,
18201 NM_TLBWR = 0x19,
18202 NM_TLBINV = 0x03,
18203 NM_TLBINVF = 0x0b,
18204 NM_DI = 0x23,
18205 NM_EI = 0x2b,
18206 NM_RDPGPR = 0x70,
18207 NM_WRPGPR = 0x78,
18208 NM_WAIT = 0x61,
18209 NM_DERET = 0x71,
18210 NM_ERETX = 0x79,
b3979b6f
SM
18211
18212 /* nanoMIPS DSP instructions */
18213 NM_ABSQ_S_QB = 0x00,
18214 NM_ABSQ_S_PH = 0x08,
18215 NM_ABSQ_S_W = 0x10,
18216 NM_PRECEQ_W_PHL = 0x28,
18217 NM_PRECEQ_W_PHR = 0x30,
18218 NM_PRECEQU_PH_QBL = 0x38,
18219 NM_PRECEQU_PH_QBR = 0x48,
18220 NM_PRECEU_PH_QBL = 0x58,
18221 NM_PRECEU_PH_QBR = 0x68,
18222 NM_PRECEQU_PH_QBLA = 0x39,
18223 NM_PRECEQU_PH_QBRA = 0x49,
18224 NM_PRECEU_PH_QBLA = 0x59,
18225 NM_PRECEU_PH_QBRA = 0x69,
18226 NM_REPLV_PH = 0x01,
18227 NM_REPLV_QB = 0x09,
18228 NM_BITREV = 0x18,
18229 NM_INSV = 0x20,
18230 NM_RADDU_W_QB = 0x78,
18231
18232 NM_BITSWAP = 0x05,
18233 NM_WSBH = 0x3d,
261c95a0
YK
18234};
18235
18236/* PP.SR instruction pool */
18237enum {
18238 NM_SAVE = 0x00,
18239 NM_RESTORE = 0x02,
18240 NM_RESTORE_JRC = 0x03,
18241};
18242
18243/* P.SR.F instruction pool */
18244enum {
18245 NM_SAVEF = 0x00,
18246 NM_RESTOREF = 0x01,
18247};
18248
18249/* P16.SYSCALL instruction pool */
18250enum {
18251 NM_SYSCALL16 = 0x00,
18252 NM_HYPCALL16 = 0x01,
18253};
18254
18255/* POOL16C_00 instruction pool */
18256enum {
18257 NM_NOT16 = 0x00,
18258 NM_XOR16 = 0x01,
18259 NM_AND16 = 0x02,
18260 NM_OR16 = 0x03,
18261};
18262
18263/* PP.LSX and PP.LSXS instruction pool */
18264enum {
18265 NM_LBX = 0x00,
18266 NM_LHX = 0x04,
18267 NM_LWX = 0x08,
18268 NM_LDX = 0x0c,
18269
18270 NM_SBX = 0x01,
18271 NM_SHX = 0x05,
18272 NM_SWX = 0x09,
18273 NM_SDX = 0x0d,
18274
18275 NM_LBUX = 0x02,
18276 NM_LHUX = 0x06,
18277 NM_LWC1X = 0x0a,
18278 NM_LDC1X = 0x0e,
18279
18280 NM_LWUX = 0x07,
18281 NM_SWC1X = 0x0b,
18282 NM_SDC1X = 0x0f,
18283
18284 NM_LHXS = 0x04,
18285 NM_LWXS = 0x08,
18286 NM_LDXS = 0x0c,
18287
18288 NM_SHXS = 0x05,
18289 NM_SWXS = 0x09,
18290 NM_SDXS = 0x0d,
18291
18292 NM_LHUXS = 0x06,
18293 NM_LWC1XS = 0x0a,
18294 NM_LDC1XS = 0x0e,
18295
18296 NM_LWUXS = 0x07,
18297 NM_SWC1XS = 0x0b,
18298 NM_SDC1XS = 0x0f,
18299};
18300
18301/* ERETx instruction pool */
18302enum {
18303 NM_ERET = 0x00,
18304 NM_ERETNC = 0x01,
18305};
18306
18307/* POOL32FxF_{0, 1} insturction pool */
18308enum {
18309 NM_CFC1 = 0x40,
18310 NM_CTC1 = 0x60,
18311 NM_MFC1 = 0x80,
18312 NM_MTC1 = 0xa0,
18313 NM_MFHC1 = 0xc0,
18314 NM_MTHC1 = 0xe0,
18315
18316 NM_CVT_S_PL = 0x84,
18317 NM_CVT_S_PU = 0xa4,
18318
18319 NM_CVT_L_S = 0x004,
18320 NM_CVT_L_D = 0x104,
18321 NM_CVT_W_S = 0x024,
18322 NM_CVT_W_D = 0x124,
18323
18324 NM_RSQRT_S = 0x008,
18325 NM_RSQRT_D = 0x108,
18326
18327 NM_SQRT_S = 0x028,
18328 NM_SQRT_D = 0x128,
18329
18330 NM_RECIP_S = 0x048,
18331 NM_RECIP_D = 0x148,
18332
18333 NM_FLOOR_L_S = 0x00c,
18334 NM_FLOOR_L_D = 0x10c,
18335
18336 NM_FLOOR_W_S = 0x02c,
18337 NM_FLOOR_W_D = 0x12c,
18338
18339 NM_CEIL_L_S = 0x04c,
18340 NM_CEIL_L_D = 0x14c,
18341 NM_CEIL_W_S = 0x06c,
18342 NM_CEIL_W_D = 0x16c,
18343 NM_TRUNC_L_S = 0x08c,
18344 NM_TRUNC_L_D = 0x18c,
18345 NM_TRUNC_W_S = 0x0ac,
18346 NM_TRUNC_W_D = 0x1ac,
18347 NM_ROUND_L_S = 0x0cc,
18348 NM_ROUND_L_D = 0x1cc,
18349 NM_ROUND_W_S = 0x0ec,
18350 NM_ROUND_W_D = 0x1ec,
18351
18352 NM_MOV_S = 0x01,
18353 NM_MOV_D = 0x81,
18354 NM_ABS_S = 0x0d,
18355 NM_ABS_D = 0x8d,
18356 NM_NEG_S = 0x2d,
18357 NM_NEG_D = 0xad,
18358 NM_CVT_D_S = 0x04d,
18359 NM_CVT_D_W = 0x0cd,
18360 NM_CVT_D_L = 0x14d,
18361 NM_CVT_S_D = 0x06d,
18362 NM_CVT_S_W = 0x0ed,
18363 NM_CVT_S_L = 0x16d,
18364};
18365
18366/* P.LL instruction pool */
18367enum {
18368 NM_LL = 0x00,
18369 NM_LLWP = 0x01,
18370};
18371
18372/* P.SC instruction pool */
18373enum {
18374 NM_SC = 0x00,
18375 NM_SCWP = 0x01,
18376};
18377
18378/* P.DVP instruction pool */
18379enum {
18380 NM_DVP = 0x00,
18381 NM_EVP = 0x01,
18382};
18383
c533c0f4
AM
18384
18385/*
18386 *
18387 * nanoMIPS decoding engine
18388 *
18389 */
18390
6bfa9f4c
AM
18391
18392/* extraction utilities */
18393
18394#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18395#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18396#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18397#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18398#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18399#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18400
ea4ca3c2
YK
18401/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18402static inline int decode_gpr_gpr3(int r)
18403{
18404 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18405
18406 return map[r & 0x7];
18407}
18408
8bdb7029
YK
18409/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18410static inline int decode_gpr_gpr3_src_store(int r)
18411{
18412 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18413
18414 return map[r & 0x7];
18415}
18416
ea4ca3c2
YK
18417/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18418static inline int decode_gpr_gpr4(int r)
18419{
18420 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18421 16, 17, 18, 19, 20, 21, 22, 23 };
18422
18423 return map[r & 0xf];
18424}
18425
8bdb7029
YK
18426/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18427static inline int decode_gpr_gpr4_zero(int r)
18428{
18429 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18430 16, 17, 18, 19, 20, 21, 22, 23 };
18431
18432 return map[r & 0xf];
18433}
18434
6bfa9f4c 18435
80845edf
YK
18436/* extraction utilities */
18437
18438#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18439#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18440#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18441#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18442#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18443#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18444
18445
bf0718c5
SM
18446static void gen_adjust_sp(DisasContext *ctx, int u)
18447{
18448 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18449}
18450
18451static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18452 uint8_t gp, uint16_t u)
18453{
18454 int counter = 0;
18455 TCGv va = tcg_temp_new();
18456 TCGv t0 = tcg_temp_new();
18457
18458 while (counter != count) {
18459 bool use_gp = gp && (counter == count - 1);
18460 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18461 int this_offset = -((counter + 1) << 2);
18462 gen_base_offset_addr(ctx, va, 29, this_offset);
18463 gen_load_gpr(t0, this_rt);
18464 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18465 (MO_TEUL | ctx->default_tcg_memop_mask));
18466 counter++;
18467 }
18468
18469 /* adjust stack pointer */
18470 gen_adjust_sp(ctx, -u);
18471
18472 tcg_temp_free(t0);
18473 tcg_temp_free(va);
18474}
18475
18476static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18477 uint8_t gp, uint16_t u)
18478{
18479 int counter = 0;
18480 TCGv va = tcg_temp_new();
18481 TCGv t0 = tcg_temp_new();
18482
18483 while (counter != count) {
18484 bool use_gp = gp && (counter == count - 1);
18485 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18486 int this_offset = u - ((counter + 1) << 2);
18487 gen_base_offset_addr(ctx, va, 29, this_offset);
18488 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18489 ctx->default_tcg_memop_mask);
18490 tcg_gen_ext32s_tl(t0, t0);
18491 gen_store_gpr(t0, this_rt);
18492 counter++;
18493 }
18494
18495 /* adjust stack pointer */
18496 gen_adjust_sp(ctx, u);
18497
18498 tcg_temp_free(t0);
18499 tcg_temp_free(va);
18500}
18501
80845edf
YK
18502static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18503{
18504 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18505 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18506
18507 switch (extract32(ctx->opcode, 2, 2)) {
18508 case NM_NOT16:
18509 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18510 break;
18511 case NM_AND16:
18512 gen_logic(ctx, OPC_AND, rt, rt, rs);
18513 break;
18514 case NM_XOR16:
18515 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18516 break;
18517 case NM_OR16:
18518 gen_logic(ctx, OPC_OR, rt, rt, rs);
18519 break;
18520 }
18521}
18522
0a1a6ed7 18523static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
18524{
18525 int rt = extract32(ctx->opcode, 21, 5);
18526 int rs = extract32(ctx->opcode, 16, 5);
18527 int rd = extract32(ctx->opcode, 11, 5);
18528
18529 switch (extract32(ctx->opcode, 3, 7)) {
18530 case NM_P_TRAP:
18531 switch (extract32(ctx->opcode, 10, 1)) {
18532 case NM_TEQ:
fb32f8c8 18533 check_nms(ctx);
e0cf0e65
YK
18534 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18535 break;
18536 case NM_TNE:
fb32f8c8 18537 check_nms(ctx);
e0cf0e65
YK
18538 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18539 break;
18540 }
18541 break;
18542 case NM_RDHWR:
fb32f8c8 18543 check_nms(ctx);
e0cf0e65
YK
18544 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18545 break;
18546 case NM_SEB:
fb32f8c8 18547 check_nms(ctx);
e0cf0e65
YK
18548 gen_bshfl(ctx, OPC_SEB, rs, rt);
18549 break;
18550 case NM_SEH:
18551 gen_bshfl(ctx, OPC_SEH, rs, rt);
18552 break;
18553 case NM_SLLV:
18554 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18555 break;
18556 case NM_SRLV:
18557 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18558 break;
18559 case NM_SRAV:
18560 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18561 break;
18562 case NM_ROTRV:
18563 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18564 break;
18565 case NM_ADD:
18566 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18567 break;
18568 case NM_ADDU:
18569 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18570 break;
18571 case NM_SUB:
fb32f8c8 18572 check_nms(ctx);
e0cf0e65
YK
18573 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18574 break;
18575 case NM_SUBU:
18576 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18577 break;
18578 case NM_P_CMOVE:
18579 switch (extract32(ctx->opcode, 10, 1)) {
18580 case NM_MOVZ:
18581 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18582 break;
18583 case NM_MOVN:
18584 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18585 break;
18586 }
18587 break;
18588 case NM_AND:
18589 gen_logic(ctx, OPC_AND, rd, rs, rt);
18590 break;
18591 case NM_OR:
18592 gen_logic(ctx, OPC_OR, rd, rs, rt);
18593 break;
18594 case NM_NOR:
18595 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18596 break;
18597 case NM_XOR:
18598 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18599 break;
18600 case NM_SLT:
18601 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18602 break;
18603 case NM_P_SLTU:
18604 if (rd == 0) {
18605 /* P_DVP */
18606#ifndef CONFIG_USER_ONLY
18607 TCGv t0 = tcg_temp_new();
18608 switch (extract32(ctx->opcode, 10, 1)) {
18609 case NM_DVP:
18610 if (ctx->vp) {
18611 check_cp0_enabled(ctx);
18612 gen_helper_dvp(t0, cpu_env);
18613 gen_store_gpr(t0, rt);
18614 }
18615 break;
18616 case NM_EVP:
18617 if (ctx->vp) {
18618 check_cp0_enabled(ctx);
18619 gen_helper_evp(t0, cpu_env);
18620 gen_store_gpr(t0, rt);
18621 }
18622 break;
18623 }
18624 tcg_temp_free(t0);
18625#endif
18626 } else {
18627 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18628 }
18629 break;
18630 case NM_SOV:
18631 {
18632 TCGv t0 = tcg_temp_new();
18633 TCGv t1 = tcg_temp_new();
18634 TCGv t2 = tcg_temp_new();
18635
18636 gen_load_gpr(t1, rs);
18637 gen_load_gpr(t2, rt);
18638 tcg_gen_add_tl(t0, t1, t2);
18639 tcg_gen_ext32s_tl(t0, t0);
18640 tcg_gen_xor_tl(t1, t1, t2);
18641 tcg_gen_xor_tl(t2, t0, t2);
18642 tcg_gen_andc_tl(t1, t2, t1);
18643
18644 /* operands of same sign, result different sign */
18645 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18646 gen_store_gpr(t0, rd);
18647
18648 tcg_temp_free(t0);
18649 tcg_temp_free(t1);
18650 tcg_temp_free(t2);
18651 }
18652 break;
18653 case NM_MUL:
18654 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18655 break;
18656 case NM_MUH:
18657 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18658 break;
18659 case NM_MULU:
18660 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18661 break;
18662 case NM_MUHU:
18663 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18664 break;
18665 case NM_DIV:
18666 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18667 break;
18668 case NM_MOD:
18669 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18670 break;
18671 case NM_DIVU:
18672 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18673 break;
18674 case NM_MODU:
18675 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18676 break;
18677#ifndef CONFIG_USER_ONLY
18678 case NM_MFC0:
18679 check_cp0_enabled(ctx);
18680 if (rt == 0) {
18681 /* Treat as NOP. */
18682 break;
18683 }
18684 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18685 break;
18686 case NM_MTC0:
18687 check_cp0_enabled(ctx);
18688 {
18689 TCGv t0 = tcg_temp_new();
18690
18691 gen_load_gpr(t0, rt);
18692 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18693 tcg_temp_free(t0);
18694 }
18695 break;
0a1a6ed7
SM
18696 case NM_D_E_MT_VPE:
18697 {
18698 uint8_t sc = extract32(ctx->opcode, 10, 1);
18699 TCGv t0 = tcg_temp_new();
18700
18701 switch (sc) {
18702 case 0:
18703 if (rs == 1) {
18704 /* DMT */
18705 check_cp0_mt(ctx);
18706 gen_helper_dmt(t0);
18707 gen_store_gpr(t0, rt);
18708 } else if (rs == 0) {
18709 /* DVPE */
18710 check_cp0_mt(ctx);
18711 gen_helper_dvpe(t0, cpu_env);
18712 gen_store_gpr(t0, rt);
18713 } else {
18714 generate_exception_end(ctx, EXCP_RI);
18715 }
18716 break;
18717 case 1:
18718 if (rs == 1) {
18719 /* EMT */
18720 check_cp0_mt(ctx);
18721 gen_helper_emt(t0);
18722 gen_store_gpr(t0, rt);
18723 } else if (rs == 0) {
18724 /* EVPE */
18725 check_cp0_mt(ctx);
18726 gen_helper_evpe(t0, cpu_env);
18727 gen_store_gpr(t0, rt);
18728 } else {
18729 generate_exception_end(ctx, EXCP_RI);
18730 }
18731 break;
18732 }
18733
18734 tcg_temp_free(t0);
18735 }
18736 break;
18737 case NM_FORK:
18738 check_mt(ctx);
18739 {
18740 TCGv t0 = tcg_temp_new();
18741 TCGv t1 = tcg_temp_new();
18742
18743 gen_load_gpr(t0, rt);
18744 gen_load_gpr(t1, rs);
18745 gen_helper_fork(t0, t1);
18746 tcg_temp_free(t0);
18747 tcg_temp_free(t1);
18748 }
18749 break;
18750 case NM_MFTR:
18751 case NM_MFHTR:
18752 check_cp0_enabled(ctx);
18753 if (rd == 0) {
18754 /* Treat as NOP. */
18755 return;
18756 }
18757 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18758 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18759 break;
18760 case NM_MTTR:
18761 case NM_MTHTR:
18762 check_cp0_enabled(ctx);
18763 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18764 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18765 break;
18766 case NM_YIELD:
18767 check_mt(ctx);
18768 {
18769 TCGv t0 = tcg_temp_new();
18770
18771 gen_load_gpr(t0, rs);
18772 gen_helper_yield(t0, cpu_env, t0);
18773 gen_store_gpr(t0, rt);
18774 tcg_temp_free(t0);
18775 }
18776 break;
e0cf0e65
YK
18777#endif
18778 default:
18779 generate_exception_end(ctx, EXCP_RI);
18780 break;
18781 }
18782}
18783
2ed42efa
SM
18784/* dsp */
18785static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18786 int ret, int v1, int v2)
18787{
18788 TCGv_i32 t0;
18789 TCGv v0_t;
18790 TCGv v1_t;
18791
18792 t0 = tcg_temp_new_i32();
18793
18794 v0_t = tcg_temp_new();
18795 v1_t = tcg_temp_new();
18796
18797 tcg_gen_movi_i32(t0, v2 >> 3);
18798
18799 gen_load_gpr(v0_t, ret);
18800 gen_load_gpr(v1_t, v1);
18801
18802 switch (opc) {
18803 case NM_MAQ_S_W_PHR:
18804 check_dsp(ctx);
18805 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18806 break;
18807 case NM_MAQ_S_W_PHL:
18808 check_dsp(ctx);
18809 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18810 break;
18811 case NM_MAQ_SA_W_PHR:
18812 check_dsp(ctx);
18813 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18814 break;
18815 case NM_MAQ_SA_W_PHL:
18816 check_dsp(ctx);
18817 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18818 break;
18819 default:
18820 generate_exception_end(ctx, EXCP_RI);
18821 break;
18822 }
18823
18824 tcg_temp_free_i32(t0);
18825
18826 tcg_temp_free(v0_t);
18827 tcg_temp_free(v1_t);
18828}
18829
18830
18831static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18832 int ret, int v1, int v2)
18833{
18834 int16_t imm;
18835 TCGv t0 = tcg_temp_new();
18836 TCGv t1 = tcg_temp_new();
18837 TCGv v0_t = tcg_temp_new();
18838
18839 gen_load_gpr(v0_t, v1);
18840
18841 switch (opc) {
18842 case NM_POOL32AXF_1_0:
18843 check_dsp(ctx);
18844 switch (extract32(ctx->opcode, 12, 2)) {
18845 case NM_MFHI:
18846 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18847 break;
18848 case NM_MFLO:
18849 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18850 break;
18851 case NM_MTHI:
18852 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18853 break;
18854 case NM_MTLO:
18855 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18856 break;
18857 }
18858 break;
18859 case NM_POOL32AXF_1_1:
18860 check_dsp(ctx);
18861 switch (extract32(ctx->opcode, 12, 2)) {
18862 case NM_MTHLIP:
18863 tcg_gen_movi_tl(t0, v2);
18864 gen_helper_mthlip(t0, v0_t, cpu_env);
18865 break;
18866 case NM_SHILOV:
18867 tcg_gen_movi_tl(t0, v2 >> 3);
18868 gen_helper_shilo(t0, v0_t, cpu_env);
18869 break;
18870 default:
18871 generate_exception_end(ctx, EXCP_RI);
18872 break;
18873 }
18874 break;
18875 case NM_POOL32AXF_1_3:
18876 check_dsp(ctx);
18877 imm = extract32(ctx->opcode, 14, 7);
18878 switch (extract32(ctx->opcode, 12, 2)) {
18879 case NM_RDDSP:
18880 tcg_gen_movi_tl(t0, imm);
18881 gen_helper_rddsp(t0, t0, cpu_env);
18882 gen_store_gpr(t0, ret);
18883 break;
18884 case NM_WRDSP:
18885 gen_load_gpr(t0, ret);
18886 tcg_gen_movi_tl(t1, imm);
18887 gen_helper_wrdsp(t0, t1, cpu_env);
18888 break;
18889 case NM_EXTP:
18890 tcg_gen_movi_tl(t0, v2 >> 3);
18891 tcg_gen_movi_tl(t1, v1);
18892 gen_helper_extp(t0, t0, t1, cpu_env);
18893 gen_store_gpr(t0, ret);
18894 break;
18895 case NM_EXTPDP:
18896 tcg_gen_movi_tl(t0, v2 >> 3);
18897 tcg_gen_movi_tl(t1, v1);
18898 gen_helper_extpdp(t0, t0, t1, cpu_env);
18899 gen_store_gpr(t0, ret);
18900 break;
18901 }
18902 break;
18903 case NM_POOL32AXF_1_4:
18904 check_dsp(ctx);
18905 tcg_gen_movi_tl(t0, v2 >> 2);
18906 switch (extract32(ctx->opcode, 12, 1)) {
18907 case NM_SHLL_QB:
18908 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18909 gen_store_gpr(t0, ret);
18910 break;
18911 case NM_SHRL_QB:
18912 gen_helper_shrl_qb(t0, t0, v0_t);
18913 gen_store_gpr(t0, ret);
18914 break;
18915 }
18916 break;
18917 case NM_POOL32AXF_1_5:
18918 opc = extract32(ctx->opcode, 12, 2);
18919 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18920 break;
18921 case NM_POOL32AXF_1_7:
18922 check_dsp(ctx);
18923 tcg_gen_movi_tl(t0, v2 >> 3);
18924 tcg_gen_movi_tl(t1, v1);
18925 switch (extract32(ctx->opcode, 12, 2)) {
18926 case NM_EXTR_W:
18927 gen_helper_extr_w(t0, t0, t1, cpu_env);
18928 gen_store_gpr(t0, ret);
18929 break;
18930 case NM_EXTR_R_W:
18931 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18932 gen_store_gpr(t0, ret);
18933 break;
18934 case NM_EXTR_RS_W:
18935 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18936 gen_store_gpr(t0, ret);
18937 break;
18938 case NM_EXTR_S_H:
18939 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18940 gen_store_gpr(t0, ret);
18941 break;
18942 }
18943 break;
18944 default:
18945 generate_exception_end(ctx, EXCP_RI);
18946 break;
18947 }
18948
18949 tcg_temp_free(t0);
18950 tcg_temp_free(t1);
18951 tcg_temp_free(v0_t);
18952}
18953
8b3698b2
SM
18954static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18955 TCGv v0, TCGv v1, int rd)
18956{
18957 TCGv_i32 t0;
18958
18959 t0 = tcg_temp_new_i32();
18960
18961 tcg_gen_movi_i32(t0, rd >> 3);
18962
18963 switch (opc) {
18964 case NM_POOL32AXF_2_0_7:
18965 switch (extract32(ctx->opcode, 9, 3)) {
18966 case NM_DPA_W_PH:
908f6be1 18967 check_dsp_r2(ctx);
8b3698b2
SM
18968 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18969 break;
18970 case NM_DPAQ_S_W_PH:
18971 check_dsp(ctx);
18972 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18973 break;
18974 case NM_DPS_W_PH:
908f6be1 18975 check_dsp_r2(ctx);
8b3698b2
SM
18976 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18977 break;
18978 case NM_DPSQ_S_W_PH:
18979 check_dsp(ctx);
18980 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18981 break;
18982 default:
18983 generate_exception_end(ctx, EXCP_RI);
18984 break;
18985 }
18986 break;
18987 case NM_POOL32AXF_2_8_15:
18988 switch (extract32(ctx->opcode, 9, 3)) {
18989 case NM_DPAX_W_PH:
908f6be1 18990 check_dsp_r2(ctx);
8b3698b2
SM
18991 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18992 break;
18993 case NM_DPAQ_SA_L_W:
18994 check_dsp(ctx);
18995 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18996 break;
18997 case NM_DPSX_W_PH:
908f6be1 18998 check_dsp_r2(ctx);
8b3698b2
SM
18999 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19000 break;
19001 case NM_DPSQ_SA_L_W:
19002 check_dsp(ctx);
19003 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19004 break;
19005 default:
19006 generate_exception_end(ctx, EXCP_RI);
19007 break;
19008 }
19009 break;
19010 case NM_POOL32AXF_2_16_23:
19011 switch (extract32(ctx->opcode, 9, 3)) {
19012 case NM_DPAU_H_QBL:
19013 check_dsp(ctx);
19014 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19015 break;
19016 case NM_DPAQX_S_W_PH:
908f6be1 19017 check_dsp_r2(ctx);
8b3698b2
SM
19018 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19019 break;
19020 case NM_DPSU_H_QBL:
19021 check_dsp(ctx);
19022 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19023 break;
19024 case NM_DPSQX_S_W_PH:
908f6be1 19025 check_dsp_r2(ctx);
8b3698b2
SM
19026 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19027 break;
19028 case NM_MULSA_W_PH:
908f6be1 19029 check_dsp_r2(ctx);
8b3698b2
SM
19030 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19031 break;
19032 default:
19033 generate_exception_end(ctx, EXCP_RI);
19034 break;
19035 }
19036 break;
19037 case NM_POOL32AXF_2_24_31:
19038 switch (extract32(ctx->opcode, 9, 3)) {
19039 case NM_DPAU_H_QBR:
19040 check_dsp(ctx);
19041 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19042 break;
19043 case NM_DPAQX_SA_W_PH:
908f6be1 19044 check_dsp_r2(ctx);
8b3698b2
SM
19045 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19046 break;
19047 case NM_DPSU_H_QBR:
19048 check_dsp(ctx);
19049 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19050 break;
19051 case NM_DPSQX_SA_W_PH:
908f6be1 19052 check_dsp_r2(ctx);
8b3698b2
SM
19053 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19054 break;
19055 case NM_MULSAQ_S_W_PH:
19056 check_dsp(ctx);
19057 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19058 break;
19059 default:
19060 generate_exception_end(ctx, EXCP_RI);
19061 break;
19062 }
19063 break;
19064 default:
19065 generate_exception_end(ctx, EXCP_RI);
19066 break;
19067 }
19068
19069 tcg_temp_free_i32(t0);
19070}
19071
19072static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19073 int rt, int rs, int rd)
19074{
19075 int ret = rt;
19076 TCGv t0 = tcg_temp_new();
19077 TCGv t1 = tcg_temp_new();
19078 TCGv v0_t = tcg_temp_new();
19079 TCGv v1_t = tcg_temp_new();
19080
19081 gen_load_gpr(v0_t, rt);
19082 gen_load_gpr(v1_t, rs);
19083
19084 switch (opc) {
19085 case NM_POOL32AXF_2_0_7:
19086 switch (extract32(ctx->opcode, 9, 3)) {
19087 case NM_DPA_W_PH:
19088 case NM_DPAQ_S_W_PH:
19089 case NM_DPS_W_PH:
19090 case NM_DPSQ_S_W_PH:
19091 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19092 break;
19093 case NM_BALIGN:
908f6be1 19094 check_dsp_r2(ctx);
8b3698b2
SM
19095 if (rt != 0) {
19096 gen_load_gpr(t0, rs);
19097 rd &= 3;
19098 if (rd != 0 && rd != 2) {
19099 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19100 tcg_gen_ext32u_tl(t0, t0);
19101 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19102 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19103 }
19104 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19105 }
19106 break;
19107 case NM_MADD:
19108 check_dsp(ctx);
19109 {
19110 int acc = extract32(ctx->opcode, 14, 2);
19111 TCGv_i64 t2 = tcg_temp_new_i64();
19112 TCGv_i64 t3 = tcg_temp_new_i64();
19113
19114 gen_load_gpr(t0, rt);
19115 gen_load_gpr(t1, rs);
19116 tcg_gen_ext_tl_i64(t2, t0);
19117 tcg_gen_ext_tl_i64(t3, t1);
19118 tcg_gen_mul_i64(t2, t2, t3);
19119 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19120 tcg_gen_add_i64(t2, t2, t3);
19121 tcg_temp_free_i64(t3);
19122 gen_move_low32(cpu_LO[acc], t2);
19123 gen_move_high32(cpu_HI[acc], t2);
19124 tcg_temp_free_i64(t2);
19125 }
19126 break;
19127 case NM_MULT:
19128 check_dsp(ctx);
19129 {
19130 int acc = extract32(ctx->opcode, 14, 2);
19131 TCGv_i32 t2 = tcg_temp_new_i32();
19132 TCGv_i32 t3 = tcg_temp_new_i32();
19133
19134 gen_load_gpr(t0, rs);
19135 gen_load_gpr(t1, rt);
19136 tcg_gen_trunc_tl_i32(t2, t0);
19137 tcg_gen_trunc_tl_i32(t3, t1);
19138 tcg_gen_muls2_i32(t2, t3, t2, t3);
19139 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19140 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19141 tcg_temp_free_i32(t2);
19142 tcg_temp_free_i32(t3);
19143 }
19144 break;
19145 case NM_EXTRV_W:
19146 check_dsp(ctx);
19147 gen_load_gpr(v1_t, rs);
19148 tcg_gen_movi_tl(t0, rd >> 3);
19149 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19150 gen_store_gpr(t0, ret);
19151 break;
19152 }
19153 break;
19154 case NM_POOL32AXF_2_8_15:
19155 switch (extract32(ctx->opcode, 9, 3)) {
19156 case NM_DPAX_W_PH:
19157 case NM_DPAQ_SA_L_W:
19158 case NM_DPSX_W_PH:
19159 case NM_DPSQ_SA_L_W:
19160 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19161 break;
19162 case NM_MADDU:
19163 check_dsp(ctx);
19164 {
19165 int acc = extract32(ctx->opcode, 14, 2);
19166 TCGv_i64 t2 = tcg_temp_new_i64();
19167 TCGv_i64 t3 = tcg_temp_new_i64();
19168
19169 gen_load_gpr(t0, rs);
19170 gen_load_gpr(t1, rt);
19171 tcg_gen_ext32u_tl(t0, t0);
19172 tcg_gen_ext32u_tl(t1, t1);
19173 tcg_gen_extu_tl_i64(t2, t0);
19174 tcg_gen_extu_tl_i64(t3, t1);
19175 tcg_gen_mul_i64(t2, t2, t3);
19176 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19177 tcg_gen_add_i64(t2, t2, t3);
19178 tcg_temp_free_i64(t3);
19179 gen_move_low32(cpu_LO[acc], t2);
19180 gen_move_high32(cpu_HI[acc], t2);
19181 tcg_temp_free_i64(t2);
19182 }
19183 break;
19184 case NM_MULTU:
19185 check_dsp(ctx);
19186 {
19187 int acc = extract32(ctx->opcode, 14, 2);
19188 TCGv_i32 t2 = tcg_temp_new_i32();
19189 TCGv_i32 t3 = tcg_temp_new_i32();
19190
19191 gen_load_gpr(t0, rs);
19192 gen_load_gpr(t1, rt);
19193 tcg_gen_trunc_tl_i32(t2, t0);
19194 tcg_gen_trunc_tl_i32(t3, t1);
19195 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19196 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19197 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19198 tcg_temp_free_i32(t2);
19199 tcg_temp_free_i32(t3);
19200 }
19201 break;
19202 case NM_EXTRV_R_W:
19203 check_dsp(ctx);
19204 tcg_gen_movi_tl(t0, rd >> 3);
19205 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19206 gen_store_gpr(t0, ret);
19207 break;
19208 default:
19209 generate_exception_end(ctx, EXCP_RI);
19210 break;
19211 }
19212 break;
19213 case NM_POOL32AXF_2_16_23:
19214 switch (extract32(ctx->opcode, 9, 3)) {
19215 case NM_DPAU_H_QBL:
19216 case NM_DPAQX_S_W_PH:
19217 case NM_DPSU_H_QBL:
19218 case NM_DPSQX_S_W_PH:
19219 case NM_MULSA_W_PH:
19220 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19221 break;
19222 case NM_EXTPV:
19223 check_dsp(ctx);
19224 tcg_gen_movi_tl(t0, rd >> 3);
19225 gen_helper_extp(t0, t0, v1_t, cpu_env);
19226 gen_store_gpr(t0, ret);
19227 break;
19228 case NM_MSUB:
19229 check_dsp(ctx);
19230 {
19231 int acc = extract32(ctx->opcode, 14, 2);
19232 TCGv_i64 t2 = tcg_temp_new_i64();
19233 TCGv_i64 t3 = tcg_temp_new_i64();
19234
19235 gen_load_gpr(t0, rs);
19236 gen_load_gpr(t1, rt);
19237 tcg_gen_ext_tl_i64(t2, t0);
19238 tcg_gen_ext_tl_i64(t3, t1);
19239 tcg_gen_mul_i64(t2, t2, t3);
19240 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19241 tcg_gen_sub_i64(t2, t3, t2);
19242 tcg_temp_free_i64(t3);
19243 gen_move_low32(cpu_LO[acc], t2);
19244 gen_move_high32(cpu_HI[acc], t2);
19245 tcg_temp_free_i64(t2);
19246 }
19247 break;
19248 case NM_EXTRV_RS_W:
19249 check_dsp(ctx);
19250 tcg_gen_movi_tl(t0, rd >> 3);
19251 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19252 gen_store_gpr(t0, ret);
19253 break;
19254 }
19255 break;
19256 case NM_POOL32AXF_2_24_31:
19257 switch (extract32(ctx->opcode, 9, 3)) {
19258 case NM_DPAU_H_QBR:
19259 case NM_DPAQX_SA_W_PH:
19260 case NM_DPSU_H_QBR:
19261 case NM_DPSQX_SA_W_PH:
19262 case NM_MULSAQ_S_W_PH:
19263 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19264 break;
19265 case NM_EXTPDPV:
19266 check_dsp(ctx);
19267 tcg_gen_movi_tl(t0, rd >> 3);
19268 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19269 gen_store_gpr(t0, ret);
19270 break;
19271 case NM_MSUBU:
19272 check_dsp(ctx);
19273 {
19274 int acc = extract32(ctx->opcode, 14, 2);
19275 TCGv_i64 t2 = tcg_temp_new_i64();
19276 TCGv_i64 t3 = tcg_temp_new_i64();
19277
19278 gen_load_gpr(t0, rs);
19279 gen_load_gpr(t1, rt);
19280 tcg_gen_ext32u_tl(t0, t0);
19281 tcg_gen_ext32u_tl(t1, t1);
19282 tcg_gen_extu_tl_i64(t2, t0);
19283 tcg_gen_extu_tl_i64(t3, t1);
19284 tcg_gen_mul_i64(t2, t2, t3);
19285 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19286 tcg_gen_sub_i64(t2, t3, t2);
19287 tcg_temp_free_i64(t3);
19288 gen_move_low32(cpu_LO[acc], t2);
19289 gen_move_high32(cpu_HI[acc], t2);
19290 tcg_temp_free_i64(t2);
19291 }
19292 break;
19293 case NM_EXTRV_S_H:
19294 check_dsp(ctx);
19295 tcg_gen_movi_tl(t0, rd >> 3);
19296 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19297 gen_store_gpr(t0, ret);
19298 break;
19299 }
19300 break;
19301 default:
19302 generate_exception_end(ctx, EXCP_RI);
19303 break;
19304 }
19305
19306 tcg_temp_free(t0);
19307 tcg_temp_free(t1);
19308
19309 tcg_temp_free(v0_t);
19310 tcg_temp_free(v1_t);
19311}
19312
4c75c985
SM
19313static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19314 int rt, int rs)
19315{
19316 int ret = rt;
19317 TCGv t0 = tcg_temp_new();
19318 TCGv v0_t = tcg_temp_new();
19319
19320 gen_load_gpr(v0_t, rs);
19321
19322 switch (opc) {
19323 case NM_ABSQ_S_QB:
908f6be1 19324 check_dsp_r2(ctx);
4c75c985
SM
19325 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19326 gen_store_gpr(v0_t, ret);
19327 break;
19328 case NM_ABSQ_S_PH:
19329 check_dsp(ctx);
19330 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19331 gen_store_gpr(v0_t, ret);
19332 break;
19333 case NM_ABSQ_S_W:
19334 check_dsp(ctx);
19335 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19336 gen_store_gpr(v0_t, ret);
19337 break;
19338 case NM_PRECEQ_W_PHL:
19339 check_dsp(ctx);
19340 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19341 tcg_gen_ext32s_tl(v0_t, v0_t);
19342 gen_store_gpr(v0_t, ret);
19343 break;
19344 case NM_PRECEQ_W_PHR:
19345 check_dsp(ctx);
19346 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19347 tcg_gen_shli_tl(v0_t, v0_t, 16);
19348 tcg_gen_ext32s_tl(v0_t, v0_t);
19349 gen_store_gpr(v0_t, ret);
19350 break;
19351 case NM_PRECEQU_PH_QBL:
19352 check_dsp(ctx);
19353 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19354 gen_store_gpr(v0_t, ret);
19355 break;
19356 case NM_PRECEQU_PH_QBR:
19357 check_dsp(ctx);
19358 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19359 gen_store_gpr(v0_t, ret);
19360 break;
19361 case NM_PRECEQU_PH_QBLA:
19362 check_dsp(ctx);
19363 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19364 gen_store_gpr(v0_t, ret);
19365 break;
19366 case NM_PRECEQU_PH_QBRA:
19367 check_dsp(ctx);
19368 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19369 gen_store_gpr(v0_t, ret);
19370 break;
19371 case NM_PRECEU_PH_QBL:
19372 check_dsp(ctx);
19373 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19374 gen_store_gpr(v0_t, ret);
19375 break;
19376 case NM_PRECEU_PH_QBR:
19377 check_dsp(ctx);
19378 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19379 gen_store_gpr(v0_t, ret);
19380 break;
19381 case NM_PRECEU_PH_QBLA:
19382 check_dsp(ctx);
19383 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19384 gen_store_gpr(v0_t, ret);
19385 break;
19386 case NM_PRECEU_PH_QBRA:
19387 check_dsp(ctx);
19388 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19389 gen_store_gpr(v0_t, ret);
19390 break;
19391 case NM_REPLV_PH:
19392 check_dsp(ctx);
19393 tcg_gen_ext16u_tl(v0_t, v0_t);
19394 tcg_gen_shli_tl(t0, v0_t, 16);
19395 tcg_gen_or_tl(v0_t, v0_t, t0);
19396 tcg_gen_ext32s_tl(v0_t, v0_t);
19397 gen_store_gpr(v0_t, ret);
19398 break;
19399 case NM_REPLV_QB:
19400 check_dsp(ctx);
19401 tcg_gen_ext8u_tl(v0_t, v0_t);
19402 tcg_gen_shli_tl(t0, v0_t, 8);
19403 tcg_gen_or_tl(v0_t, v0_t, t0);
19404 tcg_gen_shli_tl(t0, v0_t, 16);
19405 tcg_gen_or_tl(v0_t, v0_t, t0);
19406 tcg_gen_ext32s_tl(v0_t, v0_t);
19407 gen_store_gpr(v0_t, ret);
19408 break;
19409 case NM_BITREV:
19410 check_dsp(ctx);
19411 gen_helper_bitrev(v0_t, v0_t);
19412 gen_store_gpr(v0_t, ret);
19413 break;
19414 case NM_INSV:
19415 check_dsp(ctx);
19416 {
19417 TCGv tv0 = tcg_temp_new();
19418
19419 gen_load_gpr(tv0, rt);
19420 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19421 gen_store_gpr(v0_t, ret);
19422 tcg_temp_free(tv0);
19423 }
19424 break;
19425 case NM_RADDU_W_QB:
19426 check_dsp(ctx);
19427 gen_helper_raddu_w_qb(v0_t, v0_t);
19428 gen_store_gpr(v0_t, ret);
19429 break;
19430 case NM_BITSWAP:
19431 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19432 break;
19433 case NM_CLO:
fb32f8c8 19434 check_nms(ctx);
4c75c985
SM
19435 gen_cl(ctx, OPC_CLO, ret, rs);
19436 break;
19437 case NM_CLZ:
fb32f8c8 19438 check_nms(ctx);
4c75c985
SM
19439 gen_cl(ctx, OPC_CLZ, ret, rs);
19440 break;
19441 case NM_WSBH:
19442 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19443 break;
19444 default:
19445 generate_exception_end(ctx, EXCP_RI);
19446 break;
19447 }
19448
19449 tcg_temp_free(v0_t);
19450 tcg_temp_free(t0);
19451}
19452
0b591184
SM
19453static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19454 int rt, int rs, int rd)
19455{
19456 TCGv t0 = tcg_temp_new();
19457 TCGv rs_t = tcg_temp_new();
19458
19459 gen_load_gpr(rs_t, rs);
19460
19461 switch (opc) {
19462 case NM_SHRA_R_QB:
908f6be1 19463 check_dsp_r2(ctx);
0b591184
SM
19464 tcg_gen_movi_tl(t0, rd >> 2);
19465 switch (extract32(ctx->opcode, 12, 1)) {
19466 case 0:
19467 /* NM_SHRA_QB */
19468 gen_helper_shra_qb(t0, t0, rs_t);
19469 gen_store_gpr(t0, rt);
19470 break;
19471 case 1:
19472 /* NM_SHRA_R_QB */
19473 gen_helper_shra_r_qb(t0, t0, rs_t);
19474 gen_store_gpr(t0, rt);
19475 break;
19476 }
19477 break;
19478 case NM_SHRL_PH:
908f6be1 19479 check_dsp_r2(ctx);
0b591184
SM
19480 tcg_gen_movi_tl(t0, rd >> 1);
19481 gen_helper_shrl_ph(t0, t0, rs_t);
19482 gen_store_gpr(t0, rt);
19483 break;
19484 case NM_REPL_QB:
19485 check_dsp(ctx);
19486 {
19487 int16_t imm;
19488 target_long result;
19489 imm = extract32(ctx->opcode, 13, 8);
19490 result = (uint32_t)imm << 24 |
19491 (uint32_t)imm << 16 |
19492 (uint32_t)imm << 8 |
19493 (uint32_t)imm;
19494 result = (int32_t)result;
19495 tcg_gen_movi_tl(t0, result);
19496 gen_store_gpr(t0, rt);
19497 }
19498 break;
19499 default:
19500 generate_exception_end(ctx, EXCP_RI);
19501 break;
19502 }
19503 tcg_temp_free(t0);
19504 tcg_temp_free(rs_t);
19505}
19506
2ed42efa 19507
64224187
YK
19508static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19509{
64224187
YK
19510 int rt = extract32(ctx->opcode, 21, 5);
19511 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 19512 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
19513
19514 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
19515 case NM_POOL32AXF_1:
19516 {
19517 int32_t op1 = extract32(ctx->opcode, 9, 3);
19518 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19519 }
19520 break;
19521 case NM_POOL32AXF_2:
8b3698b2
SM
19522 {
19523 int32_t op1 = extract32(ctx->opcode, 12, 2);
19524 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19525 }
2ed42efa 19526 break;
64224187 19527 case NM_POOL32AXF_4:
4c75c985
SM
19528 {
19529 int32_t op1 = extract32(ctx->opcode, 9, 7);
19530 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19531 }
2ed42efa 19532 break;
64224187
YK
19533 case NM_POOL32AXF_5:
19534 switch (extract32(ctx->opcode, 9, 7)) {
19535#ifndef CONFIG_USER_ONLY
19536 case NM_TLBP:
19537 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19538 break;
19539 case NM_TLBR:
19540 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19541 break;
19542 case NM_TLBWI:
19543 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19544 break;
19545 case NM_TLBWR:
19546 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19547 break;
19548 case NM_TLBINV:
19549 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19550 break;
19551 case NM_TLBINVF:
19552 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19553 break;
19554 case NM_DI:
19555 check_cp0_enabled(ctx);
19556 {
19557 TCGv t0 = tcg_temp_new();
19558
19559 save_cpu_state(ctx, 1);
19560 gen_helper_di(t0, cpu_env);
19561 gen_store_gpr(t0, rt);
19562 /* Stop translation as we may have switched the execution mode */
19563 ctx->base.is_jmp = DISAS_STOP;
19564 tcg_temp_free(t0);
19565 }
19566 break;
19567 case NM_EI:
19568 check_cp0_enabled(ctx);
19569 {
19570 TCGv t0 = tcg_temp_new();
19571
19572 save_cpu_state(ctx, 1);
19573 gen_helper_ei(t0, cpu_env);
19574 gen_store_gpr(t0, rt);
19575 /* Stop translation as we may have switched the execution mode */
19576 ctx->base.is_jmp = DISAS_STOP;
19577 tcg_temp_free(t0);
19578 }
19579 break;
19580 case NM_RDPGPR:
19581 gen_load_srsgpr(rs, rt);
19582 break;
19583 case NM_WRPGPR:
19584 gen_store_srsgpr(rs, rt);
19585 break;
19586 case NM_WAIT:
19587 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19588 break;
19589 case NM_DERET:
19590 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19591 break;
19592 case NM_ERETX:
19593 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19594 break;
19595#endif
19596 default:
19597 generate_exception_end(ctx, EXCP_RI);
19598 break;
19599 }
19600 break;
2ed42efa 19601 case NM_POOL32AXF_7:
0b591184
SM
19602 {
19603 int32_t op1 = extract32(ctx->opcode, 9, 3);
19604 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19605 }
2ed42efa 19606 break;
64224187
YK
19607 default:
19608 generate_exception_end(ctx, EXCP_RI);
19609 break;
19610 }
19611}
19612
11d0fc10
SM
19613/* Immediate Value Compact Branches */
19614static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19615 int rt, int32_t imm, int32_t offset)
19616{
19617 TCGCond cond;
19618 int bcond_compute = 0;
19619 TCGv t0 = tcg_temp_new();
19620 TCGv t1 = tcg_temp_new();
19621
19622 gen_load_gpr(t0, rt);
19623 tcg_gen_movi_tl(t1, imm);
19624 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19625
19626 /* Load needed operands and calculate btarget */
19627 switch (opc) {
19628 case NM_BEQIC:
19629 if (rt == 0 && imm == 0) {
19630 /* Unconditional branch */
19631 } else if (rt == 0 && imm != 0) {
19632 /* Treat as NOP */
19633 goto out;
19634 } else {
19635 bcond_compute = 1;
19636 cond = TCG_COND_EQ;
19637 }
19638 break;
19639 case NM_BBEQZC:
19640 case NM_BBNEZC:
fb32f8c8 19641 check_nms(ctx);
11d0fc10
SM
19642 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19643 generate_exception_end(ctx, EXCP_RI);
19644 goto out;
19645 } else if (rt == 0 && opc == NM_BBEQZC) {
19646 /* Unconditional branch */
19647 } else if (rt == 0 && opc == NM_BBNEZC) {
19648 /* Treat as NOP */
19649 goto out;
19650 } else {
19651 tcg_gen_shri_tl(t0, t0, imm);
19652 tcg_gen_andi_tl(t0, t0, 1);
19653 tcg_gen_movi_tl(t1, 0);
19654 bcond_compute = 1;
19655 if (opc == NM_BBEQZC) {
19656 cond = TCG_COND_EQ;
19657 } else {
19658 cond = TCG_COND_NE;
19659 }
19660 }
19661 break;
19662 case NM_BNEIC:
19663 if (rt == 0 && imm == 0) {
19664 /* Treat as NOP */
19665 goto out;
19666 } else if (rt == 0 && imm != 0) {
19667 /* Unconditional branch */
19668 } else {
19669 bcond_compute = 1;
19670 cond = TCG_COND_NE;
19671 }
19672 break;
19673 case NM_BGEIC:
19674 if (rt == 0 && imm == 0) {
19675 /* Unconditional branch */
19676 } else {
19677 bcond_compute = 1;
19678 cond = TCG_COND_GE;
19679 }
19680 break;
19681 case NM_BLTIC:
19682 bcond_compute = 1;
19683 cond = TCG_COND_LT;
19684 break;
19685 case NM_BGEIUC:
19686 if (rt == 0 && imm == 0) {
19687 /* Unconditional branch */
19688 } else {
19689 bcond_compute = 1;
19690 cond = TCG_COND_GEU;
19691 }
19692 break;
19693 case NM_BLTIUC:
19694 bcond_compute = 1;
19695 cond = TCG_COND_LTU;
19696 break;
19697 default:
19698 MIPS_INVAL("Immediate Value Compact branch");
19699 generate_exception_end(ctx, EXCP_RI);
19700 goto out;
19701 }
19702
19703 if (bcond_compute == 0) {
19704 /* Uncoditional compact branch */
19705 gen_goto_tb(ctx, 0, ctx->btarget);
19706 } else {
19707 /* Conditional compact branch */
19708 TCGLabel *fs = gen_new_label();
19709
19710 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19711
19712 gen_goto_tb(ctx, 1, ctx->btarget);
19713 gen_set_label(fs);
19714
19715 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19716 }
19717
19718out:
19719 tcg_temp_free(t0);
19720 tcg_temp_free(t1);
19721}
19722
19723/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19724static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19725 int rt)
19726{
19727 TCGv t0 = tcg_temp_new();
19728 TCGv t1 = tcg_temp_new();
19729
19730 /* load rs */
19731 gen_load_gpr(t0, rs);
19732
19733 /* link */
19734 if (rt != 0) {
19735 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19736 }
19737
19738 /* calculate btarget */
19739 tcg_gen_shli_tl(t0, t0, 1);
19740 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19741 gen_op_addr_add(ctx, btarget, t1, t0);
19742
19743 /* unconditional branch to register */
19744 tcg_gen_mov_tl(cpu_PC, btarget);
19745 tcg_gen_lookup_and_goto_ptr();
19746
19747 tcg_temp_free(t0);
19748 tcg_temp_free(t1);
19749}
19750
19751/* nanoMIPS Branches */
19752static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19753 int rs, int rt, int32_t offset)
19754{
19755 int bcond_compute = 0;
19756 TCGv t0 = tcg_temp_new();
19757 TCGv t1 = tcg_temp_new();
19758
19759 /* Load needed operands and calculate btarget */
19760 switch (opc) {
19761 /* compact branch */
19762 case OPC_BGEC:
19763 case OPC_BLTC:
19764 gen_load_gpr(t0, rs);
19765 gen_load_gpr(t1, rt);
19766 bcond_compute = 1;
19767 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19768 break;
19769 case OPC_BGEUC:
19770 case OPC_BLTUC:
19771 if (rs == 0 || rs == rt) {
19772 /* OPC_BLEZALC, OPC_BGEZALC */
19773 /* OPC_BGTZALC, OPC_BLTZALC */
19774 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19775 }
19776 gen_load_gpr(t0, rs);
19777 gen_load_gpr(t1, rt);
19778 bcond_compute = 1;
19779 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19780 break;
19781 case OPC_BC:
19782 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19783 break;
19784 case OPC_BEQZC:
19785 if (rs != 0) {
19786 /* OPC_BEQZC, OPC_BNEZC */
19787 gen_load_gpr(t0, rs);
19788 bcond_compute = 1;
19789 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19790 } else {
19791 /* OPC_JIC, OPC_JIALC */
19792 TCGv tbase = tcg_temp_new();
19793 TCGv toffset = tcg_temp_new();
19794
19795 gen_load_gpr(tbase, rt);
19796 tcg_gen_movi_tl(toffset, offset);
19797 gen_op_addr_add(ctx, btarget, tbase, toffset);
19798 tcg_temp_free(tbase);
19799 tcg_temp_free(toffset);
19800 }
19801 break;
19802 default:
19803 MIPS_INVAL("Compact branch/jump");
19804 generate_exception_end(ctx, EXCP_RI);
19805 goto out;
19806 }
19807
19808 if (bcond_compute == 0) {
19809 /* Uncoditional compact branch */
19810 switch (opc) {
19811 case OPC_BC:
19812 gen_goto_tb(ctx, 0, ctx->btarget);
19813 break;
19814 default:
19815 MIPS_INVAL("Compact branch/jump");
19816 generate_exception_end(ctx, EXCP_RI);
19817 goto out;
19818 }
19819 } else {
19820 /* Conditional compact branch */
19821 TCGLabel *fs = gen_new_label();
19822
19823 switch (opc) {
19824 case OPC_BGEUC:
19825 if (rs == 0 && rt != 0) {
19826 /* OPC_BLEZALC */
19827 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19828 } else if (rs != 0 && rt != 0 && rs == rt) {
19829 /* OPC_BGEZALC */
19830 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19831 } else {
19832 /* OPC_BGEUC */
19833 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19834 }
19835 break;
19836 case OPC_BLTUC:
19837 if (rs == 0 && rt != 0) {
19838 /* OPC_BGTZALC */
19839 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19840 } else if (rs != 0 && rt != 0 && rs == rt) {
19841 /* OPC_BLTZALC */
19842 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19843 } else {
19844 /* OPC_BLTUC */
19845 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19846 }
19847 break;
19848 case OPC_BGEC:
19849 if (rs == 0 && rt != 0) {
19850 /* OPC_BLEZC */
19851 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19852 } else if (rs != 0 && rt != 0 && rs == rt) {
19853 /* OPC_BGEZC */
19854 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19855 } else {
19856 /* OPC_BGEC */
19857 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19858 }
19859 break;
19860 case OPC_BLTC:
19861 if (rs == 0 && rt != 0) {
19862 /* OPC_BGTZC */
19863 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19864 } else if (rs != 0 && rt != 0 && rs == rt) {
19865 /* OPC_BLTZC */
19866 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19867 } else {
19868 /* OPC_BLTC */
19869 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19870 }
19871 break;
19872 case OPC_BEQZC:
19873 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19874 break;
19875 default:
19876 MIPS_INVAL("Compact conditional branch/jump");
19877 generate_exception_end(ctx, EXCP_RI);
19878 goto out;
19879 }
19880
19881 /* Generating branch here as compact branches don't have delay slot */
19882 gen_goto_tb(ctx, 1, ctx->btarget);
19883 gen_set_label(fs);
19884
19885 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19886 }
19887
19888out:
19889 tcg_temp_free(t0);
19890 tcg_temp_free(t1);
19891}
19892
19893
19894/* nanoMIPS CP1 Branches */
19895static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19896 int32_t ft, int32_t offset)
19897{
19898 target_ulong btarget;
19899 TCGv_i64 t0 = tcg_temp_new_i64();
19900
19901 gen_load_fpr64(ctx, t0, ft);
19902 tcg_gen_andi_i64(t0, t0, 1);
19903
19904 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19905
19906 switch (op) {
19907 case NM_BC1EQZC:
19908 tcg_gen_xori_i64(t0, t0, 1);
19909 ctx->hflags |= MIPS_HFLAG_BC;
19910 break;
19911 case NM_BC1NEZC:
19912 /* t0 already set */
19913 ctx->hflags |= MIPS_HFLAG_BC;
19914 break;
19915 default:
19916 MIPS_INVAL("cp1 cond branch");
19917 generate_exception_end(ctx, EXCP_RI);
19918 goto out;
19919 }
19920
19921 tcg_gen_trunc_i64_tl(bcond, t0);
19922
19923 ctx->btarget = btarget;
19924
19925out:
19926 tcg_temp_free_i64(t0);
19927}
19928
eac52664
YK
19929
19930static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19931{
19932 TCGv t0, t1;
19933 t0 = tcg_temp_new();
19934 t1 = tcg_temp_new();
19935
19936 gen_load_gpr(t0, rs);
19937 gen_load_gpr(t1, rt);
19938
19939 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19940 /* PP.LSXS instructions require shifting */
19941 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 19942 case NM_SHXS:
fb32f8c8
DN
19943 check_nms(ctx);
19944 case NM_LHXS:
eac52664
YK
19945 case NM_LHUXS:
19946 tcg_gen_shli_tl(t0, t0, 1);
19947 break;
eac52664 19948 case NM_SWXS:
fb32f8c8
DN
19949 check_nms(ctx);
19950 case NM_LWXS:
eac52664
YK
19951 case NM_LWC1XS:
19952 case NM_SWC1XS:
19953 tcg_gen_shli_tl(t0, t0, 2);
19954 break;
19955 case NM_LDC1XS:
19956 case NM_SDC1XS:
19957 tcg_gen_shli_tl(t0, t0, 3);
19958 break;
19959 }
19960 }
19961 gen_op_addr_add(ctx, t0, t0, t1);
19962
19963 switch (extract32(ctx->opcode, 7, 4)) {
19964 case NM_LBX:
19965 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19966 MO_SB);
19967 gen_store_gpr(t0, rd);
19968 break;
19969 case NM_LHX:
19970 /*case NM_LHXS:*/
19971 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19972 MO_TESW);
19973 gen_store_gpr(t0, rd);
19974 break;
19975 case NM_LWX:
19976 /*case NM_LWXS:*/
19977 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19978 MO_TESL);
19979 gen_store_gpr(t0, rd);
19980 break;
19981 case NM_LBUX:
19982 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19983 MO_UB);
19984 gen_store_gpr(t0, rd);
19985 break;
19986 case NM_LHUX:
19987 /*case NM_LHUXS:*/
19988 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19989 MO_TEUW);
19990 gen_store_gpr(t0, rd);
19991 break;
19992 case NM_SBX:
fb32f8c8 19993 check_nms(ctx);
eac52664
YK
19994 gen_load_gpr(t1, rd);
19995 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19996 MO_8);
19997 break;
19998 case NM_SHX:
19999 /*case NM_SHXS:*/
fb32f8c8 20000 check_nms(ctx);
eac52664
YK
20001 gen_load_gpr(t1, rd);
20002 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20003 MO_TEUW);
20004 break;
20005 case NM_SWX:
20006 /*case NM_SWXS:*/
fb32f8c8 20007 check_nms(ctx);
eac52664
YK
20008 gen_load_gpr(t1, rd);
20009 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20010 MO_TEUL);
20011 break;
20012 case NM_LWC1X:
20013 /*case NM_LWC1XS:*/
20014 case NM_LDC1X:
20015 /*case NM_LDC1XS:*/
20016 case NM_SWC1X:
20017 /*case NM_SWC1XS:*/
20018 case NM_SDC1X:
20019 /*case NM_SDC1XS:*/
20020 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20021 check_cp1_enabled(ctx);
20022 switch (extract32(ctx->opcode, 7, 4)) {
20023 case NM_LWC1X:
20024 /*case NM_LWC1XS:*/
20025 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20026 break;
20027 case NM_LDC1X:
20028 /*case NM_LDC1XS:*/
20029 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20030 break;
20031 case NM_SWC1X:
20032 /*case NM_SWC1XS:*/
20033 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20034 break;
20035 case NM_SDC1X:
20036 /*case NM_SDC1XS:*/
20037 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20038 break;
20039 }
20040 } else {
20041 generate_exception_err(ctx, EXCP_CpU, 1);
20042 }
20043 break;
20044 default:
20045 generate_exception_end(ctx, EXCP_RI);
20046 break;
20047 }
20048
20049 tcg_temp_free(t0);
20050 tcg_temp_free(t1);
20051}
20052
579b8ea9
YK
20053static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20054{
20055 int rt, rs, rd;
20056
20057 rt = extract32(ctx->opcode, 21, 5);
20058 rs = extract32(ctx->opcode, 16, 5);
20059 rd = extract32(ctx->opcode, 11, 5);
20060
20061 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20062 generate_exception_end(ctx, EXCP_RI);
20063 return;
20064 }
20065 check_cp1_enabled(ctx);
20066 switch (extract32(ctx->opcode, 0, 3)) {
20067 case NM_POOL32F_0:
20068 switch (extract32(ctx->opcode, 3, 7)) {
20069 case NM_RINT_S:
20070 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20071 break;
20072 case NM_RINT_D:
20073 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20074 break;
20075 case NM_CLASS_S:
20076 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20077 break;
20078 case NM_CLASS_D:
20079 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20080 break;
20081 case NM_ADD_S:
20082 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20083 break;
20084 case NM_ADD_D:
20085 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20086 break;
20087 case NM_SUB_S:
20088 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20089 break;
20090 case NM_SUB_D:
20091 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20092 break;
20093 case NM_MUL_S:
20094 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20095 break;
20096 case NM_MUL_D:
20097 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20098 break;
20099 case NM_DIV_S:
20100 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20101 break;
20102 case NM_DIV_D:
20103 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20104 break;
20105 case NM_SELEQZ_S:
20106 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20107 break;
20108 case NM_SELEQZ_D:
20109 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20110 break;
20111 case NM_SELNEZ_S:
20112 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20113 break;
20114 case NM_SELNEZ_D:
20115 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20116 break;
20117 case NM_SEL_S:
20118 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20119 break;
20120 case NM_SEL_D:
20121 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20122 break;
20123 case NM_MADDF_S:
20124 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20125 break;
20126 case NM_MADDF_D:
20127 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20128 break;
20129 case NM_MSUBF_S:
20130 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20131 break;
20132 case NM_MSUBF_D:
20133 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20134 break;
20135 default:
20136 generate_exception_end(ctx, EXCP_RI);
20137 break;
20138 }
20139 break;
20140 case NM_POOL32F_3:
20141 switch (extract32(ctx->opcode, 3, 3)) {
20142 case NM_MIN_FMT:
20143 switch (extract32(ctx->opcode, 9, 1)) {
20144 case FMT_SDPS_S:
20145 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20146 break;
20147 case FMT_SDPS_D:
20148 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20149 break;
20150 }
20151 break;
20152 case NM_MAX_FMT:
20153 switch (extract32(ctx->opcode, 9, 1)) {
20154 case FMT_SDPS_S:
20155 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20156 break;
20157 case FMT_SDPS_D:
20158 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20159 break;
20160 }
20161 break;
20162 case NM_MINA_FMT:
20163 switch (extract32(ctx->opcode, 9, 1)) {
20164 case FMT_SDPS_S:
20165 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20166 break;
20167 case FMT_SDPS_D:
20168 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20169 break;
20170 }
20171 break;
20172 case NM_MAXA_FMT:
20173 switch (extract32(ctx->opcode, 9, 1)) {
20174 case FMT_SDPS_S:
20175 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20176 break;
20177 case FMT_SDPS_D:
20178 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20179 break;
20180 }
20181 break;
20182 case NM_POOL32FXF:
20183 switch (extract32(ctx->opcode, 6, 8)) {
20184 case NM_CFC1:
20185 gen_cp1(ctx, OPC_CFC1, rt, rs);
20186 break;
20187 case NM_CTC1:
20188 gen_cp1(ctx, OPC_CTC1, rt, rs);
20189 break;
20190 case NM_MFC1:
20191 gen_cp1(ctx, OPC_MFC1, rt, rs);
20192 break;
20193 case NM_MTC1:
20194 gen_cp1(ctx, OPC_MTC1, rt, rs);
20195 break;
20196 case NM_MFHC1:
20197 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20198 break;
20199 case NM_MTHC1:
20200 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20201 break;
20202 case NM_CVT_S_PL:
20203 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20204 break;
20205 case NM_CVT_S_PU:
20206 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20207 break;
20208 default:
20209 switch (extract32(ctx->opcode, 6, 9)) {
20210 case NM_CVT_L_S:
20211 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20212 break;
20213 case NM_CVT_L_D:
20214 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20215 break;
20216 case NM_CVT_W_S:
20217 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20218 break;
20219 case NM_CVT_W_D:
20220 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20221 break;
20222 case NM_RSQRT_S:
20223 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20224 break;
20225 case NM_RSQRT_D:
20226 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20227 break;
20228 case NM_SQRT_S:
20229 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20230 break;
20231 case NM_SQRT_D:
20232 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20233 break;
20234 case NM_RECIP_S:
20235 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20236 break;
20237 case NM_RECIP_D:
20238 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20239 break;
20240 case NM_FLOOR_L_S:
20241 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20242 break;
20243 case NM_FLOOR_L_D:
20244 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20245 break;
20246 case NM_FLOOR_W_S:
20247 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20248 break;
20249 case NM_FLOOR_W_D:
20250 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20251 break;
20252 case NM_CEIL_L_S:
20253 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20254 break;
20255 case NM_CEIL_L_D:
20256 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20257 break;
20258 case NM_CEIL_W_S:
20259 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20260 break;
20261 case NM_CEIL_W_D:
20262 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20263 break;
20264 case NM_TRUNC_L_S:
20265 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20266 break;
20267 case NM_TRUNC_L_D:
20268 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20269 break;
20270 case NM_TRUNC_W_S:
20271 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20272 break;
20273 case NM_TRUNC_W_D:
20274 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20275 break;
20276 case NM_ROUND_L_S:
20277 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20278 break;
20279 case NM_ROUND_L_D:
20280 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20281 break;
20282 case NM_ROUND_W_S:
20283 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20284 break;
20285 case NM_ROUND_W_D:
20286 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20287 break;
20288 case NM_MOV_S:
20289 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20290 break;
20291 case NM_MOV_D:
20292 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20293 break;
20294 case NM_ABS_S:
20295 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20296 break;
20297 case NM_ABS_D:
20298 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20299 break;
20300 case NM_NEG_S:
20301 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20302 break;
20303 case NM_NEG_D:
20304 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20305 break;
20306 case NM_CVT_D_S:
20307 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20308 break;
20309 case NM_CVT_D_W:
20310 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20311 break;
20312 case NM_CVT_D_L:
20313 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20314 break;
20315 case NM_CVT_S_D:
20316 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20317 break;
20318 case NM_CVT_S_W:
20319 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20320 break;
20321 case NM_CVT_S_L:
20322 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20323 break;
20324 default:
20325 generate_exception_end(ctx, EXCP_RI);
20326 break;
20327 }
20328 break;
20329 }
20330 break;
20331 }
20332 break;
20333 case NM_POOL32F_5:
20334 switch (extract32(ctx->opcode, 3, 3)) {
20335 case NM_CMP_CONDN_S:
20336 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20337 break;
20338 case NM_CMP_CONDN_D:
20339 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20340 break;
20341 default:
20342 generate_exception_end(ctx, EXCP_RI);
20343 break;
20344 }
20345 break;
20346 default:
20347 generate_exception_end(ctx, EXCP_RI);
20348 break;
20349 }
20350}
20351
3285a3e4
SM
20352static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20353 int rd, int rs, int rt)
20354{
20355 int ret = rd;
20356 TCGv t0 = tcg_temp_new();
20357 TCGv v1_t = tcg_temp_new();
20358 TCGv v2_t = tcg_temp_new();
20359
20360 gen_load_gpr(v1_t, rs);
20361 gen_load_gpr(v2_t, rt);
20362
20363 switch (opc) {
20364 case NM_CMP_EQ_PH:
20365 check_dsp(ctx);
20366 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20367 break;
20368 case NM_CMP_LT_PH:
20369 check_dsp(ctx);
20370 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20371 break;
20372 case NM_CMP_LE_PH:
20373 check_dsp(ctx);
20374 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20375 break;
20376 case NM_CMPU_EQ_QB:
20377 check_dsp(ctx);
20378 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20379 break;
20380 case NM_CMPU_LT_QB:
20381 check_dsp(ctx);
20382 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20383 break;
20384 case NM_CMPU_LE_QB:
20385 check_dsp(ctx);
20386 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20387 break;
20388 case NM_CMPGU_EQ_QB:
20389 check_dsp(ctx);
20390 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20391 gen_store_gpr(v1_t, ret);
20392 break;
20393 case NM_CMPGU_LT_QB:
20394 check_dsp(ctx);
20395 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20396 gen_store_gpr(v1_t, ret);
20397 break;
20398 case NM_CMPGU_LE_QB:
20399 check_dsp(ctx);
20400 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20401 gen_store_gpr(v1_t, ret);
20402 break;
20403 case NM_CMPGDU_EQ_QB:
908f6be1 20404 check_dsp_r2(ctx);
3285a3e4
SM
20405 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20406 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20407 gen_store_gpr(v1_t, ret);
20408 break;
20409 case NM_CMPGDU_LT_QB:
908f6be1 20410 check_dsp_r2(ctx);
3285a3e4
SM
20411 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20412 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20413 gen_store_gpr(v1_t, ret);
20414 break;
20415 case NM_CMPGDU_LE_QB:
908f6be1 20416 check_dsp_r2(ctx);
3285a3e4
SM
20417 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20418 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20419 gen_store_gpr(v1_t, ret);
20420 break;
20421 case NM_PACKRL_PH:
20422 check_dsp(ctx);
20423 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20424 gen_store_gpr(v1_t, ret);
20425 break;
20426 case NM_PICK_QB:
20427 check_dsp(ctx);
20428 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20429 gen_store_gpr(v1_t, ret);
20430 break;
20431 case NM_PICK_PH:
20432 check_dsp(ctx);
20433 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20434 gen_store_gpr(v1_t, ret);
20435 break;
20436 case NM_ADDQ_S_W:
20437 check_dsp(ctx);
20438 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20439 gen_store_gpr(v1_t, ret);
20440 break;
20441 case NM_SUBQ_S_W:
20442 check_dsp(ctx);
20443 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20444 gen_store_gpr(v1_t, ret);
20445 break;
20446 case NM_ADDSC:
20447 check_dsp(ctx);
20448 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20449 gen_store_gpr(v1_t, ret);
20450 break;
20451 case NM_ADDWC:
20452 check_dsp(ctx);
20453 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20454 gen_store_gpr(v1_t, ret);
20455 break;
20456 case NM_ADDQ_S_PH:
20457 check_dsp(ctx);
20458 switch (extract32(ctx->opcode, 10, 1)) {
20459 case 0:
20460 /* ADDQ_PH */
20461 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20462 gen_store_gpr(v1_t, ret);
20463 break;
20464 case 1:
20465 /* ADDQ_S_PH */
20466 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20467 gen_store_gpr(v1_t, ret);
20468 break;
20469 }
20470 break;
20471 case NM_ADDQH_R_PH:
908f6be1 20472 check_dsp_r2(ctx);
3285a3e4
SM
20473 switch (extract32(ctx->opcode, 10, 1)) {
20474 case 0:
20475 /* ADDQH_PH */
20476 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20477 gen_store_gpr(v1_t, ret);
20478 break;
20479 case 1:
20480 /* ADDQH_R_PH */
20481 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20482 gen_store_gpr(v1_t, ret);
20483 break;
20484 }
20485 break;
20486 case NM_ADDQH_R_W:
908f6be1 20487 check_dsp_r2(ctx);
3285a3e4
SM
20488 switch (extract32(ctx->opcode, 10, 1)) {
20489 case 0:
20490 /* ADDQH_W */
20491 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20492 gen_store_gpr(v1_t, ret);
20493 break;
20494 case 1:
20495 /* ADDQH_R_W */
20496 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20497 gen_store_gpr(v1_t, ret);
20498 break;
20499 }
20500 break;
20501 case NM_ADDU_S_QB:
20502 check_dsp(ctx);
20503 switch (extract32(ctx->opcode, 10, 1)) {
20504 case 0:
20505 /* ADDU_QB */
20506 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20507 gen_store_gpr(v1_t, ret);
20508 break;
20509 case 1:
20510 /* ADDU_S_QB */
20511 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20512 gen_store_gpr(v1_t, ret);
20513 break;
20514 }
20515 break;
20516 case NM_ADDU_S_PH:
908f6be1 20517 check_dsp_r2(ctx);
3285a3e4
SM
20518 switch (extract32(ctx->opcode, 10, 1)) {
20519 case 0:
20520 /* ADDU_PH */
20521 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20522 gen_store_gpr(v1_t, ret);
20523 break;
20524 case 1:
20525 /* ADDU_S_PH */
20526 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20527 gen_store_gpr(v1_t, ret);
20528 break;
20529 }
20530 break;
20531 case NM_ADDUH_R_QB:
908f6be1 20532 check_dsp_r2(ctx);
3285a3e4
SM
20533 switch (extract32(ctx->opcode, 10, 1)) {
20534 case 0:
20535 /* ADDUH_QB */
20536 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20537 gen_store_gpr(v1_t, ret);
20538 break;
20539 case 1:
20540 /* ADDUH_R_QB */
20541 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20542 gen_store_gpr(v1_t, ret);
20543 break;
20544 }
20545 break;
20546 case NM_SHRAV_R_PH:
20547 check_dsp(ctx);
20548 switch (extract32(ctx->opcode, 10, 1)) {
20549 case 0:
20550 /* SHRAV_PH */
20551 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20552 gen_store_gpr(v1_t, ret);
20553 break;
20554 case 1:
20555 /* SHRAV_R_PH */
20556 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20557 gen_store_gpr(v1_t, ret);
20558 break;
20559 }
20560 break;
20561 case NM_SHRAV_R_QB:
908f6be1 20562 check_dsp_r2(ctx);
3285a3e4
SM
20563 switch (extract32(ctx->opcode, 10, 1)) {
20564 case 0:
20565 /* SHRAV_QB */
20566 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20567 gen_store_gpr(v1_t, ret);
20568 break;
20569 case 1:
20570 /* SHRAV_R_QB */
20571 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20572 gen_store_gpr(v1_t, ret);
20573 break;
20574 }
20575 break;
20576 case NM_SUBQ_S_PH:
20577 check_dsp(ctx);
20578 switch (extract32(ctx->opcode, 10, 1)) {
20579 case 0:
20580 /* SUBQ_PH */
20581 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20582 gen_store_gpr(v1_t, ret);
20583 break;
20584 case 1:
20585 /* SUBQ_S_PH */
20586 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20587 gen_store_gpr(v1_t, ret);
20588 break;
20589 }
20590 break;
20591 case NM_SUBQH_R_PH:
908f6be1 20592 check_dsp_r2(ctx);
3285a3e4
SM
20593 switch (extract32(ctx->opcode, 10, 1)) {
20594 case 0:
20595 /* SUBQH_PH */
20596 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20597 gen_store_gpr(v1_t, ret);
20598 break;
20599 case 1:
20600 /* SUBQH_R_PH */
20601 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20602 gen_store_gpr(v1_t, ret);
20603 break;
20604 }
20605 break;
20606 case NM_SUBQH_R_W:
908f6be1 20607 check_dsp_r2(ctx);
3285a3e4
SM
20608 switch (extract32(ctx->opcode, 10, 1)) {
20609 case 0:
20610 /* SUBQH_W */
20611 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20612 gen_store_gpr(v1_t, ret);
20613 break;
20614 case 1:
20615 /* SUBQH_R_W */
20616 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20617 gen_store_gpr(v1_t, ret);
20618 break;
20619 }
20620 break;
20621 case NM_SUBU_S_QB:
20622 check_dsp(ctx);
20623 switch (extract32(ctx->opcode, 10, 1)) {
20624 case 0:
20625 /* SUBU_QB */
20626 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20627 gen_store_gpr(v1_t, ret);
20628 break;
20629 case 1:
20630 /* SUBU_S_QB */
20631 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20632 gen_store_gpr(v1_t, ret);
20633 break;
20634 }
20635 break;
20636 case NM_SUBU_S_PH:
908f6be1 20637 check_dsp_r2(ctx);
3285a3e4
SM
20638 switch (extract32(ctx->opcode, 10, 1)) {
20639 case 0:
20640 /* SUBU_PH */
20641 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20642 gen_store_gpr(v1_t, ret);
20643 break;
20644 case 1:
20645 /* SUBU_S_PH */
20646 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20647 gen_store_gpr(v1_t, ret);
20648 break;
20649 }
20650 break;
20651 case NM_SUBUH_R_QB:
908f6be1 20652 check_dsp_r2(ctx);
3285a3e4
SM
20653 switch (extract32(ctx->opcode, 10, 1)) {
20654 case 0:
20655 /* SUBUH_QB */
20656 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20657 gen_store_gpr(v1_t, ret);
20658 break;
20659 case 1:
20660 /* SUBUH_R_QB */
20661 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20662 gen_store_gpr(v1_t, ret);
20663 break;
20664 }
20665 break;
20666 case NM_SHLLV_S_PH:
20667 check_dsp(ctx);
20668 switch (extract32(ctx->opcode, 10, 1)) {
20669 case 0:
20670 /* SHLLV_PH */
20671 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20672 gen_store_gpr(v1_t, ret);
20673 break;
20674 case 1:
20675 /* SHLLV_S_PH */
20676 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20677 gen_store_gpr(v1_t, ret);
20678 break;
20679 }
20680 break;
20681 case NM_PRECR_SRA_R_PH_W:
908f6be1 20682 check_dsp_r2(ctx);
3285a3e4
SM
20683 switch (extract32(ctx->opcode, 10, 1)) {
20684 case 0:
20685 /* PRECR_SRA_PH_W */
20686 {
20687 TCGv_i32 sa_t = tcg_const_i32(rd);
20688 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20689 cpu_gpr[rt]);
20690 gen_store_gpr(v1_t, rt);
20691 tcg_temp_free_i32(sa_t);
20692 }
20693 break;
20694 case 1:
20695 /* PRECR_SRA_R_PH_W */
20696 {
20697 TCGv_i32 sa_t = tcg_const_i32(rd);
20698 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20699 cpu_gpr[rt]);
20700 gen_store_gpr(v1_t, rt);
20701 tcg_temp_free_i32(sa_t);
20702 }
20703 break;
20704 }
20705 break;
20706 case NM_MULEU_S_PH_QBL:
20707 check_dsp(ctx);
20708 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20709 gen_store_gpr(v1_t, ret);
20710 break;
20711 case NM_MULEU_S_PH_QBR:
20712 check_dsp(ctx);
20713 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20714 gen_store_gpr(v1_t, ret);
20715 break;
20716 case NM_MULQ_RS_PH:
20717 check_dsp(ctx);
20718 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20719 gen_store_gpr(v1_t, ret);
20720 break;
20721 case NM_MULQ_S_PH:
908f6be1 20722 check_dsp_r2(ctx);
3285a3e4
SM
20723 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20724 gen_store_gpr(v1_t, ret);
20725 break;
20726 case NM_MULQ_RS_W:
908f6be1 20727 check_dsp_r2(ctx);
3285a3e4
SM
20728 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20729 gen_store_gpr(v1_t, ret);
20730 break;
20731 case NM_MULQ_S_W:
908f6be1 20732 check_dsp_r2(ctx);
3285a3e4
SM
20733 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20734 gen_store_gpr(v1_t, ret);
20735 break;
20736 case NM_APPEND:
908f6be1 20737 check_dsp_r2(ctx);
3285a3e4
SM
20738 gen_load_gpr(t0, rs);
20739 if (rd != 0) {
20740 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20741 }
20742 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20743 break;
20744 case NM_MODSUB:
20745 check_dsp(ctx);
20746 gen_helper_modsub(v1_t, v1_t, v2_t);
20747 gen_store_gpr(v1_t, ret);
20748 break;
20749 case NM_SHRAV_R_W:
20750 check_dsp(ctx);
20751 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20752 gen_store_gpr(v1_t, ret);
20753 break;
20754 case NM_SHRLV_PH:
908f6be1 20755 check_dsp_r2(ctx);
3285a3e4
SM
20756 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20757 gen_store_gpr(v1_t, ret);
20758 break;
20759 case NM_SHRLV_QB:
20760 check_dsp(ctx);
20761 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20762 gen_store_gpr(v1_t, ret);
20763 break;
20764 case NM_SHLLV_QB:
20765 check_dsp(ctx);
20766 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20767 gen_store_gpr(v1_t, ret);
20768 break;
20769 case NM_SHLLV_S_W:
20770 check_dsp(ctx);
20771 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20772 gen_store_gpr(v1_t, ret);
20773 break;
20774 case NM_SHILO:
20775 check_dsp(ctx);
20776 {
20777 TCGv tv0 = tcg_temp_new();
20778 TCGv tv1 = tcg_temp_new();
20779 int16_t imm = extract32(ctx->opcode, 16, 7);
20780
20781 tcg_gen_movi_tl(tv0, rd >> 3);
20782 tcg_gen_movi_tl(tv1, imm);
20783 gen_helper_shilo(tv0, tv1, cpu_env);
20784 }
20785 break;
20786 case NM_MULEQ_S_W_PHL:
20787 check_dsp(ctx);
20788 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20789 gen_store_gpr(v1_t, ret);
20790 break;
20791 case NM_MULEQ_S_W_PHR:
20792 check_dsp(ctx);
20793 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20794 gen_store_gpr(v1_t, ret);
20795 break;
20796 case NM_MUL_S_PH:
908f6be1 20797 check_dsp_r2(ctx);
3285a3e4
SM
20798 switch (extract32(ctx->opcode, 10, 1)) {
20799 case 0:
20800 /* MUL_PH */
20801 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20802 gen_store_gpr(v1_t, ret);
20803 break;
20804 case 1:
20805 /* MUL_S_PH */
20806 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20807 gen_store_gpr(v1_t, ret);
20808 break;
20809 }
20810 break;
20811 case NM_PRECR_QB_PH:
908f6be1 20812 check_dsp_r2(ctx);
3285a3e4
SM
20813 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20814 gen_store_gpr(v1_t, ret);
20815 break;
20816 case NM_PRECRQ_QB_PH:
20817 check_dsp(ctx);
20818 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20819 gen_store_gpr(v1_t, ret);
20820 break;
20821 case NM_PRECRQ_PH_W:
20822 check_dsp(ctx);
20823 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20824 gen_store_gpr(v1_t, ret);
20825 break;
20826 case NM_PRECRQ_RS_PH_W:
20827 check_dsp(ctx);
20828 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20829 gen_store_gpr(v1_t, ret);
20830 break;
20831 case NM_PRECRQU_S_QB_PH:
20832 check_dsp(ctx);
20833 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20834 gen_store_gpr(v1_t, ret);
20835 break;
20836 case NM_SHRA_R_W:
20837 check_dsp(ctx);
20838 tcg_gen_movi_tl(t0, rd);
20839 gen_helper_shra_r_w(v1_t, t0, v1_t);
20840 gen_store_gpr(v1_t, rt);
20841 break;
20842 case NM_SHRA_R_PH:
20843 check_dsp(ctx);
20844 tcg_gen_movi_tl(t0, rd >> 1);
20845 switch (extract32(ctx->opcode, 10, 1)) {
20846 case 0:
20847 /* SHRA_PH */
20848 gen_helper_shra_ph(v1_t, t0, v1_t);
3285a3e4 20849 gen_store_gpr(v1_t, rt);
d5ebcbaf 20850 break;
3285a3e4
SM
20851 case 1:
20852 /* SHRA_R_PH */
20853 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20854 gen_store_gpr(v1_t, rt);
20855 break;
20856 }
20857 break;
20858 case NM_SHLL_S_PH:
20859 check_dsp(ctx);
20860 tcg_gen_movi_tl(t0, rd >> 1);
20861 switch (extract32(ctx->opcode, 10, 2)) {
20862 case 0:
20863 /* SHLL_PH */
20864 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20865 gen_store_gpr(v1_t, rt);
20866 break;
20867 case 2:
20868 /* SHLL_S_PH */
20869 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20870 gen_store_gpr(v1_t, rt);
20871 break;
20872 default:
20873 generate_exception_end(ctx, EXCP_RI);
20874 break;
20875 }
20876 break;
20877 case NM_SHLL_S_W:
20878 check_dsp(ctx);
20879 tcg_gen_movi_tl(t0, rd);
20880 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20881 gen_store_gpr(v1_t, rt);
20882 break;
20883 case NM_REPL_PH:
20884 check_dsp(ctx);
20885 {
20886 int16_t imm;
20887 imm = sextract32(ctx->opcode, 11, 11);
20888 imm = (int16_t)(imm << 6) >> 6;
20889 if (rt != 0) {
20890 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20891 }
20892 }
20893 break;
20894 default:
20895 generate_exception_end(ctx, EXCP_RI);
20896 break;
20897 }
20898}
20899
c0280983
YK
20900static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20901{
20902 uint16_t insn;
20903 uint32_t op;
eac52664 20904 int rt, rs, rd;
c0280983
YK
20905 int offset;
20906 int imm;
20907
20908 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20909 ctx->opcode = (ctx->opcode << 16) | insn;
20910
20911 rt = extract32(ctx->opcode, 21, 5);
20912 rs = extract32(ctx->opcode, 16, 5);
eac52664 20913 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
20914
20915 op = extract32(ctx->opcode, 26, 6);
20916 switch (op) {
20917 case NM_P_ADDIU:
20918 if (rt == 0) {
20919 /* P.RI */
20920 switch (extract32(ctx->opcode, 19, 2)) {
20921 case NM_SIGRIE:
20922 default:
20923 generate_exception_end(ctx, EXCP_RI);
20924 break;
20925 case NM_P_SYSCALL:
20926 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20927 generate_exception_end(ctx, EXCP_SYSCALL);
20928 } else {
20929 generate_exception_end(ctx, EXCP_RI);
20930 }
20931 break;
20932 case NM_BREAK:
20933 generate_exception_end(ctx, EXCP_BREAK);
20934 break;
20935 case NM_SDBBP:
20936 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20937 gen_helper_do_semihosting(cpu_env);
20938 } else {
20939 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20940 generate_exception_end(ctx, EXCP_RI);
20941 } else {
20942 generate_exception_end(ctx, EXCP_DBp);
20943 }
20944 }
20945 break;
20946 }
20947 } else {
20948 /* NM_ADDIU */
20949 imm = extract32(ctx->opcode, 0, 16);
20950 if (rs != 0) {
20951 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20952 } else {
20953 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20954 }
20955 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20956 }
20957 break;
20958 case NM_ADDIUPC:
20959 if (rt != 0) {
20960 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20961 extract32(ctx->opcode, 1, 20) << 1;
20962 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20963 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20964 }
20965 break;
20966 case NM_POOL32A:
e0cf0e65
YK
20967 switch (ctx->opcode & 0x07) {
20968 case NM_POOL32A0:
0a1a6ed7 20969 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 20970 break;
3285a3e4
SM
20971 case NM_POOL32A5:
20972 {
20973 int32_t op1 = extract32(ctx->opcode, 3, 7);
20974 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20975 }
20976 break;
e0cf0e65 20977 case NM_POOL32A7:
64224187 20978 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
20979 case NM_P_LSX:
20980 gen_p_lsx(ctx, rd, rs, rt);
20981 break;
20982 case NM_LSA:
20983 /* In nanoMIPS, the shift field directly encodes the shift
20984 * amount, meaning that the supported shift values are in
20985 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20986 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20987 extract32(ctx->opcode, 9, 2) - 1);
20988 break;
821f2008
JH
20989 case NM_EXTW:
20990 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20991 break;
64224187
YK
20992 case NM_POOL32AXF:
20993 gen_pool32axf_nanomips_insn(env, ctx);
20994 break;
20995 default:
20996 generate_exception_end(ctx, EXCP_RI);
20997 break;
20998 }
e0cf0e65
YK
20999 break;
21000 default:
21001 generate_exception_end(ctx, EXCP_RI);
21002 break;
21003 }
c0280983
YK
21004 break;
21005 case NM_P_GP_W:
21006 switch (ctx->opcode & 0x03) {
21007 case NM_ADDIUGP_W:
21008 if (rt != 0) {
21009 offset = extract32(ctx->opcode, 0, 21);
21010 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21011 }
21012 break;
21013 case NM_LWGP:
21014 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21015 break;
21016 case NM_SWGP:
21017 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21018 break;
21019 default:
21020 generate_exception_end(ctx, EXCP_RI);
21021 break;
21022 }
21023 break;
21024 case NM_P48I:
7ef009b2
YK
21025 {
21026 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21027 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21028 switch (extract32(ctx->opcode, 16, 5)) {
21029 case NM_LI48:
fb32f8c8 21030 check_nms(ctx);
7ef009b2
YK
21031 if (rt != 0) {
21032 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21033 }
21034 break;
21035 case NM_ADDIU48:
fb32f8c8 21036 check_nms(ctx);
7ef009b2
YK
21037 if (rt != 0) {
21038 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21039 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21040 }
21041 break;
21042 case NM_ADDIUGP48:
fb32f8c8 21043 check_nms(ctx);
7ef009b2
YK
21044 if (rt != 0) {
21045 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21046 }
21047 break;
21048 case NM_ADDIUPC48:
fb32f8c8 21049 check_nms(ctx);
7ef009b2
YK
21050 if (rt != 0) {
21051 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21052 addr_off);
21053
21054 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21055 }
21056 break;
21057 case NM_LWPC48:
fb32f8c8 21058 check_nms(ctx);
7ef009b2
YK
21059 if (rt != 0) {
21060 TCGv t0;
21061 t0 = tcg_temp_new();
21062
21063 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21064 addr_off);
21065
21066 tcg_gen_movi_tl(t0, addr);
21067 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21068 tcg_temp_free(t0);
21069 }
21070 break;
21071 case NM_SWPC48:
fb32f8c8 21072 check_nms(ctx);
7ef009b2
YK
21073 {
21074 TCGv t0, t1;
21075 t0 = tcg_temp_new();
21076 t1 = tcg_temp_new();
21077
21078 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21079 addr_off);
21080
21081 tcg_gen_movi_tl(t0, addr);
21082 gen_load_gpr(t1, rt);
21083
21084 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21085
21086 tcg_temp_free(t0);
21087 tcg_temp_free(t1);
21088 }
21089 break;
21090 default:
21091 generate_exception_end(ctx, EXCP_RI);
21092 break;
21093 }
21094 return 6;
21095 }
c0280983
YK
21096 case NM_P_U12:
21097 switch (extract32(ctx->opcode, 12, 4)) {
21098 case NM_ORI:
21099 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21100 break;
21101 case NM_XORI:
21102 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21103 break;
21104 case NM_ANDI:
21105 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21106 break;
21107 case NM_P_SR:
21108 switch (extract32(ctx->opcode, 20, 1)) {
21109 case NM_PP_SR:
21110 switch (ctx->opcode & 3) {
21111 case NM_SAVE:
21112 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21113 extract32(ctx->opcode, 2, 1),
21114 extract32(ctx->opcode, 3, 9) << 3);
21115 break;
21116 case NM_RESTORE:
21117 case NM_RESTORE_JRC:
21118 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21119 extract32(ctx->opcode, 2, 1),
21120 extract32(ctx->opcode, 3, 9) << 3);
21121 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21122 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21123 }
21124 break;
21125 default:
21126 generate_exception_end(ctx, EXCP_RI);
21127 break;
21128 }
21129 break;
21130 case NM_P_SR_F:
21131 generate_exception_end(ctx, EXCP_RI);
21132 break;
21133 }
21134 break;
21135 case NM_SLTI:
21136 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21137 break;
21138 case NM_SLTIU:
21139 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21140 break;
21141 case NM_SEQI:
21142 {
21143 TCGv t0 = tcg_temp_new();
21144
21145 imm = extract32(ctx->opcode, 0, 12);
21146 gen_load_gpr(t0, rs);
21147 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21148 gen_store_gpr(t0, rt);
21149
21150 tcg_temp_free(t0);
21151 }
21152 break;
21153 case NM_ADDIUNEG:
21154 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21155 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21156 break;
21157 case NM_P_SHIFT:
21158 {
21159 int shift = extract32(ctx->opcode, 0, 5);
21160 switch (extract32(ctx->opcode, 5, 4)) {
21161 case NM_P_SLL:
21162 if (rt == 0 && shift == 0) {
21163 /* NOP */
21164 } else if (rt == 0 && shift == 3) {
21165 /* EHB - treat as NOP */
21166 } else if (rt == 0 && shift == 5) {
21167 /* PAUSE - treat as NOP */
21168 } else if (rt == 0 && shift == 6) {
21169 /* SYNC */
21170 gen_sync(extract32(ctx->opcode, 16, 5));
21171 } else {
21172 /* SLL */
21173 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21174 extract32(ctx->opcode, 0, 5));
21175 }
21176 break;
21177 case NM_SRL:
21178 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21179 extract32(ctx->opcode, 0, 5));
21180 break;
21181 case NM_SRA:
21182 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21183 extract32(ctx->opcode, 0, 5));
21184 break;
21185 case NM_ROTR:
21186 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21187 extract32(ctx->opcode, 0, 5));
21188 break;
21189 }
21190 }
21191 break;
21192 case NM_P_ROTX:
fb32f8c8 21193 check_nms(ctx);
e222f506
MF
21194 if (rt != 0) {
21195 TCGv t0 = tcg_temp_new();
21196 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21197 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21198 << 1);
21199 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21200
21201 gen_load_gpr(t0, rs);
21202 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21203 tcg_temp_free(t0);
21204
21205 tcg_temp_free_i32(shift);
21206 tcg_temp_free_i32(shiftx);
21207 tcg_temp_free_i32(stripe);
21208 }
c0280983
YK
21209 break;
21210 case NM_P_INS:
21211 switch (((ctx->opcode >> 10) & 2) |
21212 (extract32(ctx->opcode, 5, 1))) {
21213 case NM_INS:
fb32f8c8 21214 check_nms(ctx);
c0280983
YK
21215 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21216 extract32(ctx->opcode, 6, 5));
21217 break;
21218 default:
21219 generate_exception_end(ctx, EXCP_RI);
21220 break;
21221 }
21222 break;
21223 case NM_P_EXT:
21224 switch (((ctx->opcode >> 10) & 2) |
21225 (extract32(ctx->opcode, 5, 1))) {
21226 case NM_EXT:
fb32f8c8 21227 check_nms(ctx);
c0280983
YK
21228 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21229 extract32(ctx->opcode, 6, 5));
21230 break;
21231 default:
21232 generate_exception_end(ctx, EXCP_RI);
21233 break;
21234 }
21235 break;
21236 default:
21237 generate_exception_end(ctx, EXCP_RI);
21238 break;
21239 }
21240 break;
21241 case NM_POOL32F:
579b8ea9 21242 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
21243 break;
21244 case NM_POOL32S:
21245 break;
21246 case NM_P_LUI:
21247 switch (extract32(ctx->opcode, 1, 1)) {
21248 case NM_LUI:
21249 if (rt != 0) {
21250 tcg_gen_movi_tl(cpu_gpr[rt],
21251 sextract32(ctx->opcode, 0, 1) << 31 |
21252 extract32(ctx->opcode, 2, 10) << 21 |
21253 extract32(ctx->opcode, 12, 9) << 12);
21254 }
21255 break;
21256 case NM_ALUIPC:
21257 if (rt != 0) {
21258 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21259 extract32(ctx->opcode, 2, 10) << 21 |
21260 extract32(ctx->opcode, 12, 9) << 12;
21261 target_long addr;
21262 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21263 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21264 }
21265 break;
21266 }
21267 break;
21268 case NM_P_GP_BH:
8f1d9b6d
YK
21269 {
21270 uint32_t u = extract32(ctx->opcode, 0, 18);
21271
21272 switch (extract32(ctx->opcode, 18, 3)) {
21273 case NM_LBGP:
21274 gen_ld(ctx, OPC_LB, rt, 28, u);
21275 break;
21276 case NM_SBGP:
21277 gen_st(ctx, OPC_SB, rt, 28, u);
21278 break;
21279 case NM_LBUGP:
21280 gen_ld(ctx, OPC_LBU, rt, 28, u);
21281 break;
21282 case NM_ADDIUGP_B:
21283 if (rt != 0) {
21284 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21285 }
21286 break;
21287 case NM_P_GP_LH:
21288 u &= ~1;
21289 switch (ctx->opcode & 1) {
21290 case NM_LHGP:
21291 gen_ld(ctx, OPC_LH, rt, 28, u);
21292 break;
21293 case NM_LHUGP:
21294 gen_ld(ctx, OPC_LHU, rt, 28, u);
21295 break;
21296 }
21297 break;
21298 case NM_P_GP_SH:
21299 u &= ~1;
21300 switch (ctx->opcode & 1) {
21301 case NM_SHGP:
21302 gen_st(ctx, OPC_SH, rt, 28, u);
21303 break;
21304 default:
21305 generate_exception_end(ctx, EXCP_RI);
21306 break;
21307 }
21308 break;
21309 case NM_P_GP_CP1:
21310 u &= ~0x3;
21311 switch (ctx->opcode & 0x3) {
21312 case NM_LWC1GP:
21313 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21314 break;
21315 case NM_LDC1GP:
21316 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21317 break;
21318 case NM_SWC1GP:
21319 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21320 break;
21321 case NM_SDC1GP:
21322 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21323 break;
21324 }
21325 break;
21326 default:
21327 generate_exception_end(ctx, EXCP_RI);
21328 break;
21329 }
21330 }
c0280983
YK
21331 break;
21332 case NM_P_LS_U12:
8f1d9b6d
YK
21333 {
21334 uint32_t u = extract32(ctx->opcode, 0, 12);
21335
21336 switch (extract32(ctx->opcode, 12, 4)) {
21337 case NM_P_PREFU12:
21338 if (rt == 31) {
21339 /* SYNCI */
21340 /* Break the TB to be able to sync copied instructions
21341 immediately */
21342 ctx->base.is_jmp = DISAS_STOP;
21343 } else {
21344 /* PREF */
21345 /* Treat as NOP. */
21346 }
21347 break;
21348 case NM_LB:
21349 gen_ld(ctx, OPC_LB, rt, rs, u);
21350 break;
21351 case NM_LH:
21352 gen_ld(ctx, OPC_LH, rt, rs, u);
21353 break;
21354 case NM_LW:
21355 gen_ld(ctx, OPC_LW, rt, rs, u);
21356 break;
21357 case NM_LBU:
21358 gen_ld(ctx, OPC_LBU, rt, rs, u);
21359 break;
21360 case NM_LHU:
21361 gen_ld(ctx, OPC_LHU, rt, rs, u);
21362 break;
21363 case NM_SB:
21364 gen_st(ctx, OPC_SB, rt, rs, u);
21365 break;
21366 case NM_SH:
21367 gen_st(ctx, OPC_SH, rt, rs, u);
21368 break;
21369 case NM_SW:
21370 gen_st(ctx, OPC_SW, rt, rs, u);
21371 break;
21372 case NM_LWC1:
21373 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21374 break;
21375 case NM_LDC1:
21376 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21377 break;
21378 case NM_SWC1:
21379 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21380 break;
21381 case NM_SDC1:
21382 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21383 break;
21384 default:
21385 generate_exception_end(ctx, EXCP_RI);
21386 break;
21387 }
21388 }
c0280983
YK
21389 break;
21390 case NM_P_LS_S9:
8f1d9b6d
YK
21391 {
21392 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21393 extract32(ctx->opcode, 0, 8);
21394
21395 switch (extract32(ctx->opcode, 8, 3)) {
21396 case NM_P_LS_S0:
21397 switch (extract32(ctx->opcode, 11, 4)) {
21398 case NM_LBS9:
21399 gen_ld(ctx, OPC_LB, rt, rs, s);
21400 break;
21401 case NM_LHS9:
21402 gen_ld(ctx, OPC_LH, rt, rs, s);
21403 break;
21404 case NM_LWS9:
21405 gen_ld(ctx, OPC_LW, rt, rs, s);
21406 break;
21407 case NM_LBUS9:
21408 gen_ld(ctx, OPC_LBU, rt, rs, s);
21409 break;
21410 case NM_LHUS9:
21411 gen_ld(ctx, OPC_LHU, rt, rs, s);
21412 break;
21413 case NM_SBS9:
21414 gen_st(ctx, OPC_SB, rt, rs, s);
21415 break;
21416 case NM_SHS9:
21417 gen_st(ctx, OPC_SH, rt, rs, s);
21418 break;
21419 case NM_SWS9:
21420 gen_st(ctx, OPC_SW, rt, rs, s);
21421 break;
21422 case NM_LWC1S9:
21423 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21424 break;
21425 case NM_LDC1S9:
21426 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21427 break;
21428 case NM_SWC1S9:
21429 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21430 break;
21431 case NM_SDC1S9:
21432 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21433 break;
21434 case NM_P_PREFS9:
21435 if (rt == 31) {
21436 /* SYNCI */
21437 /* Break the TB to be able to sync copied instructions
21438 immediately */
21439 ctx->base.is_jmp = DISAS_STOP;
21440 } else {
21441 /* PREF */
21442 /* Treat as NOP. */
21443 }
21444 break;
21445 default:
21446 generate_exception_end(ctx, EXCP_RI);
21447 break;
21448 }
21449 break;
21450 case NM_P_LS_S1:
21451 switch (extract32(ctx->opcode, 11, 4)) {
21452 case NM_UALH:
21453 case NM_UASH:
fb32f8c8 21454 check_nms(ctx);
8f1d9b6d
YK
21455 {
21456 TCGv t0 = tcg_temp_new();
21457 TCGv t1 = tcg_temp_new();
21458
21459 gen_base_offset_addr(ctx, t0, rs, s);
21460
21461 switch (extract32(ctx->opcode, 11, 4)) {
21462 case NM_UALH:
21463 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21464 MO_UNALN);
21465 gen_store_gpr(t0, rt);
21466 break;
21467 case NM_UASH:
21468 gen_load_gpr(t1, rt);
21469 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21470 MO_UNALN);
21471 break;
21472 }
21473 tcg_temp_free(t0);
21474 tcg_temp_free(t1);
21475 }
21476 break;
21477 case NM_P_LL:
21478 switch (ctx->opcode & 0x03) {
21479 case NM_LL:
21480 gen_ld(ctx, OPC_LL, rt, rs, s);
21481 break;
21482 case NM_LLWP:
0b16dcd1
AR
21483 check_xnp(ctx);
21484 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21485 break;
21486 }
21487 break;
21488 case NM_P_SC:
21489 switch (ctx->opcode & 0x03) {
21490 case NM_SC:
21491 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21492 break;
21493 case NM_SCWP:
0b16dcd1
AR
21494 check_xnp(ctx);
21495 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21496 break;
21497 }
21498 break;
21499 case NM_CACHE:
21500 check_cp0_enabled(ctx);
21501 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21502 gen_cache_operation(ctx, rt, rs, s);
21503 }
21504 break;
21505 }
21506 break;
d046a9ea
DN
21507 case NM_P_LS_E0:
21508 switch (extract32(ctx->opcode, 11, 4)) {
21509 case NM_LBE:
21510 check_eva(ctx);
21511 check_cp0_enabled(ctx);
21512 gen_ld(ctx, OPC_LBE, rt, rs, s);
21513 break;
21514 case NM_SBE:
21515 check_eva(ctx);
21516 check_cp0_enabled(ctx);
21517 gen_st(ctx, OPC_SBE, rt, rs, s);
21518 break;
21519 case NM_LBUE:
21520 check_eva(ctx);
21521 check_cp0_enabled(ctx);
21522 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21523 break;
21524 case NM_P_PREFE:
21525 if (rt == 31) {
21526 /* case NM_SYNCIE */
21527 check_eva(ctx);
21528 check_cp0_enabled(ctx);
21529 /* Break the TB to be able to sync copied instructions
21530 immediately */
21531 ctx->base.is_jmp = DISAS_STOP;
21532 } else {
21533 /* case NM_PREFE */
21534 check_eva(ctx);
21535 check_cp0_enabled(ctx);
21536 /* Treat as NOP. */
21537 }
21538 break;
21539 case NM_LHE:
21540 check_eva(ctx);
21541 check_cp0_enabled(ctx);
21542 gen_ld(ctx, OPC_LHE, rt, rs, s);
21543 break;
21544 case NM_SHE:
21545 check_eva(ctx);
21546 check_cp0_enabled(ctx);
21547 gen_st(ctx, OPC_SHE, rt, rs, s);
21548 break;
21549 case NM_LHUE:
21550 check_eva(ctx);
21551 check_cp0_enabled(ctx);
21552 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21553 break;
21554 case NM_CACHEE:
21555 check_nms_dl_il_sl_tl_l2c(ctx);
21556 gen_cache_operation(ctx, rt, rs, s);
21557 break;
21558 case NM_LWE:
21559 check_eva(ctx);
21560 check_cp0_enabled(ctx);
21561 gen_ld(ctx, OPC_LWE, rt, rs, s);
21562 break;
21563 case NM_SWE:
21564 check_eva(ctx);
21565 check_cp0_enabled(ctx);
21566 gen_st(ctx, OPC_SWE, rt, rs, s);
21567 break;
21568 case NM_P_LLE:
21569 switch (extract32(ctx->opcode, 2, 2)) {
21570 case NM_LLE:
21571 check_xnp(ctx);
21572 check_eva(ctx);
21573 check_cp0_enabled(ctx);
21574 gen_ld(ctx, OPC_LLE, rt, rs, s);
21575 break;
21576 case NM_LLWPE:
21577 check_xnp(ctx);
21578 check_eva(ctx);
21579 check_cp0_enabled(ctx);
21580 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21581 break;
d046a9ea
DN
21582 default:
21583 generate_exception_end(ctx, EXCP_RI);
21584 break;
21585 }
21586 break;
21587 case NM_P_SCE:
21588 switch (extract32(ctx->opcode, 2, 2)) {
21589 case NM_SCE:
21590 check_xnp(ctx);
21591 check_eva(ctx);
21592 check_cp0_enabled(ctx);
21593 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21594 break;
21595 case NM_SCWPE:
21596 check_xnp(ctx);
21597 check_eva(ctx);
21598 check_cp0_enabled(ctx);
21599 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21600 break;
d046a9ea
DN
21601 default:
21602 generate_exception_end(ctx, EXCP_RI);
21603 break;
21604 }
21605 break;
21606 }
21607 break;
8f1d9b6d
YK
21608 case NM_P_LS_WM:
21609 case NM_P_LS_UAWM:
fb32f8c8 21610 check_nms(ctx);
8f1d9b6d
YK
21611 {
21612 int count = extract32(ctx->opcode, 12, 3);
21613 int counter = 0;
21614
21615 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21616 extract32(ctx->opcode, 0, 8);
21617 TCGv va = tcg_temp_new();
21618 TCGv t1 = tcg_temp_new();
21619 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21620 NM_P_LS_UAWM ? MO_UNALN : 0;
21621
21622 count = (count == 0) ? 8 : count;
21623 while (counter != count) {
21624 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21625 int this_offset = offset + (counter << 2);
21626
21627 gen_base_offset_addr(ctx, va, rs, this_offset);
21628
21629 switch (extract32(ctx->opcode, 11, 1)) {
21630 case NM_LWM:
21631 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21632 memop | MO_TESL);
21633 gen_store_gpr(t1, this_rt);
21634 if ((this_rt == rs) &&
21635 (counter != (count - 1))) {
21636 /* UNPREDICTABLE */
21637 }
21638 break;
21639 case NM_SWM:
21640 this_rt = (rt == 0) ? 0 : this_rt;
21641 gen_load_gpr(t1, this_rt);
21642 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21643 memop | MO_TEUL);
21644 break;
21645 }
21646 counter++;
21647 }
21648 tcg_temp_free(va);
21649 tcg_temp_free(t1);
21650 }
21651 break;
21652 default:
21653 generate_exception_end(ctx, EXCP_RI);
21654 break;
21655 }
21656 }
c0280983
YK
21657 break;
21658 case NM_MOVE_BALC:
fb32f8c8 21659 check_nms(ctx);
11d0fc10
SM
21660 {
21661 TCGv t0 = tcg_temp_new();
21662 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21663 extract32(ctx->opcode, 1, 20) << 1;
21664 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21665 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21666 extract32(ctx->opcode, 21, 3));
21667 gen_load_gpr(t0, rt);
21668 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21669 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21670 tcg_temp_free(t0);
21671 }
c0280983
YK
21672 break;
21673 case NM_P_BAL:
11d0fc10
SM
21674 {
21675 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21676 extract32(ctx->opcode, 1, 24) << 1;
21677
21678 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21679 /* BC */
21680 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21681 } else {
21682 /* BALC */
21683 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21684 }
21685 }
c0280983
YK
21686 break;
21687 case NM_P_J:
11d0fc10
SM
21688 switch (extract32(ctx->opcode, 12, 4)) {
21689 case NM_JALRC:
21690 case NM_JALRC_HB:
21691 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21692 break;
21693 case NM_P_BALRSC:
21694 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21695 break;
21696 default:
21697 generate_exception_end(ctx, EXCP_RI);
21698 break;
21699 }
c0280983
YK
21700 break;
21701 case NM_P_BR1:
11d0fc10
SM
21702 {
21703 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21704 extract32(ctx->opcode, 1, 13) << 1;
21705 switch (extract32(ctx->opcode, 14, 2)) {
21706 case NM_BEQC:
fb32f8c8 21707 check_nms(ctx);
11d0fc10
SM
21708 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21709 break;
21710 case NM_P_BR3A:
21711 s = sextract32(ctx->opcode, 0, 1) << 14 |
21712 extract32(ctx->opcode, 1, 13) << 1;
21713 check_cp1_enabled(ctx);
21714 switch (extract32(ctx->opcode, 16, 5)) {
21715 case NM_BC1EQZC:
21716 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21717 break;
21718 case NM_BC1NEZC:
21719 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21720 break;
6d033ca7 21721 case NM_BPOSGE32C:
908f6be1 21722 check_dsp_r3(ctx);
6d033ca7
SM
21723 {
21724 int32_t imm = extract32(ctx->opcode, 1, 13) |
21725 extract32(ctx->opcode, 0, 1) << 13;
21726
21727 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21728 imm);
21729 }
21730 break;
11d0fc10
SM
21731 default:
21732 generate_exception_end(ctx, EXCP_RI);
21733 break;
21734 }
21735 break;
21736 case NM_BGEC:
21737 if (rs == rt) {
21738 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21739 } else {
21740 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21741 }
21742 break;
21743 case NM_BGEUC:
21744 if (rs == rt || rt == 0) {
21745 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21746 } else if (rs == 0) {
21747 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21748 } else {
21749 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21750 }
21751 break;
21752 }
21753 }
c0280983
YK
21754 break;
21755 case NM_P_BR2:
11d0fc10
SM
21756 {
21757 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21758 extract32(ctx->opcode, 1, 13) << 1;
21759 switch (extract32(ctx->opcode, 14, 2)) {
21760 case NM_BNEC:
fb32f8c8 21761 check_nms(ctx);
11d0fc10
SM
21762 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21763 break;
21764 case NM_BLTC:
21765 if (rs != 0 && rt != 0 && rs == rt) {
21766 /* NOP */
21767 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21768 } else {
21769 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21770 }
21771 break;
21772 case NM_BLTUC:
21773 if (rs == 0 || rs == rt) {
21774 /* NOP */
21775 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21776 } else {
21777 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21778 }
21779 break;
21780 default:
21781 generate_exception_end(ctx, EXCP_RI);
21782 break;
21783 }
21784 }
c0280983
YK
21785 break;
21786 case NM_P_BRI:
11d0fc10
SM
21787 {
21788 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21789 extract32(ctx->opcode, 1, 10) << 1;
21790 uint32_t u = extract32(ctx->opcode, 11, 7);
21791
21792 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21793 rt, u, s);
21794 }
c0280983
YK
21795 break;
21796 default:
21797 generate_exception_end(ctx, EXCP_RI);
21798 break;
21799 }
21800 return 4;
21801}
21802
c533c0f4
AM
21803static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21804{
ea4ca3c2
YK
21805 uint32_t op;
21806 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21807 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21808 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
8bdb7029 21809 int offset;
ea4ca3c2
YK
21810 int imm;
21811
21812 /* make sure instructions are on a halfword boundary */
21813 if (ctx->base.pc_next & 0x1) {
21814 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21815 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21816 tcg_temp_free(tmp);
21817 generate_exception_end(ctx, EXCP_AdEL);
21818 return 2;
21819 }
21820
21821 op = extract32(ctx->opcode, 10, 6);
21822 switch (op) {
21823 case NM_P16_MV:
8869ad02
YK
21824 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21825 if (rt != 0) {
21826 /* MOVE */
21827 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21828 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21829 } else {
21830 /* P16.RI */
21831 switch (extract32(ctx->opcode, 3, 2)) {
21832 case NM_P16_SYSCALL:
21833 if (extract32(ctx->opcode, 2, 1) == 0) {
21834 generate_exception_end(ctx, EXCP_SYSCALL);
21835 } else {
21836 generate_exception_end(ctx, EXCP_RI);
21837 }
21838 break;
21839 case NM_BREAK16:
21840 generate_exception_end(ctx, EXCP_BREAK);
21841 break;
21842 case NM_SDBBP16:
21843 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21844 gen_helper_do_semihosting(cpu_env);
21845 } else {
21846 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21847 generate_exception_end(ctx, EXCP_RI);
21848 } else {
21849 generate_exception_end(ctx, EXCP_DBp);
21850 }
21851 }
21852 break;
21853 default:
21854 generate_exception_end(ctx, EXCP_RI);
21855 break;
21856 }
21857 }
ea4ca3c2
YK
21858 break;
21859 case NM_P16_SHIFT:
c46562fb
YK
21860 {
21861 int shift = extract32(ctx->opcode, 0, 3);
21862 uint32_t opc = 0;
21863 shift = (shift == 0) ? 8 : shift;
21864
21865 switch (extract32(ctx->opcode, 3, 1)) {
21866 case NM_SLL16:
21867 opc = OPC_SLL;
21868 break;
21869 case NM_SRL16:
21870 opc = OPC_SRL;
21871 break;
21872 }
21873 gen_shift_imm(ctx, opc, rt, rs, shift);
21874 }
ea4ca3c2
YK
21875 break;
21876 case NM_P16C:
8bdb7029
YK
21877 switch (ctx->opcode & 1) {
21878 case NM_POOL16C_0:
80845edf 21879 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
21880 break;
21881 case NM_LWXS16:
21882 gen_ldxs(ctx, rt, rs, rd);
21883 break;
21884 }
ea4ca3c2
YK
21885 break;
21886 case NM_P16_A1:
21887 switch (extract32(ctx->opcode, 6, 1)) {
21888 case NM_ADDIUR1SP:
21889 imm = extract32(ctx->opcode, 0, 6) << 2;
21890 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21891 break;
21892 default:
21893 generate_exception_end(ctx, EXCP_RI);
21894 break;
21895 }
21896 break;
21897 case NM_P16_A2:
21898 switch (extract32(ctx->opcode, 3, 1)) {
21899 case NM_ADDIUR2:
21900 imm = extract32(ctx->opcode, 0, 3) << 2;
21901 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21902 break;
21903 case NM_P_ADDIURS5:
21904 rt = extract32(ctx->opcode, 5, 5);
21905 if (rt != 0) {
21906 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21907 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21908 (extract32(ctx->opcode, 0, 3));
21909 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21910 }
21911 break;
21912 }
21913 break;
21914 case NM_P16_ADDU:
21915 switch (ctx->opcode & 0x1) {
21916 case NM_ADDU16:
21917 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21918 break;
21919 case NM_SUBU16:
21920 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21921 break;
21922 }
21923 break;
21924 case NM_P16_4X4:
21925 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21926 extract32(ctx->opcode, 5, 3);
21927 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21928 extract32(ctx->opcode, 0, 3);
21929 rt = decode_gpr_gpr4(rt);
21930 rs = decode_gpr_gpr4(rs);
21931 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21932 (extract32(ctx->opcode, 3, 1))) {
21933 case NM_ADDU4X4:
fb32f8c8 21934 check_nms(ctx);
ea4ca3c2
YK
21935 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21936 break;
21937 case NM_MUL4X4:
fb32f8c8 21938 check_nms(ctx);
ea4ca3c2
YK
21939 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21940 break;
21941 default:
21942 generate_exception_end(ctx, EXCP_RI);
21943 break;
21944 }
21945 break;
21946 case NM_LI16:
8869ad02
YK
21947 {
21948 int imm = extract32(ctx->opcode, 0, 7);
21949 imm = (imm == 0x7f ? -1 : imm);
21950 if (rt != 0) {
21951 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21952 }
21953 }
ea4ca3c2
YK
21954 break;
21955 case NM_ANDI16:
80845edf
YK
21956 {
21957 uint32_t u = extract32(ctx->opcode, 0, 4);
21958 u = (u == 12) ? 0xff :
21959 (u == 13) ? 0xffff : u;
21960 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21961 }
ea4ca3c2
YK
21962 break;
21963 case NM_P16_LB:
8bdb7029
YK
21964 offset = extract32(ctx->opcode, 0, 2);
21965 switch (extract32(ctx->opcode, 2, 2)) {
21966 case NM_LB16:
21967 gen_ld(ctx, OPC_LB, rt, rs, offset);
21968 break;
21969 case NM_SB16:
21970 rt = decode_gpr_gpr3_src_store(
21971 NANOMIPS_EXTRACT_RD(ctx->opcode));
21972 gen_st(ctx, OPC_SB, rt, rs, offset);
21973 break;
21974 case NM_LBU16:
21975 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21976 break;
21977 default:
21978 generate_exception_end(ctx, EXCP_RI);
21979 break;
21980 }
ea4ca3c2
YK
21981 break;
21982 case NM_P16_LH:
8bdb7029
YK
21983 offset = extract32(ctx->opcode, 1, 2) << 1;
21984 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21985 case NM_LH16:
21986 gen_ld(ctx, OPC_LH, rt, rs, offset);
21987 break;
21988 case NM_SH16:
21989 rt = decode_gpr_gpr3_src_store(
21990 NANOMIPS_EXTRACT_RD(ctx->opcode));
21991 gen_st(ctx, OPC_SH, rt, rs, offset);
21992 break;
21993 case NM_LHU16:
21994 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21995 break;
21996 default:
21997 generate_exception_end(ctx, EXCP_RI);
21998 break;
21999 }
ea4ca3c2
YK
22000 break;
22001 case NM_LW16:
8bdb7029
YK
22002 offset = extract32(ctx->opcode, 0, 4) << 2;
22003 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
22004 break;
22005 case NM_LWSP16:
8bdb7029
YK
22006 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22007 offset = extract32(ctx->opcode, 0, 5) << 2;
22008 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
22009 break;
22010 case NM_LW4X4:
fb32f8c8 22011 check_nms(ctx);
8bdb7029
YK
22012 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22013 extract32(ctx->opcode, 5, 3);
22014 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22015 extract32(ctx->opcode, 0, 3);
22016 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22017 (extract32(ctx->opcode, 8, 1) << 2);
22018 rt = decode_gpr_gpr4(rt);
22019 rs = decode_gpr_gpr4(rs);
22020 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
22021 break;
22022 case NM_SW4X4:
fb32f8c8 22023 check_nms(ctx);
8bdb7029
YK
22024 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22025 extract32(ctx->opcode, 5, 3);
22026 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22027 extract32(ctx->opcode, 0, 3);
22028 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22029 (extract32(ctx->opcode, 8, 1) << 2);
22030 rt = decode_gpr_gpr4_zero(rt);
22031 rs = decode_gpr_gpr4(rs);
22032 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
22033 break;
22034 case NM_LWGP16:
8bdb7029
YK
22035 offset = extract32(ctx->opcode, 0, 7) << 2;
22036 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
22037 break;
22038 case NM_SWSP16:
8bdb7029
YK
22039 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22040 offset = extract32(ctx->opcode, 0, 5) << 2;
22041 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
22042 break;
22043 case NM_SW16:
8bdb7029
YK
22044 rt = decode_gpr_gpr3_src_store(
22045 NANOMIPS_EXTRACT_RD(ctx->opcode));
22046 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
22047 offset = extract32(ctx->opcode, 0, 4) << 2;
22048 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
22049 break;
22050 case NM_SWGP16:
8bdb7029
YK
22051 rt = decode_gpr_gpr3_src_store(
22052 NANOMIPS_EXTRACT_RD(ctx->opcode));
22053 offset = extract32(ctx->opcode, 0, 7) << 2;
22054 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
22055 break;
22056 case NM_BC16:
764371d2
SM
22057 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22058 (sextract32(ctx->opcode, 0, 1) << 10) |
22059 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
22060 break;
22061 case NM_BALC16:
764371d2
SM
22062 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22063 (sextract32(ctx->opcode, 0, 1) << 10) |
22064 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
22065 break;
22066 case NM_BEQZC16:
764371d2
SM
22067 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22068 (sextract32(ctx->opcode, 0, 1) << 7) |
22069 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
22070 break;
22071 case NM_BNEZC16:
764371d2
SM
22072 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22073 (sextract32(ctx->opcode, 0, 1) << 7) |
22074 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
22075 break;
22076 case NM_P16_BR:
764371d2
SM
22077 switch (ctx->opcode & 0xf) {
22078 case 0:
22079 /* P16.JRC */
22080 switch (extract32(ctx->opcode, 4, 1)) {
22081 case NM_JRC:
22082 gen_compute_branch_nm(ctx, OPC_JR, 2,
22083 extract32(ctx->opcode, 5, 5), 0, 0);
22084 break;
22085 case NM_JALRC16:
22086 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22087 extract32(ctx->opcode, 5, 5), 31, 0);
22088 break;
22089 }
22090 break;
22091 default:
22092 {
22093 /* P16.BRI */
22094 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22095 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22096 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22097 extract32(ctx->opcode, 0, 4) << 1);
22098 }
22099 break;
22100 }
ea4ca3c2
YK
22101 break;
22102 case NM_P16_SR:
bf0718c5
SM
22103 {
22104 int count = extract32(ctx->opcode, 0, 4);
22105 int u = extract32(ctx->opcode, 4, 4) << 4;
22106
22107 rt = 30 + extract32(ctx->opcode, 9, 1);
22108 switch (extract32(ctx->opcode, 8, 1)) {
22109 case NM_SAVE16:
22110 gen_save(ctx, rt, count, 0, u);
22111 break;
22112 case NM_RESTORE_JRC16:
22113 gen_restore(ctx, rt, count, 0, u);
22114 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22115 break;
22116 }
22117 }
ea4ca3c2
YK
22118 break;
22119 case NM_MOVEP:
ea4ca3c2 22120 case NM_MOVEPREV:
fb32f8c8 22121 check_nms(ctx);
4d18232c
YK
22122 {
22123 static const int gpr2reg1[] = {4, 5, 6, 7};
22124 static const int gpr2reg2[] = {5, 6, 7, 8};
22125 int re;
22126 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22127 extract32(ctx->opcode, 8, 1);
22128 int r1 = gpr2reg1[rd2];
22129 int r2 = gpr2reg2[rd2];
22130 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22131 extract32(ctx->opcode, 0, 3);
22132 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22133 extract32(ctx->opcode, 5, 3);
22134 TCGv t0 = tcg_temp_new();
22135 TCGv t1 = tcg_temp_new();
22136 if (op == NM_MOVEP) {
22137 rd = r1;
22138 re = r2;
22139 rs = decode_gpr_gpr4_zero(r3);
22140 rt = decode_gpr_gpr4_zero(r4);
22141 } else {
22142 rd = decode_gpr_gpr4(r3);
22143 re = decode_gpr_gpr4(r4);
22144 rs = r1;
22145 rt = r2;
22146 }
22147 gen_load_gpr(t0, rs);
22148 gen_load_gpr(t1, rt);
22149 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22150 tcg_gen_mov_tl(cpu_gpr[re], t1);
22151 tcg_temp_free(t0);
22152 tcg_temp_free(t1);
22153 }
ea4ca3c2
YK
22154 break;
22155 default:
c0280983 22156 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
22157 }
22158
c533c0f4
AM
22159 return 2;
22160}
22161
22162
3c824109
NF
22163/* SmartMIPS extension to MIPS32 */
22164
22165#if defined(TARGET_MIPS64)
22166
22167/* MDMX extension to MIPS64 */
22168
22169#endif
22170
9b1a1d68 22171/* MIPSDSP functions. */
d75c135e 22172static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
22173 int rd, int base, int offset)
22174{
9b1a1d68
JL
22175 TCGv t0;
22176
9b1a1d68
JL
22177 check_dsp(ctx);
22178 t0 = tcg_temp_new();
22179
22180 if (base == 0) {
22181 gen_load_gpr(t0, offset);
22182 } else if (offset == 0) {
22183 gen_load_gpr(t0, base);
22184 } else {
22185 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22186 }
22187
9b1a1d68
JL
22188 switch (opc) {
22189 case OPC_LBUX:
5f68f5ae 22190 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 22191 gen_store_gpr(t0, rd);
9b1a1d68
JL
22192 break;
22193 case OPC_LHX:
5f68f5ae 22194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 22195 gen_store_gpr(t0, rd);
9b1a1d68
JL
22196 break;
22197 case OPC_LWX:
5f68f5ae 22198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 22199 gen_store_gpr(t0, rd);
9b1a1d68
JL
22200 break;
22201#if defined(TARGET_MIPS64)
22202 case OPC_LDX:
5f68f5ae 22203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 22204 gen_store_gpr(t0, rd);
9b1a1d68
JL
22205 break;
22206#endif
22207 }
9b1a1d68
JL
22208 tcg_temp_free(t0);
22209}
22210
461c08df
JL
22211static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22212 int ret, int v1, int v2)
22213{
461c08df
JL
22214 TCGv v1_t;
22215 TCGv v2_t;
22216
22217 if (ret == 0) {
22218 /* Treat as NOP. */
461c08df
JL
22219 return;
22220 }
22221
22222 v1_t = tcg_temp_new();
22223 v2_t = tcg_temp_new();
22224
22225 gen_load_gpr(v1_t, v1);
22226 gen_load_gpr(v2_t, v2);
22227
22228 switch (op1) {
22229 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22230 case OPC_MULT_G_2E:
908f6be1 22231 check_dsp_r2(ctx);
461c08df
JL
22232 switch (op2) {
22233 case OPC_ADDUH_QB:
22234 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22235 break;
22236 case OPC_ADDUH_R_QB:
22237 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22238 break;
22239 case OPC_ADDQH_PH:
22240 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22241 break;
22242 case OPC_ADDQH_R_PH:
22243 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22244 break;
22245 case OPC_ADDQH_W:
22246 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22247 break;
22248 case OPC_ADDQH_R_W:
22249 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22250 break;
22251 case OPC_SUBUH_QB:
22252 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22253 break;
22254 case OPC_SUBUH_R_QB:
22255 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22256 break;
22257 case OPC_SUBQH_PH:
22258 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22259 break;
22260 case OPC_SUBQH_R_PH:
22261 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22262 break;
22263 case OPC_SUBQH_W:
22264 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22265 break;
22266 case OPC_SUBQH_R_W:
22267 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22268 break;
22269 }
22270 break;
22271 case OPC_ABSQ_S_PH_DSP:
22272 switch (op2) {
22273 case OPC_ABSQ_S_QB:
908f6be1 22274 check_dsp_r2(ctx);
461c08df
JL
22275 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22276 break;
22277 case OPC_ABSQ_S_PH:
22278 check_dsp(ctx);
22279 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22280 break;
22281 case OPC_ABSQ_S_W:
22282 check_dsp(ctx);
22283 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22284 break;
22285 case OPC_PRECEQ_W_PHL:
22286 check_dsp(ctx);
22287 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22288 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22289 break;
22290 case OPC_PRECEQ_W_PHR:
22291 check_dsp(ctx);
22292 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22293 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22294 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22295 break;
22296 case OPC_PRECEQU_PH_QBL:
22297 check_dsp(ctx);
22298 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22299 break;
22300 case OPC_PRECEQU_PH_QBR:
22301 check_dsp(ctx);
22302 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22303 break;
22304 case OPC_PRECEQU_PH_QBLA:
22305 check_dsp(ctx);
22306 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22307 break;
22308 case OPC_PRECEQU_PH_QBRA:
22309 check_dsp(ctx);
22310 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22311 break;
22312 case OPC_PRECEU_PH_QBL:
22313 check_dsp(ctx);
22314 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22315 break;
22316 case OPC_PRECEU_PH_QBR:
22317 check_dsp(ctx);
22318 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22319 break;
22320 case OPC_PRECEU_PH_QBLA:
22321 check_dsp(ctx);
22322 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22323 break;
22324 case OPC_PRECEU_PH_QBRA:
22325 check_dsp(ctx);
22326 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22327 break;
22328 }
22329 break;
22330 case OPC_ADDU_QB_DSP:
22331 switch (op2) {
22332 case OPC_ADDQ_PH:
22333 check_dsp(ctx);
22334 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22335 break;
22336 case OPC_ADDQ_S_PH:
22337 check_dsp(ctx);
22338 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22339 break;
22340 case OPC_ADDQ_S_W:
22341 check_dsp(ctx);
22342 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22343 break;
22344 case OPC_ADDU_QB:
22345 check_dsp(ctx);
22346 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22347 break;
22348 case OPC_ADDU_S_QB:
22349 check_dsp(ctx);
22350 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22351 break;
22352 case OPC_ADDU_PH:
908f6be1 22353 check_dsp_r2(ctx);
461c08df
JL
22354 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22355 break;
22356 case OPC_ADDU_S_PH:
908f6be1 22357 check_dsp_r2(ctx);
461c08df
JL
22358 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22359 break;
22360 case OPC_SUBQ_PH:
22361 check_dsp(ctx);
22362 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22363 break;
22364 case OPC_SUBQ_S_PH:
22365 check_dsp(ctx);
22366 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22367 break;
22368 case OPC_SUBQ_S_W:
22369 check_dsp(ctx);
22370 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22371 break;
22372 case OPC_SUBU_QB:
22373 check_dsp(ctx);
22374 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22375 break;
22376 case OPC_SUBU_S_QB:
22377 check_dsp(ctx);
22378 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22379 break;
22380 case OPC_SUBU_PH:
908f6be1 22381 check_dsp_r2(ctx);
461c08df
JL
22382 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22383 break;
22384 case OPC_SUBU_S_PH:
908f6be1 22385 check_dsp_r2(ctx);
461c08df
JL
22386 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22387 break;
22388 case OPC_ADDSC:
22389 check_dsp(ctx);
22390 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22391 break;
22392 case OPC_ADDWC:
22393 check_dsp(ctx);
22394 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22395 break;
22396 case OPC_MODSUB:
22397 check_dsp(ctx);
22398 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22399 break;
22400 case OPC_RADDU_W_QB:
22401 check_dsp(ctx);
22402 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22403 break;
22404 }
22405 break;
22406 case OPC_CMPU_EQ_QB_DSP:
22407 switch (op2) {
22408 case OPC_PRECR_QB_PH:
908f6be1 22409 check_dsp_r2(ctx);
461c08df
JL
22410 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22411 break;
22412 case OPC_PRECRQ_QB_PH:
22413 check_dsp(ctx);
22414 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22415 break;
22416 case OPC_PRECR_SRA_PH_W:
908f6be1 22417 check_dsp_r2(ctx);
461c08df
JL
22418 {
22419 TCGv_i32 sa_t = tcg_const_i32(v2);
22420 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22421 cpu_gpr[ret]);
22422 tcg_temp_free_i32(sa_t);
22423 break;
22424 }
22425 case OPC_PRECR_SRA_R_PH_W:
908f6be1 22426 check_dsp_r2(ctx);
461c08df
JL
22427 {
22428 TCGv_i32 sa_t = tcg_const_i32(v2);
22429 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22430 cpu_gpr[ret]);
22431 tcg_temp_free_i32(sa_t);
22432 break;
22433 }
22434 case OPC_PRECRQ_PH_W:
22435 check_dsp(ctx);
22436 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22437 break;
22438 case OPC_PRECRQ_RS_PH_W:
22439 check_dsp(ctx);
22440 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22441 break;
22442 case OPC_PRECRQU_S_QB_PH:
22443 check_dsp(ctx);
22444 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22445 break;
22446 }
22447 break;
22448#ifdef TARGET_MIPS64
22449 case OPC_ABSQ_S_QH_DSP:
22450 switch (op2) {
22451 case OPC_PRECEQ_L_PWL:
22452 check_dsp(ctx);
22453 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22454 break;
22455 case OPC_PRECEQ_L_PWR:
22456 check_dsp(ctx);
22457 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22458 break;
22459 case OPC_PRECEQ_PW_QHL:
22460 check_dsp(ctx);
22461 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22462 break;
22463 case OPC_PRECEQ_PW_QHR:
22464 check_dsp(ctx);
22465 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22466 break;
22467 case OPC_PRECEQ_PW_QHLA:
22468 check_dsp(ctx);
22469 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22470 break;
22471 case OPC_PRECEQ_PW_QHRA:
22472 check_dsp(ctx);
22473 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22474 break;
22475 case OPC_PRECEQU_QH_OBL:
22476 check_dsp(ctx);
22477 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22478 break;
22479 case OPC_PRECEQU_QH_OBR:
22480 check_dsp(ctx);
22481 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22482 break;
22483 case OPC_PRECEQU_QH_OBLA:
22484 check_dsp(ctx);
22485 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22486 break;
22487 case OPC_PRECEQU_QH_OBRA:
22488 check_dsp(ctx);
22489 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22490 break;
22491 case OPC_PRECEU_QH_OBL:
22492 check_dsp(ctx);
22493 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22494 break;
22495 case OPC_PRECEU_QH_OBR:
22496 check_dsp(ctx);
22497 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22498 break;
22499 case OPC_PRECEU_QH_OBLA:
22500 check_dsp(ctx);
22501 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22502 break;
22503 case OPC_PRECEU_QH_OBRA:
22504 check_dsp(ctx);
22505 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22506 break;
22507 case OPC_ABSQ_S_OB:
908f6be1 22508 check_dsp_r2(ctx);
461c08df
JL
22509 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22510 break;
22511 case OPC_ABSQ_S_PW:
22512 check_dsp(ctx);
22513 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22514 break;
22515 case OPC_ABSQ_S_QH:
22516 check_dsp(ctx);
22517 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22518 break;
22519 }
22520 break;
22521 case OPC_ADDU_OB_DSP:
22522 switch (op2) {
22523 case OPC_RADDU_L_OB:
22524 check_dsp(ctx);
22525 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22526 break;
22527 case OPC_SUBQ_PW:
22528 check_dsp(ctx);
22529 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22530 break;
22531 case OPC_SUBQ_S_PW:
22532 check_dsp(ctx);
22533 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22534 break;
22535 case OPC_SUBQ_QH:
22536 check_dsp(ctx);
22537 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22538 break;
22539 case OPC_SUBQ_S_QH:
22540 check_dsp(ctx);
22541 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22542 break;
22543 case OPC_SUBU_OB:
22544 check_dsp(ctx);
22545 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22546 break;
22547 case OPC_SUBU_S_OB:
22548 check_dsp(ctx);
22549 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22550 break;
22551 case OPC_SUBU_QH:
908f6be1 22552 check_dsp_r2(ctx);
461c08df
JL
22553 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22554 break;
22555 case OPC_SUBU_S_QH:
908f6be1 22556 check_dsp_r2(ctx);
461c08df
JL
22557 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22558 break;
22559 case OPC_SUBUH_OB:
908f6be1 22560 check_dsp_r2(ctx);
461c08df
JL
22561 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22562 break;
22563 case OPC_SUBUH_R_OB:
908f6be1 22564 check_dsp_r2(ctx);
461c08df
JL
22565 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22566 break;
22567 case OPC_ADDQ_PW:
22568 check_dsp(ctx);
22569 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22570 break;
22571 case OPC_ADDQ_S_PW:
22572 check_dsp(ctx);
22573 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22574 break;
22575 case OPC_ADDQ_QH:
22576 check_dsp(ctx);
22577 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22578 break;
22579 case OPC_ADDQ_S_QH:
22580 check_dsp(ctx);
22581 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22582 break;
22583 case OPC_ADDU_OB:
22584 check_dsp(ctx);
22585 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22586 break;
22587 case OPC_ADDU_S_OB:
22588 check_dsp(ctx);
22589 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22590 break;
22591 case OPC_ADDU_QH:
908f6be1 22592 check_dsp_r2(ctx);
461c08df
JL
22593 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22594 break;
22595 case OPC_ADDU_S_QH:
908f6be1 22596 check_dsp_r2(ctx);
461c08df
JL
22597 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22598 break;
22599 case OPC_ADDUH_OB:
908f6be1 22600 check_dsp_r2(ctx);
461c08df
JL
22601 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22602 break;
22603 case OPC_ADDUH_R_OB:
908f6be1 22604 check_dsp_r2(ctx);
461c08df
JL
22605 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22606 break;
22607 }
22608 break;
22609 case OPC_CMPU_EQ_OB_DSP:
22610 switch (op2) {
22611 case OPC_PRECR_OB_QH:
908f6be1 22612 check_dsp_r2(ctx);
461c08df
JL
22613 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22614 break;
22615 case OPC_PRECR_SRA_QH_PW:
908f6be1 22616 check_dsp_r2(ctx);
461c08df
JL
22617 {
22618 TCGv_i32 ret_t = tcg_const_i32(ret);
22619 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22620 tcg_temp_free_i32(ret_t);
22621 break;
22622 }
22623 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 22624 check_dsp_r2(ctx);
461c08df
JL
22625 {
22626 TCGv_i32 sa_v = tcg_const_i32(ret);
22627 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22628 tcg_temp_free_i32(sa_v);
22629 break;
22630 }
22631 case OPC_PRECRQ_OB_QH:
22632 check_dsp(ctx);
22633 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22634 break;
22635 case OPC_PRECRQ_PW_L:
22636 check_dsp(ctx);
22637 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22638 break;
22639 case OPC_PRECRQ_QH_PW:
22640 check_dsp(ctx);
22641 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22642 break;
22643 case OPC_PRECRQ_RS_QH_PW:
22644 check_dsp(ctx);
22645 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22646 break;
22647 case OPC_PRECRQU_S_OB_QH:
22648 check_dsp(ctx);
22649 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22650 break;
22651 }
22652 break;
22653#endif
22654 }
22655
22656 tcg_temp_free(v1_t);
22657 tcg_temp_free(v2_t);
461c08df 22658}
9b1a1d68 22659
77c5fa8b
JL
22660static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22661 int ret, int v1, int v2)
22662{
22663 uint32_t op2;
77c5fa8b
JL
22664 TCGv t0;
22665 TCGv v1_t;
22666 TCGv v2_t;
22667
22668 if (ret == 0) {
22669 /* Treat as NOP. */
77c5fa8b
JL
22670 return;
22671 }
22672
22673 t0 = tcg_temp_new();
22674 v1_t = tcg_temp_new();
22675 v2_t = tcg_temp_new();
22676
22677 tcg_gen_movi_tl(t0, v1);
22678 gen_load_gpr(v1_t, v1);
22679 gen_load_gpr(v2_t, v2);
22680
22681 switch (opc) {
22682 case OPC_SHLL_QB_DSP:
22683 {
22684 op2 = MASK_SHLL_QB(ctx->opcode);
22685 switch (op2) {
22686 case OPC_SHLL_QB:
22687 check_dsp(ctx);
22688 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22689 break;
22690 case OPC_SHLLV_QB:
22691 check_dsp(ctx);
22692 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22693 break;
22694 case OPC_SHLL_PH:
22695 check_dsp(ctx);
22696 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22697 break;
22698 case OPC_SHLLV_PH:
22699 check_dsp(ctx);
22700 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22701 break;
22702 case OPC_SHLL_S_PH:
22703 check_dsp(ctx);
22704 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22705 break;
22706 case OPC_SHLLV_S_PH:
22707 check_dsp(ctx);
22708 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22709 break;
22710 case OPC_SHLL_S_W:
22711 check_dsp(ctx);
22712 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22713 break;
22714 case OPC_SHLLV_S_W:
22715 check_dsp(ctx);
22716 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22717 break;
22718 case OPC_SHRL_QB:
22719 check_dsp(ctx);
22720 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22721 break;
22722 case OPC_SHRLV_QB:
22723 check_dsp(ctx);
22724 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22725 break;
22726 case OPC_SHRL_PH:
908f6be1 22727 check_dsp_r2(ctx);
77c5fa8b
JL
22728 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22729 break;
22730 case OPC_SHRLV_PH:
908f6be1 22731 check_dsp_r2(ctx);
77c5fa8b
JL
22732 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22733 break;
22734 case OPC_SHRA_QB:
908f6be1 22735 check_dsp_r2(ctx);
77c5fa8b
JL
22736 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22737 break;
22738 case OPC_SHRA_R_QB:
908f6be1 22739 check_dsp_r2(ctx);
77c5fa8b
JL
22740 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22741 break;
22742 case OPC_SHRAV_QB:
908f6be1 22743 check_dsp_r2(ctx);
77c5fa8b
JL
22744 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22745 break;
22746 case OPC_SHRAV_R_QB:
908f6be1 22747 check_dsp_r2(ctx);
77c5fa8b
JL
22748 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22749 break;
22750 case OPC_SHRA_PH:
22751 check_dsp(ctx);
22752 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22753 break;
22754 case OPC_SHRA_R_PH:
22755 check_dsp(ctx);
22756 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22757 break;
22758 case OPC_SHRAV_PH:
22759 check_dsp(ctx);
22760 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22761 break;
22762 case OPC_SHRAV_R_PH:
22763 check_dsp(ctx);
22764 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22765 break;
22766 case OPC_SHRA_R_W:
22767 check_dsp(ctx);
22768 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22769 break;
22770 case OPC_SHRAV_R_W:
22771 check_dsp(ctx);
22772 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22773 break;
22774 default: /* Invalid */
22775 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 22776 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22777 break;
22778 }
22779 break;
22780 }
22781#ifdef TARGET_MIPS64
22782 case OPC_SHLL_OB_DSP:
22783 op2 = MASK_SHLL_OB(ctx->opcode);
22784 switch (op2) {
22785 case OPC_SHLL_PW:
22786 check_dsp(ctx);
22787 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22788 break;
22789 case OPC_SHLLV_PW:
22790 check_dsp(ctx);
22791 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22792 break;
22793 case OPC_SHLL_S_PW:
22794 check_dsp(ctx);
22795 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22796 break;
22797 case OPC_SHLLV_S_PW:
22798 check_dsp(ctx);
22799 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22800 break;
22801 case OPC_SHLL_OB:
22802 check_dsp(ctx);
22803 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22804 break;
22805 case OPC_SHLLV_OB:
22806 check_dsp(ctx);
22807 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22808 break;
22809 case OPC_SHLL_QH:
22810 check_dsp(ctx);
22811 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22812 break;
22813 case OPC_SHLLV_QH:
22814 check_dsp(ctx);
22815 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22816 break;
22817 case OPC_SHLL_S_QH:
22818 check_dsp(ctx);
22819 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22820 break;
22821 case OPC_SHLLV_S_QH:
22822 check_dsp(ctx);
22823 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22824 break;
22825 case OPC_SHRA_OB:
908f6be1 22826 check_dsp_r2(ctx);
77c5fa8b
JL
22827 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22828 break;
22829 case OPC_SHRAV_OB:
908f6be1 22830 check_dsp_r2(ctx);
77c5fa8b
JL
22831 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22832 break;
22833 case OPC_SHRA_R_OB:
908f6be1 22834 check_dsp_r2(ctx);
77c5fa8b
JL
22835 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22836 break;
22837 case OPC_SHRAV_R_OB:
908f6be1 22838 check_dsp_r2(ctx);
77c5fa8b
JL
22839 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22840 break;
22841 case OPC_SHRA_PW:
22842 check_dsp(ctx);
22843 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22844 break;
22845 case OPC_SHRAV_PW:
22846 check_dsp(ctx);
22847 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22848 break;
22849 case OPC_SHRA_R_PW:
22850 check_dsp(ctx);
22851 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22852 break;
22853 case OPC_SHRAV_R_PW:
22854 check_dsp(ctx);
22855 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22856 break;
22857 case OPC_SHRA_QH:
22858 check_dsp(ctx);
22859 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22860 break;
22861 case OPC_SHRAV_QH:
22862 check_dsp(ctx);
22863 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22864 break;
22865 case OPC_SHRA_R_QH:
22866 check_dsp(ctx);
22867 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22868 break;
22869 case OPC_SHRAV_R_QH:
22870 check_dsp(ctx);
22871 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22872 break;
22873 case OPC_SHRL_OB:
22874 check_dsp(ctx);
22875 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22876 break;
22877 case OPC_SHRLV_OB:
22878 check_dsp(ctx);
22879 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22880 break;
22881 case OPC_SHRL_QH:
908f6be1 22882 check_dsp_r2(ctx);
77c5fa8b
JL
22883 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22884 break;
22885 case OPC_SHRLV_QH:
908f6be1 22886 check_dsp_r2(ctx);
77c5fa8b
JL
22887 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22888 break;
22889 default: /* Invalid */
22890 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 22891 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22892 break;
22893 }
22894 break;
22895#endif
22896 }
22897
22898 tcg_temp_free(t0);
22899 tcg_temp_free(v1_t);
22900 tcg_temp_free(v2_t);
77c5fa8b
JL
22901}
22902
a22260ae
JL
22903static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22904 int ret, int v1, int v2, int check_ret)
22905{
a22260ae
JL
22906 TCGv_i32 t0;
22907 TCGv v1_t;
22908 TCGv v2_t;
22909
22910 if ((ret == 0) && (check_ret == 1)) {
22911 /* Treat as NOP. */
a22260ae
JL
22912 return;
22913 }
22914
22915 t0 = tcg_temp_new_i32();
22916 v1_t = tcg_temp_new();
22917 v2_t = tcg_temp_new();
22918
22919 tcg_gen_movi_i32(t0, ret);
22920 gen_load_gpr(v1_t, v1);
22921 gen_load_gpr(v2_t, v2);
22922
22923 switch (op1) {
22924 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22925 * the same mask and op1. */
22926 case OPC_MULT_G_2E:
908f6be1 22927 check_dsp_r2(ctx);
a22260ae
JL
22928 switch (op2) {
22929 case OPC_MUL_PH:
22930 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22931 break;
22932 case OPC_MUL_S_PH:
22933 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22934 break;
22935 case OPC_MULQ_S_W:
22936 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22937 break;
22938 case OPC_MULQ_RS_W:
22939 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22940 break;
22941 }
22942 break;
22943 case OPC_DPA_W_PH_DSP:
22944 switch (op2) {
22945 case OPC_DPAU_H_QBL:
22946 check_dsp(ctx);
22947 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22948 break;
22949 case OPC_DPAU_H_QBR:
22950 check_dsp(ctx);
22951 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22952 break;
22953 case OPC_DPSU_H_QBL:
22954 check_dsp(ctx);
22955 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22956 break;
22957 case OPC_DPSU_H_QBR:
22958 check_dsp(ctx);
22959 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22960 break;
22961 case OPC_DPA_W_PH:
908f6be1 22962 check_dsp_r2(ctx);
a22260ae
JL
22963 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22964 break;
22965 case OPC_DPAX_W_PH:
908f6be1 22966 check_dsp_r2(ctx);
a22260ae
JL
22967 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22968 break;
22969 case OPC_DPAQ_S_W_PH:
22970 check_dsp(ctx);
22971 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22972 break;
22973 case OPC_DPAQX_S_W_PH:
908f6be1 22974 check_dsp_r2(ctx);
a22260ae
JL
22975 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22976 break;
22977 case OPC_DPAQX_SA_W_PH:
908f6be1 22978 check_dsp_r2(ctx);
a22260ae
JL
22979 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22980 break;
22981 case OPC_DPS_W_PH:
908f6be1 22982 check_dsp_r2(ctx);
a22260ae
JL
22983 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22984 break;
22985 case OPC_DPSX_W_PH:
908f6be1 22986 check_dsp_r2(ctx);
a22260ae
JL
22987 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22988 break;
22989 case OPC_DPSQ_S_W_PH:
22990 check_dsp(ctx);
22991 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22992 break;
22993 case OPC_DPSQX_S_W_PH:
908f6be1 22994 check_dsp_r2(ctx);
a22260ae
JL
22995 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22996 break;
22997 case OPC_DPSQX_SA_W_PH:
908f6be1 22998 check_dsp_r2(ctx);
a22260ae
JL
22999 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23000 break;
23001 case OPC_MULSAQ_S_W_PH:
23002 check_dsp(ctx);
23003 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23004 break;
23005 case OPC_DPAQ_SA_L_W:
23006 check_dsp(ctx);
23007 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23008 break;
23009 case OPC_DPSQ_SA_L_W:
23010 check_dsp(ctx);
23011 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23012 break;
23013 case OPC_MAQ_S_W_PHL:
23014 check_dsp(ctx);
23015 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23016 break;
23017 case OPC_MAQ_S_W_PHR:
23018 check_dsp(ctx);
23019 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23020 break;
23021 case OPC_MAQ_SA_W_PHL:
23022 check_dsp(ctx);
23023 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23024 break;
23025 case OPC_MAQ_SA_W_PHR:
23026 check_dsp(ctx);
23027 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23028 break;
23029 case OPC_MULSA_W_PH:
908f6be1 23030 check_dsp_r2(ctx);
a22260ae
JL
23031 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23032 break;
23033 }
23034 break;
23035#ifdef TARGET_MIPS64
23036 case OPC_DPAQ_W_QH_DSP:
23037 {
23038 int ac = ret & 0x03;
23039 tcg_gen_movi_i32(t0, ac);
23040
23041 switch (op2) {
23042 case OPC_DMADD:
23043 check_dsp(ctx);
23044 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23045 break;
23046 case OPC_DMADDU:
23047 check_dsp(ctx);
23048 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23049 break;
23050 case OPC_DMSUB:
23051 check_dsp(ctx);
23052 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23053 break;
23054 case OPC_DMSUBU:
23055 check_dsp(ctx);
23056 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23057 break;
23058 case OPC_DPA_W_QH:
908f6be1 23059 check_dsp_r2(ctx);
a22260ae
JL
23060 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23061 break;
23062 case OPC_DPAQ_S_W_QH:
23063 check_dsp(ctx);
23064 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23065 break;
23066 case OPC_DPAQ_SA_L_PW:
23067 check_dsp(ctx);
23068 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23069 break;
23070 case OPC_DPAU_H_OBL:
23071 check_dsp(ctx);
23072 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23073 break;
23074 case OPC_DPAU_H_OBR:
23075 check_dsp(ctx);
23076 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23077 break;
23078 case OPC_DPS_W_QH:
908f6be1 23079 check_dsp_r2(ctx);
a22260ae
JL
23080 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23081 break;
23082 case OPC_DPSQ_S_W_QH:
23083 check_dsp(ctx);
23084 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23085 break;
23086 case OPC_DPSQ_SA_L_PW:
23087 check_dsp(ctx);
23088 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23089 break;
23090 case OPC_DPSU_H_OBL:
23091 check_dsp(ctx);
23092 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23093 break;
23094 case OPC_DPSU_H_OBR:
23095 check_dsp(ctx);
23096 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23097 break;
23098 case OPC_MAQ_S_L_PWL:
23099 check_dsp(ctx);
23100 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23101 break;
23102 case OPC_MAQ_S_L_PWR:
23103 check_dsp(ctx);
23104 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23105 break;
23106 case OPC_MAQ_S_W_QHLL:
23107 check_dsp(ctx);
23108 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23109 break;
23110 case OPC_MAQ_SA_W_QHLL:
23111 check_dsp(ctx);
23112 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23113 break;
23114 case OPC_MAQ_S_W_QHLR:
23115 check_dsp(ctx);
23116 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23117 break;
23118 case OPC_MAQ_SA_W_QHLR:
23119 check_dsp(ctx);
23120 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23121 break;
23122 case OPC_MAQ_S_W_QHRL:
23123 check_dsp(ctx);
23124 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23125 break;
23126 case OPC_MAQ_SA_W_QHRL:
23127 check_dsp(ctx);
23128 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23129 break;
23130 case OPC_MAQ_S_W_QHRR:
23131 check_dsp(ctx);
23132 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23133 break;
23134 case OPC_MAQ_SA_W_QHRR:
23135 check_dsp(ctx);
23136 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23137 break;
23138 case OPC_MULSAQ_S_L_PW:
23139 check_dsp(ctx);
23140 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23141 break;
23142 case OPC_MULSAQ_S_W_QH:
23143 check_dsp(ctx);
23144 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23145 break;
23146 }
23147 }
23148 break;
23149#endif
23150 case OPC_ADDU_QB_DSP:
23151 switch (op2) {
23152 case OPC_MULEU_S_PH_QBL:
23153 check_dsp(ctx);
23154 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23155 break;
23156 case OPC_MULEU_S_PH_QBR:
23157 check_dsp(ctx);
23158 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23159 break;
23160 case OPC_MULQ_RS_PH:
23161 check_dsp(ctx);
23162 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23163 break;
23164 case OPC_MULEQ_S_W_PHL:
23165 check_dsp(ctx);
23166 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23167 break;
23168 case OPC_MULEQ_S_W_PHR:
23169 check_dsp(ctx);
23170 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23171 break;
23172 case OPC_MULQ_S_PH:
908f6be1 23173 check_dsp_r2(ctx);
a22260ae
JL
23174 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23175 break;
23176 }
23177 break;
23178#ifdef TARGET_MIPS64
23179 case OPC_ADDU_OB_DSP:
23180 switch (op2) {
23181 case OPC_MULEQ_S_PW_QHL:
23182 check_dsp(ctx);
23183 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23184 break;
23185 case OPC_MULEQ_S_PW_QHR:
23186 check_dsp(ctx);
23187 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23188 break;
23189 case OPC_MULEU_S_QH_OBL:
23190 check_dsp(ctx);
23191 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23192 break;
23193 case OPC_MULEU_S_QH_OBR:
23194 check_dsp(ctx);
23195 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23196 break;
23197 case OPC_MULQ_RS_QH:
23198 check_dsp(ctx);
23199 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23200 break;
23201 }
23202 break;
23203#endif
23204 }
23205
23206 tcg_temp_free_i32(t0);
23207 tcg_temp_free(v1_t);
23208 tcg_temp_free(v2_t);
a22260ae
JL
23209}
23210
d75c135e 23211static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
23212 int ret, int val)
23213{
1cb6686c
JL
23214 int16_t imm;
23215 TCGv t0;
23216 TCGv val_t;
23217
23218 if (ret == 0) {
23219 /* Treat as NOP. */
1cb6686c
JL
23220 return;
23221 }
23222
23223 t0 = tcg_temp_new();
23224 val_t = tcg_temp_new();
23225 gen_load_gpr(val_t, val);
23226
23227 switch (op1) {
23228 case OPC_ABSQ_S_PH_DSP:
23229 switch (op2) {
23230 case OPC_BITREV:
23231 check_dsp(ctx);
23232 gen_helper_bitrev(cpu_gpr[ret], val_t);
23233 break;
23234 case OPC_REPL_QB:
23235 check_dsp(ctx);
23236 {
23237 target_long result;
23238 imm = (ctx->opcode >> 16) & 0xFF;
23239 result = (uint32_t)imm << 24 |
23240 (uint32_t)imm << 16 |
23241 (uint32_t)imm << 8 |
23242 (uint32_t)imm;
23243 result = (int32_t)result;
23244 tcg_gen_movi_tl(cpu_gpr[ret], result);
23245 }
23246 break;
23247 case OPC_REPLV_QB:
23248 check_dsp(ctx);
23249 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23250 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23251 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23252 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23253 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23254 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23255 break;
23256 case OPC_REPL_PH:
23257 check_dsp(ctx);
23258 {
23259 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 23260 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
23261 tcg_gen_movi_tl(cpu_gpr[ret], \
23262 (target_long)((int32_t)imm << 16 | \
c4aaba92 23263 (uint16_t)imm));
1cb6686c
JL
23264 }
23265 break;
23266 case OPC_REPLV_PH:
23267 check_dsp(ctx);
23268 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23269 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23270 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23271 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23272 break;
23273 }
23274 break;
23275#ifdef TARGET_MIPS64
23276 case OPC_ABSQ_S_QH_DSP:
23277 switch (op2) {
23278 case OPC_REPL_OB:
23279 check_dsp(ctx);
23280 {
23281 target_long temp;
23282
23283 imm = (ctx->opcode >> 16) & 0xFF;
23284 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23285 temp = (temp << 16) | temp;
23286 temp = (temp << 32) | temp;
23287 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23288 break;
23289 }
23290 case OPC_REPL_PW:
23291 check_dsp(ctx);
23292 {
23293 target_long temp;
23294
23295 imm = (ctx->opcode >> 16) & 0x03FF;
23296 imm = (int16_t)(imm << 6) >> 6;
23297 temp = ((target_long)imm << 32) \
23298 | ((target_long)imm & 0xFFFFFFFF);
23299 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23300 break;
23301 }
23302 case OPC_REPL_QH:
23303 check_dsp(ctx);
23304 {
23305 target_long temp;
23306
23307 imm = (ctx->opcode >> 16) & 0x03FF;
23308 imm = (int16_t)(imm << 6) >> 6;
23309
23310 temp = ((uint64_t)(uint16_t)imm << 48) |
23311 ((uint64_t)(uint16_t)imm << 32) |
23312 ((uint64_t)(uint16_t)imm << 16) |
23313 (uint64_t)(uint16_t)imm;
23314 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23315 break;
23316 }
23317 case OPC_REPLV_OB:
23318 check_dsp(ctx);
23319 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23320 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23321 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23322 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23323 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23324 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23325 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23326 break;
23327 case OPC_REPLV_PW:
23328 check_dsp(ctx);
23329 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23330 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23331 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23332 break;
23333 case OPC_REPLV_QH:
23334 check_dsp(ctx);
23335 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23336 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23337 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23338 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23339 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23340 break;
23341 }
23342 break;
23343#endif
23344 }
23345 tcg_temp_free(t0);
23346 tcg_temp_free(val_t);
1cb6686c
JL
23347}
23348
26690560
JL
23349static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23350 uint32_t op1, uint32_t op2,
23351 int ret, int v1, int v2, int check_ret)
23352{
26690560
JL
23353 TCGv t1;
23354 TCGv v1_t;
23355 TCGv v2_t;
23356
23357 if ((ret == 0) && (check_ret == 1)) {
23358 /* Treat as NOP. */
26690560
JL
23359 return;
23360 }
23361
26690560
JL
23362 t1 = tcg_temp_new();
23363 v1_t = tcg_temp_new();
23364 v2_t = tcg_temp_new();
23365
23366 gen_load_gpr(v1_t, v1);
23367 gen_load_gpr(v2_t, v2);
23368
23369 switch (op1) {
26690560
JL
23370 case OPC_CMPU_EQ_QB_DSP:
23371 switch (op2) {
23372 case OPC_CMPU_EQ_QB:
23373 check_dsp(ctx);
23374 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23375 break;
23376 case OPC_CMPU_LT_QB:
23377 check_dsp(ctx);
23378 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23379 break;
23380 case OPC_CMPU_LE_QB:
23381 check_dsp(ctx);
23382 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23383 break;
23384 case OPC_CMPGU_EQ_QB:
23385 check_dsp(ctx);
23386 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23387 break;
23388 case OPC_CMPGU_LT_QB:
23389 check_dsp(ctx);
23390 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23391 break;
23392 case OPC_CMPGU_LE_QB:
23393 check_dsp(ctx);
23394 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23395 break;
23396 case OPC_CMPGDU_EQ_QB:
908f6be1 23397 check_dsp_r2(ctx);
26690560
JL
23398 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23399 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23400 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23401 tcg_gen_shli_tl(t1, t1, 24);
23402 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23403 break;
23404 case OPC_CMPGDU_LT_QB:
908f6be1 23405 check_dsp_r2(ctx);
26690560
JL
23406 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23407 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23408 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23409 tcg_gen_shli_tl(t1, t1, 24);
23410 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23411 break;
23412 case OPC_CMPGDU_LE_QB:
908f6be1 23413 check_dsp_r2(ctx);
26690560
JL
23414 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23415 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23416 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23417 tcg_gen_shli_tl(t1, t1, 24);
23418 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23419 break;
23420 case OPC_CMP_EQ_PH:
23421 check_dsp(ctx);
23422 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23423 break;
23424 case OPC_CMP_LT_PH:
23425 check_dsp(ctx);
23426 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23427 break;
23428 case OPC_CMP_LE_PH:
23429 check_dsp(ctx);
23430 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23431 break;
23432 case OPC_PICK_QB:
23433 check_dsp(ctx);
23434 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23435 break;
23436 case OPC_PICK_PH:
23437 check_dsp(ctx);
23438 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23439 break;
23440 case OPC_PACKRL_PH:
23441 check_dsp(ctx);
23442 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23443 break;
23444 }
23445 break;
23446#ifdef TARGET_MIPS64
23447 case OPC_CMPU_EQ_OB_DSP:
23448 switch (op2) {
23449 case OPC_CMP_EQ_PW:
23450 check_dsp(ctx);
23451 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23452 break;
23453 case OPC_CMP_LT_PW:
23454 check_dsp(ctx);
23455 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23456 break;
23457 case OPC_CMP_LE_PW:
23458 check_dsp(ctx);
23459 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23460 break;
23461 case OPC_CMP_EQ_QH:
23462 check_dsp(ctx);
23463 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23464 break;
23465 case OPC_CMP_LT_QH:
23466 check_dsp(ctx);
23467 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23468 break;
23469 case OPC_CMP_LE_QH:
23470 check_dsp(ctx);
23471 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23472 break;
23473 case OPC_CMPGDU_EQ_OB:
908f6be1 23474 check_dsp_r2(ctx);
26690560
JL
23475 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23476 break;
23477 case OPC_CMPGDU_LT_OB:
908f6be1 23478 check_dsp_r2(ctx);
26690560
JL
23479 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23480 break;
23481 case OPC_CMPGDU_LE_OB:
908f6be1 23482 check_dsp_r2(ctx);
26690560
JL
23483 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23484 break;
23485 case OPC_CMPGU_EQ_OB:
23486 check_dsp(ctx);
23487 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23488 break;
23489 case OPC_CMPGU_LT_OB:
23490 check_dsp(ctx);
23491 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23492 break;
23493 case OPC_CMPGU_LE_OB:
23494 check_dsp(ctx);
23495 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23496 break;
23497 case OPC_CMPU_EQ_OB:
23498 check_dsp(ctx);
23499 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23500 break;
23501 case OPC_CMPU_LT_OB:
23502 check_dsp(ctx);
23503 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23504 break;
23505 case OPC_CMPU_LE_OB:
23506 check_dsp(ctx);
23507 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23508 break;
23509 case OPC_PACKRL_PW:
23510 check_dsp(ctx);
23511 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23512 break;
23513 case OPC_PICK_OB:
23514 check_dsp(ctx);
23515 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23516 break;
23517 case OPC_PICK_PW:
23518 check_dsp(ctx);
23519 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23520 break;
23521 case OPC_PICK_QH:
23522 check_dsp(ctx);
23523 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23524 break;
23525 }
23526 break;
df6126a7
AJ
23527#endif
23528 }
23529
23530 tcg_temp_free(t1);
23531 tcg_temp_free(v1_t);
23532 tcg_temp_free(v2_t);
df6126a7
AJ
23533}
23534
23535static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23536 uint32_t op1, int rt, int rs, int sa)
23537{
df6126a7
AJ
23538 TCGv t0;
23539
908f6be1 23540 check_dsp_r2(ctx);
df6126a7
AJ
23541
23542 if (rt == 0) {
23543 /* Treat as NOP. */
df6126a7
AJ
23544 return;
23545 }
23546
23547 t0 = tcg_temp_new();
23548 gen_load_gpr(t0, rs);
23549
23550 switch (op1) {
23551 case OPC_APPEND_DSP:
23552 switch (MASK_APPEND(ctx->opcode)) {
23553 case OPC_APPEND:
23554 if (sa != 0) {
23555 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23556 }
23557 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23558 break;
23559 case OPC_PREPEND:
23560 if (sa != 0) {
23561 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23562 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23563 tcg_gen_shli_tl(t0, t0, 32 - sa);
23564 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23565 }
23566 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23567 break;
23568 case OPC_BALIGN:
23569 sa &= 3;
23570 if (sa != 0 && sa != 2) {
23571 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23572 tcg_gen_ext32u_tl(t0, t0);
23573 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23574 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23575 }
23576 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23577 break;
23578 default: /* Invalid */
23579 MIPS_INVAL("MASK APPEND");
9c708c7f 23580 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
23581 break;
23582 }
23583 break;
23584#ifdef TARGET_MIPS64
26690560 23585 case OPC_DAPPEND_DSP:
df6126a7 23586 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 23587 case OPC_DAPPEND:
df6126a7
AJ
23588 if (sa != 0) {
23589 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23590 }
26690560
JL
23591 break;
23592 case OPC_PREPENDD:
df6126a7
AJ
23593 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23594 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23595 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
23596 break;
23597 case OPC_PREPENDW:
df6126a7
AJ
23598 if (sa != 0) {
23599 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23600 tcg_gen_shli_tl(t0, t0, 64 - sa);
23601 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23602 }
26690560
JL
23603 break;
23604 case OPC_DBALIGN:
df6126a7
AJ
23605 sa &= 7;
23606 if (sa != 0 && sa != 2 && sa != 4) {
23607 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23608 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23609 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23610 }
26690560
JL
23611 break;
23612 default: /* Invalid */
23613 MIPS_INVAL("MASK DAPPEND");
9c708c7f 23614 generate_exception_end(ctx, EXCP_RI);
26690560
JL
23615 break;
23616 }
23617 break;
23618#endif
23619 }
df6126a7 23620 tcg_temp_free(t0);
26690560
JL
23621}
23622
b53371ed
JL
23623static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23624 int ret, int v1, int v2, int check_ret)
23625
23626{
b53371ed
JL
23627 TCGv t0;
23628 TCGv t1;
23629 TCGv v1_t;
23630 TCGv v2_t;
23631 int16_t imm;
23632
23633 if ((ret == 0) && (check_ret == 1)) {
23634 /* Treat as NOP. */
b53371ed
JL
23635 return;
23636 }
23637
23638 t0 = tcg_temp_new();
23639 t1 = tcg_temp_new();
23640 v1_t = tcg_temp_new();
23641 v2_t = tcg_temp_new();
23642
23643 gen_load_gpr(v1_t, v1);
23644 gen_load_gpr(v2_t, v2);
23645
23646 switch (op1) {
23647 case OPC_EXTR_W_DSP:
23648 check_dsp(ctx);
23649 switch (op2) {
23650 case OPC_EXTR_W:
23651 tcg_gen_movi_tl(t0, v2);
23652 tcg_gen_movi_tl(t1, v1);
23653 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23654 break;
23655 case OPC_EXTR_R_W:
23656 tcg_gen_movi_tl(t0, v2);
23657 tcg_gen_movi_tl(t1, v1);
23658 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23659 break;
23660 case OPC_EXTR_RS_W:
23661 tcg_gen_movi_tl(t0, v2);
23662 tcg_gen_movi_tl(t1, v1);
23663 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23664 break;
23665 case OPC_EXTR_S_H:
23666 tcg_gen_movi_tl(t0, v2);
23667 tcg_gen_movi_tl(t1, v1);
23668 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23669 break;
23670 case OPC_EXTRV_S_H:
23671 tcg_gen_movi_tl(t0, v2);
23672 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23673 break;
23674 case OPC_EXTRV_W:
23675 tcg_gen_movi_tl(t0, v2);
23676 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23677 break;
23678 case OPC_EXTRV_R_W:
23679 tcg_gen_movi_tl(t0, v2);
23680 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23681 break;
23682 case OPC_EXTRV_RS_W:
23683 tcg_gen_movi_tl(t0, v2);
23684 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23685 break;
23686 case OPC_EXTP:
23687 tcg_gen_movi_tl(t0, v2);
23688 tcg_gen_movi_tl(t1, v1);
23689 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23690 break;
23691 case OPC_EXTPV:
23692 tcg_gen_movi_tl(t0, v2);
23693 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23694 break;
23695 case OPC_EXTPDP:
23696 tcg_gen_movi_tl(t0, v2);
23697 tcg_gen_movi_tl(t1, v1);
23698 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23699 break;
23700 case OPC_EXTPDPV:
23701 tcg_gen_movi_tl(t0, v2);
23702 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23703 break;
23704 case OPC_SHILO:
23705 imm = (ctx->opcode >> 20) & 0x3F;
23706 tcg_gen_movi_tl(t0, ret);
23707 tcg_gen_movi_tl(t1, imm);
23708 gen_helper_shilo(t0, t1, cpu_env);
23709 break;
23710 case OPC_SHILOV:
23711 tcg_gen_movi_tl(t0, ret);
23712 gen_helper_shilo(t0, v1_t, cpu_env);
23713 break;
23714 case OPC_MTHLIP:
23715 tcg_gen_movi_tl(t0, ret);
23716 gen_helper_mthlip(t0, v1_t, cpu_env);
23717 break;
23718 case OPC_WRDSP:
23719 imm = (ctx->opcode >> 11) & 0x3FF;
23720 tcg_gen_movi_tl(t0, imm);
23721 gen_helper_wrdsp(v1_t, t0, cpu_env);
23722 break;
23723 case OPC_RDDSP:
23724 imm = (ctx->opcode >> 16) & 0x03FF;
23725 tcg_gen_movi_tl(t0, imm);
23726 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23727 break;
23728 }
23729 break;
23730#ifdef TARGET_MIPS64
23731 case OPC_DEXTR_W_DSP:
23732 check_dsp(ctx);
23733 switch (op2) {
23734 case OPC_DMTHLIP:
23735 tcg_gen_movi_tl(t0, ret);
23736 gen_helper_dmthlip(v1_t, t0, cpu_env);
23737 break;
23738 case OPC_DSHILO:
23739 {
23740 int shift = (ctx->opcode >> 19) & 0x7F;
23741 int ac = (ctx->opcode >> 11) & 0x03;
23742 tcg_gen_movi_tl(t0, shift);
23743 tcg_gen_movi_tl(t1, ac);
23744 gen_helper_dshilo(t0, t1, cpu_env);
23745 break;
23746 }
23747 case OPC_DSHILOV:
23748 {
23749 int ac = (ctx->opcode >> 11) & 0x03;
23750 tcg_gen_movi_tl(t0, ac);
23751 gen_helper_dshilo(v1_t, t0, cpu_env);
23752 break;
23753 }
23754 case OPC_DEXTP:
23755 tcg_gen_movi_tl(t0, v2);
23756 tcg_gen_movi_tl(t1, v1);
23757
23758 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23759 break;
23760 case OPC_DEXTPV:
23761 tcg_gen_movi_tl(t0, v2);
23762 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23763 break;
23764 case OPC_DEXTPDP:
23765 tcg_gen_movi_tl(t0, v2);
23766 tcg_gen_movi_tl(t1, v1);
23767 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23768 break;
23769 case OPC_DEXTPDPV:
23770 tcg_gen_movi_tl(t0, v2);
23771 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23772 break;
23773 case OPC_DEXTR_L:
23774 tcg_gen_movi_tl(t0, v2);
23775 tcg_gen_movi_tl(t1, v1);
23776 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23777 break;
23778 case OPC_DEXTR_R_L:
23779 tcg_gen_movi_tl(t0, v2);
23780 tcg_gen_movi_tl(t1, v1);
23781 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23782 break;
23783 case OPC_DEXTR_RS_L:
23784 tcg_gen_movi_tl(t0, v2);
23785 tcg_gen_movi_tl(t1, v1);
23786 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23787 break;
23788 case OPC_DEXTR_W:
23789 tcg_gen_movi_tl(t0, v2);
23790 tcg_gen_movi_tl(t1, v1);
23791 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23792 break;
23793 case OPC_DEXTR_R_W:
23794 tcg_gen_movi_tl(t0, v2);
23795 tcg_gen_movi_tl(t1, v1);
23796 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23797 break;
23798 case OPC_DEXTR_RS_W:
23799 tcg_gen_movi_tl(t0, v2);
23800 tcg_gen_movi_tl(t1, v1);
23801 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23802 break;
23803 case OPC_DEXTR_S_H:
23804 tcg_gen_movi_tl(t0, v2);
23805 tcg_gen_movi_tl(t1, v1);
23806 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23807 break;
23808 case OPC_DEXTRV_S_H:
23809 tcg_gen_movi_tl(t0, v2);
23810 tcg_gen_movi_tl(t1, v1);
23811 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23812 break;
23813 case OPC_DEXTRV_L:
23814 tcg_gen_movi_tl(t0, v2);
23815 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23816 break;
23817 case OPC_DEXTRV_R_L:
23818 tcg_gen_movi_tl(t0, v2);
23819 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23820 break;
23821 case OPC_DEXTRV_RS_L:
23822 tcg_gen_movi_tl(t0, v2);
23823 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23824 break;
23825 case OPC_DEXTRV_W:
23826 tcg_gen_movi_tl(t0, v2);
23827 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23828 break;
23829 case OPC_DEXTRV_R_W:
23830 tcg_gen_movi_tl(t0, v2);
23831 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23832 break;
23833 case OPC_DEXTRV_RS_W:
23834 tcg_gen_movi_tl(t0, v2);
23835 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23836 break;
23837 }
23838 break;
23839#endif
23840 }
23841
23842 tcg_temp_free(t0);
23843 tcg_temp_free(t1);
23844 tcg_temp_free(v1_t);
23845 tcg_temp_free(v2_t);
b53371ed
JL
23846}
23847
9b1a1d68
JL
23848/* End MIPSDSP functions. */
23849
10dc65db
LA
23850static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23851{
4267d3e6 23852 int rs, rt, rd, sa;
b42ee5e1 23853 uint32_t op1, op2;
10dc65db
LA
23854
23855 rs = (ctx->opcode >> 21) & 0x1f;
23856 rt = (ctx->opcode >> 16) & 0x1f;
23857 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 23858 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23859
23860 op1 = MASK_SPECIAL(ctx->opcode);
23861 switch (op1) {
d4ea6acd 23862 case OPC_LSA:
1f1b4c00 23863 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23864 break;
c2e19f3c
AM
23865 case OPC_MULT:
23866 case OPC_MULTU:
23867 case OPC_DIV:
23868 case OPC_DIVU:
b42ee5e1
LA
23869 op2 = MASK_R6_MULDIV(ctx->opcode);
23870 switch (op2) {
23871 case R6_OPC_MUL:
23872 case R6_OPC_MUH:
23873 case R6_OPC_MULU:
23874 case R6_OPC_MUHU:
23875 case R6_OPC_DIV:
23876 case R6_OPC_MOD:
23877 case R6_OPC_DIVU:
23878 case R6_OPC_MODU:
23879 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23880 break;
23881 default:
23882 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23883 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23884 break;
23885 }
23886 break;
10dc65db
LA
23887 case OPC_SELEQZ:
23888 case OPC_SELNEZ:
23889 gen_cond_move(ctx, op1, rd, rs, rt);
23890 break;
4267d3e6
LA
23891 case R6_OPC_CLO:
23892 case R6_OPC_CLZ:
23893 if (rt == 0 && sa == 1) {
23894 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23895 We need additionally to check other fields */
23896 gen_cl(ctx, op1, rd, rs);
23897 } else {
9c708c7f 23898 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23899 }
23900 break;
23901 case R6_OPC_SDBBP:
3b3c1694
LA
23902 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23903 gen_helper_do_semihosting(cpu_env);
faf1f68b 23904 } else {
3b3c1694 23905 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 23906 generate_exception_end(ctx, EXCP_RI);
3b3c1694 23907 } else {
9c708c7f 23908 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23909 }
faf1f68b 23910 }
4267d3e6 23911 break;
b42ee5e1 23912#if defined(TARGET_MIPS64)
d4ea6acd
LA
23913 case OPC_DLSA:
23914 check_mips_64(ctx);
1f1b4c00 23915 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23916 break;
4267d3e6
LA
23917 case R6_OPC_DCLO:
23918 case R6_OPC_DCLZ:
23919 if (rt == 0 && sa == 1) {
23920 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23921 We need additionally to check other fields */
23922 check_mips_64(ctx);
23923 gen_cl(ctx, op1, rd, rs);
23924 } else {
9c708c7f 23925 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23926 }
23927 break;
c2e19f3c
AM
23928 case OPC_DMULT:
23929 case OPC_DMULTU:
23930 case OPC_DDIV:
23931 case OPC_DDIVU:
23932
b42ee5e1
LA
23933 op2 = MASK_R6_MULDIV(ctx->opcode);
23934 switch (op2) {
23935 case R6_OPC_DMUL:
23936 case R6_OPC_DMUH:
23937 case R6_OPC_DMULU:
23938 case R6_OPC_DMUHU:
23939 case R6_OPC_DDIV:
23940 case R6_OPC_DMOD:
23941 case R6_OPC_DDIVU:
23942 case R6_OPC_DMODU:
23943 check_mips_64(ctx);
23944 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23945 break;
23946 default:
23947 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23948 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23949 break;
23950 }
23951 break;
23952#endif
10dc65db
LA
23953 default: /* Invalid */
23954 MIPS_INVAL("special_r6");
9c708c7f 23955 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23956 break;
23957 }
23958}
23959
9dc324ce
FN
23960static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23961{
23962 int rs = extract32(ctx->opcode, 21, 5);
23963 int rt = extract32(ctx->opcode, 16, 5);
23964 int rd = extract32(ctx->opcode, 11, 5);
23965 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23966
23967 switch (op1) {
23968 case OPC_MOVN: /* Conditional move */
23969 case OPC_MOVZ:
23970 gen_cond_move(ctx, op1, rd, rs, rt);
23971 break;
23972 case OPC_MFHI: /* Move from HI/LO */
23973 case OPC_MFLO:
23974 gen_HILO(ctx, op1, 0, rd);
23975 break;
23976 case OPC_MTHI:
23977 case OPC_MTLO: /* Move to HI/LO */
23978 gen_HILO(ctx, op1, 0, rs);
23979 break;
23980 case OPC_MULT:
23981 case OPC_MULTU:
23982 gen_mul_txx9(ctx, op1, rd, rs, rt);
23983 break;
23984 case OPC_DIV:
23985 case OPC_DIVU:
23986 gen_muldiv(ctx, op1, 0, rs, rt);
23987 break;
23988#if defined(TARGET_MIPS64)
23989 case OPC_DMULT:
23990 case OPC_DMULTU:
23991 case OPC_DDIV:
23992 case OPC_DDIVU:
23993 check_insn_opc_user_only(ctx, INSN_R5900);
23994 gen_muldiv(ctx, op1, 0, rs, rt);
23995 break;
23996#endif
23997 case OPC_JR:
23998 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
23999 break;
24000 default: /* Invalid */
24001 MIPS_INVAL("special_tx79");
24002 generate_exception_end(ctx, EXCP_RI);
24003 break;
24004 }
24005}
24006
10dc65db
LA
24007static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24008{
b42ee5e1 24009 int rs, rt, rd, sa;
10dc65db
LA
24010 uint32_t op1;
24011
24012 rs = (ctx->opcode >> 21) & 0x1f;
24013 rt = (ctx->opcode >> 16) & 0x1f;
24014 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 24015 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
24016
24017 op1 = MASK_SPECIAL(ctx->opcode);
24018 switch (op1) {
24019 case OPC_MOVN: /* Conditional move */
24020 case OPC_MOVZ:
24021 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
9dc324ce 24022 INSN_LOONGSON2E | INSN_LOONGSON2F);
10dc65db
LA
24023 gen_cond_move(ctx, op1, rd, rs, rt);
24024 break;
24025 case OPC_MFHI: /* Move from HI/LO */
24026 case OPC_MFLO:
24027 gen_HILO(ctx, op1, rs & 3, rd);
24028 break;
24029 case OPC_MTHI:
24030 case OPC_MTLO: /* Move to HI/LO */
24031 gen_HILO(ctx, op1, rd & 3, rs);
24032 break;
24033 case OPC_MOVCI:
24034 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24035 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24036 check_cp1_enabled(ctx);
24037 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24038 (ctx->opcode >> 16) & 1);
24039 } else {
24040 generate_exception_err(ctx, EXCP_CpU, 1);
24041 }
24042 break;
b42ee5e1
LA
24043 case OPC_MULT:
24044 case OPC_MULTU:
24045 if (sa) {
24046 check_insn(ctx, INSN_VR54XX);
24047 op1 = MASK_MUL_VR54XX(ctx->opcode);
24048 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24049 } else {
24050 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24051 }
24052 break;
24053 case OPC_DIV:
24054 case OPC_DIVU:
24055 gen_muldiv(ctx, op1, 0, rs, rt);
24056 break;
24057#if defined(TARGET_MIPS64)
c2e19f3c
AM
24058 case OPC_DMULT:
24059 case OPC_DMULTU:
24060 case OPC_DDIV:
24061 case OPC_DDIVU:
b42ee5e1
LA
24062 check_insn(ctx, ISA_MIPS3);
24063 check_mips_64(ctx);
24064 gen_muldiv(ctx, op1, 0, rs, rt);
24065 break;
24066#endif
0aefa333 24067 case OPC_JR:
b231c103 24068 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 24069 break;
4267d3e6
LA
24070 case OPC_SPIM:
24071#ifdef MIPS_STRICT_STANDARD
24072 MIPS_INVAL("SPIM");
9c708c7f 24073 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
24074#else
24075 /* Implemented as RI exception for now. */
24076 MIPS_INVAL("spim (unofficial)");
9c708c7f 24077 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
24078#endif
24079 break;
10dc65db
LA
24080 default: /* Invalid */
24081 MIPS_INVAL("special_legacy");
9c708c7f 24082 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
24083 break;
24084 }
24085}
24086
099e5b4d 24087static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 24088{
3c824109 24089 int rs, rt, rd, sa;
099e5b4d 24090 uint32_t op1;
3c824109 24091
3c824109
NF
24092 rs = (ctx->opcode >> 21) & 0x1f;
24093 rt = (ctx->opcode >> 16) & 0x1f;
24094 rd = (ctx->opcode >> 11) & 0x1f;
24095 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
24096
24097 op1 = MASK_SPECIAL(ctx->opcode);
24098 switch (op1) {
24099 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
24100 if (sa == 5 && rd == 0 &&
24101 rs == 0 && rt == 0) { /* PAUSE */
24102 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24103 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 24104 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
24105 break;
24106 }
24107 }
24108 /* Fallthrough */
099e5b4d
LA
24109 case OPC_SRA:
24110 gen_shift_imm(ctx, op1, rd, rt, sa);
24111 break;
24112 case OPC_SRL:
24113 switch ((ctx->opcode >> 21) & 0x1f) {
24114 case 1:
24115 /* rotr is decoded as srl on non-R2 CPUs */
24116 if (ctx->insn_flags & ISA_MIPS32R2) {
24117 op1 = OPC_ROTR;
ea63e2c3 24118 }
099e5b4d
LA
24119 /* Fallthrough */
24120 case 0:
24121 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 24122 break;
099e5b4d 24123 default:
9c708c7f 24124 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 24125 break;
099e5b4d
LA
24126 }
24127 break;
c2e19f3c
AM
24128 case OPC_ADD:
24129 case OPC_ADDU:
24130 case OPC_SUB:
24131 case OPC_SUBU:
099e5b4d
LA
24132 gen_arith(ctx, op1, rd, rs, rt);
24133 break;
24134 case OPC_SLLV: /* Shifts */
24135 case OPC_SRAV:
24136 gen_shift(ctx, op1, rd, rs, rt);
24137 break;
24138 case OPC_SRLV:
24139 switch ((ctx->opcode >> 6) & 0x1f) {
24140 case 1:
24141 /* rotrv is decoded as srlv on non-R2 CPUs */
24142 if (ctx->insn_flags & ISA_MIPS32R2) {
24143 op1 = OPC_ROTRV;
26135ead 24144 }
099e5b4d
LA
24145 /* Fallthrough */
24146 case 0:
24147 gen_shift(ctx, op1, rd, rs, rt);
26135ead 24148 break;
099e5b4d 24149 default:
9c708c7f 24150 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 24151 break;
099e5b4d
LA
24152 }
24153 break;
24154 case OPC_SLT: /* Set on less than */
24155 case OPC_SLTU:
24156 gen_slt(ctx, op1, rd, rs, rt);
24157 break;
24158 case OPC_AND: /* Logic*/
24159 case OPC_OR:
24160 case OPC_NOR:
24161 case OPC_XOR:
24162 gen_logic(ctx, op1, rd, rs, rt);
24163 break;
0aefa333 24164 case OPC_JALR:
b231c103 24165 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 24166 break;
c2e19f3c
AM
24167 case OPC_TGE: /* Traps */
24168 case OPC_TGEU:
24169 case OPC_TLT:
24170 case OPC_TLTU:
24171 case OPC_TEQ:
099e5b4d 24172 case OPC_TNE:
d9224450 24173 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
24174 gen_trap(ctx, op1, rs, rt, -1);
24175 break;
d4ea6acd 24176 case OPC_LSA: /* OPC_PMON */
f7685877
YK
24177 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24178 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
24179 decode_opc_special_r6(env, ctx);
24180 } else {
24181 /* Pmon entry point, also R4010 selsl */
b48cfdff 24182#ifdef MIPS_STRICT_STANDARD
d4ea6acd 24183 MIPS_INVAL("PMON / selsl");
9c708c7f 24184 generate_exception_end(ctx, EXCP_RI);
b48cfdff 24185#else
d4ea6acd 24186 gen_helper_0e0i(pmon, sa);
b48cfdff 24187#endif
d4ea6acd 24188 }
099e5b4d
LA
24189 break;
24190 case OPC_SYSCALL:
9c708c7f 24191 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
24192 break;
24193 case OPC_BREAK:
9c708c7f 24194 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 24195 break;
099e5b4d 24196 case OPC_SYNC:
d9224450 24197 check_insn(ctx, ISA_MIPS2);
d208ac0c 24198 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 24199 break;
4ad40f36 24200
d26bc211 24201#if defined(TARGET_MIPS64)
099e5b4d
LA
24202 /* MIPS64 specific opcodes */
24203 case OPC_DSLL:
24204 case OPC_DSRA:
24205 case OPC_DSLL32:
24206 case OPC_DSRA32:
24207 check_insn(ctx, ISA_MIPS3);
24208 check_mips_64(ctx);
24209 gen_shift_imm(ctx, op1, rd, rt, sa);
24210 break;
24211 case OPC_DSRL:
24212 switch ((ctx->opcode >> 21) & 0x1f) {
24213 case 1:
24214 /* drotr is decoded as dsrl on non-R2 CPUs */
24215 if (ctx->insn_flags & ISA_MIPS32R2) {
24216 op1 = OPC_DROTR;
ea63e2c3 24217 }
099e5b4d
LA
24218 /* Fallthrough */
24219 case 0:
d75c135e 24220 check_insn(ctx, ISA_MIPS3);
e189e748 24221 check_mips_64(ctx);
099e5b4d 24222 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24223 break;
099e5b4d 24224 default:
9c708c7f 24225 generate_exception_end(ctx, EXCP_RI);
460f00c4 24226 break;
099e5b4d
LA
24227 }
24228 break;
24229 case OPC_DSRL32:
24230 switch ((ctx->opcode >> 21) & 0x1f) {
24231 case 1:
24232 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24233 if (ctx->insn_flags & ISA_MIPS32R2) {
24234 op1 = OPC_DROTR32;
ea63e2c3 24235 }
099e5b4d
LA
24236 /* Fallthrough */
24237 case 0:
d75c135e 24238 check_insn(ctx, ISA_MIPS3);
e189e748 24239 check_mips_64(ctx);
099e5b4d 24240 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24241 break;
099e5b4d 24242 default:
9c708c7f 24243 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
24244 break;
24245 }
24246 break;
c2e19f3c
AM
24247 case OPC_DADD:
24248 case OPC_DADDU:
24249 case OPC_DSUB:
24250 case OPC_DSUBU:
099e5b4d
LA
24251 check_insn(ctx, ISA_MIPS3);
24252 check_mips_64(ctx);
24253 gen_arith(ctx, op1, rd, rs, rt);
24254 break;
24255 case OPC_DSLLV:
24256 case OPC_DSRAV:
24257 check_insn(ctx, ISA_MIPS3);
24258 check_mips_64(ctx);
24259 gen_shift(ctx, op1, rd, rs, rt);
24260 break;
24261 case OPC_DSRLV:
24262 switch ((ctx->opcode >> 6) & 0x1f) {
24263 case 1:
24264 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24265 if (ctx->insn_flags & ISA_MIPS32R2) {
24266 op1 = OPC_DROTRV;
6af0bf9c 24267 }
099e5b4d
LA
24268 /* Fallthrough */
24269 case 0:
24270 check_insn(ctx, ISA_MIPS3);
e189e748 24271 check_mips_64(ctx);
099e5b4d 24272 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 24273 break;
099e5b4d 24274 default:
9c708c7f 24275 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
24276 break;
24277 }
24278 break;
f7685877
YK
24279 case OPC_DLSA:
24280 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24281 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24282 decode_opc_special_r6(env, ctx);
24283 }
24284 break;
099e5b4d 24285#endif
10dc65db
LA
24286 default:
24287 if (ctx->insn_flags & ISA_MIPS32R6) {
24288 decode_opc_special_r6(env, ctx);
9dc324ce
FN
24289 } else if (ctx->insn_flags & INSN_R5900) {
24290 decode_opc_special_tx79(env, ctx);
10dc65db
LA
24291 } else {
24292 decode_opc_special_legacy(env, ctx);
24293 }
24294 }
24295}
24296
d67da337 24297
b621f018
AM
24298#if !defined(TARGET_MIPS64)
24299
d67da337
AM
24300/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24301#define MXU_APTN1_A 0
24302#define MXU_APTN1_S 1
24303
b70bb918
CJ
24304/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24305#define MXU_APTN2_AA 0
24306#define MXU_APTN2_AS 1
24307#define MXU_APTN2_SA 2
24308#define MXU_APTN2_SS 3
24309
5bb29992
AM
24310/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24311#define MXU_EPTN2_AA 0
24312#define MXU_EPTN2_AS 1
24313#define MXU_EPTN2_SA 2
24314#define MXU_EPTN2_SS 3
24315
a35723f4 24316/* MXU operand getting pattern 'optn2' */
16fef5b2
AM
24317#define MXU_OPTN2_PTN0 0
24318#define MXU_OPTN2_PTN1 1
24319#define MXU_OPTN2_PTN2 2
24320#define MXU_OPTN2_PTN3 3
24321/* alternative naming scheme for 'optn2' */
a35723f4
CJ
24322#define MXU_OPTN2_WW 0
24323#define MXU_OPTN2_LW 1
24324#define MXU_OPTN2_HW 2
24325#define MXU_OPTN2_XW 3
24326
53f1131f
CJ
24327/* MXU operand getting pattern 'optn3' */
24328#define MXU_OPTN3_PTN0 0
24329#define MXU_OPTN3_PTN1 1
24330#define MXU_OPTN3_PTN2 2
24331#define MXU_OPTN3_PTN3 3
24332#define MXU_OPTN3_PTN4 4
24333#define MXU_OPTN3_PTN5 5
24334#define MXU_OPTN3_PTN6 6
24335#define MXU_OPTN3_PTN7 7
24336
d67da337 24337
96992d1a
CJ
24338/*
24339 * S32I2M XRa, rb - Register move from GRF to XRF
24340 */
24341static void gen_mxu_s32i2m(DisasContext *ctx)
24342{
24343 TCGv t0;
24344 uint32_t XRa, Rb;
24345
24346 t0 = tcg_temp_new();
24347
24348 XRa = extract32(ctx->opcode, 6, 5);
24349 Rb = extract32(ctx->opcode, 16, 5);
24350
24351 gen_load_gpr(t0, Rb);
24352 if (XRa <= 15) {
24353 gen_store_mxu_gpr(t0, XRa);
24354 } else if (XRa == 16) {
24355 gen_store_mxu_cr(t0);
24356 }
24357
24358 tcg_temp_free(t0);
24359}
24360
24361/*
24362 * S32M2I XRa, rb - Register move from XRF to GRF
24363 */
24364static void gen_mxu_s32m2i(DisasContext *ctx)
24365{
24366 TCGv t0;
24367 uint32_t XRa, Rb;
24368
24369 t0 = tcg_temp_new();
24370
24371 XRa = extract32(ctx->opcode, 6, 5);
24372 Rb = extract32(ctx->opcode, 16, 5);
24373
24374 if (XRa <= 15) {
24375 gen_load_mxu_gpr(t0, XRa);
24376 } else if (XRa == 16) {
24377 gen_load_mxu_cr(t0);
24378 }
24379
24380 gen_store_gpr(t0, Rb);
24381
24382 tcg_temp_free(t0);
24383}
24384
be57bcdb
CJ
24385/*
24386 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24387 */
24388static void gen_mxu_s8ldd(DisasContext *ctx)
24389{
24390 TCGv t0, t1;
be57bcdb
CJ
24391 uint32_t XRa, Rb, s8, optn3;
24392
24393 t0 = tcg_temp_new();
24394 t1 = tcg_temp_new();
24395
be57bcdb
CJ
24396 XRa = extract32(ctx->opcode, 6, 4);
24397 s8 = extract32(ctx->opcode, 10, 8);
24398 optn3 = extract32(ctx->opcode, 18, 3);
24399 Rb = extract32(ctx->opcode, 21, 5);
24400
be57bcdb
CJ
24401 gen_load_gpr(t0, Rb);
24402 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24403
24404 switch (optn3) {
24405 /* XRa[7:0] = tmp8 */
24406 case MXU_OPTN3_PTN0:
24407 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24408 gen_load_mxu_gpr(t0, XRa);
24409 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24410 break;
24411 /* XRa[15:8] = tmp8 */
24412 case MXU_OPTN3_PTN1:
24413 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24414 gen_load_mxu_gpr(t0, XRa);
24415 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24416 break;
24417 /* XRa[23:16] = tmp8 */
24418 case MXU_OPTN3_PTN2:
24419 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24420 gen_load_mxu_gpr(t0, XRa);
24421 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24422 break;
24423 /* XRa[31:24] = tmp8 */
24424 case MXU_OPTN3_PTN3:
24425 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24426 gen_load_mxu_gpr(t0, XRa);
24427 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24428 break;
24429 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24430 case MXU_OPTN3_PTN4:
24431 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24432 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24433 break;
24434 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24435 case MXU_OPTN3_PTN5:
24436 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24437 tcg_gen_shli_tl(t1, t1, 8);
24438 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24439 break;
24440 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24441 case MXU_OPTN3_PTN6:
24442 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24443 tcg_gen_mov_tl(t0, t1);
24444 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24445 tcg_gen_shli_tl(t1, t1, 16);
24446 tcg_gen_or_tl(t0, t0, t1);
24447 break;
24448 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24449 case MXU_OPTN3_PTN7:
24450 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24451 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24452 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24453 break;
24454 }
24455
24456 gen_store_mxu_gpr(t0, XRa);
24457
be57bcdb
CJ
24458 tcg_temp_free(t0);
24459 tcg_temp_free(t1);
24460}
24461
72c9bcf8
CJ
24462/*
24463 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24464 */
24465static void gen_mxu_d16mul(DisasContext *ctx)
24466{
24467 TCGv t0, t1, t2, t3;
72c9bcf8
CJ
24468 uint32_t XRa, XRb, XRc, XRd, optn2;
24469
24470 t0 = tcg_temp_new();
24471 t1 = tcg_temp_new();
24472 t2 = tcg_temp_new();
24473 t3 = tcg_temp_new();
24474
72c9bcf8
CJ
24475 XRa = extract32(ctx->opcode, 6, 4);
24476 XRb = extract32(ctx->opcode, 10, 4);
24477 XRc = extract32(ctx->opcode, 14, 4);
24478 XRd = extract32(ctx->opcode, 18, 4);
24479 optn2 = extract32(ctx->opcode, 22, 2);
24480
72c9bcf8
CJ
24481 gen_load_mxu_gpr(t1, XRb);
24482 tcg_gen_sextract_tl(t0, t1, 0, 16);
24483 tcg_gen_sextract_tl(t1, t1, 16, 16);
24484 gen_load_mxu_gpr(t3, XRc);
24485 tcg_gen_sextract_tl(t2, t3, 0, 16);
24486 tcg_gen_sextract_tl(t3, t3, 16, 16);
24487
24488 switch (optn2) {
24489 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24490 tcg_gen_mul_tl(t3, t1, t3);
24491 tcg_gen_mul_tl(t2, t0, t2);
24492 break;
24493 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24494 tcg_gen_mul_tl(t3, t0, t3);
24495 tcg_gen_mul_tl(t2, t0, t2);
24496 break;
24497 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24498 tcg_gen_mul_tl(t3, t1, t3);
24499 tcg_gen_mul_tl(t2, t1, t2);
24500 break;
24501 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24502 tcg_gen_mul_tl(t3, t0, t3);
24503 tcg_gen_mul_tl(t2, t1, t2);
24504 break;
24505 }
24506 gen_store_mxu_gpr(t3, XRa);
24507 gen_store_mxu_gpr(t2, XRd);
24508
72c9bcf8
CJ
24509 tcg_temp_free(t0);
24510 tcg_temp_free(t1);
24511 tcg_temp_free(t2);
24512 tcg_temp_free(t3);
24513}
24514
e67915b4
CJ
24515/*
24516 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24517 * and accumulate
24518 */
24519static void gen_mxu_d16mac(DisasContext *ctx)
24520{
24521 TCGv t0, t1, t2, t3;
e67915b4
CJ
24522 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24523
24524 t0 = tcg_temp_new();
24525 t1 = tcg_temp_new();
24526 t2 = tcg_temp_new();
24527 t3 = tcg_temp_new();
24528
e67915b4
CJ
24529 XRa = extract32(ctx->opcode, 6, 4);
24530 XRb = extract32(ctx->opcode, 10, 4);
24531 XRc = extract32(ctx->opcode, 14, 4);
24532 XRd = extract32(ctx->opcode, 18, 4);
24533 optn2 = extract32(ctx->opcode, 22, 2);
24534 aptn2 = extract32(ctx->opcode, 24, 2);
24535
e67915b4
CJ
24536 gen_load_mxu_gpr(t1, XRb);
24537 tcg_gen_sextract_tl(t0, t1, 0, 16);
24538 tcg_gen_sextract_tl(t1, t1, 16, 16);
24539
24540 gen_load_mxu_gpr(t3, XRc);
24541 tcg_gen_sextract_tl(t2, t3, 0, 16);
24542 tcg_gen_sextract_tl(t3, t3, 16, 16);
24543
24544 switch (optn2) {
24545 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24546 tcg_gen_mul_tl(t3, t1, t3);
24547 tcg_gen_mul_tl(t2, t0, t2);
24548 break;
24549 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24550 tcg_gen_mul_tl(t3, t0, t3);
24551 tcg_gen_mul_tl(t2, t0, t2);
24552 break;
24553 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24554 tcg_gen_mul_tl(t3, t1, t3);
24555 tcg_gen_mul_tl(t2, t1, t2);
24556 break;
24557 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24558 tcg_gen_mul_tl(t3, t0, t3);
24559 tcg_gen_mul_tl(t2, t1, t2);
24560 break;
24561 }
24562 gen_load_mxu_gpr(t0, XRa);
24563 gen_load_mxu_gpr(t1, XRd);
24564
24565 switch (aptn2) {
24566 case MXU_APTN2_AA:
24567 tcg_gen_add_tl(t3, t0, t3);
24568 tcg_gen_add_tl(t2, t1, t2);
24569 break;
24570 case MXU_APTN2_AS:
24571 tcg_gen_add_tl(t3, t0, t3);
24572 tcg_gen_sub_tl(t2, t1, t2);
24573 break;
24574 case MXU_APTN2_SA:
24575 tcg_gen_sub_tl(t3, t0, t3);
24576 tcg_gen_add_tl(t2, t1, t2);
24577 break;
24578 case MXU_APTN2_SS:
24579 tcg_gen_sub_tl(t3, t0, t3);
24580 tcg_gen_sub_tl(t2, t1, t2);
24581 break;
24582 }
24583 gen_store_mxu_gpr(t3, XRa);
24584 gen_store_mxu_gpr(t2, XRd);
24585
e67915b4
CJ
24586 tcg_temp_free(t0);
24587 tcg_temp_free(t1);
24588 tcg_temp_free(t2);
24589 tcg_temp_free(t3);
24590}
24591
a9a4181b
CJ
24592/*
24593 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24594 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24595 */
24596static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24597{
24598 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
a9a4181b
CJ
24599 uint32_t XRa, XRb, XRc, XRd, sel;
24600
24601 t0 = tcg_temp_new();
24602 t1 = tcg_temp_new();
24603 t2 = tcg_temp_new();
24604 t3 = tcg_temp_new();
24605 t4 = tcg_temp_new();
24606 t5 = tcg_temp_new();
24607 t6 = tcg_temp_new();
24608 t7 = tcg_temp_new();
24609
a9a4181b
CJ
24610 XRa = extract32(ctx->opcode, 6, 4);
24611 XRb = extract32(ctx->opcode, 10, 4);
24612 XRc = extract32(ctx->opcode, 14, 4);
24613 XRd = extract32(ctx->opcode, 18, 4);
24614 sel = extract32(ctx->opcode, 22, 2);
24615
a9a4181b
CJ
24616 gen_load_mxu_gpr(t3, XRb);
24617 gen_load_mxu_gpr(t7, XRc);
24618
24619 if (sel == 0x2) {
24620 /* Q8MULSU */
24621 tcg_gen_ext8s_tl(t0, t3);
24622 tcg_gen_shri_tl(t3, t3, 8);
24623 tcg_gen_ext8s_tl(t1, t3);
24624 tcg_gen_shri_tl(t3, t3, 8);
24625 tcg_gen_ext8s_tl(t2, t3);
24626 tcg_gen_shri_tl(t3, t3, 8);
24627 tcg_gen_ext8s_tl(t3, t3);
24628 } else {
24629 /* Q8MUL */
24630 tcg_gen_ext8u_tl(t0, t3);
24631 tcg_gen_shri_tl(t3, t3, 8);
24632 tcg_gen_ext8u_tl(t1, t3);
24633 tcg_gen_shri_tl(t3, t3, 8);
24634 tcg_gen_ext8u_tl(t2, t3);
24635 tcg_gen_shri_tl(t3, t3, 8);
24636 tcg_gen_ext8u_tl(t3, t3);
24637 }
24638
24639 tcg_gen_ext8u_tl(t4, t7);
24640 tcg_gen_shri_tl(t7, t7, 8);
24641 tcg_gen_ext8u_tl(t5, t7);
24642 tcg_gen_shri_tl(t7, t7, 8);
24643 tcg_gen_ext8u_tl(t6, t7);
24644 tcg_gen_shri_tl(t7, t7, 8);
24645 tcg_gen_ext8u_tl(t7, t7);
24646
24647 tcg_gen_mul_tl(t0, t0, t4);
24648 tcg_gen_mul_tl(t1, t1, t5);
24649 tcg_gen_mul_tl(t2, t2, t6);
24650 tcg_gen_mul_tl(t3, t3, t7);
24651
24652 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24653 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24654 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24655 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24656
24657 tcg_gen_shli_tl(t1, t1, 16);
24658 tcg_gen_shli_tl(t3, t3, 16);
24659
24660 tcg_gen_or_tl(t0, t0, t1);
24661 tcg_gen_or_tl(t1, t2, t3);
24662
24663 gen_store_mxu_gpr(t0, XRd);
24664 gen_store_mxu_gpr(t1, XRa);
24665
a9a4181b
CJ
24666 tcg_temp_free(t0);
24667 tcg_temp_free(t1);
24668 tcg_temp_free(t2);
24669 tcg_temp_free(t3);
24670 tcg_temp_free(t4);
24671 tcg_temp_free(t5);
24672 tcg_temp_free(t6);
24673 tcg_temp_free(t7);
24674}
24675
4ca83721
CJ
24676/*
24677 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24678 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24679 */
24680static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24681{
24682 TCGv t0, t1;
4ca83721
CJ
24683 uint32_t XRa, Rb, s12, sel;
24684
24685 t0 = tcg_temp_new();
24686 t1 = tcg_temp_new();
24687
4ca83721
CJ
24688 XRa = extract32(ctx->opcode, 6, 4);
24689 s12 = extract32(ctx->opcode, 10, 10);
24690 sel = extract32(ctx->opcode, 20, 1);
24691 Rb = extract32(ctx->opcode, 21, 5);
24692
4ca83721
CJ
24693 gen_load_gpr(t0, Rb);
24694
24695 tcg_gen_movi_tl(t1, s12);
24696 tcg_gen_shli_tl(t1, t1, 2);
24697 if (s12 & 0x200) {
24698 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24699 }
24700 tcg_gen_add_tl(t1, t0, t1);
24701 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24702
24703 if (sel == 1) {
24704 /* S32LDDR */
24705 tcg_gen_bswap32_tl(t1, t1);
24706 }
24707 gen_store_mxu_gpr(t1, XRa);
24708
4ca83721
CJ
24709 tcg_temp_free(t0);
24710 tcg_temp_free(t1);
24711}
24712
96992d1a 24713
b621f018
AM
24714/*
24715 * MXU instruction category: logic
24716 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24717 *
24718 * S32NOR S32AND S32OR S32XOR
24719 */
24720
24721/*
24722 * S32NOR XRa, XRb, XRc
24723 * Update XRa with the result of logical bitwise 'nor' operation
24724 * applied to the content of XRb and XRc.
24725 *
24726 * 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
24727 * +-----------+---------+-----+-------+-------+-------+-----------+
24728 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24729 * +-----------+---------+-----+-------+-------+-------+-----------+
24730 */
24731static void gen_mxu_S32NOR(DisasContext *ctx)
24732{
24733 uint32_t pad, XRc, XRb, XRa;
24734
24735 pad = extract32(ctx->opcode, 21, 5);
24736 XRc = extract32(ctx->opcode, 14, 4);
24737 XRb = extract32(ctx->opcode, 10, 4);
24738 XRa = extract32(ctx->opcode, 6, 4);
24739
24740 if (unlikely(pad != 0)) {
24741 /* opcode padding incorrect -> do nothing */
24742 } else if (unlikely(XRa == 0)) {
24743 /* destination is zero register -> do nothing */
24744 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24745 /* both operands zero registers -> just set destination to all 1s */
24746 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24747 } else if (unlikely(XRb == 0)) {
24748 /* XRb zero register -> just set destination to the negation of XRc */
24749 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24750 } else if (unlikely(XRc == 0)) {
24751 /* XRa zero register -> just set destination to the negation of XRb */
24752 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24753 } else if (unlikely(XRb == XRc)) {
24754 /* both operands same -> just set destination to the negation of XRb */
24755 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24756 } else {
24757 /* the most general case */
24758 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24759 }
24760}
24761
24762/*
24763 * S32AND XRa, XRb, XRc
24764 * Update XRa with the result of logical bitwise 'and' operation
24765 * applied to the content of XRb and XRc.
24766 *
24767 * 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
24768 * +-----------+---------+-----+-------+-------+-------+-----------+
24769 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24770 * +-----------+---------+-----+-------+-------+-------+-----------+
24771 */
24772static void gen_mxu_S32AND(DisasContext *ctx)
24773{
24774 uint32_t pad, XRc, XRb, XRa;
24775
24776 pad = extract32(ctx->opcode, 21, 5);
24777 XRc = extract32(ctx->opcode, 14, 4);
24778 XRb = extract32(ctx->opcode, 10, 4);
24779 XRa = extract32(ctx->opcode, 6, 4);
24780
24781 if (unlikely(pad != 0)) {
24782 /* opcode padding incorrect -> do nothing */
24783 } else if (unlikely(XRa == 0)) {
24784 /* destination is zero register -> do nothing */
24785 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24786 /* one of operands zero register -> just set destination to all 0s */
24787 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24788 } else if (unlikely(XRb == XRc)) {
24789 /* both operands same -> just set destination to one of them */
24790 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24791 } else {
24792 /* the most general case */
24793 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24794 }
24795}
24796
24797/*
24798 * S32OR XRa, XRb, XRc
24799 * Update XRa with the result of logical bitwise 'or' operation
24800 * applied to the content of XRb and XRc.
24801 *
24802 * 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
24803 * +-----------+---------+-----+-------+-------+-------+-----------+
24804 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24805 * +-----------+---------+-----+-------+-------+-------+-----------+
24806 */
24807static void gen_mxu_S32OR(DisasContext *ctx)
24808{
24809 uint32_t pad, XRc, XRb, XRa;
24810
24811 pad = extract32(ctx->opcode, 21, 5);
24812 XRc = extract32(ctx->opcode, 14, 4);
24813 XRb = extract32(ctx->opcode, 10, 4);
24814 XRa = extract32(ctx->opcode, 6, 4);
24815
24816 if (unlikely(pad != 0)) {
24817 /* opcode padding incorrect -> do nothing */
24818 } else if (unlikely(XRa == 0)) {
24819 /* destination is zero register -> do nothing */
24820 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24821 /* both operands zero registers -> just set destination to all 0s */
24822 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24823 } else if (unlikely(XRb == 0)) {
24824 /* XRb zero register -> just set destination to the content of XRc */
24825 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24826 } else if (unlikely(XRc == 0)) {
24827 /* XRc zero register -> just set destination to the content of XRb */
24828 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24829 } else if (unlikely(XRb == XRc)) {
24830 /* both operands same -> just set destination to one of them */
24831 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24832 } else {
24833 /* the most general case */
24834 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24835 }
24836}
24837
24838/*
24839 * S32XOR XRa, XRb, XRc
24840 * Update XRa with the result of logical bitwise 'xor' operation
24841 * applied to the content of XRb and XRc.
24842 *
24843 * 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
24844 * +-----------+---------+-----+-------+-------+-------+-----------+
24845 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24846 * +-----------+---------+-----+-------+-------+-------+-----------+
24847 */
24848static void gen_mxu_S32XOR(DisasContext *ctx)
24849{
24850 uint32_t pad, XRc, XRb, XRa;
24851
24852 pad = extract32(ctx->opcode, 21, 5);
24853 XRc = extract32(ctx->opcode, 14, 4);
24854 XRb = extract32(ctx->opcode, 10, 4);
24855 XRa = extract32(ctx->opcode, 6, 4);
24856
24857 if (unlikely(pad != 0)) {
24858 /* opcode padding incorrect -> do nothing */
24859 } else if (unlikely(XRa == 0)) {
24860 /* destination is zero register -> do nothing */
24861 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24862 /* both operands zero registers -> just set destination to all 0s */
24863 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24864 } else if (unlikely(XRb == 0)) {
24865 /* XRb zero register -> just set destination to the content of XRc */
24866 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24867 } else if (unlikely(XRc == 0)) {
24868 /* XRc zero register -> just set destination to the content of XRb */
24869 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24870 } else if (unlikely(XRb == XRc)) {
24871 /* both operands same -> just set destination to all 0s */
24872 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24873 } else {
24874 /* the most general case */
24875 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24876 }
24877}
24878
24879
bb84cbf3
AM
24880/*
24881 * MXU instruction category max/min
24882 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24883 *
24884 * S32MAX D16MAX Q8MAX
24885 * S32MIN D16MIN Q8MIN
24886 */
24887
24888/*
24889 * S32MAX XRa, XRb, XRc
24890 * Update XRa with the maximum of signed 32-bit integers contained
24891 * in XRb and XRc.
24892 *
24893 * S32MIN XRa, XRb, XRc
24894 * Update XRa with the minimum of signed 32-bit integers contained
24895 * in XRb and XRc.
24896 *
24897 * 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
24898 * +-----------+---------+-----+-------+-------+-------+-----------+
24899 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
24900 * +-----------+---------+-----+-------+-------+-------+-----------+
24901 */
24902static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24903{
24904 uint32_t pad, opc, XRc, XRb, XRa;
24905
24906 pad = extract32(ctx->opcode, 21, 5);
24907 opc = extract32(ctx->opcode, 18, 3);
24908 XRc = extract32(ctx->opcode, 14, 4);
24909 XRb = extract32(ctx->opcode, 10, 4);
24910 XRa = extract32(ctx->opcode, 6, 4);
24911
24912 if (unlikely(pad != 0)) {
24913 /* opcode padding incorrect -> do nothing */
24914 } else if (unlikely(XRa == 0)) {
24915 /* destination is zero register -> do nothing */
24916 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24917 /* both operands zero registers -> just set destination to zero */
24918 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24919 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24920 /* exactly one operand is zero register - find which one is not...*/
24921 uint32_t XRx = XRb ? XRb : XRc;
24922 /* ...and do max/min operation with one operand 0 */
24923 if (opc == OPC_MXU_S32MAX) {
24924 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24925 } else {
24926 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24927 }
24928 } else if (unlikely(XRb == XRc)) {
24929 /* both operands same -> just set destination to one of them */
24930 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24931 } else {
24932 /* the most general case */
24933 if (opc == OPC_MXU_S32MAX) {
24934 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24935 mxu_gpr[XRc - 1]);
24936 } else {
24937 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24938 mxu_gpr[XRc - 1]);
24939 }
24940 }
24941}
24942
24943/*
24944 * D16MAX
24945 * Update XRa with the 16-bit-wise maximums of signed integers
24946 * contained in XRb and XRc.
24947 *
24948 * D16MIN
24949 * Update XRa with the 16-bit-wise minimums of signed integers
24950 * contained in XRb and XRc.
24951 *
24952 * 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
24953 * +-----------+---------+-----+-------+-------+-------+-----------+
24954 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
24955 * +-----------+---------+-----+-------+-------+-------+-----------+
24956 */
24957static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
24958{
24959 uint32_t pad, opc, XRc, XRb, XRa;
24960
24961 pad = extract32(ctx->opcode, 21, 5);
24962 opc = extract32(ctx->opcode, 18, 3);
24963 XRc = extract32(ctx->opcode, 14, 4);
24964 XRb = extract32(ctx->opcode, 10, 4);
24965 XRa = extract32(ctx->opcode, 6, 4);
24966
24967 if (unlikely(pad != 0)) {
24968 /* opcode padding incorrect -> do nothing */
24969 } else if (unlikely(XRc == 0)) {
24970 /* destination is zero register -> do nothing */
24971 } else if (unlikely((XRb == 0) && (XRa == 0))) {
24972 /* both operands zero registers -> just set destination to zero */
24973 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
24974 } else if (unlikely((XRb == 0) || (XRa == 0))) {
24975 /* exactly one operand is zero register - find which one is not...*/
24976 uint32_t XRx = XRb ? XRb : XRc;
24977 /* ...and do half-word-wise max/min with one operand 0 */
24978 TCGv_i32 t0 = tcg_temp_new();
24979 TCGv_i32 t1 = tcg_const_i32(0);
24980
24981 /* the left half-word first */
24982 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
24983 if (opc == OPC_MXU_D16MAX) {
24984 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
24985 } else {
24986 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
24987 }
24988
24989 /* the right half-word */
24990 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
24991 /* move half-words to the leftmost position */
24992 tcg_gen_shli_i32(t0, t0, 16);
24993 /* t0 will be max/min of t0 and t1 */
24994 if (opc == OPC_MXU_D16MAX) {
24995 tcg_gen_smax_i32(t0, t0, t1);
24996 } else {
24997 tcg_gen_smin_i32(t0, t0, t1);
24998 }
24999 /* return resulting half-words to its original position */
25000 tcg_gen_shri_i32(t0, t0, 16);
25001 /* finaly update the destination */
25002 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25003
25004 tcg_temp_free(t1);
25005 tcg_temp_free(t0);
25006 } else if (unlikely(XRb == XRc)) {
25007 /* both operands same -> just set destination to one of them */
25008 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25009 } else {
25010 /* the most general case */
25011 TCGv_i32 t0 = tcg_temp_new();
25012 TCGv_i32 t1 = tcg_temp_new();
25013
25014 /* the left half-word first */
25015 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25016 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25017 if (opc == OPC_MXU_D16MAX) {
25018 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25019 } else {
25020 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25021 }
25022
25023 /* the right half-word */
25024 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25025 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25026 /* move half-words to the leftmost position */
25027 tcg_gen_shli_i32(t0, t0, 16);
25028 tcg_gen_shli_i32(t1, t1, 16);
25029 /* t0 will be max/min of t0 and t1 */
25030 if (opc == OPC_MXU_D16MAX) {
25031 tcg_gen_smax_i32(t0, t0, t1);
25032 } else {
25033 tcg_gen_smin_i32(t0, t0, t1);
25034 }
25035 /* return resulting half-words to its original position */
25036 tcg_gen_shri_i32(t0, t0, 16);
25037 /* finaly update the destination */
25038 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25039
25040 tcg_temp_free(t1);
25041 tcg_temp_free(t0);
25042 }
25043}
25044
25045/*
25046 * Q8MAX
25047 * Update XRa with the 8-bit-wise maximums of signed integers
25048 * contained in XRb and XRc.
25049 *
25050 * Q8MIN
25051 * Update XRa with the 8-bit-wise minimums of signed integers
25052 * contained in XRb and XRc.
25053 *
25054 * 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
25055 * +-----------+---------+-----+-------+-------+-------+-----------+
25056 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25057 * +-----------+---------+-----+-------+-------+-------+-----------+
25058 */
25059static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25060{
25061 uint32_t pad, opc, XRc, XRb, XRa;
25062
25063 pad = extract32(ctx->opcode, 21, 5);
25064 opc = extract32(ctx->opcode, 18, 3);
25065 XRc = extract32(ctx->opcode, 14, 4);
25066 XRb = extract32(ctx->opcode, 10, 4);
25067 XRa = extract32(ctx->opcode, 6, 4);
25068
25069 if (unlikely(pad != 0)) {
25070 /* opcode padding incorrect -> do nothing */
25071 } else if (unlikely(XRa == 0)) {
25072 /* destination is zero register -> do nothing */
25073 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25074 /* both operands zero registers -> just set destination to zero */
25075 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25076 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25077 /* exactly one operand is zero register - make it be the first...*/
25078 uint32_t XRx = XRb ? XRb : XRc;
25079 /* ...and do byte-wise max/min with one operand 0 */
25080 TCGv_i32 t0 = tcg_temp_new();
25081 TCGv_i32 t1 = tcg_const_i32(0);
25082 int32_t i;
25083
25084 /* the leftmost byte (byte 3) first */
25085 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25086 if (opc == OPC_MXU_Q8MAX) {
25087 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25088 } else {
25089 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25090 }
25091
25092 /* bytes 2, 1, 0 */
25093 for (i = 2; i >= 0; i--) {
25094 /* extract the byte */
25095 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25096 /* move the byte to the leftmost position */
25097 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25098 /* t0 will be max/min of t0 and t1 */
25099 if (opc == OPC_MXU_Q8MAX) {
25100 tcg_gen_smax_i32(t0, t0, t1);
25101 } else {
25102 tcg_gen_smin_i32(t0, t0, t1);
25103 }
25104 /* return resulting byte to its original position */
25105 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25106 /* finaly update the destination */
25107 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25108 }
25109
25110 tcg_temp_free(t1);
25111 tcg_temp_free(t0);
25112 } else if (unlikely(XRb == XRc)) {
25113 /* both operands same -> just set destination to one of them */
25114 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25115 } else {
25116 /* the most general case */
25117 TCGv_i32 t0 = tcg_temp_new();
25118 TCGv_i32 t1 = tcg_temp_new();
25119 int32_t i;
25120
25121 /* the leftmost bytes (bytes 3) first */
25122 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25123 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25124 if (opc == OPC_MXU_Q8MAX) {
25125 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25126 } else {
25127 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25128 }
25129
25130 /* bytes 2, 1, 0 */
25131 for (i = 2; i >= 0; i--) {
25132 /* extract corresponding bytes */
25133 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25134 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25135 /* move the bytes to the leftmost position */
25136 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25137 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25138 /* t0 will be max/min of t0 and t1 */
25139 if (opc == OPC_MXU_Q8MAX) {
25140 tcg_gen_smax_i32(t0, t0, t1);
25141 } else {
25142 tcg_gen_smin_i32(t0, t0, t1);
25143 }
25144 /* return resulting byte to its original position */
25145 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25146 /* finaly update the destination */
25147 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25148 }
25149
25150 tcg_temp_free(t1);
25151 tcg_temp_free(t0);
25152 }
25153}
25154
25155
79f5fee7
AM
25156/*
25157 * MXU instruction category: align
25158 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25159 *
25160 * S32ALN S32ALNI
25161 */
25162
25163/*
25164 * S32ALNI XRc, XRb, XRa, optn3
25165 * Arrange bytes from XRb and XRc according to one of five sets of
25166 * rules determined by optn3, and place the result in XRa.
25167 *
25168 * 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
25169 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25170 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25171 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25172 *
25173 */
25174static void gen_mxu_S32ALNI(DisasContext *ctx)
25175{
25176 uint32_t optn3, pad, XRc, XRb, XRa;
25177
25178 optn3 = extract32(ctx->opcode, 23, 3);
25179 pad = extract32(ctx->opcode, 21, 2);
25180 XRc = extract32(ctx->opcode, 14, 4);
25181 XRb = extract32(ctx->opcode, 10, 4);
25182 XRa = extract32(ctx->opcode, 6, 4);
25183
25184 if (unlikely(pad != 0)) {
25185 /* opcode padding incorrect -> do nothing */
25186 } else if (unlikely(XRa == 0)) {
25187 /* destination is zero register -> do nothing */
25188 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25189 /* both operands zero registers -> just set destination to all 0s */
25190 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25191 } else if (unlikely(XRb == 0)) {
25192 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25193 switch (optn3) {
25194 case MXU_OPTN3_PTN0:
25195 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25196 break;
25197 case MXU_OPTN3_PTN1:
25198 case MXU_OPTN3_PTN2:
25199 case MXU_OPTN3_PTN3:
25200 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25201 8 * (4 - optn3));
25202 break;
25203 case MXU_OPTN3_PTN4:
25204 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25205 break;
25206 }
25207 } else if (unlikely(XRc == 0)) {
25208 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25209 switch (optn3) {
25210 case MXU_OPTN3_PTN0:
25211 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25212 break;
25213 case MXU_OPTN3_PTN1:
25214 case MXU_OPTN3_PTN2:
25215 case MXU_OPTN3_PTN3:
25216 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25217 break;
25218 case MXU_OPTN3_PTN4:
25219 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25220 break;
25221 }
25222 } else if (unlikely(XRb == XRc)) {
25223 /* both operands same -> just rotation or moving from any of them */
25224 switch (optn3) {
25225 case MXU_OPTN3_PTN0:
25226 case MXU_OPTN3_PTN4:
25227 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25228 break;
25229 case MXU_OPTN3_PTN1:
25230 case MXU_OPTN3_PTN2:
25231 case MXU_OPTN3_PTN3:
25232 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25233 break;
25234 }
25235 } else {
25236 /* the most general case */
25237 switch (optn3) {
25238 case MXU_OPTN3_PTN0:
25239 {
25240 /* */
25241 /* XRb XRc */
25242 /* +---------------+ */
25243 /* | A B C D | E F G H */
25244 /* +-------+-------+ */
25245 /* | */
25246 /* XRa */
25247 /* */
25248
25249 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25250 }
25251 break;
25252 case MXU_OPTN3_PTN1:
25253 {
25254 /* */
25255 /* XRb XRc */
25256 /* +-------------------+ */
25257 /* A | B C D E | F G H */
25258 /* +---------+---------+ */
25259 /* | */
25260 /* XRa */
25261 /* */
25262
25263 TCGv_i32 t0 = tcg_temp_new();
25264 TCGv_i32 t1 = tcg_temp_new();
25265
25266 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25267 tcg_gen_shli_i32(t0, t0, 8);
25268
25269 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25270 tcg_gen_shri_i32(t1, t1, 24);
25271
25272 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25273
25274 tcg_temp_free(t1);
25275 tcg_temp_free(t0);
25276 }
25277 break;
25278 case MXU_OPTN3_PTN2:
25279 {
25280 /* */
25281 /* XRb XRc */
25282 /* +-------------------+ */
25283 /* A B | C D E F | G H */
25284 /* +---------+---------+ */
25285 /* | */
25286 /* XRa */
25287 /* */
25288
25289 TCGv_i32 t0 = tcg_temp_new();
25290 TCGv_i32 t1 = tcg_temp_new();
25291
25292 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25293 tcg_gen_shli_i32(t0, t0, 16);
25294
25295 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25296 tcg_gen_shri_i32(t1, t1, 16);
25297
25298 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25299
25300 tcg_temp_free(t1);
25301 tcg_temp_free(t0);
25302 }
25303 break;
25304 case MXU_OPTN3_PTN3:
25305 {
25306 /* */
25307 /* XRb XRc */
25308 /* +-------------------+ */
25309 /* A B C | D E F G | H */
25310 /* +---------+---------+ */
25311 /* | */
25312 /* XRa */
25313 /* */
25314
25315 TCGv_i32 t0 = tcg_temp_new();
25316 TCGv_i32 t1 = tcg_temp_new();
25317
25318 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25319 tcg_gen_shli_i32(t0, t0, 24);
25320
25321 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25322 tcg_gen_shri_i32(t1, t1, 8);
25323
25324 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25325
25326 tcg_temp_free(t1);
25327 tcg_temp_free(t0);
25328 }
25329 break;
25330 case MXU_OPTN3_PTN4:
25331 {
25332 /* */
25333 /* XRb XRc */
25334 /* +---------------+ */
25335 /* A B C D | E F G H | */
25336 /* +-------+-------+ */
25337 /* | */
25338 /* XRa */
25339 /* */
25340
25341 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25342 }
25343 break;
25344 }
25345 }
25346}
25347
25348
96992d1a
CJ
25349/*
25350 * Decoding engine for MXU
25351 * =======================
25352 */
25353
03f40088
AM
25354/*
25355 *
25356 * Decode MXU pool00
25357 *
25358 * 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
25359 * +-----------+---------+-----+-------+-------+-------+-----------+
25360 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25361 * +-----------+---------+-----+-------+-------+-------+-----------+
25362 *
25363 */
25364static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25365{
25366 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25367
25368 switch (opcode) {
25369 case OPC_MXU_S32MAX:
03f40088 25370 case OPC_MXU_S32MIN:
bb84cbf3 25371 gen_mxu_S32MAX_S32MIN(ctx);
03f40088
AM
25372 break;
25373 case OPC_MXU_D16MAX:
03f40088 25374 case OPC_MXU_D16MIN:
bb84cbf3 25375 gen_mxu_D16MAX_D16MIN(ctx);
03f40088
AM
25376 break;
25377 case OPC_MXU_Q8MAX:
03f40088 25378 case OPC_MXU_Q8MIN:
bb84cbf3 25379 gen_mxu_Q8MAX_Q8MIN(ctx);
03f40088
AM
25380 break;
25381 case OPC_MXU_Q8SLT:
25382 /* TODO: Implement emulation of Q8SLT instruction. */
25383 MIPS_INVAL("OPC_MXU_Q8SLT");
25384 generate_exception_end(ctx, EXCP_RI);
25385 break;
25386 case OPC_MXU_Q8SLTU:
25387 /* TODO: Implement emulation of Q8SLTU instruction. */
25388 MIPS_INVAL("OPC_MXU_Q8SLTU");
25389 generate_exception_end(ctx, EXCP_RI);
25390 break;
25391 default:
25392 MIPS_INVAL("decode_opc_mxu");
25393 generate_exception_end(ctx, EXCP_RI);
25394 break;
25395 }
25396}
25397
25398/*
25399 *
25400 * Decode MXU pool01
25401 *
25402 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25403 * 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
25404 * +-----------+---------+-----+-------+-------+-------+-----------+
25405 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25406 * +-----------+---------+-----+-------+-------+-------+-----------+
25407 *
25408 * Q8ADD:
25409 * 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
25410 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25411 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25412 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25413 *
25414 */
25415static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25416{
25417 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25418
25419 switch (opcode) {
25420 case OPC_MXU_S32SLT:
25421 /* TODO: Implement emulation of S32SLT instruction. */
25422 MIPS_INVAL("OPC_MXU_S32SLT");
25423 generate_exception_end(ctx, EXCP_RI);
25424 break;
25425 case OPC_MXU_D16SLT:
25426 /* TODO: Implement emulation of D16SLT instruction. */
25427 MIPS_INVAL("OPC_MXU_D16SLT");
25428 generate_exception_end(ctx, EXCP_RI);
25429 break;
25430 case OPC_MXU_D16AVG:
25431 /* TODO: Implement emulation of D16AVG instruction. */
25432 MIPS_INVAL("OPC_MXU_D16AVG");
25433 generate_exception_end(ctx, EXCP_RI);
25434 break;
25435 case OPC_MXU_D16AVGR:
25436 /* TODO: Implement emulation of D16AVGR instruction. */
25437 MIPS_INVAL("OPC_MXU_D16AVGR");
25438 generate_exception_end(ctx, EXCP_RI);
25439 break;
25440 case OPC_MXU_Q8AVG:
25441 /* TODO: Implement emulation of Q8AVG instruction. */
25442 MIPS_INVAL("OPC_MXU_Q8AVG");
25443 generate_exception_end(ctx, EXCP_RI);
25444 break;
25445 case OPC_MXU_Q8AVGR:
25446 /* TODO: Implement emulation of Q8AVGR instruction. */
25447 MIPS_INVAL("OPC_MXU_Q8AVGR");
25448 generate_exception_end(ctx, EXCP_RI);
25449 break;
25450 case OPC_MXU_Q8ADD:
25451 /* TODO: Implement emulation of Q8ADD instruction. */
25452 MIPS_INVAL("OPC_MXU_Q8ADD");
25453 generate_exception_end(ctx, EXCP_RI);
25454 break;
25455 default:
25456 MIPS_INVAL("decode_opc_mxu");
25457 generate_exception_end(ctx, EXCP_RI);
25458 break;
25459 }
25460}
25461
25462/*
25463 *
25464 * Decode MXU pool02
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|x x x| XRc | XRb | XRa |MXU__POOL02|
25469 * +-----------+---------+-----+-------+-------+-------+-----------+
25470 *
25471 */
25472static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25473{
25474 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25475
25476 switch (opcode) {
25477 case OPC_MXU_S32CPS:
25478 /* TODO: Implement emulation of S32CPS instruction. */
25479 MIPS_INVAL("OPC_MXU_S32CPS");
25480 generate_exception_end(ctx, EXCP_RI);
25481 break;
25482 case OPC_MXU_D16CPS:
25483 /* TODO: Implement emulation of D16CPS instruction. */
25484 MIPS_INVAL("OPC_MXU_D16CPS");
25485 generate_exception_end(ctx, EXCP_RI);
25486 break;
25487 case OPC_MXU_Q8ABD:
25488 /* TODO: Implement emulation of Q8ABD instruction. */
25489 MIPS_INVAL("OPC_MXU_Q8ABD");
25490 generate_exception_end(ctx, EXCP_RI);
25491 break;
25492 case OPC_MXU_Q16SAT:
25493 /* TODO: Implement emulation of Q16SAT instruction. */
25494 MIPS_INVAL("OPC_MXU_Q16SAT");
25495 generate_exception_end(ctx, EXCP_RI);
25496 break;
25497 default:
25498 MIPS_INVAL("decode_opc_mxu");
25499 generate_exception_end(ctx, EXCP_RI);
25500 break;
25501 }
25502}
25503
25504/*
25505 *
25506 * Decode MXU pool03
25507 *
25508 * D16MULF:
25509 * 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
25510 * +-----------+---+---+-------+-------+-------+-------+-----------+
25511 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25512 * +-----------+---+---+-------+-------+-------+-------+-----------+
25513 *
25514 * D16MULE:
25515 * 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
25516 * +-----------+---+---+-------+-------+-------+-------+-----------+
25517 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25518 * +-----------+---+---+-------+-------+-------+-------+-----------+
25519 *
25520 */
25521static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25522{
25523 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25524
25525 switch (opcode) {
25526 case OPC_MXU_D16MULF:
25527 /* TODO: Implement emulation of D16MULF instruction. */
25528 MIPS_INVAL("OPC_MXU_D16MULF");
25529 generate_exception_end(ctx, EXCP_RI);
25530 break;
25531 case OPC_MXU_D16MULE:
25532 /* TODO: Implement emulation of D16MULE instruction. */
25533 MIPS_INVAL("OPC_MXU_D16MULE");
25534 generate_exception_end(ctx, EXCP_RI);
25535 break;
25536 default:
25537 MIPS_INVAL("decode_opc_mxu");
25538 generate_exception_end(ctx, EXCP_RI);
25539 break;
25540 }
25541}
25542
25543/*
25544 *
25545 * Decode MXU pool04
25546 *
25547 * 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
25548 * +-----------+---------+-+-------------------+-------+-----------+
25549 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25550 * +-----------+---------+-+-------------------+-------+-----------+
25551 *
25552 */
25553static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25554{
25555 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25556
25557 switch (opcode) {
25558 case OPC_MXU_S32LDD:
03f40088 25559 case OPC_MXU_S32LDDR:
4ca83721 25560 gen_mxu_s32ldd_s32lddr(ctx);
03f40088
AM
25561 break;
25562 default:
25563 MIPS_INVAL("decode_opc_mxu");
25564 generate_exception_end(ctx, EXCP_RI);
25565 break;
25566 }
25567}
25568
25569/*
25570 *
25571 * Decode MXU pool05
25572 *
25573 * 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
25574 * +-----------+---------+-+-------------------+-------+-----------+
25575 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25576 * +-----------+---------+-+-------------------+-------+-----------+
25577 *
25578 */
25579static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25580{
25581 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25582
25583 switch (opcode) {
25584 case OPC_MXU_S32STD:
25585 /* TODO: Implement emulation of S32STD instruction. */
25586 MIPS_INVAL("OPC_MXU_S32STD");
25587 generate_exception_end(ctx, EXCP_RI);
25588 break;
25589 case OPC_MXU_S32STDR:
25590 /* TODO: Implement emulation of S32STDR instruction. */
25591 MIPS_INVAL("OPC_MXU_S32STDR");
25592 generate_exception_end(ctx, EXCP_RI);
25593 break;
25594 default:
25595 MIPS_INVAL("decode_opc_mxu");
25596 generate_exception_end(ctx, EXCP_RI);
25597 break;
25598 }
25599}
25600
25601/*
25602 *
25603 * Decode MXU pool06
25604 *
25605 * 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
25606 * +-----------+---------+---------+---+-------+-------+-----------+
25607 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
25608 * +-----------+---------+---------+---+-------+-------+-----------+
25609 *
25610 */
25611static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25612{
25613 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25614
25615 switch (opcode) {
25616 case OPC_MXU_S32LDDV:
25617 /* TODO: Implement emulation of S32LDDV instruction. */
25618 MIPS_INVAL("OPC_MXU_S32LDDV");
25619 generate_exception_end(ctx, EXCP_RI);
25620 break;
25621 case OPC_MXU_S32LDDVR:
25622 /* TODO: Implement emulation of S32LDDVR instruction. */
25623 MIPS_INVAL("OPC_MXU_S32LDDVR");
25624 generate_exception_end(ctx, EXCP_RI);
25625 break;
25626 default:
25627 MIPS_INVAL("decode_opc_mxu");
25628 generate_exception_end(ctx, EXCP_RI);
25629 break;
25630 }
25631}
25632
25633/*
25634 *
25635 * Decode MXU pool07
25636 *
25637 * 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
25638 * +-----------+---------+---------+---+-------+-------+-----------+
25639 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
25640 * +-----------+---------+---------+---+-------+-------+-----------+
25641 *
25642 */
25643static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25644{
25645 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25646
25647 switch (opcode) {
25648 case OPC_MXU_S32STDV:
25649 /* TODO: Implement emulation of S32TDV instruction. */
25650 MIPS_INVAL("OPC_MXU_S32TDV");
25651 generate_exception_end(ctx, EXCP_RI);
25652 break;
25653 case OPC_MXU_S32STDVR:
25654 /* TODO: Implement emulation of S32TDVR instruction. */
25655 MIPS_INVAL("OPC_MXU_S32TDVR");
25656 generate_exception_end(ctx, EXCP_RI);
25657 break;
25658 default:
25659 MIPS_INVAL("decode_opc_mxu");
25660 generate_exception_end(ctx, EXCP_RI);
25661 break;
25662 }
25663}
25664
25665/*
25666 *
25667 * Decode MXU pool08
25668 *
25669 * 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
25670 * +-----------+---------+-+-------------------+-------+-----------+
25671 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
25672 * +-----------+---------+-+-------------------+-------+-----------+
25673 *
25674*/
25675static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25676{
25677 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25678
25679 switch (opcode) {
25680 case OPC_MXU_S32LDI:
25681 /* TODO: Implement emulation of S32LDI instruction. */
25682 MIPS_INVAL("OPC_MXU_S32LDI");
25683 generate_exception_end(ctx, EXCP_RI);
25684 break;
25685 case OPC_MXU_S32LDIR:
25686 /* TODO: Implement emulation of S32LDIR instruction. */
25687 MIPS_INVAL("OPC_MXU_S32LDIR");
25688 generate_exception_end(ctx, EXCP_RI);
25689 break;
25690 default:
25691 MIPS_INVAL("decode_opc_mxu");
25692 generate_exception_end(ctx, EXCP_RI);
25693 break;
25694 }
25695}
25696
25697/*
25698 *
25699 * Decode MXU pool09
25700 *
25701 * 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
25702 * +-----------+---------+-+-------------------+-------+-----------+
25703 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
25704 * +-----------+---------+-+-------------------+-------+-----------+
25705 *
25706 */
25707static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25708{
25709 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25710
25711 switch (opcode) {
25712 case OPC_MXU_S32SDI:
25713 /* TODO: Implement emulation of S32SDI instruction. */
25714 MIPS_INVAL("OPC_MXU_S32SDI");
25715 generate_exception_end(ctx, EXCP_RI);
25716 break;
25717 case OPC_MXU_S32SDIR:
25718 /* TODO: Implement emulation of S32SDIR instruction. */
25719 MIPS_INVAL("OPC_MXU_S32SDIR");
25720 generate_exception_end(ctx, EXCP_RI);
25721 break;
25722 default:
25723 MIPS_INVAL("decode_opc_mxu");
25724 generate_exception_end(ctx, EXCP_RI);
25725 break;
25726 }
25727}
25728
25729/*
25730 *
25731 * Decode MXU pool10
25732 *
25733 * 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
25734 * +-----------+---------+---------+---+-------+-------+-----------+
25735 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25736 * +-----------+---------+---------+---+-------+-------+-----------+
25737 *
25738 */
25739static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25740{
25741 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25742
25743 switch (opcode) {
25744 case OPC_MXU_S32LDIV:
25745 /* TODO: Implement emulation of S32LDIV instruction. */
25746 MIPS_INVAL("OPC_MXU_S32LDIV");
25747 generate_exception_end(ctx, EXCP_RI);
25748 break;
25749 case OPC_MXU_S32LDIVR:
25750 /* TODO: Implement emulation of S32LDIVR instruction. */
25751 MIPS_INVAL("OPC_MXU_S32LDIVR");
25752 generate_exception_end(ctx, EXCP_RI);
25753 break;
25754 default:
25755 MIPS_INVAL("decode_opc_mxu");
25756 generate_exception_end(ctx, EXCP_RI);
25757 break;
25758 }
25759}
25760
25761/*
25762 *
25763 * Decode MXU pool11
25764 *
25765 * 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
25766 * +-----------+---------+---------+---+-------+-------+-----------+
25767 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25768 * +-----------+---------+---------+---+-------+-------+-----------+
25769 *
25770 */
25771static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25772{
25773 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25774
25775 switch (opcode) {
25776 case OPC_MXU_S32SDIV:
25777 /* TODO: Implement emulation of S32SDIV instruction. */
25778 MIPS_INVAL("OPC_MXU_S32SDIV");
25779 generate_exception_end(ctx, EXCP_RI);
25780 break;
25781 case OPC_MXU_S32SDIVR:
25782 /* TODO: Implement emulation of S32SDIVR instruction. */
25783 MIPS_INVAL("OPC_MXU_S32SDIVR");
25784 generate_exception_end(ctx, EXCP_RI);
25785 break;
25786 default:
25787 MIPS_INVAL("decode_opc_mxu");
25788 generate_exception_end(ctx, EXCP_RI);
25789 break;
25790 }
25791}
25792
25793/*
25794 *
25795 * Decode MXU pool12
25796 *
25797 * 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
25798 * +-----------+---+---+-------+-------+-------+-------+-----------+
25799 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
25800 * +-----------+---+---+-------+-------+-------+-------+-----------+
25801 *
25802 */
25803static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25804{
25805 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25806
25807 switch (opcode) {
25808 case OPC_MXU_D32ACC:
25809 /* TODO: Implement emulation of D32ACC instruction. */
25810 MIPS_INVAL("OPC_MXU_D32ACC");
25811 generate_exception_end(ctx, EXCP_RI);
25812 break;
25813 case OPC_MXU_D32ACCM:
25814 /* TODO: Implement emulation of D32ACCM instruction. */
25815 MIPS_INVAL("OPC_MXU_D32ACCM");
25816 generate_exception_end(ctx, EXCP_RI);
25817 break;
25818 case OPC_MXU_D32ASUM:
25819 /* TODO: Implement emulation of D32ASUM instruction. */
25820 MIPS_INVAL("OPC_MXU_D32ASUM");
25821 generate_exception_end(ctx, EXCP_RI);
25822 break;
25823 default:
25824 MIPS_INVAL("decode_opc_mxu");
25825 generate_exception_end(ctx, EXCP_RI);
25826 break;
25827 }
25828}
25829
25830/*
25831 *
25832 * Decode MXU pool13
25833 *
25834 * 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
25835 * +-----------+---+---+-------+-------+-------+-------+-----------+
25836 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
25837 * +-----------+---+---+-------+-------+-------+-------+-----------+
25838 *
25839 */
25840static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25841{
25842 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25843
25844 switch (opcode) {
25845 case OPC_MXU_Q16ACC:
25846 /* TODO: Implement emulation of Q16ACC instruction. */
25847 MIPS_INVAL("OPC_MXU_Q16ACC");
25848 generate_exception_end(ctx, EXCP_RI);
25849 break;
25850 case OPC_MXU_Q16ACCM:
25851 /* TODO: Implement emulation of Q16ACCM instruction. */
25852 MIPS_INVAL("OPC_MXU_Q16ACCM");
25853 generate_exception_end(ctx, EXCP_RI);
25854 break;
25855 case OPC_MXU_Q16ASUM:
25856 /* TODO: Implement emulation of Q16ASUM instruction. */
25857 MIPS_INVAL("OPC_MXU_Q16ASUM");
25858 generate_exception_end(ctx, EXCP_RI);
25859 break;
25860 default:
25861 MIPS_INVAL("decode_opc_mxu");
25862 generate_exception_end(ctx, EXCP_RI);
25863 break;
25864 }
25865}
25866
25867/*
25868 *
25869 * Decode MXU pool14
25870 *
25871 * Q8ADDE, Q8ACCE:
25872 * 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
25873 * +-----------+---+---+-------+-------+-------+-------+-----------+
25874 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
25875 * +-----------+---+---+-------+-------+-------+-------+-----------+
25876 *
25877 * D8SUM, D8SUMC:
25878 * 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
25879 * +-----------+---+---+-------+-------+-------+-------+-----------+
25880 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
25881 * +-----------+---+---+-------+-------+-------+-------+-----------+
25882 *
25883 */
25884static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25885{
25886 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25887
25888 switch (opcode) {
25889 case OPC_MXU_Q8ADDE:
25890 /* TODO: Implement emulation of Q8ADDE instruction. */
25891 MIPS_INVAL("OPC_MXU_Q8ADDE");
25892 generate_exception_end(ctx, EXCP_RI);
25893 break;
25894 case OPC_MXU_D8SUM:
25895 /* TODO: Implement emulation of D8SUM instruction. */
25896 MIPS_INVAL("OPC_MXU_D8SUM");
25897 generate_exception_end(ctx, EXCP_RI);
25898 break;
25899 case OPC_MXU_D8SUMC:
25900 /* TODO: Implement emulation of D8SUMC instruction. */
25901 MIPS_INVAL("OPC_MXU_D8SUMC");
25902 generate_exception_end(ctx, EXCP_RI);
25903 break;
25904 default:
25905 MIPS_INVAL("decode_opc_mxu");
25906 generate_exception_end(ctx, EXCP_RI);
25907 break;
25908 }
25909}
25910
25911/*
25912 *
25913 * Decode MXU pool15
25914 *
25915 * S32MUL, S32MULU, S32EXTRV:
25916 * 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
25917 * +-----------+---------+---------+---+-------+-------+-----------+
25918 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
25919 * +-----------+---------+---------+---+-------+-------+-----------+
25920 *
25921 * S32EXTR:
25922 * 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
25923 * +-----------+---------+---------+---+-------+-------+-----------+
25924 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
25925 * +-----------+---------+---------+---+-------+-------+-----------+
25926 *
25927 */
25928static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25929{
25930 uint32_t opcode = extract32(ctx->opcode, 14, 2);
25931
25932 switch (opcode) {
25933 case OPC_MXU_S32MUL:
25934 /* TODO: Implement emulation of S32MUL instruction. */
25935 MIPS_INVAL("OPC_MXU_S32MUL");
25936 generate_exception_end(ctx, EXCP_RI);
25937 break;
25938 case OPC_MXU_S32MULU:
25939 /* TODO: Implement emulation of S32MULU instruction. */
25940 MIPS_INVAL("OPC_MXU_S32MULU");
25941 generate_exception_end(ctx, EXCP_RI);
25942 break;
25943 case OPC_MXU_S32EXTR:
25944 /* TODO: Implement emulation of S32EXTR instruction. */
25945 MIPS_INVAL("OPC_MXU_S32EXTR");
25946 generate_exception_end(ctx, EXCP_RI);
25947 break;
25948 case OPC_MXU_S32EXTRV:
25949 /* TODO: Implement emulation of S32EXTRV instruction. */
25950 MIPS_INVAL("OPC_MXU_S32EXTRV");
25951 generate_exception_end(ctx, EXCP_RI);
25952 break;
25953 default:
25954 MIPS_INVAL("decode_opc_mxu");
25955 generate_exception_end(ctx, EXCP_RI);
25956 break;
25957 }
25958}
25959
25960/*
25961 *
25962 * Decode MXU pool16
25963 *
25964 * D32SARW:
25965 * 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
25966 * +-----------+---------+-----+-------+-------+-------+-----------+
25967 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
25968 * +-----------+---------+-----+-------+-------+-------+-----------+
25969 *
25970 * S32ALN:
25971 * 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
25972 * +-----------+---------+-----+-------+-------+-------+-----------+
25973 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
25974 * +-----------+---------+-----+-------+-------+-------+-----------+
25975 *
25976 * S32ALNI:
25977 * 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
25978 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25979 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25980 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25981 *
03f40088
AM
25982 * S32LUI:
25983 * 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
25984 * +-----------+-----+---+-----+-------+---------------+-----------+
25985 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
25986 * +-----------+-----+---+-----+-------+---------------+-----------+
25987 *
b621f018
AM
25988 * S32NOR, S32AND, S32OR, S32XOR:
25989 * 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
25990 * +-----------+---------+-----+-------+-------+-------+-----------+
25991 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25992 * +-----------+---------+-----+-------+-------+-------+-----------+
25993 *
03f40088
AM
25994 */
25995static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
25996{
25997 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25998
25999 switch (opcode) {
26000 case OPC_MXU_D32SARW:
26001 /* TODO: Implement emulation of D32SARW instruction. */
26002 MIPS_INVAL("OPC_MXU_D32SARW");
26003 generate_exception_end(ctx, EXCP_RI);
26004 break;
26005 case OPC_MXU_S32ALN:
26006 /* TODO: Implement emulation of S32ALN instruction. */
26007 MIPS_INVAL("OPC_MXU_S32ALN");
26008 generate_exception_end(ctx, EXCP_RI);
26009 break;
26010 case OPC_MXU_S32ALNI:
79f5fee7 26011 gen_mxu_S32ALNI(ctx);
03f40088 26012 break;
b621f018
AM
26013 case OPC_MXU_S32LUI:
26014 /* TODO: Implement emulation of S32LUI instruction. */
26015 MIPS_INVAL("OPC_MXU_S32LUI");
03f40088
AM
26016 generate_exception_end(ctx, EXCP_RI);
26017 break;
b621f018
AM
26018 case OPC_MXU_S32NOR:
26019 gen_mxu_S32NOR(ctx);
26020 break;
03f40088 26021 case OPC_MXU_S32AND:
b621f018 26022 gen_mxu_S32AND(ctx);
03f40088
AM
26023 break;
26024 case OPC_MXU_S32OR:
b621f018 26025 gen_mxu_S32OR(ctx);
03f40088
AM
26026 break;
26027 case OPC_MXU_S32XOR:
b621f018 26028 gen_mxu_S32XOR(ctx);
03f40088
AM
26029 break;
26030 default:
26031 MIPS_INVAL("decode_opc_mxu");
26032 generate_exception_end(ctx, EXCP_RI);
26033 break;
26034 }
26035}
26036
26037/*
26038 *
26039 * Decode MXU pool17
26040 *
26041 * 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
26042 * +-----------+---------+---------+---+---------+-----+-----------+
26043 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26044 * +-----------+---------+---------+---+---------+-----+-----------+
26045 *
26046 */
26047static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26048{
26049 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26050
26051 switch (opcode) {
26052 case OPC_MXU_LXW:
26053 /* TODO: Implement emulation of LXW instruction. */
26054 MIPS_INVAL("OPC_MXU_LXW");
26055 generate_exception_end(ctx, EXCP_RI);
26056 break;
26057 case OPC_MXU_LXH:
26058 /* TODO: Implement emulation of LXH instruction. */
26059 MIPS_INVAL("OPC_MXU_LXH");
26060 generate_exception_end(ctx, EXCP_RI);
26061 break;
26062 case OPC_MXU_LXHU:
26063 /* TODO: Implement emulation of LXHU instruction. */
26064 MIPS_INVAL("OPC_MXU_LXHU");
26065 generate_exception_end(ctx, EXCP_RI);
26066 break;
26067 case OPC_MXU_LXB:
26068 /* TODO: Implement emulation of LXB instruction. */
26069 MIPS_INVAL("OPC_MXU_LXB");
26070 generate_exception_end(ctx, EXCP_RI);
26071 break;
26072 case OPC_MXU_LXBU:
26073 /* TODO: Implement emulation of LXBU instruction. */
26074 MIPS_INVAL("OPC_MXU_LXBU");
26075 generate_exception_end(ctx, EXCP_RI);
26076 break;
26077 default:
26078 MIPS_INVAL("decode_opc_mxu");
26079 generate_exception_end(ctx, EXCP_RI);
26080 break;
26081 }
26082}
26083/*
26084 *
26085 * Decode MXU pool18
26086 *
26087 * 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 26088 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 26089 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
03f40088
AM
26090 * +-----------+---------+-----+-------+-------+-------+-----------+
26091 *
26092 */
c233bf07 26093static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26094{
26095 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26096
26097 switch (opcode) {
26098 case OPC_MXU_D32SLLV:
26099 /* TODO: Implement emulation of D32SLLV instruction. */
26100 MIPS_INVAL("OPC_MXU_D32SLLV");
26101 generate_exception_end(ctx, EXCP_RI);
26102 break;
26103 case OPC_MXU_D32SLRV:
26104 /* TODO: Implement emulation of D32SLRV instruction. */
26105 MIPS_INVAL("OPC_MXU_D32SLRV");
26106 generate_exception_end(ctx, EXCP_RI);
26107 break;
26108 case OPC_MXU_D32SARV:
26109 /* TODO: Implement emulation of D32SARV instruction. */
26110 MIPS_INVAL("OPC_MXU_D32SARV");
26111 generate_exception_end(ctx, EXCP_RI);
26112 break;
26113 case OPC_MXU_Q16SLLV:
26114 /* TODO: Implement emulation of Q16SLLV instruction. */
26115 MIPS_INVAL("OPC_MXU_Q16SLLV");
26116 generate_exception_end(ctx, EXCP_RI);
26117 break;
26118 case OPC_MXU_Q16SLRV:
26119 /* TODO: Implement emulation of Q16SLRV instruction. */
26120 MIPS_INVAL("OPC_MXU_Q16SLRV");
26121 generate_exception_end(ctx, EXCP_RI);
26122 break;
26123 case OPC_MXU_Q16SARV:
26124 /* TODO: Implement emulation of Q16SARV instruction. */
26125 MIPS_INVAL("OPC_MXU_Q16SARV");
26126 generate_exception_end(ctx, EXCP_RI);
26127 break;
26128 default:
26129 MIPS_INVAL("decode_opc_mxu");
26130 generate_exception_end(ctx, EXCP_RI);
26131 break;
26132 }
26133}
26134
26135/*
26136 *
c233bf07 26137 * Decode MXU pool19
03f40088
AM
26138 *
26139 * 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
26140 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 26141 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
03f40088
AM
26142 * +-----------+---+---+-------+-------+-------+-------+-----------+
26143 *
26144 */
c233bf07 26145static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26146{
26147 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26148
26149 switch (opcode) {
26150 case OPC_MXU_Q8MUL:
03f40088 26151 case OPC_MXU_Q8MULSU:
a9a4181b 26152 gen_mxu_q8mul_q8mulsu(ctx);
03f40088
AM
26153 break;
26154 default:
26155 MIPS_INVAL("decode_opc_mxu");
26156 generate_exception_end(ctx, EXCP_RI);
26157 break;
26158 }
26159}
26160
26161/*
26162 *
c233bf07 26163 * Decode MXU pool20
03f40088
AM
26164 *
26165 * 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
26166 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 26167 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
03f40088
AM
26168 * +-----------+---------+-----+-------+-------+-------+-----------+
26169 *
26170 */
c233bf07 26171static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26172{
26173 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26174
26175 switch (opcode) {
26176 case OPC_MXU_Q8MOVZ:
26177 /* TODO: Implement emulation of Q8MOVZ instruction. */
26178 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26179 generate_exception_end(ctx, EXCP_RI);
26180 break;
26181 case OPC_MXU_Q8MOVN:
26182 /* TODO: Implement emulation of Q8MOVN instruction. */
26183 MIPS_INVAL("OPC_MXU_Q8MOVN");
26184 generate_exception_end(ctx, EXCP_RI);
26185 break;
26186 case OPC_MXU_D16MOVZ:
26187 /* TODO: Implement emulation of D16MOVZ instruction. */
26188 MIPS_INVAL("OPC_MXU_D16MOVZ");
26189 generate_exception_end(ctx, EXCP_RI);
26190 break;
26191 case OPC_MXU_D16MOVN:
26192 /* TODO: Implement emulation of D16MOVN instruction. */
26193 MIPS_INVAL("OPC_MXU_D16MOVN");
26194 generate_exception_end(ctx, EXCP_RI);
26195 break;
26196 case OPC_MXU_S32MOVZ:
26197 /* TODO: Implement emulation of S32MOVZ instruction. */
26198 MIPS_INVAL("OPC_MXU_S32MOVZ");
26199 generate_exception_end(ctx, EXCP_RI);
26200 break;
26201 case OPC_MXU_S32MOVN:
26202 /* TODO: Implement emulation of S32MOVN instruction. */
26203 MIPS_INVAL("OPC_MXU_S32MOVN");
26204 generate_exception_end(ctx, EXCP_RI);
26205 break;
26206 default:
26207 MIPS_INVAL("decode_opc_mxu");
26208 generate_exception_end(ctx, EXCP_RI);
26209 break;
26210 }
26211}
26212
26213/*
26214 *
c233bf07 26215 * Decode MXU pool21
03f40088
AM
26216 *
26217 * 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
26218 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 26219 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
03f40088
AM
26220 * +-----------+---+---+-------+-------+-------+-------+-----------+
26221 *
26222 */
c233bf07 26223static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
26224{
26225 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26226
26227 switch (opcode) {
26228 case OPC_MXU_Q8MAC:
26229 /* TODO: Implement emulation of Q8MAC instruction. */
26230 MIPS_INVAL("OPC_MXU_Q8MAC");
26231 generate_exception_end(ctx, EXCP_RI);
26232 break;
26233 case OPC_MXU_Q8MACSU:
26234 /* TODO: Implement emulation of Q8MACSU instruction. */
26235 MIPS_INVAL("OPC_MXU_Q8MACSU");
26236 generate_exception_end(ctx, EXCP_RI);
26237 break;
26238 default:
26239 MIPS_INVAL("decode_opc_mxu");
26240 generate_exception_end(ctx, EXCP_RI);
26241 break;
26242 }
26243}
26244
26245
26246/*
26247 * Main MXU decoding function
26248 *
26249 * 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
26250 * +-----------+---------------------------------------+-----------+
26251 * | SPECIAL2 | |x x x x x x|
26252 * +-----------+---------------------------------------+-----------+
26253 *
26254 */
0a348b9a
AM
26255static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26256{
11d56f61
CJ
26257 /*
26258 * TODO: Investigate necessity of including handling of
26259 * CLZ, CLO, SDBB in this function, as they belong to
26260 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26261 */
03f40088
AM
26262 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26263
87860df5
AM
26264 if (opcode == OPC__MXU_MUL) {
26265 uint32_t rs, rt, rd, op1;
26266
26267 rs = extract32(ctx->opcode, 21, 5);
26268 rt = extract32(ctx->opcode, 16, 5);
26269 rd = extract32(ctx->opcode, 11, 5);
26270 op1 = MASK_SPECIAL2(ctx->opcode);
26271
26272 gen_arith(ctx, op1, rd, rs, rt);
26273
26274 return;
26275 }
26276
26277 if (opcode == OPC_MXU_S32M2I) {
26278 gen_mxu_s32m2i(ctx);
26279 return;
26280 }
26281
26282 if (opcode == OPC_MXU_S32I2M) {
26283 gen_mxu_s32i2m(ctx);
26284 return;
26285 }
26286
e5bf8a08
AM
26287 {
26288 TCGv t_mxu_cr = tcg_temp_new();
26289 TCGLabel *l_exit = gen_new_label();
26290
26291 gen_load_mxu_cr(t_mxu_cr);
26292 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26293 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26294
26295 switch (opcode) {
26296 case OPC_MXU_S32MADD:
26297 /* TODO: Implement emulation of S32MADD instruction. */
26298 MIPS_INVAL("OPC_MXU_S32MADD");
26299 generate_exception_end(ctx, EXCP_RI);
26300 break;
26301 case OPC_MXU_S32MADDU:
26302 /* TODO: Implement emulation of S32MADDU instruction. */
26303 MIPS_INVAL("OPC_MXU_S32MADDU");
26304 generate_exception_end(ctx, EXCP_RI);
26305 break;
26306 case OPC_MXU__POOL00:
26307 decode_opc_mxu__pool00(env, ctx);
26308 break;
26309 case OPC_MXU_S32MSUB:
26310 /* TODO: Implement emulation of S32MSUB instruction. */
26311 MIPS_INVAL("OPC_MXU_S32MSUB");
26312 generate_exception_end(ctx, EXCP_RI);
26313 break;
26314 case OPC_MXU_S32MSUBU:
26315 /* TODO: Implement emulation of S32MSUBU instruction. */
26316 MIPS_INVAL("OPC_MXU_S32MSUBU");
26317 generate_exception_end(ctx, EXCP_RI);
26318 break;
26319 case OPC_MXU__POOL01:
26320 decode_opc_mxu__pool01(env, ctx);
26321 break;
26322 case OPC_MXU__POOL02:
26323 decode_opc_mxu__pool02(env, ctx);
26324 break;
26325 case OPC_MXU_D16MUL:
26326 gen_mxu_d16mul(ctx);
26327 break;
26328 case OPC_MXU__POOL03:
26329 decode_opc_mxu__pool03(env, ctx);
26330 break;
26331 case OPC_MXU_D16MAC:
26332 gen_mxu_d16mac(ctx);
26333 break;
26334 case OPC_MXU_D16MACF:
26335 /* TODO: Implement emulation of D16MACF instruction. */
26336 MIPS_INVAL("OPC_MXU_D16MACF");
26337 generate_exception_end(ctx, EXCP_RI);
26338 break;
26339 case OPC_MXU_D16MADL:
26340 /* TODO: Implement emulation of D16MADL instruction. */
26341 MIPS_INVAL("OPC_MXU_D16MADL");
26342 generate_exception_end(ctx, EXCP_RI);
26343 break;
26344 case OPC_MXU_S16MAD:
26345 /* TODO: Implement emulation of S16MAD instruction. */
26346 MIPS_INVAL("OPC_MXU_S16MAD");
26347 generate_exception_end(ctx, EXCP_RI);
26348 break;
26349 case OPC_MXU_Q16ADD:
26350 /* TODO: Implement emulation of Q16ADD instruction. */
26351 MIPS_INVAL("OPC_MXU_Q16ADD");
26352 generate_exception_end(ctx, EXCP_RI);
26353 break;
26354 case OPC_MXU_D16MACE:
26355 /* TODO: Implement emulation of D16MACE instruction. */
26356 MIPS_INVAL("OPC_MXU_D16MACE");
26357 generate_exception_end(ctx, EXCP_RI);
26358 break;
26359 case OPC_MXU__POOL04:
26360 decode_opc_mxu__pool04(env, ctx);
26361 break;
26362 case OPC_MXU__POOL05:
26363 decode_opc_mxu__pool05(env, ctx);
26364 break;
26365 case OPC_MXU__POOL06:
26366 decode_opc_mxu__pool06(env, ctx);
26367 break;
26368 case OPC_MXU__POOL07:
26369 decode_opc_mxu__pool07(env, ctx);
26370 break;
26371 case OPC_MXU__POOL08:
26372 decode_opc_mxu__pool08(env, ctx);
26373 break;
26374 case OPC_MXU__POOL09:
26375 decode_opc_mxu__pool09(env, ctx);
26376 break;
26377 case OPC_MXU__POOL10:
26378 decode_opc_mxu__pool10(env, ctx);
26379 break;
26380 case OPC_MXU__POOL11:
26381 decode_opc_mxu__pool11(env, ctx);
26382 break;
26383 case OPC_MXU_D32ADD:
26384 /* TODO: Implement emulation of D32ADD instruction. */
26385 MIPS_INVAL("OPC_MXU_D32ADD");
26386 generate_exception_end(ctx, EXCP_RI);
26387 break;
26388 case OPC_MXU__POOL12:
26389 decode_opc_mxu__pool12(env, ctx);
26390 break;
26391 case OPC_MXU__POOL13:
26392 decode_opc_mxu__pool13(env, ctx);
26393 break;
26394 case OPC_MXU__POOL14:
26395 decode_opc_mxu__pool14(env, ctx);
26396 break;
26397 case OPC_MXU_Q8ACCE:
26398 /* TODO: Implement emulation of Q8ACCE instruction. */
26399 MIPS_INVAL("OPC_MXU_Q8ACCE");
26400 generate_exception_end(ctx, EXCP_RI);
26401 break;
26402 case OPC_MXU_S8LDD:
26403 gen_mxu_s8ldd(ctx);
26404 break;
26405 case OPC_MXU_S8STD:
26406 /* TODO: Implement emulation of S8STD instruction. */
26407 MIPS_INVAL("OPC_MXU_S8STD");
26408 generate_exception_end(ctx, EXCP_RI);
26409 break;
26410 case OPC_MXU_S8LDI:
26411 /* TODO: Implement emulation of S8LDI instruction. */
26412 MIPS_INVAL("OPC_MXU_S8LDI");
26413 generate_exception_end(ctx, EXCP_RI);
26414 break;
26415 case OPC_MXU_S8SDI:
26416 /* TODO: Implement emulation of S8SDI instruction. */
26417 MIPS_INVAL("OPC_MXU_S8SDI");
26418 generate_exception_end(ctx, EXCP_RI);
26419 break;
26420 case OPC_MXU__POOL15:
26421 decode_opc_mxu__pool15(env, ctx);
26422 break;
26423 case OPC_MXU__POOL16:
26424 decode_opc_mxu__pool16(env, ctx);
26425 break;
c233bf07
AM
26426 case OPC_MXU__POOL17:
26427 decode_opc_mxu__pool17(env, ctx);
e5bf8a08
AM
26428 break;
26429 case OPC_MXU_S16LDD:
26430 /* TODO: Implement emulation of S16LDD instruction. */
26431 MIPS_INVAL("OPC_MXU_S16LDD");
26432 generate_exception_end(ctx, EXCP_RI);
26433 break;
26434 case OPC_MXU_S16STD:
26435 /* TODO: Implement emulation of S16STD instruction. */
26436 MIPS_INVAL("OPC_MXU_S16STD");
26437 generate_exception_end(ctx, EXCP_RI);
26438 break;
26439 case OPC_MXU_S16LDI:
26440 /* TODO: Implement emulation of S16LDI instruction. */
26441 MIPS_INVAL("OPC_MXU_S16LDI");
26442 generate_exception_end(ctx, EXCP_RI);
26443 break;
26444 case OPC_MXU_S16SDI:
26445 /* TODO: Implement emulation of S16SDI instruction. */
26446 MIPS_INVAL("OPC_MXU_S16SDI");
26447 generate_exception_end(ctx, EXCP_RI);
26448 break;
26449 case OPC_MXU_D32SLL:
26450 /* TODO: Implement emulation of D32SLL instruction. */
26451 MIPS_INVAL("OPC_MXU_D32SLL");
26452 generate_exception_end(ctx, EXCP_RI);
26453 break;
26454 case OPC_MXU_D32SLR:
26455 /* TODO: Implement emulation of D32SLR instruction. */
26456 MIPS_INVAL("OPC_MXU_D32SLR");
26457 generate_exception_end(ctx, EXCP_RI);
26458 break;
26459 case OPC_MXU_D32SARL:
26460 /* TODO: Implement emulation of D32SARL instruction. */
26461 MIPS_INVAL("OPC_MXU_D32SARL");
26462 generate_exception_end(ctx, EXCP_RI);
26463 break;
26464 case OPC_MXU_D32SAR:
26465 /* TODO: Implement emulation of D32SAR instruction. */
26466 MIPS_INVAL("OPC_MXU_D32SAR");
26467 generate_exception_end(ctx, EXCP_RI);
26468 break;
26469 case OPC_MXU_Q16SLL:
26470 /* TODO: Implement emulation of Q16SLL instruction. */
26471 MIPS_INVAL("OPC_MXU_Q16SLL");
26472 generate_exception_end(ctx, EXCP_RI);
26473 break;
26474 case OPC_MXU_Q16SLR:
26475 /* TODO: Implement emulation of Q16SLR instruction. */
26476 MIPS_INVAL("OPC_MXU_Q16SLR");
26477 generate_exception_end(ctx, EXCP_RI);
26478 break;
c233bf07
AM
26479 case OPC_MXU__POOL18:
26480 decode_opc_mxu__pool18(env, ctx);
e5bf8a08
AM
26481 break;
26482 case OPC_MXU_Q16SAR:
26483 /* TODO: Implement emulation of Q16SAR instruction. */
26484 MIPS_INVAL("OPC_MXU_Q16SAR");
26485 generate_exception_end(ctx, EXCP_RI);
26486 break;
e5bf8a08
AM
26487 case OPC_MXU__POOL19:
26488 decode_opc_mxu__pool19(env, ctx);
26489 break;
26490 case OPC_MXU__POOL20:
26491 decode_opc_mxu__pool20(env, ctx);
26492 break;
c233bf07
AM
26493 case OPC_MXU__POOL21:
26494 decode_opc_mxu__pool21(env, ctx);
26495 break;
e5bf8a08
AM
26496 case OPC_MXU_Q16SCOP:
26497 /* TODO: Implement emulation of Q16SCOP instruction. */
26498 MIPS_INVAL("OPC_MXU_Q16SCOP");
26499 generate_exception_end(ctx, EXCP_RI);
26500 break;
26501 case OPC_MXU_Q8MADL:
26502 /* TODO: Implement emulation of Q8MADL instruction. */
26503 MIPS_INVAL("OPC_MXU_Q8MADL");
26504 generate_exception_end(ctx, EXCP_RI);
26505 break;
26506 case OPC_MXU_S32SFL:
26507 /* TODO: Implement emulation of S32SFL instruction. */
26508 MIPS_INVAL("OPC_MXU_S32SFL");
26509 generate_exception_end(ctx, EXCP_RI);
26510 break;
26511 case OPC_MXU_Q8SAD:
26512 /* TODO: Implement emulation of Q8SAD instruction. */
26513 MIPS_INVAL("OPC_MXU_Q8SAD");
26514 generate_exception_end(ctx, EXCP_RI);
26515 break;
26516 default:
26517 MIPS_INVAL("decode_opc_mxu");
26518 generate_exception_end(ctx, EXCP_RI);
26519 }
26520
26521 gen_set_label(l_exit);
26522 tcg_temp_free(t_mxu_cr);
03f40088 26523 }
0a348b9a
AM
26524}
26525
b621f018
AM
26526#endif /* !defined(TARGET_MIPS64) */
26527
03f40088 26528
10dc65db 26529static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
26530{
26531 int rs, rt, rd;
26532 uint32_t op1;
6c5c1e20 26533
4267d3e6
LA
26534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26535
099e5b4d
LA
26536 rs = (ctx->opcode >> 21) & 0x1f;
26537 rt = (ctx->opcode >> 16) & 0x1f;
26538 rd = (ctx->opcode >> 11) & 0x1f;
26539
26540 op1 = MASK_SPECIAL2(ctx->opcode);
26541 switch (op1) {
c2e19f3c
AM
26542 case OPC_MADD: /* Multiply and add/sub */
26543 case OPC_MADDU:
26544 case OPC_MSUB:
26545 case OPC_MSUBU:
099e5b4d
LA
26546 check_insn(ctx, ISA_MIPS32);
26547 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26548 break;
26549 case OPC_MUL:
099e5b4d
LA
26550 gen_arith(ctx, op1, rd, rs, rt);
26551 break;
fac5a073
LA
26552 case OPC_DIV_G_2F:
26553 case OPC_DIVU_G_2F:
26554 case OPC_MULT_G_2F:
26555 case OPC_MULTU_G_2F:
26556 case OPC_MOD_G_2F:
26557 case OPC_MODU_G_2F:
26558 check_insn(ctx, INSN_LOONGSON2F);
26559 gen_loongson_integer(ctx, op1, rd, rs, rt);
26560 break;
099e5b4d
LA
26561 case OPC_CLO:
26562 case OPC_CLZ:
26563 check_insn(ctx, ISA_MIPS32);
26564 gen_cl(ctx, op1, rd, rs);
26565 break;
26566 case OPC_SDBBP:
3b3c1694
LA
26567 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26568 gen_helper_do_semihosting(cpu_env);
26569 } else {
26570 /* XXX: not clear which exception should be raised
26571 * when in debug mode...
26572 */
26573 check_insn(ctx, ISA_MIPS32);
9c708c7f 26574 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 26575 }
099e5b4d 26576 break;
9b1a1d68 26577#if defined(TARGET_MIPS64)
099e5b4d
LA
26578 case OPC_DCLO:
26579 case OPC_DCLZ:
26580 check_insn(ctx, ISA_MIPS64);
26581 check_mips_64(ctx);
26582 gen_cl(ctx, op1, rd, rs);
26583 break;
4267d3e6
LA
26584 case OPC_DMULT_G_2F:
26585 case OPC_DMULTU_G_2F:
26586 case OPC_DDIV_G_2F:
26587 case OPC_DDIVU_G_2F:
26588 case OPC_DMOD_G_2F:
26589 case OPC_DMODU_G_2F:
26590 check_insn(ctx, INSN_LOONGSON2F);
26591 gen_loongson_integer(ctx, op1, rd, rs, rt);
26592 break;
10dc65db 26593#endif
4267d3e6
LA
26594 default: /* Invalid */
26595 MIPS_INVAL("special2_legacy");
9c708c7f 26596 generate_exception_end(ctx, EXCP_RI);
4267d3e6 26597 break;
10dc65db
LA
26598 }
26599}
26600
26601static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26602{
15eacb9b
YK
26603 int rs, rt, rd, sa;
26604 uint32_t op1, op2;
10dc65db
LA
26605 int16_t imm;
26606
26607 rs = (ctx->opcode >> 21) & 0x1f;
26608 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
26609 rd = (ctx->opcode >> 11) & 0x1f;
26610 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
26611 imm = (int16_t)ctx->opcode >> 7;
26612
26613 op1 = MASK_SPECIAL3(ctx->opcode);
26614 switch (op1) {
bf7910c6
LA
26615 case R6_OPC_PREF:
26616 if (rt >= 24) {
26617 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 26618 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
26619 }
26620 /* Treat as NOP. */
26621 break;
26622 case R6_OPC_CACHE:
40d48212 26623 check_cp0_enabled(ctx);
0d74a222
LA
26624 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26625 gen_cache_operation(ctx, rt, rs, imm);
26626 }
bf7910c6 26627 break;
10dc65db
LA
26628 case R6_OPC_SC:
26629 gen_st_cond(ctx, op1, rt, rs, imm);
26630 break;
26631 case R6_OPC_LL:
26632 gen_ld(ctx, op1, rt, rs, imm);
26633 break;
15eacb9b
YK
26634 case OPC_BSHFL:
26635 {
26636 if (rd == 0) {
26637 /* Treat as NOP. */
26638 break;
26639 }
15eacb9b
YK
26640 op2 = MASK_BSHFL(ctx->opcode);
26641 switch (op2) {
c2e19f3c 26642 case OPC_ALIGN:
373ecd38
AM
26643 case OPC_ALIGN_1:
26644 case OPC_ALIGN_2:
26645 case OPC_ALIGN_3:
821f2008 26646 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
26647 break;
26648 case OPC_BITSWAP:
1f1b4c00 26649 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
26650 break;
26651 }
15eacb9b
YK
26652 }
26653 break;
bf7910c6
LA
26654#if defined(TARGET_MIPS64)
26655 case R6_OPC_SCD:
26656 gen_st_cond(ctx, op1, rt, rs, imm);
26657 break;
26658 case R6_OPC_LLD:
26659 gen_ld(ctx, op1, rt, rs, imm);
26660 break;
15eacb9b
YK
26661 case OPC_DBSHFL:
26662 check_mips_64(ctx);
26663 {
26664 if (rd == 0) {
26665 /* Treat as NOP. */
26666 break;
26667 }
15eacb9b
YK
26668 op2 = MASK_DBSHFL(ctx->opcode);
26669 switch (op2) {
c2e19f3c 26670 case OPC_DALIGN:
373ecd38
AM
26671 case OPC_DALIGN_1:
26672 case OPC_DALIGN_2:
26673 case OPC_DALIGN_3:
26674 case OPC_DALIGN_4:
26675 case OPC_DALIGN_5:
26676 case OPC_DALIGN_6:
26677 case OPC_DALIGN_7:
821f2008 26678 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
26679 break;
26680 case OPC_DBITSWAP:
1f1b4c00 26681 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
26682 break;
26683 }
1f1b4c00 26684
15eacb9b
YK
26685 }
26686 break;
bf7910c6 26687#endif
10dc65db
LA
26688 default: /* Invalid */
26689 MIPS_INVAL("special3_r6");
9c708c7f 26690 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
26691 break;
26692 }
26693}
26694
26695static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26696{
fac5a073 26697 int rs, rt, rd;
099e5b4d 26698 uint32_t op1, op2;
099e5b4d
LA
26699
26700 rs = (ctx->opcode >> 21) & 0x1f;
26701 rt = (ctx->opcode >> 16) & 0x1f;
26702 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
26703
26704 op1 = MASK_SPECIAL3(ctx->opcode);
26705 switch (op1) {
c2e19f3c
AM
26706 case OPC_DIV_G_2E:
26707 case OPC_DIVU_G_2E:
26708 case OPC_MOD_G_2E:
26709 case OPC_MODU_G_2E:
26710 case OPC_MULT_G_2E:
26711 case OPC_MULTU_G_2E:
099e5b4d
LA
26712 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26713 * the same mask and op1. */
908f6be1 26714 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 26715 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 26716 switch (op2) {
099e5b4d
LA
26717 case OPC_ADDUH_QB:
26718 case OPC_ADDUH_R_QB:
26719 case OPC_ADDQH_PH:
26720 case OPC_ADDQH_R_PH:
26721 case OPC_ADDQH_W:
26722 case OPC_ADDQH_R_W:
26723 case OPC_SUBUH_QB:
26724 case OPC_SUBUH_R_QB:
26725 case OPC_SUBQH_PH:
26726 case OPC_SUBQH_R_PH:
26727 case OPC_SUBQH_W:
26728 case OPC_SUBQH_R_W:
461c08df
JL
26729 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26730 break;
099e5b4d
LA
26731 case OPC_MUL_PH:
26732 case OPC_MUL_S_PH:
26733 case OPC_MULQ_S_W:
26734 case OPC_MULQ_RS_W:
26735 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 26736 break;
461c08df 26737 default:
099e5b4d 26738 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 26739 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
26740 break;
26741 }
099e5b4d
LA
26742 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26743 gen_loongson_integer(ctx, op1, rd, rs, rt);
26744 } else {
9c708c7f 26745 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26746 }
26747 break;
26748 case OPC_LX_DSP:
26749 op2 = MASK_LX(ctx->opcode);
26750 switch (op2) {
26751#if defined(TARGET_MIPS64)
26752 case OPC_LDX:
26753#endif
26754 case OPC_LBUX:
26755 case OPC_LHX:
26756 case OPC_LWX:
26757 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26758 break;
26759 default: /* Invalid */
26760 MIPS_INVAL("MASK LX");
9c708c7f 26761 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26762 break;
26763 }
26764 break;
26765 case OPC_ABSQ_S_PH_DSP:
26766 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26767 switch (op2) {
26768 case OPC_ABSQ_S_QB:
26769 case OPC_ABSQ_S_PH:
26770 case OPC_ABSQ_S_W:
26771 case OPC_PRECEQ_W_PHL:
26772 case OPC_PRECEQ_W_PHR:
26773 case OPC_PRECEQU_PH_QBL:
26774 case OPC_PRECEQU_PH_QBR:
26775 case OPC_PRECEQU_PH_QBLA:
26776 case OPC_PRECEQU_PH_QBRA:
26777 case OPC_PRECEU_PH_QBL:
26778 case OPC_PRECEU_PH_QBR:
26779 case OPC_PRECEU_PH_QBLA:
26780 case OPC_PRECEU_PH_QBRA:
26781 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26782 break;
26783 case OPC_BITREV:
26784 case OPC_REPL_QB:
26785 case OPC_REPLV_QB:
26786 case OPC_REPL_PH:
26787 case OPC_REPLV_PH:
26788 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26789 break;
26790 default:
26791 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 26792 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26793 break;
26794 }
26795 break;
26796 case OPC_ADDU_QB_DSP:
26797 op2 = MASK_ADDU_QB(ctx->opcode);
26798 switch (op2) {
26799 case OPC_ADDQ_PH:
26800 case OPC_ADDQ_S_PH:
26801 case OPC_ADDQ_S_W:
26802 case OPC_ADDU_QB:
26803 case OPC_ADDU_S_QB:
26804 case OPC_ADDU_PH:
26805 case OPC_ADDU_S_PH:
26806 case OPC_SUBQ_PH:
26807 case OPC_SUBQ_S_PH:
26808 case OPC_SUBQ_S_W:
26809 case OPC_SUBU_QB:
26810 case OPC_SUBU_S_QB:
26811 case OPC_SUBU_PH:
26812 case OPC_SUBU_S_PH:
26813 case OPC_ADDSC:
26814 case OPC_ADDWC:
26815 case OPC_MODSUB:
26816 case OPC_RADDU_W_QB:
26817 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26818 break;
26819 case OPC_MULEU_S_PH_QBL:
26820 case OPC_MULEU_S_PH_QBR:
26821 case OPC_MULQ_RS_PH:
26822 case OPC_MULEQ_S_W_PHL:
26823 case OPC_MULEQ_S_W_PHR:
26824 case OPC_MULQ_S_PH:
26825 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26826 break;
26827 default: /* Invalid */
26828 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 26829 generate_exception_end(ctx, EXCP_RI);
461c08df 26830 break;
461c08df 26831
099e5b4d
LA
26832 }
26833 break;
26834 case OPC_CMPU_EQ_QB_DSP:
26835 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26836 switch (op2) {
26837 case OPC_PRECR_SRA_PH_W:
26838 case OPC_PRECR_SRA_R_PH_W:
26839 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 26840 break;
099e5b4d
LA
26841 case OPC_PRECR_QB_PH:
26842 case OPC_PRECRQ_QB_PH:
26843 case OPC_PRECRQ_PH_W:
26844 case OPC_PRECRQ_RS_PH_W:
26845 case OPC_PRECRQU_S_QB_PH:
26846 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 26847 break;
099e5b4d
LA
26848 case OPC_CMPU_EQ_QB:
26849 case OPC_CMPU_LT_QB:
26850 case OPC_CMPU_LE_QB:
26851 case OPC_CMP_EQ_PH:
26852 case OPC_CMP_LT_PH:
26853 case OPC_CMP_LE_PH:
26854 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 26855 break;
099e5b4d
LA
26856 case OPC_CMPGU_EQ_QB:
26857 case OPC_CMPGU_LT_QB:
26858 case OPC_CMPGU_LE_QB:
26859 case OPC_CMPGDU_EQ_QB:
26860 case OPC_CMPGDU_LT_QB:
26861 case OPC_CMPGDU_LE_QB:
26862 case OPC_PICK_QB:
26863 case OPC_PICK_PH:
26864 case OPC_PACKRL_PH:
26865 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26866 break;
26867 default: /* Invalid */
26868 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 26869 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26870 break;
26871 }
26872 break;
26873 case OPC_SHLL_QB_DSP:
26874 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26875 break;
26876 case OPC_DPA_W_PH_DSP:
26877 op2 = MASK_DPA_W_PH(ctx->opcode);
26878 switch (op2) {
26879 case OPC_DPAU_H_QBL:
26880 case OPC_DPAU_H_QBR:
26881 case OPC_DPSU_H_QBL:
26882 case OPC_DPSU_H_QBR:
26883 case OPC_DPA_W_PH:
26884 case OPC_DPAX_W_PH:
26885 case OPC_DPAQ_S_W_PH:
26886 case OPC_DPAQX_S_W_PH:
26887 case OPC_DPAQX_SA_W_PH:
26888 case OPC_DPS_W_PH:
26889 case OPC_DPSX_W_PH:
26890 case OPC_DPSQ_S_W_PH:
26891 case OPC_DPSQX_S_W_PH:
26892 case OPC_DPSQX_SA_W_PH:
26893 case OPC_MULSAQ_S_W_PH:
26894 case OPC_DPAQ_SA_L_W:
26895 case OPC_DPSQ_SA_L_W:
26896 case OPC_MAQ_S_W_PHL:
26897 case OPC_MAQ_S_W_PHR:
26898 case OPC_MAQ_SA_W_PHL:
26899 case OPC_MAQ_SA_W_PHR:
26900 case OPC_MULSA_W_PH:
26901 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26902 break;
26903 default: /* Invalid */
26904 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 26905 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26906 break;
26907 }
26908 break;
26909 case OPC_INSV_DSP:
26910 op2 = MASK_INSV(ctx->opcode);
26911 switch (op2) {
26912 case OPC_INSV:
26913 check_dsp(ctx);
26914 {
26915 TCGv t0, t1;
26916
26917 if (rt == 0) {
099e5b4d
LA
26918 break;
26919 }
26920
26921 t0 = tcg_temp_new();
26922 t1 = tcg_temp_new();
26923
26924 gen_load_gpr(t0, rt);
26925 gen_load_gpr(t1, rs);
26926
26927 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26928
26929 tcg_temp_free(t0);
26930 tcg_temp_free(t1);
a22260ae
JL
26931 break;
26932 }
099e5b4d
LA
26933 default: /* Invalid */
26934 MIPS_INVAL("MASK INSV");
9c708c7f 26935 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26936 break;
26937 }
26938 break;
26939 case OPC_APPEND_DSP:
26940 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26941 break;
26942 case OPC_EXTR_W_DSP:
26943 op2 = MASK_EXTR_W(ctx->opcode);
26944 switch (op2) {
26945 case OPC_EXTR_W:
26946 case OPC_EXTR_R_W:
26947 case OPC_EXTR_RS_W:
26948 case OPC_EXTR_S_H:
26949 case OPC_EXTRV_S_H:
26950 case OPC_EXTRV_W:
26951 case OPC_EXTRV_R_W:
26952 case OPC_EXTRV_RS_W:
26953 case OPC_EXTP:
26954 case OPC_EXTPV:
26955 case OPC_EXTPDP:
26956 case OPC_EXTPDPV:
26957 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26958 break;
26959 case OPC_RDDSP:
26960 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
26961 break;
26962 case OPC_SHILO:
26963 case OPC_SHILOV:
26964 case OPC_MTHLIP:
26965 case OPC_WRDSP:
26966 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26967 break;
26968 default: /* Invalid */
26969 MIPS_INVAL("MASK EXTR.W");
9c708c7f 26970 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26971 break;
26972 }
26973 break;
099e5b4d 26974#if defined(TARGET_MIPS64)
c2e19f3c
AM
26975 case OPC_DDIV_G_2E:
26976 case OPC_DDIVU_G_2E:
26977 case OPC_DMULT_G_2E:
26978 case OPC_DMULTU_G_2E:
26979 case OPC_DMOD_G_2E:
26980 case OPC_DMODU_G_2E:
fac5a073
LA
26981 check_insn(ctx, INSN_LOONGSON2E);
26982 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 26983 break;
099e5b4d
LA
26984 case OPC_ABSQ_S_QH_DSP:
26985 op2 = MASK_ABSQ_S_QH(ctx->opcode);
26986 switch (op2) {
26987 case OPC_PRECEQ_L_PWL:
26988 case OPC_PRECEQ_L_PWR:
26989 case OPC_PRECEQ_PW_QHL:
26990 case OPC_PRECEQ_PW_QHR:
26991 case OPC_PRECEQ_PW_QHLA:
26992 case OPC_PRECEQ_PW_QHRA:
26993 case OPC_PRECEQU_QH_OBL:
26994 case OPC_PRECEQU_QH_OBR:
26995 case OPC_PRECEQU_QH_OBLA:
26996 case OPC_PRECEQU_QH_OBRA:
26997 case OPC_PRECEU_QH_OBL:
26998 case OPC_PRECEU_QH_OBR:
26999 case OPC_PRECEU_QH_OBLA:
27000 case OPC_PRECEU_QH_OBRA:
27001 case OPC_ABSQ_S_OB:
27002 case OPC_ABSQ_S_PW:
27003 case OPC_ABSQ_S_QH:
27004 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27005 break;
27006 case OPC_REPL_OB:
27007 case OPC_REPL_PW:
27008 case OPC_REPL_QH:
27009 case OPC_REPLV_OB:
27010 case OPC_REPLV_PW:
27011 case OPC_REPLV_QH:
27012 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27013 break;
27014 default: /* Invalid */
27015 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 27016 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
27017 break;
27018 }
27019 break;
27020 case OPC_ADDU_OB_DSP:
27021 op2 = MASK_ADDU_OB(ctx->opcode);
27022 switch (op2) {
27023 case OPC_RADDU_L_OB:
27024 case OPC_SUBQ_PW:
27025 case OPC_SUBQ_S_PW:
27026 case OPC_SUBQ_QH:
27027 case OPC_SUBQ_S_QH:
27028 case OPC_SUBU_OB:
27029 case OPC_SUBU_S_OB:
27030 case OPC_SUBU_QH:
27031 case OPC_SUBU_S_QH:
27032 case OPC_SUBUH_OB:
27033 case OPC_SUBUH_R_OB:
27034 case OPC_ADDQ_PW:
27035 case OPC_ADDQ_S_PW:
27036 case OPC_ADDQ_QH:
27037 case OPC_ADDQ_S_QH:
27038 case OPC_ADDU_OB:
27039 case OPC_ADDU_S_OB:
27040 case OPC_ADDU_QH:
27041 case OPC_ADDU_S_QH:
27042 case OPC_ADDUH_OB:
27043 case OPC_ADDUH_R_OB:
27044 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 27045 break;
099e5b4d
LA
27046 case OPC_MULEQ_S_PW_QHL:
27047 case OPC_MULEQ_S_PW_QHR:
27048 case OPC_MULEU_S_QH_OBL:
27049 case OPC_MULEU_S_QH_OBR:
27050 case OPC_MULQ_RS_QH:
27051 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 27052 break;
099e5b4d
LA
27053 default: /* Invalid */
27054 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 27055 generate_exception_end(ctx, EXCP_RI);
26690560 27056 break;
099e5b4d
LA
27057 }
27058 break;
27059 case OPC_CMPU_EQ_OB_DSP:
27060 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27061 switch (op2) {
27062 case OPC_PRECR_SRA_QH_PW:
27063 case OPC_PRECR_SRA_R_QH_PW:
27064 /* Return value is rt. */
27065 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 27066 break;
099e5b4d
LA
27067 case OPC_PRECR_OB_QH:
27068 case OPC_PRECRQ_OB_QH:
27069 case OPC_PRECRQ_PW_L:
27070 case OPC_PRECRQ_QH_PW:
27071 case OPC_PRECRQ_RS_QH_PW:
27072 case OPC_PRECRQU_S_OB_QH:
27073 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 27074 break;
099e5b4d
LA
27075 case OPC_CMPU_EQ_OB:
27076 case OPC_CMPU_LT_OB:
27077 case OPC_CMPU_LE_OB:
27078 case OPC_CMP_EQ_QH:
27079 case OPC_CMP_LT_QH:
27080 case OPC_CMP_LE_QH:
27081 case OPC_CMP_EQ_PW:
27082 case OPC_CMP_LT_PW:
27083 case OPC_CMP_LE_PW:
27084 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 27085 break;
099e5b4d
LA
27086 case OPC_CMPGDU_EQ_OB:
27087 case OPC_CMPGDU_LT_OB:
27088 case OPC_CMPGDU_LE_OB:
27089 case OPC_CMPGU_EQ_OB:
27090 case OPC_CMPGU_LT_OB:
27091 case OPC_CMPGU_LE_OB:
27092 case OPC_PACKRL_PW:
27093 case OPC_PICK_OB:
27094 case OPC_PICK_PW:
27095 case OPC_PICK_QH:
27096 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 27097 break;
099e5b4d
LA
27098 default: /* Invalid */
27099 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 27100 generate_exception_end(ctx, EXCP_RI);
161f85e6 27101 break;
099e5b4d
LA
27102 }
27103 break;
27104 case OPC_DAPPEND_DSP:
27105 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27106 break;
27107 case OPC_DEXTR_W_DSP:
27108 op2 = MASK_DEXTR_W(ctx->opcode);
27109 switch (op2) {
27110 case OPC_DEXTP:
27111 case OPC_DEXTPDP:
27112 case OPC_DEXTPDPV:
27113 case OPC_DEXTPV:
27114 case OPC_DEXTR_L:
27115 case OPC_DEXTR_R_L:
27116 case OPC_DEXTR_RS_L:
27117 case OPC_DEXTR_W:
27118 case OPC_DEXTR_R_W:
27119 case OPC_DEXTR_RS_W:
27120 case OPC_DEXTR_S_H:
27121 case OPC_DEXTRV_L:
27122 case OPC_DEXTRV_R_L:
27123 case OPC_DEXTRV_RS_L:
27124 case OPC_DEXTRV_S_H:
27125 case OPC_DEXTRV_W:
27126 case OPC_DEXTRV_R_W:
27127 case OPC_DEXTRV_RS_W:
27128 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 27129 break;
099e5b4d
LA
27130 case OPC_DMTHLIP:
27131 case OPC_DSHILO:
27132 case OPC_DSHILOV:
27133 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 27134 break;
099e5b4d
LA
27135 default: /* Invalid */
27136 MIPS_INVAL("MASK EXTR.W");
9c708c7f 27137 generate_exception_end(ctx, EXCP_RI);
461c08df 27138 break;
099e5b4d
LA
27139 }
27140 break;
27141 case OPC_DPAQ_W_QH_DSP:
27142 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27143 switch (op2) {
27144 case OPC_DPAU_H_OBL:
27145 case OPC_DPAU_H_OBR:
27146 case OPC_DPSU_H_OBL:
27147 case OPC_DPSU_H_OBR:
27148 case OPC_DPA_W_QH:
27149 case OPC_DPAQ_S_W_QH:
27150 case OPC_DPS_W_QH:
27151 case OPC_DPSQ_S_W_QH:
27152 case OPC_MULSAQ_S_W_QH:
27153 case OPC_DPAQ_SA_L_PW:
27154 case OPC_DPSQ_SA_L_PW:
27155 case OPC_MULSAQ_S_L_PW:
27156 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27157 break;
27158 case OPC_MAQ_S_W_QHLL:
27159 case OPC_MAQ_S_W_QHLR:
27160 case OPC_MAQ_S_W_QHRL:
27161 case OPC_MAQ_S_W_QHRR:
27162 case OPC_MAQ_SA_W_QHLL:
27163 case OPC_MAQ_SA_W_QHLR:
27164 case OPC_MAQ_SA_W_QHRL:
27165 case OPC_MAQ_SA_W_QHRR:
27166 case OPC_MAQ_S_L_PWL:
27167 case OPC_MAQ_S_L_PWR:
27168 case OPC_DMADD:
27169 case OPC_DMADDU:
27170 case OPC_DMSUB:
27171 case OPC_DMSUBU:
27172 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 27173 break;
099e5b4d
LA
27174 default: /* Invalid */
27175 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 27176 generate_exception_end(ctx, EXCP_RI);
b53371ed 27177 break;
099e5b4d
LA
27178 }
27179 break;
27180 case OPC_DINSV_DSP:
27181 op2 = MASK_INSV(ctx->opcode);
27182 switch (op2) {
27183 case OPC_DINSV:
27184 {
27185 TCGv t0, t1;
27186
27187 if (rt == 0) {
a22260ae
JL
27188 break;
27189 }
099e5b4d 27190 check_dsp(ctx);
1cb6686c 27191
099e5b4d
LA
27192 t0 = tcg_temp_new();
27193 t1 = tcg_temp_new();
1cb6686c 27194
099e5b4d
LA
27195 gen_load_gpr(t0, rt);
27196 gen_load_gpr(t1, rs);
1cb6686c 27197
099e5b4d 27198 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 27199
099e5b4d
LA
27200 tcg_temp_free(t0);
27201 tcg_temp_free(t1);
77c5fa8b 27202 break;
099e5b4d 27203 }
7a387fff 27204 default: /* Invalid */
099e5b4d 27205 MIPS_INVAL("MASK DINSV");
9c708c7f 27206 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
27207 break;
27208 }
27209 break;
099e5b4d
LA
27210 case OPC_SHLL_OB_DSP:
27211 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27212 break;
27213#endif
fac5a073
LA
27214 default: /* Invalid */
27215 MIPS_INVAL("special3_legacy");
9c708c7f 27216 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
27217 break;
27218 }
27219}
27220
874b2879 27221static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
88eafe0b 27222{
c8341e00 27223 uint32_t opc = MASK_MMI0(ctx->opcode);
88eafe0b
FN
27224
27225 switch (opc) {
baa609db
AM
27226 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27227 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27228 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27229 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27230 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27231 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27232 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27233 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27234 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27235 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27236 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27237 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27238 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27239 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27240 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27241 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27242 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27243 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27244 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27245 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27246 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27247 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27248 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27249 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27250 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
27251 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
88eafe0b
FN
27252 break;
27253 default:
27254 MIPS_INVAL("TX79 MMI class MMI0");
27255 generate_exception_end(ctx, EXCP_RI);
27256 break;
27257 }
27258}
27259
874b2879 27260static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
7a803ca2 27261{
c8341e00 27262 uint32_t opc = MASK_MMI1(ctx->opcode);
7a803ca2
FN
27263
27264 switch (opc) {
baa609db
AM
27265 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27266 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27267 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27268 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27269 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27270 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27271 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27272 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27273 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27274 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27275 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27276 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27277 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27278 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27279 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27280 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27281 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27282 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
27283 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
7a803ca2
FN
27284 break;
27285 default:
27286 MIPS_INVAL("TX79 MMI class MMI1");
27287 generate_exception_end(ctx, EXCP_RI);
27288 break;
27289 }
27290}
27291
874b2879 27292static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
6c1e48d3 27293{
c8341e00 27294 uint32_t opc = MASK_MMI2(ctx->opcode);
6c1e48d3
FN
27295
27296 switch (opc) {
baa609db
AM
27297 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27298 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27299 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27300 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27301 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27302 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27303 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27304 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27305 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
27306 case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
27307 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27308 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27309 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27310 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27311 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27312 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27313 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27314 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27315 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27316 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27317 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27318 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
27319 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
6c1e48d3
FN
27320 break;
27321 default:
27322 MIPS_INVAL("TX79 MMI class MMI2");
27323 generate_exception_end(ctx, EXCP_RI);
27324 break;
27325 }
27326}
27327
874b2879 27328static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
ec1944fc 27329{
c8341e00 27330 uint32_t opc = MASK_MMI3(ctx->opcode);
ec1944fc
FN
27331
27332 switch (opc) {
baa609db
AM
27333 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27334 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27335 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27336 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27337 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27338 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27339 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
27340 case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
27341 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27342 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27343 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
27344 case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
27345 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
27346 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
ec1944fc
FN
27347 break;
27348 default:
27349 MIPS_INVAL("TX79 MMI class MMI3");
27350 generate_exception_end(ctx, EXCP_RI);
27351 break;
27352 }
27353}
27354
874b2879 27355static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
71b8a6b3 27356{
c8341e00 27357 uint32_t opc = MASK_MMI(ctx->opcode);
06de726b
FN
27358 int rs = extract32(ctx->opcode, 21, 5);
27359 int rt = extract32(ctx->opcode, 16, 5);
27360 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
27361
27362 switch (opc) {
baa609db 27363 case MMI_OPC_CLASS_MMI0:
874b2879 27364 decode_mmi0(env, ctx);
88eafe0b 27365 break;
baa609db 27366 case MMI_OPC_CLASS_MMI1:
874b2879 27367 decode_mmi1(env, ctx);
7a803ca2 27368 break;
baa609db 27369 case MMI_OPC_CLASS_MMI2:
874b2879 27370 decode_mmi2(env, ctx);
6c1e48d3 27371 break;
baa609db 27372 case MMI_OPC_CLASS_MMI3:
874b2879 27373 decode_mmi3(env, ctx);
ec1944fc 27374 break;
baa609db
AM
27375 case MMI_OPC_MULT1:
27376 case MMI_OPC_MULTU1:
3b948f05
PMD
27377 case MMI_OPC_MADD:
27378 case MMI_OPC_MADDU:
a95c4c26
FN
27379 case MMI_OPC_MADD1:
27380 case MMI_OPC_MADDU1:
06de726b
FN
27381 gen_mul_txx9(ctx, opc, rd, rs, rt);
27382 break;
baa609db
AM
27383 case MMI_OPC_DIV1:
27384 case MMI_OPC_DIVU1:
c42171c3 27385 gen_div1_tx79(ctx, opc, rs, rt);
be9c42c9 27386 break;
baa609db
AM
27387 case MMI_OPC_MTLO1:
27388 case MMI_OPC_MTHI1:
86efbfb6 27389 gen_HILO1_tx79(ctx, opc, rs);
8d927f7c 27390 break;
baa609db
AM
27391 case MMI_OPC_MFLO1:
27392 case MMI_OPC_MFHI1:
86efbfb6 27393 gen_HILO1_tx79(ctx, opc, rd);
8d927f7c 27394 break;
baa609db 27395 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
baa609db
AM
27396 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
27397 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
27398 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
27399 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
27400 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
27401 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
27402 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
27403 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
27404 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
71b8a6b3
FN
27405 break;
27406 default:
27407 MIPS_INVAL("TX79 MMI class");
27408 generate_exception_end(ctx, EXCP_RI);
27409 break;
27410 }
27411}
27412
874b2879 27413static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
f08099ad 27414{
baa609db 27415 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
f08099ad
FN
27416}
27417
874b2879 27418static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
bb41e74b 27419{
baa609db 27420 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
bb41e74b
FN
27421}
27422
27423/*
27424 * The TX79-specific instruction Store Quadword
27425 *
27426 * +--------+-------+-------+------------------------+
27427 * | 011111 | base | rt | offset | SQ
27428 * +--------+-------+-------+------------------------+
27429 * 6 5 5 16
27430 *
27431 * has the same opcode as the Read Hardware Register instruction
27432 *
27433 * +--------+-------+-------+-------+-------+--------+
27434 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27435 * +--------+-------+-------+-------+-------+--------+
27436 * 6 5 5 5 5 6
27437 *
27438 * that is required, trapped and emulated by the Linux kernel. However, all
27439 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27440 * offset is odd. Therefore all valid SQ instructions can execute normally.
27441 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27442 * between SQ and RDHWR, as the Linux kernel does.
27443 */
874b2879 27444static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
bb41e74b
FN
27445{
27446 int base = extract32(ctx->opcode, 21, 5);
27447 int rt = extract32(ctx->opcode, 16, 5);
27448 int offset = extract32(ctx->opcode, 0, 16);
27449
27450#ifdef CONFIG_USER_ONLY
27451 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27452 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27453
27454 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27455 int rd = extract32(ctx->opcode, 11, 5);
27456
27457 gen_rdhwr(ctx, rt, rd, 0);
27458 return;
27459 }
27460#endif
27461
874b2879 27462 gen_mmi_sq(ctx, base, rt, offset);
bb41e74b
FN
27463}
27464
fac5a073
LA
27465static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27466{
27467 int rs, rt, rd, sa;
27468 uint32_t op1, op2;
76964147 27469 int16_t imm;
fac5a073
LA
27470
27471 rs = (ctx->opcode >> 21) & 0x1f;
27472 rt = (ctx->opcode >> 16) & 0x1f;
27473 rd = (ctx->opcode >> 11) & 0x1f;
27474 sa = (ctx->opcode >> 6) & 0x1f;
76964147 27475 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
27476
27477 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
27478
27479 /*
27480 * EVA loads and stores overlap Loongson 2E instructions decoded by
27481 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27482 * EVA is absent.
27483 */
27484 if (ctx->eva) {
27485 switch (op1) {
c2e19f3c
AM
27486 case OPC_LWLE:
27487 case OPC_LWRE:
76964147
JH
27488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27489 /* fall through */
c2e19f3c
AM
27490 case OPC_LBUE:
27491 case OPC_LHUE:
27492 case OPC_LBE:
27493 case OPC_LHE:
27494 case OPC_LLE:
27495 case OPC_LWE:
76964147
JH
27496 check_cp0_enabled(ctx);
27497 gen_ld(ctx, op1, rt, rs, imm);
27498 return;
c2e19f3c
AM
27499 case OPC_SWLE:
27500 case OPC_SWRE:
76964147
JH
27501 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27502 /* fall through */
c2e19f3c
AM
27503 case OPC_SBE:
27504 case OPC_SHE:
76964147
JH
27505 case OPC_SWE:
27506 check_cp0_enabled(ctx);
27507 gen_st(ctx, op1, rt, rs, imm);
27508 return;
27509 case OPC_SCE:
27510 check_cp0_enabled(ctx);
27511 gen_st_cond(ctx, op1, rt, rs, imm);
27512 return;
27513 case OPC_CACHEE:
27514 check_cp0_enabled(ctx);
27515 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27516 gen_cache_operation(ctx, rt, rs, imm);
27517 }
27518 /* Treat as NOP. */
27519 return;
27520 case OPC_PREFE:
27521 check_cp0_enabled(ctx);
27522 /* Treat as NOP. */
27523 return;
27524 }
27525 }
27526
fac5a073
LA
27527 switch (op1) {
27528 case OPC_EXT:
27529 case OPC_INS:
27530 check_insn(ctx, ISA_MIPS32R2);
27531 gen_bitops(ctx, op1, rt, rs, sa, rd);
27532 break;
27533 case OPC_BSHFL:
fac5a073 27534 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 27535 switch (op2) {
c2e19f3c 27536 case OPC_ALIGN:
373ecd38
AM
27537 case OPC_ALIGN_1:
27538 case OPC_ALIGN_2:
27539 case OPC_ALIGN_3:
15eacb9b
YK
27540 case OPC_BITSWAP:
27541 check_insn(ctx, ISA_MIPS32R6);
27542 decode_opc_special3_r6(env, ctx);
27543 break;
27544 default:
27545 check_insn(ctx, ISA_MIPS32R2);
27546 gen_bshfl(ctx, op2, rt, rd);
27547 break;
27548 }
fac5a073
LA
27549 break;
27550#if defined(TARGET_MIPS64)
c2e19f3c
AM
27551 case OPC_DEXTM:
27552 case OPC_DEXTU:
27553 case OPC_DEXT:
27554 case OPC_DINSM:
27555 case OPC_DINSU:
27556 case OPC_DINS:
fac5a073
LA
27557 check_insn(ctx, ISA_MIPS64R2);
27558 check_mips_64(ctx);
27559 gen_bitops(ctx, op1, rt, rs, sa, rd);
27560 break;
27561 case OPC_DBSHFL:
fac5a073 27562 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 27563 switch (op2) {
c2e19f3c 27564 case OPC_DALIGN:
373ecd38
AM
27565 case OPC_DALIGN_1:
27566 case OPC_DALIGN_2:
27567 case OPC_DALIGN_3:
27568 case OPC_DALIGN_4:
27569 case OPC_DALIGN_5:
27570 case OPC_DALIGN_6:
27571 case OPC_DALIGN_7:
15eacb9b
YK
27572 case OPC_DBITSWAP:
27573 check_insn(ctx, ISA_MIPS32R6);
27574 decode_opc_special3_r6(env, ctx);
27575 break;
27576 default:
27577 check_insn(ctx, ISA_MIPS64R2);
27578 check_mips_64(ctx);
27579 op2 = MASK_DBSHFL(ctx->opcode);
27580 gen_bshfl(ctx, op2, rt, rd);
27581 break;
27582 }
fac5a073
LA
27583 break;
27584#endif
27585 case OPC_RDHWR:
b00c7218 27586 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
27587 break;
27588 case OPC_FORK:
9affc1c5 27589 check_mt(ctx);
fac5a073
LA
27590 {
27591 TCGv t0 = tcg_temp_new();
27592 TCGv t1 = tcg_temp_new();
27593
27594 gen_load_gpr(t0, rt);
27595 gen_load_gpr(t1, rs);
27596 gen_helper_fork(t0, t1);
27597 tcg_temp_free(t0);
27598 tcg_temp_free(t1);
27599 }
27600 break;
27601 case OPC_YIELD:
9affc1c5 27602 check_mt(ctx);
fac5a073
LA
27603 {
27604 TCGv t0 = tcg_temp_new();
27605
fac5a073
LA
27606 gen_load_gpr(t0, rs);
27607 gen_helper_yield(t0, cpu_env, t0);
27608 gen_store_gpr(t0, rd);
27609 tcg_temp_free(t0);
27610 }
27611 break;
10dc65db
LA
27612 default:
27613 if (ctx->insn_flags & ISA_MIPS32R6) {
27614 decode_opc_special3_r6(env, ctx);
27615 } else {
27616 decode_opc_special3_legacy(env, ctx);
27617 }
099e5b4d
LA
27618 }
27619}
27620
863f264d
YK
27621/* MIPS SIMD Architecture (MSA) */
27622static inline int check_msa_access(DisasContext *ctx)
27623{
27624 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27625 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 27626 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
27627 return 0;
27628 }
27629
27630 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27631 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 27632 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
27633 return 0;
27634 } else {
9c708c7f 27635 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
27636 return 0;
27637 }
27638 }
27639 return 1;
27640}
27641
5692c6e1
YK
27642static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27643{
27644 /* generates tcg ops to check if any element is 0 */
27645 /* Note this function only works with MSA_WRLEN = 128 */
27646 uint64_t eval_zero_or_big = 0;
27647 uint64_t eval_big = 0;
27648 TCGv_i64 t0 = tcg_temp_new_i64();
27649 TCGv_i64 t1 = tcg_temp_new_i64();
27650 switch (df) {
27651 case DF_BYTE:
27652 eval_zero_or_big = 0x0101010101010101ULL;
27653 eval_big = 0x8080808080808080ULL;
27654 break;
27655 case DF_HALF:
27656 eval_zero_or_big = 0x0001000100010001ULL;
27657 eval_big = 0x8000800080008000ULL;
27658 break;
27659 case DF_WORD:
27660 eval_zero_or_big = 0x0000000100000001ULL;
27661 eval_big = 0x8000000080000000ULL;
27662 break;
27663 case DF_DOUBLE:
27664 eval_zero_or_big = 0x0000000000000001ULL;
27665 eval_big = 0x8000000000000000ULL;
27666 break;
27667 }
27668 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27669 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27670 tcg_gen_andi_i64(t0, t0, eval_big);
27671 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27672 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27673 tcg_gen_andi_i64(t1, t1, eval_big);
27674 tcg_gen_or_i64(t0, t0, t1);
27675 /* if all bits are zero then all elements are not zero */
27676 /* if some bit is non-zero then some element is zero */
27677 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27678 tcg_gen_trunc_i64_tl(tresult, t0);
27679 tcg_temp_free_i64(t0);
27680 tcg_temp_free_i64(t1);
27681}
27682
27683static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27684{
27685 uint8_t df = (ctx->opcode >> 21) & 0x3;
27686 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27687 int64_t s16 = (int16_t)ctx->opcode;
27688
27689 check_msa_access(ctx);
27690
075a1fe7 27691 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 27692 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
27693 return;
27694 }
27695 switch (op1) {
27696 case OPC_BZ_V:
27697 case OPC_BNZ_V:
27698 {
27699 TCGv_i64 t0 = tcg_temp_new_i64();
27700 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27701 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27702 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27703 tcg_gen_trunc_i64_tl(bcond, t0);
27704 tcg_temp_free_i64(t0);
27705 }
27706 break;
27707 case OPC_BZ_B:
27708 case OPC_BZ_H:
27709 case OPC_BZ_W:
27710 case OPC_BZ_D:
27711 gen_check_zero_element(bcond, df, wt);
27712 break;
27713 case OPC_BNZ_B:
27714 case OPC_BNZ_H:
27715 case OPC_BNZ_W:
27716 case OPC_BNZ_D:
27717 gen_check_zero_element(bcond, df, wt);
27718 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27719 break;
27720 }
27721
eeb3bba8 27722 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
27723
27724 ctx->hflags |= MIPS_HFLAG_BC;
27725 ctx->hflags |= MIPS_HFLAG_BDS32;
27726}
27727
4c789546
YK
27728static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27729{
27730#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27731 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27732 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27733 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27734
27735 TCGv_i32 twd = tcg_const_i32(wd);
27736 TCGv_i32 tws = tcg_const_i32(ws);
27737 TCGv_i32 ti8 = tcg_const_i32(i8);
27738
27739 switch (MASK_MSA_I8(ctx->opcode)) {
27740 case OPC_ANDI_B:
27741 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27742 break;
27743 case OPC_ORI_B:
27744 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27745 break;
27746 case OPC_NORI_B:
27747 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27748 break;
27749 case OPC_XORI_B:
27750 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27751 break;
27752 case OPC_BMNZI_B:
27753 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27754 break;
27755 case OPC_BMZI_B:
27756 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27757 break;
27758 case OPC_BSELI_B:
27759 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27760 break;
27761 case OPC_SHF_B:
27762 case OPC_SHF_H:
27763 case OPC_SHF_W:
27764 {
27765 uint8_t df = (ctx->opcode >> 24) & 0x3;
27766 if (df == DF_DOUBLE) {
9c708c7f 27767 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
27768 } else {
27769 TCGv_i32 tdf = tcg_const_i32(df);
27770 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27771 tcg_temp_free_i32(tdf);
27772 }
27773 }
27774 break;
27775 default:
27776 MIPS_INVAL("MSA instruction");
9c708c7f 27777 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
27778 break;
27779 }
27780
27781 tcg_temp_free_i32(twd);
27782 tcg_temp_free_i32(tws);
27783 tcg_temp_free_i32(ti8);
27784}
27785
80e71591
YK
27786static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27787{
27788#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27789 uint8_t df = (ctx->opcode >> 21) & 0x3;
27790 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27791 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27792 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27793 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27794
27795 TCGv_i32 tdf = tcg_const_i32(df);
27796 TCGv_i32 twd = tcg_const_i32(wd);
27797 TCGv_i32 tws = tcg_const_i32(ws);
27798 TCGv_i32 timm = tcg_temp_new_i32();
27799 tcg_gen_movi_i32(timm, u5);
27800
27801 switch (MASK_MSA_I5(ctx->opcode)) {
27802 case OPC_ADDVI_df:
27803 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27804 break;
27805 case OPC_SUBVI_df:
27806 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27807 break;
27808 case OPC_MAXI_S_df:
27809 tcg_gen_movi_i32(timm, s5);
27810 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27811 break;
27812 case OPC_MAXI_U_df:
27813 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27814 break;
27815 case OPC_MINI_S_df:
27816 tcg_gen_movi_i32(timm, s5);
27817 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27818 break;
27819 case OPC_MINI_U_df:
27820 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27821 break;
27822 case OPC_CEQI_df:
27823 tcg_gen_movi_i32(timm, s5);
27824 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27825 break;
27826 case OPC_CLTI_S_df:
27827 tcg_gen_movi_i32(timm, s5);
27828 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27829 break;
27830 case OPC_CLTI_U_df:
27831 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27832 break;
27833 case OPC_CLEI_S_df:
27834 tcg_gen_movi_i32(timm, s5);
27835 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27836 break;
27837 case OPC_CLEI_U_df:
27838 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27839 break;
27840 case OPC_LDI_df:
27841 {
27842 int32_t s10 = sextract32(ctx->opcode, 11, 10);
27843 tcg_gen_movi_i32(timm, s10);
27844 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27845 }
27846 break;
27847 default:
27848 MIPS_INVAL("MSA instruction");
9c708c7f 27849 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
27850 break;
27851 }
27852
27853 tcg_temp_free_i32(tdf);
27854 tcg_temp_free_i32(twd);
27855 tcg_temp_free_i32(tws);
27856 tcg_temp_free_i32(timm);
27857}
27858
d4cf28de
YK
27859static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27860{
27861#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27862 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27863 uint32_t df = 0, m = 0;
27864 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27865 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27866
27867 TCGv_i32 tdf;
27868 TCGv_i32 tm;
27869 TCGv_i32 twd;
27870 TCGv_i32 tws;
27871
27872 if ((dfm & 0x40) == 0x00) {
27873 m = dfm & 0x3f;
27874 df = DF_DOUBLE;
27875 } else if ((dfm & 0x60) == 0x40) {
27876 m = dfm & 0x1f;
27877 df = DF_WORD;
27878 } else if ((dfm & 0x70) == 0x60) {
27879 m = dfm & 0x0f;
27880 df = DF_HALF;
27881 } else if ((dfm & 0x78) == 0x70) {
27882 m = dfm & 0x7;
27883 df = DF_BYTE;
27884 } else {
9c708c7f 27885 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
27886 return;
27887 }
27888
27889 tdf = tcg_const_i32(df);
27890 tm = tcg_const_i32(m);
27891 twd = tcg_const_i32(wd);
27892 tws = tcg_const_i32(ws);
27893
27894 switch (MASK_MSA_BIT(ctx->opcode)) {
27895 case OPC_SLLI_df:
27896 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27897 break;
27898 case OPC_SRAI_df:
27899 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27900 break;
27901 case OPC_SRLI_df:
27902 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27903 break;
27904 case OPC_BCLRI_df:
27905 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27906 break;
27907 case OPC_BSETI_df:
27908 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27909 break;
27910 case OPC_BNEGI_df:
27911 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27912 break;
27913 case OPC_BINSLI_df:
27914 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27915 break;
27916 case OPC_BINSRI_df:
27917 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27918 break;
27919 case OPC_SAT_S_df:
27920 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27921 break;
27922 case OPC_SAT_U_df:
27923 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27924 break;
27925 case OPC_SRARI_df:
27926 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27927 break;
27928 case OPC_SRLRI_df:
27929 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27930 break;
27931 default:
27932 MIPS_INVAL("MSA instruction");
9c708c7f 27933 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
27934 break;
27935 }
27936
27937 tcg_temp_free_i32(tdf);
27938 tcg_temp_free_i32(tm);
27939 tcg_temp_free_i32(twd);
27940 tcg_temp_free_i32(tws);
27941}
27942
28f99f08
YK
27943static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
27944{
27945#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27946 uint8_t df = (ctx->opcode >> 21) & 0x3;
27947 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27948 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27949 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27950
27951 TCGv_i32 tdf = tcg_const_i32(df);
27952 TCGv_i32 twd = tcg_const_i32(wd);
27953 TCGv_i32 tws = tcg_const_i32(ws);
27954 TCGv_i32 twt = tcg_const_i32(wt);
27955
27956 switch (MASK_MSA_3R(ctx->opcode)) {
27957 case OPC_SLL_df:
27958 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
27959 break;
27960 case OPC_ADDV_df:
27961 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
27962 break;
27963 case OPC_CEQ_df:
27964 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
27965 break;
27966 case OPC_ADD_A_df:
27967 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
27968 break;
27969 case OPC_SUBS_S_df:
27970 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
27971 break;
27972 case OPC_MULV_df:
27973 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
27974 break;
27975 case OPC_SLD_df:
27976 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
27977 break;
27978 case OPC_VSHF_df:
27979 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
27980 break;
27981 case OPC_SRA_df:
27982 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
27983 break;
27984 case OPC_SUBV_df:
27985 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
27986 break;
27987 case OPC_ADDS_A_df:
27988 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
27989 break;
27990 case OPC_SUBS_U_df:
27991 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
27992 break;
27993 case OPC_MADDV_df:
27994 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
27995 break;
27996 case OPC_SPLAT_df:
27997 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
27998 break;
27999 case OPC_SRAR_df:
28000 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28001 break;
28002 case OPC_SRL_df:
28003 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28004 break;
28005 case OPC_MAX_S_df:
28006 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28007 break;
28008 case OPC_CLT_S_df:
28009 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28010 break;
28011 case OPC_ADDS_S_df:
28012 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28013 break;
28014 case OPC_SUBSUS_U_df:
28015 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28016 break;
28017 case OPC_MSUBV_df:
28018 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28019 break;
28020 case OPC_PCKEV_df:
28021 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28022 break;
28023 case OPC_SRLR_df:
28024 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28025 break;
28026 case OPC_BCLR_df:
28027 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28028 break;
28029 case OPC_MAX_U_df:
28030 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28031 break;
28032 case OPC_CLT_U_df:
28033 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28034 break;
28035 case OPC_ADDS_U_df:
28036 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28037 break;
28038 case OPC_SUBSUU_S_df:
28039 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28040 break;
28041 case OPC_PCKOD_df:
28042 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28043 break;
28044 case OPC_BSET_df:
28045 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28046 break;
28047 case OPC_MIN_S_df:
28048 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28049 break;
28050 case OPC_CLE_S_df:
28051 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28052 break;
28053 case OPC_AVE_S_df:
28054 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28055 break;
28056 case OPC_ASUB_S_df:
28057 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28058 break;
28059 case OPC_DIV_S_df:
28060 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28061 break;
28062 case OPC_ILVL_df:
28063 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28064 break;
28065 case OPC_BNEG_df:
28066 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28067 break;
28068 case OPC_MIN_U_df:
28069 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28070 break;
28071 case OPC_CLE_U_df:
28072 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28073 break;
28074 case OPC_AVE_U_df:
28075 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28076 break;
28077 case OPC_ASUB_U_df:
28078 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28079 break;
28080 case OPC_DIV_U_df:
28081 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28082 break;
28083 case OPC_ILVR_df:
28084 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28085 break;
28086 case OPC_BINSL_df:
28087 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28088 break;
28089 case OPC_MAX_A_df:
28090 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28091 break;
28092 case OPC_AVER_S_df:
28093 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28094 break;
28095 case OPC_MOD_S_df:
28096 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28097 break;
28098 case OPC_ILVEV_df:
28099 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28100 break;
28101 case OPC_BINSR_df:
28102 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28103 break;
28104 case OPC_MIN_A_df:
28105 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28106 break;
28107 case OPC_AVER_U_df:
28108 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28109 break;
28110 case OPC_MOD_U_df:
28111 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28112 break;
28113 case OPC_ILVOD_df:
28114 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28115 break;
28116
28117 case OPC_DOTP_S_df:
28118 case OPC_DOTP_U_df:
28119 case OPC_DPADD_S_df:
28120 case OPC_DPADD_U_df:
28121 case OPC_DPSUB_S_df:
28122 case OPC_HADD_S_df:
28123 case OPC_DPSUB_U_df:
28124 case OPC_HADD_U_df:
28125 case OPC_HSUB_S_df:
28126 case OPC_HSUB_U_df:
28127 if (df == DF_BYTE) {
9c708c7f
PD
28128 generate_exception_end(ctx, EXCP_RI);
28129 break;
28f99f08
YK
28130 }
28131 switch (MASK_MSA_3R(ctx->opcode)) {
28132 case OPC_DOTP_S_df:
28133 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28134 break;
28135 case OPC_DOTP_U_df:
28136 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28137 break;
28138 case OPC_DPADD_S_df:
28139 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28140 break;
28141 case OPC_DPADD_U_df:
28142 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28143 break;
28144 case OPC_DPSUB_S_df:
28145 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28146 break;
28147 case OPC_HADD_S_df:
28148 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28149 break;
28150 case OPC_DPSUB_U_df:
28151 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28152 break;
28153 case OPC_HADD_U_df:
28154 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28155 break;
28156 case OPC_HSUB_S_df:
28157 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28158 break;
28159 case OPC_HSUB_U_df:
28160 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28161 break;
28162 }
28163 break;
28164 default:
28165 MIPS_INVAL("MSA instruction");
9c708c7f 28166 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
28167 break;
28168 }
28169 tcg_temp_free_i32(twd);
28170 tcg_temp_free_i32(tws);
28171 tcg_temp_free_i32(twt);
28172 tcg_temp_free_i32(tdf);
28173}
28174
1e608ec1
YK
28175static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28176{
28177#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28178 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28179 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28180 TCGv telm = tcg_temp_new();
28181 TCGv_i32 tsr = tcg_const_i32(source);
28182 TCGv_i32 tdt = tcg_const_i32(dest);
28183
28184 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28185 case OPC_CTCMSA:
28186 gen_load_gpr(telm, source);
28187 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28188 break;
28189 case OPC_CFCMSA:
28190 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28191 gen_store_gpr(telm, dest);
28192 break;
28193 case OPC_MOVE_V:
28194 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28195 break;
28196 default:
28197 MIPS_INVAL("MSA instruction");
9c708c7f 28198 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
28199 break;
28200 }
28201
28202 tcg_temp_free(telm);
28203 tcg_temp_free_i32(tdt);
28204 tcg_temp_free_i32(tsr);
28205}
28206
28207static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28208 uint32_t n)
28209{
28210#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28211 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28212 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28213
28214 TCGv_i32 tws = tcg_const_i32(ws);
28215 TCGv_i32 twd = tcg_const_i32(wd);
28216 TCGv_i32 tn = tcg_const_i32(n);
28217 TCGv_i32 tdf = tcg_const_i32(df);
28218
28219 switch (MASK_MSA_ELM(ctx->opcode)) {
28220 case OPC_SLDI_df:
28221 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28222 break;
28223 case OPC_SPLATI_df:
28224 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28225 break;
28226 case OPC_INSVE_df:
28227 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28228 break;
28229 case OPC_COPY_S_df:
28230 case OPC_COPY_U_df:
28231 case OPC_INSERT_df:
28232#if !defined(TARGET_MIPS64)
28233 /* Double format valid only for MIPS64 */
28234 if (df == DF_DOUBLE) {
9c708c7f 28235 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
28236 break;
28237 }
28238#endif
28239 switch (MASK_MSA_ELM(ctx->opcode)) {
28240 case OPC_COPY_S_df:
cab48881
MD
28241 if (likely(wd != 0)) {
28242 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28243 }
1e608ec1
YK
28244 break;
28245 case OPC_COPY_U_df:
cab48881
MD
28246 if (likely(wd != 0)) {
28247 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28248 }
1e608ec1
YK
28249 break;
28250 case OPC_INSERT_df:
28251 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28252 break;
28253 }
28254 break;
28255 default:
28256 MIPS_INVAL("MSA instruction");
9c708c7f 28257 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
28258 }
28259 tcg_temp_free_i32(twd);
28260 tcg_temp_free_i32(tws);
28261 tcg_temp_free_i32(tn);
28262 tcg_temp_free_i32(tdf);
28263}
28264
28265static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28266{
28267 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28268 uint32_t df = 0, n = 0;
28269
28270 if ((dfn & 0x30) == 0x00) {
28271 n = dfn & 0x0f;
28272 df = DF_BYTE;
28273 } else if ((dfn & 0x38) == 0x20) {
28274 n = dfn & 0x07;
28275 df = DF_HALF;
28276 } else if ((dfn & 0x3c) == 0x30) {
28277 n = dfn & 0x03;
28278 df = DF_WORD;
28279 } else if ((dfn & 0x3e) == 0x38) {
28280 n = dfn & 0x01;
28281 df = DF_DOUBLE;
28282 } else if (dfn == 0x3E) {
28283 /* CTCMSA, CFCMSA, MOVE.V */
28284 gen_msa_elm_3e(env, ctx);
28285 return;
28286 } else {
9c708c7f 28287 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
28288 return;
28289 }
28290
28291 gen_msa_elm_df(env, ctx, df, n);
28292}
28293
7d05b9c8
YK
28294static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28295{
28296#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28297 uint8_t df = (ctx->opcode >> 21) & 0x1;
28298 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28299 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28300 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28301
28302 TCGv_i32 twd = tcg_const_i32(wd);
28303 TCGv_i32 tws = tcg_const_i32(ws);
28304 TCGv_i32 twt = tcg_const_i32(wt);
28305 TCGv_i32 tdf = tcg_temp_new_i32();
28306
28307 /* adjust df value for floating-point instruction */
28308 tcg_gen_movi_i32(tdf, df + 2);
28309
28310 switch (MASK_MSA_3RF(ctx->opcode)) {
28311 case OPC_FCAF_df:
28312 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28313 break;
28314 case OPC_FADD_df:
28315 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28316 break;
28317 case OPC_FCUN_df:
28318 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28319 break;
28320 case OPC_FSUB_df:
28321 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28322 break;
28323 case OPC_FCOR_df:
28324 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28325 break;
28326 case OPC_FCEQ_df:
28327 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28328 break;
28329 case OPC_FMUL_df:
28330 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28331 break;
28332 case OPC_FCUNE_df:
28333 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28334 break;
28335 case OPC_FCUEQ_df:
28336 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28337 break;
28338 case OPC_FDIV_df:
28339 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28340 break;
28341 case OPC_FCNE_df:
28342 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28343 break;
28344 case OPC_FCLT_df:
28345 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28346 break;
28347 case OPC_FMADD_df:
28348 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28349 break;
28350 case OPC_MUL_Q_df:
28351 tcg_gen_movi_i32(tdf, df + 1);
28352 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28353 break;
28354 case OPC_FCULT_df:
28355 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28356 break;
28357 case OPC_FMSUB_df:
28358 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28359 break;
28360 case OPC_MADD_Q_df:
28361 tcg_gen_movi_i32(tdf, df + 1);
28362 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28363 break;
28364 case OPC_FCLE_df:
28365 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28366 break;
28367 case OPC_MSUB_Q_df:
28368 tcg_gen_movi_i32(tdf, df + 1);
28369 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28370 break;
28371 case OPC_FCULE_df:
28372 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28373 break;
28374 case OPC_FEXP2_df:
28375 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28376 break;
28377 case OPC_FSAF_df:
28378 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28379 break;
28380 case OPC_FEXDO_df:
28381 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28382 break;
28383 case OPC_FSUN_df:
28384 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28385 break;
28386 case OPC_FSOR_df:
28387 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28388 break;
28389 case OPC_FSEQ_df:
28390 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28391 break;
28392 case OPC_FTQ_df:
28393 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28394 break;
28395 case OPC_FSUNE_df:
28396 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28397 break;
28398 case OPC_FSUEQ_df:
28399 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28400 break;
28401 case OPC_FSNE_df:
28402 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28403 break;
28404 case OPC_FSLT_df:
28405 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28406 break;
28407 case OPC_FMIN_df:
28408 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28409 break;
28410 case OPC_MULR_Q_df:
28411 tcg_gen_movi_i32(tdf, df + 1);
28412 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28413 break;
28414 case OPC_FSULT_df:
28415 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28416 break;
28417 case OPC_FMIN_A_df:
28418 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28419 break;
28420 case OPC_MADDR_Q_df:
28421 tcg_gen_movi_i32(tdf, df + 1);
28422 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28423 break;
28424 case OPC_FSLE_df:
28425 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28426 break;
28427 case OPC_FMAX_df:
28428 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28429 break;
28430 case OPC_MSUBR_Q_df:
28431 tcg_gen_movi_i32(tdf, df + 1);
28432 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28433 break;
28434 case OPC_FSULE_df:
28435 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28436 break;
28437 case OPC_FMAX_A_df:
28438 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28439 break;
28440 default:
28441 MIPS_INVAL("MSA instruction");
9c708c7f 28442 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
28443 break;
28444 }
28445
28446 tcg_temp_free_i32(twd);
28447 tcg_temp_free_i32(tws);
28448 tcg_temp_free_i32(twt);
28449 tcg_temp_free_i32(tdf);
28450}
28451
cbe50b9a
YK
28452static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28453{
28454#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28455 (op & (0x7 << 18)))
28456 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28457 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28458 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28459 uint8_t df = (ctx->opcode >> 16) & 0x3;
28460 TCGv_i32 twd = tcg_const_i32(wd);
28461 TCGv_i32 tws = tcg_const_i32(ws);
28462 TCGv_i32 twt = tcg_const_i32(wt);
28463 TCGv_i32 tdf = tcg_const_i32(df);
28464
28465 switch (MASK_MSA_2R(ctx->opcode)) {
28466 case OPC_FILL_df:
28467#if !defined(TARGET_MIPS64)
28468 /* Double format valid only for MIPS64 */
28469 if (df == DF_DOUBLE) {
9c708c7f 28470 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
28471 break;
28472 }
28473#endif
28474 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28475 break;
28476 case OPC_PCNT_df:
28477 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28478 break;
28479 case OPC_NLOC_df:
28480 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28481 break;
28482 case OPC_NLZC_df:
28483 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28484 break;
28485 default:
28486 MIPS_INVAL("MSA instruction");
9c708c7f 28487 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
28488 break;
28489 }
28490
28491 tcg_temp_free_i32(twd);
28492 tcg_temp_free_i32(tws);
28493 tcg_temp_free_i32(twt);
28494 tcg_temp_free_i32(tdf);
28495}
28496
3bdeb688
YK
28497static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28498{
28499#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28500 (op & (0xf << 17)))
28501 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28502 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28503 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28504 uint8_t df = (ctx->opcode >> 16) & 0x1;
28505 TCGv_i32 twd = tcg_const_i32(wd);
28506 TCGv_i32 tws = tcg_const_i32(ws);
28507 TCGv_i32 twt = tcg_const_i32(wt);
28508 /* adjust df value for floating-point instruction */
28509 TCGv_i32 tdf = tcg_const_i32(df + 2);
28510
28511 switch (MASK_MSA_2RF(ctx->opcode)) {
28512 case OPC_FCLASS_df:
28513 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28514 break;
28515 case OPC_FTRUNC_S_df:
28516 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28517 break;
28518 case OPC_FTRUNC_U_df:
28519 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28520 break;
28521 case OPC_FSQRT_df:
28522 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28523 break;
28524 case OPC_FRSQRT_df:
28525 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28526 break;
28527 case OPC_FRCP_df:
28528 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28529 break;
28530 case OPC_FRINT_df:
28531 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28532 break;
28533 case OPC_FLOG2_df:
28534 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28535 break;
28536 case OPC_FEXUPL_df:
28537 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28538 break;
28539 case OPC_FEXUPR_df:
28540 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28541 break;
28542 case OPC_FFQL_df:
28543 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28544 break;
28545 case OPC_FFQR_df:
28546 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28547 break;
28548 case OPC_FTINT_S_df:
28549 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28550 break;
28551 case OPC_FTINT_U_df:
28552 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28553 break;
28554 case OPC_FFINT_S_df:
28555 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28556 break;
28557 case OPC_FFINT_U_df:
28558 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28559 break;
28560 }
28561
28562 tcg_temp_free_i32(twd);
28563 tcg_temp_free_i32(tws);
28564 tcg_temp_free_i32(twt);
28565 tcg_temp_free_i32(tdf);
28566}
28567
cbe50b9a
YK
28568static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28569{
28570#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28571 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28572 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28573 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28574 TCGv_i32 twd = tcg_const_i32(wd);
28575 TCGv_i32 tws = tcg_const_i32(ws);
28576 TCGv_i32 twt = tcg_const_i32(wt);
28577
28578 switch (MASK_MSA_VEC(ctx->opcode)) {
28579 case OPC_AND_V:
28580 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28581 break;
28582 case OPC_OR_V:
28583 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28584 break;
28585 case OPC_NOR_V:
28586 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28587 break;
28588 case OPC_XOR_V:
28589 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28590 break;
28591 case OPC_BMNZ_V:
28592 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28593 break;
28594 case OPC_BMZ_V:
28595 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28596 break;
28597 case OPC_BSEL_V:
28598 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28599 break;
28600 default:
28601 MIPS_INVAL("MSA instruction");
9c708c7f 28602 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
28603 break;
28604 }
28605
28606 tcg_temp_free_i32(twd);
28607 tcg_temp_free_i32(tws);
28608 tcg_temp_free_i32(twt);
28609}
28610
28611static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28612{
28613 switch (MASK_MSA_VEC(ctx->opcode)) {
28614 case OPC_AND_V:
28615 case OPC_OR_V:
28616 case OPC_NOR_V:
28617 case OPC_XOR_V:
28618 case OPC_BMNZ_V:
28619 case OPC_BMZ_V:
28620 case OPC_BSEL_V:
28621 gen_msa_vec_v(env, ctx);
28622 break;
28623 case OPC_MSA_2R:
28624 gen_msa_2r(env, ctx);
28625 break;
3bdeb688
YK
28626 case OPC_MSA_2RF:
28627 gen_msa_2rf(env, ctx);
28628 break;
cbe50b9a
YK
28629 default:
28630 MIPS_INVAL("MSA instruction");
9c708c7f 28631 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
28632 break;
28633 }
28634}
28635
4c789546
YK
28636static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28637{
28638 uint32_t opcode = ctx->opcode;
28639 check_insn(ctx, ASE_MSA);
28640 check_msa_access(ctx);
28641
28642 switch (MASK_MSA_MINOR(opcode)) {
28643 case OPC_MSA_I8_00:
28644 case OPC_MSA_I8_01:
28645 case OPC_MSA_I8_02:
28646 gen_msa_i8(env, ctx);
28647 break;
80e71591
YK
28648 case OPC_MSA_I5_06:
28649 case OPC_MSA_I5_07:
28650 gen_msa_i5(env, ctx);
28651 break;
d4cf28de
YK
28652 case OPC_MSA_BIT_09:
28653 case OPC_MSA_BIT_0A:
28654 gen_msa_bit(env, ctx);
28655 break;
28f99f08
YK
28656 case OPC_MSA_3R_0D:
28657 case OPC_MSA_3R_0E:
28658 case OPC_MSA_3R_0F:
28659 case OPC_MSA_3R_10:
28660 case OPC_MSA_3R_11:
28661 case OPC_MSA_3R_12:
28662 case OPC_MSA_3R_13:
28663 case OPC_MSA_3R_14:
28664 case OPC_MSA_3R_15:
28665 gen_msa_3r(env, ctx);
28666 break;
1e608ec1
YK
28667 case OPC_MSA_ELM:
28668 gen_msa_elm(env, ctx);
28669 break;
7d05b9c8
YK
28670 case OPC_MSA_3RF_1A:
28671 case OPC_MSA_3RF_1B:
28672 case OPC_MSA_3RF_1C:
28673 gen_msa_3rf(env, ctx);
28674 break;
cbe50b9a
YK
28675 case OPC_MSA_VEC:
28676 gen_msa_vec(env, ctx);
28677 break;
f7685877
YK
28678 case OPC_LD_B:
28679 case OPC_LD_H:
28680 case OPC_LD_W:
28681 case OPC_LD_D:
28682 case OPC_ST_B:
28683 case OPC_ST_H:
28684 case OPC_ST_W:
28685 case OPC_ST_D:
28686 {
28687 int32_t s10 = sextract32(ctx->opcode, 16, 10);
28688 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28689 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28690 uint8_t df = (ctx->opcode >> 0) & 0x3;
28691
f7685877 28692 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
28693 TCGv taddr = tcg_temp_new();
28694 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
28695
28696 switch (MASK_MSA_MINOR(opcode)) {
28697 case OPC_LD_B:
adc370a4
YK
28698 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28699 break;
f7685877 28700 case OPC_LD_H:
adc370a4
YK
28701 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28702 break;
f7685877 28703 case OPC_LD_W:
adc370a4
YK
28704 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28705 break;
f7685877 28706 case OPC_LD_D:
adc370a4 28707 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
28708 break;
28709 case OPC_ST_B:
adc370a4
YK
28710 gen_helper_msa_st_b(cpu_env, twd, taddr);
28711 break;
f7685877 28712 case OPC_ST_H:
adc370a4
YK
28713 gen_helper_msa_st_h(cpu_env, twd, taddr);
28714 break;
f7685877 28715 case OPC_ST_W:
adc370a4
YK
28716 gen_helper_msa_st_w(cpu_env, twd, taddr);
28717 break;
f7685877 28718 case OPC_ST_D:
adc370a4 28719 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
28720 break;
28721 }
28722
28723 tcg_temp_free_i32(twd);
adc370a4 28724 tcg_temp_free(taddr);
f7685877
YK
28725 }
28726 break;
4c789546
YK
28727 default:
28728 MIPS_INVAL("MSA instruction");
9c708c7f 28729 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
28730 break;
28731 }
28732
28733}
28734
d2bfa6e6 28735static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
28736{
28737 int32_t offset;
28738 int rs, rt, rd, sa;
28739 uint32_t op, op1;
28740 int16_t imm;
28741
28742 /* make sure instructions are on a word boundary */
eeb3bba8
EC
28743 if (ctx->base.pc_next & 0x3) {
28744 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 28745 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
28746 return;
28747 }
28748
28749 /* Handle blikely not taken case */
28750 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 28751 TCGLabel *l1 = gen_new_label();
099e5b4d 28752
099e5b4d
LA
28753 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28754 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 28755 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
28756 gen_set_label(l1);
28757 }
28758
099e5b4d
LA
28759 op = MASK_OP_MAJOR(ctx->opcode);
28760 rs = (ctx->opcode >> 21) & 0x1f;
28761 rt = (ctx->opcode >> 16) & 0x1f;
28762 rd = (ctx->opcode >> 11) & 0x1f;
28763 sa = (ctx->opcode >> 6) & 0x1f;
28764 imm = (int16_t)ctx->opcode;
28765 switch (op) {
28766 case OPC_SPECIAL:
28767 decode_opc_special(env, ctx);
28768 break;
28769 case OPC_SPECIAL2:
71b8a6b3 28770 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
874b2879 28771 decode_mmi(env, ctx);
b621f018 28772#if !defined(TARGET_MIPS64)
0a348b9a
AM
28773 } else if (ctx->insn_flags & ASE_MXU) {
28774 decode_opc_mxu(env, ctx);
b621f018 28775#endif
71b8a6b3
FN
28776 } else {
28777 decode_opc_special2_legacy(env, ctx);
28778 }
099e5b4d
LA
28779 break;
28780 case OPC_SPECIAL3:
bb41e74b 28781 if (ctx->insn_flags & INSN_R5900) {
874b2879 28782 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
bb41e74b
FN
28783 } else {
28784 decode_opc_special3(env, ctx);
28785 }
099e5b4d 28786 break;
7a387fff
TS
28787 case OPC_REGIMM:
28788 op1 = MASK_REGIMM(ctx->opcode);
28789 switch (op1) {
fecd2646
LA
28790 case OPC_BLTZL: /* REGIMM branches */
28791 case OPC_BGEZL:
28792 case OPC_BLTZALL:
28793 case OPC_BGEZALL:
d9224450 28794 check_insn(ctx, ISA_MIPS2);
fecd2646 28795 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 28796 /* Fallthrough */
fecd2646
LA
28797 case OPC_BLTZ:
28798 case OPC_BGEZ:
b231c103 28799 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 28800 break;
fecd2646
LA
28801 case OPC_BLTZAL:
28802 case OPC_BGEZAL:
0aefa333
YK
28803 if (ctx->insn_flags & ISA_MIPS32R6) {
28804 if (rs == 0) {
28805 /* OPC_NAL, OPC_BAL */
b231c103 28806 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 28807 } else {
9c708c7f 28808 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
28809 }
28810 } else {
b231c103 28811 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 28812 }
c9602061 28813 break;
c2e19f3c
AM
28814 case OPC_TGEI: /* REGIMM traps */
28815 case OPC_TGEIU:
28816 case OPC_TLTI:
28817 case OPC_TLTIU:
28818 case OPC_TEQI:
28819
7a387fff 28820 case OPC_TNEI:
d9224450 28821 check_insn(ctx, ISA_MIPS2);
fecd2646 28822 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
28823 gen_trap(ctx, op1, rs, -1, imm);
28824 break;
bb238210
YK
28825 case OPC_SIGRIE:
28826 check_insn(ctx, ISA_MIPS32R6);
28827 generate_exception_end(ctx, EXCP_RI);
28828 break;
7a387fff 28829 case OPC_SYNCI:
d75c135e 28830 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
28831 /* Break the TB to be able to sync copied instructions
28832 immediately */
eeb3bba8 28833 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 28834 break;
e45a93e2
JL
28835 case OPC_BPOSGE32: /* MIPS DSP branch */
28836#if defined(TARGET_MIPS64)
28837 case OPC_BPOSGE64:
28838#endif
28839 check_dsp(ctx);
b231c103 28840 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 28841 break;
d4ea6acd
LA
28842#if defined(TARGET_MIPS64)
28843 case OPC_DAHI:
28844 check_insn(ctx, ISA_MIPS32R6);
28845 check_mips_64(ctx);
28846 if (rs != 0) {
28847 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28848 }
d4ea6acd
LA
28849 break;
28850 case OPC_DATI:
28851 check_insn(ctx, ISA_MIPS32R6);
28852 check_mips_64(ctx);
28853 if (rs != 0) {
28854 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28855 }
d4ea6acd
LA
28856 break;
28857#endif
6af0bf9c 28858 default: /* Invalid */
923617a3 28859 MIPS_INVAL("regimm");
9c708c7f 28860 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28861 break;
28862 }
28863 break;
7a387fff 28864 case OPC_CP0:
387a8fe5 28865 check_cp0_enabled(ctx);
7a387fff 28866 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 28867 switch (op1) {
7a387fff
TS
28868 case OPC_MFC0:
28869 case OPC_MTC0:
ead9360e
TS
28870 case OPC_MFTR:
28871 case OPC_MTTR:
5204ea79
LA
28872 case OPC_MFHC0:
28873 case OPC_MTHC0:
d26bc211 28874#if defined(TARGET_MIPS64)
7a387fff
TS
28875 case OPC_DMFC0:
28876 case OPC_DMTC0:
28877#endif
f1aa6320 28878#ifndef CONFIG_USER_ONLY
932e71cd 28879 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 28880#endif /* !CONFIG_USER_ONLY */
7a387fff 28881 break;
c38a1d52
AR
28882 case OPC_C0:
28883 case OPC_C0_1:
28884 case OPC_C0_2:
28885 case OPC_C0_3:
28886 case OPC_C0_4:
28887 case OPC_C0_5:
28888 case OPC_C0_6:
28889 case OPC_C0_7:
28890 case OPC_C0_8:
28891 case OPC_C0_9:
28892 case OPC_C0_A:
28893 case OPC_C0_B:
28894 case OPC_C0_C:
28895 case OPC_C0_D:
28896 case OPC_C0_E:
28897 case OPC_C0_F:
f1aa6320 28898#ifndef CONFIG_USER_ONLY
932e71cd 28899 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 28900#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
28901 break;
28902 case OPC_MFMC0:
8706c382 28903#ifndef CONFIG_USER_ONLY
932e71cd 28904 {
099e5b4d 28905 uint32_t op2;
35fbce2c 28906 TCGv t0 = tcg_temp_new();
6c5c1e20 28907
0eaef5aa 28908 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
28909 switch (op2) {
28910 case OPC_DMT:
9affc1c5 28911 check_cp0_mt(ctx);
9ed5726c 28912 gen_helper_dmt(t0);
35fbce2c 28913 gen_store_gpr(t0, rt);
6c5c1e20
TS
28914 break;
28915 case OPC_EMT:
9affc1c5 28916 check_cp0_mt(ctx);
9ed5726c 28917 gen_helper_emt(t0);
35fbce2c 28918 gen_store_gpr(t0, rt);
da80682b 28919 break;
6c5c1e20 28920 case OPC_DVPE:
9affc1c5 28921 check_cp0_mt(ctx);
895c2d04 28922 gen_helper_dvpe(t0, cpu_env);
35fbce2c 28923 gen_store_gpr(t0, rt);
6c5c1e20
TS
28924 break;
28925 case OPC_EVPE:
9affc1c5 28926 check_cp0_mt(ctx);
895c2d04 28927 gen_helper_evpe(t0, cpu_env);
35fbce2c 28928 gen_store_gpr(t0, rt);
6c5c1e20 28929 break;
01bc435b
YK
28930 case OPC_DVP:
28931 check_insn(ctx, ISA_MIPS32R6);
28932 if (ctx->vp) {
28933 gen_helper_dvp(t0, cpu_env);
28934 gen_store_gpr(t0, rt);
28935 }
28936 break;
28937 case OPC_EVP:
28938 check_insn(ctx, ISA_MIPS32R6);
28939 if (ctx->vp) {
28940 gen_helper_evp(t0, cpu_env);
28941 gen_store_gpr(t0, rt);
28942 }
28943 break;
6c5c1e20 28944 case OPC_DI:
d75c135e 28945 check_insn(ctx, ISA_MIPS32R2);
867abc7e 28946 save_cpu_state(ctx, 1);
895c2d04 28947 gen_helper_di(t0, cpu_env);
35fbce2c 28948 gen_store_gpr(t0, rt);
d2bfa6e6
MR
28949 /* Stop translation as we may have switched
28950 the execution mode. */
eeb3bba8 28951 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
28952 break;
28953 case OPC_EI:
d75c135e 28954 check_insn(ctx, ISA_MIPS32R2);
867abc7e 28955 save_cpu_state(ctx, 1);
895c2d04 28956 gen_helper_ei(t0, cpu_env);
35fbce2c 28957 gen_store_gpr(t0, rt);
b28425ba
EC
28958 /* DISAS_STOP isn't sufficient, we need to ensure we break
28959 out of translated code to check for pending interrupts */
eeb3bba8
EC
28960 gen_save_pc(ctx->base.pc_next + 4);
28961 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
28962 break;
28963 default: /* Invalid */
28964 MIPS_INVAL("mfmc0");
9c708c7f 28965 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
28966 break;
28967 }
6c5c1e20 28968 tcg_temp_free(t0);
7a387fff 28969 }
0eaef5aa 28970#endif /* !CONFIG_USER_ONLY */
6af0bf9c 28971 break;
7a387fff 28972 case OPC_RDPGPR:
d75c135e 28973 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 28974 gen_load_srsgpr(rt, rd);
ead9360e 28975 break;
7a387fff 28976 case OPC_WRPGPR:
d75c135e 28977 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 28978 gen_store_srsgpr(rt, rd);
38121543 28979 break;
6af0bf9c 28980 default:
923617a3 28981 MIPS_INVAL("cp0");
9c708c7f 28982 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28983 break;
28984 }
28985 break;
31837be3
YK
28986 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28987 if (ctx->insn_flags & ISA_MIPS32R6) {
28988 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28989 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28990 } else {
28991 /* OPC_ADDI */
28992 /* Arithmetic with immediate opcode */
28993 gen_arith_imm(ctx, op, rt, rs, imm);
28994 }
28995 break;
324d9e32 28996 case OPC_ADDIU:
d75c135e 28997 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28998 break;
324d9e32
AJ
28999 case OPC_SLTI: /* Set on less than with immediate opcode */
29000 case OPC_SLTIU:
d75c135e 29001 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
29002 break;
29003 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 29004 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
29005 case OPC_ORI:
29006 case OPC_XORI:
d75c135e 29007 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 29008 break;
c2e19f3c
AM
29009 case OPC_J: /* Jump */
29010 case OPC_JAL:
7a387fff 29011 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 29012 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 29013 break;
31837be3
YK
29014 /* Branch */
29015 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29016 if (ctx->insn_flags & ISA_MIPS32R6) {
29017 if (rt == 0) {
9c708c7f 29018 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
29019 break;
29020 }
29021 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29022 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29023 } else {
29024 /* OPC_BLEZL */
b231c103 29025 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
29026 }
29027 break;
29028 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29029 if (ctx->insn_flags & ISA_MIPS32R6) {
29030 if (rt == 0) {
9c708c7f 29031 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
29032 break;
29033 }
29034 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29035 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29036 } else {
29037 /* OPC_BGTZL */
b231c103 29038 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
29039 }
29040 break;
29041 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29042 if (rt == 0) {
29043 /* OPC_BLEZ */
b231c103 29044 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
29045 } else {
29046 check_insn(ctx, ISA_MIPS32R6);
29047 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29048 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29049 }
29050 break;
29051 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29052 if (rt == 0) {
29053 /* OPC_BGTZ */
b231c103 29054 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
29055 } else {
29056 check_insn(ctx, ISA_MIPS32R6);
29057 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29058 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29059 }
29060 break;
29061 case OPC_BEQL:
29062 case OPC_BNEL:
d9224450 29063 check_insn(ctx, ISA_MIPS2);
fecd2646 29064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 29065 /* Fallthrough */
31837be3
YK
29066 case OPC_BEQ:
29067 case OPC_BNE:
b231c103 29068 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 29069 break;
d9224450
MR
29070 case OPC_LL: /* Load and stores */
29071 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
29072 if (ctx->insn_flags & INSN_R5900) {
29073 check_insn_opc_user_only(ctx, INSN_R5900);
29074 }
d9224450
MR
29075 /* Fallthrough */
29076 case OPC_LWL:
fecd2646
LA
29077 case OPC_LWR:
29078 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 29079 /* Fallthrough */
c2e19f3c
AM
29080 case OPC_LB:
29081 case OPC_LH:
29082 case OPC_LW:
29083 case OPC_LWPC:
29084 case OPC_LBU:
29085 case OPC_LHU:
d75c135e 29086 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 29087 break;
fecd2646 29088 case OPC_SWL:
7a387fff 29089 case OPC_SWR:
fecd2646 29090 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 29091 /* fall through */
c2e19f3c
AM
29092 case OPC_SB:
29093 case OPC_SH:
fecd2646 29094 case OPC_SW:
5c13fdfd 29095 gen_st(ctx, op, rt, rs, imm);
7a387fff 29096 break;
d66c7132 29097 case OPC_SC:
d9224450 29098 check_insn(ctx, ISA_MIPS2);
4368b29a 29099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
55fc7a69
FN
29100 if (ctx->insn_flags & INSN_R5900) {
29101 check_insn_opc_user_only(ctx, INSN_R5900);
29102 }
d66c7132
AJ
29103 gen_st_cond(ctx, op, rt, rs, imm);
29104 break;
7a387fff 29105 case OPC_CACHE:
bf7910c6 29106 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 29107 check_cp0_enabled(ctx);
d75c135e 29108 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
29109 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29110 gen_cache_operation(ctx, rt, rs, imm);
29111 }
ead9360e 29112 /* Treat as NOP. */
34ae7b51 29113 break;
7a387fff 29114 case OPC_PREF:
bf7910c6 29115 check_insn_opc_removed(ctx, ISA_MIPS32R6);
992e8176
FN
29116 if (ctx->insn_flags & INSN_R5900) {
29117 /* Treat as NOP. */
29118 } else {
29119 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29120 /* Treat as NOP. */
29121 }
6af0bf9c 29122 break;
4ad40f36 29123
923617a3 29124 /* Floating point (COP1). */
7a387fff
TS
29125 case OPC_LWC1:
29126 case OPC_LDC1:
29127 case OPC_SWC1:
29128 case OPC_SDC1:
5ab5c041 29129 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
29130 break;
29131
7a387fff 29132 case OPC_CP1:
5692c6e1
YK
29133 op1 = MASK_CP1(ctx->opcode);
29134
29135 switch (op1) {
29136 case OPC_MFHC1:
29137 case OPC_MTHC1:
5e755519 29138 check_cp1_enabled(ctx);
5692c6e1 29139 check_insn(ctx, ISA_MIPS32R2);
146dd620 29140 /* fall through */
5692c6e1
YK
29141 case OPC_MFC1:
29142 case OPC_CFC1:
29143 case OPC_MTC1:
29144 case OPC_CTC1:
29145 check_cp1_enabled(ctx);
29146 gen_cp1(ctx, op1, rt, rd);
29147 break;
d26bc211 29148#if defined(TARGET_MIPS64)
5692c6e1
YK
29149 case OPC_DMFC1:
29150 case OPC_DMTC1:
29151 check_cp1_enabled(ctx);
29152 check_insn(ctx, ISA_MIPS3);
d9224450 29153 check_mips_64(ctx);
5692c6e1
YK
29154 gen_cp1(ctx, op1, rt, rd);
29155 break;
e189e748 29156#endif
5692c6e1
YK
29157 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29158 check_cp1_enabled(ctx);
29159 if (ctx->insn_flags & ISA_MIPS32R6) {
29160 /* OPC_BC1EQZ */
31837be3 29161 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 29162 rt, imm << 2, 4);
5692c6e1
YK
29163 } else {
29164 /* OPC_BC1ANY2 */
b8aa4598 29165 check_cop1x(ctx);
d75c135e 29166 check_insn(ctx, ASE_MIPS3D);
d75c135e 29167 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 29168 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
29169 }
29170 break;
29171 case OPC_BC1NEZ:
29172 check_cp1_enabled(ctx);
29173 check_insn(ctx, ISA_MIPS32R6);
29174 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 29175 rt, imm << 2, 4);
5692c6e1
YK
29176 break;
29177 case OPC_BC1ANY4:
29178 check_cp1_enabled(ctx);
29179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29180 check_cop1x(ctx);
29181 check_insn(ctx, ASE_MIPS3D);
29182 /* fall through */
29183 case OPC_BC1:
29184 check_cp1_enabled(ctx);
29185 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29186 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29187 (rt >> 2) & 0x7, imm << 2);
29188 break;
29189 case OPC_PS_FMT:
e29c9628 29190 check_ps(ctx);
b6f3b233 29191 /* fall through */
5692c6e1
YK
29192 case OPC_S_FMT:
29193 case OPC_D_FMT:
29194 check_cp1_enabled(ctx);
29195 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29196 (imm >> 8) & 0x7);
29197 break;
29198 case OPC_W_FMT:
29199 case OPC_L_FMT:
29200 {
29201 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29202 check_cp1_enabled(ctx);
29203 if (ctx->insn_flags & ISA_MIPS32R6) {
29204 switch (r6_op) {
29205 case R6_OPC_CMP_AF_S:
29206 case R6_OPC_CMP_UN_S:
29207 case R6_OPC_CMP_EQ_S:
29208 case R6_OPC_CMP_UEQ_S:
29209 case R6_OPC_CMP_LT_S:
29210 case R6_OPC_CMP_ULT_S:
29211 case R6_OPC_CMP_LE_S:
29212 case R6_OPC_CMP_ULE_S:
29213 case R6_OPC_CMP_SAF_S:
29214 case R6_OPC_CMP_SUN_S:
29215 case R6_OPC_CMP_SEQ_S:
29216 case R6_OPC_CMP_SEUQ_S:
29217 case R6_OPC_CMP_SLT_S:
29218 case R6_OPC_CMP_SULT_S:
29219 case R6_OPC_CMP_SLE_S:
29220 case R6_OPC_CMP_SULE_S:
29221 case R6_OPC_CMP_OR_S:
29222 case R6_OPC_CMP_UNE_S:
29223 case R6_OPC_CMP_NE_S:
29224 case R6_OPC_CMP_SOR_S:
29225 case R6_OPC_CMP_SUNE_S:
29226 case R6_OPC_CMP_SNE_S:
29227 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29228 break;
29229 case R6_OPC_CMP_AF_D:
29230 case R6_OPC_CMP_UN_D:
29231 case R6_OPC_CMP_EQ_D:
29232 case R6_OPC_CMP_UEQ_D:
29233 case R6_OPC_CMP_LT_D:
29234 case R6_OPC_CMP_ULT_D:
29235 case R6_OPC_CMP_LE_D:
29236 case R6_OPC_CMP_ULE_D:
29237 case R6_OPC_CMP_SAF_D:
29238 case R6_OPC_CMP_SUN_D:
29239 case R6_OPC_CMP_SEQ_D:
29240 case R6_OPC_CMP_SEUQ_D:
29241 case R6_OPC_CMP_SLT_D:
29242 case R6_OPC_CMP_SULT_D:
29243 case R6_OPC_CMP_SLE_D:
29244 case R6_OPC_CMP_SULE_D:
29245 case R6_OPC_CMP_OR_D:
29246 case R6_OPC_CMP_UNE_D:
29247 case R6_OPC_CMP_NE_D:
29248 case R6_OPC_CMP_SOR_D:
29249 case R6_OPC_CMP_SUNE_D:
29250 case R6_OPC_CMP_SNE_D:
29251 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29252 break;
29253 default:
d2bfa6e6
MR
29254 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29255 rt, rd, sa, (imm >> 8) & 0x7);
29256
5692c6e1 29257 break;
3f493883 29258 }
5692c6e1
YK
29259 } else {
29260 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29261 (imm >> 8) & 0x7);
36d23958 29262 }
5692c6e1
YK
29263 break;
29264 }
29265 case OPC_BZ_V:
29266 case OPC_BNZ_V:
29267 case OPC_BZ_B:
29268 case OPC_BZ_H:
29269 case OPC_BZ_W:
29270 case OPC_BZ_D:
29271 case OPC_BNZ_B:
29272 case OPC_BNZ_H:
29273 case OPC_BNZ_W:
29274 case OPC_BNZ_D:
29275 check_insn(ctx, ASE_MSA);
29276 gen_msa_branch(env, ctx, op1);
29277 break;
29278 default:
29279 MIPS_INVAL("cp1");
9c708c7f 29280 generate_exception_end(ctx, EXCP_RI);
5692c6e1 29281 break;
6ea83fed 29282 }
4ad40f36
FB
29283 break;
29284
31837be3
YK
29285 /* Compact branches [R6] and COP2 [non-R6] */
29286 case OPC_BC: /* OPC_LWC2 */
29287 case OPC_BALC: /* OPC_SWC2 */
29288 if (ctx->insn_flags & ISA_MIPS32R6) {
29289 /* OPC_BC, OPC_BALC */
29290 gen_compute_compact_branch(ctx, op, 0, 0,
29291 sextract32(ctx->opcode << 2, 0, 28));
29292 } else {
29293 /* OPC_LWC2, OPC_SWC2 */
29294 /* COP2: Not implemented. */
29295 generate_exception_err(ctx, EXCP_CpU, 2);
29296 }
29297 break;
29298 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29299 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29300 if (ctx->insn_flags & ISA_MIPS32R6) {
29301 if (rs != 0) {
29302 /* OPC_BEQZC, OPC_BNEZC */
29303 gen_compute_compact_branch(ctx, op, rs, 0,
29304 sextract32(ctx->opcode << 2, 0, 23));
29305 } else {
29306 /* OPC_JIC, OPC_JIALC */
29307 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29308 }
29309 } else {
29310 /* OPC_LWC2, OPC_SWC2 */
29311 /* COP2: Not implemented. */
29312 generate_exception_err(ctx, EXCP_CpU, 2);
29313 }
4ad40f36 29314 break;
bd277fa1 29315 case OPC_CP2:
d75c135e 29316 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
29317 /* Note that these instructions use different fields. */
29318 gen_loongson_multimedia(ctx, sa, rd, rt);
29319 break;
4ad40f36 29320
7a387fff 29321 case OPC_CP3:
fecd2646 29322 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 29323 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 29324 check_cp1_enabled(ctx);
36d23958
TS
29325 op1 = MASK_CP3(ctx->opcode);
29326 switch (op1) {
d9224450
MR
29327 case OPC_LUXC1:
29328 case OPC_SUXC1:
29329 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29330 /* Fallthrough */
5a5012ec
TS
29331 case OPC_LWXC1:
29332 case OPC_LDXC1:
5a5012ec
TS
29333 case OPC_SWXC1:
29334 case OPC_SDXC1:
d9224450 29335 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 29336 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 29337 break;
e0c84da7 29338 case OPC_PREFX:
d9224450 29339 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 29340 /* Treat as NOP. */
e0c84da7 29341 break;
5a5012ec 29342 case OPC_ALNV_PS:
d9224450
MR
29343 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29344 /* Fallthrough */
5a5012ec
TS
29345 case OPC_MADD_S:
29346 case OPC_MADD_D:
29347 case OPC_MADD_PS:
29348 case OPC_MSUB_S:
29349 case OPC_MSUB_D:
29350 case OPC_MSUB_PS:
29351 case OPC_NMADD_S:
29352 case OPC_NMADD_D:
29353 case OPC_NMADD_PS:
29354 case OPC_NMSUB_S:
29355 case OPC_NMSUB_D:
29356 case OPC_NMSUB_PS:
d9224450 29357 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
29358 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29359 break;
36d23958 29360 default:
923617a3 29361 MIPS_INVAL("cp3");
9c708c7f 29362 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
29363 break;
29364 }
29365 } else {
e397ee33 29366 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 29367 }
4ad40f36
FB
29368 break;
29369
d26bc211 29370#if defined(TARGET_MIPS64)
7a387fff 29371 /* MIPS64 opcodes */
96631327 29372 case OPC_LLD:
55fc7a69
FN
29373 if (ctx->insn_flags & INSN_R5900) {
29374 check_insn_opc_user_only(ctx, INSN_R5900);
29375 }
96631327 29376 /* fall through */
c2e19f3c
AM
29377 case OPC_LDL:
29378 case OPC_LDR:
fecd2646 29379 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 29380 /* fall through */
fecd2646 29381 case OPC_LWU:
7a387fff 29382 case OPC_LD:
d75c135e 29383 check_insn(ctx, ISA_MIPS3);
5c13fdfd 29384 check_mips_64(ctx);
d75c135e 29385 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 29386 break;
c2e19f3c
AM
29387 case OPC_SDL:
29388 case OPC_SDR:
fecd2646 29389 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 29390 /* fall through */
7a387fff 29391 case OPC_SD:
d75c135e 29392 check_insn(ctx, ISA_MIPS3);
e189e748 29393 check_mips_64(ctx);
5c13fdfd 29394 gen_st(ctx, op, rt, rs, imm);
7a387fff 29395 break;
d66c7132 29396 case OPC_SCD:
bf7910c6 29397 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 29398 check_insn(ctx, ISA_MIPS3);
55fc7a69
FN
29399 if (ctx->insn_flags & INSN_R5900) {
29400 check_insn_opc_user_only(ctx, INSN_R5900);
29401 }
d66c7132
AJ
29402 check_mips_64(ctx);
29403 gen_st_cond(ctx, op, rt, rs, imm);
29404 break;
31837be3
YK
29405 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29406 if (ctx->insn_flags & ISA_MIPS32R6) {
29407 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29408 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29409 } else {
29410 /* OPC_DADDI */
29411 check_insn(ctx, ISA_MIPS3);
29412 check_mips_64(ctx);
29413 gen_arith_imm(ctx, op, rt, rs, imm);
29414 }
29415 break;
324d9e32 29416 case OPC_DADDIU:
d75c135e 29417 check_insn(ctx, ISA_MIPS3);
e189e748 29418 check_mips_64(ctx);
d75c135e 29419 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 29420 break;
31837be3
YK
29421#else
29422 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29423 if (ctx->insn_flags & ISA_MIPS32R6) {
29424 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29425 } else {
29426 MIPS_INVAL("major opcode");
9c708c7f 29427 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
29428 }
29429 break;
6af0bf9c 29430#endif
d4ea6acd
LA
29431 case OPC_DAUI: /* OPC_JALX */
29432 if (ctx->insn_flags & ISA_MIPS32R6) {
29433#if defined(TARGET_MIPS64)
29434 /* OPC_DAUI */
29435 check_mips_64(ctx);
db77d852
LA
29436 if (rs == 0) {
29437 generate_exception(ctx, EXCP_RI);
29438 } else if (rt != 0) {
d4ea6acd
LA
29439 TCGv t0 = tcg_temp_new();
29440 gen_load_gpr(t0, rs);
29441 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29442 tcg_temp_free(t0);
29443 }
d4ea6acd 29444#else
9c708c7f 29445 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
29446 MIPS_INVAL("major opcode");
29447#endif
29448 } else {
29449 /* OPC_JALX */
29450 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29451 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 29452 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 29453 }
364d4831 29454 break;
4c789546 29455 case OPC_MSA: /* OPC_MDMX */
f08099ad 29456 if (ctx->insn_flags & INSN_R5900) {
874b2879 29457 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
f08099ad
FN
29458 } else {
29459 /* MDMX: Not implemented. */
29460 gen_msa(env, ctx);
29461 }
d4ea6acd
LA
29462 break;
29463 case OPC_PCREL:
29464 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 29465 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 29466 break;
6af0bf9c 29467 default: /* Invalid */
923617a3 29468 MIPS_INVAL("major opcode");
9c708c7f 29469 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
29470 break;
29471 }
6af0bf9c
FB
29472}
29473
18f440ed 29474static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 29475{
18f440ed 29476 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 29477 CPUMIPSState *env = cs->env_ptr;
12be9258 29478
18f440ed 29479 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
29480 ctx->saved_pc = -1;
29481 ctx->insn_flags = env->insn_flags;
29482 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 29483 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
29484 ctx->CP0_Config3 = env->CP0_Config3;
29485 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
29486 ctx->btarget = 0;
29487 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29488 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29489 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29490 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29491 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29492 ctx->PAMask = env->PAMask;
29493 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29494 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29495 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29496 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29497 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 29498 /* Restore delay slot state from the tb context. */
12be9258
EC
29499 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29500 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29501 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 29502 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
29503 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29504 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29505 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29506 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29507 restore_cpu_state(env, ctx);
932e71cd 29508#ifdef CONFIG_USER_ONLY
12be9258 29509 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 29510#else
12be9258 29511 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 29512#endif
12be9258
EC
29513 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29514 MO_UNALN : MO_ALIGN;
190ce7fb 29515
18f440ed
EC
29516 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29517 ctx->hflags);
29518}
12be9258 29519
18f440ed
EC
29520static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29521{
29522}
b933066a 29523
18f440ed
EC
29524static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29525{
29526 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 29527
18f440ed
EC
29528 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29529 ctx->btarget);
29530}
31837be3 29531
18f440ed
EC
29532static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29533 const CPUBreakpoint *bp)
29534{
29535 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 29536
18f440ed
EC
29537 save_cpu_state(ctx, 1);
29538 ctx->base.is_jmp = DISAS_NORETURN;
29539 gen_helper_raise_exception_debug(cpu_env);
29540 /* The address covered by the breakpoint must be included in
29541 [tb->pc, tb->pc + tb->size) in order to for it to be
29542 properly cleared -- thus we increment the PC here so that
29543 the logic setting tb->size below does the right thing. */
29544 ctx->base.pc_next += 4;
29545 return true;
29546}
4ad40f36 29547
18f440ed
EC
29548static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29549{
29550 CPUMIPSState *env = cs->env_ptr;
29551 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29552 int insn_bytes;
29553 int is_slot;
4ad40f36 29554
18f440ed 29555 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
29556 if (ctx->insn_flags & ISA_NANOMIPS32) {
29557 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29558 insn_bytes = decode_nanomips_opc(env, ctx);
29559 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
29560 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29561 insn_bytes = 4;
29562 decode_opc(env, ctx);
29563 } else if (ctx->insn_flags & ASE_MICROMIPS) {
29564 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29565 insn_bytes = decode_micromips_opc(env, ctx);
29566 } else if (ctx->insn_flags & ASE_MIPS16) {
29567 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29568 insn_bytes = decode_mips16_opc(env, ctx);
29569 } else {
29570 generate_exception_end(ctx, EXCP_RI);
29571 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29572 return;
29573 }
faf7aaa9 29574
18f440ed
EC
29575 if (ctx->hflags & MIPS_HFLAG_BMASK) {
29576 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29577 MIPS_HFLAG_FBNSLOT))) {
29578 /* force to generate branch as there is neither delay nor
29579 forbidden slot */
29580 is_slot = 1;
29581 }
29582 if ((ctx->hflags & MIPS_HFLAG_M16) &&
29583 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29584 /* Force to generate branch as microMIPS R6 doesn't restrict
29585 branches in the forbidden slot. */
29586 is_slot = 1;
eeb3bba8 29587 }
18f440ed
EC
29588 }
29589 if (is_slot) {
29590 gen_branch(ctx, insn_bytes);
29591 }
29592 ctx->base.pc_next += insn_bytes;
1b530a6d 29593
18f440ed
EC
29594 if (ctx->base.is_jmp != DISAS_NEXT) {
29595 return;
6af0bf9c 29596 }
18f440ed
EC
29597 /* Execute a branch and its delay slot as a single instruction.
29598 This is what GDB expects and is consistent with what the
29599 hardware does (e.g. if a delay slot instruction faults, the
29600 reported PC is the PC of the branch). */
29601 if (ctx->base.singlestep_enabled &&
29602 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29603 ctx->base.is_jmp = DISAS_TOO_MANY;
29604 }
29605 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29606 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 29607 }
18f440ed
EC
29608}
29609
29610static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29611{
29612 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29613
12be9258
EC
29614 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29615 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 29616 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 29617 } else {
12be9258 29618 switch (ctx->base.is_jmp) {
b28425ba 29619 case DISAS_STOP:
12be9258 29620 gen_save_pc(ctx->base.pc_next);
cd314a7d 29621 tcg_gen_lookup_and_goto_ptr();
df1561e2 29622 break;
b28425ba 29623 case DISAS_NEXT:
18f440ed 29624 case DISAS_TOO_MANY:
12be9258
EC
29625 save_cpu_state(ctx, 0);
29626 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 29627 break;
b28425ba 29628 case DISAS_EXIT:
07ea28b4 29629 tcg_gen_exit_tb(NULL, 0);
16c00cb2 29630 break;
b28425ba 29631 case DISAS_NORETURN:
5a5012ec 29632 break;
18f440ed
EC
29633 default:
29634 g_assert_not_reached();
6958549d 29635 }
6af0bf9c 29636 }
18f440ed
EC
29637}
29638
29639static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29640{
29641 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29642 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29643}
29644
29645static const TranslatorOps mips_tr_ops = {
29646 .init_disas_context = mips_tr_init_disas_context,
29647 .tb_start = mips_tr_tb_start,
29648 .insn_start = mips_tr_insn_start,
29649 .breakpoint_check = mips_tr_breakpoint_check,
29650 .translate_insn = mips_tr_translate_insn,
29651 .tb_stop = mips_tr_tb_stop,
29652 .disas_log = mips_tr_disas_log,
29653};
29654
29655void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29656{
29657 DisasContext ctx;
29658
29659 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
29660}
29661
7db13fae 29662static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 29663 int flags)
6ea83fed
FB
29664{
29665 int i;
5e755519 29666 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 29667
2a5612e6
SW
29668#define printfpr(fp) \
29669 do { \
29670 if (is_fpu64) \
29671 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29672 " fd:%13g fs:%13g psu: %13g\n", \
29673 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29674 (double)(fp)->fd, \
29675 (double)(fp)->fs[FP_ENDIAN_IDX], \
29676 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29677 else { \
29678 fpr_t tmp; \
29679 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29680 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29681 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29682 " fd:%13g fs:%13g psu:%13g\n", \
29683 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29684 (double)tmp.fd, \
29685 (double)tmp.fs[FP_ENDIAN_IDX], \
29686 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29687 } \
6ea83fed
FB
29688 } while(0)
29689
5a5012ec 29690
9a78eead
SW
29691 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29692 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 29693 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
29694 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29695 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 29696 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
29697 }
29698
29699#undef printfpr
29700}
29701
878096ee
AF
29702void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29703 int flags)
6af0bf9c 29704{
878096ee
AF
29705 MIPSCPU *cpu = MIPS_CPU(cs);
29706 CPUMIPSState *env = &cpu->env;
6af0bf9c 29707 int i;
3b46e624 29708
a7200c9f
SW
29709 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29710 " LO=0x" TARGET_FMT_lx " ds %04x "
29711 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
29712 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29713 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
29714 for (i = 0; i < 32; i++) {
29715 if ((i & 3) == 0)
29716 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 29717 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
29718 if ((i & 3) == 3)
29719 cpu_fprintf(f, "\n");
29720 }
568b600d 29721
3594c774 29722 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 29723 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
29724 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29725 PRIx64 "\n",
5499b6ff 29726 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
29727 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
29728 env->CP0_Config2, env->CP0_Config3);
29729 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
29730 env->CP0_Config4, env->CP0_Config5);
1cc5af69 29731 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 29732 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 29733 }
6af0bf9c
FB
29734}
29735
78ce64f4 29736void mips_tcg_init(void)
39454628 29737{
f01be154 29738 int i;
39454628 29739
f764718d 29740 cpu_gpr[0] = NULL;
bb928dbe 29741 for (i = 1; i < 32; i++)
e1ccc054 29742 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 29743 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 29744 regnames[i]);
d73ee8a2 29745
863f264d
YK
29746 for (i = 0; i < 32; i++) {
29747 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29748 msa_wr_d[i * 2] =
e1ccc054 29749 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
29750 /* The scalar floating-point unit (FPU) registers are mapped on
29751 * the MSA vector registers. */
29752 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
29753 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29754 msa_wr_d[i * 2 + 1] =
e1ccc054 29755 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
29756 }
29757
e1ccc054 29758 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 29759 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 29760 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 29761 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 29762 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 29763 regnames_HI[i]);
e1ccc054 29764 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 29765 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 29766 regnames_LO[i]);
4b2eb8d2 29767 }
e1ccc054 29768 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 29769 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 29770 "DSPControl");
e1ccc054 29771 bcond = tcg_global_mem_new(cpu_env,
7db13fae 29772 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 29773 btarget = tcg_global_mem_new(cpu_env,
7db13fae 29774 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 29775 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 29776 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 29777
e1ccc054 29778 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29779 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 29780 "fcr0");
e1ccc054 29781 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29782 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 29783 "fcr31");
b621f018 29784#if !defined(TARGET_MIPS64)
eb5559f6
CJ
29785 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29786 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29787 offsetof(CPUMIPSState,
29788 active_tc.mxu_gpr[i]),
29789 mxuregnames[i]);
29790 }
29791
29792 mxu_CR = tcg_global_mem_new(cpu_env,
29793 offsetof(CPUMIPSState, active_tc.mxu_cr),
29794 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
b621f018 29795#endif
39454628
TS
29796}
29797
5b27a92d 29798#include "translate_init.inc.c"
aaed909a 29799
27e38392
PMD
29800void cpu_mips_realize_env(CPUMIPSState *env)
29801{
29802 env->exception_base = (int32_t)0xBFC00000;
29803
29804#ifndef CONFIG_USER_ONLY
29805 mmu_init(env, env->cpu_model);
29806#endif
29807 fpu_init(env, env->cpu_model);
29808 mvp_init(env, env->cpu_model);
29809}
29810
a7519f2b 29811bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 29812{
a7519f2b
IM
29813 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29814 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
29815}
29816
a7519f2b 29817bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 29818{
a7519f2b
IM
29819 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29820 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
29821}
29822
89777fd1
LA
29823void cpu_set_exception_base(int vp_index, target_ulong address)
29824{
29825 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29826 vp->env.exception_base = address;
29827}
29828
1bba0dc9 29829void cpu_state_reset(CPUMIPSState *env)
6ae81775 29830{
55e5c285
AF
29831 MIPSCPU *cpu = mips_env_get_cpu(env);
29832 CPUState *cs = CPU(cpu);
6ae81775 29833
51cc2e78
BS
29834 /* Reset registers to their default values */
29835 env->CP0_PRid = env->cpu_model->CP0_PRid;
29836 env->CP0_Config0 = env->cpu_model->CP0_Config0;
29837#ifdef TARGET_WORDS_BIGENDIAN
29838 env->CP0_Config0 |= (1 << CP0C0_BE);
29839#endif
29840 env->CP0_Config1 = env->cpu_model->CP0_Config1;
29841 env->CP0_Config2 = env->cpu_model->CP0_Config2;
29842 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
29843 env->CP0_Config4 = env->cpu_model->CP0_Config4;
29844 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
29845 env->CP0_Config5 = env->cpu_model->CP0_Config5;
29846 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
29847 env->CP0_Config6 = env->cpu_model->CP0_Config6;
29848 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
29849 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29850 << env->cpu_model->CP0_LLAddr_shift;
29851 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
29852 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29853 env->CCRes = env->cpu_model->CCRes;
29854 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29855 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29856 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29857 env->current_tc = 0;
29858 env->SEGBITS = env->cpu_model->SEGBITS;
29859 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29860#if defined(TARGET_MIPS64)
29861 if (env->cpu_model->insn_flags & ISA_MIPS3) {
29862 env->SEGMask |= 3ULL << 62;
29863 }
29864#endif
29865 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
29866 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29867 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29868 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29869 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29870 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29871 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29872 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29873 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29874 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29875 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
29876 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29877 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 29878 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 29879 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 29880 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 29881 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 29882 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
29883 env->insn_flags = env->cpu_model->insn_flags;
29884
0eaef5aa 29885#if defined(CONFIG_USER_ONLY)
03e6e501 29886 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
29887# ifdef TARGET_MIPS64
29888 /* Enable 64-bit register mode. */
29889 env->CP0_Status |= (1 << CP0St_PX);
29890# endif
29891# ifdef TARGET_ABI_MIPSN64
29892 /* Enable 64-bit address mode. */
29893 env->CP0_Status |= (1 << CP0St_UX);
29894# endif
94159135
MI
29895 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29896 hardware registers. */
29897 env->CP0_HWREna |= 0x0000000F;
91a75935 29898 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 29899 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 29900 }
6f0af304
PJ
29901 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29902 env->CP0_Status |= (1 << CP0St_MX);
853c3240 29903 }
4d66261f
PJ
29904# if defined(TARGET_MIPS64)
29905 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29906 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29907 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
29908 env->CP0_Status |= (1 << CP0St_FR);
29909 }
4d66261f 29910# endif
932e71cd
AJ
29911#else
29912 if (env->hflags & MIPS_HFLAG_BMASK) {
29913 /* If the exception was raised from a delay slot,
29914 come back to the jump. */
c3577479
MR
29915 env->CP0_ErrorEPC = (env->active_tc.PC
29916 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 29917 } else {
932e71cd
AJ
29918 env->CP0_ErrorEPC = env->active_tc.PC;
29919 }
89777fd1 29920 env->active_tc.PC = env->exception_base;
51cc2e78
BS
29921 env->CP0_Random = env->tlb->nb_tlb - 1;
29922 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 29923 env->CP0_Wired = 0;
01bc435b 29924 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 29925 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 29926 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
29927 env->CP0_EBase |= 0x40000000;
29928 } else {
74dbf824 29929 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 29930 }
c870e3f5
YK
29931 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29932 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29933 }
a0c80608
PB
29934 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
29935 0x3ff : 0xff;
932e71cd
AJ
29936 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
29937 /* vectored interrupts not implemented, timer on int 7,
29938 no performance counters. */
29939 env->CP0_IntCtl = 0xe0000000;
29940 {
29941 int i;
29942
29943 for (i = 0; i < 7; i++) {
29944 env->CP0_WatchLo[i] = 0;
29945 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 29946 }
932e71cd
AJ
29947 env->CP0_WatchLo[7] = 0;
29948 env->CP0_WatchHi[7] = 0;
fd88b6ab 29949 }
932e71cd
AJ
29950 /* Count register increments in debug mode, EJTAG version 1 */
29951 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 29952
4b69c7e2
JH
29953 cpu_mips_store_count(env, 1);
29954
9e56e756
EI
29955 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
29956 int i;
29957
29958 /* Only TC0 on VPE 0 starts as active. */
29959 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 29960 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
29961 env->tcs[i].CP0_TCHalt = 1;
29962 }
29963 env->active_tc.CP0_TCHalt = 1;
259186a7 29964 cs->halted = 1;
9e56e756 29965
55e5c285 29966 if (cs->cpu_index == 0) {
9e56e756
EI
29967 /* VPE0 starts up enabled. */
29968 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
29969 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
29970
29971 /* TC0 starts up unhalted. */
259186a7 29972 cs->halted = 0;
9e56e756
EI
29973 env->active_tc.CP0_TCHalt = 0;
29974 env->tcs[0].CP0_TCHalt = 0;
29975 /* With thread 0 active. */
29976 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
29977 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
29978 }
29979 }
cec56a73
JH
29980
29981 /*
29982 * Configure default legacy segmentation control. We use this regardless of
29983 * whether segmentation control is presented to the guest.
29984 */
29985 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
29986 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
29987 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
29988 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
29989 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
29990 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29991 (2 << CP0SC_C);
29992 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
29993 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29994 (3 << CP0SC_C)) << 16;
29995 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
29996 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29997 (1 << CP0SC_EU) | (2 << CP0SC_C);
29998 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
29999 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30000 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30001 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30002 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 30003#endif
ddc584bd
LA
30004 if ((env->insn_flags & ISA_MIPS32R6) &&
30005 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30006 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30007 env->CP0_Status |= (1 << CP0St_FR);
30008 }
30009
63010795
YK
30010 if (env->insn_flags & ISA_MIPS32R6) {
30011 /* PTW = 1 */
30012 env->CP0_PWSize = 0x40;
30013 /* GDI = 12 */
30014 /* UDI = 12 */
30015 /* MDI = 12 */
30016 /* PRI = 12 */
30017 /* PTEI = 2 */
30018 env->CP0_PWField = 0x0C30C302;
30019 } else {
30020 /* GDI = 0 */
30021 /* UDI = 0 */
30022 /* MDI = 0 */
30023 /* PRI = 0 */
30024 /* PTEI = 2 */
30025 env->CP0_PWField = 0x02;
30026 }
30027
0bbc0396
SM
30028 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30029 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
30030 env->hflags |= MIPS_HFLAG_M16;
30031 }
30032
863f264d
YK
30033 /* MSA */
30034 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30035 msa_reset(env);
30036 }
30037
03e6e501 30038 compute_hflags(env);
599bc5e8 30039 restore_fp_status(env);
e117f526 30040 restore_pamask(env);
27103424 30041 cs->exception_index = EXCP_NONE;
3b3c1694
LA
30042
30043 if (semihosting_get_argc()) {
30044 /* UHI interface can be used to obtain argc and argv */
30045 env->active_tc.gpr[4] = -1;
30046 }
6af0bf9c 30047}
d2856f1a 30048
bad729e2
RH
30049void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30050 target_ulong *data)
d2856f1a 30051{
bad729e2 30052 env->active_tc.PC = data[0];
d2856f1a 30053 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 30054 env->hflags |= data[1];
4636401d
AJ
30055 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30056 case MIPS_HFLAG_BR:
30057 break;
30058 case MIPS_HFLAG_BC:
30059 case MIPS_HFLAG_BL:
30060 case MIPS_HFLAG_B:
bad729e2 30061 env->btarget = data[2];
4636401d
AJ
30062 break;
30063 }
d2856f1a 30064}