]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: Improve DSP R2/R3-related naming
[mirror_qemu.git] / target / mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
c684822a 24#include "qemu/osdep.h"
6af0bf9c 25#include "cpu.h"
26aa3d9a 26#include "internal.h"
76cad711 27#include "disas/disas.h"
63c91552 28#include "exec/exec-all.h"
57fec1fe 29#include "tcg-op.h"
f08b6170 30#include "exec/cpu_ldst.h"
d3d93c6c 31#include "hw/mips/cpudevs.h"
6af0bf9c 32
2ef6175a
RH
33#include "exec/helper-proto.h"
34#include "exec/helper-gen.h"
3b3c1694 35#include "exec/semihost.h"
a7812ae4 36
b44a7fb1 37#include "target/mips/trace.h"
a7e30d84 38#include "trace-tcg.h"
b28425ba 39#include "exec/translator.h"
508127e2 40#include "exec/log.h"
a7e30d84 41
fb7729e2 42#define MIPS_DEBUG_DISAS 0
6af0bf9c 43
7a387fff
TS
44/* MIPS major opcodes */
45#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
46
47enum {
48 /* indirect opcode tables */
7a387fff
TS
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 57 /* arithmetic with immediate */
7a387fff
TS
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
324d9e32 62 /* logic with immediate */
7a387fff
TS
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
324d9e32 67 /* arithmetic with immediate */
7a387fff
TS
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
e37e863f 70 /* Jump and branches */
7a387fff
TS
71 OPC_J = (0x02 << 26),
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
b231c103 81 OPC_JALX = (0x1D << 26),
d4ea6acd 82 OPC_DAUI = (0x1D << 26),
e37e863f 83 /* Load and stores */
7a387fff
TS
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
364d4831 90 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
364d4831 105 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
e37e863f 109 /* Floating point load/store */
7a387fff
TS
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
31837be3
YK
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
7a387fff
TS
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
239dfebe
YK
145 /* MSA ASE, same as MDMX */
146 OPC_MSA = OPC_MDMX,
e37e863f 147 /* Cache and prefetch */
7a387fff
TS
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
152};
153
154/* PC-relative address computation / loads */
155#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157enum {
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
162
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
166
167 /* Other */
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
169};
170
171/* MIPS special opcodes */
7a387fff
TS
172#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173
e37e863f
FB
174enum {
175 /* Shifts */
7a387fff 176 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 181 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 185 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 193 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 199 /* Multiplication / division */
7a387fff
TS
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 208
e37e863f 209 /* 2 registers arithmetic / logic */
7a387fff
TS
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 224 /* Jumps */
7a387fff
TS
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 227 /* Traps */
7a387fff
TS
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 234 /* HI / LO registers load & stores */
7a387fff
TS
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 239 /* Conditional moves */
7a387fff
TS
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 242
b691d9d2
LA
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
245
7a387fff 246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
247
248 /* Special */
a0d700e4 249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
254
7a387fff
TS
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259};
260
b42ee5e1
LA
261/* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265enum {
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
274
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
283
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
289
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
292};
293
e9c71dd1
TS
294/* Multiplication variants of the vr54xx. */
295#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297enum {
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312};
313
7a387fff
TS
314/* REGIMM (rt field) opcodes */
315#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317enum {
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
334
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
337};
338
7a387fff
TS
339/* Special2 opcodes */
340#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
341
e37e863f 342enum {
7a387fff
TS
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
349 /* Loongson 2F */
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 362 /* Misc */
7a387fff
TS
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 367 /* Special */
7a387fff
TS
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
369};
370
371/* Special3 opcodes */
372#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
373
374enum {
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
388
389 /* Loongson 2E */
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
402
403 /* MIPS DSP Load */
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 425 /* MIPS DSP Append Sub-class */
26690560 426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 431
76964147
JH
432 /* EVA */
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
449
4368b29a 450 /* R6 */
bf7910c6
LA
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
457};
458
7a387fff
TS
459/* BSHFL opcodes */
460#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
e37e863f 462enum {
15eacb9b
YK
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
467 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
469};
470
7a387fff
TS
471/* DBSHFL opcodes */
472#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
473
e37e863f 474enum {
15eacb9b
YK
475 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
476 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
477 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
480};
481
e45a93e2
JL
482/* MIPS DSP REGIMM opcodes */
483enum {
484 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 485 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
486};
487
9b1a1d68
JL
488#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489/* MIPS DSP Load */
490enum {
491 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
493 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 494 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
495};
496
461c08df
JL
497#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498enum {
499 /* MIPS DSP Arithmetic Sub-class */
500 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
505 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
506 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
512 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
513 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
516 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
517 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
523 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
524 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
525};
526
527#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
543 /* MIPS DSP Multiply Sub-class insns */
544 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
548};
549
550#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
566 /* DSP Bit/Manipulation Sub-class */
567 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
572};
573
574#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
584 /* DSP Compare-Pick Sub-class */
585 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 600};
a22260ae 601
77c5fa8b
JL
602#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603enum {
604 /* MIPS DSP GPR-Based Shift Sub-class */
605 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
627};
461c08df 628
a22260ae
JL
629#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630enum {
631 /* MIPS DSP Multiply Sub-class insns */
632 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
654};
655
1cb6686c
JL
656#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657enum {
658 /* DSP Bit/Manipulation Sub-class */
659 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
660};
661
26690560
JL
662#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663enum {
df6126a7 664 /* MIPS DSP Append Sub-class */
26690560
JL
665 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
666 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
668};
669
b53371ed
JL
670#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
672 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
685 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
686 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
687 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
688 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
689 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
690};
691
461c08df
JL
692#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
693enum {
694 /* MIPS DSP Arithmetic Sub-class */
695 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
712 /* DSP Bit/Manipulation Sub-class */
713 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 719};
461c08df 720
461c08df
JL
721#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722enum {
a22260ae
JL
723 /* MIPS DSP Multiply Sub-class insns */
724 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
729 /* MIPS DSP Arithmetic Sub-class */
730 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
751};
461c08df 752
461c08df
JL
753#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754enum {
26690560
JL
755 /* DSP Compare-Pick Sub-class */
756 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
775 /* MIPS DSP Arithmetic Sub-class */
776 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
784};
461c08df 785
26690560
JL
786#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787enum {
df6126a7 788 /* DSP Append Sub-class */
26690560
JL
789 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
790 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
793};
26690560 794
b53371ed
JL
795#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796enum {
797 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
799 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
819};
820
1cb6686c
JL
821#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
822enum {
823 /* DSP Bit/Manipulation Sub-class */
824 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
825};
1cb6686c 826
a22260ae
JL
827#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828enum {
829 /* MIPS DSP Multiply Sub-class insns */
830 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
856};
a22260ae 857
77c5fa8b
JL
858#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
859enum {
860 /* MIPS DSP GPR-Based Shift Sub-class */
861 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
887};
77c5fa8b 888
7a387fff
TS
889/* Coprocessor 0 (rs field) */
890#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
891
6ea83fed 892enum {
7a387fff
TS
893 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
894 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 895 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
896 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
897 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 898 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 899 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
900 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
901 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 902 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
903 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
904 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
905 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
906 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
907 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
908 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
909 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
910 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
911 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
912 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
913 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
914 OPC_C0_A = (0x1A << 21) | OPC_CP0,
915 OPC_C0_B = (0x1B << 21) | OPC_CP0,
916 OPC_C0_C = (0x1C << 21) | OPC_CP0,
917 OPC_C0_D = (0x1D << 21) | OPC_CP0,
918 OPC_C0_E = (0x1E << 21) | OPC_CP0,
919 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 920};
7a387fff
TS
921
922/* MFMC0 opcodes */
b48cfdff 923#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
924
925enum {
ead9360e
TS
926 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
929 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
930 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
932 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
934};
935
936/* Coprocessor 0 (with rs == C0) */
937#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
938
939enum {
940 OPC_TLBR = 0x01 | OPC_C0,
941 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
942 OPC_TLBINV = 0x03 | OPC_C0,
943 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
944 OPC_TLBWR = 0x06 | OPC_C0,
945 OPC_TLBP = 0x08 | OPC_C0,
946 OPC_RFE = 0x10 | OPC_C0,
947 OPC_ERET = 0x18 | OPC_C0,
948 OPC_DERET = 0x1F | OPC_C0,
949 OPC_WAIT = 0x20 | OPC_C0,
950};
951
952/* Coprocessor 1 (rs field) */
953#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
bf4120ad
NF
955/* Values for the fmt field in FP instructions */
956enum {
957 /* 0 - 15 are reserved */
e459440a
AJ
958 FMT_S = 16, /* single fp */
959 FMT_D = 17, /* double fp */
960 FMT_E = 18, /* extended fp */
961 FMT_Q = 19, /* quad fp */
962 FMT_W = 20, /* 32-bit fixed */
963 FMT_L = 21, /* 64-bit fixed */
964 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
965 /* 23 - 31 are reserved */
966};
967
7a387fff
TS
968enum {
969 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
970 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
971 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 972 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
973 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
974 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
975 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 976 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 977 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
978 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
979 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
980 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
981 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
982 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
983 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
984 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
985 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
986 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
987 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
988 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
989 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
990 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
991 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
992 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
993 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
994 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
995 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
996 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
997 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
998 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
999};
1000
5a5012ec
TS
1001#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1002#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1003
7a387fff
TS
1004enum {
1005 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1006 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1007 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1008 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1009};
1010
5a5012ec
TS
1011enum {
1012 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1013 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1014};
1015
1016enum {
1017 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1018 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1019};
7a387fff
TS
1020
1021#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1022
1023enum {
1024 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1025 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1026 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1027 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1028 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1029 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1030 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1031 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1032 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1033 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1034 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1035};
1036
bd277fa1
RH
1037#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039enum {
1040 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1041 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1043 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1044 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1045 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1047 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1048
1049 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1050 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1052 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1053 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1054 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1056 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1057
1058 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1059 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1063 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1064 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1065 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1066
1067 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1072 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1073 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1074 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1075
1076 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1077 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1078 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1079 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1080 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1081 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1082
1083 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1091 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1092 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1093 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1094 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1095 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1098 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1099 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1100 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1101 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1106 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1107 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1113 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1114 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1119 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1121 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1122 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1126 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1128 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1130 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131};
1132
1133
e0c84da7
TS
1134#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136enum {
1137 OPC_LWXC1 = 0x00 | OPC_CP3,
1138 OPC_LDXC1 = 0x01 | OPC_CP3,
1139 OPC_LUXC1 = 0x05 | OPC_CP3,
1140 OPC_SWXC1 = 0x08 | OPC_CP3,
1141 OPC_SDXC1 = 0x09 | OPC_CP3,
1142 OPC_SUXC1 = 0x0D | OPC_CP3,
1143 OPC_PREFX = 0x0F | OPC_CP3,
1144 OPC_ALNV_PS = 0x1E | OPC_CP3,
1145 OPC_MADD_S = 0x20 | OPC_CP3,
1146 OPC_MADD_D = 0x21 | OPC_CP3,
1147 OPC_MADD_PS = 0x26 | OPC_CP3,
1148 OPC_MSUB_S = 0x28 | OPC_CP3,
1149 OPC_MSUB_D = 0x29 | OPC_CP3,
1150 OPC_MSUB_PS = 0x2E | OPC_CP3,
1151 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1152 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1153 OPC_NMADD_PS= 0x36 | OPC_CP3,
1154 OPC_NMSUB_S = 0x38 | OPC_CP3,
1155 OPC_NMSUB_D = 0x39 | OPC_CP3,
1156 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157};
1158
239dfebe
YK
1159/* MSA Opcodes */
1160#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1161enum {
1162 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1163 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1164 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1165 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1166 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1167 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1168 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1169 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1170 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1171 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1172 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1173 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1174 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1175 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1176 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1177 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1178 OPC_MSA_ELM = 0x19 | OPC_MSA,
1179 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1180 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1181 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1182 OPC_MSA_VEC = 0x1E | OPC_MSA,
1183
1184 /* MI10 instruction */
1185 OPC_LD_B = (0x20) | OPC_MSA,
1186 OPC_LD_H = (0x21) | OPC_MSA,
1187 OPC_LD_W = (0x22) | OPC_MSA,
1188 OPC_LD_D = (0x23) | OPC_MSA,
1189 OPC_ST_B = (0x24) | OPC_MSA,
1190 OPC_ST_H = (0x25) | OPC_MSA,
1191 OPC_ST_W = (0x26) | OPC_MSA,
1192 OPC_ST_D = (0x27) | OPC_MSA,
1193};
1194
1195enum {
1196 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1198 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1199 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1200 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1201 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1202 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1203 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1204 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1205 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1206 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1207 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1208 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210 /* I8 instruction */
1211 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1212 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1214 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1215 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1216 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1217 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1218 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1220 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222 /* VEC/2R/2RF instruction */
1223 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1224 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1225 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1226 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1227 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1228 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1229 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1230
1231 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1232 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1233
1234 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240 /* 2RF instruction df(bit 16) = _w, _d */
1241 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1242 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1245 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1246 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1247 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1248 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1249 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1250 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1251 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1252 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1253 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1254 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1255 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1256 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1257
1258 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1260 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1261 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1262 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1263 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1264 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1265 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1266 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1267 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1268 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1269 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1270 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1272 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1274 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1275 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1276 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1278 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1279 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1282 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1283 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1284 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1285 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1292 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1293 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1294 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1295 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1296 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1297 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1298 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1299 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1300 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1301 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1310 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1311 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1312 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1313 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1314 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1315 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1316 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1317 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1318 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1319 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1320 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1321 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334 /* 3RF instruction _df(bit 21) = _w, _d */
1335 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1336 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1337 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1338 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1339 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1340 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1342 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1343 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1346 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1348 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1351 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1353 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1357 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1358 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1361 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1362 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1363 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1364 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1365 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1366 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1367 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1369 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1370 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1372 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1373 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1379 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1380 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1381 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1382 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1383 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1384 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1385 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1386 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1387 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1388 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1389 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1390};
1391
b158d449
AM
1392
1393/*
1394 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1395 * ============================================
1396 *
1397 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1398 * instructions set. It is designed to fit the needs of signal, graphical and
1399 * video processing applications. MXU instruction set is used in Xburst family
1400 * of microprocessors by Ingenic.
1401 *
1402 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1403 * the control register.
1404 *
1d0e663c
AM
1405 * The notation used in MXU assembler mnemonics:
1406 *
1407 * XRa, XRb, XRc, XRd - MXU registers
1408 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1409 * s12 - a subfield of an instruction code
1410 * strd2 - a subfield of an instruction code
1411 * eptn2 - a subfield of an instruction code
1412 * eptn3 - a subfield of an instruction code
1413 * optn2 - a subfield of an instruction code
1414 * optn3 - a subfield of an instruction code
1415 * sft4 - a subfield of an instruction code
1416 *
1417 * Load/Store instructions Multiplication instructions
1418 * ----------------------- ---------------------------
1419 *
1420 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1421 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1422 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1423 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1424 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1425 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1426 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1427 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1428 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1429 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1430 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1431 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1432 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1433 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1434 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1435 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1436 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1437 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1438 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1439 * S16SDI XRa, Rb, s10, eptn2
1440 * S8LDD XRa, Rb, s8, eptn3
1441 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1442 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1443 * S8SDI XRa, Rb, s8, eptn3
1444 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1445 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1446 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1447 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1448 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1449 * S32CPS XRa, XRb, XRc
1450 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1451 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1452 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1453 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1454 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1455 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1456 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1457 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1458 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1459 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1460 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1461 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1462 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1463 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1464 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1465 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1466 * Q8SLT XRa, XRb, XRc
1467 * Q8SLTU XRa, XRb, XRc
1468 * Q8MOVZ XRa, XRb, XRc Shift instructions
1469 * Q8MOVN XRa, XRb, XRc ------------------
1470 *
1471 * D32SLL XRa, XRb, XRc, XRd, sft4
1472 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1473 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1474 * D32SARL XRa, XRb, XRc, sft4
1475 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1476 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1477 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1478 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1479 * Q16SLL XRa, XRb, XRc, XRd, sft4
1480 * Q16SLR XRa, XRb, XRc, XRd, sft4
1481 * Miscelaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1482 * ------------------------- Q16SLLV XRa, XRb, Rb
1483 * Q16SLRV XRa, XRb, Rb
1484 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1485 * S32ALN XRa, XRb, XRc, Rb
1486 * S32ALNI XRa, XRb, XRc, s3
1487 * S32LUI XRa, s8, optn3 Move instructions
1488 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1489 * S32EXTRV XRa, XRb, Rs, Rt
1490 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1491 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1492 *
9ef5bff9
AM
1493 *
1494 * bits
1495 * 05..00
1496 *
1497 * ┌─ 000000 ─ OPC_MXU_S32MADD
1498 * ├─ 000001 ─ OPC_MXU_S32MADDU
1499 * ├─ 000010 ─ <not assigned>
1500 * │ 20..18
1501 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1502 * │ ├─ 001 ─ OPC_MXU_S32MIN
1503 * │ ├─ 010 ─ OPC_MXU_D16MAX
1504 * │ ├─ 011 ─ OPC_MXU_D16MIN
1505 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1506 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1507 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1508 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1509 * ├─ 000100 ─ OPC_MXU_S32MSUB
1510 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1511 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1512 * │ ├─ 001 ─ OPC_MXU_D16SLT
1513 * │ ├─ 010 ─ OPC_MXU_D16AVG
1514 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1515 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1516 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1517 * │ └─ 111 ─ OPC_MXU_Q8ADD
1518 * │
1519 * │ 20..18
1520 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1521 * │ ├─ 010 ─ OPC_MXU_D16CPS
1522 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1523 * │ └─ 110 ─ OPC_MXU_Q16SAT
1524 * ├─ 001000 ─ OPC_MXU_D16MUL
1525 * │ 25..24
1526 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1527 * │ └─ 01 ─ OPC_MXU_D16MULE
1528 * ├─ 001010 ─ OPC_MXU_D16MAC
1529 * ├─ 001011 ─ OPC_MXU_D16MACF
1530 * ├─ 001100 ─ OPC_MXU_D16MADL
1531 * │ 25..24
1532 * ├─ 001101 ─ OPC_MXU__POOL04 ─┬─ 00 ─ OPC_MXU_S16MAD
1533 * │ └─ 01 ─ OPC_MXU_S16MAD_1
1534 * ├─ 001110 ─ OPC_MXU_Q16ADD
1535 * ├─ 001111 ─ OPC_MXU_D16MACE
1536 * │ 23
1537 * ├─ 010000 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32LDD
1538 * │ └─ 1 ─ OPC_MXU_S32LDDR
1539 * │
1540 * │ 23
1541 * ├─ 010001 ─ OPC_MXU__POOL06 ─┬─ 0 ─ OPC_MXU_S32STD
1542 * │ └─ 1 ─ OPC_MXU_S32STDR
1543 * │
1544 * │ 13..10
1545 * ├─ 010010 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1546 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1547 * │
1548 * │ 13..10
1549 * ├─ 010011 ─ OPC_MXU__POOL08 ─┬─ 0000 ─ OPC_MXU_S32STDV
1550 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1551 * │
1552 * │ 23
1553 * ├─ 010100 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32LDI
1554 * │ └─ 1 ─ OPC_MXU_S32LDIR
1555 * │
1556 * │ 23
1557 * ├─ 010101 ─ OPC_MXU__POOL10 ─┬─ 0 ─ OPC_MXU_S32SDI
1558 * │ └─ 1 ─ OPC_MXU_S32SDIR
1559 * │
1560 * │ 13..10
1561 * ├─ 010110 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1562 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1563 * │
1564 * │ 13..10
1565 * ├─ 010111 ─ OPC_MXU__POOL12 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1566 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1567 * ├─ 011000 ─ OPC_MXU_D32ADD
1568 * │ 23..22
1569 * MXU ├─ 011001 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_D32ACC
1570 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1571 * │ └─ 10 ─ OPC_MXU_D32ASUM
1572 * ├─ 011010 ─ <not assigned>
1573 * │ 23..22
1574 * ├─ 011011 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q16ACC
1575 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1576 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1577 * │
1578 * │ 23..22
1579 * ├─ 011100 ─ OPC_MXU__POOL15 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1580 * │ ├─ 01 ─ OPC_MXU_D8SUM
1581 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1582 * ├─ 011110 ─ <not assigned>
1583 * ├─ 011111 ─ <not assigned>
1584 * ├─ 100000 ─ <not assigned>
1585 * ├─ 100001 ─ <not assigned>
1586 * ├─ 100010 ─ OPC_MXU_S8LDD
1587 * ├─ 100011 ─ OPC_MXU_S8STD
1588 * ├─ 100100 ─ OPC_MXU_S8LDI
1589 * ├─ 100101 ─ OPC_MXU_S8SDI
1590 * │ 15..14
1591 * ├─ 100110 ─ OPC_MXU__POOL16 ─┬─ 00 ─ OPC_MXU_S32MUL
1592 * │ ├─ 00 ─ OPC_MXU_S32MULU
1593 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1594 * │ └─ 00 ─ OPC_MXU_S32EXTRV
1595 * │
1596 * │ 20..18
1597 * ├─ 100111 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_D32SARW
1598 * │ ├─ 001 ─ OPC_MXU_S32ALN
1599 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1600 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1601 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1602 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1603 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1604 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1605 * ├─ 101000 ─ <not assigned>
1606 * ├─ 101001 ─ <not assigned>
1607 * ├─ 101010 ─ <not assigned>
1608 * ├─ 101011 ─ <not assigned>
1609 * ├─ 101100 ─ <not assigned>
1610 * ├─ 101101 ─ <not assigned>
1611 * ├─ 101110 ─ OPC_MXU_S32M2I
1612 * ├─ 101111 ─ OPC_MXU_S32I2M
1613 * ├─ 110000 ─ OPC_MXU_D32SLL
1614 * ├─ 110001 ─ OPC_MXU_D32SLR
1615 * ├─ 110010 ─ OPC_MXU_D32SARL
1616 * ├─ 110011 ─ OPC_MXU_D32SAR
1617 * ├─ 110100 ─ OPC_MXU_Q16SLL
1618 * ├─ 110101 ─ OPC_MXU_Q16SLR 20..18
1619 * ├─ 110110 ─ OPC_MXU__POOL18 ─┬─ 000 ─ OPC_MXU_D32SLLV
1620 * │ ├─ 001 ─ OPC_MXU_D32SLRV
1621 * │ ├─ 010 ─ OPC_MXU_D32SARV
1622 * │ ├─ 011 ─ OPC_MXU_Q16SLLV
1623 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1624 * │ └─ 101 ─ OPC_MXU_Q16SARV
1625 * ├─ 110111 ─ OPC_MXU_Q16SAR
1626 * │ 23..22
1627 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1628 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1629 * │
1630 * │ 20..18
1631 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1632 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1633 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1634 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1635 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1636 * │ └─ 101 ─ OPC_MXU_S32MOV
1637 * │
1638 * │ 23..22
1639 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1640 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1641 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1642 * ├─ 111100 ─ OPC_MXU_Q8MADL
1643 * ├─ 111101 ─ OPC_MXU_S32SFL
1644 * ├─ 111110 ─ OPC_MXU_Q8SAD
1645 * └─ 111111 ─ <not assigned>
1646 *
1647 *
b158d449
AM
1648 * Compiled after:
1649 *
1650 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1651 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1652 */
1653
8bacd1ff
AM
1654enum {
1655 OPC_MXU_S32MADD = 0x00,
1656 OPC_MXU_S32MADDU = 0x01,
1657 /* not assigned 0x02 */
1658 OPC_MXU__POOL00 = 0x03,
1659 OPC_MXU_S32MSUB = 0x04,
1660 OPC_MXU_S32MSUBU = 0x05,
1661 OPC_MXU__POOL01 = 0x06,
1662 OPC_MXU__POOL02 = 0x07,
1663 OPC_MXU_D16MUL = 0x08,
1664 OPC_MXU__POOL03 = 0x09,
1665 OPC_MXU_D16MAC = 0x0A,
1666 OPC_MXU_D16MACF = 0x0B,
1667 OPC_MXU_D16MADL = 0x0C,
1668 OPC_MXU__POOL04 = 0x0D,
1669 OPC_MXU_Q16ADD = 0x0E,
1670 OPC_MXU_D16MACE = 0x0F,
1671 OPC_MXU__POOL05 = 0x10,
1672 OPC_MXU__POOL06 = 0x11,
1673 OPC_MXU__POOL07 = 0x12,
1674 OPC_MXU__POOL08 = 0x13,
1675 OPC_MXU__POOL09 = 0x14,
1676 OPC_MXU__POOL10 = 0x15,
1677 OPC_MXU__POOL11 = 0x16,
1678 OPC_MXU__POOL12 = 0x17,
1679 OPC_MXU_D32ADD = 0x18,
1680 OPC_MXU__POOL13 = 0x19,
1681 /* not assigned 0x1A */
1682 OPC_MXU__POOL14 = 0x1B,
1683 OPC_MXU__POOL15 = 0x1C,
1684 OPC_MXU_Q8ACCE = 0x1D,
1685 /* not assigned 0x1E */
1686 /* not assigned 0x1F */
1687 /* not assigned 0x20 */
1688 /* not assigned 0x21 */
1689 OPC_MXU_S8LDD = 0x22,
1690 OPC_MXU_S8STD = 0x23,
1691 OPC_MXU_S8LDI = 0x24,
1692 OPC_MXU_S8SDI = 0x25,
1693 OPC_MXU__POOL16 = 0x26,
1694 OPC_MXU__POOL17 = 0x27,
1695 OPC_MXU_LXB = 0x28,
1696 /* not assigned 0x29 */
1697 OPC_MXU_S16LDD = 0x2A,
1698 OPC_MXU_S16STD = 0x2B,
1699 OPC_MXU_S16LDI = 0x2C,
1700 OPC_MXU_S16SDI = 0x2D,
1701 OPC_MXU_S32M2I = 0x2E,
1702 OPC_MXU_S32I2M = 0x2F,
1703 OPC_MXU_D32SLL = 0x30,
1704 OPC_MXU_D32SLR = 0x31,
1705 OPC_MXU_D32SARL = 0x32,
1706 OPC_MXU_D32SAR = 0x33,
1707 OPC_MXU_Q16SLL = 0x34,
1708 OPC_MXU_Q16SLR = 0x35,
1709 OPC_MXU__POOL18 = 0x36,
1710 OPC_MXU_Q16SAR = 0x37,
1711 OPC_MXU__POOL19 = 0x38,
1712 OPC_MXU__POOL20 = 0x39,
1713 OPC_MXU__POOL21 = 0x3A,
1714 OPC_MXU_Q16SCOP = 0x3B,
1715 OPC_MXU_Q8MADL = 0x3C,
1716 OPC_MXU_S32SFL = 0x3D,
1717 OPC_MXU_Q8SAD = 0x3E,
1718 /* not assigned 0x3F */
1719};
1720
1721
1722/*
1723 * MXU pool 00
1724 */
1725enum {
1726 OPC_MXU_S32MAX = 0x00,
1727 OPC_MXU_S32MIN = 0x01,
1728 OPC_MXU_D16MAX = 0x02,
1729 OPC_MXU_D16MIN = 0x03,
1730 OPC_MXU_Q8MAX = 0x04,
1731 OPC_MXU_Q8MIN = 0x05,
1732 OPC_MXU_Q8SLT = 0x06,
1733 OPC_MXU_Q8SLTU = 0x07,
1734};
1735
1736/*
1737 * MXU pool 01
1738 */
1739enum {
1740 OPC_MXU_S32SLT = 0x00,
1741 OPC_MXU_D16SLT = 0x01,
1742 OPC_MXU_D16AVG = 0x02,
1743 OPC_MXU_D16AVGR = 0x03,
1744 OPC_MXU_Q8AVG = 0x04,
1745 OPC_MXU_Q8AVGR = 0x05,
1746 OPC_MXU_Q8ADD = 0x07,
1747};
1748
1749/*
1750 * MXU pool 02
1751 */
1752enum {
1753 OPC_MXU_S32CPS = 0x00,
1754 OPC_MXU_D16CPS = 0x02,
1755 OPC_MXU_Q8ABD = 0x04,
1756 OPC_MXU_Q16SAT = 0x06,
1757};
1758
1759/*
1760 * MXU pool 03
1761 */
1762enum {
1763 OPC_MXU_D16MULF = 0x00,
1764 OPC_MXU_D16MULE = 0x01,
1765};
1766
1767/*
1768 * MXU pool 04
1769 */
1770enum {
1771 OPC_MXU_S16MAD = 0x00,
1772 OPC_MXU_S16MAD_1 = 0x01,
1773};
1774
1775/*
1776 * MXU pool 05
1777 */
1778enum {
1779 OPC_MXU_S32LDD = 0x00,
1780 OPC_MXU_S32LDDR = 0x01,
1781};
1782
1783/*
1784 * MXU pool 06
1785 */
1786enum {
1787 OPC_MXU_S32STD = 0x00,
1788 OPC_MXU_S32STDR = 0x01,
1789};
1790
1791/*
1792 * MXU pool 07
1793 */
1794enum {
1795 OPC_MXU_S32LDDV = 0x00,
1796 OPC_MXU_S32LDDVR = 0x01,
1797};
1798
1799/*
1800 * MXU pool 08
1801 */
1802enum {
1803 OPC_MXU_S32STDV = 0x00,
1804 OPC_MXU_S32STDVR = 0x01,
1805};
1806
1807/*
1808 * MXU pool 09
1809 */
1810enum {
1811 OPC_MXU_S32LDI = 0x00,
1812 OPC_MXU_S32LDIR = 0x01,
1813};
1814
1815/*
1816 * MXU pool 10
1817 */
1818enum {
1819 OPC_MXU_S32SDI = 0x00,
1820 OPC_MXU_S32SDIR = 0x01,
1821};
1822
1823/*
1824 * MXU pool 11
1825 */
1826enum {
1827 OPC_MXU_S32LDIV = 0x00,
1828 OPC_MXU_S32LDIVR = 0x01,
1829};
1830
1831/*
1832 * MXU pool 12
1833 */
1834enum {
1835 OPC_MXU_S32SDIV = 0x00,
1836 OPC_MXU_S32SDIVR = 0x01,
1837};
1838
1839/*
1840 * MXU pool 13
1841 */
1842enum {
1843 OPC_MXU_D32ACC = 0x00,
1844 OPC_MXU_D32ACCM = 0x01,
1845 OPC_MXU_D32ASUM = 0x02,
1846};
1847
1848/*
1849 * MXU pool 14
1850 */
1851enum {
1852 OPC_MXU_Q16ACC = 0x00,
1853 OPC_MXU_Q16ACCM = 0x01,
1854 OPC_MXU_Q16ASUM = 0x02,
1855};
1856
1857/*
1858 * MXU pool 15
1859 */
1860enum {
1861 OPC_MXU_Q8ADDE = 0x00,
1862 OPC_MXU_D8SUM = 0x01,
1863 OPC_MXU_D8SUMC = 0x02,
1864};
1865
1866/*
1867 * MXU pool 16
1868 */
1869enum {
1870 OPC_MXU_S32MUL = 0x00,
1871 OPC_MXU_S32MULU = 0x01,
1872 OPC_MXU_S32EXTR = 0x02,
1873 OPC_MXU_S32EXTRV = 0x03,
1874};
1875
1876/*
1877 * MXU pool 17
1878 */
1879enum {
1880 OPC_MXU_D32SARW = 0x00,
1881 OPC_MXU_S32ALN = 0x01,
1882 OPC_MXU_S32ALNI = 0x02,
1883 OPC_MXU_S32NOR = 0x03,
1884 OPC_MXU_S32AND = 0x04,
1885 OPC_MXU_S32OR = 0x05,
1886 OPC_MXU_S32XOR = 0x06,
1887 OPC_MXU_S32LUI = 0x07,
1888};
1889
1890/*
1891 * MXU pool 18
1892 */
1893enum {
1894 OPC_MXU_D32SLLV = 0x00,
1895 OPC_MXU_D32SLRV = 0x01,
1896 OPC_MXU_D32SARV = 0x03,
1897 OPC_MXU_Q16SLLV = 0x04,
1898 OPC_MXU_Q16SLRV = 0x05,
1899 OPC_MXU_Q16SARV = 0x07,
1900};
1901
1902/*
1903 * MXU pool 19
1904 */
1905enum {
1906 OPC_MXU_Q8MUL = 0x00,
1907 OPC_MXU_Q8MULSU = 0x01,
1908};
1909
1910/*
1911 * MXU pool 20
1912 */
1913enum {
1914 OPC_MXU_Q8MOVZ = 0x00,
1915 OPC_MXU_Q8MOVN = 0x01,
1916 OPC_MXU_D16MOVZ = 0x02,
1917 OPC_MXU_D16MOVN = 0x03,
1918 OPC_MXU_S32MOVZ = 0x04,
1919 OPC_MXU_S32MOVN = 0x05,
1920};
1921
1922/*
1923 * MXU pool 21
1924 */
1925enum {
1926 OPC_MXU_Q8MAC = 0x00,
1927 OPC_MXU_Q8MACSU = 0x01,
1928};
1929
b158d449 1930
39454628 1931/* global register indices */
a7812ae4 1932static TCGv cpu_gpr[32], cpu_PC;
340fff72 1933static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1934static TCGv cpu_dspctrl, btarget, bcond;
1935static TCGv_i32 hflags;
a7812ae4 1936static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1937static TCGv_i64 fpu_f64[32];
863f264d 1938static TCGv_i64 msa_wr_d[64];
aa0bf00b 1939
022c62cb 1940#include "exec/gen-icount.h"
2e70f6ef 1941
895c2d04 1942#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1943 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1944 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1945 tcg_temp_free_i32(helper_tmp); \
1946 } while(0)
be24bb4f 1947
895c2d04 1948#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1949 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1950 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1951 tcg_temp_free_i32(helper_tmp); \
1952 } while(0)
be24bb4f 1953
895c2d04
BS
1954#define gen_helper_1e0i(name, ret, arg1) do { \
1955 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1956 gen_helper_##name(ret, cpu_env, helper_tmp); \
1957 tcg_temp_free_i32(helper_tmp); \
1958 } while(0)
1959
1960#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1961 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1962 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1963 tcg_temp_free_i32(helper_tmp); \
1964 } while(0)
1965
1966#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1967 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1968 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1969 tcg_temp_free_i32(helper_tmp); \
1970 } while(0)
1971
1972#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1973 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1974 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1975 tcg_temp_free_i32(helper_tmp); \
1976 } while(0)
be24bb4f 1977
895c2d04 1978#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1979 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1980 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1981 tcg_temp_free_i32(helper_tmp); \
1982 } while(0)
c239529e 1983
8e9ade68 1984typedef struct DisasContext {
eeb3bba8
EC
1985 DisasContextBase base;
1986 target_ulong saved_pc;
18f440ed 1987 target_ulong page_start;
8e9ade68 1988 uint32_t opcode;
f9c9cd63 1989 uint64_t insn_flags;
5ab5c041 1990 int32_t CP0_Config1;
ab77fc61
DN
1991 int32_t CP0_Config3;
1992 int32_t CP0_Config5;
8e9ade68
TS
1993 /* Routine used to access memory */
1994 int mem_idx;
be3a8c53 1995 TCGMemOp default_tcg_memop_mask;
8e9ade68 1996 uint32_t hflags, saved_hflags;
8e9ade68 1997 target_ulong btarget;
d279279e 1998 bool ulri;
e98c0d17 1999 int kscrexist;
7207c7f9 2000 bool rxi;
9456c2fb 2001 int ie;
aea14095
LA
2002 bool bi;
2003 bool bp;
5204ea79
LA
2004 uint64_t PAMask;
2005 bool mvh;
76964147 2006 bool eva;
cec56a73 2007 bool sc;
5204ea79 2008 int CP0_LLAddr_shift;
e29c9628 2009 bool ps;
01bc435b 2010 bool vp;
c870e3f5 2011 bool cmgcr;
f6d4dd81 2012 bool mrp;
87552089 2013 bool nan2008;
6be77480 2014 bool abs2008;
8e9ade68
TS
2015} DisasContext;
2016
b28425ba
EC
2017#define DISAS_STOP DISAS_TARGET_0
2018#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2019
d73ee8a2
RH
2020static const char * const regnames[] = {
2021 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2022 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2023 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2024 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2025};
6af0bf9c 2026
d73ee8a2
RH
2027static const char * const regnames_HI[] = {
2028 "HI0", "HI1", "HI2", "HI3",
2029};
4b2eb8d2 2030
d73ee8a2
RH
2031static const char * const regnames_LO[] = {
2032 "LO0", "LO1", "LO2", "LO3",
2033};
4b2eb8d2 2034
d73ee8a2
RH
2035static const char * const fregnames[] = {
2036 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2037 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2038 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2039 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2040};
958fb4a9 2041
863f264d
YK
2042static const char * const msaregnames[] = {
2043 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2044 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2045 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2046 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2047 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2048 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2049 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2050 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2051 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2052 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2053 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2054 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2055 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2056 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2057 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2058 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2059};
2060
9d68ac14 2061#define LOG_DISAS(...) \
fb7729e2
RH
2062 do { \
2063 if (MIPS_DEBUG_DISAS) { \
9d68ac14 2064 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
2065 } \
2066 } while (0)
2067
9d68ac14 2068#define MIPS_INVAL(op) \
fb7729e2
RH
2069 do { \
2070 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
2071 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2072 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
2073 ctx->base.pc_next, ctx->opcode, op, \
2074 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2075 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
2076 } \
2077 } while (0)
958fb4a9 2078
8e9ade68
TS
2079/* General purpose registers moves. */
2080static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 2081{
8e9ade68
TS
2082 if (reg == 0)
2083 tcg_gen_movi_tl(t, 0);
2084 else
4b2eb8d2 2085 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
2086}
2087
8e9ade68 2088static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 2089{
8e9ade68 2090 if (reg != 0)
4b2eb8d2 2091 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
2092}
2093
8e9ade68 2094/* Moves to/from shadow registers. */
be24bb4f 2095static inline void gen_load_srsgpr (int from, int to)
aaa9128a 2096{
d9bea114 2097 TCGv t0 = tcg_temp_new();
be24bb4f
TS
2098
2099 if (from == 0)
d9bea114 2100 tcg_gen_movi_tl(t0, 0);
8e9ade68 2101 else {
d9bea114 2102 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2103 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2104
7db13fae 2105 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2106 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2107 tcg_gen_andi_i32(t2, t2, 0xf);
2108 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2109 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2110 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2111
d9bea114 2112 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2113 tcg_temp_free_ptr(addr);
d9bea114 2114 tcg_temp_free_i32(t2);
8e9ade68 2115 }
d9bea114
AJ
2116 gen_store_gpr(t0, to);
2117 tcg_temp_free(t0);
aaa9128a
TS
2118}
2119
be24bb4f 2120static inline void gen_store_srsgpr (int from, int to)
aaa9128a 2121{
be24bb4f 2122 if (to != 0) {
d9bea114
AJ
2123 TCGv t0 = tcg_temp_new();
2124 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2125 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2126
d9bea114 2127 gen_load_gpr(t0, from);
7db13fae 2128 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2129 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2130 tcg_gen_andi_i32(t2, t2, 0xf);
2131 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2132 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2133 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2134
d9bea114 2135 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2136 tcg_temp_free_ptr(addr);
d9bea114
AJ
2137 tcg_temp_free_i32(t2);
2138 tcg_temp_free(t0);
8e9ade68 2139 }
aaa9128a
TS
2140}
2141
eab9944c
LA
2142/* Tests */
2143static inline void gen_save_pc(target_ulong pc)
2144{
2145 tcg_gen_movi_tl(cpu_PC, pc);
2146}
2147
2148static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2149{
2150 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2151 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2152 gen_save_pc(ctx->base.pc_next);
2153 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2154 }
2155 if (ctx->hflags != ctx->saved_hflags) {
2156 tcg_gen_movi_i32(hflags, ctx->hflags);
2157 ctx->saved_hflags = ctx->hflags;
2158 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2159 case MIPS_HFLAG_BR:
2160 break;
2161 case MIPS_HFLAG_BC:
2162 case MIPS_HFLAG_BL:
2163 case MIPS_HFLAG_B:
2164 tcg_gen_movi_tl(btarget, ctx->btarget);
2165 break;
2166 }
2167 }
2168}
2169
2170static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2171{
2172 ctx->saved_hflags = ctx->hflags;
2173 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2174 case MIPS_HFLAG_BR:
2175 break;
2176 case MIPS_HFLAG_BC:
2177 case MIPS_HFLAG_BL:
2178 case MIPS_HFLAG_B:
2179 ctx->btarget = env->btarget;
2180 break;
2181 }
2182}
2183
2184static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2185{
2186 TCGv_i32 texcp = tcg_const_i32(excp);
2187 TCGv_i32 terr = tcg_const_i32(err);
2188 save_cpu_state(ctx, 1);
2189 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2190 tcg_temp_free_i32(terr);
2191 tcg_temp_free_i32(texcp);
eeb3bba8 2192 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2193}
2194
2195static inline void generate_exception(DisasContext *ctx, int excp)
2196{
eab9944c
LA
2197 gen_helper_0e0i(raise_exception, excp);
2198}
2199
9c708c7f
PD
2200static inline void generate_exception_end(DisasContext *ctx, int excp)
2201{
2202 generate_exception_err(ctx, excp, 0);
2203}
2204
aaa9128a 2205/* Floating point register moves. */
7c979afd 2206static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2207{
7c979afd
LA
2208 if (ctx->hflags & MIPS_HFLAG_FRE) {
2209 generate_exception(ctx, EXCP_RI);
2210 }
ecc7b3aa 2211 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2212}
2213
7c979afd 2214static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2215{
7c979afd
LA
2216 TCGv_i64 t64;
2217 if (ctx->hflags & MIPS_HFLAG_FRE) {
2218 generate_exception(ctx, EXCP_RI);
2219 }
2220 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2221 tcg_gen_extu_i32_i64(t64, t);
2222 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2223 tcg_temp_free_i64(t64);
6d066274
AJ
2224}
2225
7f6613ce 2226static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2227{
7f6613ce 2228 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2229 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2230 } else {
7c979afd 2231 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2232 }
6d066274
AJ
2233}
2234
7f6613ce 2235static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2236{
7f6613ce
PJ
2237 if (ctx->hflags & MIPS_HFLAG_F64) {
2238 TCGv_i64 t64 = tcg_temp_new_i64();
2239 tcg_gen_extu_i32_i64(t64, t);
2240 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2241 tcg_temp_free_i64(t64);
2242 } else {
7c979afd 2243 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2244 }
aa0bf00b 2245}
6ea83fed 2246
d73ee8a2 2247static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2248{
f364515c 2249 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2250 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2251 } else {
d73ee8a2 2252 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2253 }
2254}
6ea83fed 2255
d73ee8a2 2256static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2257{
f364515c 2258 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2259 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2260 } else {
d73ee8a2
RH
2261 TCGv_i64 t0;
2262 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2263 t0 = tcg_temp_new_i64();
6d066274 2264 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2265 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2266 tcg_temp_free_i64(t0);
aa0bf00b
TS
2267 }
2268}
6ea83fed 2269
d94536f4 2270static inline int get_fp_bit (int cc)
a16336e4 2271{
d94536f4
AJ
2272 if (cc)
2273 return 24 + cc;
2274 else
2275 return 23;
a16336e4
TS
2276}
2277
48d38ca5 2278/* Addresses computation */
941694d0 2279static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2280{
941694d0 2281 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2282
2283#if defined(TARGET_MIPS64)
01f72885 2284 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2285 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2286 }
2287#endif
4ad40f36
FB
2288}
2289
bf0718c5
SM
2290static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2291 target_long ofs)
2292{
2293 tcg_gen_addi_tl(ret, base, ofs);
2294
2295#if defined(TARGET_MIPS64)
2296 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2297 tcg_gen_ext32s_i64(ret, ret);
2298 }
2299#endif
2300}
2301
31837be3
YK
2302/* Addresses computation (translation time) */
2303static target_long addr_add(DisasContext *ctx, target_long base,
2304 target_long offset)
2305{
2306 target_long sum = base + offset;
2307
2308#if defined(TARGET_MIPS64)
2309 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2310 sum = (int32_t)sum;
2311 }
2312#endif
2313 return sum;
2314}
2315
71f303cd 2316/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
2317static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2318{
2319#if defined(TARGET_MIPS64)
71f303cd
RH
2320 tcg_gen_ext32s_i64(ret, arg);
2321#else
2322 tcg_gen_extrl_i64_i32(ret, arg);
2323#endif
2324}
2325
2326/* Sign-extract the high 32-bits to a target_long. */
2327static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2328{
2329#if defined(TARGET_MIPS64)
2330 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2331#else
71f303cd 2332 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2333#endif
2334}
2335
356265ae 2336static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2337{
fe253235 2338 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 2339 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
2340}
2341
356265ae 2342static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 2343{
fe253235 2344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
2345 generate_exception_err(ctx, EXCP_CpU, 1);
2346}
2347
b8aa4598
TS
2348/* Verify that the processor is running with COP1X instructions enabled.
2349 This is associated with the nabla symbol in the MIPS32 and MIPS64
2350 opcode tables. */
2351
356265ae 2352static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
2353{
2354 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 2355 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
2356}
2357
2358/* Verify that the processor is running with 64-bit floating-point
2359 operations enabled. */
2360
356265ae 2361static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2362{
b8aa4598 2363 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 2364 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2365}
2366
2367/*
2368 * Verify if floating point register is valid; an operation is not defined
2369 * if bit 0 of any register specification is set and the FR bit in the
2370 * Status register equals zero, since the register numbers specify an
2371 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2372 * in the Status register equals one, both even and odd register numbers
2373 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2374 *
2375 * Multiple 64 bit wide registers can be checked by calling
2376 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2377 */
356265ae 2378static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2379{
fe253235 2380 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 2381 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2382}
2383
853c3240
JL
2384/* Verify that the processor is running with DSP instructions enabled.
2385 This is enabled by CP0 Status register MX(24) bit.
2386 */
2387
2388static inline void check_dsp(DisasContext *ctx)
2389{
2390 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2391 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2392 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2393 } else {
9c708c7f 2394 generate_exception_end(ctx, EXCP_RI);
ad153f15 2395 }
853c3240
JL
2396 }
2397}
2398
908f6be1 2399static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2400{
908f6be1 2401 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2402 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2403 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2404 } else {
9c708c7f 2405 generate_exception_end(ctx, EXCP_RI);
ad153f15 2406 }
853c3240
JL
2407 }
2408}
2409
908f6be1 2410static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2411{
908f6be1 2412 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2413 if (ctx->insn_flags & ASE_DSP) {
2414 generate_exception_end(ctx, EXCP_DSPDIS);
2415 } else {
2416 generate_exception_end(ctx, EXCP_RI);
2417 }
2418 }
2419}
2420
3a95e3a7 2421/* This code generates a "reserved instruction" exception if the
e189e748 2422 CPU does not support the instruction set corresponding to flags. */
f9c9cd63 2423static inline void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2424{
d75c135e 2425 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 2426 generate_exception_end(ctx, EXCP_RI);
d75c135e 2427 }
3a95e3a7
TS
2428}
2429
fecd2646
LA
2430/* This code generates a "reserved instruction" exception if the
2431 CPU has corresponding flag set which indicates that the instruction
2432 has been removed. */
f9c9cd63 2433static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2434{
2435 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 2436 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
2437 }
2438}
2439
e29c9628
YK
2440/* This code generates a "reserved instruction" exception if the
2441 CPU does not support 64-bit paired-single (PS) floating point data type */
2442static inline void check_ps(DisasContext *ctx)
2443{
2444 if (unlikely(!ctx->ps)) {
2445 generate_exception(ctx, EXCP_RI);
2446 }
2447 check_cp1_64bitmode(ctx);
2448}
2449
c7986fd6 2450#ifdef TARGET_MIPS64
e189e748
TS
2451/* This code generates a "reserved instruction" exception if 64-bit
2452 instructions are not enabled. */
356265ae 2453static inline void check_mips_64(DisasContext *ctx)
e189e748 2454{
fe253235 2455 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 2456 generate_exception_end(ctx, EXCP_RI);
e189e748 2457}
c7986fd6 2458#endif
e189e748 2459
5204ea79
LA
2460#ifndef CONFIG_USER_ONLY
2461static inline void check_mvh(DisasContext *ctx)
2462{
2463 if (unlikely(!ctx->mvh)) {
2464 generate_exception(ctx, EXCP_RI);
2465 }
2466}
2467#endif
2468
0b16dcd1
AR
2469/*
2470 * This code generates a "reserved instruction" exception if the
2471 * Config5 XNP bit is set.
2472 */
2473static inline void check_xnp(DisasContext *ctx)
2474{
2475 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2476 generate_exception_end(ctx, EXCP_RI);
2477 }
2478}
2479
9affc1c5
AR
2480/*
2481 * This code generates a "reserved instruction" exception if the
2482 * Config3 MT bit is NOT set.
2483 */
2484static inline void check_mt(DisasContext *ctx)
2485{
2486 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2487 generate_exception_end(ctx, EXCP_RI);
2488 }
2489}
2490
2491#ifndef CONFIG_USER_ONLY
2492/*
2493 * This code generates a "coprocessor unusable" exception if CP0 is not
2494 * available, and, if that is not the case, generates a "reserved instruction"
2495 * exception if the Config5 MT bit is NOT set. This is needed for availability
2496 * control of some of MT ASE instructions.
2497 */
2498static inline void check_cp0_mt(DisasContext *ctx)
2499{
2500 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2501 generate_exception_err(ctx, EXCP_CpU, 0);
2502 } else {
2503 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2504 generate_exception_err(ctx, EXCP_RI, 0);
2505 }
2506 }
2507}
2508#endif
2509
fb32f8c8
DN
2510/*
2511 * This code generates a "reserved instruction" exception if the
2512 * Config5 NMS bit is set.
2513 */
2514static inline void check_nms(DisasContext *ctx)
2515{
2516 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2517 generate_exception_end(ctx, EXCP_RI);
2518 }
2519}
2520
0b16dcd1 2521
8153667c
NF
2522/* Define small wrappers for gen_load_fpr* so that we have a uniform
2523 calling interface for 32 and 64-bit FPRs. No sense in changing
2524 all callers for gen_load_fpr32 when we need the CTX parameter for
2525 this one use. */
7c979afd 2526#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
2527#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2528#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2529static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2530 int ft, int fs, int cc) \
2531{ \
2532 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
2533 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
2534 switch (ifmt) { \
2535 case FMT_PS: \
e29c9628 2536 check_ps(ctx); \
8153667c
NF
2537 break; \
2538 case FMT_D: \
2539 if (abs) { \
2540 check_cop1x(ctx); \
2541 } \
2542 check_cp1_registers(ctx, fs | ft); \
2543 break; \
2544 case FMT_S: \
2545 if (abs) { \
2546 check_cop1x(ctx); \
2547 } \
2548 break; \
2549 } \
2550 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
2551 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
2552 switch (n) { \
895c2d04
BS
2553 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
2554 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
2555 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
2556 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
2557 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
2558 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
2559 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
2560 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
2561 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
2562 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2563 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
2564 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
2565 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
2566 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
2567 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
2568 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
2569 default: abort(); \
2570 } \
2571 tcg_temp_free_i##bits (fp0); \
2572 tcg_temp_free_i##bits (fp1); \
2573}
2574
2575FOP_CONDS(, 0, d, FMT_D, 64)
2576FOP_CONDS(abs, 1, d, FMT_D, 64)
2577FOP_CONDS(, 0, s, FMT_S, 32)
2578FOP_CONDS(abs, 1, s, FMT_S, 32)
2579FOP_CONDS(, 0, ps, FMT_PS, 64)
2580FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2581#undef FOP_CONDS
3f493883
YK
2582
2583#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2584static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
2585 int ft, int fs, int fd) \
2586{ \
2587 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2588 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 2589 if (ifmt == FMT_D) { \
3f493883 2590 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
2591 } \
2592 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2593 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2594 switch (n) { \
2595 case 0: \
2596 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2597 break; \
2598 case 1: \
2599 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2600 break; \
2601 case 2: \
2602 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2603 break; \
2604 case 3: \
2605 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2606 break; \
2607 case 4: \
2608 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2609 break; \
2610 case 5: \
2611 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2612 break; \
2613 case 6: \
2614 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2615 break; \
2616 case 7: \
2617 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2618 break; \
2619 case 8: \
2620 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2621 break; \
2622 case 9: \
2623 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2624 break; \
2625 case 10: \
2626 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2627 break; \
2628 case 11: \
2629 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2630 break; \
2631 case 12: \
2632 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2633 break; \
2634 case 13: \
2635 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2636 break; \
2637 case 14: \
2638 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2639 break; \
2640 case 15: \
2641 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2642 break; \
2643 case 17: \
2644 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2645 break; \
2646 case 18: \
2647 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2648 break; \
2649 case 19: \
2650 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2651 break; \
2652 case 25: \
2653 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2654 break; \
2655 case 26: \
2656 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2657 break; \
2658 case 27: \
2659 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2660 break; \
2661 default: \
2662 abort(); \
2663 } \
2664 STORE; \
2665 tcg_temp_free_i ## bits (fp0); \
2666 tcg_temp_free_i ## bits (fp1); \
2667}
2668
2669FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2670FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2671#undef FOP_CONDNS
8153667c
NF
2672#undef gen_ldcmp_fpr32
2673#undef gen_ldcmp_fpr64
2674
958fb4a9 2675/* load/store instructions. */
e7139c44 2676#ifdef CONFIG_USER_ONLY
d9bea114 2677#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2678static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2679 DisasContext *ctx) \
d9bea114
AJ
2680{ \
2681 TCGv t0 = tcg_temp_new(); \
2682 tcg_gen_mov_tl(t0, arg1); \
2683 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2684 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2685 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2686 tcg_temp_free(t0); \
aaa9128a 2687}
e7139c44
AJ
2688#else
2689#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2690static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2691 DisasContext *ctx) \
e7139c44 2692{ \
dd4096cd 2693 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2694}
2695#endif
aaa9128a
TS
2696OP_LD_ATOMIC(ll,ld32s);
2697#if defined(TARGET_MIPS64)
2698OP_LD_ATOMIC(lld,ld64);
2699#endif
2700#undef OP_LD_ATOMIC
2701
590bc601
PB
2702#ifdef CONFIG_USER_ONLY
2703#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2704static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2705 DisasContext *ctx) \
590bc601
PB
2706{ \
2707 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2708 TCGLabel *l1 = gen_new_label(); \
2709 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2710 \
2711 tcg_gen_andi_tl(t0, arg2, almask); \
2712 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2713 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2714 generate_exception(ctx, EXCP_AdES); \
2715 gen_set_label(l1); \
7db13fae 2716 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2717 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2718 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2719 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2720 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2721 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2722 gen_set_label(l2); \
2723 tcg_gen_movi_tl(t0, 0); \
2724 gen_store_gpr(t0, rt); \
2725 tcg_temp_free(t0); \
2726}
2727#else
2728#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2729static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2730 DisasContext *ctx) \
590bc601
PB
2731{ \
2732 TCGv t0 = tcg_temp_new(); \
dd4096cd 2733 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2734 gen_store_gpr(t0, rt); \
590bc601
PB
2735 tcg_temp_free(t0); \
2736}
2737#endif
590bc601 2738OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2739#if defined(TARGET_MIPS64)
590bc601 2740OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2741#endif
2742#undef OP_ST_ATOMIC
2743
662d7485 2744static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 2745 int base, int offset)
662d7485
NF
2746{
2747 if (base == 0) {
2748 tcg_gen_movi_tl(addr, offset);
2749 } else if (offset == 0) {
2750 gen_load_gpr(addr, base);
2751 } else {
2752 tcg_gen_movi_tl(addr, offset);
2753 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2754 }
2755}
2756
364d4831
NF
2757static target_ulong pc_relative_pc (DisasContext *ctx)
2758{
eeb3bba8 2759 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2760
2761 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2762 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2763
2764 pc -= branch_bytes;
2765 }
2766
2767 pc &= ~(target_ulong)3;
2768 return pc;
2769}
2770
5c13fdfd 2771/* Load */
d75c135e 2772static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2773 int rt, int base, int offset)
6af0bf9c 2774{
fc40787a 2775 TCGv t0, t1, t2;
dd4096cd 2776 int mem_idx = ctx->mem_idx;
afa88c3a 2777
d75c135e 2778 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2779 /* Loongson CPU uses a load to zero register for prefetch.
2780 We emulate it as a NOP. On other CPU we must perform the
2781 actual memory access. */
afa88c3a
AJ
2782 return;
2783 }
6af0bf9c 2784
afa88c3a 2785 t0 = tcg_temp_new();
662d7485 2786 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2787
6af0bf9c 2788 switch (opc) {
d26bc211 2789#if defined(TARGET_MIPS64)
6e473128 2790 case OPC_LWU:
dd4096cd 2791 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2792 ctx->default_tcg_memop_mask);
78723684 2793 gen_store_gpr(t0, rt);
6e473128 2794 break;
6af0bf9c 2795 case OPC_LD:
dd4096cd 2796 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2797 ctx->default_tcg_memop_mask);
78723684 2798 gen_store_gpr(t0, rt);
6af0bf9c 2799 break;
7a387fff 2800 case OPC_LLD:
bf7910c6 2801 case R6_OPC_LLD:
dd4096cd 2802 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2803 gen_store_gpr(t0, rt);
7a387fff 2804 break;
6af0bf9c 2805 case OPC_LDL:
3cee3050 2806 t1 = tcg_temp_new();
908680c6
AJ
2807 /* Do a byte access to possibly trigger a page
2808 fault with the unaligned address. */
dd4096cd 2809 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2810 tcg_gen_andi_tl(t1, t0, 7);
2811#ifndef TARGET_WORDS_BIGENDIAN
2812 tcg_gen_xori_tl(t1, t1, 7);
2813#endif
2814 tcg_gen_shli_tl(t1, t1, 3);
2815 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2816 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2817 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2818 t2 = tcg_const_tl(-1);
2819 tcg_gen_shl_tl(t2, t2, t1);
78723684 2820 gen_load_gpr(t1, rt);
eb02cc3f 2821 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2822 tcg_temp_free(t2);
2823 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2824 tcg_temp_free(t1);
fc40787a 2825 gen_store_gpr(t0, rt);
6af0bf9c 2826 break;
6af0bf9c 2827 case OPC_LDR:
3cee3050 2828 t1 = tcg_temp_new();
908680c6
AJ
2829 /* Do a byte access to possibly trigger a page
2830 fault with the unaligned address. */
dd4096cd 2831 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2832 tcg_gen_andi_tl(t1, t0, 7);
2833#ifdef TARGET_WORDS_BIGENDIAN
2834 tcg_gen_xori_tl(t1, t1, 7);
2835#endif
2836 tcg_gen_shli_tl(t1, t1, 3);
2837 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2838 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2839 tcg_gen_shr_tl(t0, t0, t1);
2840 tcg_gen_xori_tl(t1, t1, 63);
2841 t2 = tcg_const_tl(0xfffffffffffffffeull);
2842 tcg_gen_shl_tl(t2, t2, t1);
78723684 2843 gen_load_gpr(t1, rt);
fc40787a
AJ
2844 tcg_gen_and_tl(t1, t1, t2);
2845 tcg_temp_free(t2);
2846 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2847 tcg_temp_free(t1);
fc40787a 2848 gen_store_gpr(t0, rt);
6af0bf9c 2849 break;
364d4831 2850 case OPC_LDPC:
3cee3050 2851 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2852 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2853 tcg_temp_free(t1);
dd4096cd 2854 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2855 gen_store_gpr(t0, rt);
2856 break;
6af0bf9c 2857#endif
364d4831 2858 case OPC_LWPC:
3cee3050 2859 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2860 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2861 tcg_temp_free(t1);
dd4096cd 2862 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2863 gen_store_gpr(t0, rt);
2864 break;
76964147
JH
2865 case OPC_LWE:
2866 mem_idx = MIPS_HFLAG_UM;
2867 /* fall through */
6af0bf9c 2868 case OPC_LW:
dd4096cd 2869 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2870 ctx->default_tcg_memop_mask);
78723684 2871 gen_store_gpr(t0, rt);
6af0bf9c 2872 break;
76964147
JH
2873 case OPC_LHE:
2874 mem_idx = MIPS_HFLAG_UM;
2875 /* fall through */
6af0bf9c 2876 case OPC_LH:
dd4096cd 2877 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2878 ctx->default_tcg_memop_mask);
78723684 2879 gen_store_gpr(t0, rt);
6af0bf9c 2880 break;
76964147
JH
2881 case OPC_LHUE:
2882 mem_idx = MIPS_HFLAG_UM;
2883 /* fall through */
6af0bf9c 2884 case OPC_LHU:
dd4096cd 2885 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2886 ctx->default_tcg_memop_mask);
78723684 2887 gen_store_gpr(t0, rt);
6af0bf9c 2888 break;
76964147
JH
2889 case OPC_LBE:
2890 mem_idx = MIPS_HFLAG_UM;
2891 /* fall through */
6af0bf9c 2892 case OPC_LB:
dd4096cd 2893 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2894 gen_store_gpr(t0, rt);
6af0bf9c 2895 break;
76964147
JH
2896 case OPC_LBUE:
2897 mem_idx = MIPS_HFLAG_UM;
2898 /* fall through */
6af0bf9c 2899 case OPC_LBU:
dd4096cd 2900 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2901 gen_store_gpr(t0, rt);
6af0bf9c 2902 break;
76964147
JH
2903 case OPC_LWLE:
2904 mem_idx = MIPS_HFLAG_UM;
2905 /* fall through */
6af0bf9c 2906 case OPC_LWL:
3cee3050 2907 t1 = tcg_temp_new();
908680c6
AJ
2908 /* Do a byte access to possibly trigger a page
2909 fault with the unaligned address. */
dd4096cd 2910 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2911 tcg_gen_andi_tl(t1, t0, 3);
2912#ifndef TARGET_WORDS_BIGENDIAN
2913 tcg_gen_xori_tl(t1, t1, 3);
2914#endif
2915 tcg_gen_shli_tl(t1, t1, 3);
2916 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2917 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2918 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2919 t2 = tcg_const_tl(-1);
2920 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2921 gen_load_gpr(t1, rt);
eb02cc3f 2922 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2923 tcg_temp_free(t2);
2924 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2925 tcg_temp_free(t1);
fc40787a
AJ
2926 tcg_gen_ext32s_tl(t0, t0);
2927 gen_store_gpr(t0, rt);
6af0bf9c 2928 break;
76964147
JH
2929 case OPC_LWRE:
2930 mem_idx = MIPS_HFLAG_UM;
2931 /* fall through */
6af0bf9c 2932 case OPC_LWR:
3cee3050 2933 t1 = tcg_temp_new();
908680c6
AJ
2934 /* Do a byte access to possibly trigger a page
2935 fault with the unaligned address. */
dd4096cd 2936 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2937 tcg_gen_andi_tl(t1, t0, 3);
2938#ifdef TARGET_WORDS_BIGENDIAN
2939 tcg_gen_xori_tl(t1, t1, 3);
2940#endif
2941 tcg_gen_shli_tl(t1, t1, 3);
2942 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2943 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2944 tcg_gen_shr_tl(t0, t0, t1);
2945 tcg_gen_xori_tl(t1, t1, 31);
2946 t2 = tcg_const_tl(0xfffffffeull);
2947 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2948 gen_load_gpr(t1, rt);
fc40787a
AJ
2949 tcg_gen_and_tl(t1, t1, t2);
2950 tcg_temp_free(t2);
2951 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2952 tcg_temp_free(t1);
c728154b 2953 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2954 gen_store_gpr(t0, rt);
6af0bf9c 2955 break;
76964147
JH
2956 case OPC_LLE:
2957 mem_idx = MIPS_HFLAG_UM;
2958 /* fall through */
6af0bf9c 2959 case OPC_LL:
4368b29a 2960 case R6_OPC_LL:
dd4096cd 2961 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2962 gen_store_gpr(t0, rt);
6af0bf9c 2963 break;
d66c7132 2964 }
d66c7132 2965 tcg_temp_free(t0);
d66c7132
AJ
2966}
2967
0b16dcd1
AR
2968static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2969 uint32_t reg1, uint32_t reg2)
2970{
2971 TCGv taddr = tcg_temp_new();
2972 TCGv_i64 tval = tcg_temp_new_i64();
2973 TCGv tmp1 = tcg_temp_new();
2974 TCGv tmp2 = tcg_temp_new();
2975
2976 gen_base_offset_addr(ctx, taddr, base, offset);
2977 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2978#ifdef TARGET_WORDS_BIGENDIAN
2979 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2980#else
2981 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2982#endif
2983 gen_store_gpr(tmp1, reg1);
2984 tcg_temp_free(tmp1);
2985 gen_store_gpr(tmp2, reg2);
2986 tcg_temp_free(tmp2);
2987 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
2988 tcg_temp_free_i64(tval);
2989 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
2990 tcg_temp_free(taddr);
2991}
2992
5c13fdfd
AJ
2993/* Store */
2994static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 2995 int base, int offset)
5c13fdfd 2996{
5c13fdfd
AJ
2997 TCGv t0 = tcg_temp_new();
2998 TCGv t1 = tcg_temp_new();
dd4096cd 2999 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3000
3001 gen_base_offset_addr(ctx, t0, base, offset);
3002 gen_load_gpr(t1, rt);
3003 switch (opc) {
3004#if defined(TARGET_MIPS64)
3005 case OPC_SD:
dd4096cd 3006 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3007 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3008 break;
3009 case OPC_SDL:
dd4096cd 3010 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3011 break;
3012 case OPC_SDR:
dd4096cd 3013 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3014 break;
3015#endif
76964147
JH
3016 case OPC_SWE:
3017 mem_idx = MIPS_HFLAG_UM;
3018 /* fall through */
5c13fdfd 3019 case OPC_SW:
dd4096cd 3020 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3021 ctx->default_tcg_memop_mask);
5c13fdfd 3022 break;
76964147
JH
3023 case OPC_SHE:
3024 mem_idx = MIPS_HFLAG_UM;
3025 /* fall through */
5c13fdfd 3026 case OPC_SH:
dd4096cd 3027 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3028 ctx->default_tcg_memop_mask);
5c13fdfd 3029 break;
76964147
JH
3030 case OPC_SBE:
3031 mem_idx = MIPS_HFLAG_UM;
3032 /* fall through */
5c13fdfd 3033 case OPC_SB:
dd4096cd 3034 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3035 break;
76964147
JH
3036 case OPC_SWLE:
3037 mem_idx = MIPS_HFLAG_UM;
3038 /* fall through */
5c13fdfd 3039 case OPC_SWL:
dd4096cd 3040 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3041 break;
76964147
JH
3042 case OPC_SWRE:
3043 mem_idx = MIPS_HFLAG_UM;
3044 /* fall through */
5c13fdfd 3045 case OPC_SWR:
dd4096cd 3046 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3047 break;
3048 }
5c13fdfd
AJ
3049 tcg_temp_free(t0);
3050 tcg_temp_free(t1);
3051}
3052
3053
d66c7132
AJ
3054/* Store conditional */
3055static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3056 int base, int16_t offset)
3057{
d66c7132 3058 TCGv t0, t1;
dd4096cd 3059 int mem_idx = ctx->mem_idx;
d66c7132 3060
2d2826b9 3061#ifdef CONFIG_USER_ONLY
d66c7132 3062 t0 = tcg_temp_local_new();
d66c7132 3063 t1 = tcg_temp_local_new();
2d2826b9
AJ
3064#else
3065 t0 = tcg_temp_new();
3066 t1 = tcg_temp_new();
3067#endif
3068 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
3069 gen_load_gpr(t1, rt);
3070 switch (opc) {
3071#if defined(TARGET_MIPS64)
3072 case OPC_SCD:
bf7910c6 3073 case R6_OPC_SCD:
dd4096cd 3074 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
3075 break;
3076#endif
76964147
JH
3077 case OPC_SCE:
3078 mem_idx = MIPS_HFLAG_UM;
3079 /* fall through */
6af0bf9c 3080 case OPC_SC:
4368b29a 3081 case R6_OPC_SC:
dd4096cd 3082 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 3083 break;
6af0bf9c 3084 }
78723684 3085 tcg_temp_free(t1);
d66c7132 3086 tcg_temp_free(t0);
6af0bf9c
FB
3087}
3088
0b16dcd1
AR
3089static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3090 uint32_t reg1, uint32_t reg2)
3091{
3092 TCGv taddr = tcg_temp_local_new();
3093 TCGv lladdr = tcg_temp_local_new();
3094 TCGv_i64 tval = tcg_temp_new_i64();
3095 TCGv_i64 llval = tcg_temp_new_i64();
3096 TCGv_i64 val = tcg_temp_new_i64();
3097 TCGv tmp1 = tcg_temp_new();
3098 TCGv tmp2 = tcg_temp_new();
3099 TCGLabel *lab_fail = gen_new_label();
3100 TCGLabel *lab_done = gen_new_label();
3101
3102 gen_base_offset_addr(ctx, taddr, base, offset);
3103
3104 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3105 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3106
3107 gen_load_gpr(tmp1, reg1);
3108 gen_load_gpr(tmp2, reg2);
3109
3110#ifdef TARGET_WORDS_BIGENDIAN
3111 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3112#else
3113 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3114#endif
3115
3116 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3117 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3118 ctx->mem_idx, MO_64);
3119 if (reg1 != 0) {
3120 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3121 }
3122 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3123
3124 gen_set_label(lab_fail);
3125
3126 if (reg1 != 0) {
3127 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3128 }
3129 gen_set_label(lab_done);
3130 tcg_gen_movi_tl(lladdr, -1);
3131 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3132}
3133
6ea83fed 3134/* Load and store */
7a387fff 3135static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 3136 TCGv t0)
6ea83fed 3137{
6ea83fed 3138 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 3139 memory access. */
6ea83fed
FB
3140 switch (opc) {
3141 case OPC_LWC1:
b6d96bed 3142 {
a7812ae4 3143 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3144 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3145 ctx->default_tcg_memop_mask);
7c979afd 3146 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3147 tcg_temp_free_i32(fp0);
b6d96bed 3148 }
6ea83fed
FB
3149 break;
3150 case OPC_SWC1:
b6d96bed 3151 {
a7812ae4 3152 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3153 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3154 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3155 ctx->default_tcg_memop_mask);
a7812ae4 3156 tcg_temp_free_i32(fp0);
b6d96bed 3157 }
6ea83fed
FB
3158 break;
3159 case OPC_LDC1:
b6d96bed 3160 {
a7812ae4 3161 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3162 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3163 ctx->default_tcg_memop_mask);
b6d96bed 3164 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3165 tcg_temp_free_i64(fp0);
b6d96bed 3166 }
6ea83fed
FB
3167 break;
3168 case OPC_SDC1:
b6d96bed 3169 {
a7812ae4 3170 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3171 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3172 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3173 ctx->default_tcg_memop_mask);
a7812ae4 3174 tcg_temp_free_i64(fp0);
b6d96bed 3175 }
6ea83fed
FB
3176 break;
3177 default:
9d68ac14 3178 MIPS_INVAL("flt_ldst");
9c708c7f 3179 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 3180 break;
6ea83fed 3181 }
6ea83fed 3182}
6ea83fed 3183
5ab5c041
AJ
3184static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3185 int rs, int16_t imm)
26ebe468 3186{
b52d3bfa
YK
3187 TCGv t0 = tcg_temp_new();
3188
5ab5c041 3189 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3190 check_cp1_enabled(ctx);
d9224450
MR
3191 switch (op) {
3192 case OPC_LDC1:
3193 case OPC_SDC1:
3194 check_insn(ctx, ISA_MIPS2);
3195 /* Fallthrough */
3196 default:
b52d3bfa
YK
3197 gen_base_offset_addr(ctx, t0, rs, imm);
3198 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3199 }
26ebe468
NF
3200 } else {
3201 generate_exception_err(ctx, EXCP_CpU, 1);
3202 }
b52d3bfa 3203 tcg_temp_free(t0);
26ebe468
NF
3204}
3205
6af0bf9c 3206/* Arithmetic with immediate operand */
d75c135e 3207static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3208 int rt, int rs, int imm)
6af0bf9c 3209{
324d9e32 3210 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3211
7a387fff 3212 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
3213 /* If no destination, treat it as a NOP.
3214 For addi, we must generate the overflow exception when needed. */
324d9e32 3215 return;
6af0bf9c
FB
3216 }
3217 switch (opc) {
3218 case OPC_ADDI:
48d38ca5 3219 {
324d9e32
AJ
3220 TCGv t0 = tcg_temp_local_new();
3221 TCGv t1 = tcg_temp_new();
3222 TCGv t2 = tcg_temp_new();
42a268c2 3223 TCGLabel *l1 = gen_new_label();
48d38ca5 3224
324d9e32
AJ
3225 gen_load_gpr(t1, rs);
3226 tcg_gen_addi_tl(t0, t1, uimm);
3227 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3228
324d9e32
AJ
3229 tcg_gen_xori_tl(t1, t1, ~uimm);
3230 tcg_gen_xori_tl(t2, t0, uimm);
3231 tcg_gen_and_tl(t1, t1, t2);
3232 tcg_temp_free(t2);
3233 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3234 tcg_temp_free(t1);
48d38ca5
TS
3235 /* operands of same sign, result different sign */
3236 generate_exception(ctx, EXCP_OVERFLOW);
3237 gen_set_label(l1);
78723684 3238 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3239 gen_store_gpr(t0, rt);
3240 tcg_temp_free(t0);
48d38ca5 3241 }
6af0bf9c
FB
3242 break;
3243 case OPC_ADDIU:
324d9e32
AJ
3244 if (rs != 0) {
3245 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3246 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3247 } else {
3248 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3249 }
6af0bf9c 3250 break;
d26bc211 3251#if defined(TARGET_MIPS64)
7a387fff 3252 case OPC_DADDI:
48d38ca5 3253 {
324d9e32
AJ
3254 TCGv t0 = tcg_temp_local_new();
3255 TCGv t1 = tcg_temp_new();
3256 TCGv t2 = tcg_temp_new();
42a268c2 3257 TCGLabel *l1 = gen_new_label();
48d38ca5 3258
324d9e32
AJ
3259 gen_load_gpr(t1, rs);
3260 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3261
324d9e32
AJ
3262 tcg_gen_xori_tl(t1, t1, ~uimm);
3263 tcg_gen_xori_tl(t2, t0, uimm);
3264 tcg_gen_and_tl(t1, t1, t2);
3265 tcg_temp_free(t2);
3266 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3267 tcg_temp_free(t1);
48d38ca5
TS
3268 /* operands of same sign, result different sign */
3269 generate_exception(ctx, EXCP_OVERFLOW);
3270 gen_set_label(l1);
324d9e32
AJ
3271 gen_store_gpr(t0, rt);
3272 tcg_temp_free(t0);
48d38ca5 3273 }
7a387fff
TS
3274 break;
3275 case OPC_DADDIU:
324d9e32
AJ
3276 if (rs != 0) {
3277 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3278 } else {
3279 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3280 }
7a387fff
TS
3281 break;
3282#endif
324d9e32 3283 }
324d9e32
AJ
3284}
3285
3286/* Logic with immediate operand */
d75c135e 3287static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3288 int rt, int rs, int16_t imm)
324d9e32
AJ
3289{
3290 target_ulong uimm;
324d9e32
AJ
3291
3292 if (rt == 0) {
3293 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3294 return;
3295 }
3296 uimm = (uint16_t)imm;
3297 switch (opc) {
6af0bf9c 3298 case OPC_ANDI:
324d9e32
AJ
3299 if (likely(rs != 0))
3300 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3301 else
3302 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
3303 break;
3304 case OPC_ORI:
324d9e32
AJ
3305 if (rs != 0)
3306 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3307 else
3308 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3309 break;
3310 case OPC_XORI:
324d9e32
AJ
3311 if (likely(rs != 0))
3312 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3313 else
3314 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3315 break;
3316 case OPC_LUI:
d4ea6acd
LA
3317 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3318 /* OPC_AUI */
3319 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3320 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3321 } else {
3322 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3323 }
7c2c3ea3
EJ
3324 break;
3325
3326 default:
6af0bf9c 3327 break;
324d9e32 3328 }
324d9e32
AJ
3329}
3330
3331/* Set on less than with immediate operand */
d75c135e 3332static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3333 int rt, int rs, int16_t imm)
324d9e32
AJ
3334{
3335 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3336 TCGv t0;
3337
3338 if (rt == 0) {
3339 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3340 return;
3341 }
3342 t0 = tcg_temp_new();
3343 gen_load_gpr(t0, rs);
3344 switch (opc) {
3345 case OPC_SLTI:
e68dd28f 3346 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3347 break;
3348 case OPC_SLTIU:
e68dd28f 3349 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3350 break;
3351 }
324d9e32
AJ
3352 tcg_temp_free(t0);
3353}
3354
3355/* Shifts with immediate operand */
d75c135e 3356static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3357 int rt, int rs, int16_t imm)
3358{
3359 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3360 TCGv t0;
3361
3362 if (rt == 0) {
3363 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3364 return;
3365 }
3366
3367 t0 = tcg_temp_new();
3368 gen_load_gpr(t0, rs);
3369 switch (opc) {
6af0bf9c 3370 case OPC_SLL:
78723684 3371 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3372 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3373 break;
3374 case OPC_SRA:
324d9e32 3375 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3376 break;
3377 case OPC_SRL:
ea63e2c3
NF
3378 if (uimm != 0) {
3379 tcg_gen_ext32u_tl(t0, t0);
3380 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3381 } else {
3382 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 3383 }
ea63e2c3
NF
3384 break;
3385 case OPC_ROTR:
3386 if (uimm != 0) {
3387 TCGv_i32 t1 = tcg_temp_new_i32();
3388
3389 tcg_gen_trunc_tl_i32(t1, t0);
3390 tcg_gen_rotri_i32(t1, t1, uimm);
3391 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3392 tcg_temp_free_i32(t1);
3399e30f
NF
3393 } else {
3394 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 3395 }
7a387fff 3396 break;
d26bc211 3397#if defined(TARGET_MIPS64)
7a387fff 3398 case OPC_DSLL:
324d9e32 3399 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3400 break;
3401 case OPC_DSRA:
324d9e32 3402 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3403 break;
3404 case OPC_DSRL:
ea63e2c3 3405 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
3406 break;
3407 case OPC_DROTR:
3408 if (uimm != 0) {
3409 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
3410 } else {
3411 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 3412 }
7a387fff
TS
3413 break;
3414 case OPC_DSLL32:
324d9e32 3415 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3416 break;
3417 case OPC_DSRA32:
324d9e32 3418 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3419 break;
3420 case OPC_DSRL32:
ea63e2c3 3421 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
3422 break;
3423 case OPC_DROTR32:
3424 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 3425 break;
7a387fff 3426#endif
6af0bf9c 3427 }
78723684 3428 tcg_temp_free(t0);
6af0bf9c
FB
3429}
3430
3431/* Arithmetic */
d75c135e
AJ
3432static void gen_arith(DisasContext *ctx, uint32_t opc,
3433 int rd, int rs, int rt)
6af0bf9c 3434{
7a387fff
TS
3435 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3436 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
3437 /* If no destination, treat it as a NOP.
3438 For add & sub, we must generate the overflow exception when needed. */
460f00c4 3439 return;
185f0762 3440 }
460f00c4 3441
6af0bf9c
FB
3442 switch (opc) {
3443 case OPC_ADD:
48d38ca5 3444 {
460f00c4
AJ
3445 TCGv t0 = tcg_temp_local_new();
3446 TCGv t1 = tcg_temp_new();
3447 TCGv t2 = tcg_temp_new();
42a268c2 3448 TCGLabel *l1 = gen_new_label();
48d38ca5 3449
460f00c4
AJ
3450 gen_load_gpr(t1, rs);
3451 gen_load_gpr(t2, rt);
3452 tcg_gen_add_tl(t0, t1, t2);
3453 tcg_gen_ext32s_tl(t0, t0);
3454 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3455 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3456 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3457 tcg_temp_free(t2);
3458 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3459 tcg_temp_free(t1);
48d38ca5
TS
3460 /* operands of same sign, result different sign */
3461 generate_exception(ctx, EXCP_OVERFLOW);
3462 gen_set_label(l1);
460f00c4
AJ
3463 gen_store_gpr(t0, rd);
3464 tcg_temp_free(t0);
48d38ca5 3465 }
6af0bf9c
FB
3466 break;
3467 case OPC_ADDU:
460f00c4
AJ
3468 if (rs != 0 && rt != 0) {
3469 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3470 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3471 } else if (rs == 0 && rt != 0) {
3472 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3473 } else if (rs != 0 && rt == 0) {
3474 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3475 } else {
3476 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3477 }
6af0bf9c
FB
3478 break;
3479 case OPC_SUB:
48d38ca5 3480 {
460f00c4
AJ
3481 TCGv t0 = tcg_temp_local_new();
3482 TCGv t1 = tcg_temp_new();
3483 TCGv t2 = tcg_temp_new();
42a268c2 3484 TCGLabel *l1 = gen_new_label();
48d38ca5 3485
460f00c4
AJ
3486 gen_load_gpr(t1, rs);
3487 gen_load_gpr(t2, rt);
3488 tcg_gen_sub_tl(t0, t1, t2);
3489 tcg_gen_ext32s_tl(t0, t0);
3490 tcg_gen_xor_tl(t2, t1, t2);
3491 tcg_gen_xor_tl(t1, t0, t1);
3492 tcg_gen_and_tl(t1, t1, t2);
3493 tcg_temp_free(t2);
3494 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3495 tcg_temp_free(t1);
31e3104f 3496 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
3497 generate_exception(ctx, EXCP_OVERFLOW);
3498 gen_set_label(l1);
460f00c4
AJ
3499 gen_store_gpr(t0, rd);
3500 tcg_temp_free(t0);
48d38ca5 3501 }
6af0bf9c
FB
3502 break;
3503 case OPC_SUBU:
460f00c4
AJ
3504 if (rs != 0 && rt != 0) {
3505 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3506 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3507 } else if (rs == 0 && rt != 0) {
3508 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 3509 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
3510 } else if (rs != 0 && rt == 0) {
3511 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3512 } else {
3513 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3514 }
6af0bf9c 3515 break;
d26bc211 3516#if defined(TARGET_MIPS64)
7a387fff 3517 case OPC_DADD:
48d38ca5 3518 {
460f00c4
AJ
3519 TCGv t0 = tcg_temp_local_new();
3520 TCGv t1 = tcg_temp_new();
3521 TCGv t2 = tcg_temp_new();
42a268c2 3522 TCGLabel *l1 = gen_new_label();
48d38ca5 3523
460f00c4
AJ
3524 gen_load_gpr(t1, rs);
3525 gen_load_gpr(t2, rt);
3526 tcg_gen_add_tl(t0, t1, t2);
3527 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3528 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3529 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3530 tcg_temp_free(t2);
3531 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3532 tcg_temp_free(t1);
48d38ca5
TS
3533 /* operands of same sign, result different sign */
3534 generate_exception(ctx, EXCP_OVERFLOW);
3535 gen_set_label(l1);
460f00c4
AJ
3536 gen_store_gpr(t0, rd);
3537 tcg_temp_free(t0);
48d38ca5 3538 }
7a387fff
TS
3539 break;
3540 case OPC_DADDU:
460f00c4
AJ
3541 if (rs != 0 && rt != 0) {
3542 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3543 } else if (rs == 0 && rt != 0) {
3544 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3545 } else if (rs != 0 && rt == 0) {
3546 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3547 } else {
3548 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3549 }
7a387fff
TS
3550 break;
3551 case OPC_DSUB:
48d38ca5 3552 {
460f00c4
AJ
3553 TCGv t0 = tcg_temp_local_new();
3554 TCGv t1 = tcg_temp_new();
3555 TCGv t2 = tcg_temp_new();
42a268c2 3556 TCGLabel *l1 = gen_new_label();
48d38ca5 3557
460f00c4
AJ
3558 gen_load_gpr(t1, rs);
3559 gen_load_gpr(t2, rt);
3560 tcg_gen_sub_tl(t0, t1, t2);
3561 tcg_gen_xor_tl(t2, t1, t2);
3562 tcg_gen_xor_tl(t1, t0, t1);
3563 tcg_gen_and_tl(t1, t1, t2);
3564 tcg_temp_free(t2);
3565 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3566 tcg_temp_free(t1);
31e3104f 3567 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
3568 generate_exception(ctx, EXCP_OVERFLOW);
3569 gen_set_label(l1);
460f00c4
AJ
3570 gen_store_gpr(t0, rd);
3571 tcg_temp_free(t0);
48d38ca5 3572 }
7a387fff
TS
3573 break;
3574 case OPC_DSUBU:
460f00c4
AJ
3575 if (rs != 0 && rt != 0) {
3576 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3577 } else if (rs == 0 && rt != 0) {
3578 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3579 } else if (rs != 0 && rt == 0) {
3580 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3581 } else {
3582 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3583 }
7a387fff
TS
3584 break;
3585#endif
460f00c4
AJ
3586 case OPC_MUL:
3587 if (likely(rs != 0 && rt != 0)) {
3588 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3589 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3590 } else {
3591 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3592 }
6af0bf9c 3593 break;
460f00c4 3594 }
460f00c4
AJ
3595}
3596
3597/* Conditional move */
d75c135e 3598static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 3599 int rd, int rs, int rt)
460f00c4 3600{
acf12465 3601 TCGv t0, t1, t2;
460f00c4
AJ
3602
3603 if (rd == 0) {
acf12465 3604 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3605 return;
3606 }
3607
acf12465
AJ
3608 t0 = tcg_temp_new();
3609 gen_load_gpr(t0, rt);
3610 t1 = tcg_const_tl(0);
3611 t2 = tcg_temp_new();
3612 gen_load_gpr(t2, rs);
460f00c4
AJ
3613 switch (opc) {
3614 case OPC_MOVN:
acf12465 3615 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 3616 break;
460f00c4 3617 case OPC_MOVZ:
acf12465 3618 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 3619 break;
b691d9d2
LA
3620 case OPC_SELNEZ:
3621 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
3622 break;
3623 case OPC_SELEQZ:
3624 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 3625 break;
460f00c4 3626 }
acf12465
AJ
3627 tcg_temp_free(t2);
3628 tcg_temp_free(t1);
3629 tcg_temp_free(t0);
460f00c4
AJ
3630}
3631
3632/* Logic */
d75c135e 3633static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 3634 int rd, int rs, int rt)
460f00c4 3635{
460f00c4
AJ
3636 if (rd == 0) {
3637 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3638 return;
3639 }
3640
3641 switch (opc) {
6af0bf9c 3642 case OPC_AND:
460f00c4
AJ
3643 if (likely(rs != 0 && rt != 0)) {
3644 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3645 } else {
3646 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3647 }
6af0bf9c
FB
3648 break;
3649 case OPC_NOR:
460f00c4
AJ
3650 if (rs != 0 && rt != 0) {
3651 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3652 } else if (rs == 0 && rt != 0) {
3653 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3654 } else if (rs != 0 && rt == 0) {
3655 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3656 } else {
3657 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3658 }
6af0bf9c
FB
3659 break;
3660 case OPC_OR:
460f00c4
AJ
3661 if (likely(rs != 0 && rt != 0)) {
3662 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3663 } else if (rs == 0 && rt != 0) {
3664 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3665 } else if (rs != 0 && rt == 0) {
3666 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3667 } else {
3668 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3669 }
6af0bf9c
FB
3670 break;
3671 case OPC_XOR:
460f00c4
AJ
3672 if (likely(rs != 0 && rt != 0)) {
3673 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3674 } else if (rs == 0 && rt != 0) {
3675 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3676 } else if (rs != 0 && rt == 0) {
3677 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3678 } else {
3679 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3680 }
6af0bf9c 3681 break;
460f00c4 3682 }
460f00c4
AJ
3683}
3684
3685/* Set on lower than */
d75c135e 3686static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 3687 int rd, int rs, int rt)
460f00c4 3688{
460f00c4
AJ
3689 TCGv t0, t1;
3690
3691 if (rd == 0) {
3692 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3693 return;
3694 }
3695
3696 t0 = tcg_temp_new();
3697 t1 = tcg_temp_new();
3698 gen_load_gpr(t0, rs);
3699 gen_load_gpr(t1, rt);
3700 switch (opc) {
3701 case OPC_SLT:
e68dd28f 3702 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 3703 break;
460f00c4 3704 case OPC_SLTU:
e68dd28f 3705 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3706 break;
3707 }
460f00c4
AJ
3708 tcg_temp_free(t0);
3709 tcg_temp_free(t1);
3710}
20c4c97c 3711
460f00c4 3712/* Shifts */
d75c135e
AJ
3713static void gen_shift(DisasContext *ctx, uint32_t opc,
3714 int rd, int rs, int rt)
460f00c4 3715{
460f00c4 3716 TCGv t0, t1;
20c4c97c 3717
460f00c4
AJ
3718 if (rd == 0) {
3719 /* If no destination, treat it as a NOP.
3720 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
3721 return;
3722 }
3723
3724 t0 = tcg_temp_new();
3725 t1 = tcg_temp_new();
3726 gen_load_gpr(t0, rs);
3727 gen_load_gpr(t1, rt);
3728 switch (opc) {
6af0bf9c 3729 case OPC_SLLV:
78723684
TS
3730 tcg_gen_andi_tl(t0, t0, 0x1f);
3731 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3732 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3733 break;
3734 case OPC_SRAV:
78723684 3735 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3736 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3737 break;
3738 case OPC_SRLV:
ea63e2c3
NF
3739 tcg_gen_ext32u_tl(t1, t1);
3740 tcg_gen_andi_tl(t0, t0, 0x1f);
3741 tcg_gen_shr_tl(t0, t1, t0);
3742 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
3743 break;
3744 case OPC_ROTRV:
3745 {
3746 TCGv_i32 t2 = tcg_temp_new_i32();
3747 TCGv_i32 t3 = tcg_temp_new_i32();
3748
3749 tcg_gen_trunc_tl_i32(t2, t0);
3750 tcg_gen_trunc_tl_i32(t3, t1);
3751 tcg_gen_andi_i32(t2, t2, 0x1f);
3752 tcg_gen_rotr_i32(t2, t3, t2);
3753 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3754 tcg_temp_free_i32(t2);
3755 tcg_temp_free_i32(t3);
5a63bcb2 3756 }
7a387fff 3757 break;
d26bc211 3758#if defined(TARGET_MIPS64)
7a387fff 3759 case OPC_DSLLV:
78723684 3760 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3761 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3762 break;
3763 case OPC_DSRAV:
78723684 3764 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3765 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3766 break;
3767 case OPC_DSRLV:
ea63e2c3
NF
3768 tcg_gen_andi_tl(t0, t0, 0x3f);
3769 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3770 break;
3771 case OPC_DROTRV:
3772 tcg_gen_andi_tl(t0, t0, 0x3f);
3773 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3774 break;
7a387fff 3775#endif
6af0bf9c 3776 }
78723684
TS
3777 tcg_temp_free(t0);
3778 tcg_temp_free(t1);
6af0bf9c
FB
3779}
3780
3781/* Arithmetic on HI/LO registers */
26135ead 3782static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3783{
6af0bf9c 3784 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3785 /* Treat as NOP. */
a1f6684d 3786 return;
6af0bf9c 3787 }
4133498f 3788
4133498f
JL
3789 if (acc != 0) {
3790 check_dsp(ctx);
3791 }
3792
6af0bf9c
FB
3793 switch (opc) {
3794 case OPC_MFHI:
4133498f
JL
3795#if defined(TARGET_MIPS64)
3796 if (acc != 0) {
3797 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3798 } else
3799#endif
3800 {
3801 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3802 }
6af0bf9c
FB
3803 break;
3804 case OPC_MFLO:
4133498f
JL
3805#if defined(TARGET_MIPS64)
3806 if (acc != 0) {
3807 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3808 } else
3809#endif
3810 {
3811 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3812 }
6af0bf9c
FB
3813 break;
3814 case OPC_MTHI:
4133498f
JL
3815 if (reg != 0) {
3816#if defined(TARGET_MIPS64)
3817 if (acc != 0) {
3818 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3819 } else
3820#endif
3821 {
3822 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3823 }
3824 } else {
3825 tcg_gen_movi_tl(cpu_HI[acc], 0);
3826 }
6af0bf9c
FB
3827 break;
3828 case OPC_MTLO:
4133498f
JL
3829 if (reg != 0) {
3830#if defined(TARGET_MIPS64)
3831 if (acc != 0) {
3832 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3833 } else
3834#endif
3835 {
3836 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3837 }
3838 } else {
3839 tcg_gen_movi_tl(cpu_LO[acc], 0);
3840 }
6af0bf9c 3841 break;
6af0bf9c 3842 }
6af0bf9c
FB
3843}
3844
d4ea6acd
LA
3845static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3846 TCGMemOp memop)
3847{
3848 TCGv t0 = tcg_const_tl(addr);
3849 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3850 gen_store_gpr(t0, reg);
3851 tcg_temp_free(t0);
3852}
3853
ab39ee45
YK
3854static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3855 int rs)
d4ea6acd
LA
3856{
3857 target_long offset;
3858 target_long addr;
3859
ab39ee45 3860 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3861 case OPC_ADDIUPC:
3862 if (rs != 0) {
3863 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3864 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3865 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3866 }
3867 break;
3868 case R6_OPC_LWPC:
3869 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3870 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3871 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3872 break;
3873#if defined(TARGET_MIPS64)
3874 case OPC_LWUPC:
3875 check_mips_64(ctx);
3876 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3877 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3878 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3879 break;
3880#endif
3881 default:
ab39ee45 3882 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3883 case OPC_AUIPC:
3884 if (rs != 0) {
ab39ee45
YK
3885 offset = sextract32(ctx->opcode, 0, 16) << 16;
3886 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3887 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3888 }
3889 break;
3890 case OPC_ALUIPC:
3891 if (rs != 0) {
ab39ee45
YK
3892 offset = sextract32(ctx->opcode, 0, 16) << 16;
3893 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3894 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3895 }
3896 break;
3897#if defined(TARGET_MIPS64)
3898 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3899 case R6_OPC_LDPC + (1 << 16):
3900 case R6_OPC_LDPC + (2 << 16):
3901 case R6_OPC_LDPC + (3 << 16):
3902 check_mips_64(ctx);
3903 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3904 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3905 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3906 break;
3907#endif
3908 default:
3909 MIPS_INVAL("OPC_PCREL");
9c708c7f 3910 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3911 break;
3912 }
3913 break;
3914 }
3915}
3916
b42ee5e1
LA
3917static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3918{
b42ee5e1
LA
3919 TCGv t0, t1;
3920
3921 if (rd == 0) {
3922 /* Treat as NOP. */
b42ee5e1
LA
3923 return;
3924 }
3925
3926 t0 = tcg_temp_new();
3927 t1 = tcg_temp_new();
3928
3929 gen_load_gpr(t0, rs);
3930 gen_load_gpr(t1, rt);
3931
3932 switch (opc) {
3933 case R6_OPC_DIV:
3934 {
3935 TCGv t2 = tcg_temp_new();
3936 TCGv t3 = tcg_temp_new();
3937 tcg_gen_ext32s_tl(t0, t0);
3938 tcg_gen_ext32s_tl(t1, t1);
3939 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3940 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3941 tcg_gen_and_tl(t2, t2, t3);
3942 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3943 tcg_gen_or_tl(t2, t2, t3);
3944 tcg_gen_movi_tl(t3, 0);
3945 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3946 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3947 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3948 tcg_temp_free(t3);
3949 tcg_temp_free(t2);
3950 }
b42ee5e1
LA
3951 break;
3952 case R6_OPC_MOD:
3953 {
3954 TCGv t2 = tcg_temp_new();
3955 TCGv t3 = tcg_temp_new();
3956 tcg_gen_ext32s_tl(t0, t0);
3957 tcg_gen_ext32s_tl(t1, t1);
3958 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3959 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3960 tcg_gen_and_tl(t2, t2, t3);
3961 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3962 tcg_gen_or_tl(t2, t2, t3);
3963 tcg_gen_movi_tl(t3, 0);
3964 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3965 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3966 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3967 tcg_temp_free(t3);
3968 tcg_temp_free(t2);
3969 }
b42ee5e1
LA
3970 break;
3971 case R6_OPC_DIVU:
3972 {
3973 TCGv t2 = tcg_const_tl(0);
3974 TCGv t3 = tcg_const_tl(1);
3975 tcg_gen_ext32u_tl(t0, t0);
3976 tcg_gen_ext32u_tl(t1, t1);
3977 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3978 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3979 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3980 tcg_temp_free(t3);
3981 tcg_temp_free(t2);
3982 }
b42ee5e1
LA
3983 break;
3984 case R6_OPC_MODU:
3985 {
3986 TCGv t2 = tcg_const_tl(0);
3987 TCGv t3 = tcg_const_tl(1);
3988 tcg_gen_ext32u_tl(t0, t0);
3989 tcg_gen_ext32u_tl(t1, t1);
3990 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3991 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3992 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3993 tcg_temp_free(t3);
3994 tcg_temp_free(t2);
3995 }
b42ee5e1
LA
3996 break;
3997 case R6_OPC_MUL:
3998 {
3999 TCGv_i32 t2 = tcg_temp_new_i32();
4000 TCGv_i32 t3 = tcg_temp_new_i32();
4001 tcg_gen_trunc_tl_i32(t2, t0);
4002 tcg_gen_trunc_tl_i32(t3, t1);
4003 tcg_gen_mul_i32(t2, t2, t3);
4004 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4005 tcg_temp_free_i32(t2);
4006 tcg_temp_free_i32(t3);
4007 }
b42ee5e1
LA
4008 break;
4009 case R6_OPC_MUH:
4010 {
4011 TCGv_i32 t2 = tcg_temp_new_i32();
4012 TCGv_i32 t3 = tcg_temp_new_i32();
4013 tcg_gen_trunc_tl_i32(t2, t0);
4014 tcg_gen_trunc_tl_i32(t3, t1);
4015 tcg_gen_muls2_i32(t2, t3, t2, t3);
4016 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4017 tcg_temp_free_i32(t2);
4018 tcg_temp_free_i32(t3);
4019 }
b42ee5e1
LA
4020 break;
4021 case R6_OPC_MULU:
4022 {
4023 TCGv_i32 t2 = tcg_temp_new_i32();
4024 TCGv_i32 t3 = tcg_temp_new_i32();
4025 tcg_gen_trunc_tl_i32(t2, t0);
4026 tcg_gen_trunc_tl_i32(t3, t1);
4027 tcg_gen_mul_i32(t2, t2, t3);
4028 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4029 tcg_temp_free_i32(t2);
4030 tcg_temp_free_i32(t3);
4031 }
b42ee5e1
LA
4032 break;
4033 case R6_OPC_MUHU:
4034 {
4035 TCGv_i32 t2 = tcg_temp_new_i32();
4036 TCGv_i32 t3 = tcg_temp_new_i32();
4037 tcg_gen_trunc_tl_i32(t2, t0);
4038 tcg_gen_trunc_tl_i32(t3, t1);
4039 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4040 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4041 tcg_temp_free_i32(t2);
4042 tcg_temp_free_i32(t3);
4043 }
b42ee5e1
LA
4044 break;
4045#if defined(TARGET_MIPS64)
4046 case R6_OPC_DDIV:
4047 {
4048 TCGv t2 = tcg_temp_new();
4049 TCGv t3 = tcg_temp_new();
4050 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4051 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4052 tcg_gen_and_tl(t2, t2, t3);
4053 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4054 tcg_gen_or_tl(t2, t2, t3);
4055 tcg_gen_movi_tl(t3, 0);
4056 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4057 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4058 tcg_temp_free(t3);
4059 tcg_temp_free(t2);
4060 }
b42ee5e1
LA
4061 break;
4062 case R6_OPC_DMOD:
4063 {
4064 TCGv t2 = tcg_temp_new();
4065 TCGv t3 = tcg_temp_new();
4066 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4067 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4068 tcg_gen_and_tl(t2, t2, t3);
4069 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4070 tcg_gen_or_tl(t2, t2, t3);
4071 tcg_gen_movi_tl(t3, 0);
4072 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4073 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4074 tcg_temp_free(t3);
4075 tcg_temp_free(t2);
4076 }
b42ee5e1
LA
4077 break;
4078 case R6_OPC_DDIVU:
4079 {
4080 TCGv t2 = tcg_const_tl(0);
4081 TCGv t3 = tcg_const_tl(1);
4082 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4083 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4084 tcg_temp_free(t3);
4085 tcg_temp_free(t2);
4086 }
b42ee5e1
LA
4087 break;
4088 case R6_OPC_DMODU:
4089 {
4090 TCGv t2 = tcg_const_tl(0);
4091 TCGv t3 = tcg_const_tl(1);
4092 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4093 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4094 tcg_temp_free(t3);
4095 tcg_temp_free(t2);
4096 }
b42ee5e1
LA
4097 break;
4098 case R6_OPC_DMUL:
4099 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4100 break;
4101 case R6_OPC_DMUH:
4102 {
4103 TCGv t2 = tcg_temp_new();
4104 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4105 tcg_temp_free(t2);
4106 }
b42ee5e1
LA
4107 break;
4108 case R6_OPC_DMULU:
4109 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4110 break;
4111 case R6_OPC_DMUHU:
4112 {
4113 TCGv t2 = tcg_temp_new();
4114 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4115 tcg_temp_free(t2);
4116 }
b42ee5e1
LA
4117 break;
4118#endif
4119 default:
9d68ac14 4120 MIPS_INVAL("r6 mul/div");
9c708c7f 4121 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
4122 goto out;
4123 }
b42ee5e1
LA
4124 out:
4125 tcg_temp_free(t0);
4126 tcg_temp_free(t1);
4127}
4128
26135ead
RS
4129static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4130 int acc, int rs, int rt)
6af0bf9c 4131{
d45f89f4
AJ
4132 TCGv t0, t1;
4133
51127181
AJ
4134 t0 = tcg_temp_new();
4135 t1 = tcg_temp_new();
6af0bf9c 4136
78723684
TS
4137 gen_load_gpr(t0, rs);
4138 gen_load_gpr(t1, rt);
51127181 4139
26135ead
RS
4140 if (acc != 0) {
4141 check_dsp(ctx);
4142 }
4143
6af0bf9c
FB
4144 switch (opc) {
4145 case OPC_DIV:
48d38ca5 4146 {
51127181
AJ
4147 TCGv t2 = tcg_temp_new();
4148 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4149 tcg_gen_ext32s_tl(t0, t0);
4150 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4151 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4152 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4153 tcg_gen_and_tl(t2, t2, t3);
4154 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4155 tcg_gen_or_tl(t2, t2, t3);
4156 tcg_gen_movi_tl(t3, 0);
4157 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4158 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4159 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4160 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4161 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4162 tcg_temp_free(t3);
4163 tcg_temp_free(t2);
48d38ca5 4164 }
6af0bf9c
FB
4165 break;
4166 case OPC_DIVU:
48d38ca5 4167 {
51127181
AJ
4168 TCGv t2 = tcg_const_tl(0);
4169 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4170 tcg_gen_ext32u_tl(t0, t0);
4171 tcg_gen_ext32u_tl(t1, t1);
51127181 4172 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4173 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4174 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4175 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4176 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4177 tcg_temp_free(t3);
4178 tcg_temp_free(t2);
48d38ca5 4179 }
6af0bf9c
FB
4180 break;
4181 case OPC_MULT:
214c465f 4182 {
ce1dd5d1
RH
4183 TCGv_i32 t2 = tcg_temp_new_i32();
4184 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4185 tcg_gen_trunc_tl_i32(t2, t0);
4186 tcg_gen_trunc_tl_i32(t3, t1);
4187 tcg_gen_muls2_i32(t2, t3, t2, t3);
4188 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4189 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4190 tcg_temp_free_i32(t2);
4191 tcg_temp_free_i32(t3);
214c465f 4192 }
6af0bf9c
FB
4193 break;
4194 case OPC_MULTU:
214c465f 4195 {
ce1dd5d1
RH
4196 TCGv_i32 t2 = tcg_temp_new_i32();
4197 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4198 tcg_gen_trunc_tl_i32(t2, t0);
4199 tcg_gen_trunc_tl_i32(t3, t1);
4200 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4201 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4202 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4203 tcg_temp_free_i32(t2);
4204 tcg_temp_free_i32(t3);
214c465f 4205 }
6af0bf9c 4206 break;
d26bc211 4207#if defined(TARGET_MIPS64)
7a387fff 4208 case OPC_DDIV:
48d38ca5 4209 {
51127181
AJ
4210 TCGv t2 = tcg_temp_new();
4211 TCGv t3 = tcg_temp_new();
4212 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4213 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4214 tcg_gen_and_tl(t2, t2, t3);
4215 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4216 tcg_gen_or_tl(t2, t2, t3);
4217 tcg_gen_movi_tl(t3, 0);
4218 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4219 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4220 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4221 tcg_temp_free(t3);
4222 tcg_temp_free(t2);
48d38ca5 4223 }
7a387fff
TS
4224 break;
4225 case OPC_DDIVU:
48d38ca5 4226 {
51127181
AJ
4227 TCGv t2 = tcg_const_tl(0);
4228 TCGv t3 = tcg_const_tl(1);
4229 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4230 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4231 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4232 tcg_temp_free(t3);
4233 tcg_temp_free(t2);
48d38ca5 4234 }
7a387fff
TS
4235 break;
4236 case OPC_DMULT:
26135ead 4237 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4238 break;
4239 case OPC_DMULTU:
26135ead 4240 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4241 break;
4242#endif
6af0bf9c 4243 case OPC_MADD:
214c465f 4244 {
d45f89f4
AJ
4245 TCGv_i64 t2 = tcg_temp_new_i64();
4246 TCGv_i64 t3 = tcg_temp_new_i64();
4247
4248 tcg_gen_ext_tl_i64(t2, t0);
4249 tcg_gen_ext_tl_i64(t3, t1);
4250 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4251 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4252 tcg_gen_add_i64(t2, t2, t3);
4253 tcg_temp_free_i64(t3);
71f303cd
RH
4254 gen_move_low32(cpu_LO[acc], t2);
4255 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4256 tcg_temp_free_i64(t2);
214c465f 4257 }
6af0bf9c
FB
4258 break;
4259 case OPC_MADDU:
4133498f 4260 {
d45f89f4
AJ
4261 TCGv_i64 t2 = tcg_temp_new_i64();
4262 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4263
78723684
TS
4264 tcg_gen_ext32u_tl(t0, t0);
4265 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4266 tcg_gen_extu_tl_i64(t2, t0);
4267 tcg_gen_extu_tl_i64(t3, t1);
4268 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4269 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4270 tcg_gen_add_i64(t2, t2, t3);
4271 tcg_temp_free_i64(t3);
71f303cd
RH
4272 gen_move_low32(cpu_LO[acc], t2);
4273 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4274 tcg_temp_free_i64(t2);
214c465f 4275 }
6af0bf9c
FB
4276 break;
4277 case OPC_MSUB:
214c465f 4278 {
d45f89f4
AJ
4279 TCGv_i64 t2 = tcg_temp_new_i64();
4280 TCGv_i64 t3 = tcg_temp_new_i64();
4281
4282 tcg_gen_ext_tl_i64(t2, t0);
4283 tcg_gen_ext_tl_i64(t3, t1);
4284 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4285 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4286 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4287 tcg_temp_free_i64(t3);
71f303cd
RH
4288 gen_move_low32(cpu_LO[acc], t2);
4289 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4290 tcg_temp_free_i64(t2);
214c465f 4291 }
6af0bf9c
FB
4292 break;
4293 case OPC_MSUBU:
214c465f 4294 {
d45f89f4
AJ
4295 TCGv_i64 t2 = tcg_temp_new_i64();
4296 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4297
78723684
TS
4298 tcg_gen_ext32u_tl(t0, t0);
4299 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4300 tcg_gen_extu_tl_i64(t2, t0);
4301 tcg_gen_extu_tl_i64(t3, t1);
4302 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4303 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4304 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4305 tcg_temp_free_i64(t3);
71f303cd
RH
4306 gen_move_low32(cpu_LO[acc], t2);
4307 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4308 tcg_temp_free_i64(t2);
214c465f 4309 }
6af0bf9c
FB
4310 break;
4311 default:
9d68ac14 4312 MIPS_INVAL("mul/div");
9c708c7f 4313 generate_exception_end(ctx, EXCP_RI);
78723684 4314 goto out;
6af0bf9c 4315 }
78723684
TS
4316 out:
4317 tcg_temp_free(t0);
4318 tcg_temp_free(t1);
6af0bf9c
FB
4319}
4320
e9c71dd1
TS
4321static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4322 int rd, int rs, int rt)
4323{
f157bfe1
AJ
4324 TCGv t0 = tcg_temp_new();
4325 TCGv t1 = tcg_temp_new();
e9c71dd1 4326
6c5c1e20
TS
4327 gen_load_gpr(t0, rs);
4328 gen_load_gpr(t1, rt);
e9c71dd1
TS
4329
4330 switch (opc) {
4331 case OPC_VR54XX_MULS:
895c2d04 4332 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 4333 break;
e9c71dd1 4334 case OPC_VR54XX_MULSU:
895c2d04 4335 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 4336 break;
e9c71dd1 4337 case OPC_VR54XX_MACC:
895c2d04 4338 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 4339 break;
e9c71dd1 4340 case OPC_VR54XX_MACCU:
895c2d04 4341 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 4342 break;
e9c71dd1 4343 case OPC_VR54XX_MSAC:
895c2d04 4344 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 4345 break;
e9c71dd1 4346 case OPC_VR54XX_MSACU:
895c2d04 4347 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 4348 break;
e9c71dd1 4349 case OPC_VR54XX_MULHI:
895c2d04 4350 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 4351 break;
e9c71dd1 4352 case OPC_VR54XX_MULHIU:
895c2d04 4353 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 4354 break;
e9c71dd1 4355 case OPC_VR54XX_MULSHI:
895c2d04 4356 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 4357 break;
e9c71dd1 4358 case OPC_VR54XX_MULSHIU:
895c2d04 4359 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 4360 break;
e9c71dd1 4361 case OPC_VR54XX_MACCHI:
895c2d04 4362 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 4363 break;
e9c71dd1 4364 case OPC_VR54XX_MACCHIU:
895c2d04 4365 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 4366 break;
e9c71dd1 4367 case OPC_VR54XX_MSACHI:
895c2d04 4368 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 4369 break;
e9c71dd1 4370 case OPC_VR54XX_MSACHIU:
895c2d04 4371 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 4372 break;
e9c71dd1
TS
4373 default:
4374 MIPS_INVAL("mul vr54xx");
9c708c7f 4375 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4376 goto out;
e9c71dd1 4377 }
6c5c1e20 4378 gen_store_gpr(t0, rd);
6c5c1e20
TS
4379
4380 out:
4381 tcg_temp_free(t0);
4382 tcg_temp_free(t1);
e9c71dd1
TS
4383}
4384
7a387fff 4385static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4386 int rd, int rs)
4387{
20e1fb52 4388 TCGv t0;
6c5c1e20 4389
6af0bf9c 4390 if (rd == 0) {
ead9360e 4391 /* Treat as NOP. */
20e1fb52 4392 return;
6af0bf9c 4393 }
1a0196c5 4394 t0 = cpu_gpr[rd];
6c5c1e20 4395 gen_load_gpr(t0, rs);
1a0196c5 4396
6af0bf9c
FB
4397 switch (opc) {
4398 case OPC_CLO:
4267d3e6 4399 case R6_OPC_CLO:
1a0196c5
RH
4400#if defined(TARGET_MIPS64)
4401 case OPC_DCLO:
4402 case R6_OPC_DCLO:
4403#endif
4404 tcg_gen_not_tl(t0, t0);
6af0bf9c 4405 break;
1a0196c5
RH
4406 }
4407
4408 switch (opc) {
4409 case OPC_CLO:
4410 case R6_OPC_CLO:
6af0bf9c 4411 case OPC_CLZ:
4267d3e6 4412 case R6_OPC_CLZ:
1a0196c5
RH
4413 tcg_gen_ext32u_tl(t0, t0);
4414 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4415 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 4416 break;
d26bc211 4417#if defined(TARGET_MIPS64)
7a387fff 4418 case OPC_DCLO:
4267d3e6 4419 case R6_OPC_DCLO:
7a387fff 4420 case OPC_DCLZ:
4267d3e6 4421 case R6_OPC_DCLZ:
1a0196c5 4422 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
4423 break;
4424#endif
6af0bf9c 4425 }
6af0bf9c
FB
4426}
4427
161f85e6 4428/* Godson integer instructions */
bd277fa1
RH
4429static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4430 int rd, int rs, int rt)
161f85e6 4431{
161f85e6
AJ
4432 TCGv t0, t1;
4433
4434 if (rd == 0) {
4435 /* Treat as NOP. */
161f85e6
AJ
4436 return;
4437 }
4438
4439 switch (opc) {
4440 case OPC_MULT_G_2E:
4441 case OPC_MULT_G_2F:
4442 case OPC_MULTU_G_2E:
4443 case OPC_MULTU_G_2F:
4444#if defined(TARGET_MIPS64)
4445 case OPC_DMULT_G_2E:
4446 case OPC_DMULT_G_2F:
4447 case OPC_DMULTU_G_2E:
4448 case OPC_DMULTU_G_2F:
4449#endif
4450 t0 = tcg_temp_new();
4451 t1 = tcg_temp_new();
4452 break;
4453 default:
4454 t0 = tcg_temp_local_new();
4455 t1 = tcg_temp_local_new();
4456 break;
4457 }
4458
4459 gen_load_gpr(t0, rs);
4460 gen_load_gpr(t1, rt);
4461
4462 switch (opc) {
4463 case OPC_MULT_G_2E:
4464 case OPC_MULT_G_2F:
4465 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4466 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
4467 break;
4468 case OPC_MULTU_G_2E:
4469 case OPC_MULTU_G_2F:
4470 tcg_gen_ext32u_tl(t0, t0);
4471 tcg_gen_ext32u_tl(t1, t1);
4472 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4473 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
4474 break;
4475 case OPC_DIV_G_2E:
4476 case OPC_DIV_G_2F:
4477 {
42a268c2
RH
4478 TCGLabel *l1 = gen_new_label();
4479 TCGLabel *l2 = gen_new_label();
4480 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4481 tcg_gen_ext32s_tl(t0, t0);
4482 tcg_gen_ext32s_tl(t1, t1);
4483 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4484 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4485 tcg_gen_br(l3);
4486 gen_set_label(l1);
4487 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4488 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4489 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4490 tcg_gen_br(l3);
4491 gen_set_label(l2);
4492 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4493 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4494 gen_set_label(l3);
4495 }
161f85e6
AJ
4496 break;
4497 case OPC_DIVU_G_2E:
4498 case OPC_DIVU_G_2F:
4499 {
42a268c2
RH
4500 TCGLabel *l1 = gen_new_label();
4501 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4502 tcg_gen_ext32u_tl(t0, t0);
4503 tcg_gen_ext32u_tl(t1, t1);
4504 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4505 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4506 tcg_gen_br(l2);
4507 gen_set_label(l1);
4508 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4509 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4510 gen_set_label(l2);
4511 }
161f85e6
AJ
4512 break;
4513 case OPC_MOD_G_2E:
4514 case OPC_MOD_G_2F:
4515 {
42a268c2
RH
4516 TCGLabel *l1 = gen_new_label();
4517 TCGLabel *l2 = gen_new_label();
4518 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4519 tcg_gen_ext32u_tl(t0, t0);
4520 tcg_gen_ext32u_tl(t1, t1);
4521 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4522 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4523 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4524 gen_set_label(l1);
4525 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4526 tcg_gen_br(l3);
4527 gen_set_label(l2);
4528 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4529 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4530 gen_set_label(l3);
4531 }
161f85e6
AJ
4532 break;
4533 case OPC_MODU_G_2E:
4534 case OPC_MODU_G_2F:
4535 {
42a268c2
RH
4536 TCGLabel *l1 = gen_new_label();
4537 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4538 tcg_gen_ext32u_tl(t0, t0);
4539 tcg_gen_ext32u_tl(t1, t1);
4540 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4541 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4542 tcg_gen_br(l2);
4543 gen_set_label(l1);
4544 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4545 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4546 gen_set_label(l2);
4547 }
161f85e6
AJ
4548 break;
4549#if defined(TARGET_MIPS64)
4550 case OPC_DMULT_G_2E:
4551 case OPC_DMULT_G_2F:
4552 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
4553 break;
4554 case OPC_DMULTU_G_2E:
4555 case OPC_DMULTU_G_2F:
4556 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
4557 break;
4558 case OPC_DDIV_G_2E:
4559 case OPC_DDIV_G_2F:
4560 {
42a268c2
RH
4561 TCGLabel *l1 = gen_new_label();
4562 TCGLabel *l2 = gen_new_label();
4563 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4564 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4565 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4566 tcg_gen_br(l3);
4567 gen_set_label(l1);
4568 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4569 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4570 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4571 tcg_gen_br(l3);
4572 gen_set_label(l2);
4573 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4574 gen_set_label(l3);
4575 }
161f85e6
AJ
4576 break;
4577 case OPC_DDIVU_G_2E:
4578 case OPC_DDIVU_G_2F:
4579 {
42a268c2
RH
4580 TCGLabel *l1 = gen_new_label();
4581 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4582 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4583 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4584 tcg_gen_br(l2);
4585 gen_set_label(l1);
4586 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4587 gen_set_label(l2);
4588 }
161f85e6
AJ
4589 break;
4590 case OPC_DMOD_G_2E:
4591 case OPC_DMOD_G_2F:
4592 {
42a268c2
RH
4593 TCGLabel *l1 = gen_new_label();
4594 TCGLabel *l2 = gen_new_label();
4595 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4596 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4597 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4598 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4599 gen_set_label(l1);
4600 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4601 tcg_gen_br(l3);
4602 gen_set_label(l2);
4603 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4604 gen_set_label(l3);
4605 }
161f85e6
AJ
4606 break;
4607 case OPC_DMODU_G_2E:
4608 case OPC_DMODU_G_2F:
4609 {
42a268c2
RH
4610 TCGLabel *l1 = gen_new_label();
4611 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4612 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4613 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4614 tcg_gen_br(l2);
4615 gen_set_label(l1);
4616 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4617 gen_set_label(l2);
4618 }
161f85e6
AJ
4619 break;
4620#endif
4621 }
4622
161f85e6
AJ
4623 tcg_temp_free(t0);
4624 tcg_temp_free(t1);
4625}
4626
bd277fa1
RH
4627/* Loongson multimedia instructions */
4628static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4629{
bd277fa1
RH
4630 uint32_t opc, shift_max;
4631 TCGv_i64 t0, t1;
4632
4633 opc = MASK_LMI(ctx->opcode);
4634 switch (opc) {
4635 case OPC_ADD_CP2:
4636 case OPC_SUB_CP2:
4637 case OPC_DADD_CP2:
4638 case OPC_DSUB_CP2:
4639 t0 = tcg_temp_local_new_i64();
4640 t1 = tcg_temp_local_new_i64();
4641 break;
4642 default:
4643 t0 = tcg_temp_new_i64();
4644 t1 = tcg_temp_new_i64();
4645 break;
4646 }
4647
b5a587b6 4648 check_cp1_enabled(ctx);
bd277fa1
RH
4649 gen_load_fpr64(ctx, t0, rs);
4650 gen_load_fpr64(ctx, t1, rt);
4651
4652#define LMI_HELPER(UP, LO) \
9d68ac14 4653 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 4654#define LMI_HELPER_1(UP, LO) \
9d68ac14 4655 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 4656#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 4657 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
4658
4659 switch (opc) {
4660 LMI_HELPER(PADDSH, paddsh);
4661 LMI_HELPER(PADDUSH, paddush);
4662 LMI_HELPER(PADDH, paddh);
4663 LMI_HELPER(PADDW, paddw);
4664 LMI_HELPER(PADDSB, paddsb);
4665 LMI_HELPER(PADDUSB, paddusb);
4666 LMI_HELPER(PADDB, paddb);
4667
4668 LMI_HELPER(PSUBSH, psubsh);
4669 LMI_HELPER(PSUBUSH, psubush);
4670 LMI_HELPER(PSUBH, psubh);
4671 LMI_HELPER(PSUBW, psubw);
4672 LMI_HELPER(PSUBSB, psubsb);
4673 LMI_HELPER(PSUBUSB, psubusb);
4674 LMI_HELPER(PSUBB, psubb);
4675
4676 LMI_HELPER(PSHUFH, pshufh);
4677 LMI_HELPER(PACKSSWH, packsswh);
4678 LMI_HELPER(PACKSSHB, packsshb);
4679 LMI_HELPER(PACKUSHB, packushb);
4680
4681 LMI_HELPER(PUNPCKLHW, punpcklhw);
4682 LMI_HELPER(PUNPCKHHW, punpckhhw);
4683 LMI_HELPER(PUNPCKLBH, punpcklbh);
4684 LMI_HELPER(PUNPCKHBH, punpckhbh);
4685 LMI_HELPER(PUNPCKLWD, punpcklwd);
4686 LMI_HELPER(PUNPCKHWD, punpckhwd);
4687
4688 LMI_HELPER(PAVGH, pavgh);
4689 LMI_HELPER(PAVGB, pavgb);
4690 LMI_HELPER(PMAXSH, pmaxsh);
4691 LMI_HELPER(PMINSH, pminsh);
4692 LMI_HELPER(PMAXUB, pmaxub);
4693 LMI_HELPER(PMINUB, pminub);
4694
4695 LMI_HELPER(PCMPEQW, pcmpeqw);
4696 LMI_HELPER(PCMPGTW, pcmpgtw);
4697 LMI_HELPER(PCMPEQH, pcmpeqh);
4698 LMI_HELPER(PCMPGTH, pcmpgth);
4699 LMI_HELPER(PCMPEQB, pcmpeqb);
4700 LMI_HELPER(PCMPGTB, pcmpgtb);
4701
4702 LMI_HELPER(PSLLW, psllw);
4703 LMI_HELPER(PSLLH, psllh);
4704 LMI_HELPER(PSRLW, psrlw);
4705 LMI_HELPER(PSRLH, psrlh);
4706 LMI_HELPER(PSRAW, psraw);
4707 LMI_HELPER(PSRAH, psrah);
4708
4709 LMI_HELPER(PMULLH, pmullh);
4710 LMI_HELPER(PMULHH, pmulhh);
4711 LMI_HELPER(PMULHUH, pmulhuh);
4712 LMI_HELPER(PMADDHW, pmaddhw);
4713
4714 LMI_HELPER(PASUBUB, pasubub);
4715 LMI_HELPER_1(BIADD, biadd);
4716 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4717
4718 LMI_DIRECT(PADDD, paddd, add);
4719 LMI_DIRECT(PSUBD, psubd, sub);
4720 LMI_DIRECT(XOR_CP2, xor, xor);
4721 LMI_DIRECT(NOR_CP2, nor, nor);
4722 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 4723 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 4724
9099a36b
H
4725 case OPC_PANDN:
4726 tcg_gen_andc_i64(t0, t1, t0);
4727 break;
4728
bd277fa1
RH
4729 case OPC_PINSRH_0:
4730 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4731 break;
4732 case OPC_PINSRH_1:
4733 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4734 break;
4735 case OPC_PINSRH_2:
4736 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4737 break;
4738 case OPC_PINSRH_3:
4739 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4740 break;
4741
4742 case OPC_PEXTRH:
4743 tcg_gen_andi_i64(t1, t1, 3);
4744 tcg_gen_shli_i64(t1, t1, 4);
4745 tcg_gen_shr_i64(t0, t0, t1);
4746 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4747 break;
4748
4749 case OPC_ADDU_CP2:
4750 tcg_gen_add_i64(t0, t0, t1);
4751 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4752 break;
4753 case OPC_SUBU_CP2:
4754 tcg_gen_sub_i64(t0, t0, t1);
4755 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4756 break;
4757
4758 case OPC_SLL_CP2:
bd277fa1
RH
4759 shift_max = 32;
4760 goto do_shift;
4761 case OPC_SRL_CP2:
bd277fa1
RH
4762 shift_max = 32;
4763 goto do_shift;
4764 case OPC_SRA_CP2:
bd277fa1
RH
4765 shift_max = 32;
4766 goto do_shift;
4767 case OPC_DSLL_CP2:
bd277fa1
RH
4768 shift_max = 64;
4769 goto do_shift;
4770 case OPC_DSRL_CP2:
bd277fa1
RH
4771 shift_max = 64;
4772 goto do_shift;
4773 case OPC_DSRA_CP2:
bd277fa1
RH
4774 shift_max = 64;
4775 goto do_shift;
4776 do_shift:
4777 /* Make sure shift count isn't TCG undefined behaviour. */
4778 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4779
4780 switch (opc) {
4781 case OPC_SLL_CP2:
4782 case OPC_DSLL_CP2:
4783 tcg_gen_shl_i64(t0, t0, t1);
4784 break;
4785 case OPC_SRA_CP2:
4786 case OPC_DSRA_CP2:
4787 /* Since SRA is UndefinedResult without sign-extended inputs,
4788 we can treat SRA and DSRA the same. */
4789 tcg_gen_sar_i64(t0, t0, t1);
4790 break;
4791 case OPC_SRL_CP2:
4792 /* We want to shift in zeros for SRL; zero-extend first. */
4793 tcg_gen_ext32u_i64(t0, t0);
4794 /* FALLTHRU */
4795 case OPC_DSRL_CP2:
4796 tcg_gen_shr_i64(t0, t0, t1);
4797 break;
4798 }
4799
4800 if (shift_max == 32) {
4801 tcg_gen_ext32s_i64(t0, t0);
4802 }
4803
4804 /* Shifts larger than MAX produce zero. */
4805 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4806 tcg_gen_neg_i64(t1, t1);
4807 tcg_gen_and_i64(t0, t0, t1);
4808 break;
4809
4810 case OPC_ADD_CP2:
4811 case OPC_DADD_CP2:
4812 {
4813 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4814 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4815
4816 tcg_gen_mov_i64(t2, t0);
4817 tcg_gen_add_i64(t0, t1, t2);
4818 if (opc == OPC_ADD_CP2) {
4819 tcg_gen_ext32s_i64(t0, t0);
4820 }
4821 tcg_gen_xor_i64(t1, t1, t2);
4822 tcg_gen_xor_i64(t2, t2, t0);
4823 tcg_gen_andc_i64(t1, t2, t1);
4824 tcg_temp_free_i64(t2);
4825 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4826 generate_exception(ctx, EXCP_OVERFLOW);
4827 gen_set_label(lab);
bd277fa1
RH
4828 break;
4829 }
4830
4831 case OPC_SUB_CP2:
4832 case OPC_DSUB_CP2:
4833 {
4834 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4835 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4836
4837 tcg_gen_mov_i64(t2, t0);
4838 tcg_gen_sub_i64(t0, t1, t2);
4839 if (opc == OPC_SUB_CP2) {
4840 tcg_gen_ext32s_i64(t0, t0);
4841 }
4842 tcg_gen_xor_i64(t1, t1, t2);
4843 tcg_gen_xor_i64(t2, t2, t0);
4844 tcg_gen_and_i64(t1, t1, t2);
4845 tcg_temp_free_i64(t2);
4846 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4847 generate_exception(ctx, EXCP_OVERFLOW);
4848 gen_set_label(lab);
bd277fa1
RH
4849 break;
4850 }
4851
4852 case OPC_PMULUW:
4853 tcg_gen_ext32u_i64(t0, t0);
4854 tcg_gen_ext32u_i64(t1, t1);
4855 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4856 break;
4857
4858 case OPC_SEQU_CP2:
4859 case OPC_SEQ_CP2:
4860 case OPC_SLTU_CP2:
4861 case OPC_SLT_CP2:
4862 case OPC_SLEU_CP2:
4863 case OPC_SLE_CP2:
4864 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4865 FD field is the CC field? */
4866 default:
9d68ac14 4867 MIPS_INVAL("loongson_cp2");
9c708c7f 4868 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4869 return;
4870 }
4871
4872#undef LMI_HELPER
4873#undef LMI_DIRECT
4874
4875 gen_store_fpr64(ctx, t0, rd);
4876
bd277fa1
RH
4877 tcg_temp_free_i64(t0);
4878 tcg_temp_free_i64(t1);
4879}
4880
6af0bf9c 4881/* Traps */
7a387fff 4882static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4883 int rs, int rt, int16_t imm)
4884{
4885 int cond;
cdc0faa6 4886 TCGv t0 = tcg_temp_new();
1ba74fb8 4887 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4888
4889 cond = 0;
4890 /* Load needed operands */
4891 switch (opc) {
4892 case OPC_TEQ:
4893 case OPC_TGE:
4894 case OPC_TGEU:
4895 case OPC_TLT:
4896 case OPC_TLTU:
4897 case OPC_TNE:
4898 /* Compare two registers */
4899 if (rs != rt) {
be24bb4f
TS
4900 gen_load_gpr(t0, rs);
4901 gen_load_gpr(t1, rt);
6af0bf9c
FB
4902 cond = 1;
4903 }
179e32bb 4904 break;
6af0bf9c
FB
4905 case OPC_TEQI:
4906 case OPC_TGEI:
4907 case OPC_TGEIU:
4908 case OPC_TLTI:
4909 case OPC_TLTIU:
4910 case OPC_TNEI:
4911 /* Compare register to immediate */
4912 if (rs != 0 || imm != 0) {
be24bb4f
TS
4913 gen_load_gpr(t0, rs);
4914 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4915 cond = 1;
4916 }
4917 break;
4918 }
4919 if (cond == 0) {
4920 switch (opc) {
4921 case OPC_TEQ: /* rs == rs */
4922 case OPC_TEQI: /* r0 == 0 */
4923 case OPC_TGE: /* rs >= rs */
4924 case OPC_TGEI: /* r0 >= 0 */
4925 case OPC_TGEU: /* rs >= rs unsigned */
4926 case OPC_TGEIU: /* r0 >= 0 unsigned */
4927 /* Always trap */
9c708c7f 4928 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4929 break;
4930 case OPC_TLT: /* rs < rs */
4931 case OPC_TLTI: /* r0 < 0 */
4932 case OPC_TLTU: /* rs < rs unsigned */
4933 case OPC_TLTIU: /* r0 < 0 unsigned */
4934 case OPC_TNE: /* rs != rs */
4935 case OPC_TNEI: /* r0 != 0 */
ead9360e 4936 /* Never trap: treat as NOP. */
cdc0faa6 4937 break;
6af0bf9c
FB
4938 }
4939 } else {
42a268c2 4940 TCGLabel *l1 = gen_new_label();
cdc0faa6 4941
6af0bf9c
FB
4942 switch (opc) {
4943 case OPC_TEQ:
4944 case OPC_TEQI:
cdc0faa6 4945 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4946 break;
4947 case OPC_TGE:
4948 case OPC_TGEI:
cdc0faa6 4949 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4950 break;
4951 case OPC_TGEU:
4952 case OPC_TGEIU:
cdc0faa6 4953 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4954 break;
4955 case OPC_TLT:
4956 case OPC_TLTI:
cdc0faa6 4957 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4958 break;
4959 case OPC_TLTU:
4960 case OPC_TLTIU:
cdc0faa6 4961 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4962 break;
4963 case OPC_TNE:
4964 case OPC_TNEI:
cdc0faa6 4965 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4966 break;
6af0bf9c 4967 }
cdc0faa6 4968 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4969 gen_set_label(l1);
4970 }
be24bb4f
TS
4971 tcg_temp_free(t0);
4972 tcg_temp_free(t1);
6af0bf9c
FB
4973}
4974
90aa39a1
SF
4975static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4976{
eeb3bba8 4977 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
4978 return false;
4979 }
4980
4981#ifndef CONFIG_USER_ONLY
eeb3bba8 4982 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
4983#else
4984 return true;
4985#endif
4986}
4987
356265ae 4988static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4989{
90aa39a1 4990 if (use_goto_tb(ctx, dest)) {
57fec1fe 4991 tcg_gen_goto_tb(n);
9b9e4393 4992 gen_save_pc(dest);
07ea28b4 4993 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4994 } else {
9b9e4393 4995 gen_save_pc(dest);
eeb3bba8 4996 if (ctx->base.singlestep_enabled) {
7b270ef2 4997 save_cpu_state(ctx, 0);
9c708c7f 4998 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4999 }
7f11636d 5000 tcg_gen_lookup_and_goto_ptr();
6e256c93 5001 }
c53be334
FB
5002}
5003
6af0bf9c 5004/* Branches (before delay slot) */
7a387fff 5005static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 5006 int insn_bytes,
b231c103
YK
5007 int rs, int rt, int32_t offset,
5008 int delayslot_size)
6af0bf9c 5009{
d077b6f7 5010 target_ulong btgt = -1;
3ad4bb2d 5011 int blink = 0;
2fdbad25 5012 int bcond_compute = 0;
1ba74fb8
AJ
5013 TCGv t0 = tcg_temp_new();
5014 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
5015
5016 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 5017#ifdef MIPS_DEBUG_DISAS
339cd2a8 5018 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 5019 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 5020#endif
9c708c7f 5021 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5022 goto out;
3ad4bb2d 5023 }
6af0bf9c 5024
6af0bf9c
FB
5025 /* Load needed operands */
5026 switch (opc) {
5027 case OPC_BEQ:
5028 case OPC_BEQL:
5029 case OPC_BNE:
5030 case OPC_BNEL:
5031 /* Compare two registers */
5032 if (rs != rt) {
6c5c1e20
TS
5033 gen_load_gpr(t0, rs);
5034 gen_load_gpr(t1, rt);
2fdbad25 5035 bcond_compute = 1;
6af0bf9c 5036 }
eeb3bba8 5037 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
5038 break;
5039 case OPC_BGEZ:
5040 case OPC_BGEZAL:
5041 case OPC_BGEZALL:
5042 case OPC_BGEZL:
5043 case OPC_BGTZ:
5044 case OPC_BGTZL:
5045 case OPC_BLEZ:
5046 case OPC_BLEZL:
5047 case OPC_BLTZ:
5048 case OPC_BLTZAL:
5049 case OPC_BLTZALL:
5050 case OPC_BLTZL:
5051 /* Compare to zero */
5052 if (rs != 0) {
6c5c1e20 5053 gen_load_gpr(t0, rs);
2fdbad25 5054 bcond_compute = 1;
6af0bf9c 5055 }
eeb3bba8 5056 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 5057 break;
e45a93e2
JL
5058 case OPC_BPOSGE32:
5059#if defined(TARGET_MIPS64)
5060 case OPC_BPOSGE64:
5061 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5062#else
5063 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5064#endif
5065 bcond_compute = 1;
eeb3bba8 5066 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 5067 break;
6af0bf9c
FB
5068 case OPC_J:
5069 case OPC_JAL:
364d4831 5070 case OPC_JALX:
6af0bf9c 5071 /* Jump to immediate */
eeb3bba8
EC
5072 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5073 (uint32_t)offset;
6af0bf9c
FB
5074 break;
5075 case OPC_JR:
5076 case OPC_JALR:
5077 /* Jump to register */
7a387fff
TS
5078 if (offset != 0 && offset != 16) {
5079 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 5080 others are reserved. */
923617a3 5081 MIPS_INVAL("jump hint");
9c708c7f 5082 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5083 goto out;
6af0bf9c 5084 }
d077b6f7 5085 gen_load_gpr(btarget, rs);
6af0bf9c
FB
5086 break;
5087 default:
5088 MIPS_INVAL("branch/jump");
9c708c7f 5089 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5090 goto out;
6af0bf9c 5091 }
2fdbad25 5092 if (bcond_compute == 0) {
6af0bf9c
FB
5093 /* No condition to be computed */
5094 switch (opc) {
5095 case OPC_BEQ: /* rx == rx */
5096 case OPC_BEQL: /* rx == rx likely */
5097 case OPC_BGEZ: /* 0 >= 0 */
5098 case OPC_BGEZL: /* 0 >= 0 likely */
5099 case OPC_BLEZ: /* 0 <= 0 */
5100 case OPC_BLEZL: /* 0 <= 0 likely */
5101 /* Always take */
4ad40f36 5102 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5103 break;
5104 case OPC_BGEZAL: /* 0 >= 0 */
5105 case OPC_BGEZALL: /* 0 >= 0 likely */
5106 /* Always take and link */
5107 blink = 31;
4ad40f36 5108 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5109 break;
5110 case OPC_BNE: /* rx != rx */
5111 case OPC_BGTZ: /* 0 > 0 */
5112 case OPC_BLTZ: /* 0 < 0 */
ead9360e 5113 /* Treat as NOP. */
6c5c1e20 5114 goto out;
eeef26cd 5115 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
5116 /* Handle as an unconditional branch to get correct delay
5117 slot checking. */
5118 blink = 31;
eeb3bba8 5119 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 5120 ctx->hflags |= MIPS_HFLAG_B;
3c824109 5121 break;
eeef26cd 5122 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 5123 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 5124 /* Skip the instruction in the delay slot */
eeb3bba8 5125 ctx->base.pc_next += 4;
6c5c1e20 5126 goto out;
6af0bf9c
FB
5127 case OPC_BNEL: /* rx != rx likely */
5128 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
5129 case OPC_BLTZL: /* 0 < 0 likely */
5130 /* Skip the instruction in the delay slot */
eeb3bba8 5131 ctx->base.pc_next += 4;
6c5c1e20 5132 goto out;
6af0bf9c 5133 case OPC_J:
4ad40f36 5134 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5135 break;
364d4831
NF
5136 case OPC_JALX:
5137 ctx->hflags |= MIPS_HFLAG_BX;
5138 /* Fallthrough */
6af0bf9c
FB
5139 case OPC_JAL:
5140 blink = 31;
4ad40f36 5141 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5142 break;
5143 case OPC_JR:
4ad40f36 5144 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5145 break;
5146 case OPC_JALR:
5147 blink = rt;
4ad40f36 5148 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5149 break;
5150 default:
5151 MIPS_INVAL("branch/jump");
9c708c7f 5152 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5153 goto out;
6af0bf9c
FB
5154 }
5155 } else {
5156 switch (opc) {
5157 case OPC_BEQ:
e68dd28f 5158 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5159 goto not_likely;
5160 case OPC_BEQL:
e68dd28f 5161 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5162 goto likely;
5163 case OPC_BNE:
e68dd28f 5164 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5165 goto not_likely;
5166 case OPC_BNEL:
e68dd28f 5167 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5168 goto likely;
5169 case OPC_BGEZ:
e68dd28f 5170 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5171 goto not_likely;
5172 case OPC_BGEZL:
e68dd28f 5173 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5174 goto likely;
5175 case OPC_BGEZAL:
e68dd28f 5176 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5177 blink = 31;
5178 goto not_likely;
5179 case OPC_BGEZALL:
e68dd28f 5180 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5181 blink = 31;
6af0bf9c
FB
5182 goto likely;
5183 case OPC_BGTZ:
e68dd28f 5184 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5185 goto not_likely;
5186 case OPC_BGTZL:
e68dd28f 5187 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5188 goto likely;
5189 case OPC_BLEZ:
e68dd28f 5190 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5191 goto not_likely;
5192 case OPC_BLEZL:
e68dd28f 5193 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5194 goto likely;
5195 case OPC_BLTZ:
e68dd28f 5196 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5197 goto not_likely;
5198 case OPC_BLTZL:
e68dd28f 5199 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5200 goto likely;
e45a93e2
JL
5201 case OPC_BPOSGE32:
5202 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5203 goto not_likely;
5204#if defined(TARGET_MIPS64)
5205 case OPC_BPOSGE64:
5206 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5207 goto not_likely;
5208#endif
6af0bf9c 5209 case OPC_BLTZAL:
e68dd28f 5210 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5211 blink = 31;
6af0bf9c 5212 not_likely:
4ad40f36 5213 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5214 break;
5215 case OPC_BLTZALL:
e68dd28f 5216 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5217 blink = 31;
6af0bf9c 5218 likely:
4ad40f36 5219 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5220 break;
c53f4a62
TS
5221 default:
5222 MIPS_INVAL("conditional branch/jump");
9c708c7f 5223 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5224 goto out;
6af0bf9c 5225 }
6af0bf9c 5226 }
9b9e4393 5227
d077b6f7 5228 ctx->btarget = btgt;
b231c103
YK
5229
5230 switch (delayslot_size) {
5231 case 2:
5232 ctx->hflags |= MIPS_HFLAG_BDS16;
5233 break;
5234 case 4:
5235 ctx->hflags |= MIPS_HFLAG_BDS32;
5236 break;
5237 }
5238
6af0bf9c 5239 if (blink > 0) {
b231c103 5240 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
5241 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5242
eeb3bba8
EC
5243 tcg_gen_movi_tl(cpu_gpr[blink],
5244 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 5245 }
6c5c1e20
TS
5246
5247 out:
364d4831
NF
5248 if (insn_bytes == 2)
5249 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
5250 tcg_temp_free(t0);
5251 tcg_temp_free(t1);
6af0bf9c
FB
5252}
5253
764371d2
SM
5254
5255/* nanoMIPS Branches */
5256static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5257 int insn_bytes,
5258 int rs, int rt, int32_t offset)
5259{
5260 target_ulong btgt = -1;
5261 int bcond_compute = 0;
5262 TCGv t0 = tcg_temp_new();
5263 TCGv t1 = tcg_temp_new();
5264
5265 /* Load needed operands */
5266 switch (opc) {
5267 case OPC_BEQ:
5268 case OPC_BNE:
5269 /* Compare two registers */
5270 if (rs != rt) {
5271 gen_load_gpr(t0, rs);
5272 gen_load_gpr(t1, rt);
5273 bcond_compute = 1;
5274 }
5275 btgt = ctx->base.pc_next + insn_bytes + offset;
5276 break;
5277 case OPC_BGEZAL:
5278 /* Compare to zero */
5279 if (rs != 0) {
5280 gen_load_gpr(t0, rs);
5281 bcond_compute = 1;
5282 }
5283 btgt = ctx->base.pc_next + insn_bytes + offset;
5284 break;
5285 case OPC_BPOSGE32:
5286 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5287 bcond_compute = 1;
5288 btgt = ctx->base.pc_next + insn_bytes + offset;
5289 break;
5290 case OPC_JR:
5291 case OPC_JALR:
5292 /* Jump to register */
5293 if (offset != 0 && offset != 16) {
5294 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5295 others are reserved. */
5296 MIPS_INVAL("jump hint");
5297 generate_exception_end(ctx, EXCP_RI);
5298 goto out;
5299 }
5300 gen_load_gpr(btarget, rs);
5301 break;
5302 default:
5303 MIPS_INVAL("branch/jump");
5304 generate_exception_end(ctx, EXCP_RI);
5305 goto out;
5306 }
5307 if (bcond_compute == 0) {
5308 /* No condition to be computed */
5309 switch (opc) {
5310 case OPC_BEQ: /* rx == rx */
5311 /* Always take */
5312 ctx->hflags |= MIPS_HFLAG_B;
5313 break;
5314 case OPC_BGEZAL: /* 0 >= 0 */
5315 /* Always take and link */
5316 tcg_gen_movi_tl(cpu_gpr[31],
5317 ctx->base.pc_next + insn_bytes);
5318 ctx->hflags |= MIPS_HFLAG_B;
5319 break;
5320 case OPC_BNE: /* rx != rx */
5321 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5322 /* Skip the instruction in the delay slot */
5323 ctx->base.pc_next += 4;
5324 goto out;
5325 case OPC_JR:
5326 ctx->hflags |= MIPS_HFLAG_BR;
5327 break;
5328 case OPC_JALR:
5329 if (rt > 0) {
5330 tcg_gen_movi_tl(cpu_gpr[rt],
5331 ctx->base.pc_next + insn_bytes);
5332 }
5333 ctx->hflags |= MIPS_HFLAG_BR;
5334 break;
5335 default:
5336 MIPS_INVAL("branch/jump");
5337 generate_exception_end(ctx, EXCP_RI);
5338 goto out;
5339 }
5340 } else {
5341 switch (opc) {
5342 case OPC_BEQ:
5343 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5344 goto not_likely;
5345 case OPC_BNE:
5346 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5347 goto not_likely;
5348 case OPC_BGEZAL:
5349 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5350 tcg_gen_movi_tl(cpu_gpr[31],
5351 ctx->base.pc_next + insn_bytes);
5352 goto not_likely;
5353 case OPC_BPOSGE32:
5354 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5355 not_likely:
5356 ctx->hflags |= MIPS_HFLAG_BC;
5357 break;
5358 default:
5359 MIPS_INVAL("conditional branch/jump");
5360 generate_exception_end(ctx, EXCP_RI);
5361 goto out;
5362 }
5363 }
5364
5365 ctx->btarget = btgt;
5366
5367 out:
5368 if (insn_bytes == 2) {
5369 ctx->hflags |= MIPS_HFLAG_B16;
5370 }
5371 tcg_temp_free(t0);
5372 tcg_temp_free(t1);
5373}
5374
5375
7a387fff
TS
5376/* special3 bitfield operations */
5377static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 5378 int rs, int lsb, int msb)
7a387fff 5379{
a7812ae4
PB
5380 TCGv t0 = tcg_temp_new();
5381 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
5382
5383 gen_load_gpr(t1, rs);
7a387fff
TS
5384 switch (opc) {
5385 case OPC_EXT:
b7f26e52 5386 if (lsb + msb > 31) {
7a387fff 5387 goto fail;
b7f26e52 5388 }
505ad7c2 5389 if (msb != 31) {
6eebb7a4 5390 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 5391 } else {
6eebb7a4
RH
5392 /* The two checks together imply that lsb == 0,
5393 so this is a simple sign-extension. */
5394 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 5395 }
7a387fff 5396 break;
c6d6dd7c 5397#if defined(TARGET_MIPS64)
7a387fff 5398 case OPC_DEXTU:
b7f26e52
RH
5399 lsb += 32;
5400 goto do_dext;
5401 case OPC_DEXTM:
5402 msb += 32;
5403 goto do_dext;
7a387fff 5404 case OPC_DEXT:
b7f26e52
RH
5405 do_dext:
5406 if (lsb + msb > 63) {
5407 goto fail;
5408 }
6eebb7a4 5409 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 5410 break;
c6d6dd7c 5411#endif
7a387fff 5412 case OPC_INS:
b7f26e52 5413 if (lsb > msb) {
7a387fff 5414 goto fail;
b7f26e52 5415 }
6c5c1e20 5416 gen_load_gpr(t0, rt);
e0d002f1 5417 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 5418 tcg_gen_ext32s_tl(t0, t0);
7a387fff 5419 break;
c6d6dd7c 5420#if defined(TARGET_MIPS64)
7a387fff 5421 case OPC_DINSU:
b7f26e52
RH
5422 lsb += 32;
5423 /* FALLTHRU */
5424 case OPC_DINSM:
5425 msb += 32;
5426 /* FALLTHRU */
7a387fff 5427 case OPC_DINS:
b7f26e52
RH
5428 if (lsb > msb) {
5429 goto fail;
5430 }
6c5c1e20 5431 gen_load_gpr(t0, rt);
e0d002f1 5432 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 5433 break;
c6d6dd7c 5434#endif
7a387fff
TS
5435 default:
5436fail:
5437 MIPS_INVAL("bitops");
9c708c7f 5438 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
5439 tcg_temp_free(t0);
5440 tcg_temp_free(t1);
7a387fff
TS
5441 return;
5442 }
6c5c1e20
TS
5443 gen_store_gpr(t0, rt);
5444 tcg_temp_free(t0);
5445 tcg_temp_free(t1);
7a387fff
TS
5446}
5447
49bcf33c
AJ
5448static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5449{
3a55fa47 5450 TCGv t0;
49bcf33c 5451
3a55fa47
AJ
5452 if (rd == 0) {
5453 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
5454 return;
5455 }
5456
5457 t0 = tcg_temp_new();
5458 gen_load_gpr(t0, rt);
49bcf33c
AJ
5459 switch (op2) {
5460 case OPC_WSBH:
3a55fa47
AJ
5461 {
5462 TCGv t1 = tcg_temp_new();
06a57e5c 5463 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
5464
5465 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5466 tcg_gen_and_tl(t1, t1, t2);
5467 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5468 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5469 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 5470 tcg_temp_free(t2);
3a55fa47
AJ
5471 tcg_temp_free(t1);
5472 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5473 }
49bcf33c
AJ
5474 break;
5475 case OPC_SEB:
3a55fa47 5476 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5477 break;
5478 case OPC_SEH:
3a55fa47 5479 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5480 break;
5481#if defined(TARGET_MIPS64)
5482 case OPC_DSBH:
3a55fa47
AJ
5483 {
5484 TCGv t1 = tcg_temp_new();
06a57e5c 5485 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
5486
5487 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5488 tcg_gen_and_tl(t1, t1, t2);
5489 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5490 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5491 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5492 tcg_temp_free(t2);
3a55fa47
AJ
5493 tcg_temp_free(t1);
5494 }
49bcf33c
AJ
5495 break;
5496 case OPC_DSHD:
3a55fa47
AJ
5497 {
5498 TCGv t1 = tcg_temp_new();
06a57e5c 5499 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
5500
5501 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
5502 tcg_gen_and_tl(t1, t1, t2);
5503 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5504 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
5505 tcg_gen_or_tl(t0, t0, t1);
5506 tcg_gen_shri_tl(t1, t0, 32);
5507 tcg_gen_shli_tl(t0, t0, 32);
5508 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5509 tcg_temp_free(t2);
3a55fa47
AJ
5510 tcg_temp_free(t1);
5511 }
49bcf33c
AJ
5512 break;
5513#endif
5514 default:
5515 MIPS_INVAL("bsfhl");
9c708c7f 5516 generate_exception_end(ctx, EXCP_RI);
49bcf33c 5517 tcg_temp_free(t0);
49bcf33c
AJ
5518 return;
5519 }
49bcf33c 5520 tcg_temp_free(t0);
49bcf33c
AJ
5521}
5522
1f1b4c00
YK
5523static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5524 int imm2)
5525{
5526 TCGv t0;
5527 TCGv t1;
5528 if (rd == 0) {
5529 /* Treat as NOP. */
5530 return;
5531 }
5532 t0 = tcg_temp_new();
5533 t1 = tcg_temp_new();
5534 gen_load_gpr(t0, rs);
5535 gen_load_gpr(t1, rt);
5536 tcg_gen_shli_tl(t0, t0, imm2 + 1);
5537 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5538 if (opc == OPC_LSA) {
5539 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5540 }
5541
5542 tcg_temp_free(t1);
5543 tcg_temp_free(t0);
5544
5545 return;
5546}
5547
821f2008
JH
5548static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5549 int rt, int bits)
284b731a 5550{
1f1b4c00
YK
5551 TCGv t0;
5552 if (rd == 0) {
5553 /* Treat as NOP. */
5554 return;
5555 }
5556 t0 = tcg_temp_new();
821f2008
JH
5557 if (bits == 0 || bits == wordsz) {
5558 if (bits == 0) {
5559 gen_load_gpr(t0, rt);
5560 } else {
5561 gen_load_gpr(t0, rs);
5562 }
5563 switch (wordsz) {
5564 case 32:
51243852
MD
5565 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5566 break;
5567#if defined(TARGET_MIPS64)
821f2008 5568 case 64:
51243852
MD
5569 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5570 break;
5571#endif
5572 }
1f1b4c00
YK
5573 } else {
5574 TCGv t1 = tcg_temp_new();
821f2008 5575 gen_load_gpr(t0, rt);
1f1b4c00 5576 gen_load_gpr(t1, rs);
821f2008
JH
5577 switch (wordsz) {
5578 case 32:
1f1b4c00
YK
5579 {
5580 TCGv_i64 t2 = tcg_temp_new_i64();
5581 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 5582 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
5583 gen_move_low32(cpu_gpr[rd], t2);
5584 tcg_temp_free_i64(t2);
5585 }
5586 break;
284b731a 5587#if defined(TARGET_MIPS64)
821f2008
JH
5588 case 64:
5589 tcg_gen_shli_tl(t0, t0, bits);
5590 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
5591 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5592 break;
284b731a 5593#endif
1f1b4c00
YK
5594 }
5595 tcg_temp_free(t1);
5596 }
5597
5598 tcg_temp_free(t0);
5599}
5600
821f2008
JH
5601static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5602 int bp)
5603{
5604 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5605}
5606
5607static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5608 int shift)
5609{
5610 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5611}
5612
1f1b4c00
YK
5613static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5614{
5615 TCGv t0;
5616 if (rd == 0) {
5617 /* Treat as NOP. */
5618 return;
5619 }
5620 t0 = tcg_temp_new();
5621 gen_load_gpr(t0, rt);
5622 switch (opc) {
5623 case OPC_BITSWAP:
5624 gen_helper_bitswap(cpu_gpr[rd], t0);
5625 break;
5626#if defined(TARGET_MIPS64)
5627 case OPC_DBITSWAP:
5628 gen_helper_dbitswap(cpu_gpr[rd], t0);
5629 break;
5630#endif
5631 }
5632 tcg_temp_free(t0);
284b731a
LA
5633}
5634
1f1b4c00
YK
5635#ifndef CONFIG_USER_ONLY
5636/* CP0 (MMU and control) */
5204ea79
LA
5637static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5638{
5639 TCGv_i64 t0 = tcg_temp_new_i64();
5640 TCGv_i64 t1 = tcg_temp_new_i64();
5641
5642 tcg_gen_ext_tl_i64(t0, arg);
5643 tcg_gen_ld_i64(t1, cpu_env, off);
5644#if defined(TARGET_MIPS64)
5645 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5646#else
5647 tcg_gen_concat32_i64(t1, t1, t0);
5648#endif
5649 tcg_gen_st_i64(t1, cpu_env, off);
5650 tcg_temp_free_i64(t1);
5651 tcg_temp_free_i64(t0);
5652}
5653
5654static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5655{
5656 TCGv_i64 t0 = tcg_temp_new_i64();
5657 TCGv_i64 t1 = tcg_temp_new_i64();
5658
5659 tcg_gen_ext_tl_i64(t0, arg);
5660 tcg_gen_ld_i64(t1, cpu_env, off);
5661 tcg_gen_concat32_i64(t1, t1, t0);
5662 tcg_gen_st_i64(t1, cpu_env, off);
5663 tcg_temp_free_i64(t1);
5664 tcg_temp_free_i64(t0);
5665}
5666
5667static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5668{
5669 TCGv_i64 t0 = tcg_temp_new_i64();
5670
5671 tcg_gen_ld_i64(t0, cpu_env, off);
5672#if defined(TARGET_MIPS64)
5673 tcg_gen_shri_i64(t0, t0, 30);
5674#else
5675 tcg_gen_shri_i64(t0, t0, 32);
5676#endif
5677 gen_move_low32(arg, t0);
5678 tcg_temp_free_i64(t0);
5679}
5680
5681static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5682{
5683 TCGv_i64 t0 = tcg_temp_new_i64();
5684
5685 tcg_gen_ld_i64(t0, cpu_env, off);
5686 tcg_gen_shri_i64(t0, t0, 32 + shift);
5687 gen_move_low32(arg, t0);
5688 tcg_temp_free_i64(t0);
5689}
5690
d9bea114 5691static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 5692{
d9bea114 5693 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 5694
d9bea114
AJ
5695 tcg_gen_ld_i32(t0, cpu_env, off);
5696 tcg_gen_ext_i32_tl(arg, t0);
5697 tcg_temp_free_i32(t0);
4f57689a
TS
5698}
5699
d9bea114 5700static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 5701{
d9bea114
AJ
5702 tcg_gen_ld_tl(arg, cpu_env, off);
5703 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
5704}
5705
d9bea114 5706static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 5707{
d9bea114 5708 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 5709
d9bea114
AJ
5710 tcg_gen_trunc_tl_i32(t0, arg);
5711 tcg_gen_st_i32(t0, cpu_env, off);
5712 tcg_temp_free_i32(t0);
f1aa6320
TS
5713}
5714
c98d3d79
YK
5715#define CP0_CHECK(c) \
5716 do { \
5717 if (!(c)) { \
5718 goto cp0_unimplemented; \
5719 } \
5720 } while (0)
5721
5204ea79
LA
5722static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5723{
5724 const char *rn = "invalid";
5725
5204ea79
LA
5726 switch (reg) {
5727 case 2:
5728 switch (sel) {
5729 case 0:
59488dda 5730 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5731 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5732 rn = "EntryLo0";
5733 break;
5734 default:
c98d3d79 5735 goto cp0_unimplemented;
5204ea79
LA
5736 }
5737 break;
5738 case 3:
5739 switch (sel) {
5740 case 0:
59488dda 5741 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5742 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5743 rn = "EntryLo1";
5744 break;
5745 default:
c98d3d79 5746 goto cp0_unimplemented;
5204ea79
LA
5747 }
5748 break;
5749 case 17:
5750 switch (sel) {
5751 case 0:
5752 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5753 ctx->CP0_LLAddr_shift);
5754 rn = "LLAddr";
5755 break;
f6d4dd81
YK
5756 case 1:
5757 CP0_CHECK(ctx->mrp);
5758 gen_helper_mfhc0_maar(arg, cpu_env);
5759 rn = "MAAR";
5760 break;
5204ea79 5761 default:
c98d3d79 5762 goto cp0_unimplemented;
5204ea79
LA
5763 }
5764 break;
5765 case 28:
5766 switch (sel) {
5767 case 0:
5768 case 2:
5769 case 4:
5770 case 6:
5771 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5772 rn = "TagLo";
5773 break;
5774 default:
c98d3d79 5775 goto cp0_unimplemented;
5204ea79
LA
5776 }
5777 break;
5778 default:
c98d3d79 5779 goto cp0_unimplemented;
5204ea79 5780 }
b44a7fb1 5781 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
5782 return;
5783
c98d3d79 5784cp0_unimplemented:
965447ee 5785 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5786 tcg_gen_movi_tl(arg, 0);
5787}
5788
5789static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5790{
5791 const char *rn = "invalid";
5792 uint64_t mask = ctx->PAMask >> 36;
5793
5204ea79
LA
5794 switch (reg) {
5795 case 2:
5796 switch (sel) {
5797 case 0:
59488dda 5798 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5799 tcg_gen_andi_tl(arg, arg, mask);
5800 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5801 rn = "EntryLo0";
5802 break;
5803 default:
c98d3d79 5804 goto cp0_unimplemented;
5204ea79
LA
5805 }
5806 break;
5807 case 3:
5808 switch (sel) {
5809 case 0:
59488dda 5810 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5811 tcg_gen_andi_tl(arg, arg, mask);
5812 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5813 rn = "EntryLo1";
5814 break;
5815 default:
c98d3d79 5816 goto cp0_unimplemented;
5204ea79
LA
5817 }
5818 break;
5819 case 17:
5820 switch (sel) {
5821 case 0:
5822 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5823 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5824 relevant for modern MIPS cores supporting MTHC0, therefore
5825 treating MTHC0 to LLAddr as NOP. */
5826 rn = "LLAddr";
5827 break;
f6d4dd81
YK
5828 case 1:
5829 CP0_CHECK(ctx->mrp);
5830 gen_helper_mthc0_maar(cpu_env, arg);
5831 rn = "MAAR";
5832 break;
5204ea79 5833 default:
c98d3d79 5834 goto cp0_unimplemented;
5204ea79
LA
5835 }
5836 break;
5837 case 28:
5838 switch (sel) {
5839 case 0:
5840 case 2:
5841 case 4:
5842 case 6:
5843 tcg_gen_andi_tl(arg, arg, mask);
5844 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5845 rn = "TagLo";
5846 break;
5847 default:
c98d3d79 5848 goto cp0_unimplemented;
5204ea79
LA
5849 }
5850 break;
5851 default:
c98d3d79 5852 goto cp0_unimplemented;
5204ea79 5853 }
b44a7fb1 5854 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 5855
c98d3d79 5856cp0_unimplemented:
965447ee 5857 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5858}
5859
e98c0d17
LA
5860static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5861{
5862 if (ctx->insn_flags & ISA_MIPS32R6) {
5863 tcg_gen_movi_tl(arg, 0);
5864 } else {
5865 tcg_gen_movi_tl(arg, ~0);
5866 }
5867}
5868
d75c135e 5869static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5870{
7a387fff 5871 const char *rn = "invalid";
873eb012 5872
e189e748 5873 if (sel != 0)
d75c135e 5874 check_insn(ctx, ISA_MIPS32);
e189e748 5875
873eb012
TS
5876 switch (reg) {
5877 case 0:
7a387fff
TS
5878 switch (sel) {
5879 case 0:
7db13fae 5880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5881 rn = "Index";
5882 break;
5883 case 1:
f31b035a 5884 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5885 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5886 rn = "MVPControl";
ead9360e 5887 break;
7a387fff 5888 case 2:
f31b035a 5889 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5890 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5891 rn = "MVPConf0";
ead9360e 5892 break;
7a387fff 5893 case 3:
f31b035a 5894 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5895 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5896 rn = "MVPConf1";
ead9360e 5897 break;
01bc435b
YK
5898 case 4:
5899 CP0_CHECK(ctx->vp);
5900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5901 rn = "VPControl";
5902 break;
7a387fff 5903 default:
f31b035a 5904 goto cp0_unimplemented;
7a387fff 5905 }
873eb012
TS
5906 break;
5907 case 1:
7a387fff
TS
5908 switch (sel) {
5909 case 0:
f31b035a 5910 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5911 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5912 rn = "Random";
2423f660 5913 break;
7a387fff 5914 case 1:
f31b035a 5915 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5916 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5917 rn = "VPEControl";
ead9360e 5918 break;
7a387fff 5919 case 2:
f31b035a 5920 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5922 rn = "VPEConf0";
ead9360e 5923 break;
7a387fff 5924 case 3:
f31b035a 5925 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5927 rn = "VPEConf1";
ead9360e 5928 break;
7a387fff 5929 case 4:
f31b035a 5930 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5931 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5932 rn = "YQMask";
ead9360e 5933 break;
7a387fff 5934 case 5:
f31b035a 5935 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5936 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5937 rn = "VPESchedule";
ead9360e 5938 break;
7a387fff 5939 case 6:
f31b035a 5940 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5941 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5942 rn = "VPEScheFBack";
ead9360e 5943 break;
7a387fff 5944 case 7:
f31b035a 5945 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5947 rn = "VPEOpt";
ead9360e 5948 break;
7a387fff 5949 default:
f31b035a 5950 goto cp0_unimplemented;
7a387fff 5951 }
873eb012
TS
5952 break;
5953 case 2:
7a387fff
TS
5954 switch (sel) {
5955 case 0:
284b731a
LA
5956 {
5957 TCGv_i64 tmp = tcg_temp_new_i64();
5958 tcg_gen_ld_i64(tmp, cpu_env,
5959 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5960#if defined(TARGET_MIPS64)
284b731a
LA
5961 if (ctx->rxi) {
5962 /* Move RI/XI fields to bits 31:30 */
5963 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5964 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5965 }
7207c7f9 5966#endif
284b731a
LA
5967 gen_move_low32(arg, tmp);
5968 tcg_temp_free_i64(tmp);
5969 }
2423f660
TS
5970 rn = "EntryLo0";
5971 break;
7a387fff 5972 case 1:
f31b035a 5973 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5974 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5975 rn = "TCStatus";
ead9360e 5976 break;
7a387fff 5977 case 2:
f31b035a 5978 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5979 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5980 rn = "TCBind";
ead9360e 5981 break;
7a387fff 5982 case 3:
f31b035a 5983 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5984 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5985 rn = "TCRestart";
ead9360e 5986 break;
7a387fff 5987 case 4:
f31b035a 5988 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5989 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5990 rn = "TCHalt";
ead9360e 5991 break;
7a387fff 5992 case 5:
f31b035a 5993 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5994 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5995 rn = "TCContext";
ead9360e 5996 break;
7a387fff 5997 case 6:
f31b035a 5998 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5999 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 6000 rn = "TCSchedule";
ead9360e 6001 break;
7a387fff 6002 case 7:
f31b035a 6003 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6004 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 6005 rn = "TCScheFBack";
ead9360e 6006 break;
7a387fff 6007 default:
f31b035a 6008 goto cp0_unimplemented;
7a387fff 6009 }
873eb012
TS
6010 break;
6011 case 3:
7a387fff
TS
6012 switch (sel) {
6013 case 0:
284b731a
LA
6014 {
6015 TCGv_i64 tmp = tcg_temp_new_i64();
6016 tcg_gen_ld_i64(tmp, cpu_env,
6017 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 6018#if defined(TARGET_MIPS64)
284b731a
LA
6019 if (ctx->rxi) {
6020 /* Move RI/XI fields to bits 31:30 */
6021 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6022 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6023 }
7207c7f9 6024#endif
284b731a
LA
6025 gen_move_low32(arg, tmp);
6026 tcg_temp_free_i64(tmp);
6027 }
2423f660
TS
6028 rn = "EntryLo1";
6029 break;
01bc435b
YK
6030 case 1:
6031 CP0_CHECK(ctx->vp);
6032 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6033 rn = "GlobalNumber";
6034 break;
7a387fff 6035 default:
f31b035a 6036 goto cp0_unimplemented;
1579a72e 6037 }
873eb012
TS
6038 break;
6039 case 4:
7a387fff
TS
6040 switch (sel) {
6041 case 0:
7db13fae 6042 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 6043 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6044 rn = "Context";
6045 break;
7a387fff 6046 case 1:
d9bea114 6047// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6048 rn = "ContextConfig";
f31b035a 6049 goto cp0_unimplemented;
d279279e 6050 case 2:
f31b035a 6051 CP0_CHECK(ctx->ulri);
e40df9a8
JH
6052 tcg_gen_ld_tl(arg, cpu_env,
6053 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6054 tcg_gen_ext32s_tl(arg, arg);
f31b035a 6055 rn = "UserLocal";
d279279e 6056 break;
7a387fff 6057 default:
f31b035a 6058 goto cp0_unimplemented;
1579a72e 6059 }
873eb012
TS
6060 break;
6061 case 5:
7a387fff
TS
6062 switch (sel) {
6063 case 0:
7db13fae 6064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6065 rn = "PageMask";
6066 break;
7a387fff 6067 case 1:
d75c135e 6068 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6069 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6070 rn = "PageGrain";
6071 break;
cec56a73
JH
6072 case 2:
6073 CP0_CHECK(ctx->sc);
6074 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6075 tcg_gen_ext32s_tl(arg, arg);
6076 rn = "SegCtl0";
6077 break;
6078 case 3:
6079 CP0_CHECK(ctx->sc);
6080 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6081 tcg_gen_ext32s_tl(arg, arg);
6082 rn = "SegCtl1";
6083 break;
6084 case 4:
6085 CP0_CHECK(ctx->sc);
6086 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6087 tcg_gen_ext32s_tl(arg, arg);
6088 rn = "SegCtl2";
6089 break;
7a387fff 6090 default:
f31b035a 6091 goto cp0_unimplemented;
1579a72e 6092 }
873eb012
TS
6093 break;
6094 case 6:
7a387fff
TS
6095 switch (sel) {
6096 case 0:
7db13fae 6097 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6098 rn = "Wired";
6099 break;
7a387fff 6100 case 1:
d75c135e 6101 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6102 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6103 rn = "SRSConf0";
ead9360e 6104 break;
7a387fff 6105 case 2:
d75c135e 6106 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6108 rn = "SRSConf1";
ead9360e 6109 break;
7a387fff 6110 case 3:
d75c135e 6111 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6113 rn = "SRSConf2";
ead9360e 6114 break;
7a387fff 6115 case 4:
d75c135e 6116 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6118 rn = "SRSConf3";
ead9360e 6119 break;
7a387fff 6120 case 5:
d75c135e 6121 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6123 rn = "SRSConf4";
ead9360e 6124 break;
7a387fff 6125 default:
f31b035a 6126 goto cp0_unimplemented;
1579a72e 6127 }
873eb012 6128 break;
8c0fdd85 6129 case 7:
7a387fff
TS
6130 switch (sel) {
6131 case 0:
d75c135e 6132 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6133 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6134 rn = "HWREna";
6135 break;
7a387fff 6136 default:
f31b035a 6137 goto cp0_unimplemented;
1579a72e 6138 }
8c0fdd85 6139 break;
873eb012 6140 case 8:
7a387fff
TS
6141 switch (sel) {
6142 case 0:
7db13fae 6143 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 6144 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 6145 rn = "BadVAddr";
2423f660 6146 break;
aea14095 6147 case 1:
f31b035a
LA
6148 CP0_CHECK(ctx->bi);
6149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6150 rn = "BadInstr";
aea14095
LA
6151 break;
6152 case 2:
f31b035a
LA
6153 CP0_CHECK(ctx->bp);
6154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6155 rn = "BadInstrP";
aea14095 6156 break;
25beba9b
SM
6157 case 3:
6158 CP0_CHECK(ctx->bi);
6159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6160 tcg_gen_andi_tl(arg, arg, ~0xffff);
6161 rn = "BadInstrX";
6162 break;
6163 default:
f31b035a 6164 goto cp0_unimplemented;
aea14095 6165 }
873eb012
TS
6166 break;
6167 case 9:
7a387fff
TS
6168 switch (sel) {
6169 case 0:
2e70f6ef 6170 /* Mark as an IO operation because we read the time. */
eeb3bba8 6171 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6172 gen_io_start();
bd79255d 6173 }
895c2d04 6174 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6175 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6176 gen_io_end();
2e70f6ef 6177 }
55807224 6178 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6179 after reading count. DISAS_STOP isn't sufficient, we need to
6180 ensure we break completely out of translated code. */
eeb3bba8
EC
6181 gen_save_pc(ctx->base.pc_next + 4);
6182 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6183 rn = "Count";
6184 break;
6185 /* 6,7 are implementation dependent */
7a387fff 6186 default:
f31b035a 6187 goto cp0_unimplemented;
2423f660 6188 }
873eb012
TS
6189 break;
6190 case 10:
7a387fff
TS
6191 switch (sel) {
6192 case 0:
7db13fae 6193 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 6194 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6195 rn = "EntryHi";
6196 break;
7a387fff 6197 default:
f31b035a 6198 goto cp0_unimplemented;
1579a72e 6199 }
873eb012
TS
6200 break;
6201 case 11:
7a387fff
TS
6202 switch (sel) {
6203 case 0:
7db13fae 6204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6205 rn = "Compare";
6206 break;
6207 /* 6,7 are implementation dependent */
7a387fff 6208 default:
f31b035a 6209 goto cp0_unimplemented;
2423f660 6210 }
873eb012
TS
6211 break;
6212 case 12:
7a387fff
TS
6213 switch (sel) {
6214 case 0:
7db13fae 6215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6216 rn = "Status";
6217 break;
7a387fff 6218 case 1:
d75c135e 6219 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6221 rn = "IntCtl";
6222 break;
7a387fff 6223 case 2:
d75c135e 6224 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6226 rn = "SRSCtl";
6227 break;
7a387fff 6228 case 3:
d75c135e 6229 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 6231 rn = "SRSMap";
fd88b6ab 6232 break;
7a387fff 6233 default:
f31b035a 6234 goto cp0_unimplemented;
7a387fff 6235 }
873eb012
TS
6236 break;
6237 case 13:
7a387fff
TS
6238 switch (sel) {
6239 case 0:
7db13fae 6240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6241 rn = "Cause";
6242 break;
7a387fff 6243 default:
f31b035a 6244 goto cp0_unimplemented;
7a387fff 6245 }
873eb012
TS
6246 break;
6247 case 14:
7a387fff
TS
6248 switch (sel) {
6249 case 0:
7db13fae 6250 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 6251 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6252 rn = "EPC";
6253 break;
7a387fff 6254 default:
f31b035a 6255 goto cp0_unimplemented;
1579a72e 6256 }
873eb012
TS
6257 break;
6258 case 15:
7a387fff
TS
6259 switch (sel) {
6260 case 0:
7db13fae 6261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6262 rn = "PRid";
6263 break;
7a387fff 6264 case 1:
d75c135e 6265 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
6266 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6267 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6268 rn = "EBase";
6269 break;
c870e3f5
YK
6270 case 3:
6271 check_insn(ctx, ISA_MIPS32R2);
6272 CP0_CHECK(ctx->cmgcr);
6273 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6274 tcg_gen_ext32s_tl(arg, arg);
6275 rn = "CMGCRBase";
6276 break;
7a387fff 6277 default:
f31b035a 6278 goto cp0_unimplemented;
7a387fff 6279 }
873eb012
TS
6280 break;
6281 case 16:
6282 switch (sel) {
6283 case 0:
7db13fae 6284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
6285 rn = "Config";
6286 break;
6287 case 1:
7db13fae 6288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
6289 rn = "Config1";
6290 break;
7a387fff 6291 case 2:
7db13fae 6292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
6293 rn = "Config2";
6294 break;
6295 case 3:
7db13fae 6296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
6297 rn = "Config3";
6298 break;
b4160af1
PJ
6299 case 4:
6300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6301 rn = "Config4";
6302 break;
b4dd99a3
PJ
6303 case 5:
6304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6305 rn = "Config5";
6306 break;
e397ee33
TS
6307 /* 6,7 are implementation dependent */
6308 case 6:
7db13fae 6309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
6310 rn = "Config6";
6311 break;
6312 case 7:
7db13fae 6313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
6314 rn = "Config7";
6315 break;
873eb012 6316 default:
f31b035a 6317 goto cp0_unimplemented;
873eb012
TS
6318 }
6319 break;
6320 case 17:
7a387fff
TS
6321 switch (sel) {
6322 case 0:
895c2d04 6323 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
6324 rn = "LLAddr";
6325 break;
f6d4dd81
YK
6326 case 1:
6327 CP0_CHECK(ctx->mrp);
6328 gen_helper_mfc0_maar(arg, cpu_env);
6329 rn = "MAAR";
6330 break;
6331 case 2:
6332 CP0_CHECK(ctx->mrp);
6333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6334 rn = "MAARI";
6335 break;
7a387fff 6336 default:
f31b035a 6337 goto cp0_unimplemented;
7a387fff 6338 }
873eb012
TS
6339 break;
6340 case 18:
7a387fff 6341 switch (sel) {
c2e19f3c
AM
6342 case 0:
6343 case 1:
6344 case 2:
6345 case 3:
6346 case 4:
6347 case 5:
6348 case 6:
6349 case 7:
fa192d49 6350 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6351 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
6352 rn = "WatchLo";
6353 break;
7a387fff 6354 default:
f31b035a 6355 goto cp0_unimplemented;
7a387fff 6356 }
873eb012
TS
6357 break;
6358 case 19:
7a387fff 6359 switch (sel) {
c2e19f3c
AM
6360 case 0:
6361 case 1:
6362 case 2:
6363 case 3:
6364 case 4:
6365 case 5:
6366 case 6:
6367 case 7:
fa192d49 6368 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6369 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6370 rn = "WatchHi";
6371 break;
7a387fff 6372 default:
f31b035a 6373 goto cp0_unimplemented;
7a387fff 6374 }
873eb012 6375 break;
8c0fdd85 6376 case 20:
7a387fff
TS
6377 switch (sel) {
6378 case 0:
d26bc211 6379#if defined(TARGET_MIPS64)
d75c135e 6380 check_insn(ctx, ISA_MIPS3);
7db13fae 6381 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 6382 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6383 rn = "XContext";
6384 break;
703eaf37 6385#endif
7a387fff 6386 default:
f31b035a 6387 goto cp0_unimplemented;
7a387fff 6388 }
8c0fdd85
TS
6389 break;
6390 case 21:
7a387fff 6391 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6392 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6393 switch (sel) {
6394 case 0:
7db13fae 6395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6396 rn = "Framemask";
6397 break;
7a387fff 6398 default:
f31b035a 6399 goto cp0_unimplemented;
7a387fff 6400 }
8c0fdd85
TS
6401 break;
6402 case 22:
d9bea114 6403 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6404 rn = "'Diagnostic"; /* implementation dependent */
6405 break;
873eb012 6406 case 23:
7a387fff
TS
6407 switch (sel) {
6408 case 0:
895c2d04 6409 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6410 rn = "Debug";
6411 break;
7a387fff 6412 case 1:
d9bea114 6413// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 6414 rn = "TraceControl";
3570d7f6 6415 goto cp0_unimplemented;
7a387fff 6416 case 2:
d9bea114 6417// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 6418 rn = "TraceControl2";
3570d7f6 6419 goto cp0_unimplemented;
7a387fff 6420 case 3:
d9bea114 6421// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 6422 rn = "UserTraceData";
3570d7f6 6423 goto cp0_unimplemented;
7a387fff 6424 case 4:
d9bea114 6425// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 6426 rn = "TraceBPC";
3570d7f6 6427 goto cp0_unimplemented;
7a387fff 6428 default:
f31b035a 6429 goto cp0_unimplemented;
7a387fff 6430 }
873eb012
TS
6431 break;
6432 case 24:
7a387fff
TS
6433 switch (sel) {
6434 case 0:
f0b3f3ae 6435 /* EJTAG support */
7db13fae 6436 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 6437 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6438 rn = "DEPC";
6439 break;
7a387fff 6440 default:
f31b035a 6441 goto cp0_unimplemented;
7a387fff 6442 }
873eb012 6443 break;
8c0fdd85 6444 case 25:
7a387fff
TS
6445 switch (sel) {
6446 case 0:
7db13fae 6447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6448 rn = "Performance0";
7a387fff
TS
6449 break;
6450 case 1:
d9bea114 6451// gen_helper_mfc0_performance1(arg);
2423f660 6452 rn = "Performance1";
3570d7f6 6453 goto cp0_unimplemented;
7a387fff 6454 case 2:
d9bea114 6455// gen_helper_mfc0_performance2(arg);
2423f660 6456 rn = "Performance2";
3570d7f6 6457 goto cp0_unimplemented;
7a387fff 6458 case 3:
d9bea114 6459// gen_helper_mfc0_performance3(arg);
2423f660 6460 rn = "Performance3";
3570d7f6 6461 goto cp0_unimplemented;
7a387fff 6462 case 4:
d9bea114 6463// gen_helper_mfc0_performance4(arg);
2423f660 6464 rn = "Performance4";
3570d7f6 6465 goto cp0_unimplemented;
7a387fff 6466 case 5:
d9bea114 6467// gen_helper_mfc0_performance5(arg);
2423f660 6468 rn = "Performance5";
3570d7f6 6469 goto cp0_unimplemented;
7a387fff 6470 case 6:
d9bea114 6471// gen_helper_mfc0_performance6(arg);
2423f660 6472 rn = "Performance6";
3570d7f6 6473 goto cp0_unimplemented;
7a387fff 6474 case 7:
d9bea114 6475// gen_helper_mfc0_performance7(arg);
2423f660 6476 rn = "Performance7";
3570d7f6 6477 goto cp0_unimplemented;
7a387fff 6478 default:
f31b035a 6479 goto cp0_unimplemented;
7a387fff 6480 }
8c0fdd85
TS
6481 break;
6482 case 26:
0d74a222
LA
6483 switch (sel) {
6484 case 0:
6485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6486 rn = "ErrCtl";
6487 break;
6488 default:
6489 goto cp0_unimplemented;
6490 }
da80682b 6491 break;
8c0fdd85 6492 case 27:
7a387fff 6493 switch (sel) {
c2e19f3c
AM
6494 case 0:
6495 case 1:
6496 case 2:
6497 case 3:
d9bea114 6498 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6499 rn = "CacheErr";
6500 break;
7a387fff 6501 default:
f31b035a 6502 goto cp0_unimplemented;
7a387fff 6503 }
8c0fdd85 6504 break;
873eb012
TS
6505 case 28:
6506 switch (sel) {
6507 case 0:
7a387fff
TS
6508 case 2:
6509 case 4:
6510 case 6:
284b731a
LA
6511 {
6512 TCGv_i64 tmp = tcg_temp_new_i64();
6513 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6514 gen_move_low32(arg, tmp);
6515 tcg_temp_free_i64(tmp);
6516 }
873eb012
TS
6517 rn = "TagLo";
6518 break;
6519 case 1:
7a387fff
TS
6520 case 3:
6521 case 5:
6522 case 7:
7db13fae 6523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
6524 rn = "DataLo";
6525 break;
6526 default:
f31b035a 6527 goto cp0_unimplemented;
873eb012
TS
6528 }
6529 break;
8c0fdd85 6530 case 29:
7a387fff
TS
6531 switch (sel) {
6532 case 0:
6533 case 2:
6534 case 4:
6535 case 6:
7db13fae 6536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
6537 rn = "TagHi";
6538 break;
6539 case 1:
6540 case 3:
6541 case 5:
6542 case 7:
7db13fae 6543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
6544 rn = "DataHi";
6545 break;
6546 default:
f31b035a 6547 goto cp0_unimplemented;
7a387fff 6548 }
8c0fdd85 6549 break;
873eb012 6550 case 30:
7a387fff
TS
6551 switch (sel) {
6552 case 0:
7db13fae 6553 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 6554 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6555 rn = "ErrorEPC";
6556 break;
7a387fff 6557 default:
f31b035a 6558 goto cp0_unimplemented;
7a387fff 6559 }
873eb012
TS
6560 break;
6561 case 31:
7a387fff
TS
6562 switch (sel) {
6563 case 0:
f0b3f3ae 6564 /* EJTAG support */
7db13fae 6565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6566 rn = "DESAVE";
6567 break;
c2e19f3c
AM
6568 case 2:
6569 case 3:
6570 case 4:
6571 case 5:
6572 case 6:
6573 case 7:
f31b035a
LA
6574 CP0_CHECK(ctx->kscrexist & (1 << sel));
6575 tcg_gen_ld_tl(arg, cpu_env,
6576 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6577 tcg_gen_ext32s_tl(arg, arg);
6578 rn = "KScratch";
e98c0d17 6579 break;
7a387fff 6580 default:
f31b035a 6581 goto cp0_unimplemented;
7a387fff 6582 }
873eb012
TS
6583 break;
6584 default:
f31b035a 6585 goto cp0_unimplemented;
873eb012 6586 }
b44a7fb1 6587 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
6588 return;
6589
f31b035a 6590cp0_unimplemented:
965447ee 6591 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6592 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
6593}
6594
d75c135e 6595static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 6596{
7a387fff
TS
6597 const char *rn = "invalid";
6598
e189e748 6599 if (sel != 0)
d75c135e 6600 check_insn(ctx, ISA_MIPS32);
e189e748 6601
eeb3bba8 6602 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6603 gen_io_start();
bd79255d 6604 }
2e70f6ef 6605
8c0fdd85
TS
6606 switch (reg) {
6607 case 0:
7a387fff
TS
6608 switch (sel) {
6609 case 0:
895c2d04 6610 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
6611 rn = "Index";
6612 break;
6613 case 1:
f31b035a 6614 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6615 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 6616 rn = "MVPControl";
ead9360e 6617 break;
7a387fff 6618 case 2:
f31b035a 6619 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6620 /* ignored */
7a387fff 6621 rn = "MVPConf0";
ead9360e 6622 break;
7a387fff 6623 case 3:
f31b035a 6624 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6625 /* ignored */
7a387fff 6626 rn = "MVPConf1";
ead9360e 6627 break;
01bc435b
YK
6628 case 4:
6629 CP0_CHECK(ctx->vp);
6630 /* ignored */
6631 rn = "VPControl";
6632 break;
7a387fff 6633 default:
f31b035a 6634 goto cp0_unimplemented;
7a387fff 6635 }
8c0fdd85
TS
6636 break;
6637 case 1:
7a387fff
TS
6638 switch (sel) {
6639 case 0:
2423f660 6640 /* ignored */
7a387fff 6641 rn = "Random";
2423f660 6642 break;
7a387fff 6643 case 1:
f31b035a 6644 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6645 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 6646 rn = "VPEControl";
ead9360e 6647 break;
7a387fff 6648 case 2:
f31b035a 6649 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6650 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 6651 rn = "VPEConf0";
ead9360e 6652 break;
7a387fff 6653 case 3:
f31b035a 6654 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6655 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 6656 rn = "VPEConf1";
ead9360e 6657 break;
7a387fff 6658 case 4:
f31b035a 6659 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6660 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 6661 rn = "YQMask";
ead9360e 6662 break;
7a387fff 6663 case 5:
f31b035a 6664 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6665 tcg_gen_st_tl(arg, cpu_env,
6666 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 6667 rn = "VPESchedule";
ead9360e 6668 break;
7a387fff 6669 case 6:
f31b035a 6670 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6671 tcg_gen_st_tl(arg, cpu_env,
6672 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 6673 rn = "VPEScheFBack";
ead9360e 6674 break;
7a387fff 6675 case 7:
f31b035a 6676 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6677 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 6678 rn = "VPEOpt";
ead9360e 6679 break;
7a387fff 6680 default:
f31b035a 6681 goto cp0_unimplemented;
7a387fff 6682 }
8c0fdd85
TS
6683 break;
6684 case 2:
7a387fff
TS
6685 switch (sel) {
6686 case 0:
895c2d04 6687 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
6688 rn = "EntryLo0";
6689 break;
7a387fff 6690 case 1:
f31b035a 6691 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6692 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6693 rn = "TCStatus";
ead9360e 6694 break;
7a387fff 6695 case 2:
f31b035a 6696 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6697 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6698 rn = "TCBind";
ead9360e 6699 break;
7a387fff 6700 case 3:
f31b035a 6701 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6702 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6703 rn = "TCRestart";
ead9360e 6704 break;
7a387fff 6705 case 4:
f31b035a 6706 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6707 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6708 rn = "TCHalt";
ead9360e 6709 break;
7a387fff 6710 case 5:
f31b035a 6711 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6712 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6713 rn = "TCContext";
ead9360e 6714 break;
7a387fff 6715 case 6:
f31b035a 6716 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6717 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6718 rn = "TCSchedule";
ead9360e 6719 break;
7a387fff 6720 case 7:
f31b035a 6721 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6722 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6723 rn = "TCScheFBack";
ead9360e 6724 break;
7a387fff 6725 default:
f31b035a 6726 goto cp0_unimplemented;
7a387fff 6727 }
8c0fdd85
TS
6728 break;
6729 case 3:
7a387fff
TS
6730 switch (sel) {
6731 case 0:
895c2d04 6732 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6733 rn = "EntryLo1";
6734 break;
01bc435b
YK
6735 case 1:
6736 CP0_CHECK(ctx->vp);
6737 /* ignored */
6738 rn = "GlobalNumber";
6739 break;
7a387fff 6740 default:
f31b035a 6741 goto cp0_unimplemented;
876d4b07 6742 }
8c0fdd85
TS
6743 break;
6744 case 4:
7a387fff
TS
6745 switch (sel) {
6746 case 0:
895c2d04 6747 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6748 rn = "Context";
6749 break;
7a387fff 6750 case 1:
895c2d04 6751// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6752 rn = "ContextConfig";
f31b035a 6753 goto cp0_unimplemented;
d279279e 6754 case 2:
f31b035a
LA
6755 CP0_CHECK(ctx->ulri);
6756 tcg_gen_st_tl(arg, cpu_env,
6757 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6758 rn = "UserLocal";
d279279e 6759 break;
7a387fff 6760 default:
f31b035a 6761 goto cp0_unimplemented;
876d4b07 6762 }
8c0fdd85
TS
6763 break;
6764 case 5:
7a387fff
TS
6765 switch (sel) {
6766 case 0:
895c2d04 6767 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6768 rn = "PageMask";
6769 break;
7a387fff 6770 case 1:
d75c135e 6771 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6772 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 6773 rn = "PageGrain";
eeb3bba8 6774 ctx->base.is_jmp = DISAS_STOP;
2423f660 6775 break;
cec56a73
JH
6776 case 2:
6777 CP0_CHECK(ctx->sc);
6778 gen_helper_mtc0_segctl0(cpu_env, arg);
6779 rn = "SegCtl0";
6780 break;
6781 case 3:
6782 CP0_CHECK(ctx->sc);
6783 gen_helper_mtc0_segctl1(cpu_env, arg);
6784 rn = "SegCtl1";
6785 break;
6786 case 4:
6787 CP0_CHECK(ctx->sc);
6788 gen_helper_mtc0_segctl2(cpu_env, arg);
6789 rn = "SegCtl2";
6790 break;
7a387fff 6791 default:
f31b035a 6792 goto cp0_unimplemented;
876d4b07 6793 }
8c0fdd85
TS
6794 break;
6795 case 6:
7a387fff
TS
6796 switch (sel) {
6797 case 0:
895c2d04 6798 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6799 rn = "Wired";
6800 break;
7a387fff 6801 case 1:
d75c135e 6802 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6803 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6804 rn = "SRSConf0";
ead9360e 6805 break;
7a387fff 6806 case 2:
d75c135e 6807 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6808 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6809 rn = "SRSConf1";
ead9360e 6810 break;
7a387fff 6811 case 3:
d75c135e 6812 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6813 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6814 rn = "SRSConf2";
ead9360e 6815 break;
7a387fff 6816 case 4:
d75c135e 6817 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6818 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6819 rn = "SRSConf3";
ead9360e 6820 break;
7a387fff 6821 case 5:
d75c135e 6822 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6823 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6824 rn = "SRSConf4";
ead9360e 6825 break;
7a387fff 6826 default:
f31b035a 6827 goto cp0_unimplemented;
876d4b07 6828 }
8c0fdd85
TS
6829 break;
6830 case 7:
7a387fff
TS
6831 switch (sel) {
6832 case 0:
d75c135e 6833 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6834 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6835 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6836 rn = "HWREna";
6837 break;
7a387fff 6838 default:
f31b035a 6839 goto cp0_unimplemented;
876d4b07 6840 }
8c0fdd85
TS
6841 break;
6842 case 8:
aea14095
LA
6843 switch (sel) {
6844 case 0:
6845 /* ignored */
6846 rn = "BadVAddr";
6847 break;
6848 case 1:
6849 /* ignored */
6850 rn = "BadInstr";
6851 break;
6852 case 2:
6853 /* ignored */
6854 rn = "BadInstrP";
6855 break;
25beba9b
SM
6856 case 3:
6857 /* ignored */
6858 rn = "BadInstrX";
6859 break;
aea14095 6860 default:
f31b035a 6861 goto cp0_unimplemented;
aea14095 6862 }
8c0fdd85
TS
6863 break;
6864 case 9:
7a387fff
TS
6865 switch (sel) {
6866 case 0:
895c2d04 6867 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6868 rn = "Count";
6869 break;
876d4b07 6870 /* 6,7 are implementation dependent */
7a387fff 6871 default:
f31b035a 6872 goto cp0_unimplemented;
876d4b07 6873 }
8c0fdd85
TS
6874 break;
6875 case 10:
7a387fff
TS
6876 switch (sel) {
6877 case 0:
895c2d04 6878 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6879 rn = "EntryHi";
6880 break;
7a387fff 6881 default:
f31b035a 6882 goto cp0_unimplemented;
876d4b07 6883 }
8c0fdd85
TS
6884 break;
6885 case 11:
7a387fff
TS
6886 switch (sel) {
6887 case 0:
895c2d04 6888 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6889 rn = "Compare";
6890 break;
6891 /* 6,7 are implementation dependent */
7a387fff 6892 default:
f31b035a 6893 goto cp0_unimplemented;
876d4b07 6894 }
8c0fdd85
TS
6895 break;
6896 case 12:
7a387fff
TS
6897 switch (sel) {
6898 case 0:
867abc7e 6899 save_cpu_state(ctx, 1);
895c2d04 6900 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6901 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6902 gen_save_pc(ctx->base.pc_next + 4);
6903 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6904 rn = "Status";
6905 break;
7a387fff 6906 case 1:
d75c135e 6907 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6908 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6909 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6910 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6911 rn = "IntCtl";
6912 break;
7a387fff 6913 case 2:
d75c135e 6914 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6915 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6916 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6917 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6918 rn = "SRSCtl";
6919 break;
7a387fff 6920 case 3:
d75c135e 6921 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6922 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6923 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6924 ctx->base.is_jmp = DISAS_STOP;
2423f660 6925 rn = "SRSMap";
fd88b6ab 6926 break;
7a387fff 6927 default:
f31b035a 6928 goto cp0_unimplemented;
876d4b07 6929 }
8c0fdd85
TS
6930 break;
6931 case 13:
7a387fff
TS
6932 switch (sel) {
6933 case 0:
867abc7e 6934 save_cpu_state(ctx, 1);
895c2d04 6935 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6936 /* Stop translation as we may have triggered an interrupt.
6937 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6938 * translated code to check for pending interrupts. */
eeb3bba8
EC
6939 gen_save_pc(ctx->base.pc_next + 4);
6940 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6941 rn = "Cause";
6942 break;
7a387fff 6943 default:
f31b035a 6944 goto cp0_unimplemented;
876d4b07 6945 }
8c0fdd85
TS
6946 break;
6947 case 14:
7a387fff
TS
6948 switch (sel) {
6949 case 0:
d54a299b 6950 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6951 rn = "EPC";
6952 break;
7a387fff 6953 default:
f31b035a 6954 goto cp0_unimplemented;
876d4b07 6955 }
8c0fdd85
TS
6956 break;
6957 case 15:
7a387fff
TS
6958 switch (sel) {
6959 case 0:
2423f660
TS
6960 /* ignored */
6961 rn = "PRid";
6962 break;
7a387fff 6963 case 1:
d75c135e 6964 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6965 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6966 rn = "EBase";
6967 break;
7a387fff 6968 default:
f31b035a 6969 goto cp0_unimplemented;
1579a72e 6970 }
8c0fdd85
TS
6971 break;
6972 case 16:
6973 switch (sel) {
6974 case 0:
895c2d04 6975 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6976 rn = "Config";
2423f660 6977 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6978 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6979 break;
6980 case 1:
e397ee33 6981 /* ignored, read only */
7a387fff
TS
6982 rn = "Config1";
6983 break;
6984 case 2:
895c2d04 6985 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6986 rn = "Config2";
2423f660 6987 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6988 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6989 break;
7a387fff 6990 case 3:
90f12d73 6991 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6992 rn = "Config3";
90f12d73 6993 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6994 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6995 break;
b4160af1
PJ
6996 case 4:
6997 gen_helper_mtc0_config4(cpu_env, arg);
6998 rn = "Config4";
eeb3bba8 6999 ctx->base.is_jmp = DISAS_STOP;
b4160af1 7000 break;
b4dd99a3
PJ
7001 case 5:
7002 gen_helper_mtc0_config5(cpu_env, arg);
7003 rn = "Config5";
7004 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7005 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 7006 break;
e397ee33
TS
7007 /* 6,7 are implementation dependent */
7008 case 6:
7009 /* ignored */
7010 rn = "Config6";
7011 break;
7012 case 7:
7013 /* ignored */
7014 rn = "Config7";
7015 break;
8c0fdd85
TS
7016 default:
7017 rn = "Invalid config selector";
f31b035a 7018 goto cp0_unimplemented;
8c0fdd85
TS
7019 }
7020 break;
7021 case 17:
7a387fff
TS
7022 switch (sel) {
7023 case 0:
895c2d04 7024 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7025 rn = "LLAddr";
7026 break;
f6d4dd81
YK
7027 case 1:
7028 CP0_CHECK(ctx->mrp);
7029 gen_helper_mtc0_maar(cpu_env, arg);
7030 rn = "MAAR";
7031 break;
7032 case 2:
7033 CP0_CHECK(ctx->mrp);
7034 gen_helper_mtc0_maari(cpu_env, arg);
7035 rn = "MAARI";
7036 break;
7a387fff 7037 default:
f31b035a 7038 goto cp0_unimplemented;
7a387fff 7039 }
8c0fdd85
TS
7040 break;
7041 case 18:
7a387fff 7042 switch (sel) {
c2e19f3c
AM
7043 case 0:
7044 case 1:
7045 case 2:
7046 case 3:
7047 case 4:
7048 case 5:
7049 case 6:
7050 case 7:
fa192d49 7051 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7052 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7053 rn = "WatchLo";
7054 break;
7a387fff 7055 default:
f31b035a 7056 goto cp0_unimplemented;
7a387fff 7057 }
8c0fdd85
TS
7058 break;
7059 case 19:
7a387fff 7060 switch (sel) {
c2e19f3c
AM
7061 case 0:
7062 case 1:
7063 case 2:
7064 case 3:
7065 case 4:
7066 case 5:
7067 case 6:
7068 case 7:
fa192d49 7069 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7070 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7071 rn = "WatchHi";
7072 break;
7a387fff 7073 default:
f31b035a 7074 goto cp0_unimplemented;
7a387fff 7075 }
8c0fdd85
TS
7076 break;
7077 case 20:
7a387fff
TS
7078 switch (sel) {
7079 case 0:
d26bc211 7080#if defined(TARGET_MIPS64)
d75c135e 7081 check_insn(ctx, ISA_MIPS3);
895c2d04 7082 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7083 rn = "XContext";
7084 break;
703eaf37 7085#endif
7a387fff 7086 default:
f31b035a 7087 goto cp0_unimplemented;
7a387fff 7088 }
8c0fdd85
TS
7089 break;
7090 case 21:
7a387fff 7091 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7092 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7093 switch (sel) {
7094 case 0:
895c2d04 7095 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7096 rn = "Framemask";
7097 break;
7a387fff 7098 default:
f31b035a 7099 goto cp0_unimplemented;
7a387fff
TS
7100 }
7101 break;
8c0fdd85 7102 case 22:
7a387fff
TS
7103 /* ignored */
7104 rn = "Diagnostic"; /* implementation dependent */
2423f660 7105 break;
8c0fdd85 7106 case 23:
7a387fff
TS
7107 switch (sel) {
7108 case 0:
895c2d04 7109 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7110 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7111 gen_save_pc(ctx->base.pc_next + 4);
7112 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7113 rn = "Debug";
7114 break;
7a387fff 7115 case 1:
895c2d04 7116// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 7117 rn = "TraceControl";
8487327a 7118 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7119 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7120 goto cp0_unimplemented;
7a387fff 7121 case 2:
895c2d04 7122// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 7123 rn = "TraceControl2";
8487327a 7124 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7125 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7126 goto cp0_unimplemented;
7a387fff 7127 case 3:
8487327a 7128 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7129 ctx->base.is_jmp = DISAS_STOP;
895c2d04 7130// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 7131 rn = "UserTraceData";
8487327a 7132 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7133 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7134 goto cp0_unimplemented;
7a387fff 7135 case 4:
895c2d04 7136// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7137 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7138 ctx->base.is_jmp = DISAS_STOP;
2423f660 7139 rn = "TraceBPC";
3570d7f6 7140 goto cp0_unimplemented;
7a387fff 7141 default:
f31b035a 7142 goto cp0_unimplemented;
7a387fff 7143 }
8c0fdd85
TS
7144 break;
7145 case 24:
7a387fff
TS
7146 switch (sel) {
7147 case 0:
f1aa6320 7148 /* EJTAG support */
d54a299b 7149 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7150 rn = "DEPC";
7151 break;
7a387fff 7152 default:
f31b035a 7153 goto cp0_unimplemented;
7a387fff 7154 }
8c0fdd85
TS
7155 break;
7156 case 25:
7a387fff
TS
7157 switch (sel) {
7158 case 0:
895c2d04 7159 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7160 rn = "Performance0";
7161 break;
7a387fff 7162 case 1:
d9bea114 7163// gen_helper_mtc0_performance1(arg);
2423f660 7164 rn = "Performance1";
3570d7f6 7165 goto cp0_unimplemented;
7a387fff 7166 case 2:
d9bea114 7167// gen_helper_mtc0_performance2(arg);
2423f660 7168 rn = "Performance2";
3570d7f6 7169 goto cp0_unimplemented;
7a387fff 7170 case 3:
d9bea114 7171// gen_helper_mtc0_performance3(arg);
2423f660 7172 rn = "Performance3";
3570d7f6 7173 goto cp0_unimplemented;
7a387fff 7174 case 4:
d9bea114 7175// gen_helper_mtc0_performance4(arg);
2423f660 7176 rn = "Performance4";
3570d7f6 7177 goto cp0_unimplemented;
7a387fff 7178 case 5:
d9bea114 7179// gen_helper_mtc0_performance5(arg);
2423f660 7180 rn = "Performance5";
3570d7f6 7181 goto cp0_unimplemented;
7a387fff 7182 case 6:
d9bea114 7183// gen_helper_mtc0_performance6(arg);
2423f660 7184 rn = "Performance6";
3570d7f6 7185 goto cp0_unimplemented;
7a387fff 7186 case 7:
d9bea114 7187// gen_helper_mtc0_performance7(arg);
2423f660 7188 rn = "Performance7";
3570d7f6 7189 goto cp0_unimplemented;
7a387fff 7190 default:
f31b035a 7191 goto cp0_unimplemented;
7a387fff 7192 }
8c0fdd85
TS
7193 break;
7194 case 26:
0d74a222
LA
7195 switch (sel) {
7196 case 0:
7197 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7198 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7199 rn = "ErrCtl";
7200 break;
7201 default:
7202 goto cp0_unimplemented;
7203 }
2423f660 7204 break;
8c0fdd85 7205 case 27:
7a387fff 7206 switch (sel) {
c2e19f3c
AM
7207 case 0:
7208 case 1:
7209 case 2:
7210 case 3:
2423f660
TS
7211 /* ignored */
7212 rn = "CacheErr";
7213 break;
7a387fff 7214 default:
f31b035a 7215 goto cp0_unimplemented;
7a387fff 7216 }
8c0fdd85
TS
7217 break;
7218 case 28:
7219 switch (sel) {
7220 case 0:
7a387fff
TS
7221 case 2:
7222 case 4:
7223 case 6:
895c2d04 7224 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
7225 rn = "TagLo";
7226 break;
7a387fff
TS
7227 case 1:
7228 case 3:
7229 case 5:
7230 case 7:
895c2d04 7231 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
7232 rn = "DataLo";
7233 break;
8c0fdd85 7234 default:
f31b035a 7235 goto cp0_unimplemented;
8c0fdd85
TS
7236 }
7237 break;
7238 case 29:
7a387fff
TS
7239 switch (sel) {
7240 case 0:
7241 case 2:
7242 case 4:
7243 case 6:
895c2d04 7244 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
7245 rn = "TagHi";
7246 break;
7247 case 1:
7248 case 3:
7249 case 5:
7250 case 7:
895c2d04 7251 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
7252 rn = "DataHi";
7253 break;
7254 default:
7255 rn = "invalid sel";
f31b035a 7256 goto cp0_unimplemented;
7a387fff 7257 }
8c0fdd85
TS
7258 break;
7259 case 30:
7a387fff
TS
7260 switch (sel) {
7261 case 0:
d54a299b 7262 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7263 rn = "ErrorEPC";
7264 break;
7a387fff 7265 default:
f31b035a 7266 goto cp0_unimplemented;
7a387fff 7267 }
8c0fdd85
TS
7268 break;
7269 case 31:
7a387fff
TS
7270 switch (sel) {
7271 case 0:
f1aa6320 7272 /* EJTAG support */
7db13fae 7273 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7274 rn = "DESAVE";
7275 break;
c2e19f3c
AM
7276 case 2:
7277 case 3:
7278 case 4:
7279 case 5:
7280 case 6:
7281 case 7:
f31b035a
LA
7282 CP0_CHECK(ctx->kscrexist & (1 << sel));
7283 tcg_gen_st_tl(arg, cpu_env,
7284 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7285 rn = "KScratch";
e98c0d17 7286 break;
7a387fff 7287 default:
f31b035a 7288 goto cp0_unimplemented;
7a387fff 7289 }
8c0fdd85
TS
7290 break;
7291 default:
f31b035a 7292 goto cp0_unimplemented;
8c0fdd85 7293 }
b44a7fb1
PMD
7294 trace_mips_translate_c0("mtc0", rn, reg, sel);
7295
bf20dc07 7296 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7297 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7298 gen_io_end();
b28425ba 7299 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7300 * translated code to check for pending interrupts. */
eeb3bba8
EC
7301 gen_save_pc(ctx->base.pc_next + 4);
7302 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7303 }
8c0fdd85
TS
7304 return;
7305
f31b035a 7306cp0_unimplemented:
965447ee 7307 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
7308}
7309
d26bc211 7310#if defined(TARGET_MIPS64)
d75c135e 7311static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7312{
7313 const char *rn = "invalid";
7314
e189e748 7315 if (sel != 0)
d75c135e 7316 check_insn(ctx, ISA_MIPS64);
e189e748 7317
9c2149c8
TS
7318 switch (reg) {
7319 case 0:
7320 switch (sel) {
7321 case 0:
7db13fae 7322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
7323 rn = "Index";
7324 break;
7325 case 1:
f31b035a 7326 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7327 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 7328 rn = "MVPControl";
ead9360e 7329 break;
9c2149c8 7330 case 2:
f31b035a 7331 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7332 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 7333 rn = "MVPConf0";
ead9360e 7334 break;
9c2149c8 7335 case 3:
f31b035a 7336 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7337 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 7338 rn = "MVPConf1";
ead9360e 7339 break;
01bc435b
YK
7340 case 4:
7341 CP0_CHECK(ctx->vp);
7342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7343 rn = "VPControl";
7344 break;
9c2149c8 7345 default:
f31b035a 7346 goto cp0_unimplemented;
9c2149c8
TS
7347 }
7348 break;
7349 case 1:
7350 switch (sel) {
7351 case 0:
f31b035a 7352 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 7353 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 7354 rn = "Random";
2423f660 7355 break;
9c2149c8 7356 case 1:
f31b035a 7357 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 7359 rn = "VPEControl";
ead9360e 7360 break;
9c2149c8 7361 case 2:
f31b035a 7362 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 7364 rn = "VPEConf0";
ead9360e 7365 break;
9c2149c8 7366 case 3:
f31b035a 7367 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 7369 rn = "VPEConf1";
ead9360e 7370 break;
9c2149c8 7371 case 4:
f31b035a 7372 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 7374 rn = "YQMask";
ead9360e 7375 break;
9c2149c8 7376 case 5:
f31b035a 7377 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7379 rn = "VPESchedule";
ead9360e 7380 break;
9c2149c8 7381 case 6:
f31b035a 7382 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7383 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7384 rn = "VPEScheFBack";
ead9360e 7385 break;
9c2149c8 7386 case 7:
f31b035a 7387 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 7389 rn = "VPEOpt";
ead9360e 7390 break;
9c2149c8 7391 default:
f31b035a 7392 goto cp0_unimplemented;
9c2149c8
TS
7393 }
7394 break;
7395 case 2:
7396 switch (sel) {
7397 case 0:
7db13fae 7398 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
7399 rn = "EntryLo0";
7400 break;
9c2149c8 7401 case 1:
f31b035a 7402 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7403 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 7404 rn = "TCStatus";
ead9360e 7405 break;
9c2149c8 7406 case 2:
f31b035a 7407 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7408 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 7409 rn = "TCBind";
ead9360e 7410 break;
9c2149c8 7411 case 3:
f31b035a 7412 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7413 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 7414 rn = "TCRestart";
ead9360e 7415 break;
9c2149c8 7416 case 4:
f31b035a 7417 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7418 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 7419 rn = "TCHalt";
ead9360e 7420 break;
9c2149c8 7421 case 5:
f31b035a 7422 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7423 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 7424 rn = "TCContext";
ead9360e 7425 break;
9c2149c8 7426 case 6:
f31b035a 7427 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7428 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 7429 rn = "TCSchedule";
ead9360e 7430 break;
9c2149c8 7431 case 7:
f31b035a 7432 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7433 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 7434 rn = "TCScheFBack";
ead9360e 7435 break;
9c2149c8 7436 default:
f31b035a 7437 goto cp0_unimplemented;
9c2149c8
TS
7438 }
7439 break;
7440 case 3:
7441 switch (sel) {
7442 case 0:
7db13fae 7443 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
7444 rn = "EntryLo1";
7445 break;
01bc435b
YK
7446 case 1:
7447 CP0_CHECK(ctx->vp);
7448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7449 rn = "GlobalNumber";
7450 break;
9c2149c8 7451 default:
f31b035a 7452 goto cp0_unimplemented;
1579a72e 7453 }
9c2149c8
TS
7454 break;
7455 case 4:
7456 switch (sel) {
7457 case 0:
7db13fae 7458 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
7459 rn = "Context";
7460 break;
9c2149c8 7461 case 1:
d9bea114 7462// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 7463 rn = "ContextConfig";
f31b035a 7464 goto cp0_unimplemented;
d279279e 7465 case 2:
f31b035a
LA
7466 CP0_CHECK(ctx->ulri);
7467 tcg_gen_ld_tl(arg, cpu_env,
7468 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7469 rn = "UserLocal";
d279279e 7470 break;
9c2149c8 7471 default:
f31b035a 7472 goto cp0_unimplemented;
876d4b07 7473 }
9c2149c8
TS
7474 break;
7475 case 5:
7476 switch (sel) {
7477 case 0:
7db13fae 7478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
7479 rn = "PageMask";
7480 break;
9c2149c8 7481 case 1:
d75c135e 7482 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
7484 rn = "PageGrain";
7485 break;
cec56a73
JH
7486 case 2:
7487 CP0_CHECK(ctx->sc);
7488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7489 rn = "SegCtl0";
7490 break;
7491 case 3:
7492 CP0_CHECK(ctx->sc);
7493 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7494 rn = "SegCtl1";
7495 break;
7496 case 4:
7497 CP0_CHECK(ctx->sc);
7498 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7499 rn = "SegCtl2";
7500 break;
9c2149c8 7501 default:
f31b035a 7502 goto cp0_unimplemented;
876d4b07 7503 }
9c2149c8
TS
7504 break;
7505 case 6:
7506 switch (sel) {
7507 case 0:
7db13fae 7508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
7509 rn = "Wired";
7510 break;
9c2149c8 7511 case 1:
d75c135e 7512 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 7514 rn = "SRSConf0";
ead9360e 7515 break;
9c2149c8 7516 case 2:
d75c135e 7517 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 7519 rn = "SRSConf1";
ead9360e 7520 break;
9c2149c8 7521 case 3:
d75c135e 7522 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 7524 rn = "SRSConf2";
ead9360e 7525 break;
9c2149c8 7526 case 4:
d75c135e 7527 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 7529 rn = "SRSConf3";
ead9360e 7530 break;
9c2149c8 7531 case 5:
d75c135e 7532 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 7534 rn = "SRSConf4";
ead9360e 7535 break;
9c2149c8 7536 default:
f31b035a 7537 goto cp0_unimplemented;
876d4b07 7538 }
9c2149c8
TS
7539 break;
7540 case 7:
7541 switch (sel) {
7542 case 0:
d75c135e 7543 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
7545 rn = "HWREna";
7546 break;
9c2149c8 7547 default:
f31b035a 7548 goto cp0_unimplemented;
876d4b07 7549 }
9c2149c8
TS
7550 break;
7551 case 8:
7552 switch (sel) {
7553 case 0:
7db13fae 7554 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 7555 rn = "BadVAddr";
2423f660 7556 break;
aea14095 7557 case 1:
f31b035a
LA
7558 CP0_CHECK(ctx->bi);
7559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7560 rn = "BadInstr";
aea14095
LA
7561 break;
7562 case 2:
f31b035a
LA
7563 CP0_CHECK(ctx->bp);
7564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7565 rn = "BadInstrP";
aea14095 7566 break;
25beba9b
SM
7567 case 3:
7568 CP0_CHECK(ctx->bi);
7569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7570 tcg_gen_andi_tl(arg, arg, ~0xffff);
7571 rn = "BadInstrX";
7572 break;
9c2149c8 7573 default:
f31b035a 7574 goto cp0_unimplemented;
876d4b07 7575 }
9c2149c8
TS
7576 break;
7577 case 9:
7578 switch (sel) {
7579 case 0:
2e70f6ef 7580 /* Mark as an IO operation because we read the time. */
eeb3bba8 7581 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7582 gen_io_start();
bd79255d 7583 }
895c2d04 7584 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 7585 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7586 gen_io_end();
2e70f6ef 7587 }
55807224 7588 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
7589 after reading count. DISAS_STOP isn't sufficient, we need to
7590 ensure we break completely out of translated code. */
eeb3bba8
EC
7591 gen_save_pc(ctx->base.pc_next + 4);
7592 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7593 rn = "Count";
7594 break;
7595 /* 6,7 are implementation dependent */
9c2149c8 7596 default:
f31b035a 7597 goto cp0_unimplemented;
876d4b07 7598 }
9c2149c8
TS
7599 break;
7600 case 10:
7601 switch (sel) {
7602 case 0:
7db13fae 7603 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
7604 rn = "EntryHi";
7605 break;
9c2149c8 7606 default:
f31b035a 7607 goto cp0_unimplemented;
876d4b07 7608 }
9c2149c8
TS
7609 break;
7610 case 11:
7611 switch (sel) {
7612 case 0:
7db13fae 7613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
7614 rn = "Compare";
7615 break;
876d4b07 7616 /* 6,7 are implementation dependent */
9c2149c8 7617 default:
f31b035a 7618 goto cp0_unimplemented;
876d4b07 7619 }
9c2149c8
TS
7620 break;
7621 case 12:
7622 switch (sel) {
7623 case 0:
7db13fae 7624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
7625 rn = "Status";
7626 break;
9c2149c8 7627 case 1:
d75c135e 7628 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
7630 rn = "IntCtl";
7631 break;
9c2149c8 7632 case 2:
d75c135e 7633 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
7635 rn = "SRSCtl";
7636 break;
9c2149c8 7637 case 3:
d75c135e 7638 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
7640 rn = "SRSMap";
7641 break;
9c2149c8 7642 default:
f31b035a 7643 goto cp0_unimplemented;
876d4b07 7644 }
9c2149c8
TS
7645 break;
7646 case 13:
7647 switch (sel) {
7648 case 0:
7db13fae 7649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
7650 rn = "Cause";
7651 break;
9c2149c8 7652 default:
f31b035a 7653 goto cp0_unimplemented;
876d4b07 7654 }
9c2149c8
TS
7655 break;
7656 case 14:
7657 switch (sel) {
7658 case 0:
7db13fae 7659 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7660 rn = "EPC";
7661 break;
9c2149c8 7662 default:
f31b035a 7663 goto cp0_unimplemented;
876d4b07 7664 }
9c2149c8
TS
7665 break;
7666 case 15:
7667 switch (sel) {
7668 case 0:
7db13fae 7669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
7670 rn = "PRid";
7671 break;
9c2149c8 7672 case 1:
d75c135e 7673 check_insn(ctx, ISA_MIPS32R2);
74dbf824 7674 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
7675 rn = "EBase";
7676 break;
c870e3f5
YK
7677 case 3:
7678 check_insn(ctx, ISA_MIPS32R2);
7679 CP0_CHECK(ctx->cmgcr);
7680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7681 rn = "CMGCRBase";
7682 break;
9c2149c8 7683 default:
f31b035a 7684 goto cp0_unimplemented;
876d4b07 7685 }
9c2149c8
TS
7686 break;
7687 case 16:
7688 switch (sel) {
7689 case 0:
7db13fae 7690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
7691 rn = "Config";
7692 break;
7693 case 1:
7db13fae 7694 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
7695 rn = "Config1";
7696 break;
7697 case 2:
7db13fae 7698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
7699 rn = "Config2";
7700 break;
7701 case 3:
7db13fae 7702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
7703 rn = "Config3";
7704 break;
faf1f68b
LA
7705 case 4:
7706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7707 rn = "Config4";
7708 break;
7709 case 5:
7710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7711 rn = "Config5";
7712 break;
9c2149c8 7713 /* 6,7 are implementation dependent */
f0b3f3ae 7714 case 6:
7db13fae 7715 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
7716 rn = "Config6";
7717 break;
7718 case 7:
7db13fae 7719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
7720 rn = "Config7";
7721 break;
9c2149c8 7722 default:
f31b035a 7723 goto cp0_unimplemented;
9c2149c8
TS
7724 }
7725 break;
7726 case 17:
7727 switch (sel) {
7728 case 0:
895c2d04 7729 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
7730 rn = "LLAddr";
7731 break;
f6d4dd81
YK
7732 case 1:
7733 CP0_CHECK(ctx->mrp);
7734 gen_helper_dmfc0_maar(arg, cpu_env);
7735 rn = "MAAR";
7736 break;
7737 case 2:
7738 CP0_CHECK(ctx->mrp);
7739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7740 rn = "MAARI";
7741 break;
9c2149c8 7742 default:
f31b035a 7743 goto cp0_unimplemented;
9c2149c8
TS
7744 }
7745 break;
7746 case 18:
7747 switch (sel) {
c2e19f3c
AM
7748 case 0:
7749 case 1:
7750 case 2:
7751 case 3:
7752 case 4:
7753 case 5:
7754 case 6:
7755 case 7:
fa192d49 7756 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7757 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
7758 rn = "WatchLo";
7759 break;
9c2149c8 7760 default:
f31b035a 7761 goto cp0_unimplemented;
9c2149c8
TS
7762 }
7763 break;
7764 case 19:
7765 switch (sel) {
c2e19f3c
AM
7766 case 0:
7767 case 1:
7768 case 2:
7769 case 3:
7770 case 4:
7771 case 5:
7772 case 6:
7773 case 7:
fa192d49 7774 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7775 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
7776 rn = "WatchHi";
7777 break;
9c2149c8 7778 default:
f31b035a 7779 goto cp0_unimplemented;
9c2149c8
TS
7780 }
7781 break;
7782 case 20:
7783 switch (sel) {
7784 case 0:
d75c135e 7785 check_insn(ctx, ISA_MIPS3);
7db13fae 7786 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
7787 rn = "XContext";
7788 break;
9c2149c8 7789 default:
f31b035a 7790 goto cp0_unimplemented;
9c2149c8
TS
7791 }
7792 break;
7793 case 21:
7794 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7795 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7796 switch (sel) {
7797 case 0:
7db13fae 7798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
7799 rn = "Framemask";
7800 break;
9c2149c8 7801 default:
f31b035a 7802 goto cp0_unimplemented;
9c2149c8
TS
7803 }
7804 break;
7805 case 22:
d9bea114 7806 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7807 rn = "'Diagnostic"; /* implementation dependent */
7808 break;
9c2149c8
TS
7809 case 23:
7810 switch (sel) {
7811 case 0:
895c2d04 7812 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
7813 rn = "Debug";
7814 break;
9c2149c8 7815 case 1:
895c2d04 7816// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 7817 rn = "TraceControl";
3570d7f6 7818 goto cp0_unimplemented;
9c2149c8 7819 case 2:
895c2d04 7820// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 7821 rn = "TraceControl2";
3570d7f6 7822 goto cp0_unimplemented;
9c2149c8 7823 case 3:
895c2d04 7824// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 7825 rn = "UserTraceData";
3570d7f6 7826 goto cp0_unimplemented;
9c2149c8 7827 case 4:
895c2d04 7828// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 7829 rn = "TraceBPC";
3570d7f6 7830 goto cp0_unimplemented;
9c2149c8 7831 default:
f31b035a 7832 goto cp0_unimplemented;
9c2149c8
TS
7833 }
7834 break;
7835 case 24:
7836 switch (sel) {
7837 case 0:
f0b3f3ae 7838 /* EJTAG support */
7db13fae 7839 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7840 rn = "DEPC";
7841 break;
9c2149c8 7842 default:
f31b035a 7843 goto cp0_unimplemented;
9c2149c8
TS
7844 }
7845 break;
7846 case 25:
7847 switch (sel) {
7848 case 0:
7db13fae 7849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7850 rn = "Performance0";
9c2149c8
TS
7851 break;
7852 case 1:
d9bea114 7853// gen_helper_dmfc0_performance1(arg);
2423f660 7854 rn = "Performance1";
3570d7f6 7855 goto cp0_unimplemented;
9c2149c8 7856 case 2:
d9bea114 7857// gen_helper_dmfc0_performance2(arg);
2423f660 7858 rn = "Performance2";
3570d7f6 7859 goto cp0_unimplemented;
9c2149c8 7860 case 3:
d9bea114 7861// gen_helper_dmfc0_performance3(arg);
2423f660 7862 rn = "Performance3";
3570d7f6 7863 goto cp0_unimplemented;
9c2149c8 7864 case 4:
d9bea114 7865// gen_helper_dmfc0_performance4(arg);
2423f660 7866 rn = "Performance4";
3570d7f6 7867 goto cp0_unimplemented;
9c2149c8 7868 case 5:
d9bea114 7869// gen_helper_dmfc0_performance5(arg);
2423f660 7870 rn = "Performance5";
3570d7f6 7871 goto cp0_unimplemented;
9c2149c8 7872 case 6:
d9bea114 7873// gen_helper_dmfc0_performance6(arg);
2423f660 7874 rn = "Performance6";
3570d7f6 7875 goto cp0_unimplemented;
9c2149c8 7876 case 7:
d9bea114 7877// gen_helper_dmfc0_performance7(arg);
2423f660 7878 rn = "Performance7";
3570d7f6 7879 goto cp0_unimplemented;
9c2149c8 7880 default:
f31b035a 7881 goto cp0_unimplemented;
9c2149c8
TS
7882 }
7883 break;
7884 case 26:
0d74a222
LA
7885 switch (sel) {
7886 case 0:
7887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7888 rn = "ErrCtl";
7889 break;
7890 default:
7891 goto cp0_unimplemented;
7892 }
da80682b 7893 break;
9c2149c8
TS
7894 case 27:
7895 switch (sel) {
7896 /* ignored */
c2e19f3c
AM
7897 case 0:
7898 case 1:
7899 case 2:
7900 case 3:
d9bea114 7901 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7902 rn = "CacheErr";
7903 break;
9c2149c8 7904 default:
f31b035a 7905 goto cp0_unimplemented;
9c2149c8
TS
7906 }
7907 break;
7908 case 28:
7909 switch (sel) {
7910 case 0:
7911 case 2:
7912 case 4:
7913 case 6:
7db13fae 7914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7915 rn = "TagLo";
7916 break;
7917 case 1:
7918 case 3:
7919 case 5:
7920 case 7:
7db13fae 7921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7922 rn = "DataLo";
7923 break;
7924 default:
f31b035a 7925 goto cp0_unimplemented;
9c2149c8
TS
7926 }
7927 break;
7928 case 29:
7929 switch (sel) {
7930 case 0:
7931 case 2:
7932 case 4:
7933 case 6:
7db13fae 7934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7935 rn = "TagHi";
7936 break;
7937 case 1:
7938 case 3:
7939 case 5:
7940 case 7:
7db13fae 7941 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7942 rn = "DataHi";
7943 break;
7944 default:
f31b035a 7945 goto cp0_unimplemented;
9c2149c8
TS
7946 }
7947 break;
7948 case 30:
7949 switch (sel) {
7950 case 0:
7db13fae 7951 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7952 rn = "ErrorEPC";
7953 break;
9c2149c8 7954 default:
f31b035a 7955 goto cp0_unimplemented;
9c2149c8
TS
7956 }
7957 break;
7958 case 31:
7959 switch (sel) {
7960 case 0:
f0b3f3ae 7961 /* EJTAG support */
7db13fae 7962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7963 rn = "DESAVE";
7964 break;
c2e19f3c
AM
7965 case 2:
7966 case 3:
7967 case 4:
7968 case 5:
7969 case 6:
7970 case 7:
f31b035a
LA
7971 CP0_CHECK(ctx->kscrexist & (1 << sel));
7972 tcg_gen_ld_tl(arg, cpu_env,
7973 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7974 rn = "KScratch";
e98c0d17 7975 break;
9c2149c8 7976 default:
f31b035a 7977 goto cp0_unimplemented;
9c2149c8
TS
7978 }
7979 break;
7980 default:
f31b035a 7981 goto cp0_unimplemented;
9c2149c8 7982 }
b44a7fb1 7983 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7984 return;
7985
f31b035a 7986cp0_unimplemented:
965447ee 7987 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7988 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7989}
7990
d75c135e 7991static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7992{
7993 const char *rn = "invalid";
7994
e189e748 7995 if (sel != 0)
d75c135e 7996 check_insn(ctx, ISA_MIPS64);
e189e748 7997
eeb3bba8 7998 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7999 gen_io_start();
bd79255d 8000 }
2e70f6ef 8001
9c2149c8
TS
8002 switch (reg) {
8003 case 0:
8004 switch (sel) {
8005 case 0:
895c2d04 8006 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
8007 rn = "Index";
8008 break;
8009 case 1:
f31b035a 8010 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8011 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 8012 rn = "MVPControl";
ead9360e 8013 break;
9c2149c8 8014 case 2:
f31b035a 8015 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8016 /* ignored */
9c2149c8 8017 rn = "MVPConf0";
ead9360e 8018 break;
9c2149c8 8019 case 3:
f31b035a 8020 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8021 /* ignored */
9c2149c8 8022 rn = "MVPConf1";
ead9360e 8023 break;
01bc435b
YK
8024 case 4:
8025 CP0_CHECK(ctx->vp);
8026 /* ignored */
8027 rn = "VPControl";
8028 break;
9c2149c8 8029 default:
f31b035a 8030 goto cp0_unimplemented;
9c2149c8
TS
8031 }
8032 break;
8033 case 1:
8034 switch (sel) {
8035 case 0:
2423f660 8036 /* ignored */
9c2149c8 8037 rn = "Random";
2423f660 8038 break;
9c2149c8 8039 case 1:
f31b035a 8040 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8041 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 8042 rn = "VPEControl";
ead9360e 8043 break;
9c2149c8 8044 case 2:
f31b035a 8045 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8046 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 8047 rn = "VPEConf0";
ead9360e 8048 break;
9c2149c8 8049 case 3:
f31b035a 8050 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8051 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 8052 rn = "VPEConf1";
ead9360e 8053 break;
9c2149c8 8054 case 4:
f31b035a 8055 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8056 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 8057 rn = "YQMask";
ead9360e 8058 break;
9c2149c8 8059 case 5:
f31b035a 8060 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8061 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8062 rn = "VPESchedule";
ead9360e 8063 break;
9c2149c8 8064 case 6:
f31b035a 8065 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8066 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8067 rn = "VPEScheFBack";
ead9360e 8068 break;
9c2149c8 8069 case 7:
f31b035a 8070 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8071 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 8072 rn = "VPEOpt";
ead9360e 8073 break;
9c2149c8 8074 default:
f31b035a 8075 goto cp0_unimplemented;
9c2149c8
TS
8076 }
8077 break;
8078 case 2:
8079 switch (sel) {
8080 case 0:
7207c7f9 8081 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
8082 rn = "EntryLo0";
8083 break;
9c2149c8 8084 case 1:
f31b035a 8085 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8086 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 8087 rn = "TCStatus";
ead9360e 8088 break;
9c2149c8 8089 case 2:
f31b035a 8090 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8091 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 8092 rn = "TCBind";
ead9360e 8093 break;
9c2149c8 8094 case 3:
f31b035a 8095 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8096 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 8097 rn = "TCRestart";
ead9360e 8098 break;
9c2149c8 8099 case 4:
f31b035a 8100 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8101 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 8102 rn = "TCHalt";
ead9360e 8103 break;
9c2149c8 8104 case 5:
f31b035a 8105 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8106 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 8107 rn = "TCContext";
ead9360e 8108 break;
9c2149c8 8109 case 6:
f31b035a 8110 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8111 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 8112 rn = "TCSchedule";
ead9360e 8113 break;
9c2149c8 8114 case 7:
f31b035a 8115 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8116 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 8117 rn = "TCScheFBack";
ead9360e 8118 break;
9c2149c8 8119 default:
f31b035a 8120 goto cp0_unimplemented;
9c2149c8
TS
8121 }
8122 break;
8123 case 3:
8124 switch (sel) {
8125 case 0:
7207c7f9 8126 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
8127 rn = "EntryLo1";
8128 break;
01bc435b
YK
8129 case 1:
8130 CP0_CHECK(ctx->vp);
8131 /* ignored */
8132 rn = "GlobalNumber";
8133 break;
9c2149c8 8134 default:
f31b035a 8135 goto cp0_unimplemented;
876d4b07 8136 }
9c2149c8
TS
8137 break;
8138 case 4:
8139 switch (sel) {
8140 case 0:
895c2d04 8141 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
8142 rn = "Context";
8143 break;
9c2149c8 8144 case 1:
895c2d04 8145// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 8146 rn = "ContextConfig";
f31b035a 8147 goto cp0_unimplemented;
d279279e 8148 case 2:
f31b035a
LA
8149 CP0_CHECK(ctx->ulri);
8150 tcg_gen_st_tl(arg, cpu_env,
8151 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8152 rn = "UserLocal";
d279279e 8153 break;
9c2149c8 8154 default:
f31b035a 8155 goto cp0_unimplemented;
876d4b07 8156 }
9c2149c8
TS
8157 break;
8158 case 5:
8159 switch (sel) {
8160 case 0:
895c2d04 8161 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
8162 rn = "PageMask";
8163 break;
9c2149c8 8164 case 1:
d75c135e 8165 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8166 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
8167 rn = "PageGrain";
8168 break;
cec56a73
JH
8169 case 2:
8170 CP0_CHECK(ctx->sc);
8171 gen_helper_mtc0_segctl0(cpu_env, arg);
8172 rn = "SegCtl0";
8173 break;
8174 case 3:
8175 CP0_CHECK(ctx->sc);
8176 gen_helper_mtc0_segctl1(cpu_env, arg);
8177 rn = "SegCtl1";
8178 break;
8179 case 4:
8180 CP0_CHECK(ctx->sc);
8181 gen_helper_mtc0_segctl2(cpu_env, arg);
8182 rn = "SegCtl2";
8183 break;
9c2149c8 8184 default:
f31b035a 8185 goto cp0_unimplemented;
876d4b07 8186 }
9c2149c8
TS
8187 break;
8188 case 6:
8189 switch (sel) {
8190 case 0:
895c2d04 8191 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
8192 rn = "Wired";
8193 break;
9c2149c8 8194 case 1:
d75c135e 8195 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8196 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 8197 rn = "SRSConf0";
ead9360e 8198 break;
9c2149c8 8199 case 2:
d75c135e 8200 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8201 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 8202 rn = "SRSConf1";
ead9360e 8203 break;
9c2149c8 8204 case 3:
d75c135e 8205 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8206 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 8207 rn = "SRSConf2";
ead9360e 8208 break;
9c2149c8 8209 case 4:
d75c135e 8210 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8211 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 8212 rn = "SRSConf3";
ead9360e 8213 break;
9c2149c8 8214 case 5:
d75c135e 8215 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8216 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 8217 rn = "SRSConf4";
ead9360e 8218 break;
9c2149c8 8219 default:
f31b035a 8220 goto cp0_unimplemented;
876d4b07 8221 }
9c2149c8
TS
8222 break;
8223 case 7:
8224 switch (sel) {
8225 case 0:
d75c135e 8226 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8227 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8228 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8229 rn = "HWREna";
8230 break;
9c2149c8 8231 default:
f31b035a 8232 goto cp0_unimplemented;
876d4b07 8233 }
9c2149c8
TS
8234 break;
8235 case 8:
aea14095
LA
8236 switch (sel) {
8237 case 0:
8238 /* ignored */
8239 rn = "BadVAddr";
8240 break;
8241 case 1:
8242 /* ignored */
8243 rn = "BadInstr";
8244 break;
8245 case 2:
8246 /* ignored */
8247 rn = "BadInstrP";
8248 break;
25beba9b
SM
8249 case 3:
8250 /* ignored */
8251 rn = "BadInstrX";
8252 break;
aea14095 8253 default:
f31b035a 8254 goto cp0_unimplemented;
aea14095 8255 }
9c2149c8
TS
8256 break;
8257 case 9:
8258 switch (sel) {
8259 case 0:
895c2d04 8260 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
8261 rn = "Count";
8262 break;
876d4b07 8263 /* 6,7 are implementation dependent */
9c2149c8 8264 default:
f31b035a 8265 goto cp0_unimplemented;
876d4b07
TS
8266 }
8267 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8268 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8269 break;
8270 case 10:
8271 switch (sel) {
8272 case 0:
895c2d04 8273 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
8274 rn = "EntryHi";
8275 break;
9c2149c8 8276 default:
f31b035a 8277 goto cp0_unimplemented;
876d4b07 8278 }
9c2149c8
TS
8279 break;
8280 case 11:
8281 switch (sel) {
8282 case 0:
895c2d04 8283 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
8284 rn = "Compare";
8285 break;
876d4b07 8286 /* 6,7 are implementation dependent */
9c2149c8 8287 default:
f31b035a 8288 goto cp0_unimplemented;
876d4b07 8289 }
de9a95f0 8290 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8291 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8292 break;
8293 case 12:
8294 switch (sel) {
8295 case 0:
867abc7e 8296 save_cpu_state(ctx, 1);
895c2d04 8297 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8298 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8299 gen_save_pc(ctx->base.pc_next + 4);
8300 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8301 rn = "Status";
8302 break;
9c2149c8 8303 case 1:
d75c135e 8304 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8305 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8306 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8307 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8308 rn = "IntCtl";
8309 break;
9c2149c8 8310 case 2:
d75c135e 8311 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8312 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8313 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8314 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8315 rn = "SRSCtl";
8316 break;
9c2149c8 8317 case 3:
d75c135e 8318 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8319 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8320 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8321 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8322 rn = "SRSMap";
8323 break;
8324 default:
f31b035a 8325 goto cp0_unimplemented;
876d4b07 8326 }
9c2149c8
TS
8327 break;
8328 case 13:
8329 switch (sel) {
8330 case 0:
867abc7e 8331 save_cpu_state(ctx, 1);
895c2d04 8332 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
8333 /* Stop translation as we may have triggered an interrupt.
8334 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8335 * translated code to check for pending interrupts. */
eeb3bba8
EC
8336 gen_save_pc(ctx->base.pc_next + 4);
8337 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8338 rn = "Cause";
8339 break;
9c2149c8 8340 default:
f31b035a 8341 goto cp0_unimplemented;
876d4b07 8342 }
9c2149c8
TS
8343 break;
8344 case 14:
8345 switch (sel) {
8346 case 0:
7db13fae 8347 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8348 rn = "EPC";
8349 break;
9c2149c8 8350 default:
f31b035a 8351 goto cp0_unimplemented;
876d4b07 8352 }
9c2149c8
TS
8353 break;
8354 case 15:
8355 switch (sel) {
8356 case 0:
2423f660
TS
8357 /* ignored */
8358 rn = "PRid";
8359 break;
9c2149c8 8360 case 1:
d75c135e 8361 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8362 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
8363 rn = "EBase";
8364 break;
9c2149c8 8365 default:
f31b035a 8366 goto cp0_unimplemented;
876d4b07 8367 }
9c2149c8
TS
8368 break;
8369 case 16:
8370 switch (sel) {
8371 case 0:
895c2d04 8372 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 8373 rn = "Config";
2423f660 8374 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8375 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8376 break;
8377 case 1:
1fc7bf6e 8378 /* ignored, read only */
9c2149c8
TS
8379 rn = "Config1";
8380 break;
8381 case 2:
895c2d04 8382 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 8383 rn = "Config2";
2423f660 8384 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8385 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8386 break;
8387 case 3:
90f12d73 8388 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 8389 rn = "Config3";
90f12d73 8390 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8391 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8392 break;
faf1f68b
LA
8393 case 4:
8394 /* currently ignored */
8395 rn = "Config4";
8396 break;
8397 case 5:
8398 gen_helper_mtc0_config5(cpu_env, arg);
8399 rn = "Config5";
8400 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8401 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 8402 break;
9c2149c8
TS
8403 /* 6,7 are implementation dependent */
8404 default:
8405 rn = "Invalid config selector";
f31b035a 8406 goto cp0_unimplemented;
9c2149c8 8407 }
9c2149c8
TS
8408 break;
8409 case 17:
8410 switch (sel) {
8411 case 0:
895c2d04 8412 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
8413 rn = "LLAddr";
8414 break;
f6d4dd81
YK
8415 case 1:
8416 CP0_CHECK(ctx->mrp);
8417 gen_helper_mtc0_maar(cpu_env, arg);
8418 rn = "MAAR";
8419 break;
8420 case 2:
8421 CP0_CHECK(ctx->mrp);
8422 gen_helper_mtc0_maari(cpu_env, arg);
8423 rn = "MAARI";
8424 break;
9c2149c8 8425 default:
f31b035a 8426 goto cp0_unimplemented;
9c2149c8
TS
8427 }
8428 break;
8429 case 18:
8430 switch (sel) {
c2e19f3c
AM
8431 case 0:
8432 case 1:
8433 case 2:
8434 case 3:
8435 case 4:
8436 case 5:
8437 case 6:
8438 case 7:
fa192d49 8439 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8440 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
8441 rn = "WatchLo";
8442 break;
9c2149c8 8443 default:
f31b035a 8444 goto cp0_unimplemented;
9c2149c8
TS
8445 }
8446 break;
8447 case 19:
8448 switch (sel) {
c2e19f3c
AM
8449 case 0:
8450 case 1:
8451 case 2:
8452 case 3:
8453 case 4:
8454 case 5:
8455 case 6:
8456 case 7:
fa192d49 8457 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8458 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
8459 rn = "WatchHi";
8460 break;
9c2149c8 8461 default:
f31b035a 8462 goto cp0_unimplemented;
9c2149c8
TS
8463 }
8464 break;
8465 case 20:
8466 switch (sel) {
8467 case 0:
d75c135e 8468 check_insn(ctx, ISA_MIPS3);
895c2d04 8469 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
8470 rn = "XContext";
8471 break;
9c2149c8 8472 default:
f31b035a 8473 goto cp0_unimplemented;
9c2149c8
TS
8474 }
8475 break;
8476 case 21:
8477 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 8478 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
8479 switch (sel) {
8480 case 0:
895c2d04 8481 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
8482 rn = "Framemask";
8483 break;
9c2149c8 8484 default:
f31b035a 8485 goto cp0_unimplemented;
9c2149c8
TS
8486 }
8487 break;
8488 case 22:
8489 /* ignored */
8490 rn = "Diagnostic"; /* implementation dependent */
876d4b07 8491 break;
9c2149c8
TS
8492 case 23:
8493 switch (sel) {
8494 case 0:
895c2d04 8495 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 8496 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8497 gen_save_pc(ctx->base.pc_next + 4);
8498 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8499 rn = "Debug";
8500 break;
9c2149c8 8501 case 1:
895c2d04 8502// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 8503 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8504 ctx->base.is_jmp = DISAS_STOP;
2423f660 8505 rn = "TraceControl";
3570d7f6 8506 goto cp0_unimplemented;
9c2149c8 8507 case 2:
895c2d04 8508// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 8509 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8510 ctx->base.is_jmp = DISAS_STOP;
2423f660 8511 rn = "TraceControl2";
3570d7f6 8512 goto cp0_unimplemented;
9c2149c8 8513 case 3:
895c2d04 8514// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 8515 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8516 ctx->base.is_jmp = DISAS_STOP;
2423f660 8517 rn = "UserTraceData";
3570d7f6 8518 goto cp0_unimplemented;
9c2149c8 8519 case 4:
895c2d04 8520// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 8521 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8522 ctx->base.is_jmp = DISAS_STOP;
2423f660 8523 rn = "TraceBPC";
3570d7f6 8524 goto cp0_unimplemented;
9c2149c8 8525 default:
f31b035a 8526 goto cp0_unimplemented;
9c2149c8 8527 }
9c2149c8
TS
8528 break;
8529 case 24:
8530 switch (sel) {
8531 case 0:
f1aa6320 8532 /* EJTAG support */
7db13fae 8533 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8534 rn = "DEPC";
8535 break;
9c2149c8 8536 default:
f31b035a 8537 goto cp0_unimplemented;
9c2149c8
TS
8538 }
8539 break;
8540 case 25:
8541 switch (sel) {
8542 case 0:
895c2d04 8543 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
8544 rn = "Performance0";
8545 break;
9c2149c8 8546 case 1:
895c2d04 8547// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 8548 rn = "Performance1";
3570d7f6 8549 goto cp0_unimplemented;
9c2149c8 8550 case 2:
895c2d04 8551// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 8552 rn = "Performance2";
3570d7f6 8553 goto cp0_unimplemented;
9c2149c8 8554 case 3:
895c2d04 8555// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 8556 rn = "Performance3";
3570d7f6 8557 goto cp0_unimplemented;
9c2149c8 8558 case 4:
895c2d04 8559// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 8560 rn = "Performance4";
3570d7f6 8561 goto cp0_unimplemented;
9c2149c8 8562 case 5:
895c2d04 8563// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 8564 rn = "Performance5";
3570d7f6 8565 goto cp0_unimplemented;
9c2149c8 8566 case 6:
895c2d04 8567// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 8568 rn = "Performance6";
3570d7f6 8569 goto cp0_unimplemented;
9c2149c8 8570 case 7:
895c2d04 8571// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 8572 rn = "Performance7";
3570d7f6 8573 goto cp0_unimplemented;
9c2149c8 8574 default:
f31b035a 8575 goto cp0_unimplemented;
9c2149c8 8576 }
876d4b07 8577 break;
9c2149c8 8578 case 26:
0d74a222
LA
8579 switch (sel) {
8580 case 0:
8581 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8582 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
8583 rn = "ErrCtl";
8584 break;
8585 default:
8586 goto cp0_unimplemented;
8587 }
876d4b07 8588 break;
9c2149c8
TS
8589 case 27:
8590 switch (sel) {
c2e19f3c
AM
8591 case 0:
8592 case 1:
8593 case 2:
8594 case 3:
2423f660
TS
8595 /* ignored */
8596 rn = "CacheErr";
8597 break;
9c2149c8 8598 default:
f31b035a 8599 goto cp0_unimplemented;
9c2149c8 8600 }
876d4b07 8601 break;
9c2149c8
TS
8602 case 28:
8603 switch (sel) {
8604 case 0:
8605 case 2:
8606 case 4:
8607 case 6:
895c2d04 8608 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
8609 rn = "TagLo";
8610 break;
8611 case 1:
8612 case 3:
8613 case 5:
8614 case 7:
895c2d04 8615 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
8616 rn = "DataLo";
8617 break;
8618 default:
f31b035a 8619 goto cp0_unimplemented;
9c2149c8
TS
8620 }
8621 break;
8622 case 29:
8623 switch (sel) {
8624 case 0:
8625 case 2:
8626 case 4:
8627 case 6:
895c2d04 8628 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
8629 rn = "TagHi";
8630 break;
8631 case 1:
8632 case 3:
8633 case 5:
8634 case 7:
895c2d04 8635 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
8636 rn = "DataHi";
8637 break;
8638 default:
8639 rn = "invalid sel";
f31b035a 8640 goto cp0_unimplemented;
9c2149c8 8641 }
876d4b07 8642 break;
9c2149c8
TS
8643 case 30:
8644 switch (sel) {
8645 case 0:
7db13fae 8646 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8647 rn = "ErrorEPC";
8648 break;
9c2149c8 8649 default:
f31b035a 8650 goto cp0_unimplemented;
9c2149c8
TS
8651 }
8652 break;
8653 case 31:
8654 switch (sel) {
8655 case 0:
f1aa6320 8656 /* EJTAG support */
7db13fae 8657 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8658 rn = "DESAVE";
8659 break;
c2e19f3c
AM
8660 case 2:
8661 case 3:
8662 case 4:
8663 case 5:
8664 case 6:
8665 case 7:
f31b035a
LA
8666 CP0_CHECK(ctx->kscrexist & (1 << sel));
8667 tcg_gen_st_tl(arg, cpu_env,
8668 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8669 rn = "KScratch";
e98c0d17 8670 break;
9c2149c8 8671 default:
f31b035a 8672 goto cp0_unimplemented;
9c2149c8 8673 }
9c2149c8
TS
8674 break;
8675 default:
f31b035a 8676 goto cp0_unimplemented;
9c2149c8 8677 }
b44a7fb1
PMD
8678 trace_mips_translate_c0("dmtc0", rn, reg, sel);
8679
bf20dc07 8680 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8681 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8682 gen_io_end();
b28425ba 8683 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 8684 * translated code to check for pending interrupts. */
eeb3bba8
EC
8685 gen_save_pc(ctx->base.pc_next + 4);
8686 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8687 }
9c2149c8
TS
8688 return;
8689
f31b035a 8690cp0_unimplemented:
965447ee 8691 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 8692}
d26bc211 8693#endif /* TARGET_MIPS64 */
9c2149c8 8694
7db13fae 8695static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
8696 int u, int sel, int h)
8697{
8698 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8699 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
8700
8701 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8702 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8703 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 8704 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
8705 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8706 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 8707 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
8708 else if (u == 0) {
8709 switch (rt) {
5a25ce94
EI
8710 case 1:
8711 switch (sel) {
8712 case 1:
895c2d04 8713 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
8714 break;
8715 case 2:
895c2d04 8716 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
8717 break;
8718 default:
8719 goto die;
8720 break;
8721 }
8722 break;
ead9360e
TS
8723 case 2:
8724 switch (sel) {
8725 case 1:
895c2d04 8726 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
8727 break;
8728 case 2:
895c2d04 8729 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
8730 break;
8731 case 3:
895c2d04 8732 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
8733 break;
8734 case 4:
895c2d04 8735 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
8736 break;
8737 case 5:
895c2d04 8738 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
8739 break;
8740 case 6:
895c2d04 8741 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
8742 break;
8743 case 7:
895c2d04 8744 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
8745 break;
8746 default:
d75c135e 8747 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8748 break;
8749 }
8750 break;
8751 case 10:
8752 switch (sel) {
8753 case 0:
895c2d04 8754 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
8755 break;
8756 default:
d75c135e 8757 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8758 break;
8759 }
8760 case 12:
8761 switch (sel) {
8762 case 0:
895c2d04 8763 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
8764 break;
8765 default:
d75c135e 8766 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8767 break;
8768 }
5a25ce94
EI
8769 case 13:
8770 switch (sel) {
8771 case 0:
895c2d04 8772 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
8773 break;
8774 default:
8775 goto die;
8776 break;
8777 }
8778 break;
8779 case 14:
8780 switch (sel) {
8781 case 0:
895c2d04 8782 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
8783 break;
8784 default:
8785 goto die;
8786 break;
8787 }
8788 break;
8789 case 15:
8790 switch (sel) {
8791 case 1:
895c2d04 8792 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
8793 break;
8794 default:
8795 goto die;
8796 break;
8797 }
8798 break;
8799 case 16:
8800 switch (sel) {
c2e19f3c
AM
8801 case 0:
8802 case 1:
8803 case 2:
8804 case 3:
8805 case 4:
8806 case 5:
8807 case 6:
8808 case 7:
895c2d04 8809 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
8810 break;
8811 default:
8812 goto die;
8813 break;
8814 }
8815 break;
ead9360e
TS
8816 case 23:
8817 switch (sel) {
8818 case 0:
895c2d04 8819 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
8820 break;
8821 default:
d75c135e 8822 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8823 break;
8824 }
8825 break;
8826 default:
d75c135e 8827 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8828 }
8829 } else switch (sel) {
8830 /* GPR registers. */
8831 case 0:
895c2d04 8832 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
8833 break;
8834 /* Auxiliary CPU registers */
8835 case 1:
8836 switch (rt) {
8837 case 0:
895c2d04 8838 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
8839 break;
8840 case 1:
895c2d04 8841 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
8842 break;
8843 case 2:
895c2d04 8844 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
8845 break;
8846 case 4:
895c2d04 8847 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
8848 break;
8849 case 5:
895c2d04 8850 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
8851 break;
8852 case 6:
895c2d04 8853 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
8854 break;
8855 case 8:
895c2d04 8856 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
8857 break;
8858 case 9:
895c2d04 8859 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
8860 break;
8861 case 10:
895c2d04 8862 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
8863 break;
8864 case 12:
895c2d04 8865 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
8866 break;
8867 case 13:
895c2d04 8868 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
8869 break;
8870 case 14:
895c2d04 8871 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
8872 break;
8873 case 16:
895c2d04 8874 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
8875 break;
8876 default:
8877 goto die;
8878 }
8879 break;
8880 /* Floating point (COP1). */
8881 case 2:
8882 /* XXX: For now we support only a single FPU context. */
8883 if (h == 0) {
a7812ae4 8884 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8885
7c979afd 8886 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 8887 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8888 tcg_temp_free_i32(fp0);
ead9360e 8889 } else {
a7812ae4 8890 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8891
7f6613ce 8892 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 8893 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8894 tcg_temp_free_i32(fp0);
ead9360e
TS
8895 }
8896 break;
8897 case 3:
8898 /* XXX: For now we support only a single FPU context. */
895c2d04 8899 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
8900 break;
8901 /* COP2: Not implemented. */
8902 case 4:
8903 case 5:
8904 /* fall through */
8905 default:
8906 goto die;
8907 }
b44a7fb1 8908 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8909 gen_store_gpr(t0, rd);
8910 tcg_temp_free(t0);
ead9360e
TS
8911 return;
8912
8913die:
1a3fd9c3 8914 tcg_temp_free(t0);
d12d51d5 8915 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 8916 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8917}
8918
7db13fae 8919static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8920 int u, int sel, int h)
8921{
8922 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8923 TCGv t0 = tcg_temp_local_new();
ead9360e 8924
1a3fd9c3 8925 gen_load_gpr(t0, rt);
ead9360e 8926 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8927 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8928 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
8929 /* NOP */ ;
8930 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8931 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8932 /* NOP */ ;
8933 else if (u == 0) {
8934 switch (rd) {
5a25ce94
EI
8935 case 1:
8936 switch (sel) {
8937 case 1:
895c2d04 8938 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8939 break;
8940 case 2:
895c2d04 8941 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8942 break;
8943 default:
8944 goto die;
8945 break;
8946 }
8947 break;
ead9360e
TS
8948 case 2:
8949 switch (sel) {
8950 case 1:
895c2d04 8951 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8952 break;
8953 case 2:
895c2d04 8954 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8955 break;
8956 case 3:
895c2d04 8957 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8958 break;
8959 case 4:
895c2d04 8960 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8961 break;
8962 case 5:
895c2d04 8963 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8964 break;
8965 case 6:
895c2d04 8966 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8967 break;
8968 case 7:
895c2d04 8969 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8970 break;
8971 default:
d75c135e 8972 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8973 break;
8974 }
8975 break;
8976 case 10:
8977 switch (sel) {
8978 case 0:
895c2d04 8979 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8980 break;
8981 default:
d75c135e 8982 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8983 break;
8984 }
8985 case 12:
8986 switch (sel) {
8987 case 0:
895c2d04 8988 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8989 break;
8990 default:
d75c135e 8991 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8992 break;
8993 }
5a25ce94
EI
8994 case 13:
8995 switch (sel) {
8996 case 0:
895c2d04 8997 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8998 break;
8999 default:
9000 goto die;
9001 break;
9002 }
9003 break;
9004 case 15:
9005 switch (sel) {
9006 case 1:
895c2d04 9007 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
9008 break;
9009 default:
9010 goto die;
9011 break;
9012 }
9013 break;
ead9360e
TS
9014 case 23:
9015 switch (sel) {
9016 case 0:
895c2d04 9017 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
9018 break;
9019 default:
d75c135e 9020 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9021 break;
9022 }
9023 break;
9024 default:
d75c135e 9025 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9026 }
9027 } else switch (sel) {
9028 /* GPR registers. */
9029 case 0:
895c2d04 9030 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
9031 break;
9032 /* Auxiliary CPU registers */
9033 case 1:
9034 switch (rd) {
9035 case 0:
895c2d04 9036 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
9037 break;
9038 case 1:
895c2d04 9039 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
9040 break;
9041 case 2:
895c2d04 9042 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
9043 break;
9044 case 4:
895c2d04 9045 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
9046 break;
9047 case 5:
895c2d04 9048 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
9049 break;
9050 case 6:
895c2d04 9051 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
9052 break;
9053 case 8:
895c2d04 9054 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
9055 break;
9056 case 9:
895c2d04 9057 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
9058 break;
9059 case 10:
895c2d04 9060 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
9061 break;
9062 case 12:
895c2d04 9063 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
9064 break;
9065 case 13:
895c2d04 9066 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
9067 break;
9068 case 14:
895c2d04 9069 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
9070 break;
9071 case 16:
895c2d04 9072 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
9073 break;
9074 default:
9075 goto die;
9076 }
9077 break;
9078 /* Floating point (COP1). */
9079 case 2:
9080 /* XXX: For now we support only a single FPU context. */
9081 if (h == 0) {
a7812ae4 9082 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9083
9084 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9085 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 9086 tcg_temp_free_i32(fp0);
ead9360e 9087 } else {
a7812ae4 9088 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9089
9090 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9091 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 9092 tcg_temp_free_i32(fp0);
ead9360e
TS
9093 }
9094 break;
9095 case 3:
9096 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
9097 {
9098 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9099
9100 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9101 tcg_temp_free_i32(fs_tmp);
9102 }
4cf8a45f 9103 /* Stop translation as we may have changed hflags */
eeb3bba8 9104 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
9105 break;
9106 /* COP2: Not implemented. */
9107 case 4:
9108 case 5:
9109 /* fall through */
9110 default:
9111 goto die;
9112 }
b44a7fb1 9113 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9114 tcg_temp_free(t0);
ead9360e
TS
9115 return;
9116
9117die:
1a3fd9c3 9118 tcg_temp_free(t0);
d12d51d5 9119 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 9120 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9121}
9122
7db13fae 9123static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 9124{
287c4b84 9125 const char *opn = "ldst";
6af0bf9c 9126
2e15497c 9127 check_cp0_enabled(ctx);
6af0bf9c
FB
9128 switch (opc) {
9129 case OPC_MFC0:
9130 if (rt == 0) {
ead9360e 9131 /* Treat as NOP. */
6af0bf9c
FB
9132 return;
9133 }
d75c135e 9134 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9135 opn = "mfc0";
9136 break;
9137 case OPC_MTC0:
1a3fd9c3 9138 {
1fc7bf6e 9139 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9140
9141 gen_load_gpr(t0, rt);
d75c135e 9142 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9143 tcg_temp_free(t0);
9144 }
6af0bf9c
FB
9145 opn = "mtc0";
9146 break;
d26bc211 9147#if defined(TARGET_MIPS64)
9c2149c8 9148 case OPC_DMFC0:
d75c135e 9149 check_insn(ctx, ISA_MIPS3);
9c2149c8 9150 if (rt == 0) {
ead9360e 9151 /* Treat as NOP. */
9c2149c8
TS
9152 return;
9153 }
d75c135e 9154 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
9155 opn = "dmfc0";
9156 break;
9157 case OPC_DMTC0:
d75c135e 9158 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 9159 {
1fc7bf6e 9160 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9161
9162 gen_load_gpr(t0, rt);
d75c135e 9163 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9164 tcg_temp_free(t0);
9165 }
9c2149c8
TS
9166 opn = "dmtc0";
9167 break;
534ce69f 9168#endif
5204ea79
LA
9169 case OPC_MFHC0:
9170 check_mvh(ctx);
9171 if (rt == 0) {
9172 /* Treat as NOP. */
9173 return;
9174 }
9175 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9176 opn = "mfhc0";
9177 break;
9178 case OPC_MTHC0:
9179 check_mvh(ctx);
9180 {
9181 TCGv t0 = tcg_temp_new();
9182 gen_load_gpr(t0, rt);
9183 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9184 tcg_temp_free(t0);
9185 }
9186 opn = "mthc0";
9187 break;
ead9360e 9188 case OPC_MFTR:
9affc1c5 9189 check_cp0_enabled(ctx);
ead9360e
TS
9190 if (rd == 0) {
9191 /* Treat as NOP. */
9192 return;
9193 }
6c5c1e20 9194 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 9195 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
9196 opn = "mftr";
9197 break;
9198 case OPC_MTTR:
9affc1c5 9199 check_cp0_enabled(ctx);
6c5c1e20 9200 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
9201 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9202 opn = "mttr";
9203 break;
6af0bf9c 9204 case OPC_TLBWI:
6af0bf9c 9205 opn = "tlbwi";
c01fccd2 9206 if (!env->tlb->helper_tlbwi)
29929e34 9207 goto die;
895c2d04 9208 gen_helper_tlbwi(cpu_env);
6af0bf9c 9209 break;
9456c2fb
LA
9210 case OPC_TLBINV:
9211 opn = "tlbinv";
9212 if (ctx->ie >= 2) {
9213 if (!env->tlb->helper_tlbinv) {
9214 goto die;
9215 }
9216 gen_helper_tlbinv(cpu_env);
9217 } /* treat as nop if TLBINV not supported */
9218 break;
9219 case OPC_TLBINVF:
9220 opn = "tlbinvf";
9221 if (ctx->ie >= 2) {
9222 if (!env->tlb->helper_tlbinvf) {
9223 goto die;
9224 }
9225 gen_helper_tlbinvf(cpu_env);
9226 } /* treat as nop if TLBINV not supported */
9227 break;
6af0bf9c 9228 case OPC_TLBWR:
6af0bf9c 9229 opn = "tlbwr";
c01fccd2 9230 if (!env->tlb->helper_tlbwr)
29929e34 9231 goto die;
895c2d04 9232 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
9233 break;
9234 case OPC_TLBP:
6af0bf9c 9235 opn = "tlbp";
c01fccd2 9236 if (!env->tlb->helper_tlbp)
29929e34 9237 goto die;
895c2d04 9238 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
9239 break;
9240 case OPC_TLBR:
6af0bf9c 9241 opn = "tlbr";
c01fccd2 9242 if (!env->tlb->helper_tlbr)
29929e34 9243 goto die;
895c2d04 9244 gen_helper_tlbr(cpu_env);
6af0bf9c 9245 break;
ce9782f4 9246 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
9247 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9248 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 9249 goto die;
ce9782f4
LA
9250 } else {
9251 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9252 if (ctx->opcode & (1 << bit_shift)) {
9253 /* OPC_ERETNC */
9254 opn = "eretnc";
9255 check_insn(ctx, ISA_MIPS32R5);
9256 gen_helper_eretnc(cpu_env);
9257 } else {
9258 /* OPC_ERET */
9259 opn = "eret";
9260 check_insn(ctx, ISA_MIPS2);
9261 gen_helper_eret(cpu_env);
9262 }
eeb3bba8 9263 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 9264 }
6af0bf9c
FB
9265 break;
9266 case OPC_DERET:
9267 opn = "deret";
d75c135e 9268 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
9269 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9270 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9271 goto die;
9272 }
6af0bf9c 9273 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 9274 MIPS_INVAL(opn);
9c708c7f 9275 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 9276 } else {
895c2d04 9277 gen_helper_deret(cpu_env);
eeb3bba8 9278 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
9279 }
9280 break;
4ad40f36
FB
9281 case OPC_WAIT:
9282 opn = "wait";
d75c135e 9283 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
9284 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9285 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9286 goto die;
9287 }
4ad40f36 9288 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 9289 ctx->base.pc_next += 4;
4ad40f36 9290 save_cpu_state(ctx, 1);
eeb3bba8 9291 ctx->base.pc_next -= 4;
895c2d04 9292 gen_helper_wait(cpu_env);
eeb3bba8 9293 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 9294 break;
6af0bf9c 9295 default:
29929e34 9296 die:
923617a3 9297 MIPS_INVAL(opn);
9c708c7f 9298 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
9299 return;
9300 }
2abf314d 9301 (void)opn; /* avoid a compiler warning */
6af0bf9c 9302}
f1aa6320 9303#endif /* !CONFIG_USER_ONLY */
6af0bf9c 9304
6ea83fed 9305/* CP1 Branches (before delay slot) */
d75c135e
AJ
9306static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9307 int32_t cc, int32_t offset)
6ea83fed
FB
9308{
9309 target_ulong btarget;
a7812ae4 9310 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 9311
339cd2a8 9312 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 9313 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
9314 goto out;
9315 }
9316
e189e748 9317 if (cc != 0)
d75c135e 9318 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 9319
eeb3bba8 9320 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 9321
7a387fff
TS
9322 switch (op) {
9323 case OPC_BC1F:
d94536f4
AJ
9324 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9325 tcg_gen_not_i32(t0, t0);
9326 tcg_gen_andi_i32(t0, t0, 1);
9327 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9328 goto not_likely;
7a387fff 9329 case OPC_BC1FL:
d94536f4
AJ
9330 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9331 tcg_gen_not_i32(t0, t0);
9332 tcg_gen_andi_i32(t0, t0, 1);
9333 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9334 goto likely;
7a387fff 9335 case OPC_BC1T:
d94536f4
AJ
9336 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9337 tcg_gen_andi_i32(t0, t0, 1);
9338 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 9339 goto not_likely;
7a387fff 9340 case OPC_BC1TL:
d94536f4
AJ
9341 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9342 tcg_gen_andi_i32(t0, t0, 1);
9343 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
9344 likely:
9345 ctx->hflags |= MIPS_HFLAG_BL;
9346 break;
5a5012ec 9347 case OPC_BC1FANY2:
a16336e4 9348 {
d94536f4
AJ
9349 TCGv_i32 t1 = tcg_temp_new_i32();
9350 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9351 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 9352 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9353 tcg_temp_free_i32(t1);
d94536f4
AJ
9354 tcg_gen_andi_i32(t0, t0, 1);
9355 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9356 }
5a5012ec
TS
9357 goto not_likely;
9358 case OPC_BC1TANY2:
a16336e4 9359 {
d94536f4
AJ
9360 TCGv_i32 t1 = tcg_temp_new_i32();
9361 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9362 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9363 tcg_gen_or_i32(t0, t0, t1);
9364 tcg_temp_free_i32(t1);
9365 tcg_gen_andi_i32(t0, t0, 1);
9366 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9367 }
5a5012ec
TS
9368 goto not_likely;
9369 case OPC_BC1FANY4:
a16336e4 9370 {
d94536f4
AJ
9371 TCGv_i32 t1 = tcg_temp_new_i32();
9372 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9373 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 9374 tcg_gen_and_i32(t0, t0, t1);
d94536f4 9375 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 9376 tcg_gen_and_i32(t0, t0, t1);
d94536f4 9377 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 9378 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9379 tcg_temp_free_i32(t1);
d94536f4
AJ
9380 tcg_gen_andi_i32(t0, t0, 1);
9381 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9382 }
5a5012ec
TS
9383 goto not_likely;
9384 case OPC_BC1TANY4:
a16336e4 9385 {
d94536f4
AJ
9386 TCGv_i32 t1 = tcg_temp_new_i32();
9387 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9388 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9389 tcg_gen_or_i32(t0, t0, t1);
9390 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9391 tcg_gen_or_i32(t0, t0, t1);
9392 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9393 tcg_gen_or_i32(t0, t0, t1);
9394 tcg_temp_free_i32(t1);
9395 tcg_gen_andi_i32(t0, t0, 1);
9396 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9397 }
5a5012ec
TS
9398 not_likely:
9399 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
9400 break;
9401 default:
9d68ac14 9402 MIPS_INVAL("cp1 cond branch");
9c708c7f 9403 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 9404 goto out;
6ea83fed 9405 }
6ea83fed 9406 ctx->btarget = btarget;
b231c103 9407 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 9408 out:
a7812ae4 9409 tcg_temp_free_i32(t0);
6ea83fed
FB
9410}
9411
31837be3
YK
9412/* R6 CP1 Branches */
9413static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
9414 int32_t ft, int32_t offset,
9415 int delayslot_size)
31837be3
YK
9416{
9417 target_ulong btarget;
31837be3
YK
9418 TCGv_i64 t0 = tcg_temp_new_i64();
9419
9420 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9421#ifdef MIPS_DEBUG_DISAS
339cd2a8 9422 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 9423 "\n", ctx->base.pc_next);
31837be3 9424#endif
9c708c7f 9425 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
9426 goto out;
9427 }
9428
9429 gen_load_fpr64(ctx, t0, ft);
9430 tcg_gen_andi_i64(t0, t0, 1);
9431
eeb3bba8 9432 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
9433
9434 switch (op) {
9435 case OPC_BC1EQZ:
9436 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
9437 ctx->hflags |= MIPS_HFLAG_BC;
9438 break;
9439 case OPC_BC1NEZ:
9440 /* t0 already set */
31837be3
YK
9441 ctx->hflags |= MIPS_HFLAG_BC;
9442 break;
9443 default:
9d68ac14 9444 MIPS_INVAL("cp1 cond branch");
9c708c7f 9445 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
9446 goto out;
9447 }
9448
9449 tcg_gen_trunc_i64_tl(bcond, t0);
9450
31837be3 9451 ctx->btarget = btarget;
65935f07
YK
9452
9453 switch (delayslot_size) {
9454 case 2:
9455 ctx->hflags |= MIPS_HFLAG_BDS16;
9456 break;
9457 case 4:
9458 ctx->hflags |= MIPS_HFLAG_BDS32;
9459 break;
9460 }
31837be3
YK
9461
9462out:
9463 tcg_temp_free_i64(t0);
9464}
9465
6af0bf9c 9466/* Coprocessor 1 (FPU) */
5a5012ec 9467
5a5012ec
TS
9468#define FOP(func, fmt) (((fmt) << 21) | (func))
9469
bf4120ad
NF
9470enum fopcode {
9471 OPC_ADD_S = FOP(0, FMT_S),
9472 OPC_SUB_S = FOP(1, FMT_S),
9473 OPC_MUL_S = FOP(2, FMT_S),
9474 OPC_DIV_S = FOP(3, FMT_S),
9475 OPC_SQRT_S = FOP(4, FMT_S),
9476 OPC_ABS_S = FOP(5, FMT_S),
9477 OPC_MOV_S = FOP(6, FMT_S),
9478 OPC_NEG_S = FOP(7, FMT_S),
9479 OPC_ROUND_L_S = FOP(8, FMT_S),
9480 OPC_TRUNC_L_S = FOP(9, FMT_S),
9481 OPC_CEIL_L_S = FOP(10, FMT_S),
9482 OPC_FLOOR_L_S = FOP(11, FMT_S),
9483 OPC_ROUND_W_S = FOP(12, FMT_S),
9484 OPC_TRUNC_W_S = FOP(13, FMT_S),
9485 OPC_CEIL_W_S = FOP(14, FMT_S),
9486 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 9487 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
9488 OPC_MOVCF_S = FOP(17, FMT_S),
9489 OPC_MOVZ_S = FOP(18, FMT_S),
9490 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 9491 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
9492 OPC_RECIP_S = FOP(21, FMT_S),
9493 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
9494 OPC_SELNEZ_S = FOP(23, FMT_S),
9495 OPC_MADDF_S = FOP(24, FMT_S),
9496 OPC_MSUBF_S = FOP(25, FMT_S),
9497 OPC_RINT_S = FOP(26, FMT_S),
9498 OPC_CLASS_S = FOP(27, FMT_S),
9499 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 9500 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 9501 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 9502 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 9503 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 9504 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 9505 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
9506 OPC_RSQRT2_S = FOP(31, FMT_S),
9507 OPC_CVT_D_S = FOP(33, FMT_S),
9508 OPC_CVT_W_S = FOP(36, FMT_S),
9509 OPC_CVT_L_S = FOP(37, FMT_S),
9510 OPC_CVT_PS_S = FOP(38, FMT_S),
9511 OPC_CMP_F_S = FOP (48, FMT_S),
9512 OPC_CMP_UN_S = FOP (49, FMT_S),
9513 OPC_CMP_EQ_S = FOP (50, FMT_S),
9514 OPC_CMP_UEQ_S = FOP (51, FMT_S),
9515 OPC_CMP_OLT_S = FOP (52, FMT_S),
9516 OPC_CMP_ULT_S = FOP (53, FMT_S),
9517 OPC_CMP_OLE_S = FOP (54, FMT_S),
9518 OPC_CMP_ULE_S = FOP (55, FMT_S),
9519 OPC_CMP_SF_S = FOP (56, FMT_S),
9520 OPC_CMP_NGLE_S = FOP (57, FMT_S),
9521 OPC_CMP_SEQ_S = FOP (58, FMT_S),
9522 OPC_CMP_NGL_S = FOP (59, FMT_S),
9523 OPC_CMP_LT_S = FOP (60, FMT_S),
9524 OPC_CMP_NGE_S = FOP (61, FMT_S),
9525 OPC_CMP_LE_S = FOP (62, FMT_S),
9526 OPC_CMP_NGT_S = FOP (63, FMT_S),
9527
9528 OPC_ADD_D = FOP(0, FMT_D),
9529 OPC_SUB_D = FOP(1, FMT_D),
9530 OPC_MUL_D = FOP(2, FMT_D),
9531 OPC_DIV_D = FOP(3, FMT_D),
9532 OPC_SQRT_D = FOP(4, FMT_D),
9533 OPC_ABS_D = FOP(5, FMT_D),
9534 OPC_MOV_D = FOP(6, FMT_D),
9535 OPC_NEG_D = FOP(7, FMT_D),
9536 OPC_ROUND_L_D = FOP(8, FMT_D),
9537 OPC_TRUNC_L_D = FOP(9, FMT_D),
9538 OPC_CEIL_L_D = FOP(10, FMT_D),
9539 OPC_FLOOR_L_D = FOP(11, FMT_D),
9540 OPC_ROUND_W_D = FOP(12, FMT_D),
9541 OPC_TRUNC_W_D = FOP(13, FMT_D),
9542 OPC_CEIL_W_D = FOP(14, FMT_D),
9543 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 9544 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
9545 OPC_MOVCF_D = FOP(17, FMT_D),
9546 OPC_MOVZ_D = FOP(18, FMT_D),
9547 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 9548 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
9549 OPC_RECIP_D = FOP(21, FMT_D),
9550 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
9551 OPC_SELNEZ_D = FOP(23, FMT_D),
9552 OPC_MADDF_D = FOP(24, FMT_D),
9553 OPC_MSUBF_D = FOP(25, FMT_D),
9554 OPC_RINT_D = FOP(26, FMT_D),
9555 OPC_CLASS_D = FOP(27, FMT_D),
9556 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 9557 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 9558 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 9559 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 9560 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 9561 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 9562 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
9563 OPC_RSQRT2_D = FOP(31, FMT_D),
9564 OPC_CVT_S_D = FOP(32, FMT_D),
9565 OPC_CVT_W_D = FOP(36, FMT_D),
9566 OPC_CVT_L_D = FOP(37, FMT_D),
9567 OPC_CMP_F_D = FOP (48, FMT_D),
9568 OPC_CMP_UN_D = FOP (49, FMT_D),
9569 OPC_CMP_EQ_D = FOP (50, FMT_D),
9570 OPC_CMP_UEQ_D = FOP (51, FMT_D),
9571 OPC_CMP_OLT_D = FOP (52, FMT_D),
9572 OPC_CMP_ULT_D = FOP (53, FMT_D),
9573 OPC_CMP_OLE_D = FOP (54, FMT_D),
9574 OPC_CMP_ULE_D = FOP (55, FMT_D),
9575 OPC_CMP_SF_D = FOP (56, FMT_D),
9576 OPC_CMP_NGLE_D = FOP (57, FMT_D),
9577 OPC_CMP_SEQ_D = FOP (58, FMT_D),
9578 OPC_CMP_NGL_D = FOP (59, FMT_D),
9579 OPC_CMP_LT_D = FOP (60, FMT_D),
9580 OPC_CMP_NGE_D = FOP (61, FMT_D),
9581 OPC_CMP_LE_D = FOP (62, FMT_D),
9582 OPC_CMP_NGT_D = FOP (63, FMT_D),
9583
9584 OPC_CVT_S_W = FOP(32, FMT_W),
9585 OPC_CVT_D_W = FOP(33, FMT_W),
9586 OPC_CVT_S_L = FOP(32, FMT_L),
9587 OPC_CVT_D_L = FOP(33, FMT_L),
9588 OPC_CVT_PS_PW = FOP(38, FMT_W),
9589
9590 OPC_ADD_PS = FOP(0, FMT_PS),
9591 OPC_SUB_PS = FOP(1, FMT_PS),
9592 OPC_MUL_PS = FOP(2, FMT_PS),
9593 OPC_DIV_PS = FOP(3, FMT_PS),
9594 OPC_ABS_PS = FOP(5, FMT_PS),
9595 OPC_MOV_PS = FOP(6, FMT_PS),
9596 OPC_NEG_PS = FOP(7, FMT_PS),
9597 OPC_MOVCF_PS = FOP(17, FMT_PS),
9598 OPC_MOVZ_PS = FOP(18, FMT_PS),
9599 OPC_MOVN_PS = FOP(19, FMT_PS),
9600 OPC_ADDR_PS = FOP(24, FMT_PS),
9601 OPC_MULR_PS = FOP(26, FMT_PS),
9602 OPC_RECIP2_PS = FOP(28, FMT_PS),
9603 OPC_RECIP1_PS = FOP(29, FMT_PS),
9604 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9605 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9606
9607 OPC_CVT_S_PU = FOP(32, FMT_PS),
9608 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9609 OPC_CVT_S_PL = FOP(40, FMT_PS),
9610 OPC_PLL_PS = FOP(44, FMT_PS),
9611 OPC_PLU_PS = FOP(45, FMT_PS),
9612 OPC_PUL_PS = FOP(46, FMT_PS),
9613 OPC_PUU_PS = FOP(47, FMT_PS),
9614 OPC_CMP_F_PS = FOP (48, FMT_PS),
9615 OPC_CMP_UN_PS = FOP (49, FMT_PS),
9616 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9617 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9618 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9619 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9620 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9621 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9622 OPC_CMP_SF_PS = FOP (56, FMT_PS),
9623 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9624 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9625 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9626 OPC_CMP_LT_PS = FOP (60, FMT_PS),
9627 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9628 OPC_CMP_LE_PS = FOP (62, FMT_PS),
9629 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9630};
9631
3f493883
YK
9632enum r6_f_cmp_op {
9633 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9634 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9635 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9636 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9637 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9638 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9639 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9640 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9641 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9642 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9643 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9644 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9645 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9646 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9647 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9648 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9649 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9650 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9651 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9652 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9653 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9654 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9655
9656 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9657 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9658 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9659 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9660 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9661 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9662 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9663 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9664 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9665 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9666 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9667 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9668 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9669 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9670 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9671 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9672 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9673 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9674 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9675 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9676 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9677 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9678};
7a387fff 9679static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 9680{
72c3a3ee 9681 TCGv t0 = tcg_temp_new();
6ea83fed
FB
9682
9683 switch (opc) {
9684 case OPC_MFC1:
b6d96bed 9685 {
a7812ae4 9686 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9687
7c979afd 9688 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 9689 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9690 tcg_temp_free_i32(fp0);
6958549d 9691 }
6c5c1e20 9692 gen_store_gpr(t0, rt);
6ea83fed
FB
9693 break;
9694 case OPC_MTC1:
6c5c1e20 9695 gen_load_gpr(t0, rt);
b6d96bed 9696 {
a7812ae4 9697 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9698
9699 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9700 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 9701 tcg_temp_free_i32(fp0);
6958549d 9702 }
6ea83fed
FB
9703 break;
9704 case OPC_CFC1:
895c2d04 9705 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 9706 gen_store_gpr(t0, rt);
6ea83fed
FB
9707 break;
9708 case OPC_CTC1:
6c5c1e20 9709 gen_load_gpr(t0, rt);
9c708c7f 9710 save_cpu_state(ctx, 0);
736d120a
PJ
9711 {
9712 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9713
9714 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9715 tcg_temp_free_i32(fs_tmp);
9716 }
4cf8a45f 9717 /* Stop translation as we may have changed hflags */
eeb3bba8 9718 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 9719 break;
72c3a3ee 9720#if defined(TARGET_MIPS64)
9c2149c8 9721 case OPC_DMFC1:
72c3a3ee 9722 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 9723 gen_store_gpr(t0, rt);
5a5012ec 9724 break;
9c2149c8 9725 case OPC_DMTC1:
6c5c1e20 9726 gen_load_gpr(t0, rt);
72c3a3ee 9727 gen_store_fpr64(ctx, t0, fs);
5a5012ec 9728 break;
72c3a3ee 9729#endif
5a5012ec 9730 case OPC_MFHC1:
b6d96bed 9731 {
a7812ae4 9732 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9733
7f6613ce 9734 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 9735 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9736 tcg_temp_free_i32(fp0);
6958549d 9737 }
6c5c1e20 9738 gen_store_gpr(t0, rt);
5a5012ec
TS
9739 break;
9740 case OPC_MTHC1:
6c5c1e20 9741 gen_load_gpr(t0, rt);
b6d96bed 9742 {
a7812ae4 9743 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9744
9745 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9746 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 9747 tcg_temp_free_i32(fp0);
6958549d 9748 }
5a5012ec 9749 break;
6ea83fed 9750 default:
9d68ac14 9751 MIPS_INVAL("cp1 move");
9c708c7f 9752 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 9753 goto out;
6ea83fed 9754 }
6c5c1e20
TS
9755
9756 out:
9757 tcg_temp_free(t0);
6ea83fed
FB
9758}
9759
5a5012ec
TS
9760static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9761{
42a268c2 9762 TCGLabel *l1;
e214b9bb 9763 TCGCond cond;
af58f9ca
AJ
9764 TCGv_i32 t0;
9765
9766 if (rd == 0) {
9767 /* Treat as NOP. */
9768 return;
9769 }
6ea83fed 9770
e214b9bb 9771 if (tf)
e214b9bb 9772 cond = TCG_COND_EQ;
27848470
TS
9773 else
9774 cond = TCG_COND_NE;
9775
af58f9ca
AJ
9776 l1 = gen_new_label();
9777 t0 = tcg_temp_new_i32();
fa31af0e 9778 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 9779 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9780 tcg_temp_free_i32(t0);
af58f9ca
AJ
9781 if (rs == 0) {
9782 tcg_gen_movi_tl(cpu_gpr[rd], 0);
9783 } else {
9784 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9785 }
e214b9bb 9786 gen_set_label(l1);
5a5012ec
TS
9787}
9788
7c979afd
LA
9789static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9790 int tf)
a16336e4 9791{
a16336e4 9792 int cond;
cbc37b28 9793 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 9794 TCGLabel *l1 = gen_new_label();
a16336e4 9795
a16336e4
TS
9796 if (tf)
9797 cond = TCG_COND_EQ;
9798 else
9799 cond = TCG_COND_NE;
9800
fa31af0e 9801 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9802 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9803 gen_load_fpr32(ctx, t0, fs);
9804 gen_store_fpr32(ctx, t0, fd);
a16336e4 9805 gen_set_label(l1);
cbc37b28 9806 tcg_temp_free_i32(t0);
5a5012ec 9807}
a16336e4 9808
b6d96bed 9809static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 9810{
a16336e4 9811 int cond;
cbc37b28
AJ
9812 TCGv_i32 t0 = tcg_temp_new_i32();
9813 TCGv_i64 fp0;
42a268c2 9814 TCGLabel *l1 = gen_new_label();
a16336e4 9815
a16336e4
TS
9816 if (tf)
9817 cond = TCG_COND_EQ;
9818 else
9819 cond = TCG_COND_NE;
9820
fa31af0e 9821 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9822 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9823 tcg_temp_free_i32(t0);
11f94258 9824 fp0 = tcg_temp_new_i64();
9bf3eb2c 9825 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 9826 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9827 tcg_temp_free_i64(fp0);
cbc37b28 9828 gen_set_label(l1);
a16336e4
TS
9829}
9830
7f6613ce
PJ
9831static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9832 int cc, int tf)
a16336e4
TS
9833{
9834 int cond;
cbc37b28 9835 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
9836 TCGLabel *l1 = gen_new_label();
9837 TCGLabel *l2 = gen_new_label();
a16336e4
TS
9838
9839 if (tf)
9840 cond = TCG_COND_EQ;
9841 else
9842 cond = TCG_COND_NE;
9843
fa31af0e 9844 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9845 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9846 gen_load_fpr32(ctx, t0, fs);
9847 gen_store_fpr32(ctx, t0, fd);
a16336e4 9848 gen_set_label(l1);
9bf3eb2c 9849
fa31af0e 9850 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 9851 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
9852 gen_load_fpr32h(ctx, t0, fs);
9853 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9854 tcg_temp_free_i32(t0);
a16336e4 9855 gen_set_label(l2);
a16336e4
TS
9856}
9857
e7f16abb
LA
9858static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9859 int fs)
9860{
9861 TCGv_i32 t1 = tcg_const_i32(0);
9862 TCGv_i32 fp0 = tcg_temp_new_i32();
9863 TCGv_i32 fp1 = tcg_temp_new_i32();
9864 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9865 gen_load_fpr32(ctx, fp0, fd);
9866 gen_load_fpr32(ctx, fp1, ft);
9867 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9868
9869 switch (op1) {
9870 case OPC_SEL_S:
9871 tcg_gen_andi_i32(fp0, fp0, 1);
9872 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9873 break;
9874 case OPC_SELEQZ_S:
9875 tcg_gen_andi_i32(fp1, fp1, 1);
9876 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9877 break;
9878 case OPC_SELNEZ_S:
9879 tcg_gen_andi_i32(fp1, fp1, 1);
9880 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9881 break;
9882 default:
9883 MIPS_INVAL("gen_sel_s");
9c708c7f 9884 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9885 break;
9886 }
9887
7c979afd 9888 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9889 tcg_temp_free_i32(fp2);
9890 tcg_temp_free_i32(fp1);
9891 tcg_temp_free_i32(fp0);
9892 tcg_temp_free_i32(t1);
9893}
9894
9895static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9896 int fs)
9897{
9898 TCGv_i64 t1 = tcg_const_i64(0);
9899 TCGv_i64 fp0 = tcg_temp_new_i64();
9900 TCGv_i64 fp1 = tcg_temp_new_i64();
9901 TCGv_i64 fp2 = tcg_temp_new_i64();
9902 gen_load_fpr64(ctx, fp0, fd);
9903 gen_load_fpr64(ctx, fp1, ft);
9904 gen_load_fpr64(ctx, fp2, fs);
9905
9906 switch (op1) {
9907 case OPC_SEL_D:
9908 tcg_gen_andi_i64(fp0, fp0, 1);
9909 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9910 break;
9911 case OPC_SELEQZ_D:
9912 tcg_gen_andi_i64(fp1, fp1, 1);
9913 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9914 break;
9915 case OPC_SELNEZ_D:
9916 tcg_gen_andi_i64(fp1, fp1, 1);
9917 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9918 break;
9919 default:
9920 MIPS_INVAL("gen_sel_d");
9c708c7f 9921 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9922 break;
9923 }
9924
9925 gen_store_fpr64(ctx, fp0, fd);
9926 tcg_temp_free_i64(fp2);
9927 tcg_temp_free_i64(fp1);
9928 tcg_temp_free_i64(fp0);
9929 tcg_temp_free_i64(t1);
9930}
6ea83fed 9931
bf4120ad 9932static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 9933 int ft, int fs, int fd, int cc)
6ea83fed 9934{
7a387fff 9935 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9936 switch (op1) {
9937 case OPC_ADD_S:
b6d96bed 9938 {
a7812ae4
PB
9939 TCGv_i32 fp0 = tcg_temp_new_i32();
9940 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9941
7c979afd
LA
9942 gen_load_fpr32(ctx, fp0, fs);
9943 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9944 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9945 tcg_temp_free_i32(fp1);
7c979afd 9946 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9947 tcg_temp_free_i32(fp0);
b6d96bed 9948 }
5a5012ec 9949 break;
bf4120ad 9950 case OPC_SUB_S:
b6d96bed 9951 {
a7812ae4
PB
9952 TCGv_i32 fp0 = tcg_temp_new_i32();
9953 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9954
7c979afd
LA
9955 gen_load_fpr32(ctx, fp0, fs);
9956 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9957 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9958 tcg_temp_free_i32(fp1);
7c979afd 9959 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9960 tcg_temp_free_i32(fp0);
b6d96bed 9961 }
5a5012ec 9962 break;
bf4120ad 9963 case OPC_MUL_S:
b6d96bed 9964 {
a7812ae4
PB
9965 TCGv_i32 fp0 = tcg_temp_new_i32();
9966 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9967
7c979afd
LA
9968 gen_load_fpr32(ctx, fp0, fs);
9969 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9970 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9971 tcg_temp_free_i32(fp1);
7c979afd 9972 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9973 tcg_temp_free_i32(fp0);
b6d96bed 9974 }
5a5012ec 9975 break;
bf4120ad 9976 case OPC_DIV_S:
b6d96bed 9977 {
a7812ae4
PB
9978 TCGv_i32 fp0 = tcg_temp_new_i32();
9979 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9980
7c979afd
LA
9981 gen_load_fpr32(ctx, fp0, fs);
9982 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9983 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9984 tcg_temp_free_i32(fp1);
7c979afd 9985 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9986 tcg_temp_free_i32(fp0);
b6d96bed 9987 }
5a5012ec 9988 break;
bf4120ad 9989 case OPC_SQRT_S:
b6d96bed 9990 {
a7812ae4 9991 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9992
7c979afd 9993 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9994 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9995 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9996 tcg_temp_free_i32(fp0);
b6d96bed 9997 }
5a5012ec 9998 break;
bf4120ad 9999 case OPC_ABS_S:
b6d96bed 10000 {
a7812ae4 10001 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10002
7c979afd 10003 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10004 if (ctx->abs2008) {
10005 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10006 } else {
10007 gen_helper_float_abs_s(fp0, fp0);
10008 }
7c979afd 10009 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10010 tcg_temp_free_i32(fp0);
b6d96bed 10011 }
5a5012ec 10012 break;
bf4120ad 10013 case OPC_MOV_S:
b6d96bed 10014 {
a7812ae4 10015 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10016
7c979afd
LA
10017 gen_load_fpr32(ctx, fp0, fs);
10018 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10019 tcg_temp_free_i32(fp0);
b6d96bed 10020 }
5a5012ec 10021 break;
bf4120ad 10022 case OPC_NEG_S:
b6d96bed 10023 {
a7812ae4 10024 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10025
7c979afd 10026 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10027 if (ctx->abs2008) {
10028 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10029 } else {
10030 gen_helper_float_chs_s(fp0, fp0);
10031 }
7c979afd 10032 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10033 tcg_temp_free_i32(fp0);
b6d96bed 10034 }
5a5012ec 10035 break;
bf4120ad 10036 case OPC_ROUND_L_S:
5e755519 10037 check_cp1_64bitmode(ctx);
b6d96bed 10038 {
a7812ae4
PB
10039 TCGv_i32 fp32 = tcg_temp_new_i32();
10040 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10041
7c979afd 10042 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10043 if (ctx->nan2008) {
10044 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10045 } else {
10046 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10047 }
a7812ae4 10048 tcg_temp_free_i32(fp32);
b6d96bed 10049 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10050 tcg_temp_free_i64(fp64);
b6d96bed 10051 }
5a5012ec 10052 break;
bf4120ad 10053 case OPC_TRUNC_L_S:
5e755519 10054 check_cp1_64bitmode(ctx);
b6d96bed 10055 {
a7812ae4
PB
10056 TCGv_i32 fp32 = tcg_temp_new_i32();
10057 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10058
7c979afd 10059 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10060 if (ctx->nan2008) {
10061 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10062 } else {
10063 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10064 }
a7812ae4 10065 tcg_temp_free_i32(fp32);
b6d96bed 10066 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10067 tcg_temp_free_i64(fp64);
b6d96bed 10068 }
5a5012ec 10069 break;
bf4120ad 10070 case OPC_CEIL_L_S:
5e755519 10071 check_cp1_64bitmode(ctx);
b6d96bed 10072 {
a7812ae4
PB
10073 TCGv_i32 fp32 = tcg_temp_new_i32();
10074 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10075
7c979afd 10076 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10077 if (ctx->nan2008) {
10078 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10079 } else {
10080 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10081 }
a7812ae4 10082 tcg_temp_free_i32(fp32);
b6d96bed 10083 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10084 tcg_temp_free_i64(fp64);
b6d96bed 10085 }
5a5012ec 10086 break;
bf4120ad 10087 case OPC_FLOOR_L_S:
5e755519 10088 check_cp1_64bitmode(ctx);
b6d96bed 10089 {
a7812ae4
PB
10090 TCGv_i32 fp32 = tcg_temp_new_i32();
10091 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10092
7c979afd 10093 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10094 if (ctx->nan2008) {
10095 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10096 } else {
10097 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10098 }
a7812ae4 10099 tcg_temp_free_i32(fp32);
b6d96bed 10100 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10101 tcg_temp_free_i64(fp64);
b6d96bed 10102 }
5a5012ec 10103 break;
bf4120ad 10104 case OPC_ROUND_W_S:
b6d96bed 10105 {
a7812ae4 10106 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10107
7c979afd 10108 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10109 if (ctx->nan2008) {
10110 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10111 } else {
10112 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10113 }
7c979afd 10114 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10115 tcg_temp_free_i32(fp0);
b6d96bed 10116 }
5a5012ec 10117 break;
bf4120ad 10118 case OPC_TRUNC_W_S:
b6d96bed 10119 {
a7812ae4 10120 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10121
7c979afd 10122 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10123 if (ctx->nan2008) {
10124 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10125 } else {
10126 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10127 }
7c979afd 10128 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10129 tcg_temp_free_i32(fp0);
b6d96bed 10130 }
5a5012ec 10131 break;
bf4120ad 10132 case OPC_CEIL_W_S:
b6d96bed 10133 {
a7812ae4 10134 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10135
7c979afd 10136 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10137 if (ctx->nan2008) {
10138 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10139 } else {
10140 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10141 }
7c979afd 10142 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10143 tcg_temp_free_i32(fp0);
b6d96bed 10144 }
5a5012ec 10145 break;
bf4120ad 10146 case OPC_FLOOR_W_S:
b6d96bed 10147 {
a7812ae4 10148 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10149
7c979afd 10150 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10151 if (ctx->nan2008) {
10152 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10153 } else {
10154 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10155 }
7c979afd 10156 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10157 tcg_temp_free_i32(fp0);
b6d96bed 10158 }
5a5012ec 10159 break;
e7f16abb
LA
10160 case OPC_SEL_S:
10161 check_insn(ctx, ISA_MIPS32R6);
10162 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10163 break;
10164 case OPC_SELEQZ_S:
10165 check_insn(ctx, ISA_MIPS32R6);
10166 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10167 break;
10168 case OPC_SELNEZ_S:
10169 check_insn(ctx, ISA_MIPS32R6);
10170 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 10171 break;
bf4120ad 10172 case OPC_MOVCF_S:
fecd2646 10173 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 10174 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10175 break;
bf4120ad 10176 case OPC_MOVZ_S:
fecd2646 10177 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10178 {
42a268c2 10179 TCGLabel *l1 = gen_new_label();
c9297f4d 10180 TCGv_i32 fp0;
a16336e4 10181
c9297f4d
AJ
10182 if (ft != 0) {
10183 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10184 }
10185 fp0 = tcg_temp_new_i32();
7c979afd
LA
10186 gen_load_fpr32(ctx, fp0, fs);
10187 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10188 tcg_temp_free_i32(fp0);
a16336e4
TS
10189 gen_set_label(l1);
10190 }
5a5012ec 10191 break;
bf4120ad 10192 case OPC_MOVN_S:
fecd2646 10193 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10194 {
42a268c2 10195 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10196 TCGv_i32 fp0;
10197
10198 if (ft != 0) {
10199 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10200 fp0 = tcg_temp_new_i32();
7c979afd
LA
10201 gen_load_fpr32(ctx, fp0, fs);
10202 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
10203 tcg_temp_free_i32(fp0);
10204 gen_set_label(l1);
10205 }
a16336e4 10206 }
5a5012ec 10207 break;
bf4120ad 10208 case OPC_RECIP_S:
b6d96bed 10209 {
a7812ae4 10210 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10211
7c979afd 10212 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10213 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 10214 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10215 tcg_temp_free_i32(fp0);
b6d96bed 10216 }
57fa1fb3 10217 break;
bf4120ad 10218 case OPC_RSQRT_S:
b6d96bed 10219 {
a7812ae4 10220 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10221
7c979afd 10222 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10223 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 10224 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10225 tcg_temp_free_i32(fp0);
b6d96bed 10226 }
57fa1fb3 10227 break;
e7f16abb
LA
10228 case OPC_MADDF_S:
10229 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10230 {
a7812ae4
PB
10231 TCGv_i32 fp0 = tcg_temp_new_i32();
10232 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10233 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10234 gen_load_fpr32(ctx, fp0, fs);
10235 gen_load_fpr32(ctx, fp1, ft);
10236 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10237 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10238 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 10239 tcg_temp_free_i32(fp2);
a7812ae4 10240 tcg_temp_free_i32(fp1);
a7812ae4 10241 tcg_temp_free_i32(fp0);
b6d96bed 10242 }
57fa1fb3 10243 break;
e7f16abb
LA
10244 case OPC_MSUBF_S:
10245 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10246 {
a7812ae4 10247 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
10248 TCGv_i32 fp1 = tcg_temp_new_i32();
10249 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10250 gen_load_fpr32(ctx, fp0, fs);
10251 gen_load_fpr32(ctx, fp1, ft);
10252 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10253 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10254 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10255 tcg_temp_free_i32(fp2);
10256 tcg_temp_free_i32(fp1);
a7812ae4 10257 tcg_temp_free_i32(fp0);
b6d96bed 10258 }
57fa1fb3 10259 break;
e7f16abb
LA
10260 case OPC_RINT_S:
10261 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10262 {
a7812ae4 10263 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10264 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10265 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 10266 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10267 tcg_temp_free_i32(fp0);
b6d96bed 10268 }
57fa1fb3 10269 break;
e7f16abb
LA
10270 case OPC_CLASS_S:
10271 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10272 {
e7f16abb 10273 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10274 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 10275 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 10276 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 10277 tcg_temp_free_i32(fp0);
e7f16abb
LA
10278 }
10279 break;
10280 case OPC_MIN_S: /* OPC_RECIP2_S */
10281 if (ctx->insn_flags & ISA_MIPS32R6) {
10282 /* OPC_MIN_S */
a7812ae4
PB
10283 TCGv_i32 fp0 = tcg_temp_new_i32();
10284 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10285 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10286 gen_load_fpr32(ctx, fp0, fs);
10287 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10288 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 10289 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10290 tcg_temp_free_i32(fp2);
10291 tcg_temp_free_i32(fp1);
10292 tcg_temp_free_i32(fp0);
e7f16abb
LA
10293 } else {
10294 /* OPC_RECIP2_S */
10295 check_cp1_64bitmode(ctx);
10296 {
10297 TCGv_i32 fp0 = tcg_temp_new_i32();
10298 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10299
7c979afd
LA
10300 gen_load_fpr32(ctx, fp0, fs);
10301 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10302 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10303 tcg_temp_free_i32(fp1);
7c979afd 10304 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10305 tcg_temp_free_i32(fp0);
10306 }
e7f16abb
LA
10307 }
10308 break;
10309 case OPC_MINA_S: /* OPC_RECIP1_S */
10310 if (ctx->insn_flags & ISA_MIPS32R6) {
10311 /* OPC_MINA_S */
10312 TCGv_i32 fp0 = tcg_temp_new_i32();
10313 TCGv_i32 fp1 = tcg_temp_new_i32();
10314 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10315 gen_load_fpr32(ctx, fp0, fs);
10316 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10317 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 10318 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10319 tcg_temp_free_i32(fp2);
10320 tcg_temp_free_i32(fp1);
10321 tcg_temp_free_i32(fp0);
e7f16abb
LA
10322 } else {
10323 /* OPC_RECIP1_S */
10324 check_cp1_64bitmode(ctx);
10325 {
10326 TCGv_i32 fp0 = tcg_temp_new_i32();
10327
7c979afd 10328 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10329 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 10330 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10331 tcg_temp_free_i32(fp0);
10332 }
e7f16abb
LA
10333 }
10334 break;
10335 case OPC_MAX_S: /* OPC_RSQRT1_S */
10336 if (ctx->insn_flags & ISA_MIPS32R6) {
10337 /* OPC_MAX_S */
10338 TCGv_i32 fp0 = tcg_temp_new_i32();
10339 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10340 gen_load_fpr32(ctx, fp0, fs);
10341 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10342 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 10343 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
10344 tcg_temp_free_i32(fp1);
10345 tcg_temp_free_i32(fp0);
e7f16abb
LA
10346 } else {
10347 /* OPC_RSQRT1_S */
10348 check_cp1_64bitmode(ctx);
10349 {
10350 TCGv_i32 fp0 = tcg_temp_new_i32();
10351
7c979afd 10352 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10353 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 10354 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10355 tcg_temp_free_i32(fp0);
10356 }
e7f16abb
LA
10357 }
10358 break;
10359 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10360 if (ctx->insn_flags & ISA_MIPS32R6) {
10361 /* OPC_MAXA_S */
10362 TCGv_i32 fp0 = tcg_temp_new_i32();
10363 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10364 gen_load_fpr32(ctx, fp0, fs);
10365 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10366 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 10367 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 10368 tcg_temp_free_i32(fp1);
a7812ae4 10369 tcg_temp_free_i32(fp0);
e7f16abb
LA
10370 } else {
10371 /* OPC_RSQRT2_S */
10372 check_cp1_64bitmode(ctx);
10373 {
10374 TCGv_i32 fp0 = tcg_temp_new_i32();
10375 TCGv_i32 fp1 = tcg_temp_new_i32();
10376
7c979afd
LA
10377 gen_load_fpr32(ctx, fp0, fs);
10378 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10379 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10380 tcg_temp_free_i32(fp1);
7c979afd 10381 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10382 tcg_temp_free_i32(fp0);
10383 }
b6d96bed 10384 }
57fa1fb3 10385 break;
bf4120ad 10386 case OPC_CVT_D_S:
5e755519 10387 check_cp1_registers(ctx, fd);
b6d96bed 10388 {
a7812ae4
PB
10389 TCGv_i32 fp32 = tcg_temp_new_i32();
10390 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10391
7c979afd 10392 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10393 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 10394 tcg_temp_free_i32(fp32);
b6d96bed 10395 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10396 tcg_temp_free_i64(fp64);
b6d96bed 10397 }
5a5012ec 10398 break;
bf4120ad 10399 case OPC_CVT_W_S:
b6d96bed 10400 {
a7812ae4 10401 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10402
7c979afd 10403 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10404 if (ctx->nan2008) {
10405 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10406 } else {
10407 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10408 }
7c979afd 10409 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10410 tcg_temp_free_i32(fp0);
b6d96bed 10411 }
5a5012ec 10412 break;
bf4120ad 10413 case OPC_CVT_L_S:
5e755519 10414 check_cp1_64bitmode(ctx);
b6d96bed 10415 {
a7812ae4
PB
10416 TCGv_i32 fp32 = tcg_temp_new_i32();
10417 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10418
7c979afd 10419 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10420 if (ctx->nan2008) {
10421 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10422 } else {
10423 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10424 }
a7812ae4 10425 tcg_temp_free_i32(fp32);
b6d96bed 10426 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10427 tcg_temp_free_i64(fp64);
b6d96bed 10428 }
5a5012ec 10429 break;
bf4120ad 10430 case OPC_CVT_PS_S:
e29c9628 10431 check_ps(ctx);
b6d96bed 10432 {
a7812ae4
PB
10433 TCGv_i64 fp64 = tcg_temp_new_i64();
10434 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10435 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 10436
7c979afd
LA
10437 gen_load_fpr32(ctx, fp32_0, fs);
10438 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 10439 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
10440 tcg_temp_free_i32(fp32_1);
10441 tcg_temp_free_i32(fp32_0);
36aa55dc 10442 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10443 tcg_temp_free_i64(fp64);
b6d96bed 10444 }
5a5012ec 10445 break;
bf4120ad
NF
10446 case OPC_CMP_F_S:
10447 case OPC_CMP_UN_S:
10448 case OPC_CMP_EQ_S:
10449 case OPC_CMP_UEQ_S:
10450 case OPC_CMP_OLT_S:
10451 case OPC_CMP_ULT_S:
10452 case OPC_CMP_OLE_S:
10453 case OPC_CMP_ULE_S:
10454 case OPC_CMP_SF_S:
10455 case OPC_CMP_NGLE_S:
10456 case OPC_CMP_SEQ_S:
10457 case OPC_CMP_NGL_S:
10458 case OPC_CMP_LT_S:
10459 case OPC_CMP_NGE_S:
10460 case OPC_CMP_LE_S:
10461 case OPC_CMP_NGT_S:
fecd2646 10462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10463 if (ctx->opcode & (1 << 6)) {
10464 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
10465 } else {
10466 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 10467 }
5a5012ec 10468 break;
bf4120ad 10469 case OPC_ADD_D:
5e755519 10470 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10471 {
a7812ae4
PB
10472 TCGv_i64 fp0 = tcg_temp_new_i64();
10473 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10474
10475 gen_load_fpr64(ctx, fp0, fs);
10476 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10477 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10478 tcg_temp_free_i64(fp1);
b6d96bed 10479 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10480 tcg_temp_free_i64(fp0);
b6d96bed 10481 }
6ea83fed 10482 break;
bf4120ad 10483 case OPC_SUB_D:
5e755519 10484 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10485 {
a7812ae4
PB
10486 TCGv_i64 fp0 = tcg_temp_new_i64();
10487 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10488
10489 gen_load_fpr64(ctx, fp0, fs);
10490 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10491 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10492 tcg_temp_free_i64(fp1);
b6d96bed 10493 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10494 tcg_temp_free_i64(fp0);
b6d96bed 10495 }
6ea83fed 10496 break;
bf4120ad 10497 case OPC_MUL_D:
5e755519 10498 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10499 {
a7812ae4
PB
10500 TCGv_i64 fp0 = tcg_temp_new_i64();
10501 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10502
10503 gen_load_fpr64(ctx, fp0, fs);
10504 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10505 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10506 tcg_temp_free_i64(fp1);
b6d96bed 10507 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10508 tcg_temp_free_i64(fp0);
b6d96bed 10509 }
6ea83fed 10510 break;
bf4120ad 10511 case OPC_DIV_D:
5e755519 10512 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10513 {
a7812ae4
PB
10514 TCGv_i64 fp0 = tcg_temp_new_i64();
10515 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10516
10517 gen_load_fpr64(ctx, fp0, fs);
10518 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10519 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10520 tcg_temp_free_i64(fp1);
b6d96bed 10521 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10522 tcg_temp_free_i64(fp0);
b6d96bed 10523 }
6ea83fed 10524 break;
bf4120ad 10525 case OPC_SQRT_D:
5e755519 10526 check_cp1_registers(ctx, fs | fd);
b6d96bed 10527 {
a7812ae4 10528 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10529
10530 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10531 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 10532 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10533 tcg_temp_free_i64(fp0);
b6d96bed 10534 }
6ea83fed 10535 break;
bf4120ad 10536 case OPC_ABS_D:
5e755519 10537 check_cp1_registers(ctx, fs | fd);
b6d96bed 10538 {
a7812ae4 10539 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10540
10541 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10542 if (ctx->abs2008) {
10543 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10544 } else {
10545 gen_helper_float_abs_d(fp0, fp0);
10546 }
b6d96bed 10547 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10548 tcg_temp_free_i64(fp0);
b6d96bed 10549 }
6ea83fed 10550 break;
bf4120ad 10551 case OPC_MOV_D:
5e755519 10552 check_cp1_registers(ctx, fs | fd);
b6d96bed 10553 {
a7812ae4 10554 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10555
10556 gen_load_fpr64(ctx, fp0, fs);
10557 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10558 tcg_temp_free_i64(fp0);
b6d96bed 10559 }
6ea83fed 10560 break;
bf4120ad 10561 case OPC_NEG_D:
5e755519 10562 check_cp1_registers(ctx, fs | fd);
b6d96bed 10563 {
a7812ae4 10564 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10565
10566 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10567 if (ctx->abs2008) {
10568 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10569 } else {
10570 gen_helper_float_chs_d(fp0, fp0);
10571 }
b6d96bed 10572 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10573 tcg_temp_free_i64(fp0);
b6d96bed 10574 }
6ea83fed 10575 break;
bf4120ad 10576 case OPC_ROUND_L_D:
5e755519 10577 check_cp1_64bitmode(ctx);
b6d96bed 10578 {
a7812ae4 10579 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10580
10581 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10582 if (ctx->nan2008) {
10583 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10584 } else {
10585 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10586 }
b6d96bed 10587 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10588 tcg_temp_free_i64(fp0);
b6d96bed 10589 }
5a5012ec 10590 break;
bf4120ad 10591 case OPC_TRUNC_L_D:
5e755519 10592 check_cp1_64bitmode(ctx);
b6d96bed 10593 {
a7812ae4 10594 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10595
10596 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10597 if (ctx->nan2008) {
10598 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10599 } else {
10600 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10601 }
b6d96bed 10602 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10603 tcg_temp_free_i64(fp0);
b6d96bed 10604 }
5a5012ec 10605 break;
bf4120ad 10606 case OPC_CEIL_L_D:
5e755519 10607 check_cp1_64bitmode(ctx);
b6d96bed 10608 {
a7812ae4 10609 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10610
10611 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10612 if (ctx->nan2008) {
10613 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10614 } else {
10615 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10616 }
b6d96bed 10617 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10618 tcg_temp_free_i64(fp0);
b6d96bed 10619 }
5a5012ec 10620 break;
bf4120ad 10621 case OPC_FLOOR_L_D:
5e755519 10622 check_cp1_64bitmode(ctx);
b6d96bed 10623 {
a7812ae4 10624 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10625
10626 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10627 if (ctx->nan2008) {
10628 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10629 } else {
10630 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10631 }
b6d96bed 10632 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10633 tcg_temp_free_i64(fp0);
b6d96bed 10634 }
5a5012ec 10635 break;
bf4120ad 10636 case OPC_ROUND_W_D:
5e755519 10637 check_cp1_registers(ctx, fs);
b6d96bed 10638 {
a7812ae4
PB
10639 TCGv_i32 fp32 = tcg_temp_new_i32();
10640 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10641
10642 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10643 if (ctx->nan2008) {
10644 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10645 } else {
10646 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10647 }
a7812ae4 10648 tcg_temp_free_i64(fp64);
7c979afd 10649 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10650 tcg_temp_free_i32(fp32);
b6d96bed 10651 }
6ea83fed 10652 break;
bf4120ad 10653 case OPC_TRUNC_W_D:
5e755519 10654 check_cp1_registers(ctx, fs);
b6d96bed 10655 {
a7812ae4
PB
10656 TCGv_i32 fp32 = tcg_temp_new_i32();
10657 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10658
10659 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10660 if (ctx->nan2008) {
10661 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10662 } else {
10663 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10664 }
a7812ae4 10665 tcg_temp_free_i64(fp64);
7c979afd 10666 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10667 tcg_temp_free_i32(fp32);
b6d96bed 10668 }
6ea83fed 10669 break;
bf4120ad 10670 case OPC_CEIL_W_D:
5e755519 10671 check_cp1_registers(ctx, fs);
b6d96bed 10672 {
a7812ae4
PB
10673 TCGv_i32 fp32 = tcg_temp_new_i32();
10674 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10675
10676 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10677 if (ctx->nan2008) {
10678 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10679 } else {
10680 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10681 }
a7812ae4 10682 tcg_temp_free_i64(fp64);
7c979afd 10683 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10684 tcg_temp_free_i32(fp32);
b6d96bed 10685 }
6ea83fed 10686 break;
bf4120ad 10687 case OPC_FLOOR_W_D:
5e755519 10688 check_cp1_registers(ctx, fs);
b6d96bed 10689 {
a7812ae4
PB
10690 TCGv_i32 fp32 = tcg_temp_new_i32();
10691 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10692
10693 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10694 if (ctx->nan2008) {
10695 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10696 } else {
10697 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10698 }
a7812ae4 10699 tcg_temp_free_i64(fp64);
7c979afd 10700 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10701 tcg_temp_free_i32(fp32);
b6d96bed 10702 }
6ea83fed 10703 break;
e7f16abb
LA
10704 case OPC_SEL_D:
10705 check_insn(ctx, ISA_MIPS32R6);
10706 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10707 break;
10708 case OPC_SELEQZ_D:
10709 check_insn(ctx, ISA_MIPS32R6);
10710 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10711 break;
10712 case OPC_SELNEZ_D:
10713 check_insn(ctx, ISA_MIPS32R6);
10714 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 10715 break;
bf4120ad 10716 case OPC_MOVCF_D:
fecd2646 10717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 10718 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 10719 break;
bf4120ad 10720 case OPC_MOVZ_D:
fecd2646 10721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10722 {
42a268c2 10723 TCGLabel *l1 = gen_new_label();
c9297f4d 10724 TCGv_i64 fp0;
a16336e4 10725
c9297f4d
AJ
10726 if (ft != 0) {
10727 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10728 }
10729 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10730 gen_load_fpr64(ctx, fp0, fs);
10731 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10732 tcg_temp_free_i64(fp0);
a16336e4
TS
10733 gen_set_label(l1);
10734 }
5a5012ec 10735 break;
bf4120ad 10736 case OPC_MOVN_D:
fecd2646 10737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10738 {
42a268c2 10739 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10740 TCGv_i64 fp0;
10741
10742 if (ft != 0) {
10743 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10744 fp0 = tcg_temp_new_i64();
10745 gen_load_fpr64(ctx, fp0, fs);
10746 gen_store_fpr64(ctx, fp0, fd);
10747 tcg_temp_free_i64(fp0);
10748 gen_set_label(l1);
10749 }
a16336e4 10750 }
6ea83fed 10751 break;
bf4120ad 10752 case OPC_RECIP_D:
ca6c7803 10753 check_cp1_registers(ctx, fs | fd);
b6d96bed 10754 {
a7812ae4 10755 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10756
10757 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10758 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 10759 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10760 tcg_temp_free_i64(fp0);
b6d96bed 10761 }
57fa1fb3 10762 break;
bf4120ad 10763 case OPC_RSQRT_D:
ca6c7803 10764 check_cp1_registers(ctx, fs | fd);
b6d96bed 10765 {
a7812ae4 10766 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10767
10768 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10769 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 10770 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10771 tcg_temp_free_i64(fp0);
b6d96bed 10772 }
57fa1fb3 10773 break;
e7f16abb
LA
10774 case OPC_MADDF_D:
10775 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10776 {
a7812ae4
PB
10777 TCGv_i64 fp0 = tcg_temp_new_i64();
10778 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 10779 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10780 gen_load_fpr64(ctx, fp0, fs);
10781 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10782 gen_load_fpr64(ctx, fp2, fd);
10783 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10784 gen_store_fpr64(ctx, fp2, fd);
10785 tcg_temp_free_i64(fp2);
a7812ae4 10786 tcg_temp_free_i64(fp1);
a7812ae4 10787 tcg_temp_free_i64(fp0);
b6d96bed 10788 }
57fa1fb3 10789 break;
e7f16abb
LA
10790 case OPC_MSUBF_D:
10791 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10792 {
a7812ae4 10793 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
10794 TCGv_i64 fp1 = tcg_temp_new_i64();
10795 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 10796 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
10797 gen_load_fpr64(ctx, fp1, ft);
10798 gen_load_fpr64(ctx, fp2, fd);
10799 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10800 gen_store_fpr64(ctx, fp2, fd);
10801 tcg_temp_free_i64(fp2);
10802 tcg_temp_free_i64(fp1);
a7812ae4 10803 tcg_temp_free_i64(fp0);
b6d96bed 10804 }
57fa1fb3 10805 break;
e7f16abb
LA
10806 case OPC_RINT_D:
10807 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10808 {
a7812ae4 10809 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10810 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 10811 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 10812 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10813 tcg_temp_free_i64(fp0);
b6d96bed 10814 }
57fa1fb3 10815 break;
e7f16abb
LA
10816 case OPC_CLASS_D:
10817 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10818 {
e7f16abb
LA
10819 TCGv_i64 fp0 = tcg_temp_new_i64();
10820 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 10821 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
10822 gen_store_fpr64(ctx, fp0, fd);
10823 tcg_temp_free_i64(fp0);
e7f16abb
LA
10824 }
10825 break;
10826 case OPC_MIN_D: /* OPC_RECIP2_D */
10827 if (ctx->insn_flags & ISA_MIPS32R6) {
10828 /* OPC_MIN_D */
a7812ae4
PB
10829 TCGv_i64 fp0 = tcg_temp_new_i64();
10830 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
10831 gen_load_fpr64(ctx, fp0, fs);
10832 gen_load_fpr64(ctx, fp1, ft);
10833 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10834 gen_store_fpr64(ctx, fp1, fd);
10835 tcg_temp_free_i64(fp1);
10836 tcg_temp_free_i64(fp0);
e7f16abb
LA
10837 } else {
10838 /* OPC_RECIP2_D */
10839 check_cp1_64bitmode(ctx);
10840 {
10841 TCGv_i64 fp0 = tcg_temp_new_i64();
10842 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 10843
e7f16abb
LA
10844 gen_load_fpr64(ctx, fp0, fs);
10845 gen_load_fpr64(ctx, fp1, ft);
10846 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10847 tcg_temp_free_i64(fp1);
10848 gen_store_fpr64(ctx, fp0, fd);
10849 tcg_temp_free_i64(fp0);
10850 }
e7f16abb
LA
10851 }
10852 break;
10853 case OPC_MINA_D: /* OPC_RECIP1_D */
10854 if (ctx->insn_flags & ISA_MIPS32R6) {
10855 /* OPC_MINA_D */
10856 TCGv_i64 fp0 = tcg_temp_new_i64();
10857 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10858 gen_load_fpr64(ctx, fp0, fs);
10859 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10860 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10861 gen_store_fpr64(ctx, fp1, fd);
10862 tcg_temp_free_i64(fp1);
10863 tcg_temp_free_i64(fp0);
e7f16abb
LA
10864 } else {
10865 /* OPC_RECIP1_D */
10866 check_cp1_64bitmode(ctx);
10867 {
10868 TCGv_i64 fp0 = tcg_temp_new_i64();
10869
10870 gen_load_fpr64(ctx, fp0, fs);
10871 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10872 gen_store_fpr64(ctx, fp0, fd);
10873 tcg_temp_free_i64(fp0);
10874 }
e7f16abb
LA
10875 }
10876 break;
10877 case OPC_MAX_D: /* OPC_RSQRT1_D */
10878 if (ctx->insn_flags & ISA_MIPS32R6) {
10879 /* OPC_MAX_D */
10880 TCGv_i64 fp0 = tcg_temp_new_i64();
10881 TCGv_i64 fp1 = tcg_temp_new_i64();
10882 gen_load_fpr64(ctx, fp0, fs);
10883 gen_load_fpr64(ctx, fp1, ft);
10884 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10885 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10886 tcg_temp_free_i64(fp1);
a7812ae4 10887 tcg_temp_free_i64(fp0);
e7f16abb
LA
10888 } else {
10889 /* OPC_RSQRT1_D */
10890 check_cp1_64bitmode(ctx);
10891 {
10892 TCGv_i64 fp0 = tcg_temp_new_i64();
10893
10894 gen_load_fpr64(ctx, fp0, fs);
10895 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10896 gen_store_fpr64(ctx, fp0, fd);
10897 tcg_temp_free_i64(fp0);
10898 }
e7f16abb
LA
10899 }
10900 break;
10901 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10902 if (ctx->insn_flags & ISA_MIPS32R6) {
10903 /* OPC_MAXA_D */
10904 TCGv_i64 fp0 = tcg_temp_new_i64();
10905 TCGv_i64 fp1 = tcg_temp_new_i64();
10906 gen_load_fpr64(ctx, fp0, fs);
10907 gen_load_fpr64(ctx, fp1, ft);
10908 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10909 gen_store_fpr64(ctx, fp1, fd);
10910 tcg_temp_free_i64(fp1);
10911 tcg_temp_free_i64(fp0);
e7f16abb
LA
10912 } else {
10913 /* OPC_RSQRT2_D */
10914 check_cp1_64bitmode(ctx);
10915 {
10916 TCGv_i64 fp0 = tcg_temp_new_i64();
10917 TCGv_i64 fp1 = tcg_temp_new_i64();
10918
10919 gen_load_fpr64(ctx, fp0, fs);
10920 gen_load_fpr64(ctx, fp1, ft);
10921 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10922 tcg_temp_free_i64(fp1);
10923 gen_store_fpr64(ctx, fp0, fd);
10924 tcg_temp_free_i64(fp0);
10925 }
b6d96bed 10926 }
57fa1fb3 10927 break;
bf4120ad
NF
10928 case OPC_CMP_F_D:
10929 case OPC_CMP_UN_D:
10930 case OPC_CMP_EQ_D:
10931 case OPC_CMP_UEQ_D:
10932 case OPC_CMP_OLT_D:
10933 case OPC_CMP_ULT_D:
10934 case OPC_CMP_OLE_D:
10935 case OPC_CMP_ULE_D:
10936 case OPC_CMP_SF_D:
10937 case OPC_CMP_NGLE_D:
10938 case OPC_CMP_SEQ_D:
10939 case OPC_CMP_NGL_D:
10940 case OPC_CMP_LT_D:
10941 case OPC_CMP_NGE_D:
10942 case OPC_CMP_LE_D:
10943 case OPC_CMP_NGT_D:
fecd2646 10944 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10945 if (ctx->opcode & (1 << 6)) {
10946 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
10947 } else {
10948 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 10949 }
6ea83fed 10950 break;
bf4120ad 10951 case OPC_CVT_S_D:
5e755519 10952 check_cp1_registers(ctx, fs);
b6d96bed 10953 {
a7812ae4
PB
10954 TCGv_i32 fp32 = tcg_temp_new_i32();
10955 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10956
10957 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10958 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10959 tcg_temp_free_i64(fp64);
7c979afd 10960 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10961 tcg_temp_free_i32(fp32);
b6d96bed 10962 }
5a5012ec 10963 break;
bf4120ad 10964 case OPC_CVT_W_D:
5e755519 10965 check_cp1_registers(ctx, fs);
b6d96bed 10966 {
a7812ae4
PB
10967 TCGv_i32 fp32 = tcg_temp_new_i32();
10968 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10969
10970 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10971 if (ctx->nan2008) {
10972 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10973 } else {
10974 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10975 }
a7812ae4 10976 tcg_temp_free_i64(fp64);
7c979afd 10977 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10978 tcg_temp_free_i32(fp32);
b6d96bed 10979 }
5a5012ec 10980 break;
bf4120ad 10981 case OPC_CVT_L_D:
5e755519 10982 check_cp1_64bitmode(ctx);
b6d96bed 10983 {
a7812ae4 10984 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10985
10986 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10987 if (ctx->nan2008) {
10988 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10989 } else {
10990 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10991 }
b6d96bed 10992 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10993 tcg_temp_free_i64(fp0);
b6d96bed 10994 }
5a5012ec 10995 break;
bf4120ad 10996 case OPC_CVT_S_W:
b6d96bed 10997 {
a7812ae4 10998 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10999
7c979afd 11000 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11001 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 11002 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11003 tcg_temp_free_i32(fp0);
b6d96bed 11004 }
6ea83fed 11005 break;
bf4120ad 11006 case OPC_CVT_D_W:
5e755519 11007 check_cp1_registers(ctx, fd);
b6d96bed 11008 {
a7812ae4
PB
11009 TCGv_i32 fp32 = tcg_temp_new_i32();
11010 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11011
7c979afd 11012 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11013 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11014 tcg_temp_free_i32(fp32);
b6d96bed 11015 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11016 tcg_temp_free_i64(fp64);
b6d96bed 11017 }
5a5012ec 11018 break;
bf4120ad 11019 case OPC_CVT_S_L:
5e755519 11020 check_cp1_64bitmode(ctx);
b6d96bed 11021 {
a7812ae4
PB
11022 TCGv_i32 fp32 = tcg_temp_new_i32();
11023 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11024
11025 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11026 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11027 tcg_temp_free_i64(fp64);
7c979afd 11028 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11029 tcg_temp_free_i32(fp32);
b6d96bed 11030 }
5a5012ec 11031 break;
bf4120ad 11032 case OPC_CVT_D_L:
5e755519 11033 check_cp1_64bitmode(ctx);
b6d96bed 11034 {
a7812ae4 11035 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11036
11037 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11038 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11039 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11040 tcg_temp_free_i64(fp0);
b6d96bed 11041 }
5a5012ec 11042 break;
bf4120ad 11043 case OPC_CVT_PS_PW:
e29c9628 11044 check_ps(ctx);
b6d96bed 11045 {
a7812ae4 11046 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11047
11048 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11049 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11050 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11051 tcg_temp_free_i64(fp0);
b6d96bed 11052 }
5a5012ec 11053 break;
bf4120ad 11054 case OPC_ADD_PS:
e29c9628 11055 check_ps(ctx);
b6d96bed 11056 {
a7812ae4
PB
11057 TCGv_i64 fp0 = tcg_temp_new_i64();
11058 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11059
11060 gen_load_fpr64(ctx, fp0, fs);
11061 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11062 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11063 tcg_temp_free_i64(fp1);
b6d96bed 11064 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11065 tcg_temp_free_i64(fp0);
b6d96bed 11066 }
6ea83fed 11067 break;
bf4120ad 11068 case OPC_SUB_PS:
e29c9628 11069 check_ps(ctx);
b6d96bed 11070 {
a7812ae4
PB
11071 TCGv_i64 fp0 = tcg_temp_new_i64();
11072 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11073
11074 gen_load_fpr64(ctx, fp0, fs);
11075 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11076 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11077 tcg_temp_free_i64(fp1);
b6d96bed 11078 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11079 tcg_temp_free_i64(fp0);
b6d96bed 11080 }
6ea83fed 11081 break;
bf4120ad 11082 case OPC_MUL_PS:
e29c9628 11083 check_ps(ctx);
b6d96bed 11084 {
a7812ae4
PB
11085 TCGv_i64 fp0 = tcg_temp_new_i64();
11086 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11087
11088 gen_load_fpr64(ctx, fp0, fs);
11089 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11090 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11091 tcg_temp_free_i64(fp1);
b6d96bed 11092 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11093 tcg_temp_free_i64(fp0);
b6d96bed 11094 }
6ea83fed 11095 break;
bf4120ad 11096 case OPC_ABS_PS:
e29c9628 11097 check_ps(ctx);
b6d96bed 11098 {
a7812ae4 11099 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11100
11101 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11102 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11103 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11104 tcg_temp_free_i64(fp0);
b6d96bed 11105 }
6ea83fed 11106 break;
bf4120ad 11107 case OPC_MOV_PS:
e29c9628 11108 check_ps(ctx);
b6d96bed 11109 {
a7812ae4 11110 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11111
11112 gen_load_fpr64(ctx, fp0, fs);
11113 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11114 tcg_temp_free_i64(fp0);
b6d96bed 11115 }
6ea83fed 11116 break;
bf4120ad 11117 case OPC_NEG_PS:
e29c9628 11118 check_ps(ctx);
b6d96bed 11119 {
a7812ae4 11120 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11121
11122 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11123 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11124 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11125 tcg_temp_free_i64(fp0);
b6d96bed 11126 }
6ea83fed 11127 break;
bf4120ad 11128 case OPC_MOVCF_PS:
e29c9628 11129 check_ps(ctx);
7f6613ce 11130 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11131 break;
bf4120ad 11132 case OPC_MOVZ_PS:
e29c9628 11133 check_ps(ctx);
a16336e4 11134 {
42a268c2 11135 TCGLabel *l1 = gen_new_label();
30a3848b 11136 TCGv_i64 fp0;
a16336e4 11137
c9297f4d
AJ
11138 if (ft != 0)
11139 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11140 fp0 = tcg_temp_new_i64();
11141 gen_load_fpr64(ctx, fp0, fs);
11142 gen_store_fpr64(ctx, fp0, fd);
11143 tcg_temp_free_i64(fp0);
a16336e4
TS
11144 gen_set_label(l1);
11145 }
6ea83fed 11146 break;
bf4120ad 11147 case OPC_MOVN_PS:
e29c9628 11148 check_ps(ctx);
a16336e4 11149 {
42a268c2 11150 TCGLabel *l1 = gen_new_label();
30a3848b 11151 TCGv_i64 fp0;
c9297f4d
AJ
11152
11153 if (ft != 0) {
11154 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11155 fp0 = tcg_temp_new_i64();
11156 gen_load_fpr64(ctx, fp0, fs);
11157 gen_store_fpr64(ctx, fp0, fd);
11158 tcg_temp_free_i64(fp0);
11159 gen_set_label(l1);
11160 }
a16336e4 11161 }
6ea83fed 11162 break;
bf4120ad 11163 case OPC_ADDR_PS:
e29c9628 11164 check_ps(ctx);
b6d96bed 11165 {
a7812ae4
PB
11166 TCGv_i64 fp0 = tcg_temp_new_i64();
11167 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11168
11169 gen_load_fpr64(ctx, fp0, ft);
11170 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11171 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11172 tcg_temp_free_i64(fp1);
b6d96bed 11173 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11174 tcg_temp_free_i64(fp0);
b6d96bed 11175 }
fbcc6828 11176 break;
bf4120ad 11177 case OPC_MULR_PS:
e29c9628 11178 check_ps(ctx);
b6d96bed 11179 {
a7812ae4
PB
11180 TCGv_i64 fp0 = tcg_temp_new_i64();
11181 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11182
11183 gen_load_fpr64(ctx, fp0, ft);
11184 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11185 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11186 tcg_temp_free_i64(fp1);
b6d96bed 11187 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11188 tcg_temp_free_i64(fp0);
b6d96bed 11189 }
57fa1fb3 11190 break;
bf4120ad 11191 case OPC_RECIP2_PS:
e29c9628 11192 check_ps(ctx);
b6d96bed 11193 {
a7812ae4
PB
11194 TCGv_i64 fp0 = tcg_temp_new_i64();
11195 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11196
11197 gen_load_fpr64(ctx, fp0, fs);
d22d7289 11198 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11199 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11200 tcg_temp_free_i64(fp1);
b6d96bed 11201 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11202 tcg_temp_free_i64(fp0);
b6d96bed 11203 }
57fa1fb3 11204 break;
bf4120ad 11205 case OPC_RECIP1_PS:
e29c9628 11206 check_ps(ctx);
b6d96bed 11207 {
a7812ae4 11208 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11209
11210 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11211 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 11212 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11213 tcg_temp_free_i64(fp0);
b6d96bed 11214 }
57fa1fb3 11215 break;
bf4120ad 11216 case OPC_RSQRT1_PS:
e29c9628 11217 check_ps(ctx);
b6d96bed 11218 {
a7812ae4 11219 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11220
11221 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11222 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 11223 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11224 tcg_temp_free_i64(fp0);
b6d96bed 11225 }
57fa1fb3 11226 break;
bf4120ad 11227 case OPC_RSQRT2_PS:
e29c9628 11228 check_ps(ctx);
b6d96bed 11229 {
a7812ae4
PB
11230 TCGv_i64 fp0 = tcg_temp_new_i64();
11231 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11232
11233 gen_load_fpr64(ctx, fp0, fs);
11234 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11235 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11236 tcg_temp_free_i64(fp1);
b6d96bed 11237 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11238 tcg_temp_free_i64(fp0);
b6d96bed 11239 }
57fa1fb3 11240 break;
bf4120ad 11241 case OPC_CVT_S_PU:
5e755519 11242 check_cp1_64bitmode(ctx);
b6d96bed 11243 {
a7812ae4 11244 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11245
7f6613ce 11246 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 11247 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 11248 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11249 tcg_temp_free_i32(fp0);
b6d96bed 11250 }
dd016883 11251 break;
bf4120ad 11252 case OPC_CVT_PW_PS:
e29c9628 11253 check_ps(ctx);
b6d96bed 11254 {
a7812ae4 11255 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11256
11257 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11258 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 11259 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11260 tcg_temp_free_i64(fp0);
b6d96bed 11261 }
6ea83fed 11262 break;
bf4120ad 11263 case OPC_CVT_S_PL:
5e755519 11264 check_cp1_64bitmode(ctx);
b6d96bed 11265 {
a7812ae4 11266 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11267
7c979afd 11268 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11269 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 11270 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11271 tcg_temp_free_i32(fp0);
b6d96bed 11272 }
6ea83fed 11273 break;
bf4120ad 11274 case OPC_PLL_PS:
e29c9628 11275 check_ps(ctx);
b6d96bed 11276 {
a7812ae4
PB
11277 TCGv_i32 fp0 = tcg_temp_new_i32();
11278 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11279
7c979afd
LA
11280 gen_load_fpr32(ctx, fp0, fs);
11281 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 11282 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 11283 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
11284 tcg_temp_free_i32(fp0);
11285 tcg_temp_free_i32(fp1);
b6d96bed 11286 }
6ea83fed 11287 break;
bf4120ad 11288 case OPC_PLU_PS:
e29c9628 11289 check_ps(ctx);
b6d96bed 11290 {
a7812ae4
PB
11291 TCGv_i32 fp0 = tcg_temp_new_i32();
11292 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11293
7c979afd 11294 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 11295 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11296 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11297 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11298 tcg_temp_free_i32(fp0);
11299 tcg_temp_free_i32(fp1);
b6d96bed 11300 }
5a5012ec 11301 break;
bf4120ad 11302 case OPC_PUL_PS:
e29c9628 11303 check_ps(ctx);
b6d96bed 11304 {
a7812ae4
PB
11305 TCGv_i32 fp0 = tcg_temp_new_i32();
11306 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11307
7f6613ce 11308 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
11309 gen_load_fpr32(ctx, fp1, ft);
11310 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11311 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11312 tcg_temp_free_i32(fp0);
11313 tcg_temp_free_i32(fp1);
b6d96bed 11314 }
5a5012ec 11315 break;
bf4120ad 11316 case OPC_PUU_PS:
e29c9628 11317 check_ps(ctx);
b6d96bed 11318 {
a7812ae4
PB
11319 TCGv_i32 fp0 = tcg_temp_new_i32();
11320 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11321
7f6613ce
PJ
11322 gen_load_fpr32h(ctx, fp0, fs);
11323 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11324 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11325 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11326 tcg_temp_free_i32(fp0);
11327 tcg_temp_free_i32(fp1);
b6d96bed 11328 }
5a5012ec 11329 break;
bf4120ad
NF
11330 case OPC_CMP_F_PS:
11331 case OPC_CMP_UN_PS:
11332 case OPC_CMP_EQ_PS:
11333 case OPC_CMP_UEQ_PS:
11334 case OPC_CMP_OLT_PS:
11335 case OPC_CMP_ULT_PS:
11336 case OPC_CMP_OLE_PS:
11337 case OPC_CMP_ULE_PS:
11338 case OPC_CMP_SF_PS:
11339 case OPC_CMP_NGLE_PS:
11340 case OPC_CMP_SEQ_PS:
11341 case OPC_CMP_NGL_PS:
11342 case OPC_CMP_LT_PS:
11343 case OPC_CMP_NGE_PS:
11344 case OPC_CMP_LE_PS:
11345 case OPC_CMP_NGT_PS:
8153667c
NF
11346 if (ctx->opcode & (1 << 6)) {
11347 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
11348 } else {
11349 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 11350 }
6ea83fed 11351 break;
5a5012ec 11352 default:
9d68ac14 11353 MIPS_INVAL("farith");
9c708c7f 11354 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
11355 return;
11356 }
6ea83fed 11357}
6af0bf9c 11358
5a5012ec 11359/* Coprocessor 3 (FPU) */
5e755519
TS
11360static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11361 int fd, int fs, int base, int index)
7a387fff 11362{
4e2474d6 11363 TCGv t0 = tcg_temp_new();
7a387fff 11364
93b12ccc 11365 if (base == 0) {
6c5c1e20 11366 gen_load_gpr(t0, index);
93b12ccc 11367 } else if (index == 0) {
6c5c1e20 11368 gen_load_gpr(t0, base);
93b12ccc 11369 } else {
05168674 11370 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 11371 }
5a5012ec 11372 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 11373 memory access. */
5a5012ec
TS
11374 switch (opc) {
11375 case OPC_LWXC1:
8c0ab41f 11376 check_cop1x(ctx);
b6d96bed 11377 {
a7812ae4 11378 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11379
5f68f5ae 11380 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 11381 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 11382 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11383 tcg_temp_free_i32(fp0);
b6d96bed 11384 }
5a5012ec
TS
11385 break;
11386 case OPC_LDXC1:
8c0ab41f
AJ
11387 check_cop1x(ctx);
11388 check_cp1_registers(ctx, fd);
b6d96bed 11389 {
a7812ae4 11390 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 11391 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11392 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11393 tcg_temp_free_i64(fp0);
b6d96bed 11394 }
5a5012ec
TS
11395 break;
11396 case OPC_LUXC1:
8c0ab41f 11397 check_cp1_64bitmode(ctx);
6c5c1e20 11398 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11399 {
a7812ae4 11400 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11401
5f68f5ae 11402 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11403 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11404 tcg_temp_free_i64(fp0);
b6d96bed 11405 }
5a5012ec
TS
11406 break;
11407 case OPC_SWXC1:
8c0ab41f 11408 check_cop1x(ctx);
b6d96bed 11409 {
a7812ae4 11410 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11411 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 11412 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 11413 tcg_temp_free_i32(fp0);
b6d96bed 11414 }
5a5012ec
TS
11415 break;
11416 case OPC_SDXC1:
8c0ab41f
AJ
11417 check_cop1x(ctx);
11418 check_cp1_registers(ctx, fs);
b6d96bed 11419 {
a7812ae4 11420 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11421 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11422 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11423 tcg_temp_free_i64(fp0);
b6d96bed 11424 }
5a5012ec
TS
11425 break;
11426 case OPC_SUXC1:
8c0ab41f 11427 check_cp1_64bitmode(ctx);
6c5c1e20 11428 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11429 {
a7812ae4 11430 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11431 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11432 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11433 tcg_temp_free_i64(fp0);
b6d96bed 11434 }
5a5012ec 11435 break;
5a5012ec 11436 }
6c5c1e20 11437 tcg_temp_free(t0);
5a5012ec
TS
11438}
11439
5e755519
TS
11440static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11441 int fd, int fr, int fs, int ft)
5a5012ec 11442{
5a5012ec
TS
11443 switch (opc) {
11444 case OPC_ALNV_PS:
e29c9628 11445 check_ps(ctx);
a16336e4 11446 {
a7812ae4 11447 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
11448 TCGv_i32 fp = tcg_temp_new_i32();
11449 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
11450 TCGLabel *l1 = gen_new_label();
11451 TCGLabel *l2 = gen_new_label();
a16336e4 11452
6c5c1e20
TS
11453 gen_load_gpr(t0, fr);
11454 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
11455
11456 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 11457 gen_load_fpr32(ctx, fp, fs);
7f6613ce 11458 gen_load_fpr32h(ctx, fph, fs);
7c979afd 11459 gen_store_fpr32(ctx, fp, fd);
7f6613ce 11460 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
11461 tcg_gen_br(l2);
11462 gen_set_label(l1);
6c5c1e20
TS
11463 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11464 tcg_temp_free(t0);
a16336e4 11465#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 11466 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
11467 gen_load_fpr32h(ctx, fph, ft);
11468 gen_store_fpr32h(ctx, fp, fd);
7c979afd 11469 gen_store_fpr32(ctx, fph, fd);
a16336e4 11470#else
7f6613ce 11471 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
11472 gen_load_fpr32(ctx, fp, ft);
11473 gen_store_fpr32(ctx, fph, fd);
7f6613ce 11474 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
11475#endif
11476 gen_set_label(l2);
c905fdac
AJ
11477 tcg_temp_free_i32(fp);
11478 tcg_temp_free_i32(fph);
a16336e4 11479 }
5a5012ec
TS
11480 break;
11481 case OPC_MADD_S:
b8aa4598 11482 check_cop1x(ctx);
b6d96bed 11483 {
a7812ae4
PB
11484 TCGv_i32 fp0 = tcg_temp_new_i32();
11485 TCGv_i32 fp1 = tcg_temp_new_i32();
11486 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11487
7c979afd
LA
11488 gen_load_fpr32(ctx, fp0, fs);
11489 gen_load_fpr32(ctx, fp1, ft);
11490 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11491 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11492 tcg_temp_free_i32(fp0);
11493 tcg_temp_free_i32(fp1);
7c979afd 11494 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11495 tcg_temp_free_i32(fp2);
b6d96bed 11496 }
5a5012ec
TS
11497 break;
11498 case OPC_MADD_D:
b8aa4598
TS
11499 check_cop1x(ctx);
11500 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11501 {
a7812ae4
PB
11502 TCGv_i64 fp0 = tcg_temp_new_i64();
11503 TCGv_i64 fp1 = tcg_temp_new_i64();
11504 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11505
11506 gen_load_fpr64(ctx, fp0, fs);
11507 gen_load_fpr64(ctx, fp1, ft);
11508 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11509 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11510 tcg_temp_free_i64(fp0);
11511 tcg_temp_free_i64(fp1);
b6d96bed 11512 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11513 tcg_temp_free_i64(fp2);
b6d96bed 11514 }
5a5012ec
TS
11515 break;
11516 case OPC_MADD_PS:
e29c9628 11517 check_ps(ctx);
b6d96bed 11518 {
a7812ae4
PB
11519 TCGv_i64 fp0 = tcg_temp_new_i64();
11520 TCGv_i64 fp1 = tcg_temp_new_i64();
11521 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11522
11523 gen_load_fpr64(ctx, fp0, fs);
11524 gen_load_fpr64(ctx, fp1, ft);
11525 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11526 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11527 tcg_temp_free_i64(fp0);
11528 tcg_temp_free_i64(fp1);
b6d96bed 11529 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11530 tcg_temp_free_i64(fp2);
b6d96bed 11531 }
5a5012ec
TS
11532 break;
11533 case OPC_MSUB_S:
b8aa4598 11534 check_cop1x(ctx);
b6d96bed 11535 {
a7812ae4
PB
11536 TCGv_i32 fp0 = tcg_temp_new_i32();
11537 TCGv_i32 fp1 = tcg_temp_new_i32();
11538 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11539
7c979afd
LA
11540 gen_load_fpr32(ctx, fp0, fs);
11541 gen_load_fpr32(ctx, fp1, ft);
11542 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11543 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11544 tcg_temp_free_i32(fp0);
11545 tcg_temp_free_i32(fp1);
7c979afd 11546 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11547 tcg_temp_free_i32(fp2);
b6d96bed 11548 }
5a5012ec
TS
11549 break;
11550 case OPC_MSUB_D:
b8aa4598
TS
11551 check_cop1x(ctx);
11552 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11553 {
a7812ae4
PB
11554 TCGv_i64 fp0 = tcg_temp_new_i64();
11555 TCGv_i64 fp1 = tcg_temp_new_i64();
11556 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11557
11558 gen_load_fpr64(ctx, fp0, fs);
11559 gen_load_fpr64(ctx, fp1, ft);
11560 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11561 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11562 tcg_temp_free_i64(fp0);
11563 tcg_temp_free_i64(fp1);
b6d96bed 11564 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11565 tcg_temp_free_i64(fp2);
b6d96bed 11566 }
5a5012ec
TS
11567 break;
11568 case OPC_MSUB_PS:
e29c9628 11569 check_ps(ctx);
b6d96bed 11570 {
a7812ae4
PB
11571 TCGv_i64 fp0 = tcg_temp_new_i64();
11572 TCGv_i64 fp1 = tcg_temp_new_i64();
11573 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11574
11575 gen_load_fpr64(ctx, fp0, fs);
11576 gen_load_fpr64(ctx, fp1, ft);
11577 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11578 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11579 tcg_temp_free_i64(fp0);
11580 tcg_temp_free_i64(fp1);
b6d96bed 11581 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11582 tcg_temp_free_i64(fp2);
b6d96bed 11583 }
5a5012ec
TS
11584 break;
11585 case OPC_NMADD_S:
b8aa4598 11586 check_cop1x(ctx);
b6d96bed 11587 {
a7812ae4
PB
11588 TCGv_i32 fp0 = tcg_temp_new_i32();
11589 TCGv_i32 fp1 = tcg_temp_new_i32();
11590 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11591
7c979afd
LA
11592 gen_load_fpr32(ctx, fp0, fs);
11593 gen_load_fpr32(ctx, fp1, ft);
11594 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11595 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11596 tcg_temp_free_i32(fp0);
11597 tcg_temp_free_i32(fp1);
7c979afd 11598 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11599 tcg_temp_free_i32(fp2);
b6d96bed 11600 }
5a5012ec
TS
11601 break;
11602 case OPC_NMADD_D:
b8aa4598
TS
11603 check_cop1x(ctx);
11604 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11605 {
a7812ae4
PB
11606 TCGv_i64 fp0 = tcg_temp_new_i64();
11607 TCGv_i64 fp1 = tcg_temp_new_i64();
11608 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11609
11610 gen_load_fpr64(ctx, fp0, fs);
11611 gen_load_fpr64(ctx, fp1, ft);
11612 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11613 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11614 tcg_temp_free_i64(fp0);
11615 tcg_temp_free_i64(fp1);
b6d96bed 11616 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11617 tcg_temp_free_i64(fp2);
b6d96bed 11618 }
5a5012ec
TS
11619 break;
11620 case OPC_NMADD_PS:
e29c9628 11621 check_ps(ctx);
b6d96bed 11622 {
a7812ae4
PB
11623 TCGv_i64 fp0 = tcg_temp_new_i64();
11624 TCGv_i64 fp1 = tcg_temp_new_i64();
11625 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11626
11627 gen_load_fpr64(ctx, fp0, fs);
11628 gen_load_fpr64(ctx, fp1, ft);
11629 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11630 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11631 tcg_temp_free_i64(fp0);
11632 tcg_temp_free_i64(fp1);
b6d96bed 11633 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11634 tcg_temp_free_i64(fp2);
b6d96bed 11635 }
5a5012ec
TS
11636 break;
11637 case OPC_NMSUB_S:
b8aa4598 11638 check_cop1x(ctx);
b6d96bed 11639 {
a7812ae4
PB
11640 TCGv_i32 fp0 = tcg_temp_new_i32();
11641 TCGv_i32 fp1 = tcg_temp_new_i32();
11642 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11643
7c979afd
LA
11644 gen_load_fpr32(ctx, fp0, fs);
11645 gen_load_fpr32(ctx, fp1, ft);
11646 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11647 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11648 tcg_temp_free_i32(fp0);
11649 tcg_temp_free_i32(fp1);
7c979afd 11650 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11651 tcg_temp_free_i32(fp2);
b6d96bed 11652 }
5a5012ec
TS
11653 break;
11654 case OPC_NMSUB_D:
b8aa4598
TS
11655 check_cop1x(ctx);
11656 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11657 {
a7812ae4
PB
11658 TCGv_i64 fp0 = tcg_temp_new_i64();
11659 TCGv_i64 fp1 = tcg_temp_new_i64();
11660 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11661
11662 gen_load_fpr64(ctx, fp0, fs);
11663 gen_load_fpr64(ctx, fp1, ft);
11664 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11665 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11666 tcg_temp_free_i64(fp0);
11667 tcg_temp_free_i64(fp1);
b6d96bed 11668 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11669 tcg_temp_free_i64(fp2);
b6d96bed 11670 }
5a5012ec
TS
11671 break;
11672 case OPC_NMSUB_PS:
e29c9628 11673 check_ps(ctx);
b6d96bed 11674 {
a7812ae4
PB
11675 TCGv_i64 fp0 = tcg_temp_new_i64();
11676 TCGv_i64 fp1 = tcg_temp_new_i64();
11677 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11678
11679 gen_load_fpr64(ctx, fp0, fs);
11680 gen_load_fpr64(ctx, fp1, ft);
11681 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11682 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11683 tcg_temp_free_i64(fp0);
11684 tcg_temp_free_i64(fp1);
b6d96bed 11685 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11686 tcg_temp_free_i64(fp2);
b6d96bed 11687 }
5a5012ec 11688 break;
923617a3 11689 default:
9d68ac14 11690 MIPS_INVAL("flt3_arith");
9c708c7f 11691 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
11692 return;
11693 }
7a387fff
TS
11694}
11695
b00c7218 11696static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
11697{
11698 TCGv t0;
11699
b3167288
RH
11700#if !defined(CONFIG_USER_ONLY)
11701 /* The Linux kernel will emulate rdhwr if it's not supported natively.
11702 Therefore only check the ISA in system mode. */
d75c135e 11703 check_insn(ctx, ISA_MIPS32R2);
b3167288 11704#endif
26ebe468
NF
11705 t0 = tcg_temp_new();
11706
11707 switch (rd) {
11708 case 0:
895c2d04 11709 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
11710 gen_store_gpr(t0, rt);
11711 break;
11712 case 1:
895c2d04 11713 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
11714 gen_store_gpr(t0, rt);
11715 break;
11716 case 2:
eeb3bba8 11717 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11718 gen_io_start();
11719 }
895c2d04 11720 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 11721 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11722 gen_io_end();
11723 }
26ebe468 11724 gen_store_gpr(t0, rt);
d673a68d 11725 /* Break the TB to be able to take timer interrupts immediately
b28425ba 11726 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 11727 we break completely out of translated code. */
eeb3bba8
EC
11728 gen_save_pc(ctx->base.pc_next + 4);
11729 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
11730 break;
11731 case 3:
895c2d04 11732 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
11733 gen_store_gpr(t0, rt);
11734 break;
b00c7218
YK
11735 case 4:
11736 check_insn(ctx, ISA_MIPS32R6);
11737 if (sel != 0) {
11738 /* Performance counter registers are not implemented other than
11739 * control register 0.
11740 */
11741 generate_exception(ctx, EXCP_RI);
11742 }
11743 gen_helper_rdhwr_performance(t0, cpu_env);
11744 gen_store_gpr(t0, rt);
11745 break;
11746 case 5:
11747 check_insn(ctx, ISA_MIPS32R6);
11748 gen_helper_rdhwr_xnp(t0, cpu_env);
11749 gen_store_gpr(t0, rt);
11750 break;
26ebe468
NF
11751 case 29:
11752#if defined(CONFIG_USER_ONLY)
d279279e
PJ
11753 tcg_gen_ld_tl(t0, cpu_env,
11754 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
11755 gen_store_gpr(t0, rt);
11756 break;
11757#else
d279279e
PJ
11758 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11759 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11760 tcg_gen_ld_tl(t0, cpu_env,
11761 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11762 gen_store_gpr(t0, rt);
11763 } else {
9c708c7f 11764 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
11765 }
11766 break;
26ebe468
NF
11767#endif
11768 default: /* Invalid */
11769 MIPS_INVAL("rdhwr");
9c708c7f 11770 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
11771 break;
11772 }
11773 tcg_temp_free(t0);
11774}
11775
a5f53390
LA
11776static inline void clear_branch_hflags(DisasContext *ctx)
11777{
11778 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 11779 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
11780 save_cpu_state(ctx, 0);
11781 } else {
11782 /* it is not safe to save ctx->hflags as hflags may be changed
11783 in execution time by the instruction in delay / forbidden slot. */
11784 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11785 }
11786}
11787
31837be3 11788static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
11789{
11790 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 11791 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 11792 /* Branches completion */
a5f53390 11793 clear_branch_hflags(ctx);
eeb3bba8 11794 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 11795 /* FIXME: Need to clear can_do_io. */
364d4831 11796 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 11797 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 11798 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 11799 break;
c9602061
NF
11800 case MIPS_HFLAG_B:
11801 /* unconditional branch */
364d4831
NF
11802 if (proc_hflags & MIPS_HFLAG_BX) {
11803 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11804 }
c9602061
NF
11805 gen_goto_tb(ctx, 0, ctx->btarget);
11806 break;
11807 case MIPS_HFLAG_BL:
11808 /* blikely taken case */
c9602061
NF
11809 gen_goto_tb(ctx, 0, ctx->btarget);
11810 break;
11811 case MIPS_HFLAG_BC:
11812 /* Conditional branch */
c9602061 11813 {
42a268c2 11814 TCGLabel *l1 = gen_new_label();
c9602061
NF
11815
11816 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 11817 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
11818 gen_set_label(l1);
11819 gen_goto_tb(ctx, 0, ctx->btarget);
11820 }
11821 break;
11822 case MIPS_HFLAG_BR:
11823 /* unconditional branch to register */
d75c135e 11824 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
11825 TCGv t0 = tcg_temp_new();
11826 TCGv_i32 t1 = tcg_temp_new_i32();
11827
11828 tcg_gen_andi_tl(t0, btarget, 0x1);
11829 tcg_gen_trunc_tl_i32(t1, t0);
11830 tcg_temp_free(t0);
11831 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11832 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11833 tcg_gen_or_i32(hflags, hflags, t1);
11834 tcg_temp_free_i32(t1);
11835
11836 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11837 } else {
11838 tcg_gen_mov_tl(cpu_PC, btarget);
11839 }
eeb3bba8 11840 if (ctx->base.singlestep_enabled) {
c9602061 11841 save_cpu_state(ctx, 0);
9c708c7f 11842 gen_helper_raise_exception_debug(cpu_env);
c9602061 11843 }
7f11636d 11844 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
11845 break;
11846 default:
a5f53390
LA
11847 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11848 abort();
c9602061
NF
11849 }
11850 }
11851}
11852
6893f074
YK
11853/* Compact Branches */
11854static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11855 int rs, int rt, int32_t offset)
11856{
11857 int bcond_compute = 0;
11858 TCGv t0 = tcg_temp_new();
11859 TCGv t1 = tcg_temp_new();
65935f07 11860 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11861
11862 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11863#ifdef MIPS_DEBUG_DISAS
11864 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11865 "\n", ctx->base.pc_next);
6893f074 11866#endif
9c708c7f 11867 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11868 goto out;
11869 }
11870
11871 /* Load needed operands and calculate btarget */
11872 switch (opc) {
11873 /* compact branch */
11874 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11875 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11876 gen_load_gpr(t0, rs);
11877 gen_load_gpr(t1, rt);
11878 bcond_compute = 1;
eeb3bba8 11879 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11880 if (rs <= rt && rs == 0) {
11881 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11882 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11883 }
11884 break;
11885 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11886 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11887 gen_load_gpr(t0, rs);
11888 gen_load_gpr(t1, rt);
11889 bcond_compute = 1;
eeb3bba8 11890 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11891 break;
11892 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11893 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11894 if (rs == 0 || rs == rt) {
11895 /* OPC_BLEZALC, OPC_BGEZALC */
11896 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11897 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11898 }
11899 gen_load_gpr(t0, rs);
11900 gen_load_gpr(t1, rt);
11901 bcond_compute = 1;
eeb3bba8 11902 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11903 break;
11904 case OPC_BC:
11905 case OPC_BALC:
eeb3bba8 11906 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11907 break;
11908 case OPC_BEQZC:
11909 case OPC_BNEZC:
11910 if (rs != 0) {
11911 /* OPC_BEQZC, OPC_BNEZC */
11912 gen_load_gpr(t0, rs);
11913 bcond_compute = 1;
eeb3bba8 11914 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11915 } else {
11916 /* OPC_JIC, OPC_JIALC */
11917 TCGv tbase = tcg_temp_new();
11918 TCGv toffset = tcg_temp_new();
11919
11920 gen_load_gpr(tbase, rt);
11921 tcg_gen_movi_tl(toffset, offset);
11922 gen_op_addr_add(ctx, btarget, tbase, toffset);
11923 tcg_temp_free(tbase);
11924 tcg_temp_free(toffset);
11925 }
11926 break;
11927 default:
11928 MIPS_INVAL("Compact branch/jump");
9c708c7f 11929 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11930 goto out;
11931 }
11932
11933 if (bcond_compute == 0) {
11934 /* Uncoditional compact branch */
11935 switch (opc) {
11936 case OPC_JIALC:
eeb3bba8 11937 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11938 /* Fallthrough */
11939 case OPC_JIC:
11940 ctx->hflags |= MIPS_HFLAG_BR;
11941 break;
11942 case OPC_BALC:
eeb3bba8 11943 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11944 /* Fallthrough */
11945 case OPC_BC:
11946 ctx->hflags |= MIPS_HFLAG_B;
11947 break;
11948 default:
11949 MIPS_INVAL("Compact branch/jump");
9c708c7f 11950 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11951 goto out;
11952 }
11953
11954 /* Generating branch here as compact branches don't have delay slot */
11955 gen_branch(ctx, 4);
11956 } else {
11957 /* Conditional compact branch */
11958 TCGLabel *fs = gen_new_label();
11959 save_cpu_state(ctx, 0);
11960
11961 switch (opc) {
11962 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11963 if (rs == 0 && rt != 0) {
11964 /* OPC_BLEZALC */
11965 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11966 } else if (rs != 0 && rt != 0 && rs == rt) {
11967 /* OPC_BGEZALC */
11968 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11969 } else {
11970 /* OPC_BGEUC */
11971 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11972 }
11973 break;
11974 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11975 if (rs == 0 && rt != 0) {
11976 /* OPC_BGTZALC */
11977 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11978 } else if (rs != 0 && rt != 0 && rs == rt) {
11979 /* OPC_BLTZALC */
11980 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11981 } else {
11982 /* OPC_BLTUC */
11983 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11984 }
11985 break;
11986 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11987 if (rs == 0 && rt != 0) {
11988 /* OPC_BLEZC */
11989 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11990 } else if (rs != 0 && rt != 0 && rs == rt) {
11991 /* OPC_BGEZC */
11992 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11993 } else {
11994 /* OPC_BGEC */
11995 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11996 }
11997 break;
11998 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11999 if (rs == 0 && rt != 0) {
12000 /* OPC_BGTZC */
12001 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12002 } else if (rs != 0 && rt != 0 && rs == rt) {
12003 /* OPC_BLTZC */
12004 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12005 } else {
12006 /* OPC_BLTC */
12007 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12008 }
12009 break;
12010 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12011 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12012 if (rs >= rt) {
12013 /* OPC_BOVC, OPC_BNVC */
12014 TCGv t2 = tcg_temp_new();
12015 TCGv t3 = tcg_temp_new();
12016 TCGv t4 = tcg_temp_new();
12017 TCGv input_overflow = tcg_temp_new();
12018
12019 gen_load_gpr(t0, rs);
12020 gen_load_gpr(t1, rt);
12021 tcg_gen_ext32s_tl(t2, t0);
12022 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12023 tcg_gen_ext32s_tl(t3, t1);
12024 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12025 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12026
12027 tcg_gen_add_tl(t4, t2, t3);
12028 tcg_gen_ext32s_tl(t4, t4);
12029 tcg_gen_xor_tl(t2, t2, t3);
12030 tcg_gen_xor_tl(t3, t4, t3);
12031 tcg_gen_andc_tl(t2, t3, t2);
12032 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12033 tcg_gen_or_tl(t4, t4, input_overflow);
12034 if (opc == OPC_BOVC) {
12035 /* OPC_BOVC */
12036 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12037 } else {
12038 /* OPC_BNVC */
12039 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12040 }
12041 tcg_temp_free(input_overflow);
12042 tcg_temp_free(t4);
12043 tcg_temp_free(t3);
12044 tcg_temp_free(t2);
12045 } else if (rs < rt && rs == 0) {
12046 /* OPC_BEQZALC, OPC_BNEZALC */
12047 if (opc == OPC_BEQZALC) {
12048 /* OPC_BEQZALC */
12049 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12050 } else {
12051 /* OPC_BNEZALC */
12052 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12053 }
12054 } else {
12055 /* OPC_BEQC, OPC_BNEC */
12056 if (opc == OPC_BEQC) {
12057 /* OPC_BEQC */
12058 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12059 } else {
12060 /* OPC_BNEC */
12061 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12062 }
12063 }
12064 break;
12065 case OPC_BEQZC:
12066 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12067 break;
12068 case OPC_BNEZC:
12069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12070 break;
12071 default:
12072 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 12073 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12074 goto out;
12075 }
12076
12077 /* Generating branch here as compact branches don't have delay slot */
12078 gen_goto_tb(ctx, 1, ctx->btarget);
12079 gen_set_label(fs);
12080
12081 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12082 }
12083
12084out:
12085 tcg_temp_free(t0);
12086 tcg_temp_free(t1);
12087}
12088
7a387fff 12089/* ISA extensions (ASEs) */
6af0bf9c 12090/* MIPS16 extension to MIPS32 */
6ea219d0
NF
12091
12092/* MIPS16 major opcodes */
12093enum {
12094 M16_OPC_ADDIUSP = 0x00,
12095 M16_OPC_ADDIUPC = 0x01,
12096 M16_OPC_B = 0x02,
12097 M16_OPC_JAL = 0x03,
12098 M16_OPC_BEQZ = 0x04,
12099 M16_OPC_BNEQZ = 0x05,
12100 M16_OPC_SHIFT = 0x06,
12101 M16_OPC_LD = 0x07,
12102 M16_OPC_RRIA = 0x08,
12103 M16_OPC_ADDIU8 = 0x09,
12104 M16_OPC_SLTI = 0x0a,
12105 M16_OPC_SLTIU = 0x0b,
12106 M16_OPC_I8 = 0x0c,
12107 M16_OPC_LI = 0x0d,
12108 M16_OPC_CMPI = 0x0e,
12109 M16_OPC_SD = 0x0f,
12110 M16_OPC_LB = 0x10,
12111 M16_OPC_LH = 0x11,
12112 M16_OPC_LWSP = 0x12,
12113 M16_OPC_LW = 0x13,
12114 M16_OPC_LBU = 0x14,
12115 M16_OPC_LHU = 0x15,
12116 M16_OPC_LWPC = 0x16,
12117 M16_OPC_LWU = 0x17,
12118 M16_OPC_SB = 0x18,
12119 M16_OPC_SH = 0x19,
12120 M16_OPC_SWSP = 0x1a,
12121 M16_OPC_SW = 0x1b,
12122 M16_OPC_RRR = 0x1c,
12123 M16_OPC_RR = 0x1d,
12124 M16_OPC_EXTEND = 0x1e,
12125 M16_OPC_I64 = 0x1f
12126};
12127
12128/* I8 funct field */
12129enum {
12130 I8_BTEQZ = 0x0,
12131 I8_BTNEZ = 0x1,
12132 I8_SWRASP = 0x2,
12133 I8_ADJSP = 0x3,
12134 I8_SVRS = 0x4,
12135 I8_MOV32R = 0x5,
12136 I8_MOVR32 = 0x7
12137};
12138
12139/* RRR f field */
12140enum {
12141 RRR_DADDU = 0x0,
12142 RRR_ADDU = 0x1,
12143 RRR_DSUBU = 0x2,
12144 RRR_SUBU = 0x3
12145};
12146
12147/* RR funct field */
12148enum {
12149 RR_JR = 0x00,
12150 RR_SDBBP = 0x01,
12151 RR_SLT = 0x02,
12152 RR_SLTU = 0x03,
12153 RR_SLLV = 0x04,
12154 RR_BREAK = 0x05,
12155 RR_SRLV = 0x06,
12156 RR_SRAV = 0x07,
12157 RR_DSRL = 0x08,
12158 RR_CMP = 0x0a,
12159 RR_NEG = 0x0b,
12160 RR_AND = 0x0c,
12161 RR_OR = 0x0d,
12162 RR_XOR = 0x0e,
12163 RR_NOT = 0x0f,
12164 RR_MFHI = 0x10,
12165 RR_CNVT = 0x11,
12166 RR_MFLO = 0x12,
12167 RR_DSRA = 0x13,
12168 RR_DSLLV = 0x14,
12169 RR_DSRLV = 0x16,
12170 RR_DSRAV = 0x17,
12171 RR_MULT = 0x18,
12172 RR_MULTU = 0x19,
12173 RR_DIV = 0x1a,
12174 RR_DIVU = 0x1b,
12175 RR_DMULT = 0x1c,
12176 RR_DMULTU = 0x1d,
12177 RR_DDIV = 0x1e,
12178 RR_DDIVU = 0x1f
12179};
12180
12181/* I64 funct field */
12182enum {
12183 I64_LDSP = 0x0,
12184 I64_SDSP = 0x1,
12185 I64_SDRASP = 0x2,
12186 I64_DADJSP = 0x3,
12187 I64_LDPC = 0x4,
364d4831 12188 I64_DADDIU5 = 0x5,
6ea219d0
NF
12189 I64_DADDIUPC = 0x6,
12190 I64_DADDIUSP = 0x7
12191};
12192
12193/* RR ry field for CNVT */
12194enum {
12195 RR_RY_CNVT_ZEB = 0x0,
12196 RR_RY_CNVT_ZEH = 0x1,
12197 RR_RY_CNVT_ZEW = 0x2,
12198 RR_RY_CNVT_SEB = 0x4,
12199 RR_RY_CNVT_SEH = 0x5,
12200 RR_RY_CNVT_SEW = 0x6,
12201};
12202
364d4831
NF
12203static int xlat (int r)
12204{
12205 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12206
12207 return map[r];
12208}
12209
12210static void gen_mips16_save (DisasContext *ctx,
12211 int xsregs, int aregs,
12212 int do_ra, int do_s0, int do_s1,
12213 int framesize)
12214{
12215 TCGv t0 = tcg_temp_new();
12216 TCGv t1 = tcg_temp_new();
c48245f0 12217 TCGv t2 = tcg_temp_new();
364d4831
NF
12218 int args, astatic;
12219
12220 switch (aregs) {
12221 case 0:
12222 case 1:
12223 case 2:
12224 case 3:
12225 case 11:
12226 args = 0;
12227 break;
12228 case 4:
12229 case 5:
12230 case 6:
12231 case 7:
12232 args = 1;
12233 break;
12234 case 8:
12235 case 9:
12236 case 10:
12237 args = 2;
12238 break;
12239 case 12:
12240 case 13:
12241 args = 3;
12242 break;
12243 case 14:
12244 args = 4;
12245 break;
12246 default:
9c708c7f 12247 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12248 return;
12249 }
12250
12251 switch (args) {
12252 case 4:
12253 gen_base_offset_addr(ctx, t0, 29, 12);
12254 gen_load_gpr(t1, 7);
5f68f5ae 12255 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12256 /* Fall through */
12257 case 3:
12258 gen_base_offset_addr(ctx, t0, 29, 8);
12259 gen_load_gpr(t1, 6);
5f68f5ae 12260 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12261 /* Fall through */
12262 case 2:
12263 gen_base_offset_addr(ctx, t0, 29, 4);
12264 gen_load_gpr(t1, 5);
5f68f5ae 12265 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12266 /* Fall through */
12267 case 1:
12268 gen_base_offset_addr(ctx, t0, 29, 0);
12269 gen_load_gpr(t1, 4);
5f68f5ae 12270 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12271 }
12272
12273 gen_load_gpr(t0, 29);
12274
5f68f5ae 12275#define DECR_AND_STORE(reg) do { \
c48245f0
MR
12276 tcg_gen_movi_tl(t2, -4); \
12277 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
12278 gen_load_gpr(t1, reg); \
12279 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
12280 } while (0)
12281
12282 if (do_ra) {
12283 DECR_AND_STORE(31);
12284 }
12285
12286 switch (xsregs) {
12287 case 7:
12288 DECR_AND_STORE(30);
12289 /* Fall through */
12290 case 6:
12291 DECR_AND_STORE(23);
12292 /* Fall through */
12293 case 5:
12294 DECR_AND_STORE(22);
12295 /* Fall through */
12296 case 4:
12297 DECR_AND_STORE(21);
12298 /* Fall through */
12299 case 3:
12300 DECR_AND_STORE(20);
12301 /* Fall through */
12302 case 2:
12303 DECR_AND_STORE(19);
12304 /* Fall through */
12305 case 1:
12306 DECR_AND_STORE(18);
12307 }
12308
12309 if (do_s1) {
12310 DECR_AND_STORE(17);
12311 }
12312 if (do_s0) {
12313 DECR_AND_STORE(16);
12314 }
12315
12316 switch (aregs) {
12317 case 0:
12318 case 4:
12319 case 8:
12320 case 12:
12321 case 14:
12322 astatic = 0;
12323 break;
12324 case 1:
12325 case 5:
12326 case 9:
12327 case 13:
12328 astatic = 1;
12329 break;
12330 case 2:
12331 case 6:
12332 case 10:
12333 astatic = 2;
12334 break;
12335 case 3:
12336 case 7:
12337 astatic = 3;
12338 break;
12339 case 11:
12340 astatic = 4;
12341 break;
12342 default:
9c708c7f 12343 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12344 return;
12345 }
12346
12347 if (astatic > 0) {
12348 DECR_AND_STORE(7);
12349 if (astatic > 1) {
12350 DECR_AND_STORE(6);
12351 if (astatic > 2) {
12352 DECR_AND_STORE(5);
12353 if (astatic > 3) {
12354 DECR_AND_STORE(4);
12355 }
12356 }
12357 }
12358 }
12359#undef DECR_AND_STORE
12360
c48245f0
MR
12361 tcg_gen_movi_tl(t2, -framesize);
12362 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
12363 tcg_temp_free(t0);
12364 tcg_temp_free(t1);
c48245f0 12365 tcg_temp_free(t2);
364d4831
NF
12366}
12367
12368static void gen_mips16_restore (DisasContext *ctx,
12369 int xsregs, int aregs,
12370 int do_ra, int do_s0, int do_s1,
12371 int framesize)
12372{
12373 int astatic;
12374 TCGv t0 = tcg_temp_new();
12375 TCGv t1 = tcg_temp_new();
c48245f0 12376 TCGv t2 = tcg_temp_new();
364d4831 12377
c48245f0
MR
12378 tcg_gen_movi_tl(t2, framesize);
12379 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 12380
5f68f5ae 12381#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
12382 tcg_gen_movi_tl(t2, -4); \
12383 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
12384 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12385 gen_store_gpr(t1, reg); \
364d4831
NF
12386 } while (0)
12387
12388 if (do_ra) {
12389 DECR_AND_LOAD(31);
12390 }
12391
12392 switch (xsregs) {
12393 case 7:
12394 DECR_AND_LOAD(30);
12395 /* Fall through */
12396 case 6:
12397 DECR_AND_LOAD(23);
12398 /* Fall through */
12399 case 5:
12400 DECR_AND_LOAD(22);
12401 /* Fall through */
12402 case 4:
12403 DECR_AND_LOAD(21);
12404 /* Fall through */
12405 case 3:
12406 DECR_AND_LOAD(20);
12407 /* Fall through */
12408 case 2:
12409 DECR_AND_LOAD(19);
12410 /* Fall through */
12411 case 1:
12412 DECR_AND_LOAD(18);
12413 }
12414
12415 if (do_s1) {
12416 DECR_AND_LOAD(17);
12417 }
12418 if (do_s0) {
12419 DECR_AND_LOAD(16);
12420 }
12421
12422 switch (aregs) {
12423 case 0:
12424 case 4:
12425 case 8:
12426 case 12:
12427 case 14:
12428 astatic = 0;
12429 break;
12430 case 1:
12431 case 5:
12432 case 9:
12433 case 13:
12434 astatic = 1;
12435 break;
12436 case 2:
12437 case 6:
12438 case 10:
12439 astatic = 2;
12440 break;
12441 case 3:
12442 case 7:
12443 astatic = 3;
12444 break;
12445 case 11:
12446 astatic = 4;
12447 break;
12448 default:
9c708c7f 12449 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12450 return;
12451 }
12452
12453 if (astatic > 0) {
12454 DECR_AND_LOAD(7);
12455 if (astatic > 1) {
12456 DECR_AND_LOAD(6);
12457 if (astatic > 2) {
12458 DECR_AND_LOAD(5);
12459 if (astatic > 3) {
12460 DECR_AND_LOAD(4);
12461 }
12462 }
12463 }
12464 }
12465#undef DECR_AND_LOAD
12466
c48245f0
MR
12467 tcg_gen_movi_tl(t2, framesize);
12468 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
12469 tcg_temp_free(t0);
12470 tcg_temp_free(t1);
c48245f0 12471 tcg_temp_free(t2);
364d4831
NF
12472}
12473
12474static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12475 int is_64_bit, int extended)
12476{
12477 TCGv t0;
12478
12479 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 12480 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12481 return;
12482 }
12483
12484 t0 = tcg_temp_new();
12485
12486 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12487 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12488 if (!is_64_bit) {
12489 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12490 }
12491
12492 tcg_temp_free(t0);
12493}
12494
0d74a222
LA
12495static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12496 int16_t offset)
12497{
12498 TCGv_i32 t0 = tcg_const_i32(op);
12499 TCGv t1 = tcg_temp_new();
12500 gen_base_offset_addr(ctx, t1, base, offset);
12501 gen_helper_cache(cpu_env, t1, t0);
12502}
12503
364d4831 12504#if defined(TARGET_MIPS64)
d75c135e 12505static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
12506 int ry, int funct, int16_t offset,
12507 int extended)
12508{
12509 switch (funct) {
12510 case I64_LDSP:
d9224450 12511 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12512 check_mips_64(ctx);
12513 offset = extended ? offset : offset << 3;
d75c135e 12514 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
12515 break;
12516 case I64_SDSP:
d9224450 12517 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12518 check_mips_64(ctx);
12519 offset = extended ? offset : offset << 3;
5c13fdfd 12520 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
12521 break;
12522 case I64_SDRASP:
d9224450 12523 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12524 check_mips_64(ctx);
12525 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 12526 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
12527 break;
12528 case I64_DADJSP:
d9224450 12529 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12530 check_mips_64(ctx);
12531 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 12532 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
12533 break;
12534 case I64_LDPC:
d9224450
MR
12535 check_insn(ctx, ISA_MIPS3);
12536 check_mips_64(ctx);
364d4831 12537 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 12538 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12539 } else {
12540 offset = extended ? offset : offset << 3;
d75c135e 12541 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
12542 }
12543 break;
12544 case I64_DADDIU5:
d9224450 12545 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12546 check_mips_64(ctx);
12547 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 12548 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
12549 break;
12550 case I64_DADDIUPC:
d9224450 12551 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12552 check_mips_64(ctx);
12553 offset = extended ? offset : offset << 2;
12554 gen_addiupc(ctx, ry, offset, 1, extended);
12555 break;
12556 case I64_DADDIUSP:
d9224450 12557 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12558 check_mips_64(ctx);
12559 offset = extended ? offset : offset << 2;
d75c135e 12560 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
12561 break;
12562 }
12563}
12564#endif
12565
240ce26a 12566static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 12567{
eeb3bba8 12568 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
12569 int op, rx, ry, funct, sa;
12570 int16_t imm, offset;
12571
12572 ctx->opcode = (ctx->opcode << 16) | extend;
12573 op = (ctx->opcode >> 11) & 0x1f;
12574 sa = (ctx->opcode >> 22) & 0x1f;
12575 funct = (ctx->opcode >> 8) & 0x7;
12576 rx = xlat((ctx->opcode >> 8) & 0x7);
12577 ry = xlat((ctx->opcode >> 5) & 0x7);
12578 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12579 | ((ctx->opcode >> 21) & 0x3f) << 5
12580 | (ctx->opcode & 0x1f));
12581
12582 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12583 counterparts. */
12584 switch (op) {
12585 case M16_OPC_ADDIUSP:
d75c135e 12586 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
12587 break;
12588 case M16_OPC_ADDIUPC:
12589 gen_addiupc(ctx, rx, imm, 0, 1);
12590 break;
12591 case M16_OPC_B:
b231c103 12592 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
12593 /* No delay slot, so just process as a normal instruction */
12594 break;
12595 case M16_OPC_BEQZ:
b231c103 12596 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
12597 /* No delay slot, so just process as a normal instruction */
12598 break;
12599 case M16_OPC_BNEQZ:
b231c103 12600 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
12601 /* No delay slot, so just process as a normal instruction */
12602 break;
12603 case M16_OPC_SHIFT:
12604 switch (ctx->opcode & 0x3) {
12605 case 0x0:
d75c135e 12606 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
12607 break;
12608 case 0x1:
12609#if defined(TARGET_MIPS64)
12610 check_mips_64(ctx);
d75c135e 12611 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 12612#else
9c708c7f 12613 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12614#endif
12615 break;
12616 case 0x2:
d75c135e 12617 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
12618 break;
12619 case 0x3:
d75c135e 12620 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
12621 break;
12622 }
12623 break;
12624#if defined(TARGET_MIPS64)
12625 case M16_OPC_LD:
d9224450 12626 check_insn(ctx, ISA_MIPS3);
d75de749 12627 check_mips_64(ctx);
d75c135e 12628 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
12629 break;
12630#endif
12631 case M16_OPC_RRIA:
12632 imm = ctx->opcode & 0xf;
12633 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12634 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12635 imm = (int16_t) (imm << 1) >> 1;
12636 if ((ctx->opcode >> 4) & 0x1) {
12637#if defined(TARGET_MIPS64)
12638 check_mips_64(ctx);
d75c135e 12639 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 12640#else
9c708c7f 12641 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12642#endif
12643 } else {
d75c135e 12644 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12645 }
12646 break;
12647 case M16_OPC_ADDIU8:
d75c135e 12648 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12649 break;
12650 case M16_OPC_SLTI:
d75c135e 12651 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12652 break;
12653 case M16_OPC_SLTIU:
d75c135e 12654 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12655 break;
12656 case M16_OPC_I8:
12657 switch (funct) {
12658 case I8_BTEQZ:
b231c103 12659 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
12660 break;
12661 case I8_BTNEZ:
b231c103 12662 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
12663 break;
12664 case I8_SWRASP:
5c13fdfd 12665 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
12666 break;
12667 case I8_ADJSP:
d75c135e 12668 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
12669 break;
12670 case I8_SVRS:
d9224450 12671 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12672 {
12673 int xsregs = (ctx->opcode >> 24) & 0x7;
12674 int aregs = (ctx->opcode >> 16) & 0xf;
12675 int do_ra = (ctx->opcode >> 6) & 0x1;
12676 int do_s0 = (ctx->opcode >> 5) & 0x1;
12677 int do_s1 = (ctx->opcode >> 4) & 0x1;
12678 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12679 | (ctx->opcode & 0xf)) << 3;
12680
12681 if (ctx->opcode & (1 << 7)) {
12682 gen_mips16_save(ctx, xsregs, aregs,
12683 do_ra, do_s0, do_s1,
12684 framesize);
12685 } else {
12686 gen_mips16_restore(ctx, xsregs, aregs,
12687 do_ra, do_s0, do_s1,
12688 framesize);
12689 }
12690 }
12691 break;
12692 default:
9c708c7f 12693 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12694 break;
12695 }
12696 break;
12697 case M16_OPC_LI:
12698 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12699 break;
12700 case M16_OPC_CMPI:
12701 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12702 break;
12703#if defined(TARGET_MIPS64)
12704 case M16_OPC_SD:
d9224450
MR
12705 check_insn(ctx, ISA_MIPS3);
12706 check_mips_64(ctx);
5c13fdfd 12707 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
12708 break;
12709#endif
12710 case M16_OPC_LB:
d75c135e 12711 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12712 break;
12713 case M16_OPC_LH:
d75c135e 12714 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
12715 break;
12716 case M16_OPC_LWSP:
d75c135e 12717 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
12718 break;
12719 case M16_OPC_LW:
d75c135e 12720 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
12721 break;
12722 case M16_OPC_LBU:
d75c135e 12723 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12724 break;
12725 case M16_OPC_LHU:
d75c135e 12726 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
12727 break;
12728 case M16_OPC_LWPC:
d75c135e 12729 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
12730 break;
12731#if defined(TARGET_MIPS64)
12732 case M16_OPC_LWU:
d9224450
MR
12733 check_insn(ctx, ISA_MIPS3);
12734 check_mips_64(ctx);
d75c135e 12735 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
12736 break;
12737#endif
12738 case M16_OPC_SB:
5c13fdfd 12739 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12740 break;
12741 case M16_OPC_SH:
5c13fdfd 12742 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
12743 break;
12744 case M16_OPC_SWSP:
5c13fdfd 12745 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
12746 break;
12747 case M16_OPC_SW:
5c13fdfd 12748 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
12749 break;
12750#if defined(TARGET_MIPS64)
12751 case M16_OPC_I64:
d75c135e 12752 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
12753 break;
12754#endif
12755 default:
9c708c7f 12756 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12757 break;
12758 }
12759
12760 return 4;
12761}
12762
3b3c1694
LA
12763static inline bool is_uhi(int sdbbp_code)
12764{
12765#ifdef CONFIG_USER_ONLY
12766 return false;
12767#else
12768 return semihosting_enabled() && sdbbp_code == 1;
12769#endif
12770}
12771
240ce26a 12772static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
12773{
12774 int rx, ry;
12775 int sa;
12776 int op, cnvt_op, op1, offset;
12777 int funct;
12778 int n_bytes;
12779
12780 op = (ctx->opcode >> 11) & 0x1f;
12781 sa = (ctx->opcode >> 2) & 0x7;
12782 sa = sa == 0 ? 8 : sa;
12783 rx = xlat((ctx->opcode >> 8) & 0x7);
12784 cnvt_op = (ctx->opcode >> 5) & 0x7;
12785 ry = xlat((ctx->opcode >> 5) & 0x7);
12786 op1 = offset = ctx->opcode & 0x1f;
12787
12788 n_bytes = 2;
12789
12790 switch (op) {
12791 case M16_OPC_ADDIUSP:
12792 {
12793 int16_t imm = ((uint8_t) ctx->opcode) << 2;
12794
d75c135e 12795 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
12796 }
12797 break;
12798 case M16_OPC_ADDIUPC:
12799 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12800 break;
12801 case M16_OPC_B:
12802 offset = (ctx->opcode & 0x7ff) << 1;
12803 offset = (int16_t)(offset << 4) >> 4;
b231c103 12804 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
12805 /* No delay slot, so just process as a normal instruction */
12806 break;
12807 case M16_OPC_JAL:
eeb3bba8 12808 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
12809 offset = (((ctx->opcode & 0x1f) << 21)
12810 | ((ctx->opcode >> 5) & 0x1f) << 16
12811 | offset) << 2;
b231c103
YK
12812 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12813 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 12814 n_bytes = 4;
364d4831
NF
12815 break;
12816 case M16_OPC_BEQZ:
b231c103
YK
12817 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12818 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12819 /* No delay slot, so just process as a normal instruction */
12820 break;
12821 case M16_OPC_BNEQZ:
b231c103
YK
12822 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12823 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12824 /* No delay slot, so just process as a normal instruction */
12825 break;
12826 case M16_OPC_SHIFT:
12827 switch (ctx->opcode & 0x3) {
12828 case 0x0:
d75c135e 12829 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
12830 break;
12831 case 0x1:
12832#if defined(TARGET_MIPS64)
d9224450 12833 check_insn(ctx, ISA_MIPS3);
364d4831 12834 check_mips_64(ctx);
d75c135e 12835 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 12836#else
9c708c7f 12837 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12838#endif
12839 break;
12840 case 0x2:
d75c135e 12841 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
12842 break;
12843 case 0x3:
d75c135e 12844 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
12845 break;
12846 }
12847 break;
12848#if defined(TARGET_MIPS64)
12849 case M16_OPC_LD:
d9224450 12850 check_insn(ctx, ISA_MIPS3);
364d4831 12851 check_mips_64(ctx);
d75c135e 12852 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
12853 break;
12854#endif
12855 case M16_OPC_RRIA:
12856 {
12857 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12858
12859 if ((ctx->opcode >> 4) & 1) {
12860#if defined(TARGET_MIPS64)
d9224450 12861 check_insn(ctx, ISA_MIPS3);
364d4831 12862 check_mips_64(ctx);
d75c135e 12863 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 12864#else
9c708c7f 12865 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12866#endif
12867 } else {
d75c135e 12868 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12869 }
12870 }
12871 break;
12872 case M16_OPC_ADDIU8:
12873 {
12874 int16_t imm = (int8_t) ctx->opcode;
12875
d75c135e 12876 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12877 }
12878 break;
12879 case M16_OPC_SLTI:
12880 {
12881 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12882 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12883 }
12884 break;
12885 case M16_OPC_SLTIU:
12886 {
12887 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12888 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12889 }
12890 break;
12891 case M16_OPC_I8:
12892 {
12893 int reg32;
12894
12895 funct = (ctx->opcode >> 8) & 0x7;
12896 switch (funct) {
12897 case I8_BTEQZ:
12898 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12899 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12900 break;
12901 case I8_BTNEZ:
12902 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12903 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12904 break;
12905 case I8_SWRASP:
5c13fdfd 12906 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12907 break;
12908 case I8_ADJSP:
d75c135e 12909 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12910 ((int8_t)ctx->opcode) << 3);
12911 break;
12912 case I8_SVRS:
d9224450 12913 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12914 {
12915 int do_ra = ctx->opcode & (1 << 6);
12916 int do_s0 = ctx->opcode & (1 << 5);
12917 int do_s1 = ctx->opcode & (1 << 4);
12918 int framesize = ctx->opcode & 0xf;
12919
12920 if (framesize == 0) {
12921 framesize = 128;
12922 } else {
12923 framesize = framesize << 3;
12924 }
12925
12926 if (ctx->opcode & (1 << 7)) {
12927 gen_mips16_save(ctx, 0, 0,
12928 do_ra, do_s0, do_s1, framesize);
12929 } else {
12930 gen_mips16_restore(ctx, 0, 0,
12931 do_ra, do_s0, do_s1, framesize);
12932 }
12933 }
12934 break;
12935 case I8_MOV32R:
12936 {
12937 int rz = xlat(ctx->opcode & 0x7);
12938
12939 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12940 ((ctx->opcode >> 5) & 0x7);
d75c135e 12941 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12942 }
12943 break;
12944 case I8_MOVR32:
12945 reg32 = ctx->opcode & 0x1f;
d75c135e 12946 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12947 break;
12948 default:
9c708c7f 12949 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12950 break;
12951 }
12952 }
12953 break;
12954 case M16_OPC_LI:
12955 {
12956 int16_t imm = (uint8_t) ctx->opcode;
12957
d75c135e 12958 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12959 }
12960 break;
12961 case M16_OPC_CMPI:
12962 {
12963 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12964 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12965 }
12966 break;
12967#if defined(TARGET_MIPS64)
12968 case M16_OPC_SD:
d9224450 12969 check_insn(ctx, ISA_MIPS3);
364d4831 12970 check_mips_64(ctx);
5c13fdfd 12971 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12972 break;
12973#endif
12974 case M16_OPC_LB:
d75c135e 12975 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12976 break;
12977 case M16_OPC_LH:
d75c135e 12978 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12979 break;
12980 case M16_OPC_LWSP:
d75c135e 12981 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12982 break;
12983 case M16_OPC_LW:
d75c135e 12984 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12985 break;
12986 case M16_OPC_LBU:
d75c135e 12987 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12988 break;
12989 case M16_OPC_LHU:
d75c135e 12990 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12991 break;
12992 case M16_OPC_LWPC:
d75c135e 12993 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12994 break;
12995#if defined (TARGET_MIPS64)
12996 case M16_OPC_LWU:
d9224450 12997 check_insn(ctx, ISA_MIPS3);
364d4831 12998 check_mips_64(ctx);
d75c135e 12999 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
13000 break;
13001#endif
13002 case M16_OPC_SB:
5c13fdfd 13003 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13004 break;
13005 case M16_OPC_SH:
5c13fdfd 13006 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
13007 break;
13008 case M16_OPC_SWSP:
5c13fdfd 13009 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13010 break;
13011 case M16_OPC_SW:
5c13fdfd 13012 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
13013 break;
13014 case M16_OPC_RRR:
13015 {
13016 int rz = xlat((ctx->opcode >> 2) & 0x7);
13017 int mips32_op;
13018
13019 switch (ctx->opcode & 0x3) {
13020 case RRR_ADDU:
13021 mips32_op = OPC_ADDU;
13022 break;
13023 case RRR_SUBU:
13024 mips32_op = OPC_SUBU;
13025 break;
13026#if defined(TARGET_MIPS64)
13027 case RRR_DADDU:
13028 mips32_op = OPC_DADDU;
d9224450 13029 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13030 check_mips_64(ctx);
13031 break;
13032 case RRR_DSUBU:
13033 mips32_op = OPC_DSUBU;
d9224450 13034 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13035 check_mips_64(ctx);
13036 break;
13037#endif
13038 default:
9c708c7f 13039 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13040 goto done;
13041 }
13042
d75c135e 13043 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
13044 done:
13045 ;
13046 }
13047 break;
13048 case M16_OPC_RR:
13049 switch (op1) {
13050 case RR_JR:
13051 {
13052 int nd = (ctx->opcode >> 7) & 0x1;
13053 int link = (ctx->opcode >> 6) & 0x1;
13054 int ra = (ctx->opcode >> 5) & 0x1;
13055
d9224450
MR
13056 if (nd) {
13057 check_insn(ctx, ISA_MIPS32);
13058 }
13059
364d4831 13060 if (link) {
b231c103 13061 op = OPC_JALR;
364d4831
NF
13062 } else {
13063 op = OPC_JR;
13064 }
13065
b231c103
YK
13066 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13067 (nd ? 0 : 2));
364d4831
NF
13068 }
13069 break;
13070 case RR_SDBBP:
3b3c1694
LA
13071 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13072 gen_helper_do_semihosting(cpu_env);
13073 } else {
13074 /* XXX: not clear which exception should be raised
13075 * when in debug mode...
13076 */
13077 check_insn(ctx, ISA_MIPS32);
9c708c7f 13078 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13079 }
364d4831
NF
13080 break;
13081 case RR_SLT:
d75c135e 13082 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
13083 break;
13084 case RR_SLTU:
d75c135e 13085 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
13086 break;
13087 case RR_BREAK:
9c708c7f 13088 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
13089 break;
13090 case RR_SLLV:
d75c135e 13091 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
13092 break;
13093 case RR_SRLV:
d75c135e 13094 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
13095 break;
13096 case RR_SRAV:
d75c135e 13097 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
13098 break;
13099#if defined (TARGET_MIPS64)
13100 case RR_DSRL:
d9224450 13101 check_insn(ctx, ISA_MIPS3);
364d4831 13102 check_mips_64(ctx);
d75c135e 13103 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
13104 break;
13105#endif
13106 case RR_CMP:
d75c135e 13107 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
13108 break;
13109 case RR_NEG:
d75c135e 13110 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
13111 break;
13112 case RR_AND:
d75c135e 13113 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
13114 break;
13115 case RR_OR:
d75c135e 13116 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
13117 break;
13118 case RR_XOR:
d75c135e 13119 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
13120 break;
13121 case RR_NOT:
d75c135e 13122 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
13123 break;
13124 case RR_MFHI:
26135ead 13125 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
13126 break;
13127 case RR_CNVT:
d9224450 13128 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13129 switch (cnvt_op) {
13130 case RR_RY_CNVT_ZEB:
13131 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13132 break;
13133 case RR_RY_CNVT_ZEH:
13134 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13135 break;
13136 case RR_RY_CNVT_SEB:
13137 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13138 break;
13139 case RR_RY_CNVT_SEH:
13140 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13141 break;
13142#if defined (TARGET_MIPS64)
13143 case RR_RY_CNVT_ZEW:
d9224450 13144 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13145 check_mips_64(ctx);
13146 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13147 break;
13148 case RR_RY_CNVT_SEW:
d9224450 13149 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13150 check_mips_64(ctx);
13151 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13152 break;
13153#endif
13154 default:
9c708c7f 13155 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13156 break;
13157 }
13158 break;
13159 case RR_MFLO:
26135ead 13160 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
13161 break;
13162#if defined (TARGET_MIPS64)
13163 case RR_DSRA:
d9224450 13164 check_insn(ctx, ISA_MIPS3);
364d4831 13165 check_mips_64(ctx);
d75c135e 13166 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
13167 break;
13168 case RR_DSLLV:
d9224450 13169 check_insn(ctx, ISA_MIPS3);
364d4831 13170 check_mips_64(ctx);
d75c135e 13171 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
13172 break;
13173 case RR_DSRLV:
d9224450 13174 check_insn(ctx, ISA_MIPS3);
364d4831 13175 check_mips_64(ctx);
d75c135e 13176 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
13177 break;
13178 case RR_DSRAV:
d9224450 13179 check_insn(ctx, ISA_MIPS3);
364d4831 13180 check_mips_64(ctx);
d75c135e 13181 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
13182 break;
13183#endif
13184 case RR_MULT:
26135ead 13185 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
13186 break;
13187 case RR_MULTU:
26135ead 13188 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
13189 break;
13190 case RR_DIV:
26135ead 13191 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
13192 break;
13193 case RR_DIVU:
26135ead 13194 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
13195 break;
13196#if defined (TARGET_MIPS64)
13197 case RR_DMULT:
d9224450 13198 check_insn(ctx, ISA_MIPS3);
364d4831 13199 check_mips_64(ctx);
26135ead 13200 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
13201 break;
13202 case RR_DMULTU:
d9224450 13203 check_insn(ctx, ISA_MIPS3);
364d4831 13204 check_mips_64(ctx);
26135ead 13205 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
13206 break;
13207 case RR_DDIV:
d9224450 13208 check_insn(ctx, ISA_MIPS3);
364d4831 13209 check_mips_64(ctx);
26135ead 13210 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
13211 break;
13212 case RR_DDIVU:
d9224450 13213 check_insn(ctx, ISA_MIPS3);
364d4831 13214 check_mips_64(ctx);
26135ead 13215 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
13216 break;
13217#endif
13218 default:
9c708c7f 13219 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13220 break;
13221 }
13222 break;
13223 case M16_OPC_EXTEND:
240ce26a 13224 decode_extended_mips16_opc(env, ctx);
364d4831
NF
13225 n_bytes = 4;
13226 break;
13227#if defined(TARGET_MIPS64)
13228 case M16_OPC_I64:
13229 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 13230 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
13231 break;
13232#endif
13233 default:
9c708c7f 13234 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13235 break;
13236 }
13237
13238 return n_bytes;
13239}
13240
211da992 13241/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 13242
211da992
CWR
13243/*
13244 * microMIPS32/microMIPS64 major opcodes
13245 *
13246 * 1. MIPS Architecture for Programmers Volume II-B:
13247 * The microMIPS32 Instruction Set (Revision 3.05)
13248 *
13249 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13250 *
13251 * 2. MIPS Architecture For Programmers Volume II-A:
13252 * The MIPS64 Instruction Set (Revision 3.51)
13253 */
6af0bf9c 13254
3c824109
NF
13255enum {
13256 POOL32A = 0x00,
13257 POOL16A = 0x01,
13258 LBU16 = 0x02,
13259 MOVE16 = 0x03,
13260 ADDI32 = 0x04,
3a1f4268
YK
13261 R6_LUI = 0x04,
13262 AUI = 0x04,
3c824109
NF
13263 LBU32 = 0x05,
13264 SB32 = 0x06,
13265 LB32 = 0x07,
13266
13267 POOL32B = 0x08,
13268 POOL16B = 0x09,
13269 LHU16 = 0x0a,
13270 ANDI16 = 0x0b,
13271 ADDIU32 = 0x0c,
13272 LHU32 = 0x0d,
13273 SH32 = 0x0e,
13274 LH32 = 0x0f,
13275
13276 POOL32I = 0x10,
13277 POOL16C = 0x11,
13278 LWSP16 = 0x12,
13279 POOL16D = 0x13,
13280 ORI32 = 0x14,
13281 POOL32F = 0x15,
211da992
CWR
13282 POOL32S = 0x16, /* MIPS64 */
13283 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
13284
13285 POOL32C = 0x18,
13286 LWGP16 = 0x19,
13287 LW16 = 0x1a,
13288 POOL16E = 0x1b,
13289 XORI32 = 0x1c,
13290 JALS32 = 0x1d,
3a1f4268
YK
13291 BOVC = 0x1d,
13292 BEQC = 0x1d,
13293 BEQZALC = 0x1d,
3c824109 13294 ADDIUPC = 0x1e,
3a1f4268
YK
13295 PCREL = 0x1e,
13296 BNVC = 0x1f,
13297 BNEC = 0x1f,
13298 BNEZALC = 0x1f,
3c824109 13299
3a1f4268
YK
13300 R6_BEQZC = 0x20,
13301 JIC = 0x20,
3c824109
NF
13302 POOL16F = 0x21,
13303 SB16 = 0x22,
13304 BEQZ16 = 0x23,
3a1f4268 13305 BEQZC16 = 0x23,
3c824109
NF
13306 SLTI32 = 0x24,
13307 BEQ32 = 0x25,
3a1f4268 13308 BC = 0x25,
3c824109
NF
13309 SWC132 = 0x26,
13310 LWC132 = 0x27,
13311
3a1f4268 13312 /* 0x29 is reserved */
3c824109 13313 RES_29 = 0x29,
3a1f4268
YK
13314 R6_BNEZC = 0x28,
13315 JIALC = 0x28,
3c824109
NF
13316 SH16 = 0x2a,
13317 BNEZ16 = 0x2b,
3a1f4268 13318 BNEZC16 = 0x2b,
3c824109
NF
13319 SLTIU32 = 0x2c,
13320 BNE32 = 0x2d,
3a1f4268 13321 BALC = 0x2d,
3c824109
NF
13322 SDC132 = 0x2e,
13323 LDC132 = 0x2f,
13324
3a1f4268 13325 /* 0x31 is reserved */
3c824109 13326 RES_31 = 0x31,
3a1f4268
YK
13327 BLEZALC = 0x30,
13328 BGEZALC = 0x30,
13329 BGEUC = 0x30,
3c824109
NF
13330 SWSP16 = 0x32,
13331 B16 = 0x33,
3a1f4268 13332 BC16 = 0x33,
3c824109
NF
13333 ANDI32 = 0x34,
13334 J32 = 0x35,
3a1f4268
YK
13335 BGTZC = 0x35,
13336 BLTZC = 0x35,
13337 BLTC = 0x35,
211da992
CWR
13338 SD32 = 0x36, /* MIPS64 */
13339 LD32 = 0x37, /* MIPS64 */
3c824109 13340
3a1f4268 13341 /* 0x39 is reserved */
3c824109 13342 RES_39 = 0x39,
3a1f4268
YK
13343 BGTZALC = 0x38,
13344 BLTZALC = 0x38,
13345 BLTUC = 0x38,
3c824109
NF
13346 SW16 = 0x3a,
13347 LI16 = 0x3b,
13348 JALX32 = 0x3c,
13349 JAL32 = 0x3d,
3a1f4268
YK
13350 BLEZC = 0x3d,
13351 BGEZC = 0x3d,
13352 BGEC = 0x3d,
3c824109
NF
13353 SW32 = 0x3e,
13354 LW32 = 0x3f
13355};
13356
3a1f4268
YK
13357/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13358enum {
13359 ADDIUPC_00 = 0x00,
c38a1d52
AR
13360 ADDIUPC_01 = 0x01,
13361 ADDIUPC_02 = 0x02,
13362 ADDIUPC_03 = 0x03,
13363 ADDIUPC_04 = 0x04,
13364 ADDIUPC_05 = 0x05,
13365 ADDIUPC_06 = 0x06,
3a1f4268
YK
13366 ADDIUPC_07 = 0x07,
13367 AUIPC = 0x1e,
13368 ALUIPC = 0x1f,
13369 LWPC_08 = 0x08,
c38a1d52
AR
13370 LWPC_09 = 0x09,
13371 LWPC_0A = 0x0A,
13372 LWPC_0B = 0x0B,
13373 LWPC_0C = 0x0C,
13374 LWPC_0D = 0x0D,
13375 LWPC_0E = 0x0E,
3a1f4268
YK
13376 LWPC_0F = 0x0F,
13377};
13378
3c824109
NF
13379/* POOL32A encoding of minor opcode field */
13380
13381enum {
13382 /* These opcodes are distinguished only by bits 9..6; those bits are
13383 * what are recorded below. */
13384 SLL32 = 0x0,
13385 SRL32 = 0x1,
13386 SRA = 0x2,
13387 ROTR = 0x3,
3a1f4268
YK
13388 SELEQZ = 0x5,
13389 SELNEZ = 0x6,
b00c7218 13390 R6_RDHWR = 0x7,
3c824109
NF
13391
13392 SLLV = 0x0,
13393 SRLV = 0x1,
13394 SRAV = 0x2,
13395 ROTRV = 0x3,
13396 ADD = 0x4,
13397 ADDU32 = 0x5,
13398 SUB = 0x6,
13399 SUBU32 = 0x7,
13400 MUL = 0x8,
13401 AND = 0x9,
13402 OR32 = 0xa,
13403 NOR = 0xb,
13404 XOR32 = 0xc,
13405 SLT = 0xd,
13406 SLTU = 0xe,
13407
13408 MOVN = 0x0,
3a1f4268 13409 R6_MUL = 0x0,
3c824109 13410 MOVZ = 0x1,
3a1f4268
YK
13411 MUH = 0x1,
13412 MULU = 0x2,
13413 MUHU = 0x3,
3c824109 13414 LWXS = 0x4,
3a1f4268
YK
13415 R6_DIV = 0x4,
13416 MOD = 0x5,
13417 R6_DIVU = 0x6,
13418 MODU = 0x7,
3c824109
NF
13419
13420 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 13421 BREAK32 = 0x07,
3c824109 13422 INS = 0x0c,
3a1f4268
YK
13423 LSA = 0x0f,
13424 ALIGN = 0x1f,
3c824109 13425 EXT = 0x2c,
bb238210
YK
13426 POOL32AXF = 0x3c,
13427 SIGRIE = 0x3f
3c824109
NF
13428};
13429
13430/* POOL32AXF encoding of minor opcode field extension */
13431
d132c79f
CWR
13432/*
13433 * 1. MIPS Architecture for Programmers Volume II-B:
13434 * The microMIPS32 Instruction Set (Revision 3.05)
13435 *
13436 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13437 *
13438 * 2. MIPS Architecture for Programmers VolumeIV-e:
13439 * The MIPS DSP Application-Specific Extension
13440 * to the microMIPS32 Architecture (Revision 2.34)
13441 *
13442 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13443 */
13444
3c824109
NF
13445enum {
13446 /* bits 11..6 */
13447 TEQ = 0x00,
13448 TGE = 0x08,
13449 TGEU = 0x10,
13450 TLT = 0x20,
13451 TLTU = 0x28,
13452 TNE = 0x30,
13453
13454 MFC0 = 0x03,
13455 MTC0 = 0x0b,
13456
d132c79f
CWR
13457 /* begin of microMIPS32 DSP */
13458
3c824109
NF
13459 /* bits 13..12 for 0x01 */
13460 MFHI_ACC = 0x0,
13461 MFLO_ACC = 0x1,
13462 MTHI_ACC = 0x2,
13463 MTLO_ACC = 0x3,
13464
13465 /* bits 13..12 for 0x2a */
13466 MADD_ACC = 0x0,
13467 MADDU_ACC = 0x1,
13468 MSUB_ACC = 0x2,
13469 MSUBU_ACC = 0x3,
13470
13471 /* bits 13..12 for 0x32 */
13472 MULT_ACC = 0x0,
6801038b 13473 MULTU_ACC = 0x1,
3c824109 13474
d132c79f
CWR
13475 /* end of microMIPS32 DSP */
13476
3c824109 13477 /* bits 15..12 for 0x2c */
3a1f4268 13478 BITSWAP = 0x0,
3c824109
NF
13479 SEB = 0x2,
13480 SEH = 0x3,
13481 CLO = 0x4,
13482 CLZ = 0x5,
13483 RDHWR = 0x6,
13484 WSBH = 0x7,
13485 MULT = 0x8,
13486 MULTU = 0x9,
13487 DIV = 0xa,
13488 DIVU = 0xb,
13489 MADD = 0xc,
13490 MADDU = 0xd,
13491 MSUB = 0xe,
13492 MSUBU = 0xf,
13493
13494 /* bits 15..12 for 0x34 */
13495 MFC2 = 0x4,
13496 MTC2 = 0x5,
13497 MFHC2 = 0x8,
13498 MTHC2 = 0x9,
13499 CFC2 = 0xc,
13500 CTC2 = 0xd,
13501
13502 /* bits 15..12 for 0x3c */
13503 JALR = 0x0,
13504 JR = 0x0, /* alias */
3a1f4268
YK
13505 JALRC = 0x0,
13506 JRC = 0x0,
3c824109 13507 JALR_HB = 0x1,
3a1f4268 13508 JALRC_HB = 0x1,
3c824109
NF
13509 JALRS = 0x4,
13510 JALRS_HB = 0x5,
13511
13512 /* bits 15..12 for 0x05 */
13513 RDPGPR = 0xe,
13514 WRPGPR = 0xf,
13515
13516 /* bits 15..12 for 0x0d */
13517 TLBP = 0x0,
13518 TLBR = 0x1,
13519 TLBWI = 0x2,
13520 TLBWR = 0x3,
e60ec063
YK
13521 TLBINV = 0x4,
13522 TLBINVF = 0x5,
3c824109
NF
13523 WAIT = 0x9,
13524 IRET = 0xd,
13525 DERET = 0xe,
13526 ERET = 0xf,
13527
13528 /* bits 15..12 for 0x15 */
13529 DMT = 0x0,
13530 DVPE = 0x1,
13531 EMT = 0x2,
13532 EVPE = 0x3,
13533
13534 /* bits 15..12 for 0x1d */
13535 DI = 0x4,
13536 EI = 0x5,
13537
13538 /* bits 15..12 for 0x2d */
13539 SYNC = 0x6,
13540 SYSCALL = 0x8,
13541 SDBBP = 0xd,
13542
13543 /* bits 15..12 for 0x35 */
13544 MFHI32 = 0x0,
13545 MFLO32 = 0x1,
13546 MTHI32 = 0x2,
13547 MTLO32 = 0x3,
13548};
13549
13550/* POOL32B encoding of minor opcode field (bits 15..12) */
13551
13552enum {
13553 LWC2 = 0x0,
13554 LWP = 0x1,
13555 LDP = 0x4,
13556 LWM32 = 0x5,
13557 CACHE = 0x6,
13558 LDM = 0x7,
13559 SWC2 = 0x8,
13560 SWP = 0x9,
13561 SDP = 0xc,
13562 SWM32 = 0xd,
13563 SDM = 0xf
13564};
13565
13566/* POOL32C encoding of minor opcode field (bits 15..12) */
13567
13568enum {
13569 LWL = 0x0,
13570 SWL = 0x8,
13571 LWR = 0x1,
13572 SWR = 0x9,
13573 PREF = 0x2,
8fffc646 13574 ST_EVA = 0xa,
3c824109
NF
13575 LL = 0x3,
13576 SC = 0xb,
13577 LDL = 0x4,
13578 SDL = 0xc,
13579 LDR = 0x5,
13580 SDR = 0xd,
8fffc646 13581 LD_EVA = 0x6,
3c824109
NF
13582 LWU = 0xe,
13583 LLD = 0x7,
13584 SCD = 0xf
13585};
13586
8fffc646
JH
13587/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13588
13589enum {
13590 LBUE = 0x0,
13591 LHUE = 0x1,
13592 LWLE = 0x2,
13593 LWRE = 0x3,
13594 LBE = 0x4,
13595 LHE = 0x5,
13596 LLE = 0x6,
13597 LWE = 0x7,
13598};
13599
13600/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13601
13602enum {
13603 SWLE = 0x0,
13604 SWRE = 0x1,
13605 PREFE = 0x2,
13606 CACHEE = 0x3,
13607 SBE = 0x4,
13608 SHE = 0x5,
13609 SCE = 0x6,
13610 SWE = 0x7,
13611};
13612
3c824109
NF
13613/* POOL32F encoding of minor opcode field (bits 5..0) */
13614
13615enum {
13616 /* These are the bit 7..6 values */
13617 ADD_FMT = 0x0,
3c824109
NF
13618
13619 SUB_FMT = 0x1,
3c824109
NF
13620
13621 MUL_FMT = 0x2,
13622
13623 DIV_FMT = 0x3,
13624
13625 /* These are the bit 8..6 values */
3a1f4268 13626 MOVN_FMT = 0x0,
3c824109
NF
13627 RSQRT2_FMT = 0x0,
13628 MOVF_FMT = 0x0,
3a1f4268
YK
13629 RINT_FMT = 0x0,
13630 SELNEZ_FMT = 0x0,
3c824109 13631
3a1f4268 13632 MOVZ_FMT = 0x1,
3c824109
NF
13633 LWXC1 = 0x1,
13634 MOVT_FMT = 0x1,
3a1f4268
YK
13635 CLASS_FMT = 0x1,
13636 SELEQZ_FMT = 0x1,
3c824109
NF
13637
13638 PLL_PS = 0x2,
13639 SWXC1 = 0x2,
3a1f4268 13640 SEL_FMT = 0x2,
3c824109
NF
13641
13642 PLU_PS = 0x3,
13643 LDXC1 = 0x3,
13644
3a1f4268 13645 MOVN_FMT_04 = 0x4,
3c824109
NF
13646 PUL_PS = 0x4,
13647 SDXC1 = 0x4,
13648 RECIP2_FMT = 0x4,
13649
3a1f4268 13650 MOVZ_FMT_05 = 0x05,
3c824109
NF
13651 PUU_PS = 0x5,
13652 LUXC1 = 0x5,
13653
13654 CVT_PS_S = 0x6,
13655 SUXC1 = 0x6,
13656 ADDR_PS = 0x6,
13657 PREFX = 0x6,
3a1f4268 13658 MADDF_FMT = 0x6,
3c824109
NF
13659
13660 MULR_PS = 0x7,
3a1f4268 13661 MSUBF_FMT = 0x7,
3c824109
NF
13662
13663 MADD_S = 0x01,
13664 MADD_D = 0x09,
13665 MADD_PS = 0x11,
13666 ALNV_PS = 0x19,
13667 MSUB_S = 0x21,
13668 MSUB_D = 0x29,
13669 MSUB_PS = 0x31,
13670
13671 NMADD_S = 0x02,
13672 NMADD_D = 0x0a,
13673 NMADD_PS = 0x12,
13674 NMSUB_S = 0x22,
13675 NMSUB_D = 0x2a,
13676 NMSUB_PS = 0x32,
13677
3a1f4268
YK
13678 MIN_FMT = 0x3,
13679 MAX_FMT = 0xb,
13680 MINA_FMT = 0x23,
13681 MAXA_FMT = 0x2b,
3c824109
NF
13682 POOL32FXF = 0x3b,
13683
13684 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
13685 C_COND_FMT = 0x3c,
13686
13687 CMP_CONDN_S = 0x5,
13688 CMP_CONDN_D = 0x15
3c824109
NF
13689};
13690
13691/* POOL32Fxf encoding of minor opcode extension field */
13692
13693enum {
13694 CVT_L = 0x04,
13695 RSQRT_FMT = 0x08,
13696 FLOOR_L = 0x0c,
13697 CVT_PW_PS = 0x1c,
13698 CVT_W = 0x24,
13699 SQRT_FMT = 0x28,
13700 FLOOR_W = 0x2c,
13701 CVT_PS_PW = 0x3c,
13702 CFC1 = 0x40,
13703 RECIP_FMT = 0x48,
13704 CEIL_L = 0x4c,
13705 CTC1 = 0x60,
13706 CEIL_W = 0x6c,
13707 MFC1 = 0x80,
13708 CVT_S_PL = 0x84,
13709 TRUNC_L = 0x8c,
13710 MTC1 = 0xa0,
13711 CVT_S_PU = 0xa4,
13712 TRUNC_W = 0xac,
13713 MFHC1 = 0xc0,
13714 ROUND_L = 0xcc,
13715 MTHC1 = 0xe0,
13716 ROUND_W = 0xec,
13717
13718 MOV_FMT = 0x01,
13719 MOVF = 0x05,
13720 ABS_FMT = 0x0d,
13721 RSQRT1_FMT = 0x1d,
13722 MOVT = 0x25,
13723 NEG_FMT = 0x2d,
13724 CVT_D = 0x4d,
13725 RECIP1_FMT = 0x5d,
13726 CVT_S = 0x6d
13727};
13728
13729/* POOL32I encoding of minor opcode field (bits 25..21) */
13730
13731enum {
13732 BLTZ = 0x00,
13733 BLTZAL = 0x01,
13734 BGEZ = 0x02,
13735 BGEZAL = 0x03,
13736 BLEZ = 0x04,
13737 BNEZC = 0x05,
13738 BGTZ = 0x06,
13739 BEQZC = 0x07,
13740 TLTI = 0x08,
3a1f4268 13741 BC1EQZC = 0x08,
3c824109 13742 TGEI = 0x09,
3a1f4268 13743 BC1NEZC = 0x09,
3c824109 13744 TLTIU = 0x0a,
3a1f4268 13745 BC2EQZC = 0x0a,
3c824109 13746 TGEIU = 0x0b,
3a1f4268 13747 BC2NEZC = 0x0a,
3c824109 13748 TNEI = 0x0c,
3a1f4268 13749 R6_SYNCI = 0x0c,
3c824109
NF
13750 LUI = 0x0d,
13751 TEQI = 0x0e,
13752 SYNCI = 0x10,
13753 BLTZALS = 0x11,
13754 BGEZALS = 0x13,
13755 BC2F = 0x14,
13756 BC2T = 0x15,
13757 BPOSGE64 = 0x1a,
13758 BPOSGE32 = 0x1b,
13759 /* These overlap and are distinguished by bit16 of the instruction */
13760 BC1F = 0x1c,
13761 BC1T = 0x1d,
13762 BC1ANY2F = 0x1c,
13763 BC1ANY2T = 0x1d,
13764 BC1ANY4F = 0x1e,
13765 BC1ANY4T = 0x1f
13766};
13767
13768/* POOL16A encoding of minor opcode field */
13769
13770enum {
13771 ADDU16 = 0x0,
13772 SUBU16 = 0x1
13773};
13774
13775/* POOL16B encoding of minor opcode field */
13776
13777enum {
13778 SLL16 = 0x0,
13779 SRL16 = 0x1
13780};
13781
13782/* POOL16C encoding of minor opcode field */
13783
13784enum {
13785 NOT16 = 0x00,
13786 XOR16 = 0x04,
13787 AND16 = 0x08,
13788 OR16 = 0x0c,
13789 LWM16 = 0x10,
13790 SWM16 = 0x14,
13791 JR16 = 0x18,
13792 JRC16 = 0x1a,
13793 JALR16 = 0x1c,
13794 JALR16S = 0x1e,
13795 MFHI16 = 0x20,
13796 MFLO16 = 0x24,
13797 BREAK16 = 0x28,
13798 SDBBP16 = 0x2c,
13799 JRADDIUSP = 0x30
13800};
13801
3a1f4268
YK
13802/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13803
13804enum {
13805 R6_NOT16 = 0x00,
13806 R6_AND16 = 0x01,
13807 R6_LWM16 = 0x02,
13808 R6_JRC16 = 0x03,
13809 MOVEP = 0x04,
c38a1d52
AR
13810 MOVEP_05 = 0x05,
13811 MOVEP_06 = 0x06,
3a1f4268
YK
13812 MOVEP_07 = 0x07,
13813 R6_XOR16 = 0x08,
13814 R6_OR16 = 0x09,
13815 R6_SWM16 = 0x0a,
13816 JALRC16 = 0x0b,
13817 MOVEP_0C = 0x0c,
c38a1d52
AR
13818 MOVEP_0D = 0x0d,
13819 MOVEP_0E = 0x0e,
3a1f4268
YK
13820 MOVEP_0F = 0x0f,
13821 JRCADDIUSP = 0x13,
13822 R6_BREAK16 = 0x1b,
13823 R6_SDBBP16 = 0x3b
13824};
13825
3c824109
NF
13826/* POOL16D encoding of minor opcode field */
13827
13828enum {
13829 ADDIUS5 = 0x0,
13830 ADDIUSP = 0x1
13831};
13832
13833/* POOL16E encoding of minor opcode field */
13834
13835enum {
13836 ADDIUR2 = 0x0,
13837 ADDIUR1SP = 0x1
13838};
13839
13840static int mmreg (int r)
13841{
13842 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13843
13844 return map[r];
13845}
13846
13847/* Used for 16-bit store instructions. */
13848static int mmreg2 (int r)
13849{
13850 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13851
13852 return map[r];
13853}
13854
13855#define uMIPS_RD(op) ((op >> 7) & 0x7)
13856#define uMIPS_RS(op) ((op >> 4) & 0x7)
13857#define uMIPS_RS2(op) uMIPS_RS(op)
13858#define uMIPS_RS1(op) ((op >> 1) & 0x7)
13859#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13860#define uMIPS_RS5(op) (op & 0x1f)
13861
13862/* Signed immediate */
13863#define SIMM(op, start, width) \
13864 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13865 << (32-width)) \
13866 >> (32-width))
13867/* Zero-extended immediate */
13868#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13869
d75c135e 13870static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
13871{
13872 int rd = mmreg(uMIPS_RD(ctx->opcode));
13873
d75c135e 13874 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
13875}
13876
d75c135e 13877static void gen_addiur2(DisasContext *ctx)
3c824109
NF
13878{
13879 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13880 int rd = mmreg(uMIPS_RD(ctx->opcode));
13881 int rs = mmreg(uMIPS_RS(ctx->opcode));
13882
d75c135e 13883 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
13884}
13885
d75c135e 13886static void gen_addiusp(DisasContext *ctx)
3c824109
NF
13887{
13888 int encoded = ZIMM(ctx->opcode, 1, 9);
13889 int decoded;
13890
13891 if (encoded <= 1) {
13892 decoded = 256 + encoded;
13893 } else if (encoded <= 255) {
13894 decoded = encoded;
13895 } else if (encoded <= 509) {
13896 decoded = encoded - 512;
13897 } else {
13898 decoded = encoded - 768;
13899 }
13900
d75c135e 13901 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
13902}
13903
d75c135e 13904static void gen_addius5(DisasContext *ctx)
3c824109
NF
13905{
13906 int imm = SIMM(ctx->opcode, 1, 4);
13907 int rd = (ctx->opcode >> 5) & 0x1f;
13908
d75c135e 13909 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
13910}
13911
d75c135e 13912static void gen_andi16(DisasContext *ctx)
3c824109
NF
13913{
13914 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13915 31, 32, 63, 64, 255, 32768, 65535 };
13916 int rd = mmreg(uMIPS_RD(ctx->opcode));
13917 int rs = mmreg(uMIPS_RS(ctx->opcode));
13918 int encoded = ZIMM(ctx->opcode, 0, 4);
13919
d75c135e 13920 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13921}
13922
13923static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13924 int base, int16_t offset)
13925{
13926 TCGv t0, t1;
13927 TCGv_i32 t2;
13928
13929 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 13930 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13931 return;
13932 }
13933
13934 t0 = tcg_temp_new();
13935
13936 gen_base_offset_addr(ctx, t0, base, offset);
13937
13938 t1 = tcg_const_tl(reglist);
13939 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13940
3c824109
NF
13941 save_cpu_state(ctx, 1);
13942 switch (opc) {
13943 case LWM32:
895c2d04 13944 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
13945 break;
13946 case SWM32:
895c2d04 13947 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
13948 break;
13949#ifdef TARGET_MIPS64
13950 case LDM:
895c2d04 13951 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
13952 break;
13953 case SDM:
895c2d04 13954 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 13955 break;
6af0bf9c 13956#endif
3c824109 13957 }
3c824109 13958 tcg_temp_free(t0);
33087598 13959 tcg_temp_free(t1);
3c824109
NF
13960 tcg_temp_free_i32(t2);
13961}
6af0bf9c 13962
3c824109 13963
240ce26a 13964static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13965{
3c824109
NF
13966 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13967 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13968
3c824109
NF
13969 switch (((ctx->opcode) >> 4) & 0x3f) {
13970 case NOT16 + 0:
13971 case NOT16 + 1:
13972 case NOT16 + 2:
13973 case NOT16 + 3:
d75c135e 13974 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13975 break;
13976 case XOR16 + 0:
13977 case XOR16 + 1:
13978 case XOR16 + 2:
13979 case XOR16 + 3:
d75c135e 13980 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13981 break;
13982 case AND16 + 0:
13983 case AND16 + 1:
13984 case AND16 + 2:
13985 case AND16 + 3:
d75c135e 13986 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13987 break;
13988 case OR16 + 0:
13989 case OR16 + 1:
13990 case OR16 + 2:
13991 case OR16 + 3:
d75c135e 13992 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13993 break;
13994 case LWM16 + 0:
13995 case LWM16 + 1:
13996 case LWM16 + 2:
13997 case LWM16 + 3:
13998 {
13999 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14000 int offset = ZIMM(ctx->opcode, 0, 4);
14001
14002 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14003 29, offset << 2);
14004 }
14005 break;
14006 case SWM16 + 0:
14007 case SWM16 + 1:
14008 case SWM16 + 2:
14009 case SWM16 + 3:
14010 {
14011 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14012 int offset = ZIMM(ctx->opcode, 0, 4);
14013
14014 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14015 29, offset << 2);
14016 }
14017 break;
14018 case JR16 + 0:
14019 case JR16 + 1:
14020 {
14021 int reg = ctx->opcode & 0x1f;
14022
b231c103 14023 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 14024 }
3c824109
NF
14025 break;
14026 case JRC16 + 0:
14027 case JRC16 + 1:
14028 {
14029 int reg = ctx->opcode & 0x1f;
b231c103 14030 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
14031 /* Let normal delay slot handling in our caller take us
14032 to the branch target. */
14033 }
14034 break;
14035 case JALR16 + 0:
14036 case JALR16 + 1:
b231c103
YK
14037 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14038 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14039 break;
3c824109
NF
14040 case JALR16S + 0:
14041 case JALR16S + 1:
b231c103
YK
14042 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14043 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14044 break;
14045 case MFHI16 + 0:
14046 case MFHI16 + 1:
26135ead 14047 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14048 break;
14049 case MFLO16 + 0:
14050 case MFLO16 + 1:
26135ead 14051 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14052 break;
14053 case BREAK16:
9c708c7f 14054 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
14055 break;
14056 case SDBBP16:
3b3c1694
LA
14057 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14058 gen_helper_do_semihosting(cpu_env);
14059 } else {
14060 /* XXX: not clear which exception should be raised
14061 * when in debug mode...
14062 */
14063 check_insn(ctx, ISA_MIPS32);
9c708c7f 14064 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14065 }
3c824109
NF
14066 break;
14067 case JRADDIUSP + 0:
14068 case JRADDIUSP + 1:
14069 {
14070 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 14071 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 14072 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
14073 /* Let normal delay slot handling in our caller take us
14074 to the branch target. */
14075 }
14076 break;
14077 default:
9c708c7f 14078 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14079 break;
14080 }
14081}
14082
ed7ce6c0
YK
14083static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14084 int enc_rs)
14085{
14086 int rd, rs, re, rt;
14087 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14088 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14089 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14090 rd = rd_enc[enc_dest];
14091 re = re_enc[enc_dest];
14092 rs = rs_rt_enc[enc_rs];
14093 rt = rs_rt_enc[enc_rt];
14094 if (rs) {
14095 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14096 } else {
14097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14098 }
14099 if (rt) {
14100 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14101 } else {
14102 tcg_gen_movi_tl(cpu_gpr[re], 0);
14103 }
14104}
14105
14106static void gen_pool16c_r6_insn(DisasContext *ctx)
14107{
14108 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14109 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14110
14111 switch (ctx->opcode & 0xf) {
14112 case R6_NOT16:
14113 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14114 break;
14115 case R6_AND16:
14116 gen_logic(ctx, OPC_AND, rt, rt, rs);
14117 break;
14118 case R6_LWM16:
14119 {
14120 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14121 int offset = extract32(ctx->opcode, 4, 4);
14122 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14123 }
14124 break;
14125 case R6_JRC16: /* JRCADDIUSP */
14126 if ((ctx->opcode >> 4) & 1) {
14127 /* JRCADDIUSP */
14128 int imm = extract32(ctx->opcode, 5, 5);
14129 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14130 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14131 } else {
14132 /* JRC16 */
e1555d7d 14133 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
14134 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14135 }
14136 break;
c38a1d52
AR
14137 case MOVEP:
14138 case MOVEP_05:
14139 case MOVEP_06:
14140 case MOVEP_07:
14141 case MOVEP_0C:
14142 case MOVEP_0D:
14143 case MOVEP_0E:
14144 case MOVEP_0F:
ed7ce6c0
YK
14145 {
14146 int enc_dest = uMIPS_RD(ctx->opcode);
14147 int enc_rt = uMIPS_RS2(ctx->opcode);
14148 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14149 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14150 }
14151 break;
14152 case R6_XOR16:
14153 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14154 break;
14155 case R6_OR16:
14156 gen_logic(ctx, OPC_OR, rt, rt, rs);
14157 break;
14158 case R6_SWM16:
14159 {
14160 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14161 int offset = extract32(ctx->opcode, 4, 4);
14162 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14163 }
14164 break;
14165 case JALRC16: /* BREAK16, SDBBP16 */
14166 switch (ctx->opcode & 0x3f) {
14167 case JALRC16:
14168 case JALRC16 + 0x20:
14169 /* JALRC16 */
14170 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14171 31, 0, 0);
14172 break;
14173 case R6_BREAK16:
14174 /* BREAK16 */
14175 generate_exception(ctx, EXCP_BREAK);
14176 break;
14177 case R6_SDBBP16:
14178 /* SDBBP16 */
060ebfef
LA
14179 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14180 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 14181 } else {
060ebfef
LA
14182 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14183 generate_exception(ctx, EXCP_RI);
14184 } else {
14185 generate_exception(ctx, EXCP_DBp);
14186 }
ed7ce6c0
YK
14187 }
14188 break;
14189 }
14190 break;
14191 default:
14192 generate_exception(ctx, EXCP_RI);
14193 break;
14194 }
14195}
14196
3c824109
NF
14197static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14198{
14199 TCGv t0 = tcg_temp_new();
14200 TCGv t1 = tcg_temp_new();
14201
14202 gen_load_gpr(t0, base);
14203
14204 if (index != 0) {
14205 gen_load_gpr(t1, index);
14206 tcg_gen_shli_tl(t1, t1, 2);
14207 gen_op_addr_add(ctx, t0, t1, t0);
14208 }
14209
5f68f5ae 14210 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14211 gen_store_gpr(t1, rd);
14212
14213 tcg_temp_free(t0);
14214 tcg_temp_free(t1);
14215}
14216
14217static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14218 int base, int16_t offset)
14219{
3c824109
NF
14220 TCGv t0, t1;
14221
36c6711b 14222 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 14223 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
14224 return;
14225 }
14226
3c824109
NF
14227 t0 = tcg_temp_new();
14228 t1 = tcg_temp_new();
8e9ade68 14229
3c824109
NF
14230 gen_base_offset_addr(ctx, t0, base, offset);
14231
14232 switch (opc) {
14233 case LWP:
36c6711b 14234 if (rd == base) {
9c708c7f 14235 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14236 return;
14237 }
5f68f5ae 14238 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14239 gen_store_gpr(t1, rd);
14240 tcg_gen_movi_tl(t1, 4);
14241 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14242 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 14243 gen_store_gpr(t1, rd+1);
3c824109
NF
14244 break;
14245 case SWP:
3c824109 14246 gen_load_gpr(t1, rd);
5f68f5ae 14247 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14248 tcg_gen_movi_tl(t1, 4);
14249 gen_op_addr_add(ctx, t0, t0, t1);
14250 gen_load_gpr(t1, rd+1);
5f68f5ae 14251 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14252 break;
14253#ifdef TARGET_MIPS64
14254 case LDP:
36c6711b 14255 if (rd == base) {
9c708c7f 14256 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14257 return;
14258 }
5f68f5ae 14259 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14260 gen_store_gpr(t1, rd);
14261 tcg_gen_movi_tl(t1, 8);
14262 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14263 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 14264 gen_store_gpr(t1, rd+1);
3c824109
NF
14265 break;
14266 case SDP:
3c824109 14267 gen_load_gpr(t1, rd);
5f68f5ae 14268 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14269 tcg_gen_movi_tl(t1, 8);
14270 gen_op_addr_add(ctx, t0, t0, t1);
14271 gen_load_gpr(t1, rd+1);
5f68f5ae 14272 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14273 break;
14274#endif
6af0bf9c 14275 }
3c824109
NF
14276 tcg_temp_free(t0);
14277 tcg_temp_free(t1);
14278}
618b0fe9 14279
d208ac0c
LA
14280static void gen_sync(int stype)
14281{
14282 TCGBar tcg_mo = TCG_BAR_SC;
14283
14284 switch (stype) {
14285 case 0x4: /* SYNC_WMB */
14286 tcg_mo |= TCG_MO_ST_ST;
14287 break;
14288 case 0x10: /* SYNC_MB */
14289 tcg_mo |= TCG_MO_ALL;
14290 break;
14291 case 0x11: /* SYNC_ACQUIRE */
14292 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14293 break;
14294 case 0x12: /* SYNC_RELEASE */
14295 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14296 break;
14297 case 0x13: /* SYNC_RMB */
14298 tcg_mo |= TCG_MO_LD_LD;
14299 break;
14300 default:
14301 tcg_mo |= TCG_MO_ALL;
14302 break;
14303 }
14304
14305 tcg_gen_mb(tcg_mo);
14306}
14307
240ce26a 14308static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
14309{
14310 int extension = (ctx->opcode >> 6) & 0x3f;
14311 int minor = (ctx->opcode >> 12) & 0xf;
14312 uint32_t mips32_op;
14313
14314 switch (extension) {
14315 case TEQ:
14316 mips32_op = OPC_TEQ;
14317 goto do_trap;
14318 case TGE:
14319 mips32_op = OPC_TGE;
14320 goto do_trap;
14321 case TGEU:
14322 mips32_op = OPC_TGEU;
14323 goto do_trap;
14324 case TLT:
14325 mips32_op = OPC_TLT;
14326 goto do_trap;
14327 case TLTU:
14328 mips32_op = OPC_TLTU;
14329 goto do_trap;
14330 case TNE:
14331 mips32_op = OPC_TNE;
14332 do_trap:
14333 gen_trap(ctx, mips32_op, rs, rt, -1);
14334 break;
14335#ifndef CONFIG_USER_ONLY
14336 case MFC0:
14337 case MFC0 + 32:
2e15497c 14338 check_cp0_enabled(ctx);
3c824109
NF
14339 if (rt == 0) {
14340 /* Treat as NOP. */
14341 break;
14342 }
d75c135e 14343 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
14344 break;
14345 case MTC0:
14346 case MTC0 + 32:
2e15497c 14347 check_cp0_enabled(ctx);
3c824109
NF
14348 {
14349 TCGv t0 = tcg_temp_new();
618b0fe9 14350
3c824109 14351 gen_load_gpr(t0, rt);
d75c135e 14352 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
14353 tcg_temp_free(t0);
14354 }
14355 break;
14356#endif
a1fc6246
LA
14357 case 0x2a:
14358 switch (minor & 3) {
14359 case MADD_ACC:
14360 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14361 break;
14362 case MADDU_ACC:
14363 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14364 break;
14365 case MSUB_ACC:
14366 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14367 break;
14368 case MSUBU_ACC:
14369 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14370 break;
14371 default:
14372 goto pool32axf_invalid;
14373 }
14374 break;
14375 case 0x32:
14376 switch (minor & 3) {
14377 case MULT_ACC:
14378 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14379 break;
14380 case MULTU_ACC:
14381 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14382 break;
14383 default:
14384 goto pool32axf_invalid;
14385 }
14386 break;
3c824109
NF
14387 case 0x2c:
14388 switch (minor) {
e0332095
YK
14389 case BITSWAP:
14390 check_insn(ctx, ISA_MIPS32R6);
14391 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14392 break;
3c824109
NF
14393 case SEB:
14394 gen_bshfl(ctx, OPC_SEB, rs, rt);
14395 break;
14396 case SEH:
14397 gen_bshfl(ctx, OPC_SEH, rs, rt);
14398 break;
14399 case CLO:
14400 mips32_op = OPC_CLO;
14401 goto do_cl;
14402 case CLZ:
14403 mips32_op = OPC_CLZ;
14404 do_cl:
d75c135e 14405 check_insn(ctx, ISA_MIPS32);
3c824109
NF
14406 gen_cl(ctx, mips32_op, rt, rs);
14407 break;
14408 case RDHWR:
b00c7218
YK
14409 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14410 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
14411 break;
14412 case WSBH:
14413 gen_bshfl(ctx, OPC_WSBH, rs, rt);
14414 break;
14415 case MULT:
9e8f441a 14416 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14417 mips32_op = OPC_MULT;
26135ead 14418 goto do_mul;
3c824109 14419 case MULTU:
9e8f441a 14420 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14421 mips32_op = OPC_MULTU;
26135ead 14422 goto do_mul;
3c824109 14423 case DIV:
9e8f441a 14424 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14425 mips32_op = OPC_DIV;
26135ead 14426 goto do_div;
3c824109 14427 case DIVU:
9e8f441a 14428 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14429 mips32_op = OPC_DIVU;
26135ead
RS
14430 goto do_div;
14431 do_div:
14432 check_insn(ctx, ISA_MIPS32);
14433 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14434 break;
3c824109 14435 case MADD:
9e8f441a 14436 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14437 mips32_op = OPC_MADD;
26135ead 14438 goto do_mul;
3c824109 14439 case MADDU:
9e8f441a 14440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14441 mips32_op = OPC_MADDU;
26135ead 14442 goto do_mul;
3c824109 14443 case MSUB:
9e8f441a 14444 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14445 mips32_op = OPC_MSUB;
26135ead 14446 goto do_mul;
3c824109 14447 case MSUBU:
9e8f441a 14448 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14449 mips32_op = OPC_MSUBU;
26135ead 14450 do_mul:
d75c135e 14451 check_insn(ctx, ISA_MIPS32);
a1fc6246 14452 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
14453 break;
14454 default:
14455 goto pool32axf_invalid;
14456 }
14457 break;
14458 case 0x34:
14459 switch (minor) {
14460 case MFC2:
14461 case MTC2:
14462 case MFHC2:
14463 case MTHC2:
14464 case CFC2:
14465 case CTC2:
14466 generate_exception_err(ctx, EXCP_CpU, 2);
14467 break;
14468 default:
14469 goto pool32axf_invalid;
14470 }
14471 break;
14472 case 0x3c:
14473 switch (minor) {
65935f07
YK
14474 case JALR: /* JALRC */
14475 case JALR_HB: /* JALRC_HB */
14476 if (ctx->insn_flags & ISA_MIPS32R6) {
14477 /* JALRC, JALRC_HB */
14478 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14479 } else {
14480 /* JALR, JALR_HB */
14481 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14482 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14483 }
3c824109
NF
14484 break;
14485 case JALRS:
14486 case JALRS_HB:
9e8f441a 14487 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14488 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14489 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14490 break;
14491 default:
14492 goto pool32axf_invalid;
14493 }
14494 break;
14495 case 0x05:
14496 switch (minor) {
14497 case RDPGPR:
2e15497c 14498 check_cp0_enabled(ctx);
d75c135e 14499 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 14500 gen_load_srsgpr(rs, rt);
3c824109
NF
14501 break;
14502 case WRPGPR:
2e15497c 14503 check_cp0_enabled(ctx);
d75c135e 14504 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 14505 gen_store_srsgpr(rs, rt);
3c824109
NF
14506 break;
14507 default:
14508 goto pool32axf_invalid;
14509 }
14510 break;
14511#ifndef CONFIG_USER_ONLY
14512 case 0x0d:
14513 switch (minor) {
14514 case TLBP:
14515 mips32_op = OPC_TLBP;
14516 goto do_cp0;
14517 case TLBR:
14518 mips32_op = OPC_TLBR;
14519 goto do_cp0;
14520 case TLBWI:
14521 mips32_op = OPC_TLBWI;
14522 goto do_cp0;
14523 case TLBWR:
14524 mips32_op = OPC_TLBWR;
14525 goto do_cp0;
e60ec063
YK
14526 case TLBINV:
14527 mips32_op = OPC_TLBINV;
14528 goto do_cp0;
14529 case TLBINVF:
14530 mips32_op = OPC_TLBINVF;
14531 goto do_cp0;
3c824109
NF
14532 case WAIT:
14533 mips32_op = OPC_WAIT;
14534 goto do_cp0;
14535 case DERET:
14536 mips32_op = OPC_DERET;
14537 goto do_cp0;
14538 case ERET:
14539 mips32_op = OPC_ERET;
14540 do_cp0:
14541 gen_cp0(env, ctx, mips32_op, rt, rs);
14542 break;
14543 default:
14544 goto pool32axf_invalid;
14545 }
14546 break;
14547 case 0x1d:
14548 switch (minor) {
14549 case DI:
2e15497c 14550 check_cp0_enabled(ctx);
3c824109
NF
14551 {
14552 TCGv t0 = tcg_temp_new();
14553
14554 save_cpu_state(ctx, 1);
895c2d04 14555 gen_helper_di(t0, cpu_env);
3c824109
NF
14556 gen_store_gpr(t0, rs);
14557 /* Stop translation as we may have switched the execution mode */
eeb3bba8 14558 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
14559 tcg_temp_free(t0);
14560 }
14561 break;
14562 case EI:
2e15497c 14563 check_cp0_enabled(ctx);
3c824109
NF
14564 {
14565 TCGv t0 = tcg_temp_new();
14566
14567 save_cpu_state(ctx, 1);
895c2d04 14568 gen_helper_ei(t0, cpu_env);
3c824109 14569 gen_store_gpr(t0, rs);
b28425ba 14570 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 14571 of translated code to check for pending interrupts. */
eeb3bba8
EC
14572 gen_save_pc(ctx->base.pc_next + 4);
14573 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
14574 tcg_temp_free(t0);
14575 }
14576 break;
14577 default:
14578 goto pool32axf_invalid;
14579 }
14580 break;
14581#endif
14582 case 0x2d:
14583 switch (minor) {
14584 case SYNC:
d208ac0c 14585 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
14586 break;
14587 case SYSCALL:
9c708c7f 14588 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
14589 break;
14590 case SDBBP:
3b3c1694
LA
14591 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14592 gen_helper_do_semihosting(cpu_env);
14593 } else {
14594 check_insn(ctx, ISA_MIPS32);
e0332095 14595 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 14596 generate_exception_end(ctx, EXCP_RI);
e0332095 14597 } else {
9c708c7f 14598 generate_exception_end(ctx, EXCP_DBp);
e0332095 14599 }
3b3c1694 14600 }
3c824109
NF
14601 break;
14602 default:
14603 goto pool32axf_invalid;
14604 }
14605 break;
a1fc6246 14606 case 0x01:
26135ead 14607 switch (minor & 3) {
a1fc6246 14608 case MFHI_ACC:
26135ead 14609 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 14610 break;
a1fc6246 14611 case MFLO_ACC:
26135ead 14612 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 14613 break;
a1fc6246 14614 case MTHI_ACC:
26135ead 14615 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 14616 break;
a1fc6246 14617 case MTLO_ACC:
26135ead 14618 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
14619 break;
14620 default:
14621 goto pool32axf_invalid;
14622 }
14623 break;
a1fc6246 14624 case 0x35:
9e8f441a 14625 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
14626 switch (minor) {
14627 case MFHI32:
14628 gen_HILO(ctx, OPC_MFHI, 0, rs);
14629 break;
14630 case MFLO32:
14631 gen_HILO(ctx, OPC_MFLO, 0, rs);
14632 break;
14633 case MTHI32:
14634 gen_HILO(ctx, OPC_MTHI, 0, rs);
14635 break;
14636 case MTLO32:
14637 gen_HILO(ctx, OPC_MTLO, 0, rs);
14638 break;
14639 default:
14640 goto pool32axf_invalid;
14641 }
14642 break;
3c824109
NF
14643 default:
14644 pool32axf_invalid:
14645 MIPS_INVAL("pool32axf");
9c708c7f 14646 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14647 break;
14648 }
14649}
14650
14651/* Values for microMIPS fmt field. Variable-width, depending on which
14652 formats the instruction supports. */
14653
14654enum {
14655 FMT_SD_S = 0,
14656 FMT_SD_D = 1,
14657
14658 FMT_SDPS_S = 0,
14659 FMT_SDPS_D = 1,
14660 FMT_SDPS_PS = 2,
14661
14662 FMT_SWL_S = 0,
14663 FMT_SWL_W = 1,
14664 FMT_SWL_L = 2,
14665
14666 FMT_DWL_D = 0,
14667 FMT_DWL_W = 1,
14668 FMT_DWL_L = 2
14669};
14670
d75c135e 14671static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
14672{
14673 int extension = (ctx->opcode >> 6) & 0x3ff;
14674 uint32_t mips32_op;
14675
14676#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14677#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14678#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14679
14680 switch (extension) {
14681 case FLOAT_1BIT_FMT(CFC1, 0):
14682 mips32_op = OPC_CFC1;
14683 goto do_cp1;
14684 case FLOAT_1BIT_FMT(CTC1, 0):
14685 mips32_op = OPC_CTC1;
14686 goto do_cp1;
14687 case FLOAT_1BIT_FMT(MFC1, 0):
14688 mips32_op = OPC_MFC1;
14689 goto do_cp1;
14690 case FLOAT_1BIT_FMT(MTC1, 0):
14691 mips32_op = OPC_MTC1;
14692 goto do_cp1;
14693 case FLOAT_1BIT_FMT(MFHC1, 0):
14694 mips32_op = OPC_MFHC1;
14695 goto do_cp1;
14696 case FLOAT_1BIT_FMT(MTHC1, 0):
14697 mips32_op = OPC_MTHC1;
14698 do_cp1:
14699 gen_cp1(ctx, mips32_op, rt, rs);
14700 break;
14701
14702 /* Reciprocal square root */
14703 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14704 mips32_op = OPC_RSQRT_S;
14705 goto do_unaryfp;
14706 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14707 mips32_op = OPC_RSQRT_D;
14708 goto do_unaryfp;
14709
14710 /* Square root */
14711 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14712 mips32_op = OPC_SQRT_S;
14713 goto do_unaryfp;
14714 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14715 mips32_op = OPC_SQRT_D;
14716 goto do_unaryfp;
14717
14718 /* Reciprocal */
14719 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14720 mips32_op = OPC_RECIP_S;
14721 goto do_unaryfp;
14722 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14723 mips32_op = OPC_RECIP_D;
14724 goto do_unaryfp;
14725
14726 /* Floor */
14727 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14728 mips32_op = OPC_FLOOR_L_S;
14729 goto do_unaryfp;
14730 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14731 mips32_op = OPC_FLOOR_L_D;
14732 goto do_unaryfp;
14733 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14734 mips32_op = OPC_FLOOR_W_S;
14735 goto do_unaryfp;
14736 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14737 mips32_op = OPC_FLOOR_W_D;
14738 goto do_unaryfp;
14739
14740 /* Ceiling */
14741 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14742 mips32_op = OPC_CEIL_L_S;
14743 goto do_unaryfp;
14744 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14745 mips32_op = OPC_CEIL_L_D;
14746 goto do_unaryfp;
14747 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14748 mips32_op = OPC_CEIL_W_S;
14749 goto do_unaryfp;
14750 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14751 mips32_op = OPC_CEIL_W_D;
14752 goto do_unaryfp;
14753
14754 /* Truncation */
14755 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14756 mips32_op = OPC_TRUNC_L_S;
14757 goto do_unaryfp;
14758 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14759 mips32_op = OPC_TRUNC_L_D;
14760 goto do_unaryfp;
14761 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14762 mips32_op = OPC_TRUNC_W_S;
14763 goto do_unaryfp;
14764 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14765 mips32_op = OPC_TRUNC_W_D;
14766 goto do_unaryfp;
14767
14768 /* Round */
14769 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14770 mips32_op = OPC_ROUND_L_S;
14771 goto do_unaryfp;
14772 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14773 mips32_op = OPC_ROUND_L_D;
14774 goto do_unaryfp;
14775 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14776 mips32_op = OPC_ROUND_W_S;
14777 goto do_unaryfp;
14778 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14779 mips32_op = OPC_ROUND_W_D;
14780 goto do_unaryfp;
14781
14782 /* Integer to floating-point conversion */
14783 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14784 mips32_op = OPC_CVT_L_S;
14785 goto do_unaryfp;
14786 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14787 mips32_op = OPC_CVT_L_D;
14788 goto do_unaryfp;
14789 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14790 mips32_op = OPC_CVT_W_S;
14791 goto do_unaryfp;
14792 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14793 mips32_op = OPC_CVT_W_D;
14794 goto do_unaryfp;
14795
14796 /* Paired-foo conversions */
14797 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14798 mips32_op = OPC_CVT_S_PL;
14799 goto do_unaryfp;
14800 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14801 mips32_op = OPC_CVT_S_PU;
14802 goto do_unaryfp;
14803 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14804 mips32_op = OPC_CVT_PW_PS;
14805 goto do_unaryfp;
14806 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14807 mips32_op = OPC_CVT_PS_PW;
14808 goto do_unaryfp;
14809
14810 /* Floating-point moves */
14811 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14812 mips32_op = OPC_MOV_S;
14813 goto do_unaryfp;
14814 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14815 mips32_op = OPC_MOV_D;
14816 goto do_unaryfp;
14817 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14818 mips32_op = OPC_MOV_PS;
14819 goto do_unaryfp;
14820
14821 /* Absolute value */
14822 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14823 mips32_op = OPC_ABS_S;
14824 goto do_unaryfp;
14825 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14826 mips32_op = OPC_ABS_D;
14827 goto do_unaryfp;
14828 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14829 mips32_op = OPC_ABS_PS;
14830 goto do_unaryfp;
14831
14832 /* Negation */
14833 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14834 mips32_op = OPC_NEG_S;
14835 goto do_unaryfp;
14836 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14837 mips32_op = OPC_NEG_D;
14838 goto do_unaryfp;
14839 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14840 mips32_op = OPC_NEG_PS;
14841 goto do_unaryfp;
14842
14843 /* Reciprocal square root step */
14844 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14845 mips32_op = OPC_RSQRT1_S;
14846 goto do_unaryfp;
14847 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14848 mips32_op = OPC_RSQRT1_D;
14849 goto do_unaryfp;
14850 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14851 mips32_op = OPC_RSQRT1_PS;
14852 goto do_unaryfp;
14853
14854 /* Reciprocal step */
14855 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14856 mips32_op = OPC_RECIP1_S;
14857 goto do_unaryfp;
14858 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14859 mips32_op = OPC_RECIP1_S;
14860 goto do_unaryfp;
14861 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14862 mips32_op = OPC_RECIP1_PS;
14863 goto do_unaryfp;
14864
14865 /* Conversions from double */
14866 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14867 mips32_op = OPC_CVT_D_S;
14868 goto do_unaryfp;
14869 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14870 mips32_op = OPC_CVT_D_W;
14871 goto do_unaryfp;
14872 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14873 mips32_op = OPC_CVT_D_L;
14874 goto do_unaryfp;
14875
14876 /* Conversions from single */
14877 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14878 mips32_op = OPC_CVT_S_D;
14879 goto do_unaryfp;
14880 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14881 mips32_op = OPC_CVT_S_W;
14882 goto do_unaryfp;
14883 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14884 mips32_op = OPC_CVT_S_L;
14885 do_unaryfp:
14886 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14887 break;
14888
14889 /* Conditional moves on floating-point codes */
14890 case COND_FLOAT_MOV(MOVT, 0):
14891 case COND_FLOAT_MOV(MOVT, 1):
14892 case COND_FLOAT_MOV(MOVT, 2):
14893 case COND_FLOAT_MOV(MOVT, 3):
14894 case COND_FLOAT_MOV(MOVT, 4):
14895 case COND_FLOAT_MOV(MOVT, 5):
14896 case COND_FLOAT_MOV(MOVT, 6):
14897 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 14898 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14899 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14900 break;
14901 case COND_FLOAT_MOV(MOVF, 0):
14902 case COND_FLOAT_MOV(MOVF, 1):
14903 case COND_FLOAT_MOV(MOVF, 2):
14904 case COND_FLOAT_MOV(MOVF, 3):
14905 case COND_FLOAT_MOV(MOVF, 4):
14906 case COND_FLOAT_MOV(MOVF, 5):
14907 case COND_FLOAT_MOV(MOVF, 6):
14908 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 14909 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14910 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14911 break;
14912 default:
14913 MIPS_INVAL("pool32fxf");
9c708c7f 14914 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14915 break;
14916 }
14917}
14918
f60eeb0c 14919static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14920{
14921 int32_t offset;
14922 uint16_t insn;
14923 int rt, rs, rd, rr;
14924 int16_t imm;
8fffc646 14925 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
14926 uint32_t cond, fmt, cc;
14927
eeb3bba8 14928 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
14929 ctx->opcode = (ctx->opcode << 16) | insn;
14930
14931 rt = (ctx->opcode >> 21) & 0x1f;
14932 rs = (ctx->opcode >> 16) & 0x1f;
14933 rd = (ctx->opcode >> 11) & 0x1f;
14934 rr = (ctx->opcode >> 6) & 0x1f;
14935 imm = (int16_t) ctx->opcode;
14936
14937 op = (ctx->opcode >> 26) & 0x3f;
14938 switch (op) {
14939 case POOL32A:
14940 minor = ctx->opcode & 0x3f;
14941 switch (minor) {
14942 case 0x00:
14943 minor = (ctx->opcode >> 6) & 0xf;
14944 switch (minor) {
14945 case SLL32:
14946 mips32_op = OPC_SLL;
14947 goto do_shifti;
14948 case SRA:
14949 mips32_op = OPC_SRA;
14950 goto do_shifti;
14951 case SRL32:
14952 mips32_op = OPC_SRL;
14953 goto do_shifti;
14954 case ROTR:
14955 mips32_op = OPC_ROTR;
14956 do_shifti:
d75c135e 14957 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 14958 break;
e0332095
YK
14959 case SELEQZ:
14960 check_insn(ctx, ISA_MIPS32R6);
14961 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14962 break;
14963 case SELNEZ:
14964 check_insn(ctx, ISA_MIPS32R6);
14965 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14966 break;
b00c7218
YK
14967 case R6_RDHWR:
14968 check_insn(ctx, ISA_MIPS32R6);
14969 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14970 break;
3c824109
NF
14971 default:
14972 goto pool32a_invalid;
14973 }
14974 break;
14975 case 0x10:
14976 minor = (ctx->opcode >> 6) & 0xf;
14977 switch (minor) {
14978 /* Arithmetic */
14979 case ADD:
14980 mips32_op = OPC_ADD;
14981 goto do_arith;
14982 case ADDU32:
14983 mips32_op = OPC_ADDU;
14984 goto do_arith;
14985 case SUB:
14986 mips32_op = OPC_SUB;
14987 goto do_arith;
14988 case SUBU32:
14989 mips32_op = OPC_SUBU;
14990 goto do_arith;
14991 case MUL:
9e8f441a 14992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14993 mips32_op = OPC_MUL;
14994 do_arith:
d75c135e 14995 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14996 break;
14997 /* Shifts */
14998 case SLLV:
14999 mips32_op = OPC_SLLV;
15000 goto do_shift;
15001 case SRLV:
15002 mips32_op = OPC_SRLV;
15003 goto do_shift;
15004 case SRAV:
15005 mips32_op = OPC_SRAV;
15006 goto do_shift;
15007 case ROTRV:
15008 mips32_op = OPC_ROTRV;
15009 do_shift:
d75c135e 15010 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15011 break;
15012 /* Logical operations */
15013 case AND:
15014 mips32_op = OPC_AND;
15015 goto do_logic;
15016 case OR32:
15017 mips32_op = OPC_OR;
15018 goto do_logic;
15019 case NOR:
15020 mips32_op = OPC_NOR;
15021 goto do_logic;
15022 case XOR32:
15023 mips32_op = OPC_XOR;
15024 do_logic:
d75c135e 15025 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15026 break;
15027 /* Set less than */
15028 case SLT:
15029 mips32_op = OPC_SLT;
15030 goto do_slt;
15031 case SLTU:
15032 mips32_op = OPC_SLTU;
15033 do_slt:
d75c135e 15034 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15035 break;
15036 default:
15037 goto pool32a_invalid;
15038 }
15039 break;
15040 case 0x18:
15041 minor = (ctx->opcode >> 6) & 0xf;
15042 switch (minor) {
15043 /* Conditional moves */
e0332095
YK
15044 case MOVN: /* MUL */
15045 if (ctx->insn_flags & ISA_MIPS32R6) {
15046 /* MUL */
15047 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15048 } else {
15049 /* MOVN */
15050 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15051 }
15052 break;
15053 case MOVZ: /* MUH */
15054 if (ctx->insn_flags & ISA_MIPS32R6) {
15055 /* MUH */
15056 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15057 } else {
15058 /* MOVZ */
15059 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15060 }
15061 break;
15062 case MULU:
15063 check_insn(ctx, ISA_MIPS32R6);
15064 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15065 break;
15066 case MUHU:
15067 check_insn(ctx, ISA_MIPS32R6);
15068 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15069 break;
15070 case LWXS: /* DIV */
15071 if (ctx->insn_flags & ISA_MIPS32R6) {
15072 /* DIV */
15073 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15074 } else {
15075 /* LWXS */
15076 gen_ldxs(ctx, rs, rt, rd);
15077 }
15078 break;
15079 case MOD:
15080 check_insn(ctx, ISA_MIPS32R6);
15081 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15082 break;
15083 case R6_DIVU:
15084 check_insn(ctx, ISA_MIPS32R6);
15085 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 15086 break;
e0332095
YK
15087 case MODU:
15088 check_insn(ctx, ISA_MIPS32R6);
15089 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
15090 break;
15091 default:
15092 goto pool32a_invalid;
15093 }
15094 break;
15095 case INS:
15096 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15097 return;
e0332095
YK
15098 case LSA:
15099 check_insn(ctx, ISA_MIPS32R6);
15100 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15101 extract32(ctx->opcode, 9, 2));
15102 break;
15103 case ALIGN:
15104 check_insn(ctx, ISA_MIPS32R6);
821f2008 15105 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 15106 break;
3c824109
NF
15107 case EXT:
15108 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15109 return;
15110 case POOL32AXF:
240ce26a 15111 gen_pool32axf(env, ctx, rt, rs);
3c824109 15112 break;
dbd8af98 15113 case BREAK32:
9c708c7f 15114 generate_exception_end(ctx, EXCP_BREAK);
3c824109 15115 break;
bb238210
YK
15116 case SIGRIE:
15117 check_insn(ctx, ISA_MIPS32R6);
15118 generate_exception_end(ctx, EXCP_RI);
15119 break;
3c824109
NF
15120 default:
15121 pool32a_invalid:
15122 MIPS_INVAL("pool32a");
9c708c7f 15123 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15124 break;
15125 }
15126 break;
15127 case POOL32B:
15128 minor = (ctx->opcode >> 12) & 0xf;
15129 switch (minor) {
15130 case CACHE:
2e15497c 15131 check_cp0_enabled(ctx);
0d74a222
LA
15132 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15133 gen_cache_operation(ctx, rt, rs, imm);
15134 }
3c824109
NF
15135 break;
15136 case LWC2:
15137 case SWC2:
15138 /* COP2: Not implemented. */
15139 generate_exception_err(ctx, EXCP_CpU, 2);
15140 break;
3c824109
NF
15141#ifdef TARGET_MIPS64
15142 case LDP:
15143 case SDP:
d9224450
MR
15144 check_insn(ctx, ISA_MIPS3);
15145 check_mips_64(ctx);
3c824109 15146#endif
146dd620 15147 /* fall through */
d9224450
MR
15148 case LWP:
15149 case SWP:
3c824109
NF
15150 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15151 break;
3c824109
NF
15152#ifdef TARGET_MIPS64
15153 case LDM:
15154 case SDM:
d9224450
MR
15155 check_insn(ctx, ISA_MIPS3);
15156 check_mips_64(ctx);
3c824109 15157#endif
146dd620 15158 /* fall through */
d9224450
MR
15159 case LWM32:
15160 case SWM32:
3c824109
NF
15161 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15162 break;
15163 default:
15164 MIPS_INVAL("pool32b");
9c708c7f 15165 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15166 break;
15167 }
15168 break;
15169 case POOL32F:
5ab5c041 15170 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
15171 minor = ctx->opcode & 0x3f;
15172 check_cp1_enabled(ctx);
15173 switch (minor) {
15174 case ALNV_PS:
9e8f441a 15175 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15176 mips32_op = OPC_ALNV_PS;
15177 goto do_madd;
15178 case MADD_S:
9e8f441a 15179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15180 mips32_op = OPC_MADD_S;
15181 goto do_madd;
15182 case MADD_D:
9e8f441a 15183 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15184 mips32_op = OPC_MADD_D;
15185 goto do_madd;
15186 case MADD_PS:
9e8f441a 15187 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15188 mips32_op = OPC_MADD_PS;
15189 goto do_madd;
15190 case MSUB_S:
9e8f441a 15191 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15192 mips32_op = OPC_MSUB_S;
15193 goto do_madd;
15194 case MSUB_D:
9e8f441a 15195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15196 mips32_op = OPC_MSUB_D;
15197 goto do_madd;
15198 case MSUB_PS:
9e8f441a 15199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15200 mips32_op = OPC_MSUB_PS;
15201 goto do_madd;
15202 case NMADD_S:
9e8f441a 15203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15204 mips32_op = OPC_NMADD_S;
15205 goto do_madd;
15206 case NMADD_D:
9e8f441a 15207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15208 mips32_op = OPC_NMADD_D;
15209 goto do_madd;
15210 case NMADD_PS:
9e8f441a 15211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15212 mips32_op = OPC_NMADD_PS;
15213 goto do_madd;
15214 case NMSUB_S:
9e8f441a 15215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15216 mips32_op = OPC_NMSUB_S;
15217 goto do_madd;
15218 case NMSUB_D:
9e8f441a 15219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15220 mips32_op = OPC_NMSUB_D;
15221 goto do_madd;
15222 case NMSUB_PS:
9e8f441a 15223 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15224 mips32_op = OPC_NMSUB_PS;
15225 do_madd:
15226 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15227 break;
15228 case CABS_COND_FMT:
9e8f441a 15229 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15230 cond = (ctx->opcode >> 6) & 0xf;
15231 cc = (ctx->opcode >> 13) & 0x7;
15232 fmt = (ctx->opcode >> 10) & 0x3;
15233 switch (fmt) {
15234 case 0x0:
15235 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15236 break;
15237 case 0x1:
15238 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15239 break;
15240 case 0x2:
15241 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15242 break;
15243 default:
15244 goto pool32f_invalid;
15245 }
15246 break;
15247 case C_COND_FMT:
9e8f441a 15248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15249 cond = (ctx->opcode >> 6) & 0xf;
15250 cc = (ctx->opcode >> 13) & 0x7;
15251 fmt = (ctx->opcode >> 10) & 0x3;
15252 switch (fmt) {
15253 case 0x0:
15254 gen_cmp_s(ctx, cond, rt, rs, cc);
15255 break;
15256 case 0x1:
15257 gen_cmp_d(ctx, cond, rt, rs, cc);
15258 break;
15259 case 0x2:
15260 gen_cmp_ps(ctx, cond, rt, rs, cc);
15261 break;
15262 default:
15263 goto pool32f_invalid;
15264 }
15265 break;
2a24a7ba
YK
15266 case CMP_CONDN_S:
15267 check_insn(ctx, ISA_MIPS32R6);
15268 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15269 break;
15270 case CMP_CONDN_D:
15271 check_insn(ctx, ISA_MIPS32R6);
15272 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15273 break;
3c824109 15274 case POOL32FXF:
d75c135e 15275 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
15276 break;
15277 case 0x00:
15278 /* PLL foo */
15279 switch ((ctx->opcode >> 6) & 0x7) {
15280 case PLL_PS:
15281 mips32_op = OPC_PLL_PS;
15282 goto do_ps;
15283 case PLU_PS:
15284 mips32_op = OPC_PLU_PS;
15285 goto do_ps;
15286 case PUL_PS:
15287 mips32_op = OPC_PUL_PS;
15288 goto do_ps;
15289 case PUU_PS:
15290 mips32_op = OPC_PUU_PS;
15291 goto do_ps;
15292 case CVT_PS_S:
9e8f441a 15293 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15294 mips32_op = OPC_CVT_PS_S;
15295 do_ps:
15296 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15297 break;
15298 default:
15299 goto pool32f_invalid;
15300 }
15301 break;
2a24a7ba
YK
15302 case MIN_FMT:
15303 check_insn(ctx, ISA_MIPS32R6);
15304 switch ((ctx->opcode >> 9) & 0x3) {
15305 case FMT_SDPS_S:
15306 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15307 break;
15308 case FMT_SDPS_D:
15309 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15310 break;
15311 default:
15312 goto pool32f_invalid;
15313 }
15314 break;
3c824109
NF
15315 case 0x08:
15316 /* [LS][WDU]XC1 */
15317 switch ((ctx->opcode >> 6) & 0x7) {
15318 case LWXC1:
9e8f441a 15319 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15320 mips32_op = OPC_LWXC1;
15321 goto do_ldst_cp1;
15322 case SWXC1:
9e8f441a 15323 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15324 mips32_op = OPC_SWXC1;
15325 goto do_ldst_cp1;
15326 case LDXC1:
9e8f441a 15327 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15328 mips32_op = OPC_LDXC1;
15329 goto do_ldst_cp1;
15330 case SDXC1:
9e8f441a 15331 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15332 mips32_op = OPC_SDXC1;
15333 goto do_ldst_cp1;
15334 case LUXC1:
9e8f441a 15335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15336 mips32_op = OPC_LUXC1;
15337 goto do_ldst_cp1;
15338 case SUXC1:
9e8f441a 15339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15340 mips32_op = OPC_SUXC1;
15341 do_ldst_cp1:
15342 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15343 break;
15344 default:
15345 goto pool32f_invalid;
15346 }
15347 break;
2a24a7ba
YK
15348 case MAX_FMT:
15349 check_insn(ctx, ISA_MIPS32R6);
15350 switch ((ctx->opcode >> 9) & 0x3) {
15351 case FMT_SDPS_S:
15352 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15353 break;
15354 case FMT_SDPS_D:
15355 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15356 break;
15357 default:
15358 goto pool32f_invalid;
15359 }
15360 break;
3c824109
NF
15361 case 0x18:
15362 /* 3D insns */
9e8f441a 15363 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15364 fmt = (ctx->opcode >> 9) & 0x3;
15365 switch ((ctx->opcode >> 6) & 0x7) {
15366 case RSQRT2_FMT:
15367 switch (fmt) {
15368 case FMT_SDPS_S:
15369 mips32_op = OPC_RSQRT2_S;
15370 goto do_3d;
15371 case FMT_SDPS_D:
15372 mips32_op = OPC_RSQRT2_D;
15373 goto do_3d;
15374 case FMT_SDPS_PS:
15375 mips32_op = OPC_RSQRT2_PS;
15376 goto do_3d;
15377 default:
15378 goto pool32f_invalid;
15379 }
15380 break;
15381 case RECIP2_FMT:
15382 switch (fmt) {
15383 case FMT_SDPS_S:
15384 mips32_op = OPC_RECIP2_S;
15385 goto do_3d;
15386 case FMT_SDPS_D:
15387 mips32_op = OPC_RECIP2_D;
15388 goto do_3d;
15389 case FMT_SDPS_PS:
15390 mips32_op = OPC_RECIP2_PS;
15391 goto do_3d;
15392 default:
15393 goto pool32f_invalid;
15394 }
15395 break;
15396 case ADDR_PS:
15397 mips32_op = OPC_ADDR_PS;
15398 goto do_3d;
15399 case MULR_PS:
15400 mips32_op = OPC_MULR_PS;
15401 do_3d:
15402 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15403 break;
15404 default:
15405 goto pool32f_invalid;
15406 }
15407 break;
15408 case 0x20:
2a24a7ba 15409 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
15410 cc = (ctx->opcode >> 13) & 0x7;
15411 fmt = (ctx->opcode >> 9) & 0x3;
15412 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
15413 case MOVF_FMT: /* RINT_FMT */
15414 if (ctx->insn_flags & ISA_MIPS32R6) {
15415 /* RINT_FMT */
15416 switch (fmt) {
15417 case FMT_SDPS_S:
15418 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15419 break;
15420 case FMT_SDPS_D:
15421 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15422 break;
15423 default:
15424 goto pool32f_invalid;
15425 }
15426 } else {
15427 /* MOVF_FMT */
15428 switch (fmt) {
15429 case FMT_SDPS_S:
15430 gen_movcf_s(ctx, rs, rt, cc, 0);
15431 break;
15432 case FMT_SDPS_D:
15433 gen_movcf_d(ctx, rs, rt, cc, 0);
15434 break;
15435 case FMT_SDPS_PS:
15436 check_ps(ctx);
15437 gen_movcf_ps(ctx, rs, rt, cc, 0);
15438 break;
15439 default:
15440 goto pool32f_invalid;
15441 }
3c824109
NF
15442 }
15443 break;
2a24a7ba
YK
15444 case MOVT_FMT: /* CLASS_FMT */
15445 if (ctx->insn_flags & ISA_MIPS32R6) {
15446 /* CLASS_FMT */
15447 switch (fmt) {
15448 case FMT_SDPS_S:
15449 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15450 break;
15451 case FMT_SDPS_D:
15452 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15453 break;
15454 default:
15455 goto pool32f_invalid;
15456 }
15457 } else {
15458 /* MOVT_FMT */
15459 switch (fmt) {
15460 case FMT_SDPS_S:
15461 gen_movcf_s(ctx, rs, rt, cc, 1);
15462 break;
15463 case FMT_SDPS_D:
15464 gen_movcf_d(ctx, rs, rt, cc, 1);
15465 break;
15466 case FMT_SDPS_PS:
15467 check_ps(ctx);
15468 gen_movcf_ps(ctx, rs, rt, cc, 1);
15469 break;
15470 default:
15471 goto pool32f_invalid;
15472 }
3c824109
NF
15473 }
15474 break;
15475 case PREFX:
9e8f441a 15476 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15477 break;
15478 default:
15479 goto pool32f_invalid;
15480 }
15481 break;
15482#define FINSN_3ARG_SDPS(prfx) \
15483 switch ((ctx->opcode >> 8) & 0x3) { \
15484 case FMT_SDPS_S: \
15485 mips32_op = OPC_##prfx##_S; \
15486 goto do_fpop; \
15487 case FMT_SDPS_D: \
15488 mips32_op = OPC_##prfx##_D; \
15489 goto do_fpop; \
15490 case FMT_SDPS_PS: \
e29c9628 15491 check_ps(ctx); \
3c824109
NF
15492 mips32_op = OPC_##prfx##_PS; \
15493 goto do_fpop; \
15494 default: \
15495 goto pool32f_invalid; \
15496 }
2a24a7ba
YK
15497 case MINA_FMT:
15498 check_insn(ctx, ISA_MIPS32R6);
15499 switch ((ctx->opcode >> 9) & 0x3) {
15500 case FMT_SDPS_S:
15501 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15502 break;
15503 case FMT_SDPS_D:
15504 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15505 break;
15506 default:
15507 goto pool32f_invalid;
15508 }
15509 break;
15510 case MAXA_FMT:
15511 check_insn(ctx, ISA_MIPS32R6);
15512 switch ((ctx->opcode >> 9) & 0x3) {
15513 case FMT_SDPS_S:
15514 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15515 break;
15516 case FMT_SDPS_D:
15517 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15518 break;
15519 default:
15520 goto pool32f_invalid;
15521 }
15522 break;
3c824109
NF
15523 case 0x30:
15524 /* regular FP ops */
15525 switch ((ctx->opcode >> 6) & 0x3) {
15526 case ADD_FMT:
15527 FINSN_3ARG_SDPS(ADD);
15528 break;
15529 case SUB_FMT:
15530 FINSN_3ARG_SDPS(SUB);
15531 break;
15532 case MUL_FMT:
15533 FINSN_3ARG_SDPS(MUL);
15534 break;
15535 case DIV_FMT:
15536 fmt = (ctx->opcode >> 8) & 0x3;
15537 if (fmt == 1) {
15538 mips32_op = OPC_DIV_D;
15539 } else if (fmt == 0) {
15540 mips32_op = OPC_DIV_S;
15541 } else {
15542 goto pool32f_invalid;
15543 }
15544 goto do_fpop;
15545 default:
15546 goto pool32f_invalid;
15547 }
15548 break;
15549 case 0x38:
15550 /* cmovs */
2a24a7ba
YK
15551 switch ((ctx->opcode >> 6) & 0x7) {
15552 case MOVN_FMT: /* SELNEZ_FMT */
15553 if (ctx->insn_flags & ISA_MIPS32R6) {
15554 /* SELNEZ_FMT */
15555 switch ((ctx->opcode >> 9) & 0x3) {
15556 case FMT_SDPS_S:
15557 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15558 break;
15559 case FMT_SDPS_D:
15560 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15561 break;
15562 default:
15563 goto pool32f_invalid;
15564 }
15565 } else {
15566 /* MOVN_FMT */
15567 FINSN_3ARG_SDPS(MOVN);
15568 }
15569 break;
15570 case MOVN_FMT_04:
15571 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15572 FINSN_3ARG_SDPS(MOVN);
15573 break;
2a24a7ba
YK
15574 case MOVZ_FMT: /* SELEQZ_FMT */
15575 if (ctx->insn_flags & ISA_MIPS32R6) {
15576 /* SELEQZ_FMT */
15577 switch ((ctx->opcode >> 9) & 0x3) {
15578 case FMT_SDPS_S:
15579 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15580 break;
15581 case FMT_SDPS_D:
15582 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15583 break;
15584 default:
15585 goto pool32f_invalid;
15586 }
15587 } else {
15588 /* MOVZ_FMT */
15589 FINSN_3ARG_SDPS(MOVZ);
15590 }
15591 break;
15592 case MOVZ_FMT_05:
15593 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15594 FINSN_3ARG_SDPS(MOVZ);
15595 break;
2a24a7ba
YK
15596 case SEL_FMT:
15597 check_insn(ctx, ISA_MIPS32R6);
15598 switch ((ctx->opcode >> 9) & 0x3) {
15599 case FMT_SDPS_S:
15600 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15601 break;
15602 case FMT_SDPS_D:
15603 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15604 break;
15605 default:
15606 goto pool32f_invalid;
15607 }
15608 break;
15609 case MADDF_FMT:
15610 check_insn(ctx, ISA_MIPS32R6);
15611 switch ((ctx->opcode >> 9) & 0x3) {
15612 case FMT_SDPS_S:
15613 mips32_op = OPC_MADDF_S;
15614 goto do_fpop;
15615 case FMT_SDPS_D:
15616 mips32_op = OPC_MADDF_D;
15617 goto do_fpop;
15618 default:
15619 goto pool32f_invalid;
15620 }
15621 break;
15622 case MSUBF_FMT:
15623 check_insn(ctx, ISA_MIPS32R6);
15624 switch ((ctx->opcode >> 9) & 0x3) {
15625 case FMT_SDPS_S:
15626 mips32_op = OPC_MSUBF_S;
15627 goto do_fpop;
15628 case FMT_SDPS_D:
15629 mips32_op = OPC_MSUBF_D;
15630 goto do_fpop;
15631 default:
15632 goto pool32f_invalid;
15633 }
15634 break;
3c824109
NF
15635 default:
15636 goto pool32f_invalid;
15637 }
15638 break;
15639 do_fpop:
15640 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15641 break;
15642 default:
15643 pool32f_invalid:
15644 MIPS_INVAL("pool32f");
9c708c7f 15645 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15646 break;
15647 }
15648 } else {
15649 generate_exception_err(ctx, EXCP_CpU, 1);
15650 }
15651 break;
15652 case POOL32I:
15653 minor = (ctx->opcode >> 21) & 0x1f;
15654 switch (minor) {
15655 case BLTZ:
9e8f441a 15656 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15657 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15658 break;
3c824109 15659 case BLTZAL:
9e8f441a 15660 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15661 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15662 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15663 break;
3c824109 15664 case BLTZALS:
9e8f441a 15665 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15666 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15667 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15668 break;
3c824109 15669 case BGEZ:
9e8f441a 15670 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15671 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15672 break;
3c824109 15673 case BGEZAL:
9e8f441a 15674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15675 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15676 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15677 break;
3c824109 15678 case BGEZALS:
9e8f441a 15679 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15680 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15681 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15682 break;
3c824109 15683 case BLEZ:
9e8f441a 15684 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15685 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15686 break;
3c824109 15687 case BGTZ:
9e8f441a 15688 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 15689 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
15690 break;
15691
15692 /* Traps */
65935f07
YK
15693 case TLTI: /* BC1EQZC */
15694 if (ctx->insn_flags & ISA_MIPS32R6) {
15695 /* BC1EQZC */
15696 check_cp1_enabled(ctx);
15697 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15698 } else {
15699 /* TLTI */
15700 mips32_op = OPC_TLTI;
15701 goto do_trapi;
15702 }
15703 break;
15704 case TGEI: /* BC1NEZC */
15705 if (ctx->insn_flags & ISA_MIPS32R6) {
15706 /* BC1NEZC */
15707 check_cp1_enabled(ctx);
15708 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15709 } else {
15710 /* TGEI */
15711 mips32_op = OPC_TGEI;
15712 goto do_trapi;
15713 }
15714 break;
3c824109 15715 case TLTIU:
9e8f441a 15716 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15717 mips32_op = OPC_TLTIU;
15718 goto do_trapi;
15719 case TGEIU:
9e8f441a 15720 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15721 mips32_op = OPC_TGEIU;
15722 goto do_trapi;
3b4a5489
YK
15723 case TNEI: /* SYNCI */
15724 if (ctx->insn_flags & ISA_MIPS32R6) {
15725 /* SYNCI */
15726 /* Break the TB to be able to sync copied instructions
15727 immediately */
eeb3bba8 15728 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
15729 } else {
15730 /* TNEI */
15731 mips32_op = OPC_TNEI;
15732 goto do_trapi;
15733 }
15734 break;
3c824109 15735 case TEQI:
9e8f441a 15736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15737 mips32_op = OPC_TEQI;
15738 do_trapi:
15739 gen_trap(ctx, mips32_op, rs, -1, imm);
15740 break;
15741
15742 case BNEZC:
15743 case BEQZC:
9e8f441a 15744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15745 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 15746 4, rs, 0, imm << 1, 0);
3c824109
NF
15747 /* Compact branches don't have a delay slot, so just let
15748 the normal delay slot handling take us to the branch
15749 target. */
15750 break;
15751 case LUI:
9e8f441a 15752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 15753 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
15754 break;
15755 case SYNCI:
9e8f441a 15756 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
15757 /* Break the TB to be able to sync copied instructions
15758 immediately */
eeb3bba8 15759 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15760 break;
15761 case BC2F:
15762 case BC2T:
9e8f441a 15763 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15764 /* COP2: Not implemented. */
15765 generate_exception_err(ctx, EXCP_CpU, 2);
15766 break;
15767 case BC1F:
9e8f441a 15768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15769 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15770 goto do_cp1branch;
15771 case BC1T:
9e8f441a 15772 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15773 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15774 goto do_cp1branch;
15775 case BC1ANY4F:
9e8f441a 15776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15777 mips32_op = OPC_BC1FANY4;
15778 goto do_cp1mips3d;
15779 case BC1ANY4T:
9e8f441a 15780 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15781 mips32_op = OPC_BC1TANY4;
15782 do_cp1mips3d:
15783 check_cop1x(ctx);
d75c135e 15784 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
15785 /* Fall through */
15786 do_cp1branch:
272f458d
MR
15787 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15788 check_cp1_enabled(ctx);
15789 gen_compute_branch1(ctx, mips32_op,
15790 (ctx->opcode >> 18) & 0x7, imm << 1);
15791 } else {
15792 generate_exception_err(ctx, EXCP_CpU, 1);
15793 }
3c824109
NF
15794 break;
15795 case BPOSGE64:
15796 case BPOSGE32:
15797 /* MIPS DSP: not implemented */
15798 /* Fall through */
15799 default:
15800 MIPS_INVAL("pool32i");
9c708c7f 15801 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15802 break;
15803 }
15804 break;
15805 case POOL32C:
15806 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
15807 offset = sextract32(ctx->opcode, 0,
15808 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
15809 switch (minor) {
15810 case LWL:
9e8f441a 15811 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15812 mips32_op = OPC_LWL;
5c13fdfd 15813 goto do_ld_lr;
3c824109 15814 case SWL:
9e8f441a 15815 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15816 mips32_op = OPC_SWL;
5c13fdfd 15817 goto do_st_lr;
3c824109 15818 case LWR:
9e8f441a 15819 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15820 mips32_op = OPC_LWR;
5c13fdfd 15821 goto do_ld_lr;
3c824109 15822 case SWR:
9e8f441a 15823 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15824 mips32_op = OPC_SWR;
5c13fdfd 15825 goto do_st_lr;
3c824109
NF
15826#if defined(TARGET_MIPS64)
15827 case LDL:
d9224450
MR
15828 check_insn(ctx, ISA_MIPS3);
15829 check_mips_64(ctx);
9e8f441a 15830 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15831 mips32_op = OPC_LDL;
5c13fdfd 15832 goto do_ld_lr;
3c824109 15833 case SDL:
d9224450
MR
15834 check_insn(ctx, ISA_MIPS3);
15835 check_mips_64(ctx);
9e8f441a 15836 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15837 mips32_op = OPC_SDL;
5c13fdfd 15838 goto do_st_lr;
3c824109 15839 case LDR:
d9224450
MR
15840 check_insn(ctx, ISA_MIPS3);
15841 check_mips_64(ctx);
9e8f441a 15842 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15843 mips32_op = OPC_LDR;
5c13fdfd 15844 goto do_ld_lr;
3c824109 15845 case SDR:
d9224450
MR
15846 check_insn(ctx, ISA_MIPS3);
15847 check_mips_64(ctx);
9e8f441a 15848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15849 mips32_op = OPC_SDR;
5c13fdfd 15850 goto do_st_lr;
3c824109 15851 case LWU:
d9224450
MR
15852 check_insn(ctx, ISA_MIPS3);
15853 check_mips_64(ctx);
3c824109 15854 mips32_op = OPC_LWU;
5c13fdfd 15855 goto do_ld_lr;
3c824109 15856 case LLD:
d9224450
MR
15857 check_insn(ctx, ISA_MIPS3);
15858 check_mips_64(ctx);
3c824109 15859 mips32_op = OPC_LLD;
5c13fdfd 15860 goto do_ld_lr;
3c824109
NF
15861#endif
15862 case LL:
15863 mips32_op = OPC_LL;
5c13fdfd
AJ
15864 goto do_ld_lr;
15865 do_ld_lr:
3b4a5489 15866 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
15867 break;
15868 do_st_lr:
8fffc646 15869 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
15870 break;
15871 case SC:
3b4a5489 15872 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
15873 break;
15874#if defined(TARGET_MIPS64)
15875 case SCD:
d9224450
MR
15876 check_insn(ctx, ISA_MIPS3);
15877 check_mips_64(ctx);
3b4a5489 15878 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
15879 break;
15880#endif
8fffc646
JH
15881 case LD_EVA:
15882 if (!ctx->eva) {
15883 MIPS_INVAL("pool32c ld-eva");
15884 generate_exception_end(ctx, EXCP_RI);
15885 break;
15886 }
15887 check_cp0_enabled(ctx);
15888
15889 minor2 = (ctx->opcode >> 9) & 0x7;
15890 offset = sextract32(ctx->opcode, 0, 9);
15891 switch (minor2) {
15892 case LBUE:
15893 mips32_op = OPC_LBUE;
15894 goto do_ld_lr;
15895 case LHUE:
15896 mips32_op = OPC_LHUE;
15897 goto do_ld_lr;
15898 case LWLE:
15899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15900 mips32_op = OPC_LWLE;
15901 goto do_ld_lr;
15902 case LWRE:
15903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15904 mips32_op = OPC_LWRE;
15905 goto do_ld_lr;
15906 case LBE:
15907 mips32_op = OPC_LBE;
15908 goto do_ld_lr;
15909 case LHE:
15910 mips32_op = OPC_LHE;
15911 goto do_ld_lr;
15912 case LLE:
15913 mips32_op = OPC_LLE;
15914 goto do_ld_lr;
15915 case LWE:
15916 mips32_op = OPC_LWE;
15917 goto do_ld_lr;
15918 };
15919 break;
15920 case ST_EVA:
15921 if (!ctx->eva) {
15922 MIPS_INVAL("pool32c st-eva");
15923 generate_exception_end(ctx, EXCP_RI);
15924 break;
15925 }
15926 check_cp0_enabled(ctx);
15927
15928 minor2 = (ctx->opcode >> 9) & 0x7;
15929 offset = sextract32(ctx->opcode, 0, 9);
15930 switch (minor2) {
15931 case SWLE:
15932 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15933 mips32_op = OPC_SWLE;
15934 goto do_st_lr;
15935 case SWRE:
15936 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15937 mips32_op = OPC_SWRE;
15938 goto do_st_lr;
15939 case PREFE:
15940 /* Treat as no-op */
15941 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15942 /* hint codes 24-31 are reserved and signal RI */
15943 generate_exception(ctx, EXCP_RI);
15944 }
15945 break;
15946 case CACHEE:
15947 /* Treat as no-op */
15948 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15949 gen_cache_operation(ctx, rt, rs, offset);
15950 }
15951 break;
15952 case SBE:
15953 mips32_op = OPC_SBE;
15954 goto do_st_lr;
15955 case SHE:
15956 mips32_op = OPC_SHE;
15957 goto do_st_lr;
15958 case SCE:
15959 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15960 break;
15961 case SWE:
15962 mips32_op = OPC_SWE;
15963 goto do_st_lr;
15964 };
15965 break;
3c824109
NF
15966 case PREF:
15967 /* Treat as no-op */
3b4a5489
YK
15968 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15969 /* hint codes 24-31 are reserved and signal RI */
15970 generate_exception(ctx, EXCP_RI);
15971 }
3c824109
NF
15972 break;
15973 default:
15974 MIPS_INVAL("pool32c");
9c708c7f 15975 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15976 break;
15977 }
15978 break;
ab39ee45
YK
15979 case ADDI32: /* AUI, LUI */
15980 if (ctx->insn_flags & ISA_MIPS32R6) {
15981 /* AUI, LUI */
15982 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15983 } else {
15984 /* ADDI32 */
15985 mips32_op = OPC_ADDI;
15986 goto do_addi;
15987 }
15988 break;
3c824109
NF
15989 case ADDIU32:
15990 mips32_op = OPC_ADDIU;
15991 do_addi:
d75c135e 15992 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15993 break;
15994
15995 /* Logical operations */
15996 case ORI32:
15997 mips32_op = OPC_ORI;
15998 goto do_logici;
15999 case XORI32:
16000 mips32_op = OPC_XORI;
16001 goto do_logici;
16002 case ANDI32:
16003 mips32_op = OPC_ANDI;
16004 do_logici:
d75c135e 16005 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16006 break;
16007
16008 /* Set less than immediate */
16009 case SLTI32:
16010 mips32_op = OPC_SLTI;
16011 goto do_slti;
16012 case SLTIU32:
16013 mips32_op = OPC_SLTIU;
16014 do_slti:
d75c135e 16015 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16016 break;
16017 case JALX32:
9e8f441a 16018 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16019 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
16020 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16021 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 16022 break;
65935f07
YK
16023 case JALS32: /* BOVC, BEQC, BEQZALC */
16024 if (ctx->insn_flags & ISA_MIPS32R6) {
16025 if (rs >= rt) {
16026 /* BOVC */
16027 mips32_op = OPC_BOVC;
16028 } else if (rs < rt && rs == 0) {
16029 /* BEQZALC */
16030 mips32_op = OPC_BEQZALC;
16031 } else {
16032 /* BEQC */
16033 mips32_op = OPC_BEQC;
16034 }
16035 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16036 } else {
16037 /* JALS32 */
16038 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16039 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16040 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16041 }
3c824109 16042 break;
65935f07
YK
16043 case BEQ32: /* BC */
16044 if (ctx->insn_flags & ISA_MIPS32R6) {
16045 /* BC */
16046 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16047 sextract32(ctx->opcode << 1, 0, 27));
16048 } else {
16049 /* BEQ32 */
16050 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16051 }
3c824109 16052 break;
65935f07
YK
16053 case BNE32: /* BALC */
16054 if (ctx->insn_flags & ISA_MIPS32R6) {
16055 /* BALC */
16056 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16057 sextract32(ctx->opcode << 1, 0, 27));
16058 } else {
16059 /* BNE32 */
16060 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16061 }
3c824109 16062 break;
65935f07
YK
16063 case J32: /* BGTZC, BLTZC, BLTC */
16064 if (ctx->insn_flags & ISA_MIPS32R6) {
16065 if (rs == 0 && rt != 0) {
16066 /* BGTZC */
16067 mips32_op = OPC_BGTZC;
16068 } else if (rs != 0 && rt != 0 && rs == rt) {
16069 /* BLTZC */
16070 mips32_op = OPC_BLTZC;
16071 } else {
16072 /* BLTC */
16073 mips32_op = OPC_BLTC;
16074 }
16075 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16076 } else {
16077 /* J32 */
16078 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16079 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16080 }
3c824109 16081 break;
65935f07
YK
16082 case JAL32: /* BLEZC, BGEZC, BGEC */
16083 if (ctx->insn_flags & ISA_MIPS32R6) {
16084 if (rs == 0 && rt != 0) {
16085 /* BLEZC */
16086 mips32_op = OPC_BLEZC;
16087 } else if (rs != 0 && rt != 0 && rs == rt) {
16088 /* BGEZC */
16089 mips32_op = OPC_BGEZC;
16090 } else {
16091 /* BGEC */
16092 mips32_op = OPC_BGEC;
16093 }
16094 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16095 } else {
16096 /* JAL32 */
16097 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16098 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16099 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16100 }
3c824109
NF
16101 break;
16102 /* Floating point (COP1) */
16103 case LWC132:
16104 mips32_op = OPC_LWC1;
16105 goto do_cop1;
16106 case LDC132:
16107 mips32_op = OPC_LDC1;
16108 goto do_cop1;
16109 case SWC132:
16110 mips32_op = OPC_SWC1;
16111 goto do_cop1;
16112 case SDC132:
16113 mips32_op = OPC_SDC1;
16114 do_cop1:
5ab5c041 16115 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 16116 break;
ab39ee45
YK
16117 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16118 if (ctx->insn_flags & ISA_MIPS32R6) {
16119 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16120 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
16121 case ADDIUPC_00:
16122 case ADDIUPC_01:
16123 case ADDIUPC_02:
16124 case ADDIUPC_03:
16125 case ADDIUPC_04:
16126 case ADDIUPC_05:
16127 case ADDIUPC_06:
16128 case ADDIUPC_07:
eeb3bba8 16129 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16130 break;
16131 case AUIPC:
eeb3bba8 16132 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
16133 break;
16134 case ALUIPC:
eeb3bba8 16135 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 16136 break;
c38a1d52
AR
16137 case LWPC_08:
16138 case LWPC_09:
16139 case LWPC_0A:
16140 case LWPC_0B:
16141 case LWPC_0C:
16142 case LWPC_0D:
16143 case LWPC_0E:
16144 case LWPC_0F:
eeb3bba8 16145 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16146 break;
16147 default:
16148 generate_exception(ctx, EXCP_RI);
16149 break;
16150 }
16151 } else {
16152 /* ADDIUPC */
3c824109 16153 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 16154 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
16155
16156 gen_addiupc(ctx, reg, offset, 0, 0);
16157 }
16158 break;
65935f07
YK
16159 case BNVC: /* BNEC, BNEZALC */
16160 check_insn(ctx, ISA_MIPS32R6);
16161 if (rs >= rt) {
16162 /* BNVC */
16163 mips32_op = OPC_BNVC;
16164 } else if (rs < rt && rs == 0) {
16165 /* BNEZALC */
16166 mips32_op = OPC_BNEZALC;
16167 } else {
16168 /* BNEC */
16169 mips32_op = OPC_BNEC;
16170 }
16171 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16172 break;
16173 case R6_BNEZC: /* JIALC */
16174 check_insn(ctx, ISA_MIPS32R6);
16175 if (rt != 0) {
16176 /* BNEZC */
16177 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16178 sextract32(ctx->opcode << 1, 0, 22));
16179 } else {
16180 /* JIALC */
16181 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16182 }
16183 break;
16184 case R6_BEQZC: /* JIC */
16185 check_insn(ctx, ISA_MIPS32R6);
16186 if (rt != 0) {
16187 /* BEQZC */
16188 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16189 sextract32(ctx->opcode << 1, 0, 22));
16190 } else {
16191 /* JIC */
16192 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16193 }
16194 break;
16195 case BLEZALC: /* BGEZALC, BGEUC */
16196 check_insn(ctx, ISA_MIPS32R6);
16197 if (rs == 0 && rt != 0) {
16198 /* BLEZALC */
16199 mips32_op = OPC_BLEZALC;
16200 } else if (rs != 0 && rt != 0 && rs == rt) {
16201 /* BGEZALC */
16202 mips32_op = OPC_BGEZALC;
16203 } else {
16204 /* BGEUC */
16205 mips32_op = OPC_BGEUC;
16206 }
16207 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16208 break;
16209 case BGTZALC: /* BLTZALC, BLTUC */
16210 check_insn(ctx, ISA_MIPS32R6);
16211 if (rs == 0 && rt != 0) {
16212 /* BGTZALC */
16213 mips32_op = OPC_BGTZALC;
16214 } else if (rs != 0 && rt != 0 && rs == rt) {
16215 /* BLTZALC */
16216 mips32_op = OPC_BLTZALC;
16217 } else {
16218 /* BLTUC */
16219 mips32_op = OPC_BLTUC;
16220 }
16221 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16222 break;
3c824109
NF
16223 /* Loads and stores */
16224 case LB32:
16225 mips32_op = OPC_LB;
5c13fdfd 16226 goto do_ld;
3c824109
NF
16227 case LBU32:
16228 mips32_op = OPC_LBU;
5c13fdfd 16229 goto do_ld;
3c824109
NF
16230 case LH32:
16231 mips32_op = OPC_LH;
5c13fdfd 16232 goto do_ld;
3c824109
NF
16233 case LHU32:
16234 mips32_op = OPC_LHU;
5c13fdfd 16235 goto do_ld;
3c824109
NF
16236 case LW32:
16237 mips32_op = OPC_LW;
5c13fdfd 16238 goto do_ld;
3c824109
NF
16239#ifdef TARGET_MIPS64
16240 case LD32:
d9224450
MR
16241 check_insn(ctx, ISA_MIPS3);
16242 check_mips_64(ctx);
3c824109 16243 mips32_op = OPC_LD;
5c13fdfd 16244 goto do_ld;
3c824109 16245 case SD32:
d9224450
MR
16246 check_insn(ctx, ISA_MIPS3);
16247 check_mips_64(ctx);
3c824109 16248 mips32_op = OPC_SD;
5c13fdfd 16249 goto do_st;
3c824109
NF
16250#endif
16251 case SB32:
16252 mips32_op = OPC_SB;
5c13fdfd 16253 goto do_st;
3c824109
NF
16254 case SH32:
16255 mips32_op = OPC_SH;
5c13fdfd 16256 goto do_st;
3c824109
NF
16257 case SW32:
16258 mips32_op = OPC_SW;
5c13fdfd
AJ
16259 goto do_st;
16260 do_ld:
d75c135e 16261 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
16262 break;
16263 do_st:
16264 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16265 break;
16266 default:
9c708c7f 16267 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16268 break;
16269 }
16270}
16271
240ce26a 16272static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
16273{
16274 uint32_t op;
16275
16276 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
16277 if (ctx->base.pc_next & 0x1) {
16278 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 16279 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
16280 return 2;
16281 }
16282
16283 op = (ctx->opcode >> 10) & 0x3f;
16284 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
16285 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16286 switch (op & 0x7) { /* MSB-3..MSB-5 */
16287 case 0:
16288 /* POOL32A, POOL32B, POOL32I, POOL32C */
16289 case 4:
16290 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16291 case 5:
16292 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16293 case 6:
16294 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16295 case 7:
16296 /* LB32, LH32, LWC132, LDC132, LW32 */
16297 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 16298 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16299 return 2;
16300 }
16301 break;
b231c103
YK
16302 case 1:
16303 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16304 case 2:
16305 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16306 case 3:
16307 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16308 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 16309 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16310 return 2;
16311 }
16312 break;
3c824109
NF
16313 }
16314 }
b231c103 16315
3c824109
NF
16316 switch (op) {
16317 case POOL16A:
16318 {
16319 int rd = mmreg(uMIPS_RD(ctx->opcode));
16320 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16321 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16322 uint32_t opc = 0;
16323
16324 switch (ctx->opcode & 0x1) {
16325 case ADDU16:
16326 opc = OPC_ADDU;
16327 break;
16328 case SUBU16:
16329 opc = OPC_SUBU;
16330 break;
16331 }
ed7ce6c0
YK
16332 if (ctx->insn_flags & ISA_MIPS32R6) {
16333 /* In the Release 6 the register number location in
16334 * the instruction encoding has changed.
16335 */
16336 gen_arith(ctx, opc, rs1, rd, rs2);
16337 } else {
16338 gen_arith(ctx, opc, rd, rs1, rs2);
16339 }
3c824109
NF
16340 }
16341 break;
16342 case POOL16B:
16343 {
16344 int rd = mmreg(uMIPS_RD(ctx->opcode));
16345 int rs = mmreg(uMIPS_RS(ctx->opcode));
16346 int amount = (ctx->opcode >> 1) & 0x7;
16347 uint32_t opc = 0;
16348 amount = amount == 0 ? 8 : amount;
16349
16350 switch (ctx->opcode & 0x1) {
16351 case SLL16:
16352 opc = OPC_SLL;
16353 break;
16354 case SRL16:
16355 opc = OPC_SRL;
16356 break;
16357 }
16358
d75c135e 16359 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
16360 }
16361 break;
16362 case POOL16C:
ed7ce6c0
YK
16363 if (ctx->insn_flags & ISA_MIPS32R6) {
16364 gen_pool16c_r6_insn(ctx);
16365 } else {
16366 gen_pool16c_insn(ctx);
16367 }
3c824109
NF
16368 break;
16369 case LWGP16:
16370 {
16371 int rd = mmreg(uMIPS_RD(ctx->opcode));
16372 int rb = 28; /* GP */
16373 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16374
d75c135e 16375 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16376 }
16377 break;
16378 case POOL16F:
9e8f441a 16379 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16380 if (ctx->opcode & 1) {
9c708c7f 16381 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16382 } else {
16383 /* MOVEP */
16384 int enc_dest = uMIPS_RD(ctx->opcode);
16385 int enc_rt = uMIPS_RS2(ctx->opcode);
16386 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 16387 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
16388 }
16389 break;
16390 case LBU16:
16391 {
16392 int rd = mmreg(uMIPS_RD(ctx->opcode));
16393 int rb = mmreg(uMIPS_RS(ctx->opcode));
16394 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16395 offset = (offset == 0xf ? -1 : offset);
16396
d75c135e 16397 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
16398 }
16399 break;
16400 case LHU16:
16401 {
16402 int rd = mmreg(uMIPS_RD(ctx->opcode));
16403 int rb = mmreg(uMIPS_RS(ctx->opcode));
16404 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16405
d75c135e 16406 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
16407 }
16408 break;
16409 case LWSP16:
16410 {
16411 int rd = (ctx->opcode >> 5) & 0x1f;
16412 int rb = 29; /* SP */
16413 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16414
d75c135e 16415 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16416 }
16417 break;
16418 case LW16:
16419 {
16420 int rd = mmreg(uMIPS_RD(ctx->opcode));
16421 int rb = mmreg(uMIPS_RS(ctx->opcode));
16422 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16423
d75c135e 16424 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
16425 }
16426 break;
16427 case SB16:
16428 {
16429 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16430 int rb = mmreg(uMIPS_RS(ctx->opcode));
16431 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16432
5c13fdfd 16433 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
16434 }
16435 break;
16436 case SH16:
16437 {
16438 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16439 int rb = mmreg(uMIPS_RS(ctx->opcode));
16440 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16441
5c13fdfd 16442 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
16443 }
16444 break;
16445 case SWSP16:
16446 {
16447 int rd = (ctx->opcode >> 5) & 0x1f;
16448 int rb = 29; /* SP */
16449 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16450
5c13fdfd 16451 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
16452 }
16453 break;
16454 case SW16:
16455 {
16456 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16457 int rb = mmreg(uMIPS_RS(ctx->opcode));
16458 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16459
5c13fdfd 16460 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
16461 }
16462 break;
16463 case MOVE16:
16464 {
16465 int rd = uMIPS_RD5(ctx->opcode);
16466 int rs = uMIPS_RS5(ctx->opcode);
16467
7215d7e7 16468 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
16469 }
16470 break;
16471 case ANDI16:
d75c135e 16472 gen_andi16(ctx);
3c824109
NF
16473 break;
16474 case POOL16D:
16475 switch (ctx->opcode & 0x1) {
16476 case ADDIUS5:
d75c135e 16477 gen_addius5(ctx);
3c824109
NF
16478 break;
16479 case ADDIUSP:
d75c135e 16480 gen_addiusp(ctx);
3c824109
NF
16481 break;
16482 }
16483 break;
16484 case POOL16E:
16485 switch (ctx->opcode & 0x1) {
16486 case ADDIUR2:
d75c135e 16487 gen_addiur2(ctx);
3c824109
NF
16488 break;
16489 case ADDIUR1SP:
d75c135e 16490 gen_addiur1sp(ctx);
3c824109
NF
16491 break;
16492 }
16493 break;
65935f07 16494 case B16: /* BC16 */
3c824109 16495 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
16496 sextract32(ctx->opcode, 0, 10) << 1,
16497 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 16498 break;
65935f07
YK
16499 case BNEZ16: /* BNEZC16 */
16500 case BEQZ16: /* BEQZC16 */
3c824109
NF
16501 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16502 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
16503 0, sextract32(ctx->opcode, 0, 7) << 1,
16504 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16505
3c824109
NF
16506 break;
16507 case LI16:
16508 {
16509 int reg = mmreg(uMIPS_RD(ctx->opcode));
16510 int imm = ZIMM(ctx->opcode, 0, 7);
16511
16512 imm = (imm == 0x7f ? -1 : imm);
16513 tcg_gen_movi_tl(cpu_gpr[reg], imm);
16514 }
16515 break;
3c824109 16516 case RES_29:
3c824109 16517 case RES_31:
3c824109 16518 case RES_39:
9c708c7f 16519 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16520 break;
16521 default:
f60eeb0c 16522 decode_micromips32_opc(env, ctx);
3c824109
NF
16523 return 4;
16524 }
16525
16526 return 2;
16527}
16528
261c95a0
YK
16529/*
16530 *
16531 * nanoMIPS opcodes
16532 *
16533 */
16534
16535/* MAJOR, P16, and P32 pools opcodes */
16536enum {
16537 NM_P_ADDIU = 0x00,
16538 NM_ADDIUPC = 0x01,
16539 NM_MOVE_BALC = 0x02,
16540 NM_P16_MV = 0x04,
16541 NM_LW16 = 0x05,
16542 NM_BC16 = 0x06,
16543 NM_P16_SR = 0x07,
16544
16545 NM_POOL32A = 0x08,
16546 NM_P_BAL = 0x0a,
16547 NM_P16_SHIFT = 0x0c,
16548 NM_LWSP16 = 0x0d,
16549 NM_BALC16 = 0x0e,
16550 NM_P16_4X4 = 0x0f,
16551
16552 NM_P_GP_W = 0x10,
16553 NM_P_GP_BH = 0x11,
16554 NM_P_J = 0x12,
16555 NM_P16C = 0x14,
16556 NM_LWGP16 = 0x15,
16557 NM_P16_LB = 0x17,
16558
16559 NM_P48I = 0x18,
16560 NM_P16_A1 = 0x1c,
16561 NM_LW4X4 = 0x1d,
16562 NM_P16_LH = 0x1f,
16563
16564 NM_P_U12 = 0x20,
16565 NM_P_LS_U12 = 0x21,
16566 NM_P_BR1 = 0x22,
16567 NM_P16_A2 = 0x24,
16568 NM_SW16 = 0x25,
16569 NM_BEQZC16 = 0x26,
16570
16571 NM_POOL32F = 0x28,
16572 NM_P_LS_S9 = 0x29,
16573 NM_P_BR2 = 0x2a,
16574
16575 NM_P16_ADDU = 0x2c,
16576 NM_SWSP16 = 0x2d,
16577 NM_BNEZC16 = 0x2e,
16578 NM_MOVEP = 0x2f,
16579
16580 NM_POOL32S = 0x30,
16581 NM_P_BRI = 0x32,
16582 NM_LI16 = 0x34,
16583 NM_SWGP16 = 0x35,
16584 NM_P16_BR = 0x36,
16585
16586 NM_P_LUI = 0x38,
16587 NM_ANDI16 = 0x3c,
16588 NM_SW4X4 = 0x3d,
16589 NM_MOVEPREV = 0x3f,
16590};
16591
16592/* POOL32A instruction pool */
16593enum {
16594 NM_POOL32A0 = 0x00,
16595 NM_SPECIAL2 = 0x01,
16596 NM_COP2_1 = 0x02,
16597 NM_UDI = 0x03,
16598 NM_POOL32A5 = 0x05,
16599 NM_POOL32A7 = 0x07,
16600};
16601
16602/* P.GP.W instruction pool */
16603enum {
16604 NM_ADDIUGP_W = 0x00,
16605 NM_LWGP = 0x02,
16606 NM_SWGP = 0x03,
16607};
16608
16609/* P48I instruction pool */
16610enum {
16611 NM_LI48 = 0x00,
16612 NM_ADDIU48 = 0x01,
16613 NM_ADDIUGP48 = 0x02,
16614 NM_ADDIUPC48 = 0x03,
16615 NM_LWPC48 = 0x0b,
16616 NM_SWPC48 = 0x0f,
16617};
16618
16619/* P.U12 instruction pool */
16620enum {
16621 NM_ORI = 0x00,
16622 NM_XORI = 0x01,
16623 NM_ANDI = 0x02,
16624 NM_P_SR = 0x03,
16625 NM_SLTI = 0x04,
16626 NM_SLTIU = 0x05,
16627 NM_SEQI = 0x06,
16628 NM_ADDIUNEG = 0x08,
16629 NM_P_SHIFT = 0x0c,
16630 NM_P_ROTX = 0x0d,
16631 NM_P_INS = 0x0e,
16632 NM_P_EXT = 0x0f,
16633};
16634
16635/* POOL32F instruction pool */
16636enum {
16637 NM_POOL32F_0 = 0x00,
16638 NM_POOL32F_3 = 0x03,
16639 NM_POOL32F_5 = 0x05,
16640};
16641
16642/* POOL32S instruction pool */
16643enum {
16644 NM_POOL32S_0 = 0x00,
16645 NM_POOL32S_4 = 0x04,
16646};
16647
16648/* P.LUI instruction pool */
16649enum {
16650 NM_LUI = 0x00,
16651 NM_ALUIPC = 0x01,
16652};
16653
16654/* P.GP.BH instruction pool */
16655enum {
16656 NM_LBGP = 0x00,
16657 NM_SBGP = 0x01,
16658 NM_LBUGP = 0x02,
16659 NM_ADDIUGP_B = 0x03,
16660 NM_P_GP_LH = 0x04,
16661 NM_P_GP_SH = 0x05,
16662 NM_P_GP_CP1 = 0x06,
16663};
16664
16665/* P.LS.U12 instruction pool */
16666enum {
16667 NM_LB = 0x00,
16668 NM_SB = 0x01,
16669 NM_LBU = 0x02,
16670 NM_P_PREFU12 = 0x03,
16671 NM_LH = 0x04,
16672 NM_SH = 0x05,
16673 NM_LHU = 0x06,
16674 NM_LWU = 0x07,
16675 NM_LW = 0x08,
16676 NM_SW = 0x09,
16677 NM_LWC1 = 0x0a,
16678 NM_SWC1 = 0x0b,
16679 NM_LDC1 = 0x0e,
16680 NM_SDC1 = 0x0f,
16681};
16682
16683/* P.LS.S9 instruction pool */
16684enum {
16685 NM_P_LS_S0 = 0x00,
16686 NM_P_LS_S1 = 0x01,
16687 NM_P_LS_E0 = 0x02,
16688 NM_P_LS_WM = 0x04,
16689 NM_P_LS_UAWM = 0x05,
16690};
16691
16692/* P.BAL instruction pool */
16693enum {
16694 NM_BC = 0x00,
16695 NM_BALC = 0x01,
16696};
16697
16698/* P.J instruction pool */
16699enum {
16700 NM_JALRC = 0x00,
16701 NM_JALRC_HB = 0x01,
16702 NM_P_BALRSC = 0x08,
16703};
16704
16705/* P.BR1 instruction pool */
16706enum {
16707 NM_BEQC = 0x00,
16708 NM_P_BR3A = 0x01,
16709 NM_BGEC = 0x02,
16710 NM_BGEUC = 0x03,
16711};
16712
16713/* P.BR2 instruction pool */
16714enum {
16715 NM_BNEC = 0x00,
16716 NM_BLTC = 0x02,
16717 NM_BLTUC = 0x03,
16718};
16719
16720/* P.BRI instruction pool */
16721enum {
16722 NM_BEQIC = 0x00,
16723 NM_BBEQZC = 0x01,
16724 NM_BGEIC = 0x02,
16725 NM_BGEIUC = 0x03,
16726 NM_BNEIC = 0x04,
16727 NM_BBNEZC = 0x05,
16728 NM_BLTIC = 0x06,
16729 NM_BLTIUC = 0x07,
16730};
16731
16732/* P16.SHIFT instruction pool */
16733enum {
16734 NM_SLL16 = 0x00,
16735 NM_SRL16 = 0x01,
16736};
16737
16738/* POOL16C instruction pool */
16739enum {
16740 NM_POOL16C_0 = 0x00,
16741 NM_LWXS16 = 0x01,
16742};
16743
16744/* P16.A1 instruction pool */
16745enum {
16746 NM_ADDIUR1SP = 0x01,
16747};
16748
16749/* P16.A2 instruction pool */
16750enum {
16751 NM_ADDIUR2 = 0x00,
16752 NM_P_ADDIURS5 = 0x01,
16753};
16754
16755/* P16.ADDU instruction pool */
16756enum {
16757 NM_ADDU16 = 0x00,
16758 NM_SUBU16 = 0x01,
16759};
16760
16761/* P16.SR instruction pool */
16762enum {
16763 NM_SAVE16 = 0x00,
16764 NM_RESTORE_JRC16 = 0x01,
16765};
16766
16767/* P16.4X4 instruction pool */
16768enum {
16769 NM_ADDU4X4 = 0x00,
16770 NM_MUL4X4 = 0x01,
16771};
16772
16773/* P16.LB instruction pool */
16774enum {
16775 NM_LB16 = 0x00,
16776 NM_SB16 = 0x01,
16777 NM_LBU16 = 0x02,
16778};
16779
16780/* P16.LH instruction pool */
16781enum {
16782 NM_LH16 = 0x00,
16783 NM_SH16 = 0x01,
16784 NM_LHU16 = 0x02,
16785};
16786
16787/* P.RI instruction pool */
16788enum {
16789 NM_SIGRIE = 0x00,
16790 NM_P_SYSCALL = 0x01,
16791 NM_BREAK = 0x02,
16792 NM_SDBBP = 0x03,
16793};
16794
16795/* POOL32A0 instruction pool */
16796enum {
16797 NM_P_TRAP = 0x00,
16798 NM_SEB = 0x01,
16799 NM_SLLV = 0x02,
16800 NM_MUL = 0x03,
16801 NM_MFC0 = 0x06,
16802 NM_MFHC0 = 0x07,
16803 NM_SEH = 0x09,
16804 NM_SRLV = 0x0a,
16805 NM_MUH = 0x0b,
16806 NM_MTC0 = 0x0e,
16807 NM_MTHC0 = 0x0f,
16808 NM_SRAV = 0x12,
16809 NM_MULU = 0x13,
16810 NM_ROTRV = 0x1a,
16811 NM_MUHU = 0x1b,
16812 NM_ADD = 0x22,
16813 NM_DIV = 0x23,
16814 NM_ADDU = 0x2a,
16815 NM_MOD = 0x2b,
16816 NM_SUB = 0x32,
16817 NM_DIVU = 0x33,
16818 NM_RDHWR = 0x38,
16819 NM_SUBU = 0x3a,
16820 NM_MODU = 0x3b,
16821 NM_P_CMOVE = 0x42,
16822 NM_FORK = 0x45,
16823 NM_MFTR = 0x46,
16824 NM_MFHTR = 0x47,
16825 NM_AND = 0x4a,
16826 NM_YIELD = 0x4d,
16827 NM_MTTR = 0x4e,
16828 NM_MTHTR = 0x4f,
16829 NM_OR = 0x52,
16830 NM_D_E_MT_VPE = 0x56,
16831 NM_NOR = 0x5a,
16832 NM_XOR = 0x62,
16833 NM_SLT = 0x6a,
16834 NM_P_SLTU = 0x72,
16835 NM_SOV = 0x7a,
16836};
16837
b3979b6f
SM
16838/* POOL32A5 instruction pool */
16839enum {
16840 NM_CMP_EQ_PH = 0x00,
16841 NM_CMP_LT_PH = 0x08,
16842 NM_CMP_LE_PH = 0x10,
16843 NM_CMPGU_EQ_QB = 0x18,
16844 NM_CMPGU_LT_QB = 0x20,
16845 NM_CMPGU_LE_QB = 0x28,
16846 NM_CMPGDU_EQ_QB = 0x30,
16847 NM_CMPGDU_LT_QB = 0x38,
16848 NM_CMPGDU_LE_QB = 0x40,
16849 NM_CMPU_EQ_QB = 0x48,
16850 NM_CMPU_LT_QB = 0x50,
16851 NM_CMPU_LE_QB = 0x58,
16852 NM_ADDQ_S_W = 0x60,
16853 NM_SUBQ_S_W = 0x68,
16854 NM_ADDSC = 0x70,
16855 NM_ADDWC = 0x78,
16856
16857 NM_ADDQ_S_PH = 0x01,
16858 NM_ADDQH_R_PH = 0x09,
16859 NM_ADDQH_R_W = 0x11,
16860 NM_ADDU_S_QB = 0x19,
16861 NM_ADDU_S_PH = 0x21,
16862 NM_ADDUH_R_QB = 0x29,
16863 NM_SHRAV_R_PH = 0x31,
16864 NM_SHRAV_R_QB = 0x39,
16865 NM_SUBQ_S_PH = 0x41,
16866 NM_SUBQH_R_PH = 0x49,
16867 NM_SUBQH_R_W = 0x51,
16868 NM_SUBU_S_QB = 0x59,
16869 NM_SUBU_S_PH = 0x61,
16870 NM_SUBUH_R_QB = 0x69,
16871 NM_SHLLV_S_PH = 0x71,
16872 NM_PRECR_SRA_R_PH_W = 0x79,
16873
16874 NM_MULEU_S_PH_QBL = 0x12,
16875 NM_MULEU_S_PH_QBR = 0x1a,
16876 NM_MULQ_RS_PH = 0x22,
16877 NM_MULQ_S_PH = 0x2a,
16878 NM_MULQ_RS_W = 0x32,
16879 NM_MULQ_S_W = 0x3a,
16880 NM_APPEND = 0x42,
16881 NM_MODSUB = 0x52,
16882 NM_SHRAV_R_W = 0x5a,
16883 NM_SHRLV_PH = 0x62,
16884 NM_SHRLV_QB = 0x6a,
16885 NM_SHLLV_QB = 0x72,
16886 NM_SHLLV_S_W = 0x7a,
16887
16888 NM_SHILO = 0x03,
16889
16890 NM_MULEQ_S_W_PHL = 0x04,
16891 NM_MULEQ_S_W_PHR = 0x0c,
16892
16893 NM_MUL_S_PH = 0x05,
16894 NM_PRECR_QB_PH = 0x0d,
16895 NM_PRECRQ_QB_PH = 0x15,
16896 NM_PRECRQ_PH_W = 0x1d,
16897 NM_PRECRQ_RS_PH_W = 0x25,
16898 NM_PRECRQU_S_QB_PH = 0x2d,
16899 NM_PACKRL_PH = 0x35,
16900 NM_PICK_QB = 0x3d,
16901 NM_PICK_PH = 0x45,
16902
16903 NM_SHRA_R_W = 0x5e,
16904 NM_SHRA_R_PH = 0x66,
16905 NM_SHLL_S_PH = 0x76,
16906 NM_SHLL_S_W = 0x7e,
16907
16908 NM_REPL_PH = 0x07
16909};
16910
261c95a0
YK
16911/* POOL32A7 instruction pool */
16912enum {
16913 NM_P_LSX = 0x00,
16914 NM_LSA = 0x01,
16915 NM_EXTW = 0x03,
16916 NM_POOL32AXF = 0x07,
16917};
16918
16919/* P.SR instruction pool */
16920enum {
16921 NM_PP_SR = 0x00,
16922 NM_P_SR_F = 0x01,
16923};
16924
16925/* P.SHIFT instruction pool */
16926enum {
16927 NM_P_SLL = 0x00,
16928 NM_SRL = 0x02,
16929 NM_SRA = 0x04,
16930 NM_ROTR = 0x06,
16931};
16932
16933/* P.ROTX instruction pool */
16934enum {
16935 NM_ROTX = 0x00,
16936};
16937
16938/* P.INS instruction pool */
16939enum {
16940 NM_INS = 0x00,
16941};
16942
16943/* P.EXT instruction pool */
16944enum {
16945 NM_EXT = 0x00,
16946};
16947
16948/* POOL32F_0 (fmt) instruction pool */
16949enum {
16950 NM_RINT_S = 0x04,
16951 NM_RINT_D = 0x44,
16952 NM_ADD_S = 0x06,
16953 NM_SELEQZ_S = 0x07,
16954 NM_SELEQZ_D = 0x47,
16955 NM_CLASS_S = 0x0c,
16956 NM_CLASS_D = 0x4c,
16957 NM_SUB_S = 0x0e,
16958 NM_SELNEZ_S = 0x0f,
16959 NM_SELNEZ_D = 0x4f,
16960 NM_MUL_S = 0x16,
16961 NM_SEL_S = 0x17,
16962 NM_SEL_D = 0x57,
16963 NM_DIV_S = 0x1e,
16964 NM_ADD_D = 0x26,
16965 NM_SUB_D = 0x2e,
16966 NM_MUL_D = 0x36,
16967 NM_MADDF_S = 0x37,
16968 NM_MADDF_D = 0x77,
16969 NM_DIV_D = 0x3e,
16970 NM_MSUBF_S = 0x3f,
16971 NM_MSUBF_D = 0x7f,
16972};
16973
16974/* POOL32F_3 instruction pool */
16975enum {
16976 NM_MIN_FMT = 0x00,
16977 NM_MAX_FMT = 0x01,
16978 NM_MINA_FMT = 0x04,
16979 NM_MAXA_FMT = 0x05,
16980 NM_POOL32FXF = 0x07,
16981};
16982
16983/* POOL32F_5 instruction pool */
16984enum {
16985 NM_CMP_CONDN_S = 0x00,
16986 NM_CMP_CONDN_D = 0x02,
16987};
16988
16989/* P.GP.LH instruction pool */
16990enum {
16991 NM_LHGP = 0x00,
16992 NM_LHUGP = 0x01,
16993};
16994
16995/* P.GP.SH instruction pool */
16996enum {
16997 NM_SHGP = 0x00,
16998};
16999
17000/* P.GP.CP1 instruction pool */
17001enum {
17002 NM_LWC1GP = 0x00,
17003 NM_SWC1GP = 0x01,
17004 NM_LDC1GP = 0x02,
17005 NM_SDC1GP = 0x03,
17006};
17007
17008/* P.LS.S0 instruction pool */
17009enum {
17010 NM_LBS9 = 0x00,
17011 NM_LHS9 = 0x04,
17012 NM_LWS9 = 0x08,
17013 NM_LDS9 = 0x0c,
17014
17015 NM_SBS9 = 0x01,
17016 NM_SHS9 = 0x05,
17017 NM_SWS9 = 0x09,
17018 NM_SDS9 = 0x0d,
17019
17020 NM_LBUS9 = 0x02,
17021 NM_LHUS9 = 0x06,
17022 NM_LWC1S9 = 0x0a,
17023 NM_LDC1S9 = 0x0e,
17024
17025 NM_P_PREFS9 = 0x03,
17026 NM_LWUS9 = 0x07,
17027 NM_SWC1S9 = 0x0b,
17028 NM_SDC1S9 = 0x0f,
17029};
17030
17031/* P.LS.S1 instruction pool */
17032enum {
17033 NM_ASET_ACLR = 0x02,
17034 NM_UALH = 0x04,
17035 NM_UASH = 0x05,
17036 NM_CACHE = 0x07,
17037 NM_P_LL = 0x0a,
17038 NM_P_SC = 0x0b,
17039};
17040
17041/* P.LS.WM instruction pool */
17042enum {
17043 NM_LWM = 0x00,
17044 NM_SWM = 0x01,
17045};
17046
17047/* P.LS.UAWM instruction pool */
17048enum {
17049 NM_UALWM = 0x00,
17050 NM_UASWM = 0x01,
17051};
17052
17053/* P.BR3A instruction pool */
17054enum {
17055 NM_BC1EQZC = 0x00,
17056 NM_BC1NEZC = 0x01,
17057 NM_BC2EQZC = 0x02,
17058 NM_BC2NEZC = 0x03,
17059 NM_BPOSGE32C = 0x04,
17060};
17061
17062/* P16.RI instruction pool */
17063enum {
17064 NM_P16_SYSCALL = 0x01,
17065 NM_BREAK16 = 0x02,
17066 NM_SDBBP16 = 0x03,
17067};
17068
17069/* POOL16C_0 instruction pool */
17070enum {
17071 NM_POOL16C_00 = 0x00,
17072};
17073
17074/* P16.JRC instruction pool */
17075enum {
17076 NM_JRC = 0x00,
17077 NM_JALRC16 = 0x01,
17078};
17079
17080/* P.SYSCALL instruction pool */
17081enum {
17082 NM_SYSCALL = 0x00,
17083 NM_HYPCALL = 0x01,
17084};
17085
17086/* P.TRAP instruction pool */
17087enum {
17088 NM_TEQ = 0x00,
17089 NM_TNE = 0x01,
17090};
17091
17092/* P.CMOVE instruction pool */
17093enum {
17094 NM_MOVZ = 0x00,
17095 NM_MOVN = 0x01,
17096};
17097
17098/* POOL32Axf instruction pool */
17099enum {
b3979b6f
SM
17100 NM_POOL32AXF_1 = 0x01,
17101 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
17102 NM_POOL32AXF_4 = 0x04,
17103 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
17104 NM_POOL32AXF_7 = 0x07,
17105};
17106
17107/* POOL32Axf_1 instruction pool */
17108enum {
17109 NM_POOL32AXF_1_0 = 0x00,
17110 NM_POOL32AXF_1_1 = 0x01,
17111 NM_POOL32AXF_1_3 = 0x03,
17112 NM_POOL32AXF_1_4 = 0x04,
17113 NM_POOL32AXF_1_5 = 0x05,
17114 NM_POOL32AXF_1_7 = 0x07,
17115};
17116
17117/* POOL32Axf_2 instruction pool */
17118enum {
17119 NM_POOL32AXF_2_0_7 = 0x00,
17120 NM_POOL32AXF_2_8_15 = 0x01,
17121 NM_POOL32AXF_2_16_23 = 0x02,
17122 NM_POOL32AXF_2_24_31 = 0x03,
17123};
17124
17125/* POOL32Axf_7 instruction pool */
17126enum {
17127 NM_SHRA_R_QB = 0x0,
17128 NM_SHRL_PH = 0x1,
17129 NM_REPL_QB = 0x2,
17130};
17131
17132/* POOL32Axf_1_0 instruction pool */
17133enum {
17134 NM_MFHI = 0x0,
17135 NM_MFLO = 0x1,
17136 NM_MTHI = 0x2,
17137 NM_MTLO = 0x3,
17138};
17139
17140/* POOL32Axf_1_1 instruction pool */
17141enum {
17142 NM_MTHLIP = 0x0,
17143 NM_SHILOV = 0x1,
17144};
17145
17146/* POOL32Axf_1_3 instruction pool */
17147enum {
17148 NM_RDDSP = 0x0,
17149 NM_WRDSP = 0x1,
17150 NM_EXTP = 0x2,
17151 NM_EXTPDP = 0x3,
17152};
17153
17154/* POOL32Axf_1_4 instruction pool */
17155enum {
17156 NM_SHLL_QB = 0x0,
17157 NM_SHRL_QB = 0x1,
17158};
17159
17160/* POOL32Axf_1_5 instruction pool */
17161enum {
17162 NM_MAQ_S_W_PHR = 0x0,
17163 NM_MAQ_S_W_PHL = 0x1,
17164 NM_MAQ_SA_W_PHR = 0x2,
17165 NM_MAQ_SA_W_PHL = 0x3,
17166};
17167
17168/* POOL32Axf_1_7 instruction pool */
17169enum {
17170 NM_EXTR_W = 0x0,
17171 NM_EXTR_R_W = 0x1,
17172 NM_EXTR_RS_W = 0x2,
17173 NM_EXTR_S_H = 0x3,
17174};
17175
17176/* POOL32Axf_2_0_7 instruction pool */
17177enum {
17178 NM_DPA_W_PH = 0x0,
17179 NM_DPAQ_S_W_PH = 0x1,
17180 NM_DPS_W_PH = 0x2,
17181 NM_DPSQ_S_W_PH = 0x3,
17182 NM_BALIGN = 0x4,
17183 NM_MADD = 0x5,
17184 NM_MULT = 0x6,
17185 NM_EXTRV_W = 0x7,
17186};
17187
17188/* POOL32Axf_2_8_15 instruction pool */
17189enum {
17190 NM_DPAX_W_PH = 0x0,
17191 NM_DPAQ_SA_L_W = 0x1,
17192 NM_DPSX_W_PH = 0x2,
17193 NM_DPSQ_SA_L_W = 0x3,
17194 NM_MADDU = 0x5,
17195 NM_MULTU = 0x6,
17196 NM_EXTRV_R_W = 0x7,
17197};
17198
17199/* POOL32Axf_2_16_23 instruction pool */
17200enum {
17201 NM_DPAU_H_QBL = 0x0,
17202 NM_DPAQX_S_W_PH = 0x1,
17203 NM_DPSU_H_QBL = 0x2,
17204 NM_DPSQX_S_W_PH = 0x3,
17205 NM_EXTPV = 0x4,
17206 NM_MSUB = 0x5,
17207 NM_MULSA_W_PH = 0x6,
17208 NM_EXTRV_RS_W = 0x7,
17209};
17210
17211/* POOL32Axf_2_24_31 instruction pool */
17212enum {
17213 NM_DPAU_H_QBR = 0x0,
17214 NM_DPAQX_SA_W_PH = 0x1,
17215 NM_DPSU_H_QBR = 0x2,
17216 NM_DPSQX_SA_W_PH = 0x3,
17217 NM_EXTPDPV = 0x4,
17218 NM_MSUBU = 0x5,
17219 NM_MULSAQ_S_W_PH = 0x6,
17220 NM_EXTRV_S_H = 0x7,
261c95a0
YK
17221};
17222
17223/* POOL32Axf_{4, 5} instruction pool */
17224enum {
17225 NM_CLO = 0x25,
17226 NM_CLZ = 0x2d,
17227
17228 NM_TLBP = 0x01,
17229 NM_TLBR = 0x09,
17230 NM_TLBWI = 0x11,
17231 NM_TLBWR = 0x19,
17232 NM_TLBINV = 0x03,
17233 NM_TLBINVF = 0x0b,
17234 NM_DI = 0x23,
17235 NM_EI = 0x2b,
17236 NM_RDPGPR = 0x70,
17237 NM_WRPGPR = 0x78,
17238 NM_WAIT = 0x61,
17239 NM_DERET = 0x71,
17240 NM_ERETX = 0x79,
b3979b6f
SM
17241
17242 /* nanoMIPS DSP instructions */
17243 NM_ABSQ_S_QB = 0x00,
17244 NM_ABSQ_S_PH = 0x08,
17245 NM_ABSQ_S_W = 0x10,
17246 NM_PRECEQ_W_PHL = 0x28,
17247 NM_PRECEQ_W_PHR = 0x30,
17248 NM_PRECEQU_PH_QBL = 0x38,
17249 NM_PRECEQU_PH_QBR = 0x48,
17250 NM_PRECEU_PH_QBL = 0x58,
17251 NM_PRECEU_PH_QBR = 0x68,
17252 NM_PRECEQU_PH_QBLA = 0x39,
17253 NM_PRECEQU_PH_QBRA = 0x49,
17254 NM_PRECEU_PH_QBLA = 0x59,
17255 NM_PRECEU_PH_QBRA = 0x69,
17256 NM_REPLV_PH = 0x01,
17257 NM_REPLV_QB = 0x09,
17258 NM_BITREV = 0x18,
17259 NM_INSV = 0x20,
17260 NM_RADDU_W_QB = 0x78,
17261
17262 NM_BITSWAP = 0x05,
17263 NM_WSBH = 0x3d,
261c95a0
YK
17264};
17265
17266/* PP.SR instruction pool */
17267enum {
17268 NM_SAVE = 0x00,
17269 NM_RESTORE = 0x02,
17270 NM_RESTORE_JRC = 0x03,
17271};
17272
17273/* P.SR.F instruction pool */
17274enum {
17275 NM_SAVEF = 0x00,
17276 NM_RESTOREF = 0x01,
17277};
17278
17279/* P16.SYSCALL instruction pool */
17280enum {
17281 NM_SYSCALL16 = 0x00,
17282 NM_HYPCALL16 = 0x01,
17283};
17284
17285/* POOL16C_00 instruction pool */
17286enum {
17287 NM_NOT16 = 0x00,
17288 NM_XOR16 = 0x01,
17289 NM_AND16 = 0x02,
17290 NM_OR16 = 0x03,
17291};
17292
17293/* PP.LSX and PP.LSXS instruction pool */
17294enum {
17295 NM_LBX = 0x00,
17296 NM_LHX = 0x04,
17297 NM_LWX = 0x08,
17298 NM_LDX = 0x0c,
17299
17300 NM_SBX = 0x01,
17301 NM_SHX = 0x05,
17302 NM_SWX = 0x09,
17303 NM_SDX = 0x0d,
17304
17305 NM_LBUX = 0x02,
17306 NM_LHUX = 0x06,
17307 NM_LWC1X = 0x0a,
17308 NM_LDC1X = 0x0e,
17309
17310 NM_LWUX = 0x07,
17311 NM_SWC1X = 0x0b,
17312 NM_SDC1X = 0x0f,
17313
17314 NM_LHXS = 0x04,
17315 NM_LWXS = 0x08,
17316 NM_LDXS = 0x0c,
17317
17318 NM_SHXS = 0x05,
17319 NM_SWXS = 0x09,
17320 NM_SDXS = 0x0d,
17321
17322 NM_LHUXS = 0x06,
17323 NM_LWC1XS = 0x0a,
17324 NM_LDC1XS = 0x0e,
17325
17326 NM_LWUXS = 0x07,
17327 NM_SWC1XS = 0x0b,
17328 NM_SDC1XS = 0x0f,
17329};
17330
17331/* ERETx instruction pool */
17332enum {
17333 NM_ERET = 0x00,
17334 NM_ERETNC = 0x01,
17335};
17336
17337/* POOL32FxF_{0, 1} insturction pool */
17338enum {
17339 NM_CFC1 = 0x40,
17340 NM_CTC1 = 0x60,
17341 NM_MFC1 = 0x80,
17342 NM_MTC1 = 0xa0,
17343 NM_MFHC1 = 0xc0,
17344 NM_MTHC1 = 0xe0,
17345
17346 NM_CVT_S_PL = 0x84,
17347 NM_CVT_S_PU = 0xa4,
17348
17349 NM_CVT_L_S = 0x004,
17350 NM_CVT_L_D = 0x104,
17351 NM_CVT_W_S = 0x024,
17352 NM_CVT_W_D = 0x124,
17353
17354 NM_RSQRT_S = 0x008,
17355 NM_RSQRT_D = 0x108,
17356
17357 NM_SQRT_S = 0x028,
17358 NM_SQRT_D = 0x128,
17359
17360 NM_RECIP_S = 0x048,
17361 NM_RECIP_D = 0x148,
17362
17363 NM_FLOOR_L_S = 0x00c,
17364 NM_FLOOR_L_D = 0x10c,
17365
17366 NM_FLOOR_W_S = 0x02c,
17367 NM_FLOOR_W_D = 0x12c,
17368
17369 NM_CEIL_L_S = 0x04c,
17370 NM_CEIL_L_D = 0x14c,
17371 NM_CEIL_W_S = 0x06c,
17372 NM_CEIL_W_D = 0x16c,
17373 NM_TRUNC_L_S = 0x08c,
17374 NM_TRUNC_L_D = 0x18c,
17375 NM_TRUNC_W_S = 0x0ac,
17376 NM_TRUNC_W_D = 0x1ac,
17377 NM_ROUND_L_S = 0x0cc,
17378 NM_ROUND_L_D = 0x1cc,
17379 NM_ROUND_W_S = 0x0ec,
17380 NM_ROUND_W_D = 0x1ec,
17381
17382 NM_MOV_S = 0x01,
17383 NM_MOV_D = 0x81,
17384 NM_ABS_S = 0x0d,
17385 NM_ABS_D = 0x8d,
17386 NM_NEG_S = 0x2d,
17387 NM_NEG_D = 0xad,
17388 NM_CVT_D_S = 0x04d,
17389 NM_CVT_D_W = 0x0cd,
17390 NM_CVT_D_L = 0x14d,
17391 NM_CVT_S_D = 0x06d,
17392 NM_CVT_S_W = 0x0ed,
17393 NM_CVT_S_L = 0x16d,
17394};
17395
17396/* P.LL instruction pool */
17397enum {
17398 NM_LL = 0x00,
17399 NM_LLWP = 0x01,
17400};
17401
17402/* P.SC instruction pool */
17403enum {
17404 NM_SC = 0x00,
17405 NM_SCWP = 0x01,
17406};
17407
17408/* P.DVP instruction pool */
17409enum {
17410 NM_DVP = 0x00,
17411 NM_EVP = 0x01,
17412};
17413
c533c0f4
AM
17414
17415/*
17416 *
17417 * nanoMIPS decoding engine
17418 *
17419 */
17420
6bfa9f4c
AM
17421
17422/* extraction utilities */
17423
17424#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17425#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17426#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17427#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17428#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17429#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17430
ea4ca3c2
YK
17431/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17432static inline int decode_gpr_gpr3(int r)
17433{
17434 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17435
17436 return map[r & 0x7];
17437}
17438
8bdb7029
YK
17439/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17440static inline int decode_gpr_gpr3_src_store(int r)
17441{
17442 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17443
17444 return map[r & 0x7];
17445}
17446
ea4ca3c2
YK
17447/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17448static inline int decode_gpr_gpr4(int r)
17449{
17450 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17451 16, 17, 18, 19, 20, 21, 22, 23 };
17452
17453 return map[r & 0xf];
17454}
17455
8bdb7029
YK
17456/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17457static inline int decode_gpr_gpr4_zero(int r)
17458{
17459 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17460 16, 17, 18, 19, 20, 21, 22, 23 };
17461
17462 return map[r & 0xf];
17463}
17464
6bfa9f4c 17465
80845edf
YK
17466/* extraction utilities */
17467
17468#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17469#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17470#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17471#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17472#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17473#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17474
17475
bf0718c5
SM
17476static void gen_adjust_sp(DisasContext *ctx, int u)
17477{
17478 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17479}
17480
17481static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17482 uint8_t gp, uint16_t u)
17483{
17484 int counter = 0;
17485 TCGv va = tcg_temp_new();
17486 TCGv t0 = tcg_temp_new();
17487
17488 while (counter != count) {
17489 bool use_gp = gp && (counter == count - 1);
17490 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17491 int this_offset = -((counter + 1) << 2);
17492 gen_base_offset_addr(ctx, va, 29, this_offset);
17493 gen_load_gpr(t0, this_rt);
17494 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17495 (MO_TEUL | ctx->default_tcg_memop_mask));
17496 counter++;
17497 }
17498
17499 /* adjust stack pointer */
17500 gen_adjust_sp(ctx, -u);
17501
17502 tcg_temp_free(t0);
17503 tcg_temp_free(va);
17504}
17505
17506static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17507 uint8_t gp, uint16_t u)
17508{
17509 int counter = 0;
17510 TCGv va = tcg_temp_new();
17511 TCGv t0 = tcg_temp_new();
17512
17513 while (counter != count) {
17514 bool use_gp = gp && (counter == count - 1);
17515 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17516 int this_offset = u - ((counter + 1) << 2);
17517 gen_base_offset_addr(ctx, va, 29, this_offset);
17518 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17519 ctx->default_tcg_memop_mask);
17520 tcg_gen_ext32s_tl(t0, t0);
17521 gen_store_gpr(t0, this_rt);
17522 counter++;
17523 }
17524
17525 /* adjust stack pointer */
17526 gen_adjust_sp(ctx, u);
17527
17528 tcg_temp_free(t0);
17529 tcg_temp_free(va);
17530}
17531
80845edf
YK
17532static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17533{
17534 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17535 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17536
17537 switch (extract32(ctx->opcode, 2, 2)) {
17538 case NM_NOT16:
17539 gen_logic(ctx, OPC_NOR, rt, rs, 0);
17540 break;
17541 case NM_AND16:
17542 gen_logic(ctx, OPC_AND, rt, rt, rs);
17543 break;
17544 case NM_XOR16:
17545 gen_logic(ctx, OPC_XOR, rt, rt, rs);
17546 break;
17547 case NM_OR16:
17548 gen_logic(ctx, OPC_OR, rt, rt, rs);
17549 break;
17550 }
17551}
17552
0a1a6ed7 17553static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
17554{
17555 int rt = extract32(ctx->opcode, 21, 5);
17556 int rs = extract32(ctx->opcode, 16, 5);
17557 int rd = extract32(ctx->opcode, 11, 5);
17558
17559 switch (extract32(ctx->opcode, 3, 7)) {
17560 case NM_P_TRAP:
17561 switch (extract32(ctx->opcode, 10, 1)) {
17562 case NM_TEQ:
fb32f8c8 17563 check_nms(ctx);
e0cf0e65
YK
17564 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17565 break;
17566 case NM_TNE:
fb32f8c8 17567 check_nms(ctx);
e0cf0e65
YK
17568 gen_trap(ctx, OPC_TNE, rs, rt, -1);
17569 break;
17570 }
17571 break;
17572 case NM_RDHWR:
fb32f8c8 17573 check_nms(ctx);
e0cf0e65
YK
17574 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17575 break;
17576 case NM_SEB:
fb32f8c8 17577 check_nms(ctx);
e0cf0e65
YK
17578 gen_bshfl(ctx, OPC_SEB, rs, rt);
17579 break;
17580 case NM_SEH:
17581 gen_bshfl(ctx, OPC_SEH, rs, rt);
17582 break;
17583 case NM_SLLV:
17584 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17585 break;
17586 case NM_SRLV:
17587 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17588 break;
17589 case NM_SRAV:
17590 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17591 break;
17592 case NM_ROTRV:
17593 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17594 break;
17595 case NM_ADD:
17596 gen_arith(ctx, OPC_ADD, rd, rs, rt);
17597 break;
17598 case NM_ADDU:
17599 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17600 break;
17601 case NM_SUB:
fb32f8c8 17602 check_nms(ctx);
e0cf0e65
YK
17603 gen_arith(ctx, OPC_SUB, rd, rs, rt);
17604 break;
17605 case NM_SUBU:
17606 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17607 break;
17608 case NM_P_CMOVE:
17609 switch (extract32(ctx->opcode, 10, 1)) {
17610 case NM_MOVZ:
17611 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17612 break;
17613 case NM_MOVN:
17614 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17615 break;
17616 }
17617 break;
17618 case NM_AND:
17619 gen_logic(ctx, OPC_AND, rd, rs, rt);
17620 break;
17621 case NM_OR:
17622 gen_logic(ctx, OPC_OR, rd, rs, rt);
17623 break;
17624 case NM_NOR:
17625 gen_logic(ctx, OPC_NOR, rd, rs, rt);
17626 break;
17627 case NM_XOR:
17628 gen_logic(ctx, OPC_XOR, rd, rs, rt);
17629 break;
17630 case NM_SLT:
17631 gen_slt(ctx, OPC_SLT, rd, rs, rt);
17632 break;
17633 case NM_P_SLTU:
17634 if (rd == 0) {
17635 /* P_DVP */
17636#ifndef CONFIG_USER_ONLY
17637 TCGv t0 = tcg_temp_new();
17638 switch (extract32(ctx->opcode, 10, 1)) {
17639 case NM_DVP:
17640 if (ctx->vp) {
17641 check_cp0_enabled(ctx);
17642 gen_helper_dvp(t0, cpu_env);
17643 gen_store_gpr(t0, rt);
17644 }
17645 break;
17646 case NM_EVP:
17647 if (ctx->vp) {
17648 check_cp0_enabled(ctx);
17649 gen_helper_evp(t0, cpu_env);
17650 gen_store_gpr(t0, rt);
17651 }
17652 break;
17653 }
17654 tcg_temp_free(t0);
17655#endif
17656 } else {
17657 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17658 }
17659 break;
17660 case NM_SOV:
17661 {
17662 TCGv t0 = tcg_temp_new();
17663 TCGv t1 = tcg_temp_new();
17664 TCGv t2 = tcg_temp_new();
17665
17666 gen_load_gpr(t1, rs);
17667 gen_load_gpr(t2, rt);
17668 tcg_gen_add_tl(t0, t1, t2);
17669 tcg_gen_ext32s_tl(t0, t0);
17670 tcg_gen_xor_tl(t1, t1, t2);
17671 tcg_gen_xor_tl(t2, t0, t2);
17672 tcg_gen_andc_tl(t1, t2, t1);
17673
17674 /* operands of same sign, result different sign */
17675 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17676 gen_store_gpr(t0, rd);
17677
17678 tcg_temp_free(t0);
17679 tcg_temp_free(t1);
17680 tcg_temp_free(t2);
17681 }
17682 break;
17683 case NM_MUL:
17684 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17685 break;
17686 case NM_MUH:
17687 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17688 break;
17689 case NM_MULU:
17690 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17691 break;
17692 case NM_MUHU:
17693 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17694 break;
17695 case NM_DIV:
17696 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17697 break;
17698 case NM_MOD:
17699 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17700 break;
17701 case NM_DIVU:
17702 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17703 break;
17704 case NM_MODU:
17705 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17706 break;
17707#ifndef CONFIG_USER_ONLY
17708 case NM_MFC0:
17709 check_cp0_enabled(ctx);
17710 if (rt == 0) {
17711 /* Treat as NOP. */
17712 break;
17713 }
17714 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17715 break;
17716 case NM_MTC0:
17717 check_cp0_enabled(ctx);
17718 {
17719 TCGv t0 = tcg_temp_new();
17720
17721 gen_load_gpr(t0, rt);
17722 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17723 tcg_temp_free(t0);
17724 }
17725 break;
0a1a6ed7
SM
17726 case NM_D_E_MT_VPE:
17727 {
17728 uint8_t sc = extract32(ctx->opcode, 10, 1);
17729 TCGv t0 = tcg_temp_new();
17730
17731 switch (sc) {
17732 case 0:
17733 if (rs == 1) {
17734 /* DMT */
17735 check_cp0_mt(ctx);
17736 gen_helper_dmt(t0);
17737 gen_store_gpr(t0, rt);
17738 } else if (rs == 0) {
17739 /* DVPE */
17740 check_cp0_mt(ctx);
17741 gen_helper_dvpe(t0, cpu_env);
17742 gen_store_gpr(t0, rt);
17743 } else {
17744 generate_exception_end(ctx, EXCP_RI);
17745 }
17746 break;
17747 case 1:
17748 if (rs == 1) {
17749 /* EMT */
17750 check_cp0_mt(ctx);
17751 gen_helper_emt(t0);
17752 gen_store_gpr(t0, rt);
17753 } else if (rs == 0) {
17754 /* EVPE */
17755 check_cp0_mt(ctx);
17756 gen_helper_evpe(t0, cpu_env);
17757 gen_store_gpr(t0, rt);
17758 } else {
17759 generate_exception_end(ctx, EXCP_RI);
17760 }
17761 break;
17762 }
17763
17764 tcg_temp_free(t0);
17765 }
17766 break;
17767 case NM_FORK:
17768 check_mt(ctx);
17769 {
17770 TCGv t0 = tcg_temp_new();
17771 TCGv t1 = tcg_temp_new();
17772
17773 gen_load_gpr(t0, rt);
17774 gen_load_gpr(t1, rs);
17775 gen_helper_fork(t0, t1);
17776 tcg_temp_free(t0);
17777 tcg_temp_free(t1);
17778 }
17779 break;
17780 case NM_MFTR:
17781 case NM_MFHTR:
17782 check_cp0_enabled(ctx);
17783 if (rd == 0) {
17784 /* Treat as NOP. */
17785 return;
17786 }
17787 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17788 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17789 break;
17790 case NM_MTTR:
17791 case NM_MTHTR:
17792 check_cp0_enabled(ctx);
17793 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17794 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17795 break;
17796 case NM_YIELD:
17797 check_mt(ctx);
17798 {
17799 TCGv t0 = tcg_temp_new();
17800
17801 gen_load_gpr(t0, rs);
17802 gen_helper_yield(t0, cpu_env, t0);
17803 gen_store_gpr(t0, rt);
17804 tcg_temp_free(t0);
17805 }
17806 break;
e0cf0e65
YK
17807#endif
17808 default:
17809 generate_exception_end(ctx, EXCP_RI);
17810 break;
17811 }
17812}
17813
2ed42efa
SM
17814/* dsp */
17815static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17816 int ret, int v1, int v2)
17817{
17818 TCGv_i32 t0;
17819 TCGv v0_t;
17820 TCGv v1_t;
17821
17822 t0 = tcg_temp_new_i32();
17823
17824 v0_t = tcg_temp_new();
17825 v1_t = tcg_temp_new();
17826
17827 tcg_gen_movi_i32(t0, v2 >> 3);
17828
17829 gen_load_gpr(v0_t, ret);
17830 gen_load_gpr(v1_t, v1);
17831
17832 switch (opc) {
17833 case NM_MAQ_S_W_PHR:
17834 check_dsp(ctx);
17835 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17836 break;
17837 case NM_MAQ_S_W_PHL:
17838 check_dsp(ctx);
17839 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17840 break;
17841 case NM_MAQ_SA_W_PHR:
17842 check_dsp(ctx);
17843 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17844 break;
17845 case NM_MAQ_SA_W_PHL:
17846 check_dsp(ctx);
17847 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17848 break;
17849 default:
17850 generate_exception_end(ctx, EXCP_RI);
17851 break;
17852 }
17853
17854 tcg_temp_free_i32(t0);
17855
17856 tcg_temp_free(v0_t);
17857 tcg_temp_free(v1_t);
17858}
17859
17860
17861static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17862 int ret, int v1, int v2)
17863{
17864 int16_t imm;
17865 TCGv t0 = tcg_temp_new();
17866 TCGv t1 = tcg_temp_new();
17867 TCGv v0_t = tcg_temp_new();
17868
17869 gen_load_gpr(v0_t, v1);
17870
17871 switch (opc) {
17872 case NM_POOL32AXF_1_0:
17873 check_dsp(ctx);
17874 switch (extract32(ctx->opcode, 12, 2)) {
17875 case NM_MFHI:
17876 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
17877 break;
17878 case NM_MFLO:
17879 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
17880 break;
17881 case NM_MTHI:
17882 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
17883 break;
17884 case NM_MTLO:
17885 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
17886 break;
17887 }
17888 break;
17889 case NM_POOL32AXF_1_1:
17890 check_dsp(ctx);
17891 switch (extract32(ctx->opcode, 12, 2)) {
17892 case NM_MTHLIP:
17893 tcg_gen_movi_tl(t0, v2);
17894 gen_helper_mthlip(t0, v0_t, cpu_env);
17895 break;
17896 case NM_SHILOV:
17897 tcg_gen_movi_tl(t0, v2 >> 3);
17898 gen_helper_shilo(t0, v0_t, cpu_env);
17899 break;
17900 default:
17901 generate_exception_end(ctx, EXCP_RI);
17902 break;
17903 }
17904 break;
17905 case NM_POOL32AXF_1_3:
17906 check_dsp(ctx);
17907 imm = extract32(ctx->opcode, 14, 7);
17908 switch (extract32(ctx->opcode, 12, 2)) {
17909 case NM_RDDSP:
17910 tcg_gen_movi_tl(t0, imm);
17911 gen_helper_rddsp(t0, t0, cpu_env);
17912 gen_store_gpr(t0, ret);
17913 break;
17914 case NM_WRDSP:
17915 gen_load_gpr(t0, ret);
17916 tcg_gen_movi_tl(t1, imm);
17917 gen_helper_wrdsp(t0, t1, cpu_env);
17918 break;
17919 case NM_EXTP:
17920 tcg_gen_movi_tl(t0, v2 >> 3);
17921 tcg_gen_movi_tl(t1, v1);
17922 gen_helper_extp(t0, t0, t1, cpu_env);
17923 gen_store_gpr(t0, ret);
17924 break;
17925 case NM_EXTPDP:
17926 tcg_gen_movi_tl(t0, v2 >> 3);
17927 tcg_gen_movi_tl(t1, v1);
17928 gen_helper_extpdp(t0, t0, t1, cpu_env);
17929 gen_store_gpr(t0, ret);
17930 break;
17931 }
17932 break;
17933 case NM_POOL32AXF_1_4:
17934 check_dsp(ctx);
17935 tcg_gen_movi_tl(t0, v2 >> 2);
17936 switch (extract32(ctx->opcode, 12, 1)) {
17937 case NM_SHLL_QB:
17938 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
17939 gen_store_gpr(t0, ret);
17940 break;
17941 case NM_SHRL_QB:
17942 gen_helper_shrl_qb(t0, t0, v0_t);
17943 gen_store_gpr(t0, ret);
17944 break;
17945 }
17946 break;
17947 case NM_POOL32AXF_1_5:
17948 opc = extract32(ctx->opcode, 12, 2);
17949 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
17950 break;
17951 case NM_POOL32AXF_1_7:
17952 check_dsp(ctx);
17953 tcg_gen_movi_tl(t0, v2 >> 3);
17954 tcg_gen_movi_tl(t1, v1);
17955 switch (extract32(ctx->opcode, 12, 2)) {
17956 case NM_EXTR_W:
17957 gen_helper_extr_w(t0, t0, t1, cpu_env);
17958 gen_store_gpr(t0, ret);
17959 break;
17960 case NM_EXTR_R_W:
17961 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
17962 gen_store_gpr(t0, ret);
17963 break;
17964 case NM_EXTR_RS_W:
17965 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
17966 gen_store_gpr(t0, ret);
17967 break;
17968 case NM_EXTR_S_H:
17969 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
17970 gen_store_gpr(t0, ret);
17971 break;
17972 }
17973 break;
17974 default:
17975 generate_exception_end(ctx, EXCP_RI);
17976 break;
17977 }
17978
17979 tcg_temp_free(t0);
17980 tcg_temp_free(t1);
17981 tcg_temp_free(v0_t);
17982}
17983
8b3698b2
SM
17984static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
17985 TCGv v0, TCGv v1, int rd)
17986{
17987 TCGv_i32 t0;
17988
17989 t0 = tcg_temp_new_i32();
17990
17991 tcg_gen_movi_i32(t0, rd >> 3);
17992
17993 switch (opc) {
17994 case NM_POOL32AXF_2_0_7:
17995 switch (extract32(ctx->opcode, 9, 3)) {
17996 case NM_DPA_W_PH:
908f6be1 17997 check_dsp_r2(ctx);
8b3698b2
SM
17998 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
17999 break;
18000 case NM_DPAQ_S_W_PH:
18001 check_dsp(ctx);
18002 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18003 break;
18004 case NM_DPS_W_PH:
908f6be1 18005 check_dsp_r2(ctx);
8b3698b2
SM
18006 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18007 break;
18008 case NM_DPSQ_S_W_PH:
18009 check_dsp(ctx);
18010 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18011 break;
18012 default:
18013 generate_exception_end(ctx, EXCP_RI);
18014 break;
18015 }
18016 break;
18017 case NM_POOL32AXF_2_8_15:
18018 switch (extract32(ctx->opcode, 9, 3)) {
18019 case NM_DPAX_W_PH:
908f6be1 18020 check_dsp_r2(ctx);
8b3698b2
SM
18021 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18022 break;
18023 case NM_DPAQ_SA_L_W:
18024 check_dsp(ctx);
18025 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18026 break;
18027 case NM_DPSX_W_PH:
908f6be1 18028 check_dsp_r2(ctx);
8b3698b2
SM
18029 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18030 break;
18031 case NM_DPSQ_SA_L_W:
18032 check_dsp(ctx);
18033 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18034 break;
18035 default:
18036 generate_exception_end(ctx, EXCP_RI);
18037 break;
18038 }
18039 break;
18040 case NM_POOL32AXF_2_16_23:
18041 switch (extract32(ctx->opcode, 9, 3)) {
18042 case NM_DPAU_H_QBL:
18043 check_dsp(ctx);
18044 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18045 break;
18046 case NM_DPAQX_S_W_PH:
908f6be1 18047 check_dsp_r2(ctx);
8b3698b2
SM
18048 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18049 break;
18050 case NM_DPSU_H_QBL:
18051 check_dsp(ctx);
18052 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18053 break;
18054 case NM_DPSQX_S_W_PH:
908f6be1 18055 check_dsp_r2(ctx);
8b3698b2
SM
18056 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18057 break;
18058 case NM_MULSA_W_PH:
908f6be1 18059 check_dsp_r2(ctx);
8b3698b2
SM
18060 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18061 break;
18062 default:
18063 generate_exception_end(ctx, EXCP_RI);
18064 break;
18065 }
18066 break;
18067 case NM_POOL32AXF_2_24_31:
18068 switch (extract32(ctx->opcode, 9, 3)) {
18069 case NM_DPAU_H_QBR:
18070 check_dsp(ctx);
18071 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18072 break;
18073 case NM_DPAQX_SA_W_PH:
908f6be1 18074 check_dsp_r2(ctx);
8b3698b2
SM
18075 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18076 break;
18077 case NM_DPSU_H_QBR:
18078 check_dsp(ctx);
18079 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18080 break;
18081 case NM_DPSQX_SA_W_PH:
908f6be1 18082 check_dsp_r2(ctx);
8b3698b2
SM
18083 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18084 break;
18085 case NM_MULSAQ_S_W_PH:
18086 check_dsp(ctx);
18087 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18088 break;
18089 default:
18090 generate_exception_end(ctx, EXCP_RI);
18091 break;
18092 }
18093 break;
18094 default:
18095 generate_exception_end(ctx, EXCP_RI);
18096 break;
18097 }
18098
18099 tcg_temp_free_i32(t0);
18100}
18101
18102static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18103 int rt, int rs, int rd)
18104{
18105 int ret = rt;
18106 TCGv t0 = tcg_temp_new();
18107 TCGv t1 = tcg_temp_new();
18108 TCGv v0_t = tcg_temp_new();
18109 TCGv v1_t = tcg_temp_new();
18110
18111 gen_load_gpr(v0_t, rt);
18112 gen_load_gpr(v1_t, rs);
18113
18114 switch (opc) {
18115 case NM_POOL32AXF_2_0_7:
18116 switch (extract32(ctx->opcode, 9, 3)) {
18117 case NM_DPA_W_PH:
18118 case NM_DPAQ_S_W_PH:
18119 case NM_DPS_W_PH:
18120 case NM_DPSQ_S_W_PH:
18121 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18122 break;
18123 case NM_BALIGN:
908f6be1 18124 check_dsp_r2(ctx);
8b3698b2
SM
18125 if (rt != 0) {
18126 gen_load_gpr(t0, rs);
18127 rd &= 3;
18128 if (rd != 0 && rd != 2) {
18129 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18130 tcg_gen_ext32u_tl(t0, t0);
18131 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18132 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18133 }
18134 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18135 }
18136 break;
18137 case NM_MADD:
18138 check_dsp(ctx);
18139 {
18140 int acc = extract32(ctx->opcode, 14, 2);
18141 TCGv_i64 t2 = tcg_temp_new_i64();
18142 TCGv_i64 t3 = tcg_temp_new_i64();
18143
18144 gen_load_gpr(t0, rt);
18145 gen_load_gpr(t1, rs);
18146 tcg_gen_ext_tl_i64(t2, t0);
18147 tcg_gen_ext_tl_i64(t3, t1);
18148 tcg_gen_mul_i64(t2, t2, t3);
18149 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18150 tcg_gen_add_i64(t2, t2, t3);
18151 tcg_temp_free_i64(t3);
18152 gen_move_low32(cpu_LO[acc], t2);
18153 gen_move_high32(cpu_HI[acc], t2);
18154 tcg_temp_free_i64(t2);
18155 }
18156 break;
18157 case NM_MULT:
18158 check_dsp(ctx);
18159 {
18160 int acc = extract32(ctx->opcode, 14, 2);
18161 TCGv_i32 t2 = tcg_temp_new_i32();
18162 TCGv_i32 t3 = tcg_temp_new_i32();
18163
18164 gen_load_gpr(t0, rs);
18165 gen_load_gpr(t1, rt);
18166 tcg_gen_trunc_tl_i32(t2, t0);
18167 tcg_gen_trunc_tl_i32(t3, t1);
18168 tcg_gen_muls2_i32(t2, t3, t2, t3);
18169 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18170 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18171 tcg_temp_free_i32(t2);
18172 tcg_temp_free_i32(t3);
18173 }
18174 break;
18175 case NM_EXTRV_W:
18176 check_dsp(ctx);
18177 gen_load_gpr(v1_t, rs);
18178 tcg_gen_movi_tl(t0, rd >> 3);
18179 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18180 gen_store_gpr(t0, ret);
18181 break;
18182 }
18183 break;
18184 case NM_POOL32AXF_2_8_15:
18185 switch (extract32(ctx->opcode, 9, 3)) {
18186 case NM_DPAX_W_PH:
18187 case NM_DPAQ_SA_L_W:
18188 case NM_DPSX_W_PH:
18189 case NM_DPSQ_SA_L_W:
18190 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18191 break;
18192 case NM_MADDU:
18193 check_dsp(ctx);
18194 {
18195 int acc = extract32(ctx->opcode, 14, 2);
18196 TCGv_i64 t2 = tcg_temp_new_i64();
18197 TCGv_i64 t3 = tcg_temp_new_i64();
18198
18199 gen_load_gpr(t0, rs);
18200 gen_load_gpr(t1, rt);
18201 tcg_gen_ext32u_tl(t0, t0);
18202 tcg_gen_ext32u_tl(t1, t1);
18203 tcg_gen_extu_tl_i64(t2, t0);
18204 tcg_gen_extu_tl_i64(t3, t1);
18205 tcg_gen_mul_i64(t2, t2, t3);
18206 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18207 tcg_gen_add_i64(t2, t2, t3);
18208 tcg_temp_free_i64(t3);
18209 gen_move_low32(cpu_LO[acc], t2);
18210 gen_move_high32(cpu_HI[acc], t2);
18211 tcg_temp_free_i64(t2);
18212 }
18213 break;
18214 case NM_MULTU:
18215 check_dsp(ctx);
18216 {
18217 int acc = extract32(ctx->opcode, 14, 2);
18218 TCGv_i32 t2 = tcg_temp_new_i32();
18219 TCGv_i32 t3 = tcg_temp_new_i32();
18220
18221 gen_load_gpr(t0, rs);
18222 gen_load_gpr(t1, rt);
18223 tcg_gen_trunc_tl_i32(t2, t0);
18224 tcg_gen_trunc_tl_i32(t3, t1);
18225 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18226 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18227 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18228 tcg_temp_free_i32(t2);
18229 tcg_temp_free_i32(t3);
18230 }
18231 break;
18232 case NM_EXTRV_R_W:
18233 check_dsp(ctx);
18234 tcg_gen_movi_tl(t0, rd >> 3);
18235 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18236 gen_store_gpr(t0, ret);
18237 break;
18238 default:
18239 generate_exception_end(ctx, EXCP_RI);
18240 break;
18241 }
18242 break;
18243 case NM_POOL32AXF_2_16_23:
18244 switch (extract32(ctx->opcode, 9, 3)) {
18245 case NM_DPAU_H_QBL:
18246 case NM_DPAQX_S_W_PH:
18247 case NM_DPSU_H_QBL:
18248 case NM_DPSQX_S_W_PH:
18249 case NM_MULSA_W_PH:
18250 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18251 break;
18252 case NM_EXTPV:
18253 check_dsp(ctx);
18254 tcg_gen_movi_tl(t0, rd >> 3);
18255 gen_helper_extp(t0, t0, v1_t, cpu_env);
18256 gen_store_gpr(t0, ret);
18257 break;
18258 case NM_MSUB:
18259 check_dsp(ctx);
18260 {
18261 int acc = extract32(ctx->opcode, 14, 2);
18262 TCGv_i64 t2 = tcg_temp_new_i64();
18263 TCGv_i64 t3 = tcg_temp_new_i64();
18264
18265 gen_load_gpr(t0, rs);
18266 gen_load_gpr(t1, rt);
18267 tcg_gen_ext_tl_i64(t2, t0);
18268 tcg_gen_ext_tl_i64(t3, t1);
18269 tcg_gen_mul_i64(t2, t2, t3);
18270 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18271 tcg_gen_sub_i64(t2, t3, t2);
18272 tcg_temp_free_i64(t3);
18273 gen_move_low32(cpu_LO[acc], t2);
18274 gen_move_high32(cpu_HI[acc], t2);
18275 tcg_temp_free_i64(t2);
18276 }
18277 break;
18278 case NM_EXTRV_RS_W:
18279 check_dsp(ctx);
18280 tcg_gen_movi_tl(t0, rd >> 3);
18281 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18282 gen_store_gpr(t0, ret);
18283 break;
18284 }
18285 break;
18286 case NM_POOL32AXF_2_24_31:
18287 switch (extract32(ctx->opcode, 9, 3)) {
18288 case NM_DPAU_H_QBR:
18289 case NM_DPAQX_SA_W_PH:
18290 case NM_DPSU_H_QBR:
18291 case NM_DPSQX_SA_W_PH:
18292 case NM_MULSAQ_S_W_PH:
18293 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18294 break;
18295 case NM_EXTPDPV:
18296 check_dsp(ctx);
18297 tcg_gen_movi_tl(t0, rd >> 3);
18298 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18299 gen_store_gpr(t0, ret);
18300 break;
18301 case NM_MSUBU:
18302 check_dsp(ctx);
18303 {
18304 int acc = extract32(ctx->opcode, 14, 2);
18305 TCGv_i64 t2 = tcg_temp_new_i64();
18306 TCGv_i64 t3 = tcg_temp_new_i64();
18307
18308 gen_load_gpr(t0, rs);
18309 gen_load_gpr(t1, rt);
18310 tcg_gen_ext32u_tl(t0, t0);
18311 tcg_gen_ext32u_tl(t1, t1);
18312 tcg_gen_extu_tl_i64(t2, t0);
18313 tcg_gen_extu_tl_i64(t3, t1);
18314 tcg_gen_mul_i64(t2, t2, t3);
18315 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18316 tcg_gen_sub_i64(t2, t3, t2);
18317 tcg_temp_free_i64(t3);
18318 gen_move_low32(cpu_LO[acc], t2);
18319 gen_move_high32(cpu_HI[acc], t2);
18320 tcg_temp_free_i64(t2);
18321 }
18322 break;
18323 case NM_EXTRV_S_H:
18324 check_dsp(ctx);
18325 tcg_gen_movi_tl(t0, rd >> 3);
18326 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18327 gen_store_gpr(t0, ret);
18328 break;
18329 }
18330 break;
18331 default:
18332 generate_exception_end(ctx, EXCP_RI);
18333 break;
18334 }
18335
18336 tcg_temp_free(t0);
18337 tcg_temp_free(t1);
18338
18339 tcg_temp_free(v0_t);
18340 tcg_temp_free(v1_t);
18341}
18342
4c75c985
SM
18343static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18344 int rt, int rs)
18345{
18346 int ret = rt;
18347 TCGv t0 = tcg_temp_new();
18348 TCGv v0_t = tcg_temp_new();
18349
18350 gen_load_gpr(v0_t, rs);
18351
18352 switch (opc) {
18353 case NM_ABSQ_S_QB:
908f6be1 18354 check_dsp_r2(ctx);
4c75c985
SM
18355 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18356 gen_store_gpr(v0_t, ret);
18357 break;
18358 case NM_ABSQ_S_PH:
18359 check_dsp(ctx);
18360 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18361 gen_store_gpr(v0_t, ret);
18362 break;
18363 case NM_ABSQ_S_W:
18364 check_dsp(ctx);
18365 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18366 gen_store_gpr(v0_t, ret);
18367 break;
18368 case NM_PRECEQ_W_PHL:
18369 check_dsp(ctx);
18370 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18371 tcg_gen_ext32s_tl(v0_t, v0_t);
18372 gen_store_gpr(v0_t, ret);
18373 break;
18374 case NM_PRECEQ_W_PHR:
18375 check_dsp(ctx);
18376 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18377 tcg_gen_shli_tl(v0_t, v0_t, 16);
18378 tcg_gen_ext32s_tl(v0_t, v0_t);
18379 gen_store_gpr(v0_t, ret);
18380 break;
18381 case NM_PRECEQU_PH_QBL:
18382 check_dsp(ctx);
18383 gen_helper_precequ_ph_qbl(v0_t, v0_t);
18384 gen_store_gpr(v0_t, ret);
18385 break;
18386 case NM_PRECEQU_PH_QBR:
18387 check_dsp(ctx);
18388 gen_helper_precequ_ph_qbr(v0_t, v0_t);
18389 gen_store_gpr(v0_t, ret);
18390 break;
18391 case NM_PRECEQU_PH_QBLA:
18392 check_dsp(ctx);
18393 gen_helper_precequ_ph_qbla(v0_t, v0_t);
18394 gen_store_gpr(v0_t, ret);
18395 break;
18396 case NM_PRECEQU_PH_QBRA:
18397 check_dsp(ctx);
18398 gen_helper_precequ_ph_qbra(v0_t, v0_t);
18399 gen_store_gpr(v0_t, ret);
18400 break;
18401 case NM_PRECEU_PH_QBL:
18402 check_dsp(ctx);
18403 gen_helper_preceu_ph_qbl(v0_t, v0_t);
18404 gen_store_gpr(v0_t, ret);
18405 break;
18406 case NM_PRECEU_PH_QBR:
18407 check_dsp(ctx);
18408 gen_helper_preceu_ph_qbr(v0_t, v0_t);
18409 gen_store_gpr(v0_t, ret);
18410 break;
18411 case NM_PRECEU_PH_QBLA:
18412 check_dsp(ctx);
18413 gen_helper_preceu_ph_qbla(v0_t, v0_t);
18414 gen_store_gpr(v0_t, ret);
18415 break;
18416 case NM_PRECEU_PH_QBRA:
18417 check_dsp(ctx);
18418 gen_helper_preceu_ph_qbra(v0_t, v0_t);
18419 gen_store_gpr(v0_t, ret);
18420 break;
18421 case NM_REPLV_PH:
18422 check_dsp(ctx);
18423 tcg_gen_ext16u_tl(v0_t, v0_t);
18424 tcg_gen_shli_tl(t0, v0_t, 16);
18425 tcg_gen_or_tl(v0_t, v0_t, t0);
18426 tcg_gen_ext32s_tl(v0_t, v0_t);
18427 gen_store_gpr(v0_t, ret);
18428 break;
18429 case NM_REPLV_QB:
18430 check_dsp(ctx);
18431 tcg_gen_ext8u_tl(v0_t, v0_t);
18432 tcg_gen_shli_tl(t0, v0_t, 8);
18433 tcg_gen_or_tl(v0_t, v0_t, t0);
18434 tcg_gen_shli_tl(t0, v0_t, 16);
18435 tcg_gen_or_tl(v0_t, v0_t, t0);
18436 tcg_gen_ext32s_tl(v0_t, v0_t);
18437 gen_store_gpr(v0_t, ret);
18438 break;
18439 case NM_BITREV:
18440 check_dsp(ctx);
18441 gen_helper_bitrev(v0_t, v0_t);
18442 gen_store_gpr(v0_t, ret);
18443 break;
18444 case NM_INSV:
18445 check_dsp(ctx);
18446 {
18447 TCGv tv0 = tcg_temp_new();
18448
18449 gen_load_gpr(tv0, rt);
18450 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18451 gen_store_gpr(v0_t, ret);
18452 tcg_temp_free(tv0);
18453 }
18454 break;
18455 case NM_RADDU_W_QB:
18456 check_dsp(ctx);
18457 gen_helper_raddu_w_qb(v0_t, v0_t);
18458 gen_store_gpr(v0_t, ret);
18459 break;
18460 case NM_BITSWAP:
18461 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18462 break;
18463 case NM_CLO:
fb32f8c8 18464 check_nms(ctx);
4c75c985
SM
18465 gen_cl(ctx, OPC_CLO, ret, rs);
18466 break;
18467 case NM_CLZ:
fb32f8c8 18468 check_nms(ctx);
4c75c985
SM
18469 gen_cl(ctx, OPC_CLZ, ret, rs);
18470 break;
18471 case NM_WSBH:
18472 gen_bshfl(ctx, OPC_WSBH, ret, rs);
18473 break;
18474 default:
18475 generate_exception_end(ctx, EXCP_RI);
18476 break;
18477 }
18478
18479 tcg_temp_free(v0_t);
18480 tcg_temp_free(t0);
18481}
18482
0b591184
SM
18483static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18484 int rt, int rs, int rd)
18485{
18486 TCGv t0 = tcg_temp_new();
18487 TCGv rs_t = tcg_temp_new();
18488
18489 gen_load_gpr(rs_t, rs);
18490
18491 switch (opc) {
18492 case NM_SHRA_R_QB:
908f6be1 18493 check_dsp_r2(ctx);
0b591184
SM
18494 tcg_gen_movi_tl(t0, rd >> 2);
18495 switch (extract32(ctx->opcode, 12, 1)) {
18496 case 0:
18497 /* NM_SHRA_QB */
18498 gen_helper_shra_qb(t0, t0, rs_t);
18499 gen_store_gpr(t0, rt);
18500 break;
18501 case 1:
18502 /* NM_SHRA_R_QB */
18503 gen_helper_shra_r_qb(t0, t0, rs_t);
18504 gen_store_gpr(t0, rt);
18505 break;
18506 }
18507 break;
18508 case NM_SHRL_PH:
908f6be1 18509 check_dsp_r2(ctx);
0b591184
SM
18510 tcg_gen_movi_tl(t0, rd >> 1);
18511 gen_helper_shrl_ph(t0, t0, rs_t);
18512 gen_store_gpr(t0, rt);
18513 break;
18514 case NM_REPL_QB:
18515 check_dsp(ctx);
18516 {
18517 int16_t imm;
18518 target_long result;
18519 imm = extract32(ctx->opcode, 13, 8);
18520 result = (uint32_t)imm << 24 |
18521 (uint32_t)imm << 16 |
18522 (uint32_t)imm << 8 |
18523 (uint32_t)imm;
18524 result = (int32_t)result;
18525 tcg_gen_movi_tl(t0, result);
18526 gen_store_gpr(t0, rt);
18527 }
18528 break;
18529 default:
18530 generate_exception_end(ctx, EXCP_RI);
18531 break;
18532 }
18533 tcg_temp_free(t0);
18534 tcg_temp_free(rs_t);
18535}
18536
2ed42efa 18537
64224187
YK
18538static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18539{
64224187
YK
18540 int rt = extract32(ctx->opcode, 21, 5);
18541 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 18542 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
18543
18544 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
18545 case NM_POOL32AXF_1:
18546 {
18547 int32_t op1 = extract32(ctx->opcode, 9, 3);
18548 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18549 }
18550 break;
18551 case NM_POOL32AXF_2:
8b3698b2
SM
18552 {
18553 int32_t op1 = extract32(ctx->opcode, 12, 2);
18554 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18555 }
2ed42efa 18556 break;
64224187 18557 case NM_POOL32AXF_4:
4c75c985
SM
18558 {
18559 int32_t op1 = extract32(ctx->opcode, 9, 7);
18560 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18561 }
2ed42efa 18562 break;
64224187
YK
18563 case NM_POOL32AXF_5:
18564 switch (extract32(ctx->opcode, 9, 7)) {
18565#ifndef CONFIG_USER_ONLY
18566 case NM_TLBP:
18567 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18568 break;
18569 case NM_TLBR:
18570 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18571 break;
18572 case NM_TLBWI:
18573 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18574 break;
18575 case NM_TLBWR:
18576 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18577 break;
18578 case NM_TLBINV:
18579 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18580 break;
18581 case NM_TLBINVF:
18582 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18583 break;
18584 case NM_DI:
18585 check_cp0_enabled(ctx);
18586 {
18587 TCGv t0 = tcg_temp_new();
18588
18589 save_cpu_state(ctx, 1);
18590 gen_helper_di(t0, cpu_env);
18591 gen_store_gpr(t0, rt);
18592 /* Stop translation as we may have switched the execution mode */
18593 ctx->base.is_jmp = DISAS_STOP;
18594 tcg_temp_free(t0);
18595 }
18596 break;
18597 case NM_EI:
18598 check_cp0_enabled(ctx);
18599 {
18600 TCGv t0 = tcg_temp_new();
18601
18602 save_cpu_state(ctx, 1);
18603 gen_helper_ei(t0, cpu_env);
18604 gen_store_gpr(t0, rt);
18605 /* Stop translation as we may have switched the execution mode */
18606 ctx->base.is_jmp = DISAS_STOP;
18607 tcg_temp_free(t0);
18608 }
18609 break;
18610 case NM_RDPGPR:
18611 gen_load_srsgpr(rs, rt);
18612 break;
18613 case NM_WRPGPR:
18614 gen_store_srsgpr(rs, rt);
18615 break;
18616 case NM_WAIT:
18617 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18618 break;
18619 case NM_DERET:
18620 gen_cp0(env, ctx, OPC_DERET, 0, 0);
18621 break;
18622 case NM_ERETX:
18623 gen_cp0(env, ctx, OPC_ERET, 0, 0);
18624 break;
18625#endif
18626 default:
18627 generate_exception_end(ctx, EXCP_RI);
18628 break;
18629 }
18630 break;
2ed42efa 18631 case NM_POOL32AXF_7:
0b591184
SM
18632 {
18633 int32_t op1 = extract32(ctx->opcode, 9, 3);
18634 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18635 }
2ed42efa 18636 break;
64224187
YK
18637 default:
18638 generate_exception_end(ctx, EXCP_RI);
18639 break;
18640 }
18641}
18642
11d0fc10
SM
18643/* Immediate Value Compact Branches */
18644static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18645 int rt, int32_t imm, int32_t offset)
18646{
18647 TCGCond cond;
18648 int bcond_compute = 0;
18649 TCGv t0 = tcg_temp_new();
18650 TCGv t1 = tcg_temp_new();
18651
18652 gen_load_gpr(t0, rt);
18653 tcg_gen_movi_tl(t1, imm);
18654 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18655
18656 /* Load needed operands and calculate btarget */
18657 switch (opc) {
18658 case NM_BEQIC:
18659 if (rt == 0 && imm == 0) {
18660 /* Unconditional branch */
18661 } else if (rt == 0 && imm != 0) {
18662 /* Treat as NOP */
18663 goto out;
18664 } else {
18665 bcond_compute = 1;
18666 cond = TCG_COND_EQ;
18667 }
18668 break;
18669 case NM_BBEQZC:
18670 case NM_BBNEZC:
fb32f8c8 18671 check_nms(ctx);
11d0fc10
SM
18672 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18673 generate_exception_end(ctx, EXCP_RI);
18674 goto out;
18675 } else if (rt == 0 && opc == NM_BBEQZC) {
18676 /* Unconditional branch */
18677 } else if (rt == 0 && opc == NM_BBNEZC) {
18678 /* Treat as NOP */
18679 goto out;
18680 } else {
18681 tcg_gen_shri_tl(t0, t0, imm);
18682 tcg_gen_andi_tl(t0, t0, 1);
18683 tcg_gen_movi_tl(t1, 0);
18684 bcond_compute = 1;
18685 if (opc == NM_BBEQZC) {
18686 cond = TCG_COND_EQ;
18687 } else {
18688 cond = TCG_COND_NE;
18689 }
18690 }
18691 break;
18692 case NM_BNEIC:
18693 if (rt == 0 && imm == 0) {
18694 /* Treat as NOP */
18695 goto out;
18696 } else if (rt == 0 && imm != 0) {
18697 /* Unconditional branch */
18698 } else {
18699 bcond_compute = 1;
18700 cond = TCG_COND_NE;
18701 }
18702 break;
18703 case NM_BGEIC:
18704 if (rt == 0 && imm == 0) {
18705 /* Unconditional branch */
18706 } else {
18707 bcond_compute = 1;
18708 cond = TCG_COND_GE;
18709 }
18710 break;
18711 case NM_BLTIC:
18712 bcond_compute = 1;
18713 cond = TCG_COND_LT;
18714 break;
18715 case NM_BGEIUC:
18716 if (rt == 0 && imm == 0) {
18717 /* Unconditional branch */
18718 } else {
18719 bcond_compute = 1;
18720 cond = TCG_COND_GEU;
18721 }
18722 break;
18723 case NM_BLTIUC:
18724 bcond_compute = 1;
18725 cond = TCG_COND_LTU;
18726 break;
18727 default:
18728 MIPS_INVAL("Immediate Value Compact branch");
18729 generate_exception_end(ctx, EXCP_RI);
18730 goto out;
18731 }
18732
18733 if (bcond_compute == 0) {
18734 /* Uncoditional compact branch */
18735 gen_goto_tb(ctx, 0, ctx->btarget);
18736 } else {
18737 /* Conditional compact branch */
18738 TCGLabel *fs = gen_new_label();
18739
18740 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18741
18742 gen_goto_tb(ctx, 1, ctx->btarget);
18743 gen_set_label(fs);
18744
18745 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18746 }
18747
18748out:
18749 tcg_temp_free(t0);
18750 tcg_temp_free(t1);
18751}
18752
18753/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18754static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18755 int rt)
18756{
18757 TCGv t0 = tcg_temp_new();
18758 TCGv t1 = tcg_temp_new();
18759
18760 /* load rs */
18761 gen_load_gpr(t0, rs);
18762
18763 /* link */
18764 if (rt != 0) {
18765 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18766 }
18767
18768 /* calculate btarget */
18769 tcg_gen_shli_tl(t0, t0, 1);
18770 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18771 gen_op_addr_add(ctx, btarget, t1, t0);
18772
18773 /* unconditional branch to register */
18774 tcg_gen_mov_tl(cpu_PC, btarget);
18775 tcg_gen_lookup_and_goto_ptr();
18776
18777 tcg_temp_free(t0);
18778 tcg_temp_free(t1);
18779}
18780
18781/* nanoMIPS Branches */
18782static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18783 int rs, int rt, int32_t offset)
18784{
18785 int bcond_compute = 0;
18786 TCGv t0 = tcg_temp_new();
18787 TCGv t1 = tcg_temp_new();
18788
18789 /* Load needed operands and calculate btarget */
18790 switch (opc) {
18791 /* compact branch */
18792 case OPC_BGEC:
18793 case OPC_BLTC:
18794 gen_load_gpr(t0, rs);
18795 gen_load_gpr(t1, rt);
18796 bcond_compute = 1;
18797 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18798 break;
18799 case OPC_BGEUC:
18800 case OPC_BLTUC:
18801 if (rs == 0 || rs == rt) {
18802 /* OPC_BLEZALC, OPC_BGEZALC */
18803 /* OPC_BGTZALC, OPC_BLTZALC */
18804 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18805 }
18806 gen_load_gpr(t0, rs);
18807 gen_load_gpr(t1, rt);
18808 bcond_compute = 1;
18809 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18810 break;
18811 case OPC_BC:
18812 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18813 break;
18814 case OPC_BEQZC:
18815 if (rs != 0) {
18816 /* OPC_BEQZC, OPC_BNEZC */
18817 gen_load_gpr(t0, rs);
18818 bcond_compute = 1;
18819 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18820 } else {
18821 /* OPC_JIC, OPC_JIALC */
18822 TCGv tbase = tcg_temp_new();
18823 TCGv toffset = tcg_temp_new();
18824
18825 gen_load_gpr(tbase, rt);
18826 tcg_gen_movi_tl(toffset, offset);
18827 gen_op_addr_add(ctx, btarget, tbase, toffset);
18828 tcg_temp_free(tbase);
18829 tcg_temp_free(toffset);
18830 }
18831 break;
18832 default:
18833 MIPS_INVAL("Compact branch/jump");
18834 generate_exception_end(ctx, EXCP_RI);
18835 goto out;
18836 }
18837
18838 if (bcond_compute == 0) {
18839 /* Uncoditional compact branch */
18840 switch (opc) {
18841 case OPC_BC:
18842 gen_goto_tb(ctx, 0, ctx->btarget);
18843 break;
18844 default:
18845 MIPS_INVAL("Compact branch/jump");
18846 generate_exception_end(ctx, EXCP_RI);
18847 goto out;
18848 }
18849 } else {
18850 /* Conditional compact branch */
18851 TCGLabel *fs = gen_new_label();
18852
18853 switch (opc) {
18854 case OPC_BGEUC:
18855 if (rs == 0 && rt != 0) {
18856 /* OPC_BLEZALC */
18857 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18858 } else if (rs != 0 && rt != 0 && rs == rt) {
18859 /* OPC_BGEZALC */
18860 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18861 } else {
18862 /* OPC_BGEUC */
18863 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18864 }
18865 break;
18866 case OPC_BLTUC:
18867 if (rs == 0 && rt != 0) {
18868 /* OPC_BGTZALC */
18869 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18870 } else if (rs != 0 && rt != 0 && rs == rt) {
18871 /* OPC_BLTZALC */
18872 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18873 } else {
18874 /* OPC_BLTUC */
18875 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
18876 }
18877 break;
18878 case OPC_BGEC:
18879 if (rs == 0 && rt != 0) {
18880 /* OPC_BLEZC */
18881 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18882 } else if (rs != 0 && rt != 0 && rs == rt) {
18883 /* OPC_BGEZC */
18884 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18885 } else {
18886 /* OPC_BGEC */
18887 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
18888 }
18889 break;
18890 case OPC_BLTC:
18891 if (rs == 0 && rt != 0) {
18892 /* OPC_BGTZC */
18893 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18894 } else if (rs != 0 && rt != 0 && rs == rt) {
18895 /* OPC_BLTZC */
18896 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18897 } else {
18898 /* OPC_BLTC */
18899 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
18900 }
18901 break;
18902 case OPC_BEQZC:
18903 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
18904 break;
18905 default:
18906 MIPS_INVAL("Compact conditional branch/jump");
18907 generate_exception_end(ctx, EXCP_RI);
18908 goto out;
18909 }
18910
18911 /* Generating branch here as compact branches don't have delay slot */
18912 gen_goto_tb(ctx, 1, ctx->btarget);
18913 gen_set_label(fs);
18914
18915 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18916 }
18917
18918out:
18919 tcg_temp_free(t0);
18920 tcg_temp_free(t1);
18921}
18922
18923
18924/* nanoMIPS CP1 Branches */
18925static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
18926 int32_t ft, int32_t offset)
18927{
18928 target_ulong btarget;
18929 TCGv_i64 t0 = tcg_temp_new_i64();
18930
18931 gen_load_fpr64(ctx, t0, ft);
18932 tcg_gen_andi_i64(t0, t0, 1);
18933
18934 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18935
18936 switch (op) {
18937 case NM_BC1EQZC:
18938 tcg_gen_xori_i64(t0, t0, 1);
18939 ctx->hflags |= MIPS_HFLAG_BC;
18940 break;
18941 case NM_BC1NEZC:
18942 /* t0 already set */
18943 ctx->hflags |= MIPS_HFLAG_BC;
18944 break;
18945 default:
18946 MIPS_INVAL("cp1 cond branch");
18947 generate_exception_end(ctx, EXCP_RI);
18948 goto out;
18949 }
18950
18951 tcg_gen_trunc_i64_tl(bcond, t0);
18952
18953 ctx->btarget = btarget;
18954
18955out:
18956 tcg_temp_free_i64(t0);
18957}
18958
eac52664
YK
18959
18960static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
18961{
18962 TCGv t0, t1;
18963 t0 = tcg_temp_new();
18964 t1 = tcg_temp_new();
18965
18966 gen_load_gpr(t0, rs);
18967 gen_load_gpr(t1, rt);
18968
18969 if ((extract32(ctx->opcode, 6, 1)) == 1) {
18970 /* PP.LSXS instructions require shifting */
18971 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 18972 case NM_SHXS:
fb32f8c8
DN
18973 check_nms(ctx);
18974 case NM_LHXS:
eac52664
YK
18975 case NM_LHUXS:
18976 tcg_gen_shli_tl(t0, t0, 1);
18977 break;
eac52664 18978 case NM_SWXS:
fb32f8c8
DN
18979 check_nms(ctx);
18980 case NM_LWXS:
eac52664
YK
18981 case NM_LWC1XS:
18982 case NM_SWC1XS:
18983 tcg_gen_shli_tl(t0, t0, 2);
18984 break;
18985 case NM_LDC1XS:
18986 case NM_SDC1XS:
18987 tcg_gen_shli_tl(t0, t0, 3);
18988 break;
18989 }
18990 }
18991 gen_op_addr_add(ctx, t0, t0, t1);
18992
18993 switch (extract32(ctx->opcode, 7, 4)) {
18994 case NM_LBX:
18995 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
18996 MO_SB);
18997 gen_store_gpr(t0, rd);
18998 break;
18999 case NM_LHX:
19000 /*case NM_LHXS:*/
19001 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19002 MO_TESW);
19003 gen_store_gpr(t0, rd);
19004 break;
19005 case NM_LWX:
19006 /*case NM_LWXS:*/
19007 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19008 MO_TESL);
19009 gen_store_gpr(t0, rd);
19010 break;
19011 case NM_LBUX:
19012 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19013 MO_UB);
19014 gen_store_gpr(t0, rd);
19015 break;
19016 case NM_LHUX:
19017 /*case NM_LHUXS:*/
19018 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19019 MO_TEUW);
19020 gen_store_gpr(t0, rd);
19021 break;
19022 case NM_SBX:
fb32f8c8 19023 check_nms(ctx);
eac52664
YK
19024 gen_load_gpr(t1, rd);
19025 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19026 MO_8);
19027 break;
19028 case NM_SHX:
19029 /*case NM_SHXS:*/
fb32f8c8 19030 check_nms(ctx);
eac52664
YK
19031 gen_load_gpr(t1, rd);
19032 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19033 MO_TEUW);
19034 break;
19035 case NM_SWX:
19036 /*case NM_SWXS:*/
fb32f8c8 19037 check_nms(ctx);
eac52664
YK
19038 gen_load_gpr(t1, rd);
19039 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19040 MO_TEUL);
19041 break;
19042 case NM_LWC1X:
19043 /*case NM_LWC1XS:*/
19044 case NM_LDC1X:
19045 /*case NM_LDC1XS:*/
19046 case NM_SWC1X:
19047 /*case NM_SWC1XS:*/
19048 case NM_SDC1X:
19049 /*case NM_SDC1XS:*/
19050 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19051 check_cp1_enabled(ctx);
19052 switch (extract32(ctx->opcode, 7, 4)) {
19053 case NM_LWC1X:
19054 /*case NM_LWC1XS:*/
19055 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19056 break;
19057 case NM_LDC1X:
19058 /*case NM_LDC1XS:*/
19059 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19060 break;
19061 case NM_SWC1X:
19062 /*case NM_SWC1XS:*/
19063 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19064 break;
19065 case NM_SDC1X:
19066 /*case NM_SDC1XS:*/
19067 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19068 break;
19069 }
19070 } else {
19071 generate_exception_err(ctx, EXCP_CpU, 1);
19072 }
19073 break;
19074 default:
19075 generate_exception_end(ctx, EXCP_RI);
19076 break;
19077 }
19078
19079 tcg_temp_free(t0);
19080 tcg_temp_free(t1);
19081}
19082
579b8ea9
YK
19083static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19084{
19085 int rt, rs, rd;
19086
19087 rt = extract32(ctx->opcode, 21, 5);
19088 rs = extract32(ctx->opcode, 16, 5);
19089 rd = extract32(ctx->opcode, 11, 5);
19090
19091 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19092 generate_exception_end(ctx, EXCP_RI);
19093 return;
19094 }
19095 check_cp1_enabled(ctx);
19096 switch (extract32(ctx->opcode, 0, 3)) {
19097 case NM_POOL32F_0:
19098 switch (extract32(ctx->opcode, 3, 7)) {
19099 case NM_RINT_S:
19100 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19101 break;
19102 case NM_RINT_D:
19103 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19104 break;
19105 case NM_CLASS_S:
19106 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19107 break;
19108 case NM_CLASS_D:
19109 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19110 break;
19111 case NM_ADD_S:
19112 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19113 break;
19114 case NM_ADD_D:
19115 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19116 break;
19117 case NM_SUB_S:
19118 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19119 break;
19120 case NM_SUB_D:
19121 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19122 break;
19123 case NM_MUL_S:
19124 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19125 break;
19126 case NM_MUL_D:
19127 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19128 break;
19129 case NM_DIV_S:
19130 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19131 break;
19132 case NM_DIV_D:
19133 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19134 break;
19135 case NM_SELEQZ_S:
19136 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19137 break;
19138 case NM_SELEQZ_D:
19139 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19140 break;
19141 case NM_SELNEZ_S:
19142 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19143 break;
19144 case NM_SELNEZ_D:
19145 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19146 break;
19147 case NM_SEL_S:
19148 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19149 break;
19150 case NM_SEL_D:
19151 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19152 break;
19153 case NM_MADDF_S:
19154 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19155 break;
19156 case NM_MADDF_D:
19157 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19158 break;
19159 case NM_MSUBF_S:
19160 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19161 break;
19162 case NM_MSUBF_D:
19163 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19164 break;
19165 default:
19166 generate_exception_end(ctx, EXCP_RI);
19167 break;
19168 }
19169 break;
19170 case NM_POOL32F_3:
19171 switch (extract32(ctx->opcode, 3, 3)) {
19172 case NM_MIN_FMT:
19173 switch (extract32(ctx->opcode, 9, 1)) {
19174 case FMT_SDPS_S:
19175 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19176 break;
19177 case FMT_SDPS_D:
19178 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19179 break;
19180 }
19181 break;
19182 case NM_MAX_FMT:
19183 switch (extract32(ctx->opcode, 9, 1)) {
19184 case FMT_SDPS_S:
19185 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19186 break;
19187 case FMT_SDPS_D:
19188 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19189 break;
19190 }
19191 break;
19192 case NM_MINA_FMT:
19193 switch (extract32(ctx->opcode, 9, 1)) {
19194 case FMT_SDPS_S:
19195 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19196 break;
19197 case FMT_SDPS_D:
19198 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19199 break;
19200 }
19201 break;
19202 case NM_MAXA_FMT:
19203 switch (extract32(ctx->opcode, 9, 1)) {
19204 case FMT_SDPS_S:
19205 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19206 break;
19207 case FMT_SDPS_D:
19208 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19209 break;
19210 }
19211 break;
19212 case NM_POOL32FXF:
19213 switch (extract32(ctx->opcode, 6, 8)) {
19214 case NM_CFC1:
19215 gen_cp1(ctx, OPC_CFC1, rt, rs);
19216 break;
19217 case NM_CTC1:
19218 gen_cp1(ctx, OPC_CTC1, rt, rs);
19219 break;
19220 case NM_MFC1:
19221 gen_cp1(ctx, OPC_MFC1, rt, rs);
19222 break;
19223 case NM_MTC1:
19224 gen_cp1(ctx, OPC_MTC1, rt, rs);
19225 break;
19226 case NM_MFHC1:
19227 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19228 break;
19229 case NM_MTHC1:
19230 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19231 break;
19232 case NM_CVT_S_PL:
19233 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19234 break;
19235 case NM_CVT_S_PU:
19236 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19237 break;
19238 default:
19239 switch (extract32(ctx->opcode, 6, 9)) {
19240 case NM_CVT_L_S:
19241 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19242 break;
19243 case NM_CVT_L_D:
19244 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19245 break;
19246 case NM_CVT_W_S:
19247 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19248 break;
19249 case NM_CVT_W_D:
19250 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19251 break;
19252 case NM_RSQRT_S:
19253 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19254 break;
19255 case NM_RSQRT_D:
19256 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19257 break;
19258 case NM_SQRT_S:
19259 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19260 break;
19261 case NM_SQRT_D:
19262 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19263 break;
19264 case NM_RECIP_S:
19265 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19266 break;
19267 case NM_RECIP_D:
19268 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19269 break;
19270 case NM_FLOOR_L_S:
19271 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19272 break;
19273 case NM_FLOOR_L_D:
19274 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19275 break;
19276 case NM_FLOOR_W_S:
19277 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19278 break;
19279 case NM_FLOOR_W_D:
19280 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19281 break;
19282 case NM_CEIL_L_S:
19283 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19284 break;
19285 case NM_CEIL_L_D:
19286 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19287 break;
19288 case NM_CEIL_W_S:
19289 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19290 break;
19291 case NM_CEIL_W_D:
19292 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19293 break;
19294 case NM_TRUNC_L_S:
19295 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19296 break;
19297 case NM_TRUNC_L_D:
19298 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19299 break;
19300 case NM_TRUNC_W_S:
19301 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19302 break;
19303 case NM_TRUNC_W_D:
19304 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19305 break;
19306 case NM_ROUND_L_S:
19307 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19308 break;
19309 case NM_ROUND_L_D:
19310 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19311 break;
19312 case NM_ROUND_W_S:
19313 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19314 break;
19315 case NM_ROUND_W_D:
19316 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19317 break;
19318 case NM_MOV_S:
19319 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19320 break;
19321 case NM_MOV_D:
19322 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19323 break;
19324 case NM_ABS_S:
19325 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19326 break;
19327 case NM_ABS_D:
19328 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19329 break;
19330 case NM_NEG_S:
19331 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19332 break;
19333 case NM_NEG_D:
19334 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19335 break;
19336 case NM_CVT_D_S:
19337 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19338 break;
19339 case NM_CVT_D_W:
19340 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19341 break;
19342 case NM_CVT_D_L:
19343 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19344 break;
19345 case NM_CVT_S_D:
19346 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19347 break;
19348 case NM_CVT_S_W:
19349 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19350 break;
19351 case NM_CVT_S_L:
19352 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19353 break;
19354 default:
19355 generate_exception_end(ctx, EXCP_RI);
19356 break;
19357 }
19358 break;
19359 }
19360 break;
19361 }
19362 break;
19363 case NM_POOL32F_5:
19364 switch (extract32(ctx->opcode, 3, 3)) {
19365 case NM_CMP_CONDN_S:
19366 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19367 break;
19368 case NM_CMP_CONDN_D:
19369 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19370 break;
19371 default:
19372 generate_exception_end(ctx, EXCP_RI);
19373 break;
19374 }
19375 break;
19376 default:
19377 generate_exception_end(ctx, EXCP_RI);
19378 break;
19379 }
19380}
19381
3285a3e4
SM
19382static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19383 int rd, int rs, int rt)
19384{
19385 int ret = rd;
19386 TCGv t0 = tcg_temp_new();
19387 TCGv v1_t = tcg_temp_new();
19388 TCGv v2_t = tcg_temp_new();
19389
19390 gen_load_gpr(v1_t, rs);
19391 gen_load_gpr(v2_t, rt);
19392
19393 switch (opc) {
19394 case NM_CMP_EQ_PH:
19395 check_dsp(ctx);
19396 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19397 break;
19398 case NM_CMP_LT_PH:
19399 check_dsp(ctx);
19400 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19401 break;
19402 case NM_CMP_LE_PH:
19403 check_dsp(ctx);
19404 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19405 break;
19406 case NM_CMPU_EQ_QB:
19407 check_dsp(ctx);
19408 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19409 break;
19410 case NM_CMPU_LT_QB:
19411 check_dsp(ctx);
19412 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19413 break;
19414 case NM_CMPU_LE_QB:
19415 check_dsp(ctx);
19416 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19417 break;
19418 case NM_CMPGU_EQ_QB:
19419 check_dsp(ctx);
19420 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19421 gen_store_gpr(v1_t, ret);
19422 break;
19423 case NM_CMPGU_LT_QB:
19424 check_dsp(ctx);
19425 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19426 gen_store_gpr(v1_t, ret);
19427 break;
19428 case NM_CMPGU_LE_QB:
19429 check_dsp(ctx);
19430 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19431 gen_store_gpr(v1_t, ret);
19432 break;
19433 case NM_CMPGDU_EQ_QB:
908f6be1 19434 check_dsp_r2(ctx);
3285a3e4
SM
19435 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19436 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19437 gen_store_gpr(v1_t, ret);
19438 break;
19439 case NM_CMPGDU_LT_QB:
908f6be1 19440 check_dsp_r2(ctx);
3285a3e4
SM
19441 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19442 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19443 gen_store_gpr(v1_t, ret);
19444 break;
19445 case NM_CMPGDU_LE_QB:
908f6be1 19446 check_dsp_r2(ctx);
3285a3e4
SM
19447 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19448 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19449 gen_store_gpr(v1_t, ret);
19450 break;
19451 case NM_PACKRL_PH:
19452 check_dsp(ctx);
19453 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19454 gen_store_gpr(v1_t, ret);
19455 break;
19456 case NM_PICK_QB:
19457 check_dsp(ctx);
19458 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19459 gen_store_gpr(v1_t, ret);
19460 break;
19461 case NM_PICK_PH:
19462 check_dsp(ctx);
19463 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19464 gen_store_gpr(v1_t, ret);
19465 break;
19466 case NM_ADDQ_S_W:
19467 check_dsp(ctx);
19468 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19469 gen_store_gpr(v1_t, ret);
19470 break;
19471 case NM_SUBQ_S_W:
19472 check_dsp(ctx);
19473 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19474 gen_store_gpr(v1_t, ret);
19475 break;
19476 case NM_ADDSC:
19477 check_dsp(ctx);
19478 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19479 gen_store_gpr(v1_t, ret);
19480 break;
19481 case NM_ADDWC:
19482 check_dsp(ctx);
19483 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19484 gen_store_gpr(v1_t, ret);
19485 break;
19486 case NM_ADDQ_S_PH:
19487 check_dsp(ctx);
19488 switch (extract32(ctx->opcode, 10, 1)) {
19489 case 0:
19490 /* ADDQ_PH */
19491 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19492 gen_store_gpr(v1_t, ret);
19493 break;
19494 case 1:
19495 /* ADDQ_S_PH */
19496 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19497 gen_store_gpr(v1_t, ret);
19498 break;
19499 }
19500 break;
19501 case NM_ADDQH_R_PH:
908f6be1 19502 check_dsp_r2(ctx);
3285a3e4
SM
19503 switch (extract32(ctx->opcode, 10, 1)) {
19504 case 0:
19505 /* ADDQH_PH */
19506 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19507 gen_store_gpr(v1_t, ret);
19508 break;
19509 case 1:
19510 /* ADDQH_R_PH */
19511 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19512 gen_store_gpr(v1_t, ret);
19513 break;
19514 }
19515 break;
19516 case NM_ADDQH_R_W:
908f6be1 19517 check_dsp_r2(ctx);
3285a3e4
SM
19518 switch (extract32(ctx->opcode, 10, 1)) {
19519 case 0:
19520 /* ADDQH_W */
19521 gen_helper_addqh_w(v1_t, v1_t, v2_t);
19522 gen_store_gpr(v1_t, ret);
19523 break;
19524 case 1:
19525 /* ADDQH_R_W */
19526 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19527 gen_store_gpr(v1_t, ret);
19528 break;
19529 }
19530 break;
19531 case NM_ADDU_S_QB:
19532 check_dsp(ctx);
19533 switch (extract32(ctx->opcode, 10, 1)) {
19534 case 0:
19535 /* ADDU_QB */
19536 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19537 gen_store_gpr(v1_t, ret);
19538 break;
19539 case 1:
19540 /* ADDU_S_QB */
19541 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19542 gen_store_gpr(v1_t, ret);
19543 break;
19544 }
19545 break;
19546 case NM_ADDU_S_PH:
908f6be1 19547 check_dsp_r2(ctx);
3285a3e4
SM
19548 switch (extract32(ctx->opcode, 10, 1)) {
19549 case 0:
19550 /* ADDU_PH */
19551 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19552 gen_store_gpr(v1_t, ret);
19553 break;
19554 case 1:
19555 /* ADDU_S_PH */
19556 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19557 gen_store_gpr(v1_t, ret);
19558 break;
19559 }
19560 break;
19561 case NM_ADDUH_R_QB:
908f6be1 19562 check_dsp_r2(ctx);
3285a3e4
SM
19563 switch (extract32(ctx->opcode, 10, 1)) {
19564 case 0:
19565 /* ADDUH_QB */
19566 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19567 gen_store_gpr(v1_t, ret);
19568 break;
19569 case 1:
19570 /* ADDUH_R_QB */
19571 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19572 gen_store_gpr(v1_t, ret);
19573 break;
19574 }
19575 break;
19576 case NM_SHRAV_R_PH:
19577 check_dsp(ctx);
19578 switch (extract32(ctx->opcode, 10, 1)) {
19579 case 0:
19580 /* SHRAV_PH */
19581 gen_helper_shra_ph(v1_t, v1_t, v2_t);
19582 gen_store_gpr(v1_t, ret);
19583 break;
19584 case 1:
19585 /* SHRAV_R_PH */
19586 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19587 gen_store_gpr(v1_t, ret);
19588 break;
19589 }
19590 break;
19591 case NM_SHRAV_R_QB:
908f6be1 19592 check_dsp_r2(ctx);
3285a3e4
SM
19593 switch (extract32(ctx->opcode, 10, 1)) {
19594 case 0:
19595 /* SHRAV_QB */
19596 gen_helper_shra_qb(v1_t, v1_t, v2_t);
19597 gen_store_gpr(v1_t, ret);
19598 break;
19599 case 1:
19600 /* SHRAV_R_QB */
19601 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19602 gen_store_gpr(v1_t, ret);
19603 break;
19604 }
19605 break;
19606 case NM_SUBQ_S_PH:
19607 check_dsp(ctx);
19608 switch (extract32(ctx->opcode, 10, 1)) {
19609 case 0:
19610 /* SUBQ_PH */
19611 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19612 gen_store_gpr(v1_t, ret);
19613 break;
19614 case 1:
19615 /* SUBQ_S_PH */
19616 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19617 gen_store_gpr(v1_t, ret);
19618 break;
19619 }
19620 break;
19621 case NM_SUBQH_R_PH:
908f6be1 19622 check_dsp_r2(ctx);
3285a3e4
SM
19623 switch (extract32(ctx->opcode, 10, 1)) {
19624 case 0:
19625 /* SUBQH_PH */
19626 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19627 gen_store_gpr(v1_t, ret);
19628 break;
19629 case 1:
19630 /* SUBQH_R_PH */
19631 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19632 gen_store_gpr(v1_t, ret);
19633 break;
19634 }
19635 break;
19636 case NM_SUBQH_R_W:
908f6be1 19637 check_dsp_r2(ctx);
3285a3e4
SM
19638 switch (extract32(ctx->opcode, 10, 1)) {
19639 case 0:
19640 /* SUBQH_W */
19641 gen_helper_subqh_w(v1_t, v1_t, v2_t);
19642 gen_store_gpr(v1_t, ret);
19643 break;
19644 case 1:
19645 /* SUBQH_R_W */
19646 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19647 gen_store_gpr(v1_t, ret);
19648 break;
19649 }
19650 break;
19651 case NM_SUBU_S_QB:
19652 check_dsp(ctx);
19653 switch (extract32(ctx->opcode, 10, 1)) {
19654 case 0:
19655 /* SUBU_QB */
19656 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19657 gen_store_gpr(v1_t, ret);
19658 break;
19659 case 1:
19660 /* SUBU_S_QB */
19661 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19662 gen_store_gpr(v1_t, ret);
19663 break;
19664 }
19665 break;
19666 case NM_SUBU_S_PH:
908f6be1 19667 check_dsp_r2(ctx);
3285a3e4
SM
19668 switch (extract32(ctx->opcode, 10, 1)) {
19669 case 0:
19670 /* SUBU_PH */
19671 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19672 gen_store_gpr(v1_t, ret);
19673 break;
19674 case 1:
19675 /* SUBU_S_PH */
19676 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19677 gen_store_gpr(v1_t, ret);
19678 break;
19679 }
19680 break;
19681 case NM_SUBUH_R_QB:
908f6be1 19682 check_dsp_r2(ctx);
3285a3e4
SM
19683 switch (extract32(ctx->opcode, 10, 1)) {
19684 case 0:
19685 /* SUBUH_QB */
19686 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19687 gen_store_gpr(v1_t, ret);
19688 break;
19689 case 1:
19690 /* SUBUH_R_QB */
19691 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19692 gen_store_gpr(v1_t, ret);
19693 break;
19694 }
19695 break;
19696 case NM_SHLLV_S_PH:
19697 check_dsp(ctx);
19698 switch (extract32(ctx->opcode, 10, 1)) {
19699 case 0:
19700 /* SHLLV_PH */
19701 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19702 gen_store_gpr(v1_t, ret);
19703 break;
19704 case 1:
19705 /* SHLLV_S_PH */
19706 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19707 gen_store_gpr(v1_t, ret);
19708 break;
19709 }
19710 break;
19711 case NM_PRECR_SRA_R_PH_W:
908f6be1 19712 check_dsp_r2(ctx);
3285a3e4
SM
19713 switch (extract32(ctx->opcode, 10, 1)) {
19714 case 0:
19715 /* PRECR_SRA_PH_W */
19716 {
19717 TCGv_i32 sa_t = tcg_const_i32(rd);
19718 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19719 cpu_gpr[rt]);
19720 gen_store_gpr(v1_t, rt);
19721 tcg_temp_free_i32(sa_t);
19722 }
19723 break;
19724 case 1:
19725 /* PRECR_SRA_R_PH_W */
19726 {
19727 TCGv_i32 sa_t = tcg_const_i32(rd);
19728 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19729 cpu_gpr[rt]);
19730 gen_store_gpr(v1_t, rt);
19731 tcg_temp_free_i32(sa_t);
19732 }
19733 break;
19734 }
19735 break;
19736 case NM_MULEU_S_PH_QBL:
19737 check_dsp(ctx);
19738 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19739 gen_store_gpr(v1_t, ret);
19740 break;
19741 case NM_MULEU_S_PH_QBR:
19742 check_dsp(ctx);
19743 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19744 gen_store_gpr(v1_t, ret);
19745 break;
19746 case NM_MULQ_RS_PH:
19747 check_dsp(ctx);
19748 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19749 gen_store_gpr(v1_t, ret);
19750 break;
19751 case NM_MULQ_S_PH:
908f6be1 19752 check_dsp_r2(ctx);
3285a3e4
SM
19753 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19754 gen_store_gpr(v1_t, ret);
19755 break;
19756 case NM_MULQ_RS_W:
908f6be1 19757 check_dsp_r2(ctx);
3285a3e4
SM
19758 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19759 gen_store_gpr(v1_t, ret);
19760 break;
19761 case NM_MULQ_S_W:
908f6be1 19762 check_dsp_r2(ctx);
3285a3e4
SM
19763 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19764 gen_store_gpr(v1_t, ret);
19765 break;
19766 case NM_APPEND:
908f6be1 19767 check_dsp_r2(ctx);
3285a3e4
SM
19768 gen_load_gpr(t0, rs);
19769 if (rd != 0) {
19770 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19771 }
19772 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19773 break;
19774 case NM_MODSUB:
19775 check_dsp(ctx);
19776 gen_helper_modsub(v1_t, v1_t, v2_t);
19777 gen_store_gpr(v1_t, ret);
19778 break;
19779 case NM_SHRAV_R_W:
19780 check_dsp(ctx);
19781 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19782 gen_store_gpr(v1_t, ret);
19783 break;
19784 case NM_SHRLV_PH:
908f6be1 19785 check_dsp_r2(ctx);
3285a3e4
SM
19786 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19787 gen_store_gpr(v1_t, ret);
19788 break;
19789 case NM_SHRLV_QB:
19790 check_dsp(ctx);
19791 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19792 gen_store_gpr(v1_t, ret);
19793 break;
19794 case NM_SHLLV_QB:
19795 check_dsp(ctx);
19796 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19797 gen_store_gpr(v1_t, ret);
19798 break;
19799 case NM_SHLLV_S_W:
19800 check_dsp(ctx);
19801 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19802 gen_store_gpr(v1_t, ret);
19803 break;
19804 case NM_SHILO:
19805 check_dsp(ctx);
19806 {
19807 TCGv tv0 = tcg_temp_new();
19808 TCGv tv1 = tcg_temp_new();
19809 int16_t imm = extract32(ctx->opcode, 16, 7);
19810
19811 tcg_gen_movi_tl(tv0, rd >> 3);
19812 tcg_gen_movi_tl(tv1, imm);
19813 gen_helper_shilo(tv0, tv1, cpu_env);
19814 }
19815 break;
19816 case NM_MULEQ_S_W_PHL:
19817 check_dsp(ctx);
19818 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19819 gen_store_gpr(v1_t, ret);
19820 break;
19821 case NM_MULEQ_S_W_PHR:
19822 check_dsp(ctx);
19823 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19824 gen_store_gpr(v1_t, ret);
19825 break;
19826 case NM_MUL_S_PH:
908f6be1 19827 check_dsp_r2(ctx);
3285a3e4
SM
19828 switch (extract32(ctx->opcode, 10, 1)) {
19829 case 0:
19830 /* MUL_PH */
19831 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19832 gen_store_gpr(v1_t, ret);
19833 break;
19834 case 1:
19835 /* MUL_S_PH */
19836 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19837 gen_store_gpr(v1_t, ret);
19838 break;
19839 }
19840 break;
19841 case NM_PRECR_QB_PH:
908f6be1 19842 check_dsp_r2(ctx);
3285a3e4
SM
19843 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19844 gen_store_gpr(v1_t, ret);
19845 break;
19846 case NM_PRECRQ_QB_PH:
19847 check_dsp(ctx);
19848 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19849 gen_store_gpr(v1_t, ret);
19850 break;
19851 case NM_PRECRQ_PH_W:
19852 check_dsp(ctx);
19853 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19854 gen_store_gpr(v1_t, ret);
19855 break;
19856 case NM_PRECRQ_RS_PH_W:
19857 check_dsp(ctx);
19858 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19859 gen_store_gpr(v1_t, ret);
19860 break;
19861 case NM_PRECRQU_S_QB_PH:
19862 check_dsp(ctx);
19863 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19864 gen_store_gpr(v1_t, ret);
19865 break;
19866 case NM_SHRA_R_W:
19867 check_dsp(ctx);
19868 tcg_gen_movi_tl(t0, rd);
19869 gen_helper_shra_r_w(v1_t, t0, v1_t);
19870 gen_store_gpr(v1_t, rt);
19871 break;
19872 case NM_SHRA_R_PH:
19873 check_dsp(ctx);
19874 tcg_gen_movi_tl(t0, rd >> 1);
19875 switch (extract32(ctx->opcode, 10, 1)) {
19876 case 0:
19877 /* SHRA_PH */
19878 gen_helper_shra_ph(v1_t, t0, v1_t);
19879 break;
19880 gen_store_gpr(v1_t, rt);
19881 case 1:
19882 /* SHRA_R_PH */
19883 gen_helper_shra_r_ph(v1_t, t0, v1_t);
19884 gen_store_gpr(v1_t, rt);
19885 break;
19886 }
19887 break;
19888 case NM_SHLL_S_PH:
19889 check_dsp(ctx);
19890 tcg_gen_movi_tl(t0, rd >> 1);
19891 switch (extract32(ctx->opcode, 10, 2)) {
19892 case 0:
19893 /* SHLL_PH */
19894 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
19895 gen_store_gpr(v1_t, rt);
19896 break;
19897 case 2:
19898 /* SHLL_S_PH */
19899 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
19900 gen_store_gpr(v1_t, rt);
19901 break;
19902 default:
19903 generate_exception_end(ctx, EXCP_RI);
19904 break;
19905 }
19906 break;
19907 case NM_SHLL_S_W:
19908 check_dsp(ctx);
19909 tcg_gen_movi_tl(t0, rd);
19910 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
19911 gen_store_gpr(v1_t, rt);
19912 break;
19913 case NM_REPL_PH:
19914 check_dsp(ctx);
19915 {
19916 int16_t imm;
19917 imm = sextract32(ctx->opcode, 11, 11);
19918 imm = (int16_t)(imm << 6) >> 6;
19919 if (rt != 0) {
19920 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
19921 }
19922 }
19923 break;
19924 default:
19925 generate_exception_end(ctx, EXCP_RI);
19926 break;
19927 }
19928}
19929
c0280983
YK
19930static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
19931{
19932 uint16_t insn;
19933 uint32_t op;
eac52664 19934 int rt, rs, rd;
c0280983
YK
19935 int offset;
19936 int imm;
19937
19938 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
19939 ctx->opcode = (ctx->opcode << 16) | insn;
19940
19941 rt = extract32(ctx->opcode, 21, 5);
19942 rs = extract32(ctx->opcode, 16, 5);
eac52664 19943 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
19944
19945 op = extract32(ctx->opcode, 26, 6);
19946 switch (op) {
19947 case NM_P_ADDIU:
19948 if (rt == 0) {
19949 /* P.RI */
19950 switch (extract32(ctx->opcode, 19, 2)) {
19951 case NM_SIGRIE:
19952 default:
19953 generate_exception_end(ctx, EXCP_RI);
19954 break;
19955 case NM_P_SYSCALL:
19956 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
19957 generate_exception_end(ctx, EXCP_SYSCALL);
19958 } else {
19959 generate_exception_end(ctx, EXCP_RI);
19960 }
19961 break;
19962 case NM_BREAK:
19963 generate_exception_end(ctx, EXCP_BREAK);
19964 break;
19965 case NM_SDBBP:
19966 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
19967 gen_helper_do_semihosting(cpu_env);
19968 } else {
19969 if (ctx->hflags & MIPS_HFLAG_SBRI) {
19970 generate_exception_end(ctx, EXCP_RI);
19971 } else {
19972 generate_exception_end(ctx, EXCP_DBp);
19973 }
19974 }
19975 break;
19976 }
19977 } else {
19978 /* NM_ADDIU */
19979 imm = extract32(ctx->opcode, 0, 16);
19980 if (rs != 0) {
19981 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
19982 } else {
19983 tcg_gen_movi_tl(cpu_gpr[rt], imm);
19984 }
19985 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19986 }
19987 break;
19988 case NM_ADDIUPC:
19989 if (rt != 0) {
19990 offset = sextract32(ctx->opcode, 0, 1) << 21 |
19991 extract32(ctx->opcode, 1, 20) << 1;
19992 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
19993 tcg_gen_movi_tl(cpu_gpr[rt], addr);
19994 }
19995 break;
19996 case NM_POOL32A:
e0cf0e65
YK
19997 switch (ctx->opcode & 0x07) {
19998 case NM_POOL32A0:
0a1a6ed7 19999 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 20000 break;
3285a3e4
SM
20001 case NM_POOL32A5:
20002 {
20003 int32_t op1 = extract32(ctx->opcode, 3, 7);
20004 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20005 }
20006 break;
e0cf0e65 20007 case NM_POOL32A7:
64224187 20008 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
20009 case NM_P_LSX:
20010 gen_p_lsx(ctx, rd, rs, rt);
20011 break;
20012 case NM_LSA:
20013 /* In nanoMIPS, the shift field directly encodes the shift
20014 * amount, meaning that the supported shift values are in
20015 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20016 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20017 extract32(ctx->opcode, 9, 2) - 1);
20018 break;
821f2008
JH
20019 case NM_EXTW:
20020 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20021 break;
64224187
YK
20022 case NM_POOL32AXF:
20023 gen_pool32axf_nanomips_insn(env, ctx);
20024 break;
20025 default:
20026 generate_exception_end(ctx, EXCP_RI);
20027 break;
20028 }
e0cf0e65
YK
20029 break;
20030 default:
20031 generate_exception_end(ctx, EXCP_RI);
20032 break;
20033 }
c0280983
YK
20034 break;
20035 case NM_P_GP_W:
20036 switch (ctx->opcode & 0x03) {
20037 case NM_ADDIUGP_W:
20038 if (rt != 0) {
20039 offset = extract32(ctx->opcode, 0, 21);
20040 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20041 }
20042 break;
20043 case NM_LWGP:
20044 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20045 break;
20046 case NM_SWGP:
20047 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20048 break;
20049 default:
20050 generate_exception_end(ctx, EXCP_RI);
20051 break;
20052 }
20053 break;
20054 case NM_P48I:
7ef009b2
YK
20055 {
20056 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20057 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20058 switch (extract32(ctx->opcode, 16, 5)) {
20059 case NM_LI48:
fb32f8c8 20060 check_nms(ctx);
7ef009b2
YK
20061 if (rt != 0) {
20062 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20063 }
20064 break;
20065 case NM_ADDIU48:
fb32f8c8 20066 check_nms(ctx);
7ef009b2
YK
20067 if (rt != 0) {
20068 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20069 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20070 }
20071 break;
20072 case NM_ADDIUGP48:
fb32f8c8 20073 check_nms(ctx);
7ef009b2
YK
20074 if (rt != 0) {
20075 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20076 }
20077 break;
20078 case NM_ADDIUPC48:
fb32f8c8 20079 check_nms(ctx);
7ef009b2
YK
20080 if (rt != 0) {
20081 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20082 addr_off);
20083
20084 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20085 }
20086 break;
20087 case NM_LWPC48:
fb32f8c8 20088 check_nms(ctx);
7ef009b2
YK
20089 if (rt != 0) {
20090 TCGv t0;
20091 t0 = tcg_temp_new();
20092
20093 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20094 addr_off);
20095
20096 tcg_gen_movi_tl(t0, addr);
20097 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20098 tcg_temp_free(t0);
20099 }
20100 break;
20101 case NM_SWPC48:
fb32f8c8 20102 check_nms(ctx);
7ef009b2
YK
20103 {
20104 TCGv t0, t1;
20105 t0 = tcg_temp_new();
20106 t1 = tcg_temp_new();
20107
20108 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20109 addr_off);
20110
20111 tcg_gen_movi_tl(t0, addr);
20112 gen_load_gpr(t1, rt);
20113
20114 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20115
20116 tcg_temp_free(t0);
20117 tcg_temp_free(t1);
20118 }
20119 break;
20120 default:
20121 generate_exception_end(ctx, EXCP_RI);
20122 break;
20123 }
20124 return 6;
20125 }
c0280983
YK
20126 case NM_P_U12:
20127 switch (extract32(ctx->opcode, 12, 4)) {
20128 case NM_ORI:
20129 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20130 break;
20131 case NM_XORI:
20132 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20133 break;
20134 case NM_ANDI:
20135 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20136 break;
20137 case NM_P_SR:
20138 switch (extract32(ctx->opcode, 20, 1)) {
20139 case NM_PP_SR:
20140 switch (ctx->opcode & 3) {
20141 case NM_SAVE:
20142 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20143 extract32(ctx->opcode, 2, 1),
20144 extract32(ctx->opcode, 3, 9) << 3);
20145 break;
20146 case NM_RESTORE:
20147 case NM_RESTORE_JRC:
20148 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20149 extract32(ctx->opcode, 2, 1),
20150 extract32(ctx->opcode, 3, 9) << 3);
20151 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20152 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20153 }
20154 break;
20155 default:
20156 generate_exception_end(ctx, EXCP_RI);
20157 break;
20158 }
20159 break;
20160 case NM_P_SR_F:
20161 generate_exception_end(ctx, EXCP_RI);
20162 break;
20163 }
20164 break;
20165 case NM_SLTI:
20166 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20167 break;
20168 case NM_SLTIU:
20169 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20170 break;
20171 case NM_SEQI:
20172 {
20173 TCGv t0 = tcg_temp_new();
20174
20175 imm = extract32(ctx->opcode, 0, 12);
20176 gen_load_gpr(t0, rs);
20177 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20178 gen_store_gpr(t0, rt);
20179
20180 tcg_temp_free(t0);
20181 }
20182 break;
20183 case NM_ADDIUNEG:
20184 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20185 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20186 break;
20187 case NM_P_SHIFT:
20188 {
20189 int shift = extract32(ctx->opcode, 0, 5);
20190 switch (extract32(ctx->opcode, 5, 4)) {
20191 case NM_P_SLL:
20192 if (rt == 0 && shift == 0) {
20193 /* NOP */
20194 } else if (rt == 0 && shift == 3) {
20195 /* EHB - treat as NOP */
20196 } else if (rt == 0 && shift == 5) {
20197 /* PAUSE - treat as NOP */
20198 } else if (rt == 0 && shift == 6) {
20199 /* SYNC */
20200 gen_sync(extract32(ctx->opcode, 16, 5));
20201 } else {
20202 /* SLL */
20203 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20204 extract32(ctx->opcode, 0, 5));
20205 }
20206 break;
20207 case NM_SRL:
20208 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20209 extract32(ctx->opcode, 0, 5));
20210 break;
20211 case NM_SRA:
20212 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20213 extract32(ctx->opcode, 0, 5));
20214 break;
20215 case NM_ROTR:
20216 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20217 extract32(ctx->opcode, 0, 5));
20218 break;
20219 }
20220 }
20221 break;
20222 case NM_P_ROTX:
fb32f8c8 20223 check_nms(ctx);
e222f506
MF
20224 if (rt != 0) {
20225 TCGv t0 = tcg_temp_new();
20226 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20227 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20228 << 1);
20229 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20230
20231 gen_load_gpr(t0, rs);
20232 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20233 tcg_temp_free(t0);
20234
20235 tcg_temp_free_i32(shift);
20236 tcg_temp_free_i32(shiftx);
20237 tcg_temp_free_i32(stripe);
20238 }
c0280983
YK
20239 break;
20240 case NM_P_INS:
20241 switch (((ctx->opcode >> 10) & 2) |
20242 (extract32(ctx->opcode, 5, 1))) {
20243 case NM_INS:
fb32f8c8 20244 check_nms(ctx);
c0280983
YK
20245 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20246 extract32(ctx->opcode, 6, 5));
20247 break;
20248 default:
20249 generate_exception_end(ctx, EXCP_RI);
20250 break;
20251 }
20252 break;
20253 case NM_P_EXT:
20254 switch (((ctx->opcode >> 10) & 2) |
20255 (extract32(ctx->opcode, 5, 1))) {
20256 case NM_EXT:
fb32f8c8 20257 check_nms(ctx);
c0280983
YK
20258 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20259 extract32(ctx->opcode, 6, 5));
20260 break;
20261 default:
20262 generate_exception_end(ctx, EXCP_RI);
20263 break;
20264 }
20265 break;
20266 default:
20267 generate_exception_end(ctx, EXCP_RI);
20268 break;
20269 }
20270 break;
20271 case NM_POOL32F:
579b8ea9 20272 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
20273 break;
20274 case NM_POOL32S:
20275 break;
20276 case NM_P_LUI:
20277 switch (extract32(ctx->opcode, 1, 1)) {
20278 case NM_LUI:
20279 if (rt != 0) {
20280 tcg_gen_movi_tl(cpu_gpr[rt],
20281 sextract32(ctx->opcode, 0, 1) << 31 |
20282 extract32(ctx->opcode, 2, 10) << 21 |
20283 extract32(ctx->opcode, 12, 9) << 12);
20284 }
20285 break;
20286 case NM_ALUIPC:
20287 if (rt != 0) {
20288 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20289 extract32(ctx->opcode, 2, 10) << 21 |
20290 extract32(ctx->opcode, 12, 9) << 12;
20291 target_long addr;
20292 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20293 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20294 }
20295 break;
20296 }
20297 break;
20298 case NM_P_GP_BH:
8f1d9b6d
YK
20299 {
20300 uint32_t u = extract32(ctx->opcode, 0, 18);
20301
20302 switch (extract32(ctx->opcode, 18, 3)) {
20303 case NM_LBGP:
20304 gen_ld(ctx, OPC_LB, rt, 28, u);
20305 break;
20306 case NM_SBGP:
20307 gen_st(ctx, OPC_SB, rt, 28, u);
20308 break;
20309 case NM_LBUGP:
20310 gen_ld(ctx, OPC_LBU, rt, 28, u);
20311 break;
20312 case NM_ADDIUGP_B:
20313 if (rt != 0) {
20314 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20315 }
20316 break;
20317 case NM_P_GP_LH:
20318 u &= ~1;
20319 switch (ctx->opcode & 1) {
20320 case NM_LHGP:
20321 gen_ld(ctx, OPC_LH, rt, 28, u);
20322 break;
20323 case NM_LHUGP:
20324 gen_ld(ctx, OPC_LHU, rt, 28, u);
20325 break;
20326 }
20327 break;
20328 case NM_P_GP_SH:
20329 u &= ~1;
20330 switch (ctx->opcode & 1) {
20331 case NM_SHGP:
20332 gen_st(ctx, OPC_SH, rt, 28, u);
20333 break;
20334 default:
20335 generate_exception_end(ctx, EXCP_RI);
20336 break;
20337 }
20338 break;
20339 case NM_P_GP_CP1:
20340 u &= ~0x3;
20341 switch (ctx->opcode & 0x3) {
20342 case NM_LWC1GP:
20343 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20344 break;
20345 case NM_LDC1GP:
20346 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20347 break;
20348 case NM_SWC1GP:
20349 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20350 break;
20351 case NM_SDC1GP:
20352 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20353 break;
20354 }
20355 break;
20356 default:
20357 generate_exception_end(ctx, EXCP_RI);
20358 break;
20359 }
20360 }
c0280983
YK
20361 break;
20362 case NM_P_LS_U12:
8f1d9b6d
YK
20363 {
20364 uint32_t u = extract32(ctx->opcode, 0, 12);
20365
20366 switch (extract32(ctx->opcode, 12, 4)) {
20367 case NM_P_PREFU12:
20368 if (rt == 31) {
20369 /* SYNCI */
20370 /* Break the TB to be able to sync copied instructions
20371 immediately */
20372 ctx->base.is_jmp = DISAS_STOP;
20373 } else {
20374 /* PREF */
20375 /* Treat as NOP. */
20376 }
20377 break;
20378 case NM_LB:
20379 gen_ld(ctx, OPC_LB, rt, rs, u);
20380 break;
20381 case NM_LH:
20382 gen_ld(ctx, OPC_LH, rt, rs, u);
20383 break;
20384 case NM_LW:
20385 gen_ld(ctx, OPC_LW, rt, rs, u);
20386 break;
20387 case NM_LBU:
20388 gen_ld(ctx, OPC_LBU, rt, rs, u);
20389 break;
20390 case NM_LHU:
20391 gen_ld(ctx, OPC_LHU, rt, rs, u);
20392 break;
20393 case NM_SB:
20394 gen_st(ctx, OPC_SB, rt, rs, u);
20395 break;
20396 case NM_SH:
20397 gen_st(ctx, OPC_SH, rt, rs, u);
20398 break;
20399 case NM_SW:
20400 gen_st(ctx, OPC_SW, rt, rs, u);
20401 break;
20402 case NM_LWC1:
20403 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20404 break;
20405 case NM_LDC1:
20406 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20407 break;
20408 case NM_SWC1:
20409 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20410 break;
20411 case NM_SDC1:
20412 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20413 break;
20414 default:
20415 generate_exception_end(ctx, EXCP_RI);
20416 break;
20417 }
20418 }
c0280983
YK
20419 break;
20420 case NM_P_LS_S9:
8f1d9b6d
YK
20421 {
20422 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20423 extract32(ctx->opcode, 0, 8);
20424
20425 switch (extract32(ctx->opcode, 8, 3)) {
20426 case NM_P_LS_S0:
20427 switch (extract32(ctx->opcode, 11, 4)) {
20428 case NM_LBS9:
20429 gen_ld(ctx, OPC_LB, rt, rs, s);
20430 break;
20431 case NM_LHS9:
20432 gen_ld(ctx, OPC_LH, rt, rs, s);
20433 break;
20434 case NM_LWS9:
20435 gen_ld(ctx, OPC_LW, rt, rs, s);
20436 break;
20437 case NM_LBUS9:
20438 gen_ld(ctx, OPC_LBU, rt, rs, s);
20439 break;
20440 case NM_LHUS9:
20441 gen_ld(ctx, OPC_LHU, rt, rs, s);
20442 break;
20443 case NM_SBS9:
20444 gen_st(ctx, OPC_SB, rt, rs, s);
20445 break;
20446 case NM_SHS9:
20447 gen_st(ctx, OPC_SH, rt, rs, s);
20448 break;
20449 case NM_SWS9:
20450 gen_st(ctx, OPC_SW, rt, rs, s);
20451 break;
20452 case NM_LWC1S9:
20453 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20454 break;
20455 case NM_LDC1S9:
20456 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20457 break;
20458 case NM_SWC1S9:
20459 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20460 break;
20461 case NM_SDC1S9:
20462 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20463 break;
20464 case NM_P_PREFS9:
20465 if (rt == 31) {
20466 /* SYNCI */
20467 /* Break the TB to be able to sync copied instructions
20468 immediately */
20469 ctx->base.is_jmp = DISAS_STOP;
20470 } else {
20471 /* PREF */
20472 /* Treat as NOP. */
20473 }
20474 break;
20475 default:
20476 generate_exception_end(ctx, EXCP_RI);
20477 break;
20478 }
20479 break;
20480 case NM_P_LS_S1:
20481 switch (extract32(ctx->opcode, 11, 4)) {
20482 case NM_UALH:
20483 case NM_UASH:
fb32f8c8 20484 check_nms(ctx);
8f1d9b6d
YK
20485 {
20486 TCGv t0 = tcg_temp_new();
20487 TCGv t1 = tcg_temp_new();
20488
20489 gen_base_offset_addr(ctx, t0, rs, s);
20490
20491 switch (extract32(ctx->opcode, 11, 4)) {
20492 case NM_UALH:
20493 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20494 MO_UNALN);
20495 gen_store_gpr(t0, rt);
20496 break;
20497 case NM_UASH:
20498 gen_load_gpr(t1, rt);
20499 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20500 MO_UNALN);
20501 break;
20502 }
20503 tcg_temp_free(t0);
20504 tcg_temp_free(t1);
20505 }
20506 break;
20507 case NM_P_LL:
20508 switch (ctx->opcode & 0x03) {
20509 case NM_LL:
20510 gen_ld(ctx, OPC_LL, rt, rs, s);
20511 break;
20512 case NM_LLWP:
0b16dcd1
AR
20513 check_xnp(ctx);
20514 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
20515 break;
20516 }
20517 break;
20518 case NM_P_SC:
20519 switch (ctx->opcode & 0x03) {
20520 case NM_SC:
20521 gen_st_cond(ctx, OPC_SC, rt, rs, s);
20522 break;
20523 case NM_SCWP:
0b16dcd1
AR
20524 check_xnp(ctx);
20525 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
20526 break;
20527 }
20528 break;
20529 case NM_CACHE:
20530 check_cp0_enabled(ctx);
20531 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20532 gen_cache_operation(ctx, rt, rs, s);
20533 }
20534 break;
20535 }
20536 break;
20537 case NM_P_LS_WM:
20538 case NM_P_LS_UAWM:
fb32f8c8 20539 check_nms(ctx);
8f1d9b6d
YK
20540 {
20541 int count = extract32(ctx->opcode, 12, 3);
20542 int counter = 0;
20543
20544 offset = sextract32(ctx->opcode, 15, 1) << 8 |
20545 extract32(ctx->opcode, 0, 8);
20546 TCGv va = tcg_temp_new();
20547 TCGv t1 = tcg_temp_new();
20548 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20549 NM_P_LS_UAWM ? MO_UNALN : 0;
20550
20551 count = (count == 0) ? 8 : count;
20552 while (counter != count) {
20553 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20554 int this_offset = offset + (counter << 2);
20555
20556 gen_base_offset_addr(ctx, va, rs, this_offset);
20557
20558 switch (extract32(ctx->opcode, 11, 1)) {
20559 case NM_LWM:
20560 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20561 memop | MO_TESL);
20562 gen_store_gpr(t1, this_rt);
20563 if ((this_rt == rs) &&
20564 (counter != (count - 1))) {
20565 /* UNPREDICTABLE */
20566 }
20567 break;
20568 case NM_SWM:
20569 this_rt = (rt == 0) ? 0 : this_rt;
20570 gen_load_gpr(t1, this_rt);
20571 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20572 memop | MO_TEUL);
20573 break;
20574 }
20575 counter++;
20576 }
20577 tcg_temp_free(va);
20578 tcg_temp_free(t1);
20579 }
20580 break;
20581 default:
20582 generate_exception_end(ctx, EXCP_RI);
20583 break;
20584 }
20585 }
c0280983
YK
20586 break;
20587 case NM_MOVE_BALC:
fb32f8c8 20588 check_nms(ctx);
11d0fc10
SM
20589 {
20590 TCGv t0 = tcg_temp_new();
20591 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20592 extract32(ctx->opcode, 1, 20) << 1;
20593 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20594 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20595 extract32(ctx->opcode, 21, 3));
20596 gen_load_gpr(t0, rt);
20597 tcg_gen_mov_tl(cpu_gpr[rd], t0);
20598 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20599 tcg_temp_free(t0);
20600 }
c0280983
YK
20601 break;
20602 case NM_P_BAL:
11d0fc10
SM
20603 {
20604 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20605 extract32(ctx->opcode, 1, 24) << 1;
20606
20607 if ((extract32(ctx->opcode, 25, 1)) == 0) {
20608 /* BC */
20609 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20610 } else {
20611 /* BALC */
20612 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20613 }
20614 }
c0280983
YK
20615 break;
20616 case NM_P_J:
11d0fc10
SM
20617 switch (extract32(ctx->opcode, 12, 4)) {
20618 case NM_JALRC:
20619 case NM_JALRC_HB:
20620 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20621 break;
20622 case NM_P_BALRSC:
20623 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20624 break;
20625 default:
20626 generate_exception_end(ctx, EXCP_RI);
20627 break;
20628 }
c0280983
YK
20629 break;
20630 case NM_P_BR1:
11d0fc10
SM
20631 {
20632 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20633 extract32(ctx->opcode, 1, 13) << 1;
20634 switch (extract32(ctx->opcode, 14, 2)) {
20635 case NM_BEQC:
fb32f8c8 20636 check_nms(ctx);
11d0fc10
SM
20637 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20638 break;
20639 case NM_P_BR3A:
20640 s = sextract32(ctx->opcode, 0, 1) << 14 |
20641 extract32(ctx->opcode, 1, 13) << 1;
20642 check_cp1_enabled(ctx);
20643 switch (extract32(ctx->opcode, 16, 5)) {
20644 case NM_BC1EQZC:
20645 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20646 break;
20647 case NM_BC1NEZC:
20648 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20649 break;
6d033ca7 20650 case NM_BPOSGE32C:
908f6be1 20651 check_dsp_r3(ctx);
6d033ca7
SM
20652 {
20653 int32_t imm = extract32(ctx->opcode, 1, 13) |
20654 extract32(ctx->opcode, 0, 1) << 13;
20655
20656 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20657 imm);
20658 }
20659 break;
11d0fc10
SM
20660 default:
20661 generate_exception_end(ctx, EXCP_RI);
20662 break;
20663 }
20664 break;
20665 case NM_BGEC:
20666 if (rs == rt) {
20667 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20668 } else {
20669 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20670 }
20671 break;
20672 case NM_BGEUC:
20673 if (rs == rt || rt == 0) {
20674 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20675 } else if (rs == 0) {
20676 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20677 } else {
20678 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20679 }
20680 break;
20681 }
20682 }
c0280983
YK
20683 break;
20684 case NM_P_BR2:
11d0fc10
SM
20685 {
20686 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20687 extract32(ctx->opcode, 1, 13) << 1;
20688 switch (extract32(ctx->opcode, 14, 2)) {
20689 case NM_BNEC:
fb32f8c8 20690 check_nms(ctx);
11d0fc10
SM
20691 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20692 break;
20693 case NM_BLTC:
20694 if (rs != 0 && rt != 0 && rs == rt) {
20695 /* NOP */
20696 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20697 } else {
20698 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20699 }
20700 break;
20701 case NM_BLTUC:
20702 if (rs == 0 || rs == rt) {
20703 /* NOP */
20704 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20705 } else {
20706 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20707 }
20708 break;
20709 default:
20710 generate_exception_end(ctx, EXCP_RI);
20711 break;
20712 }
20713 }
c0280983
YK
20714 break;
20715 case NM_P_BRI:
11d0fc10
SM
20716 {
20717 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20718 extract32(ctx->opcode, 1, 10) << 1;
20719 uint32_t u = extract32(ctx->opcode, 11, 7);
20720
20721 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20722 rt, u, s);
20723 }
c0280983
YK
20724 break;
20725 default:
20726 generate_exception_end(ctx, EXCP_RI);
20727 break;
20728 }
20729 return 4;
20730}
20731
c533c0f4
AM
20732static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20733{
ea4ca3c2
YK
20734 uint32_t op;
20735 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20736 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20737 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
8bdb7029 20738 int offset;
ea4ca3c2
YK
20739 int imm;
20740
20741 /* make sure instructions are on a halfword boundary */
20742 if (ctx->base.pc_next & 0x1) {
20743 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20744 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20745 tcg_temp_free(tmp);
20746 generate_exception_end(ctx, EXCP_AdEL);
20747 return 2;
20748 }
20749
20750 op = extract32(ctx->opcode, 10, 6);
20751 switch (op) {
20752 case NM_P16_MV:
8869ad02
YK
20753 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20754 if (rt != 0) {
20755 /* MOVE */
20756 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20757 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20758 } else {
20759 /* P16.RI */
20760 switch (extract32(ctx->opcode, 3, 2)) {
20761 case NM_P16_SYSCALL:
20762 if (extract32(ctx->opcode, 2, 1) == 0) {
20763 generate_exception_end(ctx, EXCP_SYSCALL);
20764 } else {
20765 generate_exception_end(ctx, EXCP_RI);
20766 }
20767 break;
20768 case NM_BREAK16:
20769 generate_exception_end(ctx, EXCP_BREAK);
20770 break;
20771 case NM_SDBBP16:
20772 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20773 gen_helper_do_semihosting(cpu_env);
20774 } else {
20775 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20776 generate_exception_end(ctx, EXCP_RI);
20777 } else {
20778 generate_exception_end(ctx, EXCP_DBp);
20779 }
20780 }
20781 break;
20782 default:
20783 generate_exception_end(ctx, EXCP_RI);
20784 break;
20785 }
20786 }
ea4ca3c2
YK
20787 break;
20788 case NM_P16_SHIFT:
c46562fb
YK
20789 {
20790 int shift = extract32(ctx->opcode, 0, 3);
20791 uint32_t opc = 0;
20792 shift = (shift == 0) ? 8 : shift;
20793
20794 switch (extract32(ctx->opcode, 3, 1)) {
20795 case NM_SLL16:
20796 opc = OPC_SLL;
20797 break;
20798 case NM_SRL16:
20799 opc = OPC_SRL;
20800 break;
20801 }
20802 gen_shift_imm(ctx, opc, rt, rs, shift);
20803 }
ea4ca3c2
YK
20804 break;
20805 case NM_P16C:
8bdb7029
YK
20806 switch (ctx->opcode & 1) {
20807 case NM_POOL16C_0:
80845edf 20808 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
20809 break;
20810 case NM_LWXS16:
20811 gen_ldxs(ctx, rt, rs, rd);
20812 break;
20813 }
ea4ca3c2
YK
20814 break;
20815 case NM_P16_A1:
20816 switch (extract32(ctx->opcode, 6, 1)) {
20817 case NM_ADDIUR1SP:
20818 imm = extract32(ctx->opcode, 0, 6) << 2;
20819 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20820 break;
20821 default:
20822 generate_exception_end(ctx, EXCP_RI);
20823 break;
20824 }
20825 break;
20826 case NM_P16_A2:
20827 switch (extract32(ctx->opcode, 3, 1)) {
20828 case NM_ADDIUR2:
20829 imm = extract32(ctx->opcode, 0, 3) << 2;
20830 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20831 break;
20832 case NM_P_ADDIURS5:
20833 rt = extract32(ctx->opcode, 5, 5);
20834 if (rt != 0) {
20835 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20836 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20837 (extract32(ctx->opcode, 0, 3));
20838 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20839 }
20840 break;
20841 }
20842 break;
20843 case NM_P16_ADDU:
20844 switch (ctx->opcode & 0x1) {
20845 case NM_ADDU16:
20846 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20847 break;
20848 case NM_SUBU16:
20849 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20850 break;
20851 }
20852 break;
20853 case NM_P16_4X4:
20854 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20855 extract32(ctx->opcode, 5, 3);
20856 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20857 extract32(ctx->opcode, 0, 3);
20858 rt = decode_gpr_gpr4(rt);
20859 rs = decode_gpr_gpr4(rs);
20860 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20861 (extract32(ctx->opcode, 3, 1))) {
20862 case NM_ADDU4X4:
fb32f8c8 20863 check_nms(ctx);
ea4ca3c2
YK
20864 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20865 break;
20866 case NM_MUL4X4:
fb32f8c8 20867 check_nms(ctx);
ea4ca3c2
YK
20868 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20869 break;
20870 default:
20871 generate_exception_end(ctx, EXCP_RI);
20872 break;
20873 }
20874 break;
20875 case NM_LI16:
8869ad02
YK
20876 {
20877 int imm = extract32(ctx->opcode, 0, 7);
20878 imm = (imm == 0x7f ? -1 : imm);
20879 if (rt != 0) {
20880 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20881 }
20882 }
ea4ca3c2
YK
20883 break;
20884 case NM_ANDI16:
80845edf
YK
20885 {
20886 uint32_t u = extract32(ctx->opcode, 0, 4);
20887 u = (u == 12) ? 0xff :
20888 (u == 13) ? 0xffff : u;
20889 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
20890 }
ea4ca3c2
YK
20891 break;
20892 case NM_P16_LB:
8bdb7029
YK
20893 offset = extract32(ctx->opcode, 0, 2);
20894 switch (extract32(ctx->opcode, 2, 2)) {
20895 case NM_LB16:
20896 gen_ld(ctx, OPC_LB, rt, rs, offset);
20897 break;
20898 case NM_SB16:
20899 rt = decode_gpr_gpr3_src_store(
20900 NANOMIPS_EXTRACT_RD(ctx->opcode));
20901 gen_st(ctx, OPC_SB, rt, rs, offset);
20902 break;
20903 case NM_LBU16:
20904 gen_ld(ctx, OPC_LBU, rt, rs, offset);
20905 break;
20906 default:
20907 generate_exception_end(ctx, EXCP_RI);
20908 break;
20909 }
ea4ca3c2
YK
20910 break;
20911 case NM_P16_LH:
8bdb7029
YK
20912 offset = extract32(ctx->opcode, 1, 2) << 1;
20913 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
20914 case NM_LH16:
20915 gen_ld(ctx, OPC_LH, rt, rs, offset);
20916 break;
20917 case NM_SH16:
20918 rt = decode_gpr_gpr3_src_store(
20919 NANOMIPS_EXTRACT_RD(ctx->opcode));
20920 gen_st(ctx, OPC_SH, rt, rs, offset);
20921 break;
20922 case NM_LHU16:
20923 gen_ld(ctx, OPC_LHU, rt, rs, offset);
20924 break;
20925 default:
20926 generate_exception_end(ctx, EXCP_RI);
20927 break;
20928 }
ea4ca3c2
YK
20929 break;
20930 case NM_LW16:
8bdb7029
YK
20931 offset = extract32(ctx->opcode, 0, 4) << 2;
20932 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
20933 break;
20934 case NM_LWSP16:
8bdb7029
YK
20935 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20936 offset = extract32(ctx->opcode, 0, 5) << 2;
20937 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
20938 break;
20939 case NM_LW4X4:
fb32f8c8 20940 check_nms(ctx);
8bdb7029
YK
20941 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20942 extract32(ctx->opcode, 5, 3);
20943 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20944 extract32(ctx->opcode, 0, 3);
20945 offset = (extract32(ctx->opcode, 3, 1) << 3) |
20946 (extract32(ctx->opcode, 8, 1) << 2);
20947 rt = decode_gpr_gpr4(rt);
20948 rs = decode_gpr_gpr4(rs);
20949 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
20950 break;
20951 case NM_SW4X4:
fb32f8c8 20952 check_nms(ctx);
8bdb7029
YK
20953 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20954 extract32(ctx->opcode, 5, 3);
20955 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20956 extract32(ctx->opcode, 0, 3);
20957 offset = (extract32(ctx->opcode, 3, 1) << 3) |
20958 (extract32(ctx->opcode, 8, 1) << 2);
20959 rt = decode_gpr_gpr4_zero(rt);
20960 rs = decode_gpr_gpr4(rs);
20961 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
20962 break;
20963 case NM_LWGP16:
8bdb7029
YK
20964 offset = extract32(ctx->opcode, 0, 7) << 2;
20965 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
20966 break;
20967 case NM_SWSP16:
8bdb7029
YK
20968 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20969 offset = extract32(ctx->opcode, 0, 5) << 2;
20970 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
20971 break;
20972 case NM_SW16:
8bdb7029
YK
20973 rt = decode_gpr_gpr3_src_store(
20974 NANOMIPS_EXTRACT_RD(ctx->opcode));
20975 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20976 offset = extract32(ctx->opcode, 0, 4) << 2;
20977 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
20978 break;
20979 case NM_SWGP16:
8bdb7029
YK
20980 rt = decode_gpr_gpr3_src_store(
20981 NANOMIPS_EXTRACT_RD(ctx->opcode));
20982 offset = extract32(ctx->opcode, 0, 7) << 2;
20983 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
20984 break;
20985 case NM_BC16:
764371d2
SM
20986 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
20987 (sextract32(ctx->opcode, 0, 1) << 10) |
20988 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
20989 break;
20990 case NM_BALC16:
764371d2
SM
20991 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
20992 (sextract32(ctx->opcode, 0, 1) << 10) |
20993 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
20994 break;
20995 case NM_BEQZC16:
764371d2
SM
20996 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
20997 (sextract32(ctx->opcode, 0, 1) << 7) |
20998 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
20999 break;
21000 case NM_BNEZC16:
764371d2
SM
21001 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21002 (sextract32(ctx->opcode, 0, 1) << 7) |
21003 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21004 break;
21005 case NM_P16_BR:
764371d2
SM
21006 switch (ctx->opcode & 0xf) {
21007 case 0:
21008 /* P16.JRC */
21009 switch (extract32(ctx->opcode, 4, 1)) {
21010 case NM_JRC:
21011 gen_compute_branch_nm(ctx, OPC_JR, 2,
21012 extract32(ctx->opcode, 5, 5), 0, 0);
21013 break;
21014 case NM_JALRC16:
21015 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21016 extract32(ctx->opcode, 5, 5), 31, 0);
21017 break;
21018 }
21019 break;
21020 default:
21021 {
21022 /* P16.BRI */
21023 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21024 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21025 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21026 extract32(ctx->opcode, 0, 4) << 1);
21027 }
21028 break;
21029 }
ea4ca3c2
YK
21030 break;
21031 case NM_P16_SR:
bf0718c5
SM
21032 {
21033 int count = extract32(ctx->opcode, 0, 4);
21034 int u = extract32(ctx->opcode, 4, 4) << 4;
21035
21036 rt = 30 + extract32(ctx->opcode, 9, 1);
21037 switch (extract32(ctx->opcode, 8, 1)) {
21038 case NM_SAVE16:
21039 gen_save(ctx, rt, count, 0, u);
21040 break;
21041 case NM_RESTORE_JRC16:
21042 gen_restore(ctx, rt, count, 0, u);
21043 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21044 break;
21045 }
21046 }
ea4ca3c2
YK
21047 break;
21048 case NM_MOVEP:
ea4ca3c2 21049 case NM_MOVEPREV:
fb32f8c8 21050 check_nms(ctx);
4d18232c
YK
21051 {
21052 static const int gpr2reg1[] = {4, 5, 6, 7};
21053 static const int gpr2reg2[] = {5, 6, 7, 8};
21054 int re;
21055 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21056 extract32(ctx->opcode, 8, 1);
21057 int r1 = gpr2reg1[rd2];
21058 int r2 = gpr2reg2[rd2];
21059 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21060 extract32(ctx->opcode, 0, 3);
21061 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21062 extract32(ctx->opcode, 5, 3);
21063 TCGv t0 = tcg_temp_new();
21064 TCGv t1 = tcg_temp_new();
21065 if (op == NM_MOVEP) {
21066 rd = r1;
21067 re = r2;
21068 rs = decode_gpr_gpr4_zero(r3);
21069 rt = decode_gpr_gpr4_zero(r4);
21070 } else {
21071 rd = decode_gpr_gpr4(r3);
21072 re = decode_gpr_gpr4(r4);
21073 rs = r1;
21074 rt = r2;
21075 }
21076 gen_load_gpr(t0, rs);
21077 gen_load_gpr(t1, rt);
21078 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21079 tcg_gen_mov_tl(cpu_gpr[re], t1);
21080 tcg_temp_free(t0);
21081 tcg_temp_free(t1);
21082 }
ea4ca3c2
YK
21083 break;
21084 default:
c0280983 21085 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
21086 }
21087
c533c0f4
AM
21088 return 2;
21089}
21090
21091
3c824109
NF
21092/* SmartMIPS extension to MIPS32 */
21093
21094#if defined(TARGET_MIPS64)
21095
21096/* MDMX extension to MIPS64 */
21097
21098#endif
21099
9b1a1d68 21100/* MIPSDSP functions. */
d75c135e 21101static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
21102 int rd, int base, int offset)
21103{
9b1a1d68
JL
21104 TCGv t0;
21105
9b1a1d68
JL
21106 check_dsp(ctx);
21107 t0 = tcg_temp_new();
21108
21109 if (base == 0) {
21110 gen_load_gpr(t0, offset);
21111 } else if (offset == 0) {
21112 gen_load_gpr(t0, base);
21113 } else {
21114 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21115 }
21116
9b1a1d68
JL
21117 switch (opc) {
21118 case OPC_LBUX:
5f68f5ae 21119 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 21120 gen_store_gpr(t0, rd);
9b1a1d68
JL
21121 break;
21122 case OPC_LHX:
5f68f5ae 21123 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 21124 gen_store_gpr(t0, rd);
9b1a1d68
JL
21125 break;
21126 case OPC_LWX:
5f68f5ae 21127 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 21128 gen_store_gpr(t0, rd);
9b1a1d68
JL
21129 break;
21130#if defined(TARGET_MIPS64)
21131 case OPC_LDX:
5f68f5ae 21132 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 21133 gen_store_gpr(t0, rd);
9b1a1d68
JL
21134 break;
21135#endif
21136 }
9b1a1d68
JL
21137 tcg_temp_free(t0);
21138}
21139
461c08df
JL
21140static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21141 int ret, int v1, int v2)
21142{
461c08df
JL
21143 TCGv v1_t;
21144 TCGv v2_t;
21145
21146 if (ret == 0) {
21147 /* Treat as NOP. */
461c08df
JL
21148 return;
21149 }
21150
21151 v1_t = tcg_temp_new();
21152 v2_t = tcg_temp_new();
21153
21154 gen_load_gpr(v1_t, v1);
21155 gen_load_gpr(v2_t, v2);
21156
21157 switch (op1) {
21158 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21159 case OPC_MULT_G_2E:
908f6be1 21160 check_dsp_r2(ctx);
461c08df
JL
21161 switch (op2) {
21162 case OPC_ADDUH_QB:
21163 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21164 break;
21165 case OPC_ADDUH_R_QB:
21166 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21167 break;
21168 case OPC_ADDQH_PH:
21169 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21170 break;
21171 case OPC_ADDQH_R_PH:
21172 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21173 break;
21174 case OPC_ADDQH_W:
21175 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21176 break;
21177 case OPC_ADDQH_R_W:
21178 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21179 break;
21180 case OPC_SUBUH_QB:
21181 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21182 break;
21183 case OPC_SUBUH_R_QB:
21184 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21185 break;
21186 case OPC_SUBQH_PH:
21187 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21188 break;
21189 case OPC_SUBQH_R_PH:
21190 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21191 break;
21192 case OPC_SUBQH_W:
21193 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21194 break;
21195 case OPC_SUBQH_R_W:
21196 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21197 break;
21198 }
21199 break;
21200 case OPC_ABSQ_S_PH_DSP:
21201 switch (op2) {
21202 case OPC_ABSQ_S_QB:
908f6be1 21203 check_dsp_r2(ctx);
461c08df
JL
21204 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21205 break;
21206 case OPC_ABSQ_S_PH:
21207 check_dsp(ctx);
21208 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21209 break;
21210 case OPC_ABSQ_S_W:
21211 check_dsp(ctx);
21212 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21213 break;
21214 case OPC_PRECEQ_W_PHL:
21215 check_dsp(ctx);
21216 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21217 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21218 break;
21219 case OPC_PRECEQ_W_PHR:
21220 check_dsp(ctx);
21221 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21222 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21223 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21224 break;
21225 case OPC_PRECEQU_PH_QBL:
21226 check_dsp(ctx);
21227 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21228 break;
21229 case OPC_PRECEQU_PH_QBR:
21230 check_dsp(ctx);
21231 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21232 break;
21233 case OPC_PRECEQU_PH_QBLA:
21234 check_dsp(ctx);
21235 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21236 break;
21237 case OPC_PRECEQU_PH_QBRA:
21238 check_dsp(ctx);
21239 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21240 break;
21241 case OPC_PRECEU_PH_QBL:
21242 check_dsp(ctx);
21243 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21244 break;
21245 case OPC_PRECEU_PH_QBR:
21246 check_dsp(ctx);
21247 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21248 break;
21249 case OPC_PRECEU_PH_QBLA:
21250 check_dsp(ctx);
21251 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21252 break;
21253 case OPC_PRECEU_PH_QBRA:
21254 check_dsp(ctx);
21255 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21256 break;
21257 }
21258 break;
21259 case OPC_ADDU_QB_DSP:
21260 switch (op2) {
21261 case OPC_ADDQ_PH:
21262 check_dsp(ctx);
21263 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21264 break;
21265 case OPC_ADDQ_S_PH:
21266 check_dsp(ctx);
21267 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21268 break;
21269 case OPC_ADDQ_S_W:
21270 check_dsp(ctx);
21271 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21272 break;
21273 case OPC_ADDU_QB:
21274 check_dsp(ctx);
21275 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21276 break;
21277 case OPC_ADDU_S_QB:
21278 check_dsp(ctx);
21279 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21280 break;
21281 case OPC_ADDU_PH:
908f6be1 21282 check_dsp_r2(ctx);
461c08df
JL
21283 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21284 break;
21285 case OPC_ADDU_S_PH:
908f6be1 21286 check_dsp_r2(ctx);
461c08df
JL
21287 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21288 break;
21289 case OPC_SUBQ_PH:
21290 check_dsp(ctx);
21291 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21292 break;
21293 case OPC_SUBQ_S_PH:
21294 check_dsp(ctx);
21295 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21296 break;
21297 case OPC_SUBQ_S_W:
21298 check_dsp(ctx);
21299 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21300 break;
21301 case OPC_SUBU_QB:
21302 check_dsp(ctx);
21303 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21304 break;
21305 case OPC_SUBU_S_QB:
21306 check_dsp(ctx);
21307 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21308 break;
21309 case OPC_SUBU_PH:
908f6be1 21310 check_dsp_r2(ctx);
461c08df
JL
21311 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21312 break;
21313 case OPC_SUBU_S_PH:
908f6be1 21314 check_dsp_r2(ctx);
461c08df
JL
21315 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21316 break;
21317 case OPC_ADDSC:
21318 check_dsp(ctx);
21319 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21320 break;
21321 case OPC_ADDWC:
21322 check_dsp(ctx);
21323 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21324 break;
21325 case OPC_MODSUB:
21326 check_dsp(ctx);
21327 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21328 break;
21329 case OPC_RADDU_W_QB:
21330 check_dsp(ctx);
21331 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21332 break;
21333 }
21334 break;
21335 case OPC_CMPU_EQ_QB_DSP:
21336 switch (op2) {
21337 case OPC_PRECR_QB_PH:
908f6be1 21338 check_dsp_r2(ctx);
461c08df
JL
21339 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21340 break;
21341 case OPC_PRECRQ_QB_PH:
21342 check_dsp(ctx);
21343 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21344 break;
21345 case OPC_PRECR_SRA_PH_W:
908f6be1 21346 check_dsp_r2(ctx);
461c08df
JL
21347 {
21348 TCGv_i32 sa_t = tcg_const_i32(v2);
21349 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21350 cpu_gpr[ret]);
21351 tcg_temp_free_i32(sa_t);
21352 break;
21353 }
21354 case OPC_PRECR_SRA_R_PH_W:
908f6be1 21355 check_dsp_r2(ctx);
461c08df
JL
21356 {
21357 TCGv_i32 sa_t = tcg_const_i32(v2);
21358 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21359 cpu_gpr[ret]);
21360 tcg_temp_free_i32(sa_t);
21361 break;
21362 }
21363 case OPC_PRECRQ_PH_W:
21364 check_dsp(ctx);
21365 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21366 break;
21367 case OPC_PRECRQ_RS_PH_W:
21368 check_dsp(ctx);
21369 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21370 break;
21371 case OPC_PRECRQU_S_QB_PH:
21372 check_dsp(ctx);
21373 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21374 break;
21375 }
21376 break;
21377#ifdef TARGET_MIPS64
21378 case OPC_ABSQ_S_QH_DSP:
21379 switch (op2) {
21380 case OPC_PRECEQ_L_PWL:
21381 check_dsp(ctx);
21382 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21383 break;
21384 case OPC_PRECEQ_L_PWR:
21385 check_dsp(ctx);
21386 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21387 break;
21388 case OPC_PRECEQ_PW_QHL:
21389 check_dsp(ctx);
21390 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21391 break;
21392 case OPC_PRECEQ_PW_QHR:
21393 check_dsp(ctx);
21394 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21395 break;
21396 case OPC_PRECEQ_PW_QHLA:
21397 check_dsp(ctx);
21398 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21399 break;
21400 case OPC_PRECEQ_PW_QHRA:
21401 check_dsp(ctx);
21402 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21403 break;
21404 case OPC_PRECEQU_QH_OBL:
21405 check_dsp(ctx);
21406 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21407 break;
21408 case OPC_PRECEQU_QH_OBR:
21409 check_dsp(ctx);
21410 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21411 break;
21412 case OPC_PRECEQU_QH_OBLA:
21413 check_dsp(ctx);
21414 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21415 break;
21416 case OPC_PRECEQU_QH_OBRA:
21417 check_dsp(ctx);
21418 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21419 break;
21420 case OPC_PRECEU_QH_OBL:
21421 check_dsp(ctx);
21422 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21423 break;
21424 case OPC_PRECEU_QH_OBR:
21425 check_dsp(ctx);
21426 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21427 break;
21428 case OPC_PRECEU_QH_OBLA:
21429 check_dsp(ctx);
21430 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21431 break;
21432 case OPC_PRECEU_QH_OBRA:
21433 check_dsp(ctx);
21434 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21435 break;
21436 case OPC_ABSQ_S_OB:
908f6be1 21437 check_dsp_r2(ctx);
461c08df
JL
21438 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21439 break;
21440 case OPC_ABSQ_S_PW:
21441 check_dsp(ctx);
21442 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21443 break;
21444 case OPC_ABSQ_S_QH:
21445 check_dsp(ctx);
21446 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21447 break;
21448 }
21449 break;
21450 case OPC_ADDU_OB_DSP:
21451 switch (op2) {
21452 case OPC_RADDU_L_OB:
21453 check_dsp(ctx);
21454 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21455 break;
21456 case OPC_SUBQ_PW:
21457 check_dsp(ctx);
21458 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21459 break;
21460 case OPC_SUBQ_S_PW:
21461 check_dsp(ctx);
21462 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21463 break;
21464 case OPC_SUBQ_QH:
21465 check_dsp(ctx);
21466 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21467 break;
21468 case OPC_SUBQ_S_QH:
21469 check_dsp(ctx);
21470 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21471 break;
21472 case OPC_SUBU_OB:
21473 check_dsp(ctx);
21474 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21475 break;
21476 case OPC_SUBU_S_OB:
21477 check_dsp(ctx);
21478 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21479 break;
21480 case OPC_SUBU_QH:
908f6be1 21481 check_dsp_r2(ctx);
461c08df
JL
21482 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21483 break;
21484 case OPC_SUBU_S_QH:
908f6be1 21485 check_dsp_r2(ctx);
461c08df
JL
21486 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21487 break;
21488 case OPC_SUBUH_OB:
908f6be1 21489 check_dsp_r2(ctx);
461c08df
JL
21490 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21491 break;
21492 case OPC_SUBUH_R_OB:
908f6be1 21493 check_dsp_r2(ctx);
461c08df
JL
21494 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21495 break;
21496 case OPC_ADDQ_PW:
21497 check_dsp(ctx);
21498 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21499 break;
21500 case OPC_ADDQ_S_PW:
21501 check_dsp(ctx);
21502 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21503 break;
21504 case OPC_ADDQ_QH:
21505 check_dsp(ctx);
21506 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21507 break;
21508 case OPC_ADDQ_S_QH:
21509 check_dsp(ctx);
21510 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21511 break;
21512 case OPC_ADDU_OB:
21513 check_dsp(ctx);
21514 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21515 break;
21516 case OPC_ADDU_S_OB:
21517 check_dsp(ctx);
21518 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21519 break;
21520 case OPC_ADDU_QH:
908f6be1 21521 check_dsp_r2(ctx);
461c08df
JL
21522 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21523 break;
21524 case OPC_ADDU_S_QH:
908f6be1 21525 check_dsp_r2(ctx);
461c08df
JL
21526 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21527 break;
21528 case OPC_ADDUH_OB:
908f6be1 21529 check_dsp_r2(ctx);
461c08df
JL
21530 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21531 break;
21532 case OPC_ADDUH_R_OB:
908f6be1 21533 check_dsp_r2(ctx);
461c08df
JL
21534 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21535 break;
21536 }
21537 break;
21538 case OPC_CMPU_EQ_OB_DSP:
21539 switch (op2) {
21540 case OPC_PRECR_OB_QH:
908f6be1 21541 check_dsp_r2(ctx);
461c08df
JL
21542 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21543 break;
21544 case OPC_PRECR_SRA_QH_PW:
908f6be1 21545 check_dsp_r2(ctx);
461c08df
JL
21546 {
21547 TCGv_i32 ret_t = tcg_const_i32(ret);
21548 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21549 tcg_temp_free_i32(ret_t);
21550 break;
21551 }
21552 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 21553 check_dsp_r2(ctx);
461c08df
JL
21554 {
21555 TCGv_i32 sa_v = tcg_const_i32(ret);
21556 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21557 tcg_temp_free_i32(sa_v);
21558 break;
21559 }
21560 case OPC_PRECRQ_OB_QH:
21561 check_dsp(ctx);
21562 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21563 break;
21564 case OPC_PRECRQ_PW_L:
21565 check_dsp(ctx);
21566 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21567 break;
21568 case OPC_PRECRQ_QH_PW:
21569 check_dsp(ctx);
21570 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21571 break;
21572 case OPC_PRECRQ_RS_QH_PW:
21573 check_dsp(ctx);
21574 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21575 break;
21576 case OPC_PRECRQU_S_OB_QH:
21577 check_dsp(ctx);
21578 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21579 break;
21580 }
21581 break;
21582#endif
21583 }
21584
21585 tcg_temp_free(v1_t);
21586 tcg_temp_free(v2_t);
461c08df 21587}
9b1a1d68 21588
77c5fa8b
JL
21589static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21590 int ret, int v1, int v2)
21591{
21592 uint32_t op2;
77c5fa8b
JL
21593 TCGv t0;
21594 TCGv v1_t;
21595 TCGv v2_t;
21596
21597 if (ret == 0) {
21598 /* Treat as NOP. */
77c5fa8b
JL
21599 return;
21600 }
21601
21602 t0 = tcg_temp_new();
21603 v1_t = tcg_temp_new();
21604 v2_t = tcg_temp_new();
21605
21606 tcg_gen_movi_tl(t0, v1);
21607 gen_load_gpr(v1_t, v1);
21608 gen_load_gpr(v2_t, v2);
21609
21610 switch (opc) {
21611 case OPC_SHLL_QB_DSP:
21612 {
21613 op2 = MASK_SHLL_QB(ctx->opcode);
21614 switch (op2) {
21615 case OPC_SHLL_QB:
21616 check_dsp(ctx);
21617 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21618 break;
21619 case OPC_SHLLV_QB:
21620 check_dsp(ctx);
21621 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21622 break;
21623 case OPC_SHLL_PH:
21624 check_dsp(ctx);
21625 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21626 break;
21627 case OPC_SHLLV_PH:
21628 check_dsp(ctx);
21629 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21630 break;
21631 case OPC_SHLL_S_PH:
21632 check_dsp(ctx);
21633 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21634 break;
21635 case OPC_SHLLV_S_PH:
21636 check_dsp(ctx);
21637 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21638 break;
21639 case OPC_SHLL_S_W:
21640 check_dsp(ctx);
21641 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21642 break;
21643 case OPC_SHLLV_S_W:
21644 check_dsp(ctx);
21645 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21646 break;
21647 case OPC_SHRL_QB:
21648 check_dsp(ctx);
21649 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21650 break;
21651 case OPC_SHRLV_QB:
21652 check_dsp(ctx);
21653 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21654 break;
21655 case OPC_SHRL_PH:
908f6be1 21656 check_dsp_r2(ctx);
77c5fa8b
JL
21657 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21658 break;
21659 case OPC_SHRLV_PH:
908f6be1 21660 check_dsp_r2(ctx);
77c5fa8b
JL
21661 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21662 break;
21663 case OPC_SHRA_QB:
908f6be1 21664 check_dsp_r2(ctx);
77c5fa8b
JL
21665 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21666 break;
21667 case OPC_SHRA_R_QB:
908f6be1 21668 check_dsp_r2(ctx);
77c5fa8b
JL
21669 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21670 break;
21671 case OPC_SHRAV_QB:
908f6be1 21672 check_dsp_r2(ctx);
77c5fa8b
JL
21673 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21674 break;
21675 case OPC_SHRAV_R_QB:
908f6be1 21676 check_dsp_r2(ctx);
77c5fa8b
JL
21677 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21678 break;
21679 case OPC_SHRA_PH:
21680 check_dsp(ctx);
21681 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21682 break;
21683 case OPC_SHRA_R_PH:
21684 check_dsp(ctx);
21685 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21686 break;
21687 case OPC_SHRAV_PH:
21688 check_dsp(ctx);
21689 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21690 break;
21691 case OPC_SHRAV_R_PH:
21692 check_dsp(ctx);
21693 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21694 break;
21695 case OPC_SHRA_R_W:
21696 check_dsp(ctx);
21697 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21698 break;
21699 case OPC_SHRAV_R_W:
21700 check_dsp(ctx);
21701 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21702 break;
21703 default: /* Invalid */
21704 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 21705 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
21706 break;
21707 }
21708 break;
21709 }
21710#ifdef TARGET_MIPS64
21711 case OPC_SHLL_OB_DSP:
21712 op2 = MASK_SHLL_OB(ctx->opcode);
21713 switch (op2) {
21714 case OPC_SHLL_PW:
21715 check_dsp(ctx);
21716 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21717 break;
21718 case OPC_SHLLV_PW:
21719 check_dsp(ctx);
21720 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21721 break;
21722 case OPC_SHLL_S_PW:
21723 check_dsp(ctx);
21724 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21725 break;
21726 case OPC_SHLLV_S_PW:
21727 check_dsp(ctx);
21728 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21729 break;
21730 case OPC_SHLL_OB:
21731 check_dsp(ctx);
21732 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21733 break;
21734 case OPC_SHLLV_OB:
21735 check_dsp(ctx);
21736 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21737 break;
21738 case OPC_SHLL_QH:
21739 check_dsp(ctx);
21740 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21741 break;
21742 case OPC_SHLLV_QH:
21743 check_dsp(ctx);
21744 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21745 break;
21746 case OPC_SHLL_S_QH:
21747 check_dsp(ctx);
21748 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21749 break;
21750 case OPC_SHLLV_S_QH:
21751 check_dsp(ctx);
21752 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21753 break;
21754 case OPC_SHRA_OB:
908f6be1 21755 check_dsp_r2(ctx);
77c5fa8b
JL
21756 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21757 break;
21758 case OPC_SHRAV_OB:
908f6be1 21759 check_dsp_r2(ctx);
77c5fa8b
JL
21760 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21761 break;
21762 case OPC_SHRA_R_OB:
908f6be1 21763 check_dsp_r2(ctx);
77c5fa8b
JL
21764 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21765 break;
21766 case OPC_SHRAV_R_OB:
908f6be1 21767 check_dsp_r2(ctx);
77c5fa8b
JL
21768 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21769 break;
21770 case OPC_SHRA_PW:
21771 check_dsp(ctx);
21772 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21773 break;
21774 case OPC_SHRAV_PW:
21775 check_dsp(ctx);
21776 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21777 break;
21778 case OPC_SHRA_R_PW:
21779 check_dsp(ctx);
21780 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21781 break;
21782 case OPC_SHRAV_R_PW:
21783 check_dsp(ctx);
21784 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21785 break;
21786 case OPC_SHRA_QH:
21787 check_dsp(ctx);
21788 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21789 break;
21790 case OPC_SHRAV_QH:
21791 check_dsp(ctx);
21792 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21793 break;
21794 case OPC_SHRA_R_QH:
21795 check_dsp(ctx);
21796 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21797 break;
21798 case OPC_SHRAV_R_QH:
21799 check_dsp(ctx);
21800 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21801 break;
21802 case OPC_SHRL_OB:
21803 check_dsp(ctx);
21804 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21805 break;
21806 case OPC_SHRLV_OB:
21807 check_dsp(ctx);
21808 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21809 break;
21810 case OPC_SHRL_QH:
908f6be1 21811 check_dsp_r2(ctx);
77c5fa8b
JL
21812 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21813 break;
21814 case OPC_SHRLV_QH:
908f6be1 21815 check_dsp_r2(ctx);
77c5fa8b
JL
21816 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21817 break;
21818 default: /* Invalid */
21819 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 21820 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
21821 break;
21822 }
21823 break;
21824#endif
21825 }
21826
21827 tcg_temp_free(t0);
21828 tcg_temp_free(v1_t);
21829 tcg_temp_free(v2_t);
77c5fa8b
JL
21830}
21831
a22260ae
JL
21832static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21833 int ret, int v1, int v2, int check_ret)
21834{
a22260ae
JL
21835 TCGv_i32 t0;
21836 TCGv v1_t;
21837 TCGv v2_t;
21838
21839 if ((ret == 0) && (check_ret == 1)) {
21840 /* Treat as NOP. */
a22260ae
JL
21841 return;
21842 }
21843
21844 t0 = tcg_temp_new_i32();
21845 v1_t = tcg_temp_new();
21846 v2_t = tcg_temp_new();
21847
21848 tcg_gen_movi_i32(t0, ret);
21849 gen_load_gpr(v1_t, v1);
21850 gen_load_gpr(v2_t, v2);
21851
21852 switch (op1) {
21853 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21854 * the same mask and op1. */
21855 case OPC_MULT_G_2E:
908f6be1 21856 check_dsp_r2(ctx);
a22260ae
JL
21857 switch (op2) {
21858 case OPC_MUL_PH:
21859 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21860 break;
21861 case OPC_MUL_S_PH:
21862 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21863 break;
21864 case OPC_MULQ_S_W:
21865 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21866 break;
21867 case OPC_MULQ_RS_W:
21868 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21869 break;
21870 }
21871 break;
21872 case OPC_DPA_W_PH_DSP:
21873 switch (op2) {
21874 case OPC_DPAU_H_QBL:
21875 check_dsp(ctx);
21876 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
21877 break;
21878 case OPC_DPAU_H_QBR:
21879 check_dsp(ctx);
21880 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
21881 break;
21882 case OPC_DPSU_H_QBL:
21883 check_dsp(ctx);
21884 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
21885 break;
21886 case OPC_DPSU_H_QBR:
21887 check_dsp(ctx);
21888 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
21889 break;
21890 case OPC_DPA_W_PH:
908f6be1 21891 check_dsp_r2(ctx);
a22260ae
JL
21892 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
21893 break;
21894 case OPC_DPAX_W_PH:
908f6be1 21895 check_dsp_r2(ctx);
a22260ae
JL
21896 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
21897 break;
21898 case OPC_DPAQ_S_W_PH:
21899 check_dsp(ctx);
21900 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21901 break;
21902 case OPC_DPAQX_S_W_PH:
908f6be1 21903 check_dsp_r2(ctx);
a22260ae
JL
21904 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21905 break;
21906 case OPC_DPAQX_SA_W_PH:
908f6be1 21907 check_dsp_r2(ctx);
a22260ae
JL
21908 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21909 break;
21910 case OPC_DPS_W_PH:
908f6be1 21911 check_dsp_r2(ctx);
a22260ae
JL
21912 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
21913 break;
21914 case OPC_DPSX_W_PH:
908f6be1 21915 check_dsp_r2(ctx);
a22260ae
JL
21916 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
21917 break;
21918 case OPC_DPSQ_S_W_PH:
21919 check_dsp(ctx);
21920 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21921 break;
21922 case OPC_DPSQX_S_W_PH:
908f6be1 21923 check_dsp_r2(ctx);
a22260ae
JL
21924 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21925 break;
21926 case OPC_DPSQX_SA_W_PH:
908f6be1 21927 check_dsp_r2(ctx);
a22260ae
JL
21928 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21929 break;
21930 case OPC_MULSAQ_S_W_PH:
21931 check_dsp(ctx);
21932 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21933 break;
21934 case OPC_DPAQ_SA_L_W:
21935 check_dsp(ctx);
21936 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21937 break;
21938 case OPC_DPSQ_SA_L_W:
21939 check_dsp(ctx);
21940 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21941 break;
21942 case OPC_MAQ_S_W_PHL:
21943 check_dsp(ctx);
21944 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
21945 break;
21946 case OPC_MAQ_S_W_PHR:
21947 check_dsp(ctx);
21948 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
21949 break;
21950 case OPC_MAQ_SA_W_PHL:
21951 check_dsp(ctx);
21952 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
21953 break;
21954 case OPC_MAQ_SA_W_PHR:
21955 check_dsp(ctx);
21956 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
21957 break;
21958 case OPC_MULSA_W_PH:
908f6be1 21959 check_dsp_r2(ctx);
a22260ae
JL
21960 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
21961 break;
21962 }
21963 break;
21964#ifdef TARGET_MIPS64
21965 case OPC_DPAQ_W_QH_DSP:
21966 {
21967 int ac = ret & 0x03;
21968 tcg_gen_movi_i32(t0, ac);
21969
21970 switch (op2) {
21971 case OPC_DMADD:
21972 check_dsp(ctx);
21973 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
21974 break;
21975 case OPC_DMADDU:
21976 check_dsp(ctx);
21977 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
21978 break;
21979 case OPC_DMSUB:
21980 check_dsp(ctx);
21981 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
21982 break;
21983 case OPC_DMSUBU:
21984 check_dsp(ctx);
21985 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
21986 break;
21987 case OPC_DPA_W_QH:
908f6be1 21988 check_dsp_r2(ctx);
a22260ae
JL
21989 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
21990 break;
21991 case OPC_DPAQ_S_W_QH:
21992 check_dsp(ctx);
21993 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
21994 break;
21995 case OPC_DPAQ_SA_L_PW:
21996 check_dsp(ctx);
21997 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
21998 break;
21999 case OPC_DPAU_H_OBL:
22000 check_dsp(ctx);
22001 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22002 break;
22003 case OPC_DPAU_H_OBR:
22004 check_dsp(ctx);
22005 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22006 break;
22007 case OPC_DPS_W_QH:
908f6be1 22008 check_dsp_r2(ctx);
a22260ae
JL
22009 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22010 break;
22011 case OPC_DPSQ_S_W_QH:
22012 check_dsp(ctx);
22013 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22014 break;
22015 case OPC_DPSQ_SA_L_PW:
22016 check_dsp(ctx);
22017 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22018 break;
22019 case OPC_DPSU_H_OBL:
22020 check_dsp(ctx);
22021 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22022 break;
22023 case OPC_DPSU_H_OBR:
22024 check_dsp(ctx);
22025 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22026 break;
22027 case OPC_MAQ_S_L_PWL:
22028 check_dsp(ctx);
22029 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22030 break;
22031 case OPC_MAQ_S_L_PWR:
22032 check_dsp(ctx);
22033 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22034 break;
22035 case OPC_MAQ_S_W_QHLL:
22036 check_dsp(ctx);
22037 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22038 break;
22039 case OPC_MAQ_SA_W_QHLL:
22040 check_dsp(ctx);
22041 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22042 break;
22043 case OPC_MAQ_S_W_QHLR:
22044 check_dsp(ctx);
22045 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22046 break;
22047 case OPC_MAQ_SA_W_QHLR:
22048 check_dsp(ctx);
22049 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22050 break;
22051 case OPC_MAQ_S_W_QHRL:
22052 check_dsp(ctx);
22053 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22054 break;
22055 case OPC_MAQ_SA_W_QHRL:
22056 check_dsp(ctx);
22057 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22058 break;
22059 case OPC_MAQ_S_W_QHRR:
22060 check_dsp(ctx);
22061 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22062 break;
22063 case OPC_MAQ_SA_W_QHRR:
22064 check_dsp(ctx);
22065 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22066 break;
22067 case OPC_MULSAQ_S_L_PW:
22068 check_dsp(ctx);
22069 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22070 break;
22071 case OPC_MULSAQ_S_W_QH:
22072 check_dsp(ctx);
22073 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22074 break;
22075 }
22076 }
22077 break;
22078#endif
22079 case OPC_ADDU_QB_DSP:
22080 switch (op2) {
22081 case OPC_MULEU_S_PH_QBL:
22082 check_dsp(ctx);
22083 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22084 break;
22085 case OPC_MULEU_S_PH_QBR:
22086 check_dsp(ctx);
22087 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22088 break;
22089 case OPC_MULQ_RS_PH:
22090 check_dsp(ctx);
22091 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22092 break;
22093 case OPC_MULEQ_S_W_PHL:
22094 check_dsp(ctx);
22095 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22096 break;
22097 case OPC_MULEQ_S_W_PHR:
22098 check_dsp(ctx);
22099 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22100 break;
22101 case OPC_MULQ_S_PH:
908f6be1 22102 check_dsp_r2(ctx);
a22260ae
JL
22103 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22104 break;
22105 }
22106 break;
22107#ifdef TARGET_MIPS64
22108 case OPC_ADDU_OB_DSP:
22109 switch (op2) {
22110 case OPC_MULEQ_S_PW_QHL:
22111 check_dsp(ctx);
22112 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22113 break;
22114 case OPC_MULEQ_S_PW_QHR:
22115 check_dsp(ctx);
22116 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22117 break;
22118 case OPC_MULEU_S_QH_OBL:
22119 check_dsp(ctx);
22120 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22121 break;
22122 case OPC_MULEU_S_QH_OBR:
22123 check_dsp(ctx);
22124 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22125 break;
22126 case OPC_MULQ_RS_QH:
22127 check_dsp(ctx);
22128 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22129 break;
22130 }
22131 break;
22132#endif
22133 }
22134
22135 tcg_temp_free_i32(t0);
22136 tcg_temp_free(v1_t);
22137 tcg_temp_free(v2_t);
a22260ae
JL
22138}
22139
d75c135e 22140static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
22141 int ret, int val)
22142{
1cb6686c
JL
22143 int16_t imm;
22144 TCGv t0;
22145 TCGv val_t;
22146
22147 if (ret == 0) {
22148 /* Treat as NOP. */
1cb6686c
JL
22149 return;
22150 }
22151
22152 t0 = tcg_temp_new();
22153 val_t = tcg_temp_new();
22154 gen_load_gpr(val_t, val);
22155
22156 switch (op1) {
22157 case OPC_ABSQ_S_PH_DSP:
22158 switch (op2) {
22159 case OPC_BITREV:
22160 check_dsp(ctx);
22161 gen_helper_bitrev(cpu_gpr[ret], val_t);
22162 break;
22163 case OPC_REPL_QB:
22164 check_dsp(ctx);
22165 {
22166 target_long result;
22167 imm = (ctx->opcode >> 16) & 0xFF;
22168 result = (uint32_t)imm << 24 |
22169 (uint32_t)imm << 16 |
22170 (uint32_t)imm << 8 |
22171 (uint32_t)imm;
22172 result = (int32_t)result;
22173 tcg_gen_movi_tl(cpu_gpr[ret], result);
22174 }
22175 break;
22176 case OPC_REPLV_QB:
22177 check_dsp(ctx);
22178 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22179 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22180 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22181 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22182 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22183 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22184 break;
22185 case OPC_REPL_PH:
22186 check_dsp(ctx);
22187 {
22188 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 22189 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
22190 tcg_gen_movi_tl(cpu_gpr[ret], \
22191 (target_long)((int32_t)imm << 16 | \
c4aaba92 22192 (uint16_t)imm));
1cb6686c
JL
22193 }
22194 break;
22195 case OPC_REPLV_PH:
22196 check_dsp(ctx);
22197 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22198 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22199 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22200 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22201 break;
22202 }
22203 break;
22204#ifdef TARGET_MIPS64
22205 case OPC_ABSQ_S_QH_DSP:
22206 switch (op2) {
22207 case OPC_REPL_OB:
22208 check_dsp(ctx);
22209 {
22210 target_long temp;
22211
22212 imm = (ctx->opcode >> 16) & 0xFF;
22213 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22214 temp = (temp << 16) | temp;
22215 temp = (temp << 32) | temp;
22216 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22217 break;
22218 }
22219 case OPC_REPL_PW:
22220 check_dsp(ctx);
22221 {
22222 target_long temp;
22223
22224 imm = (ctx->opcode >> 16) & 0x03FF;
22225 imm = (int16_t)(imm << 6) >> 6;
22226 temp = ((target_long)imm << 32) \
22227 | ((target_long)imm & 0xFFFFFFFF);
22228 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22229 break;
22230 }
22231 case OPC_REPL_QH:
22232 check_dsp(ctx);
22233 {
22234 target_long temp;
22235
22236 imm = (ctx->opcode >> 16) & 0x03FF;
22237 imm = (int16_t)(imm << 6) >> 6;
22238
22239 temp = ((uint64_t)(uint16_t)imm << 48) |
22240 ((uint64_t)(uint16_t)imm << 32) |
22241 ((uint64_t)(uint16_t)imm << 16) |
22242 (uint64_t)(uint16_t)imm;
22243 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22244 break;
22245 }
22246 case OPC_REPLV_OB:
22247 check_dsp(ctx);
22248 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22249 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22250 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22251 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22252 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22253 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22254 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22255 break;
22256 case OPC_REPLV_PW:
22257 check_dsp(ctx);
22258 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22259 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22260 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22261 break;
22262 case OPC_REPLV_QH:
22263 check_dsp(ctx);
22264 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22265 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22266 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22267 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22268 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22269 break;
22270 }
22271 break;
22272#endif
22273 }
22274 tcg_temp_free(t0);
22275 tcg_temp_free(val_t);
1cb6686c
JL
22276}
22277
26690560
JL
22278static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22279 uint32_t op1, uint32_t op2,
22280 int ret, int v1, int v2, int check_ret)
22281{
26690560
JL
22282 TCGv t1;
22283 TCGv v1_t;
22284 TCGv v2_t;
22285
22286 if ((ret == 0) && (check_ret == 1)) {
22287 /* Treat as NOP. */
26690560
JL
22288 return;
22289 }
22290
26690560
JL
22291 t1 = tcg_temp_new();
22292 v1_t = tcg_temp_new();
22293 v2_t = tcg_temp_new();
22294
22295 gen_load_gpr(v1_t, v1);
22296 gen_load_gpr(v2_t, v2);
22297
22298 switch (op1) {
26690560
JL
22299 case OPC_CMPU_EQ_QB_DSP:
22300 switch (op2) {
22301 case OPC_CMPU_EQ_QB:
22302 check_dsp(ctx);
22303 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22304 break;
22305 case OPC_CMPU_LT_QB:
22306 check_dsp(ctx);
22307 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22308 break;
22309 case OPC_CMPU_LE_QB:
22310 check_dsp(ctx);
22311 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22312 break;
22313 case OPC_CMPGU_EQ_QB:
22314 check_dsp(ctx);
22315 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22316 break;
22317 case OPC_CMPGU_LT_QB:
22318 check_dsp(ctx);
22319 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22320 break;
22321 case OPC_CMPGU_LE_QB:
22322 check_dsp(ctx);
22323 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22324 break;
22325 case OPC_CMPGDU_EQ_QB:
908f6be1 22326 check_dsp_r2(ctx);
26690560
JL
22327 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22328 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22329 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22330 tcg_gen_shli_tl(t1, t1, 24);
22331 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22332 break;
22333 case OPC_CMPGDU_LT_QB:
908f6be1 22334 check_dsp_r2(ctx);
26690560
JL
22335 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22336 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22337 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22338 tcg_gen_shli_tl(t1, t1, 24);
22339 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22340 break;
22341 case OPC_CMPGDU_LE_QB:
908f6be1 22342 check_dsp_r2(ctx);
26690560
JL
22343 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22344 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22345 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22346 tcg_gen_shli_tl(t1, t1, 24);
22347 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22348 break;
22349 case OPC_CMP_EQ_PH:
22350 check_dsp(ctx);
22351 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22352 break;
22353 case OPC_CMP_LT_PH:
22354 check_dsp(ctx);
22355 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22356 break;
22357 case OPC_CMP_LE_PH:
22358 check_dsp(ctx);
22359 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22360 break;
22361 case OPC_PICK_QB:
22362 check_dsp(ctx);
22363 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22364 break;
22365 case OPC_PICK_PH:
22366 check_dsp(ctx);
22367 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22368 break;
22369 case OPC_PACKRL_PH:
22370 check_dsp(ctx);
22371 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22372 break;
22373 }
22374 break;
22375#ifdef TARGET_MIPS64
22376 case OPC_CMPU_EQ_OB_DSP:
22377 switch (op2) {
22378 case OPC_CMP_EQ_PW:
22379 check_dsp(ctx);
22380 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22381 break;
22382 case OPC_CMP_LT_PW:
22383 check_dsp(ctx);
22384 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22385 break;
22386 case OPC_CMP_LE_PW:
22387 check_dsp(ctx);
22388 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22389 break;
22390 case OPC_CMP_EQ_QH:
22391 check_dsp(ctx);
22392 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22393 break;
22394 case OPC_CMP_LT_QH:
22395 check_dsp(ctx);
22396 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22397 break;
22398 case OPC_CMP_LE_QH:
22399 check_dsp(ctx);
22400 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22401 break;
22402 case OPC_CMPGDU_EQ_OB:
908f6be1 22403 check_dsp_r2(ctx);
26690560
JL
22404 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22405 break;
22406 case OPC_CMPGDU_LT_OB:
908f6be1 22407 check_dsp_r2(ctx);
26690560
JL
22408 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22409 break;
22410 case OPC_CMPGDU_LE_OB:
908f6be1 22411 check_dsp_r2(ctx);
26690560
JL
22412 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22413 break;
22414 case OPC_CMPGU_EQ_OB:
22415 check_dsp(ctx);
22416 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22417 break;
22418 case OPC_CMPGU_LT_OB:
22419 check_dsp(ctx);
22420 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22421 break;
22422 case OPC_CMPGU_LE_OB:
22423 check_dsp(ctx);
22424 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22425 break;
22426 case OPC_CMPU_EQ_OB:
22427 check_dsp(ctx);
22428 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22429 break;
22430 case OPC_CMPU_LT_OB:
22431 check_dsp(ctx);
22432 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22433 break;
22434 case OPC_CMPU_LE_OB:
22435 check_dsp(ctx);
22436 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22437 break;
22438 case OPC_PACKRL_PW:
22439 check_dsp(ctx);
22440 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22441 break;
22442 case OPC_PICK_OB:
22443 check_dsp(ctx);
22444 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22445 break;
22446 case OPC_PICK_PW:
22447 check_dsp(ctx);
22448 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22449 break;
22450 case OPC_PICK_QH:
22451 check_dsp(ctx);
22452 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22453 break;
22454 }
22455 break;
df6126a7
AJ
22456#endif
22457 }
22458
22459 tcg_temp_free(t1);
22460 tcg_temp_free(v1_t);
22461 tcg_temp_free(v2_t);
df6126a7
AJ
22462}
22463
22464static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22465 uint32_t op1, int rt, int rs, int sa)
22466{
df6126a7
AJ
22467 TCGv t0;
22468
908f6be1 22469 check_dsp_r2(ctx);
df6126a7
AJ
22470
22471 if (rt == 0) {
22472 /* Treat as NOP. */
df6126a7
AJ
22473 return;
22474 }
22475
22476 t0 = tcg_temp_new();
22477 gen_load_gpr(t0, rs);
22478
22479 switch (op1) {
22480 case OPC_APPEND_DSP:
22481 switch (MASK_APPEND(ctx->opcode)) {
22482 case OPC_APPEND:
22483 if (sa != 0) {
22484 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22485 }
22486 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22487 break;
22488 case OPC_PREPEND:
22489 if (sa != 0) {
22490 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22491 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22492 tcg_gen_shli_tl(t0, t0, 32 - sa);
22493 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22494 }
22495 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22496 break;
22497 case OPC_BALIGN:
22498 sa &= 3;
22499 if (sa != 0 && sa != 2) {
22500 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22501 tcg_gen_ext32u_tl(t0, t0);
22502 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22503 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22504 }
22505 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22506 break;
22507 default: /* Invalid */
22508 MIPS_INVAL("MASK APPEND");
9c708c7f 22509 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
22510 break;
22511 }
22512 break;
22513#ifdef TARGET_MIPS64
26690560 22514 case OPC_DAPPEND_DSP:
df6126a7 22515 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 22516 case OPC_DAPPEND:
df6126a7
AJ
22517 if (sa != 0) {
22518 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22519 }
26690560
JL
22520 break;
22521 case OPC_PREPENDD:
df6126a7
AJ
22522 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22523 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22524 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
22525 break;
22526 case OPC_PREPENDW:
df6126a7
AJ
22527 if (sa != 0) {
22528 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22529 tcg_gen_shli_tl(t0, t0, 64 - sa);
22530 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22531 }
26690560
JL
22532 break;
22533 case OPC_DBALIGN:
df6126a7
AJ
22534 sa &= 7;
22535 if (sa != 0 && sa != 2 && sa != 4) {
22536 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22537 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22538 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22539 }
26690560
JL
22540 break;
22541 default: /* Invalid */
22542 MIPS_INVAL("MASK DAPPEND");
9c708c7f 22543 generate_exception_end(ctx, EXCP_RI);
26690560
JL
22544 break;
22545 }
22546 break;
22547#endif
22548 }
df6126a7 22549 tcg_temp_free(t0);
26690560
JL
22550}
22551
b53371ed
JL
22552static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22553 int ret, int v1, int v2, int check_ret)
22554
22555{
b53371ed
JL
22556 TCGv t0;
22557 TCGv t1;
22558 TCGv v1_t;
22559 TCGv v2_t;
22560 int16_t imm;
22561
22562 if ((ret == 0) && (check_ret == 1)) {
22563 /* Treat as NOP. */
b53371ed
JL
22564 return;
22565 }
22566
22567 t0 = tcg_temp_new();
22568 t1 = tcg_temp_new();
22569 v1_t = tcg_temp_new();
22570 v2_t = tcg_temp_new();
22571
22572 gen_load_gpr(v1_t, v1);
22573 gen_load_gpr(v2_t, v2);
22574
22575 switch (op1) {
22576 case OPC_EXTR_W_DSP:
22577 check_dsp(ctx);
22578 switch (op2) {
22579 case OPC_EXTR_W:
22580 tcg_gen_movi_tl(t0, v2);
22581 tcg_gen_movi_tl(t1, v1);
22582 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22583 break;
22584 case OPC_EXTR_R_W:
22585 tcg_gen_movi_tl(t0, v2);
22586 tcg_gen_movi_tl(t1, v1);
22587 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22588 break;
22589 case OPC_EXTR_RS_W:
22590 tcg_gen_movi_tl(t0, v2);
22591 tcg_gen_movi_tl(t1, v1);
22592 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22593 break;
22594 case OPC_EXTR_S_H:
22595 tcg_gen_movi_tl(t0, v2);
22596 tcg_gen_movi_tl(t1, v1);
22597 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22598 break;
22599 case OPC_EXTRV_S_H:
22600 tcg_gen_movi_tl(t0, v2);
22601 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22602 break;
22603 case OPC_EXTRV_W:
22604 tcg_gen_movi_tl(t0, v2);
22605 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22606 break;
22607 case OPC_EXTRV_R_W:
22608 tcg_gen_movi_tl(t0, v2);
22609 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22610 break;
22611 case OPC_EXTRV_RS_W:
22612 tcg_gen_movi_tl(t0, v2);
22613 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22614 break;
22615 case OPC_EXTP:
22616 tcg_gen_movi_tl(t0, v2);
22617 tcg_gen_movi_tl(t1, v1);
22618 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22619 break;
22620 case OPC_EXTPV:
22621 tcg_gen_movi_tl(t0, v2);
22622 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22623 break;
22624 case OPC_EXTPDP:
22625 tcg_gen_movi_tl(t0, v2);
22626 tcg_gen_movi_tl(t1, v1);
22627 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22628 break;
22629 case OPC_EXTPDPV:
22630 tcg_gen_movi_tl(t0, v2);
22631 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22632 break;
22633 case OPC_SHILO:
22634 imm = (ctx->opcode >> 20) & 0x3F;
22635 tcg_gen_movi_tl(t0, ret);
22636 tcg_gen_movi_tl(t1, imm);
22637 gen_helper_shilo(t0, t1, cpu_env);
22638 break;
22639 case OPC_SHILOV:
22640 tcg_gen_movi_tl(t0, ret);
22641 gen_helper_shilo(t0, v1_t, cpu_env);
22642 break;
22643 case OPC_MTHLIP:
22644 tcg_gen_movi_tl(t0, ret);
22645 gen_helper_mthlip(t0, v1_t, cpu_env);
22646 break;
22647 case OPC_WRDSP:
22648 imm = (ctx->opcode >> 11) & 0x3FF;
22649 tcg_gen_movi_tl(t0, imm);
22650 gen_helper_wrdsp(v1_t, t0, cpu_env);
22651 break;
22652 case OPC_RDDSP:
22653 imm = (ctx->opcode >> 16) & 0x03FF;
22654 tcg_gen_movi_tl(t0, imm);
22655 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22656 break;
22657 }
22658 break;
22659#ifdef TARGET_MIPS64
22660 case OPC_DEXTR_W_DSP:
22661 check_dsp(ctx);
22662 switch (op2) {
22663 case OPC_DMTHLIP:
22664 tcg_gen_movi_tl(t0, ret);
22665 gen_helper_dmthlip(v1_t, t0, cpu_env);
22666 break;
22667 case OPC_DSHILO:
22668 {
22669 int shift = (ctx->opcode >> 19) & 0x7F;
22670 int ac = (ctx->opcode >> 11) & 0x03;
22671 tcg_gen_movi_tl(t0, shift);
22672 tcg_gen_movi_tl(t1, ac);
22673 gen_helper_dshilo(t0, t1, cpu_env);
22674 break;
22675 }
22676 case OPC_DSHILOV:
22677 {
22678 int ac = (ctx->opcode >> 11) & 0x03;
22679 tcg_gen_movi_tl(t0, ac);
22680 gen_helper_dshilo(v1_t, t0, cpu_env);
22681 break;
22682 }
22683 case OPC_DEXTP:
22684 tcg_gen_movi_tl(t0, v2);
22685 tcg_gen_movi_tl(t1, v1);
22686
22687 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22688 break;
22689 case OPC_DEXTPV:
22690 tcg_gen_movi_tl(t0, v2);
22691 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22692 break;
22693 case OPC_DEXTPDP:
22694 tcg_gen_movi_tl(t0, v2);
22695 tcg_gen_movi_tl(t1, v1);
22696 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22697 break;
22698 case OPC_DEXTPDPV:
22699 tcg_gen_movi_tl(t0, v2);
22700 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22701 break;
22702 case OPC_DEXTR_L:
22703 tcg_gen_movi_tl(t0, v2);
22704 tcg_gen_movi_tl(t1, v1);
22705 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22706 break;
22707 case OPC_DEXTR_R_L:
22708 tcg_gen_movi_tl(t0, v2);
22709 tcg_gen_movi_tl(t1, v1);
22710 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22711 break;
22712 case OPC_DEXTR_RS_L:
22713 tcg_gen_movi_tl(t0, v2);
22714 tcg_gen_movi_tl(t1, v1);
22715 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22716 break;
22717 case OPC_DEXTR_W:
22718 tcg_gen_movi_tl(t0, v2);
22719 tcg_gen_movi_tl(t1, v1);
22720 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22721 break;
22722 case OPC_DEXTR_R_W:
22723 tcg_gen_movi_tl(t0, v2);
22724 tcg_gen_movi_tl(t1, v1);
22725 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22726 break;
22727 case OPC_DEXTR_RS_W:
22728 tcg_gen_movi_tl(t0, v2);
22729 tcg_gen_movi_tl(t1, v1);
22730 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22731 break;
22732 case OPC_DEXTR_S_H:
22733 tcg_gen_movi_tl(t0, v2);
22734 tcg_gen_movi_tl(t1, v1);
22735 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22736 break;
22737 case OPC_DEXTRV_S_H:
22738 tcg_gen_movi_tl(t0, v2);
22739 tcg_gen_movi_tl(t1, v1);
22740 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22741 break;
22742 case OPC_DEXTRV_L:
22743 tcg_gen_movi_tl(t0, v2);
22744 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22745 break;
22746 case OPC_DEXTRV_R_L:
22747 tcg_gen_movi_tl(t0, v2);
22748 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22749 break;
22750 case OPC_DEXTRV_RS_L:
22751 tcg_gen_movi_tl(t0, v2);
22752 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22753 break;
22754 case OPC_DEXTRV_W:
22755 tcg_gen_movi_tl(t0, v2);
22756 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22757 break;
22758 case OPC_DEXTRV_R_W:
22759 tcg_gen_movi_tl(t0, v2);
22760 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22761 break;
22762 case OPC_DEXTRV_RS_W:
22763 tcg_gen_movi_tl(t0, v2);
22764 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22765 break;
22766 }
22767 break;
22768#endif
22769 }
22770
22771 tcg_temp_free(t0);
22772 tcg_temp_free(t1);
22773 tcg_temp_free(v1_t);
22774 tcg_temp_free(v2_t);
b53371ed
JL
22775}
22776
9b1a1d68
JL
22777/* End MIPSDSP functions. */
22778
10dc65db
LA
22779static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22780{
4267d3e6 22781 int rs, rt, rd, sa;
b42ee5e1 22782 uint32_t op1, op2;
10dc65db
LA
22783
22784 rs = (ctx->opcode >> 21) & 0x1f;
22785 rt = (ctx->opcode >> 16) & 0x1f;
22786 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 22787 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
22788
22789 op1 = MASK_SPECIAL(ctx->opcode);
22790 switch (op1) {
d4ea6acd 22791 case OPC_LSA:
1f1b4c00 22792 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 22793 break;
c2e19f3c
AM
22794 case OPC_MULT:
22795 case OPC_MULTU:
22796 case OPC_DIV:
22797 case OPC_DIVU:
b42ee5e1
LA
22798 op2 = MASK_R6_MULDIV(ctx->opcode);
22799 switch (op2) {
22800 case R6_OPC_MUL:
22801 case R6_OPC_MUH:
22802 case R6_OPC_MULU:
22803 case R6_OPC_MUHU:
22804 case R6_OPC_DIV:
22805 case R6_OPC_MOD:
22806 case R6_OPC_DIVU:
22807 case R6_OPC_MODU:
22808 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22809 break;
22810 default:
22811 MIPS_INVAL("special_r6 muldiv");
9c708c7f 22812 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
22813 break;
22814 }
22815 break;
10dc65db
LA
22816 case OPC_SELEQZ:
22817 case OPC_SELNEZ:
22818 gen_cond_move(ctx, op1, rd, rs, rt);
22819 break;
4267d3e6
LA
22820 case R6_OPC_CLO:
22821 case R6_OPC_CLZ:
22822 if (rt == 0 && sa == 1) {
22823 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22824 We need additionally to check other fields */
22825 gen_cl(ctx, op1, rd, rs);
22826 } else {
9c708c7f 22827 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
22828 }
22829 break;
22830 case R6_OPC_SDBBP:
3b3c1694
LA
22831 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22832 gen_helper_do_semihosting(cpu_env);
faf1f68b 22833 } else {
3b3c1694 22834 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 22835 generate_exception_end(ctx, EXCP_RI);
3b3c1694 22836 } else {
9c708c7f 22837 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 22838 }
faf1f68b 22839 }
4267d3e6 22840 break;
b42ee5e1 22841#if defined(TARGET_MIPS64)
d4ea6acd
LA
22842 case OPC_DLSA:
22843 check_mips_64(ctx);
1f1b4c00 22844 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 22845 break;
4267d3e6
LA
22846 case R6_OPC_DCLO:
22847 case R6_OPC_DCLZ:
22848 if (rt == 0 && sa == 1) {
22849 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22850 We need additionally to check other fields */
22851 check_mips_64(ctx);
22852 gen_cl(ctx, op1, rd, rs);
22853 } else {
9c708c7f 22854 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
22855 }
22856 break;
c2e19f3c
AM
22857 case OPC_DMULT:
22858 case OPC_DMULTU:
22859 case OPC_DDIV:
22860 case OPC_DDIVU:
22861
b42ee5e1
LA
22862 op2 = MASK_R6_MULDIV(ctx->opcode);
22863 switch (op2) {
22864 case R6_OPC_DMUL:
22865 case R6_OPC_DMUH:
22866 case R6_OPC_DMULU:
22867 case R6_OPC_DMUHU:
22868 case R6_OPC_DDIV:
22869 case R6_OPC_DMOD:
22870 case R6_OPC_DDIVU:
22871 case R6_OPC_DMODU:
22872 check_mips_64(ctx);
22873 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22874 break;
22875 default:
22876 MIPS_INVAL("special_r6 muldiv");
9c708c7f 22877 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
22878 break;
22879 }
22880 break;
22881#endif
10dc65db
LA
22882 default: /* Invalid */
22883 MIPS_INVAL("special_r6");
9c708c7f 22884 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
22885 break;
22886 }
22887}
22888
22889static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
22890{
b42ee5e1 22891 int rs, rt, rd, sa;
10dc65db
LA
22892 uint32_t op1;
22893
22894 rs = (ctx->opcode >> 21) & 0x1f;
22895 rt = (ctx->opcode >> 16) & 0x1f;
22896 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 22897 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
22898
22899 op1 = MASK_SPECIAL(ctx->opcode);
22900 switch (op1) {
22901 case OPC_MOVN: /* Conditional move */
22902 case OPC_MOVZ:
22903 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
22904 INSN_LOONGSON2E | INSN_LOONGSON2F);
22905 gen_cond_move(ctx, op1, rd, rs, rt);
22906 break;
22907 case OPC_MFHI: /* Move from HI/LO */
22908 case OPC_MFLO:
22909 gen_HILO(ctx, op1, rs & 3, rd);
22910 break;
22911 case OPC_MTHI:
22912 case OPC_MTLO: /* Move to HI/LO */
22913 gen_HILO(ctx, op1, rd & 3, rs);
22914 break;
22915 case OPC_MOVCI:
22916 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
22917 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
22918 check_cp1_enabled(ctx);
22919 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
22920 (ctx->opcode >> 16) & 1);
22921 } else {
22922 generate_exception_err(ctx, EXCP_CpU, 1);
22923 }
22924 break;
b42ee5e1
LA
22925 case OPC_MULT:
22926 case OPC_MULTU:
22927 if (sa) {
22928 check_insn(ctx, INSN_VR54XX);
22929 op1 = MASK_MUL_VR54XX(ctx->opcode);
22930 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
22931 } else {
22932 gen_muldiv(ctx, op1, rd & 3, rs, rt);
22933 }
22934 break;
22935 case OPC_DIV:
22936 case OPC_DIVU:
22937 gen_muldiv(ctx, op1, 0, rs, rt);
22938 break;
22939#if defined(TARGET_MIPS64)
c2e19f3c
AM
22940 case OPC_DMULT:
22941 case OPC_DMULTU:
22942 case OPC_DDIV:
22943 case OPC_DDIVU:
b42ee5e1
LA
22944 check_insn(ctx, ISA_MIPS3);
22945 check_mips_64(ctx);
22946 gen_muldiv(ctx, op1, 0, rs, rt);
22947 break;
22948#endif
0aefa333 22949 case OPC_JR:
b231c103 22950 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 22951 break;
4267d3e6
LA
22952 case OPC_SPIM:
22953#ifdef MIPS_STRICT_STANDARD
22954 MIPS_INVAL("SPIM");
9c708c7f 22955 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
22956#else
22957 /* Implemented as RI exception for now. */
22958 MIPS_INVAL("spim (unofficial)");
9c708c7f 22959 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
22960#endif
22961 break;
10dc65db
LA
22962 default: /* Invalid */
22963 MIPS_INVAL("special_legacy");
9c708c7f 22964 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
22965 break;
22966 }
22967}
22968
099e5b4d 22969static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 22970{
3c824109 22971 int rs, rt, rd, sa;
099e5b4d 22972 uint32_t op1;
3c824109 22973
3c824109
NF
22974 rs = (ctx->opcode >> 21) & 0x1f;
22975 rt = (ctx->opcode >> 16) & 0x1f;
22976 rd = (ctx->opcode >> 11) & 0x1f;
22977 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
22978
22979 op1 = MASK_SPECIAL(ctx->opcode);
22980 switch (op1) {
22981 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
22982 if (sa == 5 && rd == 0 &&
22983 rs == 0 && rt == 0) { /* PAUSE */
22984 if ((ctx->insn_flags & ISA_MIPS32R6) &&
22985 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 22986 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
22987 break;
22988 }
22989 }
22990 /* Fallthrough */
099e5b4d
LA
22991 case OPC_SRA:
22992 gen_shift_imm(ctx, op1, rd, rt, sa);
22993 break;
22994 case OPC_SRL:
22995 switch ((ctx->opcode >> 21) & 0x1f) {
22996 case 1:
22997 /* rotr is decoded as srl on non-R2 CPUs */
22998 if (ctx->insn_flags & ISA_MIPS32R2) {
22999 op1 = OPC_ROTR;
ea63e2c3 23000 }
099e5b4d
LA
23001 /* Fallthrough */
23002 case 0:
23003 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 23004 break;
099e5b4d 23005 default:
9c708c7f 23006 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 23007 break;
099e5b4d
LA
23008 }
23009 break;
c2e19f3c
AM
23010 case OPC_ADD:
23011 case OPC_ADDU:
23012 case OPC_SUB:
23013 case OPC_SUBU:
099e5b4d
LA
23014 gen_arith(ctx, op1, rd, rs, rt);
23015 break;
23016 case OPC_SLLV: /* Shifts */
23017 case OPC_SRAV:
23018 gen_shift(ctx, op1, rd, rs, rt);
23019 break;
23020 case OPC_SRLV:
23021 switch ((ctx->opcode >> 6) & 0x1f) {
23022 case 1:
23023 /* rotrv is decoded as srlv on non-R2 CPUs */
23024 if (ctx->insn_flags & ISA_MIPS32R2) {
23025 op1 = OPC_ROTRV;
26135ead 23026 }
099e5b4d
LA
23027 /* Fallthrough */
23028 case 0:
23029 gen_shift(ctx, op1, rd, rs, rt);
26135ead 23030 break;
099e5b4d 23031 default:
9c708c7f 23032 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 23033 break;
099e5b4d
LA
23034 }
23035 break;
23036 case OPC_SLT: /* Set on less than */
23037 case OPC_SLTU:
23038 gen_slt(ctx, op1, rd, rs, rt);
23039 break;
23040 case OPC_AND: /* Logic*/
23041 case OPC_OR:
23042 case OPC_NOR:
23043 case OPC_XOR:
23044 gen_logic(ctx, op1, rd, rs, rt);
23045 break;
0aefa333 23046 case OPC_JALR:
b231c103 23047 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 23048 break;
c2e19f3c
AM
23049 case OPC_TGE: /* Traps */
23050 case OPC_TGEU:
23051 case OPC_TLT:
23052 case OPC_TLTU:
23053 case OPC_TEQ:
099e5b4d 23054 case OPC_TNE:
d9224450 23055 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
23056 gen_trap(ctx, op1, rs, rt, -1);
23057 break;
d4ea6acd 23058 case OPC_LSA: /* OPC_PMON */
f7685877
YK
23059 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23060 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
23061 decode_opc_special_r6(env, ctx);
23062 } else {
23063 /* Pmon entry point, also R4010 selsl */
b48cfdff 23064#ifdef MIPS_STRICT_STANDARD
d4ea6acd 23065 MIPS_INVAL("PMON / selsl");
9c708c7f 23066 generate_exception_end(ctx, EXCP_RI);
b48cfdff 23067#else
d4ea6acd 23068 gen_helper_0e0i(pmon, sa);
b48cfdff 23069#endif
d4ea6acd 23070 }
099e5b4d
LA
23071 break;
23072 case OPC_SYSCALL:
9c708c7f 23073 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
23074 break;
23075 case OPC_BREAK:
9c708c7f 23076 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 23077 break;
099e5b4d 23078 case OPC_SYNC:
d9224450 23079 check_insn(ctx, ISA_MIPS2);
d208ac0c 23080 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 23081 break;
4ad40f36 23082
d26bc211 23083#if defined(TARGET_MIPS64)
099e5b4d
LA
23084 /* MIPS64 specific opcodes */
23085 case OPC_DSLL:
23086 case OPC_DSRA:
23087 case OPC_DSLL32:
23088 case OPC_DSRA32:
23089 check_insn(ctx, ISA_MIPS3);
23090 check_mips_64(ctx);
23091 gen_shift_imm(ctx, op1, rd, rt, sa);
23092 break;
23093 case OPC_DSRL:
23094 switch ((ctx->opcode >> 21) & 0x1f) {
23095 case 1:
23096 /* drotr is decoded as dsrl on non-R2 CPUs */
23097 if (ctx->insn_flags & ISA_MIPS32R2) {
23098 op1 = OPC_DROTR;
ea63e2c3 23099 }
099e5b4d
LA
23100 /* Fallthrough */
23101 case 0:
d75c135e 23102 check_insn(ctx, ISA_MIPS3);
e189e748 23103 check_mips_64(ctx);
099e5b4d 23104 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23105 break;
099e5b4d 23106 default:
9c708c7f 23107 generate_exception_end(ctx, EXCP_RI);
460f00c4 23108 break;
099e5b4d
LA
23109 }
23110 break;
23111 case OPC_DSRL32:
23112 switch ((ctx->opcode >> 21) & 0x1f) {
23113 case 1:
23114 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23115 if (ctx->insn_flags & ISA_MIPS32R2) {
23116 op1 = OPC_DROTR32;
ea63e2c3 23117 }
099e5b4d
LA
23118 /* Fallthrough */
23119 case 0:
d75c135e 23120 check_insn(ctx, ISA_MIPS3);
e189e748 23121 check_mips_64(ctx);
099e5b4d 23122 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23123 break;
099e5b4d 23124 default:
9c708c7f 23125 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23126 break;
23127 }
23128 break;
c2e19f3c
AM
23129 case OPC_DADD:
23130 case OPC_DADDU:
23131 case OPC_DSUB:
23132 case OPC_DSUBU:
099e5b4d
LA
23133 check_insn(ctx, ISA_MIPS3);
23134 check_mips_64(ctx);
23135 gen_arith(ctx, op1, rd, rs, rt);
23136 break;
23137 case OPC_DSLLV:
23138 case OPC_DSRAV:
23139 check_insn(ctx, ISA_MIPS3);
23140 check_mips_64(ctx);
23141 gen_shift(ctx, op1, rd, rs, rt);
23142 break;
23143 case OPC_DSRLV:
23144 switch ((ctx->opcode >> 6) & 0x1f) {
23145 case 1:
23146 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23147 if (ctx->insn_flags & ISA_MIPS32R2) {
23148 op1 = OPC_DROTRV;
6af0bf9c 23149 }
099e5b4d
LA
23150 /* Fallthrough */
23151 case 0:
23152 check_insn(ctx, ISA_MIPS3);
e189e748 23153 check_mips_64(ctx);
099e5b4d 23154 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 23155 break;
099e5b4d 23156 default:
9c708c7f 23157 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23158 break;
23159 }
23160 break;
f7685877
YK
23161 case OPC_DLSA:
23162 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23163 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23164 decode_opc_special_r6(env, ctx);
23165 }
23166 break;
099e5b4d 23167#endif
10dc65db
LA
23168 default:
23169 if (ctx->insn_flags & ISA_MIPS32R6) {
23170 decode_opc_special_r6(env, ctx);
23171 } else {
23172 decode_opc_special_legacy(env, ctx);
23173 }
23174 }
23175}
23176
10dc65db 23177static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
23178{
23179 int rs, rt, rd;
23180 uint32_t op1;
6c5c1e20 23181
4267d3e6
LA
23182 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23183
099e5b4d
LA
23184 rs = (ctx->opcode >> 21) & 0x1f;
23185 rt = (ctx->opcode >> 16) & 0x1f;
23186 rd = (ctx->opcode >> 11) & 0x1f;
23187
23188 op1 = MASK_SPECIAL2(ctx->opcode);
23189 switch (op1) {
c2e19f3c
AM
23190 case OPC_MADD: /* Multiply and add/sub */
23191 case OPC_MADDU:
23192 case OPC_MSUB:
23193 case OPC_MSUBU:
099e5b4d
LA
23194 check_insn(ctx, ISA_MIPS32);
23195 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23196 break;
23197 case OPC_MUL:
099e5b4d
LA
23198 gen_arith(ctx, op1, rd, rs, rt);
23199 break;
fac5a073
LA
23200 case OPC_DIV_G_2F:
23201 case OPC_DIVU_G_2F:
23202 case OPC_MULT_G_2F:
23203 case OPC_MULTU_G_2F:
23204 case OPC_MOD_G_2F:
23205 case OPC_MODU_G_2F:
23206 check_insn(ctx, INSN_LOONGSON2F);
23207 gen_loongson_integer(ctx, op1, rd, rs, rt);
23208 break;
099e5b4d
LA
23209 case OPC_CLO:
23210 case OPC_CLZ:
23211 check_insn(ctx, ISA_MIPS32);
23212 gen_cl(ctx, op1, rd, rs);
23213 break;
23214 case OPC_SDBBP:
3b3c1694
LA
23215 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23216 gen_helper_do_semihosting(cpu_env);
23217 } else {
23218 /* XXX: not clear which exception should be raised
23219 * when in debug mode...
23220 */
23221 check_insn(ctx, ISA_MIPS32);
9c708c7f 23222 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23223 }
099e5b4d 23224 break;
9b1a1d68 23225#if defined(TARGET_MIPS64)
099e5b4d
LA
23226 case OPC_DCLO:
23227 case OPC_DCLZ:
23228 check_insn(ctx, ISA_MIPS64);
23229 check_mips_64(ctx);
23230 gen_cl(ctx, op1, rd, rs);
23231 break;
4267d3e6
LA
23232 case OPC_DMULT_G_2F:
23233 case OPC_DMULTU_G_2F:
23234 case OPC_DDIV_G_2F:
23235 case OPC_DDIVU_G_2F:
23236 case OPC_DMOD_G_2F:
23237 case OPC_DMODU_G_2F:
23238 check_insn(ctx, INSN_LOONGSON2F);
23239 gen_loongson_integer(ctx, op1, rd, rs, rt);
23240 break;
10dc65db 23241#endif
4267d3e6
LA
23242 default: /* Invalid */
23243 MIPS_INVAL("special2_legacy");
9c708c7f 23244 generate_exception_end(ctx, EXCP_RI);
4267d3e6 23245 break;
10dc65db
LA
23246 }
23247}
23248
23249static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23250{
15eacb9b
YK
23251 int rs, rt, rd, sa;
23252 uint32_t op1, op2;
10dc65db
LA
23253 int16_t imm;
23254
23255 rs = (ctx->opcode >> 21) & 0x1f;
23256 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
23257 rd = (ctx->opcode >> 11) & 0x1f;
23258 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23259 imm = (int16_t)ctx->opcode >> 7;
23260
23261 op1 = MASK_SPECIAL3(ctx->opcode);
23262 switch (op1) {
bf7910c6
LA
23263 case R6_OPC_PREF:
23264 if (rt >= 24) {
23265 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 23266 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
23267 }
23268 /* Treat as NOP. */
23269 break;
23270 case R6_OPC_CACHE:
40d48212 23271 check_cp0_enabled(ctx);
0d74a222
LA
23272 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23273 gen_cache_operation(ctx, rt, rs, imm);
23274 }
bf7910c6 23275 break;
10dc65db
LA
23276 case R6_OPC_SC:
23277 gen_st_cond(ctx, op1, rt, rs, imm);
23278 break;
23279 case R6_OPC_LL:
23280 gen_ld(ctx, op1, rt, rs, imm);
23281 break;
15eacb9b
YK
23282 case OPC_BSHFL:
23283 {
23284 if (rd == 0) {
23285 /* Treat as NOP. */
23286 break;
23287 }
15eacb9b
YK
23288 op2 = MASK_BSHFL(ctx->opcode);
23289 switch (op2) {
c2e19f3c
AM
23290 case OPC_ALIGN:
23291 case OPC_ALIGN_END:
821f2008 23292 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
23293 break;
23294 case OPC_BITSWAP:
1f1b4c00 23295 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
23296 break;
23297 }
15eacb9b
YK
23298 }
23299 break;
bf7910c6
LA
23300#if defined(TARGET_MIPS64)
23301 case R6_OPC_SCD:
23302 gen_st_cond(ctx, op1, rt, rs, imm);
23303 break;
23304 case R6_OPC_LLD:
23305 gen_ld(ctx, op1, rt, rs, imm);
23306 break;
15eacb9b
YK
23307 case OPC_DBSHFL:
23308 check_mips_64(ctx);
23309 {
23310 if (rd == 0) {
23311 /* Treat as NOP. */
23312 break;
23313 }
15eacb9b
YK
23314 op2 = MASK_DBSHFL(ctx->opcode);
23315 switch (op2) {
c2e19f3c
AM
23316 case OPC_DALIGN:
23317 case OPC_DALIGN_END:
821f2008 23318 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
23319 break;
23320 case OPC_DBITSWAP:
1f1b4c00 23321 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
23322 break;
23323 }
1f1b4c00 23324
15eacb9b
YK
23325 }
23326 break;
bf7910c6 23327#endif
10dc65db
LA
23328 default: /* Invalid */
23329 MIPS_INVAL("special3_r6");
9c708c7f 23330 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23331 break;
23332 }
23333}
23334
23335static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23336{
fac5a073 23337 int rs, rt, rd;
099e5b4d 23338 uint32_t op1, op2;
099e5b4d
LA
23339
23340 rs = (ctx->opcode >> 21) & 0x1f;
23341 rt = (ctx->opcode >> 16) & 0x1f;
23342 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
23343
23344 op1 = MASK_SPECIAL3(ctx->opcode);
23345 switch (op1) {
c2e19f3c
AM
23346 case OPC_DIV_G_2E:
23347 case OPC_DIVU_G_2E:
23348 case OPC_MOD_G_2E:
23349 case OPC_MODU_G_2E:
23350 case OPC_MULT_G_2E:
23351 case OPC_MULTU_G_2E:
099e5b4d
LA
23352 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23353 * the same mask and op1. */
908f6be1 23354 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 23355 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 23356 switch (op2) {
099e5b4d
LA
23357 case OPC_ADDUH_QB:
23358 case OPC_ADDUH_R_QB:
23359 case OPC_ADDQH_PH:
23360 case OPC_ADDQH_R_PH:
23361 case OPC_ADDQH_W:
23362 case OPC_ADDQH_R_W:
23363 case OPC_SUBUH_QB:
23364 case OPC_SUBUH_R_QB:
23365 case OPC_SUBQH_PH:
23366 case OPC_SUBQH_R_PH:
23367 case OPC_SUBQH_W:
23368 case OPC_SUBQH_R_W:
461c08df
JL
23369 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23370 break;
099e5b4d
LA
23371 case OPC_MUL_PH:
23372 case OPC_MUL_S_PH:
23373 case OPC_MULQ_S_W:
23374 case OPC_MULQ_RS_W:
23375 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 23376 break;
461c08df 23377 default:
099e5b4d 23378 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 23379 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
23380 break;
23381 }
099e5b4d
LA
23382 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23383 gen_loongson_integer(ctx, op1, rd, rs, rt);
23384 } else {
9c708c7f 23385 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23386 }
23387 break;
23388 case OPC_LX_DSP:
23389 op2 = MASK_LX(ctx->opcode);
23390 switch (op2) {
23391#if defined(TARGET_MIPS64)
23392 case OPC_LDX:
23393#endif
23394 case OPC_LBUX:
23395 case OPC_LHX:
23396 case OPC_LWX:
23397 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23398 break;
23399 default: /* Invalid */
23400 MIPS_INVAL("MASK LX");
9c708c7f 23401 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23402 break;
23403 }
23404 break;
23405 case OPC_ABSQ_S_PH_DSP:
23406 op2 = MASK_ABSQ_S_PH(ctx->opcode);
23407 switch (op2) {
23408 case OPC_ABSQ_S_QB:
23409 case OPC_ABSQ_S_PH:
23410 case OPC_ABSQ_S_W:
23411 case OPC_PRECEQ_W_PHL:
23412 case OPC_PRECEQ_W_PHR:
23413 case OPC_PRECEQU_PH_QBL:
23414 case OPC_PRECEQU_PH_QBR:
23415 case OPC_PRECEQU_PH_QBLA:
23416 case OPC_PRECEQU_PH_QBRA:
23417 case OPC_PRECEU_PH_QBL:
23418 case OPC_PRECEU_PH_QBR:
23419 case OPC_PRECEU_PH_QBLA:
23420 case OPC_PRECEU_PH_QBRA:
23421 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23422 break;
23423 case OPC_BITREV:
23424 case OPC_REPL_QB:
23425 case OPC_REPLV_QB:
23426 case OPC_REPL_PH:
23427 case OPC_REPLV_PH:
23428 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23429 break;
23430 default:
23431 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 23432 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23433 break;
23434 }
23435 break;
23436 case OPC_ADDU_QB_DSP:
23437 op2 = MASK_ADDU_QB(ctx->opcode);
23438 switch (op2) {
23439 case OPC_ADDQ_PH:
23440 case OPC_ADDQ_S_PH:
23441 case OPC_ADDQ_S_W:
23442 case OPC_ADDU_QB:
23443 case OPC_ADDU_S_QB:
23444 case OPC_ADDU_PH:
23445 case OPC_ADDU_S_PH:
23446 case OPC_SUBQ_PH:
23447 case OPC_SUBQ_S_PH:
23448 case OPC_SUBQ_S_W:
23449 case OPC_SUBU_QB:
23450 case OPC_SUBU_S_QB:
23451 case OPC_SUBU_PH:
23452 case OPC_SUBU_S_PH:
23453 case OPC_ADDSC:
23454 case OPC_ADDWC:
23455 case OPC_MODSUB:
23456 case OPC_RADDU_W_QB:
23457 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23458 break;
23459 case OPC_MULEU_S_PH_QBL:
23460 case OPC_MULEU_S_PH_QBR:
23461 case OPC_MULQ_RS_PH:
23462 case OPC_MULEQ_S_W_PHL:
23463 case OPC_MULEQ_S_W_PHR:
23464 case OPC_MULQ_S_PH:
23465 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23466 break;
23467 default: /* Invalid */
23468 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 23469 generate_exception_end(ctx, EXCP_RI);
461c08df 23470 break;
461c08df 23471
099e5b4d
LA
23472 }
23473 break;
23474 case OPC_CMPU_EQ_QB_DSP:
23475 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23476 switch (op2) {
23477 case OPC_PRECR_SRA_PH_W:
23478 case OPC_PRECR_SRA_R_PH_W:
23479 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 23480 break;
099e5b4d
LA
23481 case OPC_PRECR_QB_PH:
23482 case OPC_PRECRQ_QB_PH:
23483 case OPC_PRECRQ_PH_W:
23484 case OPC_PRECRQ_RS_PH_W:
23485 case OPC_PRECRQU_S_QB_PH:
23486 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 23487 break;
099e5b4d
LA
23488 case OPC_CMPU_EQ_QB:
23489 case OPC_CMPU_LT_QB:
23490 case OPC_CMPU_LE_QB:
23491 case OPC_CMP_EQ_PH:
23492 case OPC_CMP_LT_PH:
23493 case OPC_CMP_LE_PH:
23494 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 23495 break;
099e5b4d
LA
23496 case OPC_CMPGU_EQ_QB:
23497 case OPC_CMPGU_LT_QB:
23498 case OPC_CMPGU_LE_QB:
23499 case OPC_CMPGDU_EQ_QB:
23500 case OPC_CMPGDU_LT_QB:
23501 case OPC_CMPGDU_LE_QB:
23502 case OPC_PICK_QB:
23503 case OPC_PICK_PH:
23504 case OPC_PACKRL_PH:
23505 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23506 break;
23507 default: /* Invalid */
23508 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 23509 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23510 break;
23511 }
23512 break;
23513 case OPC_SHLL_QB_DSP:
23514 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23515 break;
23516 case OPC_DPA_W_PH_DSP:
23517 op2 = MASK_DPA_W_PH(ctx->opcode);
23518 switch (op2) {
23519 case OPC_DPAU_H_QBL:
23520 case OPC_DPAU_H_QBR:
23521 case OPC_DPSU_H_QBL:
23522 case OPC_DPSU_H_QBR:
23523 case OPC_DPA_W_PH:
23524 case OPC_DPAX_W_PH:
23525 case OPC_DPAQ_S_W_PH:
23526 case OPC_DPAQX_S_W_PH:
23527 case OPC_DPAQX_SA_W_PH:
23528 case OPC_DPS_W_PH:
23529 case OPC_DPSX_W_PH:
23530 case OPC_DPSQ_S_W_PH:
23531 case OPC_DPSQX_S_W_PH:
23532 case OPC_DPSQX_SA_W_PH:
23533 case OPC_MULSAQ_S_W_PH:
23534 case OPC_DPAQ_SA_L_W:
23535 case OPC_DPSQ_SA_L_W:
23536 case OPC_MAQ_S_W_PHL:
23537 case OPC_MAQ_S_W_PHR:
23538 case OPC_MAQ_SA_W_PHL:
23539 case OPC_MAQ_SA_W_PHR:
23540 case OPC_MULSA_W_PH:
23541 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23542 break;
23543 default: /* Invalid */
23544 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 23545 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23546 break;
23547 }
23548 break;
23549 case OPC_INSV_DSP:
23550 op2 = MASK_INSV(ctx->opcode);
23551 switch (op2) {
23552 case OPC_INSV:
23553 check_dsp(ctx);
23554 {
23555 TCGv t0, t1;
23556
23557 if (rt == 0) {
099e5b4d
LA
23558 break;
23559 }
23560
23561 t0 = tcg_temp_new();
23562 t1 = tcg_temp_new();
23563
23564 gen_load_gpr(t0, rt);
23565 gen_load_gpr(t1, rs);
23566
23567 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23568
23569 tcg_temp_free(t0);
23570 tcg_temp_free(t1);
a22260ae
JL
23571 break;
23572 }
099e5b4d
LA
23573 default: /* Invalid */
23574 MIPS_INVAL("MASK INSV");
9c708c7f 23575 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23576 break;
23577 }
23578 break;
23579 case OPC_APPEND_DSP:
23580 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23581 break;
23582 case OPC_EXTR_W_DSP:
23583 op2 = MASK_EXTR_W(ctx->opcode);
23584 switch (op2) {
23585 case OPC_EXTR_W:
23586 case OPC_EXTR_R_W:
23587 case OPC_EXTR_RS_W:
23588 case OPC_EXTR_S_H:
23589 case OPC_EXTRV_S_H:
23590 case OPC_EXTRV_W:
23591 case OPC_EXTRV_R_W:
23592 case OPC_EXTRV_RS_W:
23593 case OPC_EXTP:
23594 case OPC_EXTPV:
23595 case OPC_EXTPDP:
23596 case OPC_EXTPDPV:
23597 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23598 break;
23599 case OPC_RDDSP:
23600 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23601 break;
23602 case OPC_SHILO:
23603 case OPC_SHILOV:
23604 case OPC_MTHLIP:
23605 case OPC_WRDSP:
23606 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23607 break;
23608 default: /* Invalid */
23609 MIPS_INVAL("MASK EXTR.W");
9c708c7f 23610 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23611 break;
23612 }
23613 break;
099e5b4d 23614#if defined(TARGET_MIPS64)
c2e19f3c
AM
23615 case OPC_DDIV_G_2E:
23616 case OPC_DDIVU_G_2E:
23617 case OPC_DMULT_G_2E:
23618 case OPC_DMULTU_G_2E:
23619 case OPC_DMOD_G_2E:
23620 case OPC_DMODU_G_2E:
fac5a073
LA
23621 check_insn(ctx, INSN_LOONGSON2E);
23622 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 23623 break;
099e5b4d
LA
23624 case OPC_ABSQ_S_QH_DSP:
23625 op2 = MASK_ABSQ_S_QH(ctx->opcode);
23626 switch (op2) {
23627 case OPC_PRECEQ_L_PWL:
23628 case OPC_PRECEQ_L_PWR:
23629 case OPC_PRECEQ_PW_QHL:
23630 case OPC_PRECEQ_PW_QHR:
23631 case OPC_PRECEQ_PW_QHLA:
23632 case OPC_PRECEQ_PW_QHRA:
23633 case OPC_PRECEQU_QH_OBL:
23634 case OPC_PRECEQU_QH_OBR:
23635 case OPC_PRECEQU_QH_OBLA:
23636 case OPC_PRECEQU_QH_OBRA:
23637 case OPC_PRECEU_QH_OBL:
23638 case OPC_PRECEU_QH_OBR:
23639 case OPC_PRECEU_QH_OBLA:
23640 case OPC_PRECEU_QH_OBRA:
23641 case OPC_ABSQ_S_OB:
23642 case OPC_ABSQ_S_PW:
23643 case OPC_ABSQ_S_QH:
23644 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23645 break;
23646 case OPC_REPL_OB:
23647 case OPC_REPL_PW:
23648 case OPC_REPL_QH:
23649 case OPC_REPLV_OB:
23650 case OPC_REPLV_PW:
23651 case OPC_REPLV_QH:
23652 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23653 break;
23654 default: /* Invalid */
23655 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 23656 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
23657 break;
23658 }
23659 break;
23660 case OPC_ADDU_OB_DSP:
23661 op2 = MASK_ADDU_OB(ctx->opcode);
23662 switch (op2) {
23663 case OPC_RADDU_L_OB:
23664 case OPC_SUBQ_PW:
23665 case OPC_SUBQ_S_PW:
23666 case OPC_SUBQ_QH:
23667 case OPC_SUBQ_S_QH:
23668 case OPC_SUBU_OB:
23669 case OPC_SUBU_S_OB:
23670 case OPC_SUBU_QH:
23671 case OPC_SUBU_S_QH:
23672 case OPC_SUBUH_OB:
23673 case OPC_SUBUH_R_OB:
23674 case OPC_ADDQ_PW:
23675 case OPC_ADDQ_S_PW:
23676 case OPC_ADDQ_QH:
23677 case OPC_ADDQ_S_QH:
23678 case OPC_ADDU_OB:
23679 case OPC_ADDU_S_OB:
23680 case OPC_ADDU_QH:
23681 case OPC_ADDU_S_QH:
23682 case OPC_ADDUH_OB:
23683 case OPC_ADDUH_R_OB:
23684 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 23685 break;
099e5b4d
LA
23686 case OPC_MULEQ_S_PW_QHL:
23687 case OPC_MULEQ_S_PW_QHR:
23688 case OPC_MULEU_S_QH_OBL:
23689 case OPC_MULEU_S_QH_OBR:
23690 case OPC_MULQ_RS_QH:
23691 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 23692 break;
099e5b4d
LA
23693 default: /* Invalid */
23694 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 23695 generate_exception_end(ctx, EXCP_RI);
26690560 23696 break;
099e5b4d
LA
23697 }
23698 break;
23699 case OPC_CMPU_EQ_OB_DSP:
23700 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23701 switch (op2) {
23702 case OPC_PRECR_SRA_QH_PW:
23703 case OPC_PRECR_SRA_R_QH_PW:
23704 /* Return value is rt. */
23705 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 23706 break;
099e5b4d
LA
23707 case OPC_PRECR_OB_QH:
23708 case OPC_PRECRQ_OB_QH:
23709 case OPC_PRECRQ_PW_L:
23710 case OPC_PRECRQ_QH_PW:
23711 case OPC_PRECRQ_RS_QH_PW:
23712 case OPC_PRECRQU_S_OB_QH:
23713 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 23714 break;
099e5b4d
LA
23715 case OPC_CMPU_EQ_OB:
23716 case OPC_CMPU_LT_OB:
23717 case OPC_CMPU_LE_OB:
23718 case OPC_CMP_EQ_QH:
23719 case OPC_CMP_LT_QH:
23720 case OPC_CMP_LE_QH:
23721 case OPC_CMP_EQ_PW:
23722 case OPC_CMP_LT_PW:
23723 case OPC_CMP_LE_PW:
23724 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 23725 break;
099e5b4d
LA
23726 case OPC_CMPGDU_EQ_OB:
23727 case OPC_CMPGDU_LT_OB:
23728 case OPC_CMPGDU_LE_OB:
23729 case OPC_CMPGU_EQ_OB:
23730 case OPC_CMPGU_LT_OB:
23731 case OPC_CMPGU_LE_OB:
23732 case OPC_PACKRL_PW:
23733 case OPC_PICK_OB:
23734 case OPC_PICK_PW:
23735 case OPC_PICK_QH:
23736 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 23737 break;
099e5b4d
LA
23738 default: /* Invalid */
23739 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 23740 generate_exception_end(ctx, EXCP_RI);
161f85e6 23741 break;
099e5b4d
LA
23742 }
23743 break;
23744 case OPC_DAPPEND_DSP:
23745 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23746 break;
23747 case OPC_DEXTR_W_DSP:
23748 op2 = MASK_DEXTR_W(ctx->opcode);
23749 switch (op2) {
23750 case OPC_DEXTP:
23751 case OPC_DEXTPDP:
23752 case OPC_DEXTPDPV:
23753 case OPC_DEXTPV:
23754 case OPC_DEXTR_L:
23755 case OPC_DEXTR_R_L:
23756 case OPC_DEXTR_RS_L:
23757 case OPC_DEXTR_W:
23758 case OPC_DEXTR_R_W:
23759 case OPC_DEXTR_RS_W:
23760 case OPC_DEXTR_S_H:
23761 case OPC_DEXTRV_L:
23762 case OPC_DEXTRV_R_L:
23763 case OPC_DEXTRV_RS_L:
23764 case OPC_DEXTRV_S_H:
23765 case OPC_DEXTRV_W:
23766 case OPC_DEXTRV_R_W:
23767 case OPC_DEXTRV_RS_W:
23768 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 23769 break;
099e5b4d
LA
23770 case OPC_DMTHLIP:
23771 case OPC_DSHILO:
23772 case OPC_DSHILOV:
23773 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 23774 break;
099e5b4d
LA
23775 default: /* Invalid */
23776 MIPS_INVAL("MASK EXTR.W");
9c708c7f 23777 generate_exception_end(ctx, EXCP_RI);
461c08df 23778 break;
099e5b4d
LA
23779 }
23780 break;
23781 case OPC_DPAQ_W_QH_DSP:
23782 op2 = MASK_DPAQ_W_QH(ctx->opcode);
23783 switch (op2) {
23784 case OPC_DPAU_H_OBL:
23785 case OPC_DPAU_H_OBR:
23786 case OPC_DPSU_H_OBL:
23787 case OPC_DPSU_H_OBR:
23788 case OPC_DPA_W_QH:
23789 case OPC_DPAQ_S_W_QH:
23790 case OPC_DPS_W_QH:
23791 case OPC_DPSQ_S_W_QH:
23792 case OPC_MULSAQ_S_W_QH:
23793 case OPC_DPAQ_SA_L_PW:
23794 case OPC_DPSQ_SA_L_PW:
23795 case OPC_MULSAQ_S_L_PW:
23796 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23797 break;
23798 case OPC_MAQ_S_W_QHLL:
23799 case OPC_MAQ_S_W_QHLR:
23800 case OPC_MAQ_S_W_QHRL:
23801 case OPC_MAQ_S_W_QHRR:
23802 case OPC_MAQ_SA_W_QHLL:
23803 case OPC_MAQ_SA_W_QHLR:
23804 case OPC_MAQ_SA_W_QHRL:
23805 case OPC_MAQ_SA_W_QHRR:
23806 case OPC_MAQ_S_L_PWL:
23807 case OPC_MAQ_S_L_PWR:
23808 case OPC_DMADD:
23809 case OPC_DMADDU:
23810 case OPC_DMSUB:
23811 case OPC_DMSUBU:
23812 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 23813 break;
099e5b4d
LA
23814 default: /* Invalid */
23815 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 23816 generate_exception_end(ctx, EXCP_RI);
b53371ed 23817 break;
099e5b4d
LA
23818 }
23819 break;
23820 case OPC_DINSV_DSP:
23821 op2 = MASK_INSV(ctx->opcode);
23822 switch (op2) {
23823 case OPC_DINSV:
23824 {
23825 TCGv t0, t1;
23826
23827 if (rt == 0) {
a22260ae
JL
23828 break;
23829 }
099e5b4d 23830 check_dsp(ctx);
1cb6686c 23831
099e5b4d
LA
23832 t0 = tcg_temp_new();
23833 t1 = tcg_temp_new();
1cb6686c 23834
099e5b4d
LA
23835 gen_load_gpr(t0, rt);
23836 gen_load_gpr(t1, rs);
1cb6686c 23837
099e5b4d 23838 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 23839
099e5b4d
LA
23840 tcg_temp_free(t0);
23841 tcg_temp_free(t1);
77c5fa8b 23842 break;
099e5b4d 23843 }
7a387fff 23844 default: /* Invalid */
099e5b4d 23845 MIPS_INVAL("MASK DINSV");
9c708c7f 23846 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
23847 break;
23848 }
23849 break;
099e5b4d
LA
23850 case OPC_SHLL_OB_DSP:
23851 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23852 break;
23853#endif
fac5a073
LA
23854 default: /* Invalid */
23855 MIPS_INVAL("special3_legacy");
9c708c7f 23856 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
23857 break;
23858 }
23859}
23860
23861static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23862{
23863 int rs, rt, rd, sa;
23864 uint32_t op1, op2;
76964147 23865 int16_t imm;
fac5a073
LA
23866
23867 rs = (ctx->opcode >> 21) & 0x1f;
23868 rt = (ctx->opcode >> 16) & 0x1f;
23869 rd = (ctx->opcode >> 11) & 0x1f;
23870 sa = (ctx->opcode >> 6) & 0x1f;
76964147 23871 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
23872
23873 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
23874
23875 /*
23876 * EVA loads and stores overlap Loongson 2E instructions decoded by
23877 * decode_opc_special3_legacy(), so be careful to allow their decoding when
23878 * EVA is absent.
23879 */
23880 if (ctx->eva) {
23881 switch (op1) {
c2e19f3c
AM
23882 case OPC_LWLE:
23883 case OPC_LWRE:
76964147
JH
23884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23885 /* fall through */
c2e19f3c
AM
23886 case OPC_LBUE:
23887 case OPC_LHUE:
23888 case OPC_LBE:
23889 case OPC_LHE:
23890 case OPC_LLE:
23891 case OPC_LWE:
76964147
JH
23892 check_cp0_enabled(ctx);
23893 gen_ld(ctx, op1, rt, rs, imm);
23894 return;
c2e19f3c
AM
23895 case OPC_SWLE:
23896 case OPC_SWRE:
76964147
JH
23897 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23898 /* fall through */
c2e19f3c
AM
23899 case OPC_SBE:
23900 case OPC_SHE:
76964147
JH
23901 case OPC_SWE:
23902 check_cp0_enabled(ctx);
23903 gen_st(ctx, op1, rt, rs, imm);
23904 return;
23905 case OPC_SCE:
23906 check_cp0_enabled(ctx);
23907 gen_st_cond(ctx, op1, rt, rs, imm);
23908 return;
23909 case OPC_CACHEE:
23910 check_cp0_enabled(ctx);
23911 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23912 gen_cache_operation(ctx, rt, rs, imm);
23913 }
23914 /* Treat as NOP. */
23915 return;
23916 case OPC_PREFE:
23917 check_cp0_enabled(ctx);
23918 /* Treat as NOP. */
23919 return;
23920 }
23921 }
23922
fac5a073
LA
23923 switch (op1) {
23924 case OPC_EXT:
23925 case OPC_INS:
23926 check_insn(ctx, ISA_MIPS32R2);
23927 gen_bitops(ctx, op1, rt, rs, sa, rd);
23928 break;
23929 case OPC_BSHFL:
fac5a073 23930 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 23931 switch (op2) {
c2e19f3c
AM
23932 case OPC_ALIGN:
23933 case OPC_ALIGN_END:
15eacb9b
YK
23934 case OPC_BITSWAP:
23935 check_insn(ctx, ISA_MIPS32R6);
23936 decode_opc_special3_r6(env, ctx);
23937 break;
23938 default:
23939 check_insn(ctx, ISA_MIPS32R2);
23940 gen_bshfl(ctx, op2, rt, rd);
23941 break;
23942 }
fac5a073
LA
23943 break;
23944#if defined(TARGET_MIPS64)
c2e19f3c
AM
23945 case OPC_DEXTM:
23946 case OPC_DEXTU:
23947 case OPC_DEXT:
23948 case OPC_DINSM:
23949 case OPC_DINSU:
23950 case OPC_DINS:
fac5a073
LA
23951 check_insn(ctx, ISA_MIPS64R2);
23952 check_mips_64(ctx);
23953 gen_bitops(ctx, op1, rt, rs, sa, rd);
23954 break;
23955 case OPC_DBSHFL:
fac5a073 23956 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 23957 switch (op2) {
c2e19f3c
AM
23958 case OPC_DALIGN:
23959 case OPC_DALIGN_END:
15eacb9b
YK
23960 case OPC_DBITSWAP:
23961 check_insn(ctx, ISA_MIPS32R6);
23962 decode_opc_special3_r6(env, ctx);
23963 break;
23964 default:
23965 check_insn(ctx, ISA_MIPS64R2);
23966 check_mips_64(ctx);
23967 op2 = MASK_DBSHFL(ctx->opcode);
23968 gen_bshfl(ctx, op2, rt, rd);
23969 break;
23970 }
fac5a073
LA
23971 break;
23972#endif
23973 case OPC_RDHWR:
b00c7218 23974 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
23975 break;
23976 case OPC_FORK:
9affc1c5 23977 check_mt(ctx);
fac5a073
LA
23978 {
23979 TCGv t0 = tcg_temp_new();
23980 TCGv t1 = tcg_temp_new();
23981
23982 gen_load_gpr(t0, rt);
23983 gen_load_gpr(t1, rs);
23984 gen_helper_fork(t0, t1);
23985 tcg_temp_free(t0);
23986 tcg_temp_free(t1);
23987 }
23988 break;
23989 case OPC_YIELD:
9affc1c5 23990 check_mt(ctx);
fac5a073
LA
23991 {
23992 TCGv t0 = tcg_temp_new();
23993
fac5a073
LA
23994 gen_load_gpr(t0, rs);
23995 gen_helper_yield(t0, cpu_env, t0);
23996 gen_store_gpr(t0, rd);
23997 tcg_temp_free(t0);
23998 }
23999 break;
10dc65db
LA
24000 default:
24001 if (ctx->insn_flags & ISA_MIPS32R6) {
24002 decode_opc_special3_r6(env, ctx);
24003 } else {
24004 decode_opc_special3_legacy(env, ctx);
24005 }
099e5b4d
LA
24006 }
24007}
24008
863f264d
YK
24009/* MIPS SIMD Architecture (MSA) */
24010static inline int check_msa_access(DisasContext *ctx)
24011{
24012 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24013 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 24014 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
24015 return 0;
24016 }
24017
24018 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24019 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 24020 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
24021 return 0;
24022 } else {
9c708c7f 24023 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
24024 return 0;
24025 }
24026 }
24027 return 1;
24028}
24029
5692c6e1
YK
24030static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24031{
24032 /* generates tcg ops to check if any element is 0 */
24033 /* Note this function only works with MSA_WRLEN = 128 */
24034 uint64_t eval_zero_or_big = 0;
24035 uint64_t eval_big = 0;
24036 TCGv_i64 t0 = tcg_temp_new_i64();
24037 TCGv_i64 t1 = tcg_temp_new_i64();
24038 switch (df) {
24039 case DF_BYTE:
24040 eval_zero_or_big = 0x0101010101010101ULL;
24041 eval_big = 0x8080808080808080ULL;
24042 break;
24043 case DF_HALF:
24044 eval_zero_or_big = 0x0001000100010001ULL;
24045 eval_big = 0x8000800080008000ULL;
24046 break;
24047 case DF_WORD:
24048 eval_zero_or_big = 0x0000000100000001ULL;
24049 eval_big = 0x8000000080000000ULL;
24050 break;
24051 case DF_DOUBLE:
24052 eval_zero_or_big = 0x0000000000000001ULL;
24053 eval_big = 0x8000000000000000ULL;
24054 break;
24055 }
24056 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24057 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24058 tcg_gen_andi_i64(t0, t0, eval_big);
24059 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24060 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24061 tcg_gen_andi_i64(t1, t1, eval_big);
24062 tcg_gen_or_i64(t0, t0, t1);
24063 /* if all bits are zero then all elements are not zero */
24064 /* if some bit is non-zero then some element is zero */
24065 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24066 tcg_gen_trunc_i64_tl(tresult, t0);
24067 tcg_temp_free_i64(t0);
24068 tcg_temp_free_i64(t1);
24069}
24070
24071static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24072{
24073 uint8_t df = (ctx->opcode >> 21) & 0x3;
24074 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24075 int64_t s16 = (int16_t)ctx->opcode;
24076
24077 check_msa_access(ctx);
24078
075a1fe7 24079 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 24080 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
24081 return;
24082 }
24083 switch (op1) {
24084 case OPC_BZ_V:
24085 case OPC_BNZ_V:
24086 {
24087 TCGv_i64 t0 = tcg_temp_new_i64();
24088 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24089 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24090 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24091 tcg_gen_trunc_i64_tl(bcond, t0);
24092 tcg_temp_free_i64(t0);
24093 }
24094 break;
24095 case OPC_BZ_B:
24096 case OPC_BZ_H:
24097 case OPC_BZ_W:
24098 case OPC_BZ_D:
24099 gen_check_zero_element(bcond, df, wt);
24100 break;
24101 case OPC_BNZ_B:
24102 case OPC_BNZ_H:
24103 case OPC_BNZ_W:
24104 case OPC_BNZ_D:
24105 gen_check_zero_element(bcond, df, wt);
24106 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24107 break;
24108 }
24109
eeb3bba8 24110 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
24111
24112 ctx->hflags |= MIPS_HFLAG_BC;
24113 ctx->hflags |= MIPS_HFLAG_BDS32;
24114}
24115
4c789546
YK
24116static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24117{
24118#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24119 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24120 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24121 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24122
24123 TCGv_i32 twd = tcg_const_i32(wd);
24124 TCGv_i32 tws = tcg_const_i32(ws);
24125 TCGv_i32 ti8 = tcg_const_i32(i8);
24126
24127 switch (MASK_MSA_I8(ctx->opcode)) {
24128 case OPC_ANDI_B:
24129 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24130 break;
24131 case OPC_ORI_B:
24132 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24133 break;
24134 case OPC_NORI_B:
24135 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24136 break;
24137 case OPC_XORI_B:
24138 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24139 break;
24140 case OPC_BMNZI_B:
24141 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24142 break;
24143 case OPC_BMZI_B:
24144 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24145 break;
24146 case OPC_BSELI_B:
24147 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24148 break;
24149 case OPC_SHF_B:
24150 case OPC_SHF_H:
24151 case OPC_SHF_W:
24152 {
24153 uint8_t df = (ctx->opcode >> 24) & 0x3;
24154 if (df == DF_DOUBLE) {
9c708c7f 24155 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
24156 } else {
24157 TCGv_i32 tdf = tcg_const_i32(df);
24158 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24159 tcg_temp_free_i32(tdf);
24160 }
24161 }
24162 break;
24163 default:
24164 MIPS_INVAL("MSA instruction");
9c708c7f 24165 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
24166 break;
24167 }
24168
24169 tcg_temp_free_i32(twd);
24170 tcg_temp_free_i32(tws);
24171 tcg_temp_free_i32(ti8);
24172}
24173
80e71591
YK
24174static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24175{
24176#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24177 uint8_t df = (ctx->opcode >> 21) & 0x3;
24178 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24179 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24180 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24181 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24182
24183 TCGv_i32 tdf = tcg_const_i32(df);
24184 TCGv_i32 twd = tcg_const_i32(wd);
24185 TCGv_i32 tws = tcg_const_i32(ws);
24186 TCGv_i32 timm = tcg_temp_new_i32();
24187 tcg_gen_movi_i32(timm, u5);
24188
24189 switch (MASK_MSA_I5(ctx->opcode)) {
24190 case OPC_ADDVI_df:
24191 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24192 break;
24193 case OPC_SUBVI_df:
24194 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24195 break;
24196 case OPC_MAXI_S_df:
24197 tcg_gen_movi_i32(timm, s5);
24198 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24199 break;
24200 case OPC_MAXI_U_df:
24201 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24202 break;
24203 case OPC_MINI_S_df:
24204 tcg_gen_movi_i32(timm, s5);
24205 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24206 break;
24207 case OPC_MINI_U_df:
24208 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24209 break;
24210 case OPC_CEQI_df:
24211 tcg_gen_movi_i32(timm, s5);
24212 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24213 break;
24214 case OPC_CLTI_S_df:
24215 tcg_gen_movi_i32(timm, s5);
24216 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24217 break;
24218 case OPC_CLTI_U_df:
24219 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24220 break;
24221 case OPC_CLEI_S_df:
24222 tcg_gen_movi_i32(timm, s5);
24223 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24224 break;
24225 case OPC_CLEI_U_df:
24226 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24227 break;
24228 case OPC_LDI_df:
24229 {
24230 int32_t s10 = sextract32(ctx->opcode, 11, 10);
24231 tcg_gen_movi_i32(timm, s10);
24232 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24233 }
24234 break;
24235 default:
24236 MIPS_INVAL("MSA instruction");
9c708c7f 24237 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
24238 break;
24239 }
24240
24241 tcg_temp_free_i32(tdf);
24242 tcg_temp_free_i32(twd);
24243 tcg_temp_free_i32(tws);
24244 tcg_temp_free_i32(timm);
24245}
24246
d4cf28de
YK
24247static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24248{
24249#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24250 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24251 uint32_t df = 0, m = 0;
24252 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24253 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24254
24255 TCGv_i32 tdf;
24256 TCGv_i32 tm;
24257 TCGv_i32 twd;
24258 TCGv_i32 tws;
24259
24260 if ((dfm & 0x40) == 0x00) {
24261 m = dfm & 0x3f;
24262 df = DF_DOUBLE;
24263 } else if ((dfm & 0x60) == 0x40) {
24264 m = dfm & 0x1f;
24265 df = DF_WORD;
24266 } else if ((dfm & 0x70) == 0x60) {
24267 m = dfm & 0x0f;
24268 df = DF_HALF;
24269 } else if ((dfm & 0x78) == 0x70) {
24270 m = dfm & 0x7;
24271 df = DF_BYTE;
24272 } else {
9c708c7f 24273 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
24274 return;
24275 }
24276
24277 tdf = tcg_const_i32(df);
24278 tm = tcg_const_i32(m);
24279 twd = tcg_const_i32(wd);
24280 tws = tcg_const_i32(ws);
24281
24282 switch (MASK_MSA_BIT(ctx->opcode)) {
24283 case OPC_SLLI_df:
24284 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24285 break;
24286 case OPC_SRAI_df:
24287 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24288 break;
24289 case OPC_SRLI_df:
24290 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24291 break;
24292 case OPC_BCLRI_df:
24293 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24294 break;
24295 case OPC_BSETI_df:
24296 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24297 break;
24298 case OPC_BNEGI_df:
24299 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24300 break;
24301 case OPC_BINSLI_df:
24302 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24303 break;
24304 case OPC_BINSRI_df:
24305 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24306 break;
24307 case OPC_SAT_S_df:
24308 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24309 break;
24310 case OPC_SAT_U_df:
24311 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24312 break;
24313 case OPC_SRARI_df:
24314 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24315 break;
24316 case OPC_SRLRI_df:
24317 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24318 break;
24319 default:
24320 MIPS_INVAL("MSA instruction");
9c708c7f 24321 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
24322 break;
24323 }
24324
24325 tcg_temp_free_i32(tdf);
24326 tcg_temp_free_i32(tm);
24327 tcg_temp_free_i32(twd);
24328 tcg_temp_free_i32(tws);
24329}
24330
28f99f08
YK
24331static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24332{
24333#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24334 uint8_t df = (ctx->opcode >> 21) & 0x3;
24335 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24336 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24337 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24338
24339 TCGv_i32 tdf = tcg_const_i32(df);
24340 TCGv_i32 twd = tcg_const_i32(wd);
24341 TCGv_i32 tws = tcg_const_i32(ws);
24342 TCGv_i32 twt = tcg_const_i32(wt);
24343
24344 switch (MASK_MSA_3R(ctx->opcode)) {
24345 case OPC_SLL_df:
24346 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24347 break;
24348 case OPC_ADDV_df:
24349 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24350 break;
24351 case OPC_CEQ_df:
24352 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24353 break;
24354 case OPC_ADD_A_df:
24355 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24356 break;
24357 case OPC_SUBS_S_df:
24358 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24359 break;
24360 case OPC_MULV_df:
24361 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24362 break;
24363 case OPC_SLD_df:
24364 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24365 break;
24366 case OPC_VSHF_df:
24367 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24368 break;
24369 case OPC_SRA_df:
24370 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24371 break;
24372 case OPC_SUBV_df:
24373 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24374 break;
24375 case OPC_ADDS_A_df:
24376 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24377 break;
24378 case OPC_SUBS_U_df:
24379 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24380 break;
24381 case OPC_MADDV_df:
24382 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24383 break;
24384 case OPC_SPLAT_df:
24385 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24386 break;
24387 case OPC_SRAR_df:
24388 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24389 break;
24390 case OPC_SRL_df:
24391 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24392 break;
24393 case OPC_MAX_S_df:
24394 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24395 break;
24396 case OPC_CLT_S_df:
24397 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24398 break;
24399 case OPC_ADDS_S_df:
24400 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24401 break;
24402 case OPC_SUBSUS_U_df:
24403 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24404 break;
24405 case OPC_MSUBV_df:
24406 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24407 break;
24408 case OPC_PCKEV_df:
24409 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24410 break;
24411 case OPC_SRLR_df:
24412 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24413 break;
24414 case OPC_BCLR_df:
24415 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24416 break;
24417 case OPC_MAX_U_df:
24418 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24419 break;
24420 case OPC_CLT_U_df:
24421 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24422 break;
24423 case OPC_ADDS_U_df:
24424 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24425 break;
24426 case OPC_SUBSUU_S_df:
24427 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24428 break;
24429 case OPC_PCKOD_df:
24430 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24431 break;
24432 case OPC_BSET_df:
24433 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24434 break;
24435 case OPC_MIN_S_df:
24436 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24437 break;
24438 case OPC_CLE_S_df:
24439 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24440 break;
24441 case OPC_AVE_S_df:
24442 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24443 break;
24444 case OPC_ASUB_S_df:
24445 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24446 break;
24447 case OPC_DIV_S_df:
24448 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24449 break;
24450 case OPC_ILVL_df:
24451 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24452 break;
24453 case OPC_BNEG_df:
24454 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24455 break;
24456 case OPC_MIN_U_df:
24457 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24458 break;
24459 case OPC_CLE_U_df:
24460 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24461 break;
24462 case OPC_AVE_U_df:
24463 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24464 break;
24465 case OPC_ASUB_U_df:
24466 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24467 break;
24468 case OPC_DIV_U_df:
24469 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24470 break;
24471 case OPC_ILVR_df:
24472 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24473 break;
24474 case OPC_BINSL_df:
24475 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24476 break;
24477 case OPC_MAX_A_df:
24478 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24479 break;
24480 case OPC_AVER_S_df:
24481 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24482 break;
24483 case OPC_MOD_S_df:
24484 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24485 break;
24486 case OPC_ILVEV_df:
24487 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24488 break;
24489 case OPC_BINSR_df:
24490 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24491 break;
24492 case OPC_MIN_A_df:
24493 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24494 break;
24495 case OPC_AVER_U_df:
24496 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24497 break;
24498 case OPC_MOD_U_df:
24499 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24500 break;
24501 case OPC_ILVOD_df:
24502 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24503 break;
24504
24505 case OPC_DOTP_S_df:
24506 case OPC_DOTP_U_df:
24507 case OPC_DPADD_S_df:
24508 case OPC_DPADD_U_df:
24509 case OPC_DPSUB_S_df:
24510 case OPC_HADD_S_df:
24511 case OPC_DPSUB_U_df:
24512 case OPC_HADD_U_df:
24513 case OPC_HSUB_S_df:
24514 case OPC_HSUB_U_df:
24515 if (df == DF_BYTE) {
9c708c7f
PD
24516 generate_exception_end(ctx, EXCP_RI);
24517 break;
28f99f08
YK
24518 }
24519 switch (MASK_MSA_3R(ctx->opcode)) {
24520 case OPC_DOTP_S_df:
24521 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24522 break;
24523 case OPC_DOTP_U_df:
24524 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24525 break;
24526 case OPC_DPADD_S_df:
24527 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24528 break;
24529 case OPC_DPADD_U_df:
24530 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24531 break;
24532 case OPC_DPSUB_S_df:
24533 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24534 break;
24535 case OPC_HADD_S_df:
24536 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24537 break;
24538 case OPC_DPSUB_U_df:
24539 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24540 break;
24541 case OPC_HADD_U_df:
24542 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24543 break;
24544 case OPC_HSUB_S_df:
24545 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24546 break;
24547 case OPC_HSUB_U_df:
24548 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24549 break;
24550 }
24551 break;
24552 default:
24553 MIPS_INVAL("MSA instruction");
9c708c7f 24554 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
24555 break;
24556 }
24557 tcg_temp_free_i32(twd);
24558 tcg_temp_free_i32(tws);
24559 tcg_temp_free_i32(twt);
24560 tcg_temp_free_i32(tdf);
24561}
24562
1e608ec1
YK
24563static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24564{
24565#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24566 uint8_t source = (ctx->opcode >> 11) & 0x1f;
24567 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24568 TCGv telm = tcg_temp_new();
24569 TCGv_i32 tsr = tcg_const_i32(source);
24570 TCGv_i32 tdt = tcg_const_i32(dest);
24571
24572 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24573 case OPC_CTCMSA:
24574 gen_load_gpr(telm, source);
24575 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24576 break;
24577 case OPC_CFCMSA:
24578 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24579 gen_store_gpr(telm, dest);
24580 break;
24581 case OPC_MOVE_V:
24582 gen_helper_msa_move_v(cpu_env, tdt, tsr);
24583 break;
24584 default:
24585 MIPS_INVAL("MSA instruction");
9c708c7f 24586 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
24587 break;
24588 }
24589
24590 tcg_temp_free(telm);
24591 tcg_temp_free_i32(tdt);
24592 tcg_temp_free_i32(tsr);
24593}
24594
24595static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24596 uint32_t n)
24597{
24598#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24599 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24600 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24601
24602 TCGv_i32 tws = tcg_const_i32(ws);
24603 TCGv_i32 twd = tcg_const_i32(wd);
24604 TCGv_i32 tn = tcg_const_i32(n);
24605 TCGv_i32 tdf = tcg_const_i32(df);
24606
24607 switch (MASK_MSA_ELM(ctx->opcode)) {
24608 case OPC_SLDI_df:
24609 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24610 break;
24611 case OPC_SPLATI_df:
24612 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24613 break;
24614 case OPC_INSVE_df:
24615 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24616 break;
24617 case OPC_COPY_S_df:
24618 case OPC_COPY_U_df:
24619 case OPC_INSERT_df:
24620#if !defined(TARGET_MIPS64)
24621 /* Double format valid only for MIPS64 */
24622 if (df == DF_DOUBLE) {
9c708c7f 24623 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
24624 break;
24625 }
24626#endif
24627 switch (MASK_MSA_ELM(ctx->opcode)) {
24628 case OPC_COPY_S_df:
cab48881
MD
24629 if (likely(wd != 0)) {
24630 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24631 }
1e608ec1
YK
24632 break;
24633 case OPC_COPY_U_df:
cab48881
MD
24634 if (likely(wd != 0)) {
24635 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24636 }
1e608ec1
YK
24637 break;
24638 case OPC_INSERT_df:
24639 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24640 break;
24641 }
24642 break;
24643 default:
24644 MIPS_INVAL("MSA instruction");
9c708c7f 24645 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
24646 }
24647 tcg_temp_free_i32(twd);
24648 tcg_temp_free_i32(tws);
24649 tcg_temp_free_i32(tn);
24650 tcg_temp_free_i32(tdf);
24651}
24652
24653static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24654{
24655 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24656 uint32_t df = 0, n = 0;
24657
24658 if ((dfn & 0x30) == 0x00) {
24659 n = dfn & 0x0f;
24660 df = DF_BYTE;
24661 } else if ((dfn & 0x38) == 0x20) {
24662 n = dfn & 0x07;
24663 df = DF_HALF;
24664 } else if ((dfn & 0x3c) == 0x30) {
24665 n = dfn & 0x03;
24666 df = DF_WORD;
24667 } else if ((dfn & 0x3e) == 0x38) {
24668 n = dfn & 0x01;
24669 df = DF_DOUBLE;
24670 } else if (dfn == 0x3E) {
24671 /* CTCMSA, CFCMSA, MOVE.V */
24672 gen_msa_elm_3e(env, ctx);
24673 return;
24674 } else {
9c708c7f 24675 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
24676 return;
24677 }
24678
24679 gen_msa_elm_df(env, ctx, df, n);
24680}
24681
7d05b9c8
YK
24682static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24683{
24684#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24685 uint8_t df = (ctx->opcode >> 21) & 0x1;
24686 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24687 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24688 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24689
24690 TCGv_i32 twd = tcg_const_i32(wd);
24691 TCGv_i32 tws = tcg_const_i32(ws);
24692 TCGv_i32 twt = tcg_const_i32(wt);
24693 TCGv_i32 tdf = tcg_temp_new_i32();
24694
24695 /* adjust df value for floating-point instruction */
24696 tcg_gen_movi_i32(tdf, df + 2);
24697
24698 switch (MASK_MSA_3RF(ctx->opcode)) {
24699 case OPC_FCAF_df:
24700 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24701 break;
24702 case OPC_FADD_df:
24703 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24704 break;
24705 case OPC_FCUN_df:
24706 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24707 break;
24708 case OPC_FSUB_df:
24709 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24710 break;
24711 case OPC_FCOR_df:
24712 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24713 break;
24714 case OPC_FCEQ_df:
24715 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24716 break;
24717 case OPC_FMUL_df:
24718 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24719 break;
24720 case OPC_FCUNE_df:
24721 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24722 break;
24723 case OPC_FCUEQ_df:
24724 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24725 break;
24726 case OPC_FDIV_df:
24727 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24728 break;
24729 case OPC_FCNE_df:
24730 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24731 break;
24732 case OPC_FCLT_df:
24733 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24734 break;
24735 case OPC_FMADD_df:
24736 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24737 break;
24738 case OPC_MUL_Q_df:
24739 tcg_gen_movi_i32(tdf, df + 1);
24740 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24741 break;
24742 case OPC_FCULT_df:
24743 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24744 break;
24745 case OPC_FMSUB_df:
24746 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24747 break;
24748 case OPC_MADD_Q_df:
24749 tcg_gen_movi_i32(tdf, df + 1);
24750 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24751 break;
24752 case OPC_FCLE_df:
24753 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24754 break;
24755 case OPC_MSUB_Q_df:
24756 tcg_gen_movi_i32(tdf, df + 1);
24757 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24758 break;
24759 case OPC_FCULE_df:
24760 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24761 break;
24762 case OPC_FEXP2_df:
24763 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24764 break;
24765 case OPC_FSAF_df:
24766 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24767 break;
24768 case OPC_FEXDO_df:
24769 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24770 break;
24771 case OPC_FSUN_df:
24772 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24773 break;
24774 case OPC_FSOR_df:
24775 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24776 break;
24777 case OPC_FSEQ_df:
24778 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24779 break;
24780 case OPC_FTQ_df:
24781 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24782 break;
24783 case OPC_FSUNE_df:
24784 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24785 break;
24786 case OPC_FSUEQ_df:
24787 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24788 break;
24789 case OPC_FSNE_df:
24790 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24791 break;
24792 case OPC_FSLT_df:
24793 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24794 break;
24795 case OPC_FMIN_df:
24796 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24797 break;
24798 case OPC_MULR_Q_df:
24799 tcg_gen_movi_i32(tdf, df + 1);
24800 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24801 break;
24802 case OPC_FSULT_df:
24803 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24804 break;
24805 case OPC_FMIN_A_df:
24806 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24807 break;
24808 case OPC_MADDR_Q_df:
24809 tcg_gen_movi_i32(tdf, df + 1);
24810 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24811 break;
24812 case OPC_FSLE_df:
24813 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24814 break;
24815 case OPC_FMAX_df:
24816 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24817 break;
24818 case OPC_MSUBR_Q_df:
24819 tcg_gen_movi_i32(tdf, df + 1);
24820 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24821 break;
24822 case OPC_FSULE_df:
24823 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24824 break;
24825 case OPC_FMAX_A_df:
24826 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24827 break;
24828 default:
24829 MIPS_INVAL("MSA instruction");
9c708c7f 24830 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
24831 break;
24832 }
24833
24834 tcg_temp_free_i32(twd);
24835 tcg_temp_free_i32(tws);
24836 tcg_temp_free_i32(twt);
24837 tcg_temp_free_i32(tdf);
24838}
24839
cbe50b9a
YK
24840static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24841{
24842#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24843 (op & (0x7 << 18)))
24844 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24845 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24846 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24847 uint8_t df = (ctx->opcode >> 16) & 0x3;
24848 TCGv_i32 twd = tcg_const_i32(wd);
24849 TCGv_i32 tws = tcg_const_i32(ws);
24850 TCGv_i32 twt = tcg_const_i32(wt);
24851 TCGv_i32 tdf = tcg_const_i32(df);
24852
24853 switch (MASK_MSA_2R(ctx->opcode)) {
24854 case OPC_FILL_df:
24855#if !defined(TARGET_MIPS64)
24856 /* Double format valid only for MIPS64 */
24857 if (df == DF_DOUBLE) {
9c708c7f 24858 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
24859 break;
24860 }
24861#endif
24862 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24863 break;
24864 case OPC_PCNT_df:
24865 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24866 break;
24867 case OPC_NLOC_df:
24868 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24869 break;
24870 case OPC_NLZC_df:
24871 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
24872 break;
24873 default:
24874 MIPS_INVAL("MSA instruction");
9c708c7f 24875 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
24876 break;
24877 }
24878
24879 tcg_temp_free_i32(twd);
24880 tcg_temp_free_i32(tws);
24881 tcg_temp_free_i32(twt);
24882 tcg_temp_free_i32(tdf);
24883}
24884
3bdeb688
YK
24885static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
24886{
24887#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24888 (op & (0xf << 17)))
24889 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24890 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24891 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24892 uint8_t df = (ctx->opcode >> 16) & 0x1;
24893 TCGv_i32 twd = tcg_const_i32(wd);
24894 TCGv_i32 tws = tcg_const_i32(ws);
24895 TCGv_i32 twt = tcg_const_i32(wt);
24896 /* adjust df value for floating-point instruction */
24897 TCGv_i32 tdf = tcg_const_i32(df + 2);
24898
24899 switch (MASK_MSA_2RF(ctx->opcode)) {
24900 case OPC_FCLASS_df:
24901 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
24902 break;
24903 case OPC_FTRUNC_S_df:
24904 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
24905 break;
24906 case OPC_FTRUNC_U_df:
24907 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
24908 break;
24909 case OPC_FSQRT_df:
24910 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
24911 break;
24912 case OPC_FRSQRT_df:
24913 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
24914 break;
24915 case OPC_FRCP_df:
24916 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
24917 break;
24918 case OPC_FRINT_df:
24919 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
24920 break;
24921 case OPC_FLOG2_df:
24922 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
24923 break;
24924 case OPC_FEXUPL_df:
24925 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
24926 break;
24927 case OPC_FEXUPR_df:
24928 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
24929 break;
24930 case OPC_FFQL_df:
24931 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
24932 break;
24933 case OPC_FFQR_df:
24934 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
24935 break;
24936 case OPC_FTINT_S_df:
24937 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
24938 break;
24939 case OPC_FTINT_U_df:
24940 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
24941 break;
24942 case OPC_FFINT_S_df:
24943 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
24944 break;
24945 case OPC_FFINT_U_df:
24946 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
24947 break;
24948 }
24949
24950 tcg_temp_free_i32(twd);
24951 tcg_temp_free_i32(tws);
24952 tcg_temp_free_i32(twt);
24953 tcg_temp_free_i32(tdf);
24954}
24955
cbe50b9a
YK
24956static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
24957{
24958#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
24959 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24960 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24961 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24962 TCGv_i32 twd = tcg_const_i32(wd);
24963 TCGv_i32 tws = tcg_const_i32(ws);
24964 TCGv_i32 twt = tcg_const_i32(wt);
24965
24966 switch (MASK_MSA_VEC(ctx->opcode)) {
24967 case OPC_AND_V:
24968 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
24969 break;
24970 case OPC_OR_V:
24971 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
24972 break;
24973 case OPC_NOR_V:
24974 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
24975 break;
24976 case OPC_XOR_V:
24977 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
24978 break;
24979 case OPC_BMNZ_V:
24980 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
24981 break;
24982 case OPC_BMZ_V:
24983 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
24984 break;
24985 case OPC_BSEL_V:
24986 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
24987 break;
24988 default:
24989 MIPS_INVAL("MSA instruction");
9c708c7f 24990 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
24991 break;
24992 }
24993
24994 tcg_temp_free_i32(twd);
24995 tcg_temp_free_i32(tws);
24996 tcg_temp_free_i32(twt);
24997}
24998
24999static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25000{
25001 switch (MASK_MSA_VEC(ctx->opcode)) {
25002 case OPC_AND_V:
25003 case OPC_OR_V:
25004 case OPC_NOR_V:
25005 case OPC_XOR_V:
25006 case OPC_BMNZ_V:
25007 case OPC_BMZ_V:
25008 case OPC_BSEL_V:
25009 gen_msa_vec_v(env, ctx);
25010 break;
25011 case OPC_MSA_2R:
25012 gen_msa_2r(env, ctx);
25013 break;
3bdeb688
YK
25014 case OPC_MSA_2RF:
25015 gen_msa_2rf(env, ctx);
25016 break;
cbe50b9a
YK
25017 default:
25018 MIPS_INVAL("MSA instruction");
9c708c7f 25019 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
25020 break;
25021 }
25022}
25023
4c789546
YK
25024static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25025{
25026 uint32_t opcode = ctx->opcode;
25027 check_insn(ctx, ASE_MSA);
25028 check_msa_access(ctx);
25029
25030 switch (MASK_MSA_MINOR(opcode)) {
25031 case OPC_MSA_I8_00:
25032 case OPC_MSA_I8_01:
25033 case OPC_MSA_I8_02:
25034 gen_msa_i8(env, ctx);
25035 break;
80e71591
YK
25036 case OPC_MSA_I5_06:
25037 case OPC_MSA_I5_07:
25038 gen_msa_i5(env, ctx);
25039 break;
d4cf28de
YK
25040 case OPC_MSA_BIT_09:
25041 case OPC_MSA_BIT_0A:
25042 gen_msa_bit(env, ctx);
25043 break;
28f99f08
YK
25044 case OPC_MSA_3R_0D:
25045 case OPC_MSA_3R_0E:
25046 case OPC_MSA_3R_0F:
25047 case OPC_MSA_3R_10:
25048 case OPC_MSA_3R_11:
25049 case OPC_MSA_3R_12:
25050 case OPC_MSA_3R_13:
25051 case OPC_MSA_3R_14:
25052 case OPC_MSA_3R_15:
25053 gen_msa_3r(env, ctx);
25054 break;
1e608ec1
YK
25055 case OPC_MSA_ELM:
25056 gen_msa_elm(env, ctx);
25057 break;
7d05b9c8
YK
25058 case OPC_MSA_3RF_1A:
25059 case OPC_MSA_3RF_1B:
25060 case OPC_MSA_3RF_1C:
25061 gen_msa_3rf(env, ctx);
25062 break;
cbe50b9a
YK
25063 case OPC_MSA_VEC:
25064 gen_msa_vec(env, ctx);
25065 break;
f7685877
YK
25066 case OPC_LD_B:
25067 case OPC_LD_H:
25068 case OPC_LD_W:
25069 case OPC_LD_D:
25070 case OPC_ST_B:
25071 case OPC_ST_H:
25072 case OPC_ST_W:
25073 case OPC_ST_D:
25074 {
25075 int32_t s10 = sextract32(ctx->opcode, 16, 10);
25076 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25077 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25078 uint8_t df = (ctx->opcode >> 0) & 0x3;
25079
f7685877 25080 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
25081 TCGv taddr = tcg_temp_new();
25082 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
25083
25084 switch (MASK_MSA_MINOR(opcode)) {
25085 case OPC_LD_B:
adc370a4
YK
25086 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25087 break;
f7685877 25088 case OPC_LD_H:
adc370a4
YK
25089 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25090 break;
f7685877 25091 case OPC_LD_W:
adc370a4
YK
25092 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25093 break;
f7685877 25094 case OPC_LD_D:
adc370a4 25095 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
25096 break;
25097 case OPC_ST_B:
adc370a4
YK
25098 gen_helper_msa_st_b(cpu_env, twd, taddr);
25099 break;
f7685877 25100 case OPC_ST_H:
adc370a4
YK
25101 gen_helper_msa_st_h(cpu_env, twd, taddr);
25102 break;
f7685877 25103 case OPC_ST_W:
adc370a4
YK
25104 gen_helper_msa_st_w(cpu_env, twd, taddr);
25105 break;
f7685877 25106 case OPC_ST_D:
adc370a4 25107 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
25108 break;
25109 }
25110
25111 tcg_temp_free_i32(twd);
adc370a4 25112 tcg_temp_free(taddr);
f7685877
YK
25113 }
25114 break;
4c789546
YK
25115 default:
25116 MIPS_INVAL("MSA instruction");
9c708c7f 25117 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
25118 break;
25119 }
25120
25121}
25122
d2bfa6e6 25123static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
25124{
25125 int32_t offset;
25126 int rs, rt, rd, sa;
25127 uint32_t op, op1;
25128 int16_t imm;
25129
25130 /* make sure instructions are on a word boundary */
eeb3bba8
EC
25131 if (ctx->base.pc_next & 0x3) {
25132 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 25133 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
25134 return;
25135 }
25136
25137 /* Handle blikely not taken case */
25138 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 25139 TCGLabel *l1 = gen_new_label();
099e5b4d 25140
099e5b4d
LA
25141 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25142 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 25143 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
25144 gen_set_label(l1);
25145 }
25146
099e5b4d
LA
25147 op = MASK_OP_MAJOR(ctx->opcode);
25148 rs = (ctx->opcode >> 21) & 0x1f;
25149 rt = (ctx->opcode >> 16) & 0x1f;
25150 rd = (ctx->opcode >> 11) & 0x1f;
25151 sa = (ctx->opcode >> 6) & 0x1f;
25152 imm = (int16_t)ctx->opcode;
25153 switch (op) {
25154 case OPC_SPECIAL:
25155 decode_opc_special(env, ctx);
25156 break;
25157 case OPC_SPECIAL2:
4267d3e6 25158 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
25159 break;
25160 case OPC_SPECIAL3:
25161 decode_opc_special3(env, ctx);
25162 break;
7a387fff
TS
25163 case OPC_REGIMM:
25164 op1 = MASK_REGIMM(ctx->opcode);
25165 switch (op1) {
fecd2646
LA
25166 case OPC_BLTZL: /* REGIMM branches */
25167 case OPC_BGEZL:
25168 case OPC_BLTZALL:
25169 case OPC_BGEZALL:
d9224450 25170 check_insn(ctx, ISA_MIPS2);
fecd2646 25171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 25172 /* Fallthrough */
fecd2646
LA
25173 case OPC_BLTZ:
25174 case OPC_BGEZ:
b231c103 25175 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 25176 break;
fecd2646
LA
25177 case OPC_BLTZAL:
25178 case OPC_BGEZAL:
0aefa333
YK
25179 if (ctx->insn_flags & ISA_MIPS32R6) {
25180 if (rs == 0) {
25181 /* OPC_NAL, OPC_BAL */
b231c103 25182 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 25183 } else {
9c708c7f 25184 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
25185 }
25186 } else {
b231c103 25187 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 25188 }
c9602061 25189 break;
c2e19f3c
AM
25190 case OPC_TGEI: /* REGIMM traps */
25191 case OPC_TGEIU:
25192 case OPC_TLTI:
25193 case OPC_TLTIU:
25194 case OPC_TEQI:
25195
7a387fff 25196 case OPC_TNEI:
d9224450 25197 check_insn(ctx, ISA_MIPS2);
fecd2646 25198 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
25199 gen_trap(ctx, op1, rs, -1, imm);
25200 break;
bb238210
YK
25201 case OPC_SIGRIE:
25202 check_insn(ctx, ISA_MIPS32R6);
25203 generate_exception_end(ctx, EXCP_RI);
25204 break;
7a387fff 25205 case OPC_SYNCI:
d75c135e 25206 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
25207 /* Break the TB to be able to sync copied instructions
25208 immediately */
eeb3bba8 25209 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 25210 break;
e45a93e2
JL
25211 case OPC_BPOSGE32: /* MIPS DSP branch */
25212#if defined(TARGET_MIPS64)
25213 case OPC_BPOSGE64:
25214#endif
25215 check_dsp(ctx);
b231c103 25216 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 25217 break;
d4ea6acd
LA
25218#if defined(TARGET_MIPS64)
25219 case OPC_DAHI:
25220 check_insn(ctx, ISA_MIPS32R6);
25221 check_mips_64(ctx);
25222 if (rs != 0) {
25223 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25224 }
d4ea6acd
LA
25225 break;
25226 case OPC_DATI:
25227 check_insn(ctx, ISA_MIPS32R6);
25228 check_mips_64(ctx);
25229 if (rs != 0) {
25230 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25231 }
d4ea6acd
LA
25232 break;
25233#endif
6af0bf9c 25234 default: /* Invalid */
923617a3 25235 MIPS_INVAL("regimm");
9c708c7f 25236 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
25237 break;
25238 }
25239 break;
7a387fff 25240 case OPC_CP0:
387a8fe5 25241 check_cp0_enabled(ctx);
7a387fff 25242 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 25243 switch (op1) {
7a387fff
TS
25244 case OPC_MFC0:
25245 case OPC_MTC0:
ead9360e
TS
25246 case OPC_MFTR:
25247 case OPC_MTTR:
5204ea79
LA
25248 case OPC_MFHC0:
25249 case OPC_MTHC0:
d26bc211 25250#if defined(TARGET_MIPS64)
7a387fff
TS
25251 case OPC_DMFC0:
25252 case OPC_DMTC0:
25253#endif
f1aa6320 25254#ifndef CONFIG_USER_ONLY
932e71cd 25255 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 25256#endif /* !CONFIG_USER_ONLY */
7a387fff 25257 break;
c38a1d52
AR
25258 case OPC_C0:
25259 case OPC_C0_1:
25260 case OPC_C0_2:
25261 case OPC_C0_3:
25262 case OPC_C0_4:
25263 case OPC_C0_5:
25264 case OPC_C0_6:
25265 case OPC_C0_7:
25266 case OPC_C0_8:
25267 case OPC_C0_9:
25268 case OPC_C0_A:
25269 case OPC_C0_B:
25270 case OPC_C0_C:
25271 case OPC_C0_D:
25272 case OPC_C0_E:
25273 case OPC_C0_F:
f1aa6320 25274#ifndef CONFIG_USER_ONLY
932e71cd 25275 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 25276#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
25277 break;
25278 case OPC_MFMC0:
8706c382 25279#ifndef CONFIG_USER_ONLY
932e71cd 25280 {
099e5b4d 25281 uint32_t op2;
35fbce2c 25282 TCGv t0 = tcg_temp_new();
6c5c1e20 25283
0eaef5aa 25284 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
25285 switch (op2) {
25286 case OPC_DMT:
9affc1c5 25287 check_cp0_mt(ctx);
9ed5726c 25288 gen_helper_dmt(t0);
35fbce2c 25289 gen_store_gpr(t0, rt);
6c5c1e20
TS
25290 break;
25291 case OPC_EMT:
9affc1c5 25292 check_cp0_mt(ctx);
9ed5726c 25293 gen_helper_emt(t0);
35fbce2c 25294 gen_store_gpr(t0, rt);
da80682b 25295 break;
6c5c1e20 25296 case OPC_DVPE:
9affc1c5 25297 check_cp0_mt(ctx);
895c2d04 25298 gen_helper_dvpe(t0, cpu_env);
35fbce2c 25299 gen_store_gpr(t0, rt);
6c5c1e20
TS
25300 break;
25301 case OPC_EVPE:
9affc1c5 25302 check_cp0_mt(ctx);
895c2d04 25303 gen_helper_evpe(t0, cpu_env);
35fbce2c 25304 gen_store_gpr(t0, rt);
6c5c1e20 25305 break;
01bc435b
YK
25306 case OPC_DVP:
25307 check_insn(ctx, ISA_MIPS32R6);
25308 if (ctx->vp) {
25309 gen_helper_dvp(t0, cpu_env);
25310 gen_store_gpr(t0, rt);
25311 }
25312 break;
25313 case OPC_EVP:
25314 check_insn(ctx, ISA_MIPS32R6);
25315 if (ctx->vp) {
25316 gen_helper_evp(t0, cpu_env);
25317 gen_store_gpr(t0, rt);
25318 }
25319 break;
6c5c1e20 25320 case OPC_DI:
d75c135e 25321 check_insn(ctx, ISA_MIPS32R2);
867abc7e 25322 save_cpu_state(ctx, 1);
895c2d04 25323 gen_helper_di(t0, cpu_env);
35fbce2c 25324 gen_store_gpr(t0, rt);
d2bfa6e6
MR
25325 /* Stop translation as we may have switched
25326 the execution mode. */
eeb3bba8 25327 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
25328 break;
25329 case OPC_EI:
d75c135e 25330 check_insn(ctx, ISA_MIPS32R2);
867abc7e 25331 save_cpu_state(ctx, 1);
895c2d04 25332 gen_helper_ei(t0, cpu_env);
35fbce2c 25333 gen_store_gpr(t0, rt);
b28425ba
EC
25334 /* DISAS_STOP isn't sufficient, we need to ensure we break
25335 out of translated code to check for pending interrupts */
eeb3bba8
EC
25336 gen_save_pc(ctx->base.pc_next + 4);
25337 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
25338 break;
25339 default: /* Invalid */
25340 MIPS_INVAL("mfmc0");
9c708c7f 25341 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
25342 break;
25343 }
6c5c1e20 25344 tcg_temp_free(t0);
7a387fff 25345 }
0eaef5aa 25346#endif /* !CONFIG_USER_ONLY */
6af0bf9c 25347 break;
7a387fff 25348 case OPC_RDPGPR:
d75c135e 25349 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 25350 gen_load_srsgpr(rt, rd);
ead9360e 25351 break;
7a387fff 25352 case OPC_WRPGPR:
d75c135e 25353 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 25354 gen_store_srsgpr(rt, rd);
38121543 25355 break;
6af0bf9c 25356 default:
923617a3 25357 MIPS_INVAL("cp0");
9c708c7f 25358 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
25359 break;
25360 }
25361 break;
31837be3
YK
25362 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25363 if (ctx->insn_flags & ISA_MIPS32R6) {
25364 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25365 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25366 } else {
25367 /* OPC_ADDI */
25368 /* Arithmetic with immediate opcode */
25369 gen_arith_imm(ctx, op, rt, rs, imm);
25370 }
25371 break;
324d9e32 25372 case OPC_ADDIU:
d75c135e 25373 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 25374 break;
324d9e32
AJ
25375 case OPC_SLTI: /* Set on less than with immediate opcode */
25376 case OPC_SLTIU:
d75c135e 25377 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
25378 break;
25379 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 25380 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
25381 case OPC_ORI:
25382 case OPC_XORI:
d75c135e 25383 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 25384 break;
c2e19f3c
AM
25385 case OPC_J: /* Jump */
25386 case OPC_JAL:
7a387fff 25387 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 25388 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 25389 break;
31837be3
YK
25390 /* Branch */
25391 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25392 if (ctx->insn_flags & ISA_MIPS32R6) {
25393 if (rt == 0) {
9c708c7f 25394 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
25395 break;
25396 }
25397 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25398 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25399 } else {
25400 /* OPC_BLEZL */
b231c103 25401 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25402 }
25403 break;
25404 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25405 if (ctx->insn_flags & ISA_MIPS32R6) {
25406 if (rt == 0) {
9c708c7f 25407 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
25408 break;
25409 }
25410 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25411 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25412 } else {
25413 /* OPC_BGTZL */
b231c103 25414 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25415 }
25416 break;
25417 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25418 if (rt == 0) {
25419 /* OPC_BLEZ */
b231c103 25420 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25421 } else {
25422 check_insn(ctx, ISA_MIPS32R6);
25423 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25424 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25425 }
25426 break;
25427 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25428 if (rt == 0) {
25429 /* OPC_BGTZ */
b231c103 25430 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
25431 } else {
25432 check_insn(ctx, ISA_MIPS32R6);
25433 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25434 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25435 }
25436 break;
25437 case OPC_BEQL:
25438 case OPC_BNEL:
d9224450 25439 check_insn(ctx, ISA_MIPS2);
fecd2646 25440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 25441 /* Fallthrough */
31837be3
YK
25442 case OPC_BEQ:
25443 case OPC_BNE:
b231c103 25444 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 25445 break;
d9224450
MR
25446 case OPC_LL: /* Load and stores */
25447 check_insn(ctx, ISA_MIPS2);
25448 /* Fallthrough */
25449 case OPC_LWL:
fecd2646
LA
25450 case OPC_LWR:
25451 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 25452 /* Fallthrough */
c2e19f3c
AM
25453 case OPC_LB:
25454 case OPC_LH:
25455 case OPC_LW:
25456 case OPC_LWPC:
25457 case OPC_LBU:
25458 case OPC_LHU:
d75c135e 25459 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 25460 break;
fecd2646 25461 case OPC_SWL:
7a387fff 25462 case OPC_SWR:
fecd2646 25463 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 25464 /* fall through */
c2e19f3c
AM
25465 case OPC_SB:
25466 case OPC_SH:
fecd2646 25467 case OPC_SW:
5c13fdfd 25468 gen_st(ctx, op, rt, rs, imm);
7a387fff 25469 break;
d66c7132 25470 case OPC_SC:
d9224450 25471 check_insn(ctx, ISA_MIPS2);
4368b29a 25472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
25473 gen_st_cond(ctx, op, rt, rs, imm);
25474 break;
7a387fff 25475 case OPC_CACHE:
bf7910c6 25476 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 25477 check_cp0_enabled(ctx);
d75c135e 25478 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
25479 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25480 gen_cache_operation(ctx, rt, rs, imm);
25481 }
ead9360e 25482 /* Treat as NOP. */
34ae7b51 25483 break;
7a387fff 25484 case OPC_PREF:
bf7910c6 25485 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 25486 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 25487 /* Treat as NOP. */
6af0bf9c 25488 break;
4ad40f36 25489
923617a3 25490 /* Floating point (COP1). */
7a387fff
TS
25491 case OPC_LWC1:
25492 case OPC_LDC1:
25493 case OPC_SWC1:
25494 case OPC_SDC1:
5ab5c041 25495 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
25496 break;
25497
7a387fff 25498 case OPC_CP1:
5692c6e1
YK
25499 op1 = MASK_CP1(ctx->opcode);
25500
25501 switch (op1) {
25502 case OPC_MFHC1:
25503 case OPC_MTHC1:
5e755519 25504 check_cp1_enabled(ctx);
5692c6e1 25505 check_insn(ctx, ISA_MIPS32R2);
146dd620 25506 /* fall through */
5692c6e1
YK
25507 case OPC_MFC1:
25508 case OPC_CFC1:
25509 case OPC_MTC1:
25510 case OPC_CTC1:
25511 check_cp1_enabled(ctx);
25512 gen_cp1(ctx, op1, rt, rd);
25513 break;
d26bc211 25514#if defined(TARGET_MIPS64)
5692c6e1
YK
25515 case OPC_DMFC1:
25516 case OPC_DMTC1:
25517 check_cp1_enabled(ctx);
25518 check_insn(ctx, ISA_MIPS3);
d9224450 25519 check_mips_64(ctx);
5692c6e1
YK
25520 gen_cp1(ctx, op1, rt, rd);
25521 break;
e189e748 25522#endif
5692c6e1
YK
25523 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25524 check_cp1_enabled(ctx);
25525 if (ctx->insn_flags & ISA_MIPS32R6) {
25526 /* OPC_BC1EQZ */
31837be3 25527 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 25528 rt, imm << 2, 4);
5692c6e1
YK
25529 } else {
25530 /* OPC_BC1ANY2 */
b8aa4598 25531 check_cop1x(ctx);
d75c135e 25532 check_insn(ctx, ASE_MIPS3D);
d75c135e 25533 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 25534 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
25535 }
25536 break;
25537 case OPC_BC1NEZ:
25538 check_cp1_enabled(ctx);
25539 check_insn(ctx, ISA_MIPS32R6);
25540 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 25541 rt, imm << 2, 4);
5692c6e1
YK
25542 break;
25543 case OPC_BC1ANY4:
25544 check_cp1_enabled(ctx);
25545 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25546 check_cop1x(ctx);
25547 check_insn(ctx, ASE_MIPS3D);
25548 /* fall through */
25549 case OPC_BC1:
25550 check_cp1_enabled(ctx);
25551 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25552 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25553 (rt >> 2) & 0x7, imm << 2);
25554 break;
25555 case OPC_PS_FMT:
e29c9628 25556 check_ps(ctx);
b6f3b233 25557 /* fall through */
5692c6e1
YK
25558 case OPC_S_FMT:
25559 case OPC_D_FMT:
25560 check_cp1_enabled(ctx);
25561 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25562 (imm >> 8) & 0x7);
25563 break;
25564 case OPC_W_FMT:
25565 case OPC_L_FMT:
25566 {
25567 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25568 check_cp1_enabled(ctx);
25569 if (ctx->insn_flags & ISA_MIPS32R6) {
25570 switch (r6_op) {
25571 case R6_OPC_CMP_AF_S:
25572 case R6_OPC_CMP_UN_S:
25573 case R6_OPC_CMP_EQ_S:
25574 case R6_OPC_CMP_UEQ_S:
25575 case R6_OPC_CMP_LT_S:
25576 case R6_OPC_CMP_ULT_S:
25577 case R6_OPC_CMP_LE_S:
25578 case R6_OPC_CMP_ULE_S:
25579 case R6_OPC_CMP_SAF_S:
25580 case R6_OPC_CMP_SUN_S:
25581 case R6_OPC_CMP_SEQ_S:
25582 case R6_OPC_CMP_SEUQ_S:
25583 case R6_OPC_CMP_SLT_S:
25584 case R6_OPC_CMP_SULT_S:
25585 case R6_OPC_CMP_SLE_S:
25586 case R6_OPC_CMP_SULE_S:
25587 case R6_OPC_CMP_OR_S:
25588 case R6_OPC_CMP_UNE_S:
25589 case R6_OPC_CMP_NE_S:
25590 case R6_OPC_CMP_SOR_S:
25591 case R6_OPC_CMP_SUNE_S:
25592 case R6_OPC_CMP_SNE_S:
25593 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25594 break;
25595 case R6_OPC_CMP_AF_D:
25596 case R6_OPC_CMP_UN_D:
25597 case R6_OPC_CMP_EQ_D:
25598 case R6_OPC_CMP_UEQ_D:
25599 case R6_OPC_CMP_LT_D:
25600 case R6_OPC_CMP_ULT_D:
25601 case R6_OPC_CMP_LE_D:
25602 case R6_OPC_CMP_ULE_D:
25603 case R6_OPC_CMP_SAF_D:
25604 case R6_OPC_CMP_SUN_D:
25605 case R6_OPC_CMP_SEQ_D:
25606 case R6_OPC_CMP_SEUQ_D:
25607 case R6_OPC_CMP_SLT_D:
25608 case R6_OPC_CMP_SULT_D:
25609 case R6_OPC_CMP_SLE_D:
25610 case R6_OPC_CMP_SULE_D:
25611 case R6_OPC_CMP_OR_D:
25612 case R6_OPC_CMP_UNE_D:
25613 case R6_OPC_CMP_NE_D:
25614 case R6_OPC_CMP_SOR_D:
25615 case R6_OPC_CMP_SUNE_D:
25616 case R6_OPC_CMP_SNE_D:
25617 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25618 break;
25619 default:
d2bfa6e6
MR
25620 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25621 rt, rd, sa, (imm >> 8) & 0x7);
25622
5692c6e1 25623 break;
3f493883 25624 }
5692c6e1
YK
25625 } else {
25626 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25627 (imm >> 8) & 0x7);
36d23958 25628 }
5692c6e1
YK
25629 break;
25630 }
25631 case OPC_BZ_V:
25632 case OPC_BNZ_V:
25633 case OPC_BZ_B:
25634 case OPC_BZ_H:
25635 case OPC_BZ_W:
25636 case OPC_BZ_D:
25637 case OPC_BNZ_B:
25638 case OPC_BNZ_H:
25639 case OPC_BNZ_W:
25640 case OPC_BNZ_D:
25641 check_insn(ctx, ASE_MSA);
25642 gen_msa_branch(env, ctx, op1);
25643 break;
25644 default:
25645 MIPS_INVAL("cp1");
9c708c7f 25646 generate_exception_end(ctx, EXCP_RI);
5692c6e1 25647 break;
6ea83fed 25648 }
4ad40f36
FB
25649 break;
25650
31837be3
YK
25651 /* Compact branches [R6] and COP2 [non-R6] */
25652 case OPC_BC: /* OPC_LWC2 */
25653 case OPC_BALC: /* OPC_SWC2 */
25654 if (ctx->insn_flags & ISA_MIPS32R6) {
25655 /* OPC_BC, OPC_BALC */
25656 gen_compute_compact_branch(ctx, op, 0, 0,
25657 sextract32(ctx->opcode << 2, 0, 28));
25658 } else {
25659 /* OPC_LWC2, OPC_SWC2 */
25660 /* COP2: Not implemented. */
25661 generate_exception_err(ctx, EXCP_CpU, 2);
25662 }
25663 break;
25664 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25665 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25666 if (ctx->insn_flags & ISA_MIPS32R6) {
25667 if (rs != 0) {
25668 /* OPC_BEQZC, OPC_BNEZC */
25669 gen_compute_compact_branch(ctx, op, rs, 0,
25670 sextract32(ctx->opcode << 2, 0, 23));
25671 } else {
25672 /* OPC_JIC, OPC_JIALC */
25673 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25674 }
25675 } else {
25676 /* OPC_LWC2, OPC_SWC2 */
25677 /* COP2: Not implemented. */
25678 generate_exception_err(ctx, EXCP_CpU, 2);
25679 }
4ad40f36 25680 break;
bd277fa1 25681 case OPC_CP2:
d75c135e 25682 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
25683 /* Note that these instructions use different fields. */
25684 gen_loongson_multimedia(ctx, sa, rd, rt);
25685 break;
4ad40f36 25686
7a387fff 25687 case OPC_CP3:
fecd2646 25688 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 25689 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 25690 check_cp1_enabled(ctx);
36d23958
TS
25691 op1 = MASK_CP3(ctx->opcode);
25692 switch (op1) {
d9224450
MR
25693 case OPC_LUXC1:
25694 case OPC_SUXC1:
25695 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25696 /* Fallthrough */
5a5012ec
TS
25697 case OPC_LWXC1:
25698 case OPC_LDXC1:
5a5012ec
TS
25699 case OPC_SWXC1:
25700 case OPC_SDXC1:
d9224450 25701 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 25702 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 25703 break;
e0c84da7 25704 case OPC_PREFX:
d9224450 25705 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 25706 /* Treat as NOP. */
e0c84da7 25707 break;
5a5012ec 25708 case OPC_ALNV_PS:
d9224450
MR
25709 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25710 /* Fallthrough */
5a5012ec
TS
25711 case OPC_MADD_S:
25712 case OPC_MADD_D:
25713 case OPC_MADD_PS:
25714 case OPC_MSUB_S:
25715 case OPC_MSUB_D:
25716 case OPC_MSUB_PS:
25717 case OPC_NMADD_S:
25718 case OPC_NMADD_D:
25719 case OPC_NMADD_PS:
25720 case OPC_NMSUB_S:
25721 case OPC_NMSUB_D:
25722 case OPC_NMSUB_PS:
d9224450 25723 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
25724 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25725 break;
36d23958 25726 default:
923617a3 25727 MIPS_INVAL("cp3");
9c708c7f 25728 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
25729 break;
25730 }
25731 } else {
e397ee33 25732 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 25733 }
4ad40f36
FB
25734 break;
25735
d26bc211 25736#if defined(TARGET_MIPS64)
7a387fff 25737 /* MIPS64 opcodes */
c2e19f3c
AM
25738 case OPC_LDL:
25739 case OPC_LDR:
bf7910c6 25740 case OPC_LLD:
fecd2646 25741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 25742 /* fall through */
fecd2646 25743 case OPC_LWU:
7a387fff 25744 case OPC_LD:
d75c135e 25745 check_insn(ctx, ISA_MIPS3);
5c13fdfd 25746 check_mips_64(ctx);
d75c135e 25747 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 25748 break;
c2e19f3c
AM
25749 case OPC_SDL:
25750 case OPC_SDR:
fecd2646 25751 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 25752 /* fall through */
7a387fff 25753 case OPC_SD:
d75c135e 25754 check_insn(ctx, ISA_MIPS3);
e189e748 25755 check_mips_64(ctx);
5c13fdfd 25756 gen_st(ctx, op, rt, rs, imm);
7a387fff 25757 break;
d66c7132 25758 case OPC_SCD:
bf7910c6 25759 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 25760 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
25761 check_mips_64(ctx);
25762 gen_st_cond(ctx, op, rt, rs, imm);
25763 break;
31837be3
YK
25764 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25765 if (ctx->insn_flags & ISA_MIPS32R6) {
25766 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25767 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25768 } else {
25769 /* OPC_DADDI */
25770 check_insn(ctx, ISA_MIPS3);
25771 check_mips_64(ctx);
25772 gen_arith_imm(ctx, op, rt, rs, imm);
25773 }
25774 break;
324d9e32 25775 case OPC_DADDIU:
d75c135e 25776 check_insn(ctx, ISA_MIPS3);
e189e748 25777 check_mips_64(ctx);
d75c135e 25778 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 25779 break;
31837be3
YK
25780#else
25781 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25782 if (ctx->insn_flags & ISA_MIPS32R6) {
25783 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25784 } else {
25785 MIPS_INVAL("major opcode");
9c708c7f 25786 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
25787 }
25788 break;
6af0bf9c 25789#endif
d4ea6acd
LA
25790 case OPC_DAUI: /* OPC_JALX */
25791 if (ctx->insn_flags & ISA_MIPS32R6) {
25792#if defined(TARGET_MIPS64)
25793 /* OPC_DAUI */
25794 check_mips_64(ctx);
db77d852
LA
25795 if (rs == 0) {
25796 generate_exception(ctx, EXCP_RI);
25797 } else if (rt != 0) {
d4ea6acd
LA
25798 TCGv t0 = tcg_temp_new();
25799 gen_load_gpr(t0, rs);
25800 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25801 tcg_temp_free(t0);
25802 }
d4ea6acd 25803#else
9c708c7f 25804 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
25805 MIPS_INVAL("major opcode");
25806#endif
25807 } else {
25808 /* OPC_JALX */
25809 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25810 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 25811 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 25812 }
364d4831 25813 break;
4c789546 25814 case OPC_MSA: /* OPC_MDMX */
7a387fff 25815 /* MDMX: Not implemented. */
4c789546 25816 gen_msa(env, ctx);
d4ea6acd
LA
25817 break;
25818 case OPC_PCREL:
25819 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 25820 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 25821 break;
6af0bf9c 25822 default: /* Invalid */
923617a3 25823 MIPS_INVAL("major opcode");
9c708c7f 25824 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
25825 break;
25826 }
6af0bf9c
FB
25827}
25828
18f440ed 25829static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 25830{
18f440ed 25831 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 25832 CPUMIPSState *env = cs->env_ptr;
12be9258 25833
18f440ed 25834 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
25835 ctx->saved_pc = -1;
25836 ctx->insn_flags = env->insn_flags;
25837 ctx->CP0_Config1 = env->CP0_Config1;
ab77fc61
DN
25838 ctx->CP0_Config3 = env->CP0_Config3;
25839 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
25840 ctx->btarget = 0;
25841 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25842 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25843 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25844 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25845 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25846 ctx->PAMask = env->PAMask;
25847 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25848 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25849 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25850 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25851 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 25852 /* Restore delay slot state from the tb context. */
12be9258
EC
25853 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25854 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25855 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 25856 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
25857 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25858 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25859 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25860 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25861 restore_cpu_state(env, ctx);
932e71cd 25862#ifdef CONFIG_USER_ONLY
12be9258 25863 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 25864#else
12be9258 25865 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 25866#endif
12be9258
EC
25867 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25868 MO_UNALN : MO_ALIGN;
190ce7fb 25869
18f440ed
EC
25870 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25871 ctx->hflags);
25872}
12be9258 25873
18f440ed
EC
25874static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25875{
25876}
b933066a 25877
18f440ed
EC
25878static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25879{
25880 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 25881
18f440ed
EC
25882 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25883 ctx->btarget);
25884}
31837be3 25885
18f440ed
EC
25886static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25887 const CPUBreakpoint *bp)
25888{
25889 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 25890
18f440ed
EC
25891 save_cpu_state(ctx, 1);
25892 ctx->base.is_jmp = DISAS_NORETURN;
25893 gen_helper_raise_exception_debug(cpu_env);
25894 /* The address covered by the breakpoint must be included in
25895 [tb->pc, tb->pc + tb->size) in order to for it to be
25896 properly cleared -- thus we increment the PC here so that
25897 the logic setting tb->size below does the right thing. */
25898 ctx->base.pc_next += 4;
25899 return true;
25900}
4ad40f36 25901
18f440ed
EC
25902static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25903{
25904 CPUMIPSState *env = cs->env_ptr;
25905 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25906 int insn_bytes;
25907 int is_slot;
4ad40f36 25908
18f440ed 25909 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
25910 if (ctx->insn_flags & ISA_NANOMIPS32) {
25911 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25912 insn_bytes = decode_nanomips_opc(env, ctx);
25913 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
25914 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
25915 insn_bytes = 4;
25916 decode_opc(env, ctx);
25917 } else if (ctx->insn_flags & ASE_MICROMIPS) {
25918 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25919 insn_bytes = decode_micromips_opc(env, ctx);
25920 } else if (ctx->insn_flags & ASE_MIPS16) {
25921 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25922 insn_bytes = decode_mips16_opc(env, ctx);
25923 } else {
25924 generate_exception_end(ctx, EXCP_RI);
25925 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
25926 return;
25927 }
faf7aaa9 25928
18f440ed
EC
25929 if (ctx->hflags & MIPS_HFLAG_BMASK) {
25930 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
25931 MIPS_HFLAG_FBNSLOT))) {
25932 /* force to generate branch as there is neither delay nor
25933 forbidden slot */
25934 is_slot = 1;
25935 }
25936 if ((ctx->hflags & MIPS_HFLAG_M16) &&
25937 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
25938 /* Force to generate branch as microMIPS R6 doesn't restrict
25939 branches in the forbidden slot. */
25940 is_slot = 1;
eeb3bba8 25941 }
18f440ed
EC
25942 }
25943 if (is_slot) {
25944 gen_branch(ctx, insn_bytes);
25945 }
25946 ctx->base.pc_next += insn_bytes;
1b530a6d 25947
18f440ed
EC
25948 if (ctx->base.is_jmp != DISAS_NEXT) {
25949 return;
6af0bf9c 25950 }
18f440ed
EC
25951 /* Execute a branch and its delay slot as a single instruction.
25952 This is what GDB expects and is consistent with what the
25953 hardware does (e.g. if a delay slot instruction faults, the
25954 reported PC is the PC of the branch). */
25955 if (ctx->base.singlestep_enabled &&
25956 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
25957 ctx->base.is_jmp = DISAS_TOO_MANY;
25958 }
25959 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
25960 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 25961 }
18f440ed
EC
25962}
25963
25964static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
25965{
25966 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25967
12be9258
EC
25968 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
25969 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 25970 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 25971 } else {
12be9258 25972 switch (ctx->base.is_jmp) {
b28425ba 25973 case DISAS_STOP:
12be9258 25974 gen_save_pc(ctx->base.pc_next);
cd314a7d 25975 tcg_gen_lookup_and_goto_ptr();
df1561e2 25976 break;
b28425ba 25977 case DISAS_NEXT:
18f440ed 25978 case DISAS_TOO_MANY:
12be9258
EC
25979 save_cpu_state(ctx, 0);
25980 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 25981 break;
b28425ba 25982 case DISAS_EXIT:
07ea28b4 25983 tcg_gen_exit_tb(NULL, 0);
16c00cb2 25984 break;
b28425ba 25985 case DISAS_NORETURN:
5a5012ec 25986 break;
18f440ed
EC
25987 default:
25988 g_assert_not_reached();
6958549d 25989 }
6af0bf9c 25990 }
18f440ed
EC
25991}
25992
25993static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
25994{
25995 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
25996 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
25997}
25998
25999static const TranslatorOps mips_tr_ops = {
26000 .init_disas_context = mips_tr_init_disas_context,
26001 .tb_start = mips_tr_tb_start,
26002 .insn_start = mips_tr_insn_start,
26003 .breakpoint_check = mips_tr_breakpoint_check,
26004 .translate_insn = mips_tr_translate_insn,
26005 .tb_stop = mips_tr_tb_stop,
26006 .disas_log = mips_tr_disas_log,
26007};
26008
26009void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26010{
26011 DisasContext ctx;
26012
26013 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
26014}
26015
7db13fae 26016static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 26017 int flags)
6ea83fed
FB
26018{
26019 int i;
5e755519 26020 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 26021
2a5612e6
SW
26022#define printfpr(fp) \
26023 do { \
26024 if (is_fpu64) \
26025 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26026 " fd:%13g fs:%13g psu: %13g\n", \
26027 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26028 (double)(fp)->fd, \
26029 (double)(fp)->fs[FP_ENDIAN_IDX], \
26030 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26031 else { \
26032 fpr_t tmp; \
26033 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26034 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26035 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26036 " fd:%13g fs:%13g psu:%13g\n", \
26037 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26038 (double)tmp.fd, \
26039 (double)tmp.fs[FP_ENDIAN_IDX], \
26040 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26041 } \
6ea83fed
FB
26042 } while(0)
26043
5a5012ec 26044
9a78eead
SW
26045 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26046 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 26047 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
26048 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26049 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 26050 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
26051 }
26052
26053#undef printfpr
26054}
26055
878096ee
AF
26056void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26057 int flags)
6af0bf9c 26058{
878096ee
AF
26059 MIPSCPU *cpu = MIPS_CPU(cs);
26060 CPUMIPSState *env = &cpu->env;
6af0bf9c 26061 int i;
3b46e624 26062
a7200c9f
SW
26063 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26064 " LO=0x" TARGET_FMT_lx " ds %04x "
26065 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
26066 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26067 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
26068 for (i = 0; i < 32; i++) {
26069 if ((i & 3) == 0)
26070 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 26071 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
26072 if ((i & 3) == 3)
26073 cpu_fprintf(f, "\n");
26074 }
568b600d 26075
3594c774 26076 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 26077 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
26078 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26079 PRIx64 "\n",
5499b6ff 26080 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
26081 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
26082 env->CP0_Config2, env->CP0_Config3);
26083 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
26084 env->CP0_Config4, env->CP0_Config5);
1cc5af69 26085 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 26086 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 26087 }
6af0bf9c
FB
26088}
26089
78ce64f4 26090void mips_tcg_init(void)
39454628 26091{
f01be154 26092 int i;
39454628 26093
f764718d 26094 cpu_gpr[0] = NULL;
bb928dbe 26095 for (i = 1; i < 32; i++)
e1ccc054 26096 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 26097 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 26098 regnames[i]);
d73ee8a2 26099
863f264d
YK
26100 for (i = 0; i < 32; i++) {
26101 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26102 msa_wr_d[i * 2] =
e1ccc054 26103 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
26104 /* The scalar floating-point unit (FPU) registers are mapped on
26105 * the MSA vector registers. */
26106 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
26107 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26108 msa_wr_d[i * 2 + 1] =
e1ccc054 26109 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
26110 }
26111
e1ccc054 26112 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 26113 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 26114 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 26115 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 26116 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 26117 regnames_HI[i]);
e1ccc054 26118 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 26119 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 26120 regnames_LO[i]);
4b2eb8d2 26121 }
e1ccc054 26122 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 26123 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 26124 "DSPControl");
e1ccc054 26125 bcond = tcg_global_mem_new(cpu_env,
7db13fae 26126 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 26127 btarget = tcg_global_mem_new(cpu_env,
7db13fae 26128 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 26129 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 26130 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 26131
e1ccc054 26132 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 26133 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 26134 "fcr0");
e1ccc054 26135 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 26136 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 26137 "fcr31");
39454628
TS
26138}
26139
5b27a92d 26140#include "translate_init.inc.c"
aaed909a 26141
27e38392
PMD
26142void cpu_mips_realize_env(CPUMIPSState *env)
26143{
26144 env->exception_base = (int32_t)0xBFC00000;
26145
26146#ifndef CONFIG_USER_ONLY
26147 mmu_init(env, env->cpu_model);
26148#endif
26149 fpu_init(env, env->cpu_model);
26150 mvp_init(env, env->cpu_model);
26151}
26152
a7519f2b 26153bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 26154{
a7519f2b
IM
26155 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26156 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
26157}
26158
a7519f2b 26159bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 26160{
a7519f2b
IM
26161 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26162 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
26163}
26164
89777fd1
LA
26165void cpu_set_exception_base(int vp_index, target_ulong address)
26166{
26167 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26168 vp->env.exception_base = address;
26169}
26170
1bba0dc9 26171void cpu_state_reset(CPUMIPSState *env)
6ae81775 26172{
55e5c285
AF
26173 MIPSCPU *cpu = mips_env_get_cpu(env);
26174 CPUState *cs = CPU(cpu);
6ae81775 26175
51cc2e78
BS
26176 /* Reset registers to their default values */
26177 env->CP0_PRid = env->cpu_model->CP0_PRid;
26178 env->CP0_Config0 = env->cpu_model->CP0_Config0;
26179#ifdef TARGET_WORDS_BIGENDIAN
26180 env->CP0_Config0 |= (1 << CP0C0_BE);
26181#endif
26182 env->CP0_Config1 = env->cpu_model->CP0_Config1;
26183 env->CP0_Config2 = env->cpu_model->CP0_Config2;
26184 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
26185 env->CP0_Config4 = env->cpu_model->CP0_Config4;
26186 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
26187 env->CP0_Config5 = env->cpu_model->CP0_Config5;
26188 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
26189 env->CP0_Config6 = env->cpu_model->CP0_Config6;
26190 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
26191 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26192 << env->cpu_model->CP0_LLAddr_shift;
26193 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
26194 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26195 env->CCRes = env->cpu_model->CCRes;
26196 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26197 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26198 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26199 env->current_tc = 0;
26200 env->SEGBITS = env->cpu_model->SEGBITS;
26201 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26202#if defined(TARGET_MIPS64)
26203 if (env->cpu_model->insn_flags & ISA_MIPS3) {
26204 env->SEGMask |= 3ULL << 62;
26205 }
26206#endif
26207 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
26208 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26209 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26210 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26211 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26212 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26213 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26214 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26215 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26216 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26217 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
26218 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26219 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 26220 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 26221 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 26222 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 26223 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 26224 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
26225 env->insn_flags = env->cpu_model->insn_flags;
26226
0eaef5aa 26227#if defined(CONFIG_USER_ONLY)
03e6e501 26228 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
26229# ifdef TARGET_MIPS64
26230 /* Enable 64-bit register mode. */
26231 env->CP0_Status |= (1 << CP0St_PX);
26232# endif
26233# ifdef TARGET_ABI_MIPSN64
26234 /* Enable 64-bit address mode. */
26235 env->CP0_Status |= (1 << CP0St_UX);
26236# endif
94159135
MI
26237 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26238 hardware registers. */
26239 env->CP0_HWREna |= 0x0000000F;
91a75935 26240 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 26241 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 26242 }
6f0af304
PJ
26243 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26244 env->CP0_Status |= (1 << CP0St_MX);
853c3240 26245 }
4d66261f
PJ
26246# if defined(TARGET_MIPS64)
26247 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26248 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26249 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
26250 env->CP0_Status |= (1 << CP0St_FR);
26251 }
4d66261f 26252# endif
932e71cd
AJ
26253#else
26254 if (env->hflags & MIPS_HFLAG_BMASK) {
26255 /* If the exception was raised from a delay slot,
26256 come back to the jump. */
c3577479
MR
26257 env->CP0_ErrorEPC = (env->active_tc.PC
26258 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 26259 } else {
932e71cd
AJ
26260 env->CP0_ErrorEPC = env->active_tc.PC;
26261 }
89777fd1 26262 env->active_tc.PC = env->exception_base;
51cc2e78
BS
26263 env->CP0_Random = env->tlb->nb_tlb - 1;
26264 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 26265 env->CP0_Wired = 0;
01bc435b 26266 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 26267 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 26268 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
26269 env->CP0_EBase |= 0x40000000;
26270 } else {
74dbf824 26271 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 26272 }
c870e3f5
YK
26273 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26274 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26275 }
a0c80608
PB
26276 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26277 0x3ff : 0xff;
932e71cd
AJ
26278 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26279 /* vectored interrupts not implemented, timer on int 7,
26280 no performance counters. */
26281 env->CP0_IntCtl = 0xe0000000;
26282 {
26283 int i;
26284
26285 for (i = 0; i < 7; i++) {
26286 env->CP0_WatchLo[i] = 0;
26287 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 26288 }
932e71cd
AJ
26289 env->CP0_WatchLo[7] = 0;
26290 env->CP0_WatchHi[7] = 0;
fd88b6ab 26291 }
932e71cd
AJ
26292 /* Count register increments in debug mode, EJTAG version 1 */
26293 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 26294
4b69c7e2
JH
26295 cpu_mips_store_count(env, 1);
26296
9e56e756
EI
26297 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26298 int i;
26299
26300 /* Only TC0 on VPE 0 starts as active. */
26301 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 26302 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
26303 env->tcs[i].CP0_TCHalt = 1;
26304 }
26305 env->active_tc.CP0_TCHalt = 1;
259186a7 26306 cs->halted = 1;
9e56e756 26307
55e5c285 26308 if (cs->cpu_index == 0) {
9e56e756
EI
26309 /* VPE0 starts up enabled. */
26310 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26311 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26312
26313 /* TC0 starts up unhalted. */
259186a7 26314 cs->halted = 0;
9e56e756
EI
26315 env->active_tc.CP0_TCHalt = 0;
26316 env->tcs[0].CP0_TCHalt = 0;
26317 /* With thread 0 active. */
26318 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26319 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26320 }
26321 }
cec56a73
JH
26322
26323 /*
26324 * Configure default legacy segmentation control. We use this regardless of
26325 * whether segmentation control is presented to the guest.
26326 */
26327 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26328 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
26329 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26330 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26331 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26332 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26333 (2 << CP0SC_C);
26334 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26335 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26336 (3 << CP0SC_C)) << 16;
26337 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26338 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26339 (1 << CP0SC_EU) | (2 << CP0SC_C);
26340 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26341 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26342 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26343 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26344 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 26345#endif
ddc584bd
LA
26346 if ((env->insn_flags & ISA_MIPS32R6) &&
26347 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26348 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26349 env->CP0_Status |= (1 << CP0St_FR);
26350 }
26351
0bbc0396
SM
26352 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26353 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
26354 env->hflags |= MIPS_HFLAG_M16;
26355 }
26356
863f264d
YK
26357 /* MSA */
26358 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26359 msa_reset(env);
26360 }
26361
03e6e501 26362 compute_hflags(env);
599bc5e8 26363 restore_fp_status(env);
e117f526 26364 restore_pamask(env);
27103424 26365 cs->exception_index = EXCP_NONE;
3b3c1694
LA
26366
26367 if (semihosting_get_argc()) {
26368 /* UHI interface can be used to obtain argc and argv */
26369 env->active_tc.gpr[4] = -1;
26370 }
6af0bf9c 26371}
d2856f1a 26372
bad729e2
RH
26373void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26374 target_ulong *data)
d2856f1a 26375{
bad729e2 26376 env->active_tc.PC = data[0];
d2856f1a 26377 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 26378 env->hflags |= data[1];
4636401d
AJ
26379 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26380 case MIPS_HFLAG_BR:
26381 break;
26382 case MIPS_HFLAG_BC:
26383 case MIPS_HFLAG_BL:
26384 case MIPS_HFLAG_B:
bad729e2 26385 env->btarget = data[2];
4636401d
AJ
26386 break;
26387 }
d2856f1a 26388}