]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
qcow2: Inform block layer about discard boundaries
[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"
76cad711 26#include "disas/disas.h"
63c91552 27#include "exec/exec-all.h"
57fec1fe 28#include "tcg-op.h"
f08b6170 29#include "exec/cpu_ldst.h"
6af0bf9c 30
2ef6175a
RH
31#include "exec/helper-proto.h"
32#include "exec/helper-gen.h"
0a2672b7 33#include "sysemu/kvm.h"
3b3c1694 34#include "exec/semihost.h"
a7812ae4 35
a7e30d84 36#include "trace-tcg.h"
508127e2 37#include "exec/log.h"
a7e30d84 38
fb7729e2 39#define MIPS_DEBUG_DISAS 0
6af0bf9c 40
7a387fff
TS
41/* MIPS major opcodes */
42#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
43
44enum {
45 /* indirect opcode tables */
7a387fff
TS
46 OPC_SPECIAL = (0x00 << 26),
47 OPC_REGIMM = (0x01 << 26),
48 OPC_CP0 = (0x10 << 26),
49 OPC_CP1 = (0x11 << 26),
50 OPC_CP2 = (0x12 << 26),
51 OPC_CP3 = (0x13 << 26),
52 OPC_SPECIAL2 = (0x1C << 26),
53 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 54 /* arithmetic with immediate */
7a387fff
TS
55 OPC_ADDI = (0x08 << 26),
56 OPC_ADDIU = (0x09 << 26),
57 OPC_SLTI = (0x0A << 26),
58 OPC_SLTIU = (0x0B << 26),
324d9e32 59 /* logic with immediate */
7a387fff
TS
60 OPC_ANDI = (0x0C << 26),
61 OPC_ORI = (0x0D << 26),
62 OPC_XORI = (0x0E << 26),
63 OPC_LUI = (0x0F << 26),
324d9e32 64 /* arithmetic with immediate */
7a387fff
TS
65 OPC_DADDI = (0x18 << 26),
66 OPC_DADDIU = (0x19 << 26),
e37e863f 67 /* Jump and branches */
7a387fff
TS
68 OPC_J = (0x02 << 26),
69 OPC_JAL = (0x03 << 26),
70 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71 OPC_BEQL = (0x14 << 26),
72 OPC_BNE = (0x05 << 26),
73 OPC_BNEL = (0x15 << 26),
74 OPC_BLEZ = (0x06 << 26),
75 OPC_BLEZL = (0x16 << 26),
76 OPC_BGTZ = (0x07 << 26),
77 OPC_BGTZL = (0x17 << 26),
b231c103 78 OPC_JALX = (0x1D << 26),
d4ea6acd 79 OPC_DAUI = (0x1D << 26),
e37e863f 80 /* Load and stores */
7a387fff
TS
81 OPC_LDL = (0x1A << 26),
82 OPC_LDR = (0x1B << 26),
83 OPC_LB = (0x20 << 26),
84 OPC_LH = (0x21 << 26),
85 OPC_LWL = (0x22 << 26),
86 OPC_LW = (0x23 << 26),
364d4831 87 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
88 OPC_LBU = (0x24 << 26),
89 OPC_LHU = (0x25 << 26),
90 OPC_LWR = (0x26 << 26),
91 OPC_LWU = (0x27 << 26),
92 OPC_SB = (0x28 << 26),
93 OPC_SH = (0x29 << 26),
94 OPC_SWL = (0x2A << 26),
95 OPC_SW = (0x2B << 26),
96 OPC_SDL = (0x2C << 26),
97 OPC_SDR = (0x2D << 26),
98 OPC_SWR = (0x2E << 26),
99 OPC_LL = (0x30 << 26),
100 OPC_LLD = (0x34 << 26),
101 OPC_LD = (0x37 << 26),
364d4831 102 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
103 OPC_SC = (0x38 << 26),
104 OPC_SCD = (0x3C << 26),
105 OPC_SD = (0x3F << 26),
e37e863f 106 /* Floating point load/store */
7a387fff
TS
107 OPC_LWC1 = (0x31 << 26),
108 OPC_LWC2 = (0x32 << 26),
109 OPC_LDC1 = (0x35 << 26),
110 OPC_LDC2 = (0x36 << 26),
111 OPC_SWC1 = (0x39 << 26),
112 OPC_SWC2 = (0x3A << 26),
113 OPC_SDC1 = (0x3D << 26),
114 OPC_SDC2 = (0x3E << 26),
31837be3
YK
115 /* Compact Branches */
116 OPC_BLEZALC = (0x06 << 26),
117 OPC_BGEZALC = (0x06 << 26),
118 OPC_BGEUC = (0x06 << 26),
119 OPC_BGTZALC = (0x07 << 26),
120 OPC_BLTZALC = (0x07 << 26),
121 OPC_BLTUC = (0x07 << 26),
122 OPC_BOVC = (0x08 << 26),
123 OPC_BEQZALC = (0x08 << 26),
124 OPC_BEQC = (0x08 << 26),
125 OPC_BLEZC = (0x16 << 26),
126 OPC_BGEZC = (0x16 << 26),
127 OPC_BGEC = (0x16 << 26),
128 OPC_BGTZC = (0x17 << 26),
129 OPC_BLTZC = (0x17 << 26),
130 OPC_BLTC = (0x17 << 26),
131 OPC_BNVC = (0x18 << 26),
132 OPC_BNEZALC = (0x18 << 26),
133 OPC_BNEC = (0x18 << 26),
134 OPC_BC = (0x32 << 26),
135 OPC_BEQZC = (0x36 << 26),
136 OPC_JIC = (0x36 << 26),
137 OPC_BALC = (0x3A << 26),
138 OPC_BNEZC = (0x3E << 26),
139 OPC_JIALC = (0x3E << 26),
7a387fff
TS
140 /* MDMX ASE specific */
141 OPC_MDMX = (0x1E << 26),
239dfebe
YK
142 /* MSA ASE, same as MDMX */
143 OPC_MSA = OPC_MDMX,
e37e863f 144 /* Cache and prefetch */
7a387fff
TS
145 OPC_CACHE = (0x2F << 26),
146 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
147 /* PC-relative address computation / loads */
148 OPC_PCREL = (0x3B << 26),
149};
150
151/* PC-relative address computation / loads */
152#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
153#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
154enum {
155 /* Instructions determined by bits 19 and 20 */
156 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
157 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
158 OPC_LWUPC = OPC_PCREL | (2 << 19),
159
160 /* Instructions determined by bits 16 ... 20 */
161 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
162 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
163
164 /* Other */
165 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
166};
167
168/* MIPS special opcodes */
7a387fff
TS
169#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
170
e37e863f
FB
171enum {
172 /* Shifts */
7a387fff 173 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
174 /* NOP is SLL r0, r0, 0 */
175 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
176 /* EHB is SLL r0, r0, 3 */
177 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 178 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
179 OPC_SRA = 0x03 | OPC_SPECIAL,
180 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 181 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 182 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
183 OPC_SRAV = 0x07 | OPC_SPECIAL,
184 OPC_DSLLV = 0x14 | OPC_SPECIAL,
185 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 186 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
187 OPC_DSRAV = 0x17 | OPC_SPECIAL,
188 OPC_DSLL = 0x38 | OPC_SPECIAL,
189 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 190 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
191 OPC_DSRA = 0x3B | OPC_SPECIAL,
192 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
193 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 194 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 195 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 196 /* Multiplication / division */
7a387fff
TS
197 OPC_MULT = 0x18 | OPC_SPECIAL,
198 OPC_MULTU = 0x19 | OPC_SPECIAL,
199 OPC_DIV = 0x1A | OPC_SPECIAL,
200 OPC_DIVU = 0x1B | OPC_SPECIAL,
201 OPC_DMULT = 0x1C | OPC_SPECIAL,
202 OPC_DMULTU = 0x1D | OPC_SPECIAL,
203 OPC_DDIV = 0x1E | OPC_SPECIAL,
204 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 205
e37e863f 206 /* 2 registers arithmetic / logic */
7a387fff
TS
207 OPC_ADD = 0x20 | OPC_SPECIAL,
208 OPC_ADDU = 0x21 | OPC_SPECIAL,
209 OPC_SUB = 0x22 | OPC_SPECIAL,
210 OPC_SUBU = 0x23 | OPC_SPECIAL,
211 OPC_AND = 0x24 | OPC_SPECIAL,
212 OPC_OR = 0x25 | OPC_SPECIAL,
213 OPC_XOR = 0x26 | OPC_SPECIAL,
214 OPC_NOR = 0x27 | OPC_SPECIAL,
215 OPC_SLT = 0x2A | OPC_SPECIAL,
216 OPC_SLTU = 0x2B | OPC_SPECIAL,
217 OPC_DADD = 0x2C | OPC_SPECIAL,
218 OPC_DADDU = 0x2D | OPC_SPECIAL,
219 OPC_DSUB = 0x2E | OPC_SPECIAL,
220 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 221 /* Jumps */
7a387fff
TS
222 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
223 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 224 /* Traps */
7a387fff
TS
225 OPC_TGE = 0x30 | OPC_SPECIAL,
226 OPC_TGEU = 0x31 | OPC_SPECIAL,
227 OPC_TLT = 0x32 | OPC_SPECIAL,
228 OPC_TLTU = 0x33 | OPC_SPECIAL,
229 OPC_TEQ = 0x34 | OPC_SPECIAL,
230 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 231 /* HI / LO registers load & stores */
7a387fff
TS
232 OPC_MFHI = 0x10 | OPC_SPECIAL,
233 OPC_MTHI = 0x11 | OPC_SPECIAL,
234 OPC_MFLO = 0x12 | OPC_SPECIAL,
235 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 236 /* Conditional moves */
7a387fff
TS
237 OPC_MOVZ = 0x0A | OPC_SPECIAL,
238 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 239
b691d9d2
LA
240 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
241 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
242
7a387fff 243 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
244
245 /* Special */
a0d700e4 246 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
247 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
248 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 249 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYNC = 0x0F | OPC_SPECIAL,
251
7a387fff
TS
252 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
253 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
254 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
255 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
256};
257
b42ee5e1
LA
258/* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261
262enum {
263 R6_OPC_MUL = OPC_MULT | (2 << 6),
264 R6_OPC_MUH = OPC_MULT | (3 << 6),
265 R6_OPC_MULU = OPC_MULTU | (2 << 6),
266 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
267 R6_OPC_DIV = OPC_DIV | (2 << 6),
268 R6_OPC_MOD = OPC_DIV | (3 << 6),
269 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
270 R6_OPC_MODU = OPC_DIVU | (3 << 6),
271
272 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
273 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
274 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
275 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
276 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
277 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
278 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
279 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
280
281 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
282 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
283 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
284 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
285 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
286
287 OPC_LSA = 0x05 | OPC_SPECIAL,
288 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
289};
290
e9c71dd1
TS
291/* Multiplication variants of the vr54xx. */
292#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293
294enum {
295 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
296 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
297 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
298 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
299 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
300 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
302 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
303 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
304 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
305 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
306 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
307 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
308 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
309};
310
7a387fff
TS
311/* REGIMM (rt field) opcodes */
312#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313
314enum {
315 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
316 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
317 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
318 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
319 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
320 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
321 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
322 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
323 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
324 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
325 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
326 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
327 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
328 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 329 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 330 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
331
332 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
333 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
334};
335
7a387fff
TS
336/* Special2 opcodes */
337#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
338
e37e863f 339enum {
7a387fff
TS
340 /* Multiply & xxx operations */
341 OPC_MADD = 0x00 | OPC_SPECIAL2,
342 OPC_MADDU = 0x01 | OPC_SPECIAL2,
343 OPC_MUL = 0x02 | OPC_SPECIAL2,
344 OPC_MSUB = 0x04 | OPC_SPECIAL2,
345 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
346 /* Loongson 2F */
347 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
348 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
349 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
350 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
351 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
352 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
353 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
354 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
355 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
356 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
357 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
358 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 359 /* Misc */
7a387fff
TS
360 OPC_CLZ = 0x20 | OPC_SPECIAL2,
361 OPC_CLO = 0x21 | OPC_SPECIAL2,
362 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
363 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 364 /* Special */
7a387fff
TS
365 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
366};
367
368/* Special3 opcodes */
369#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
370
371enum {
372 OPC_EXT = 0x00 | OPC_SPECIAL3,
373 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
374 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
375 OPC_DEXT = 0x03 | OPC_SPECIAL3,
376 OPC_INS = 0x04 | OPC_SPECIAL3,
377 OPC_DINSM = 0x05 | OPC_SPECIAL3,
378 OPC_DINSU = 0x06 | OPC_SPECIAL3,
379 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
380 OPC_FORK = 0x08 | OPC_SPECIAL3,
381 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
382 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
383 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
384 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
385
386 /* Loongson 2E */
387 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
388 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
389 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
390 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
391 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
392 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
393 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
394 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
395 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
396 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
397 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
398 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
399
400 /* MIPS DSP Load */
401 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
402 /* MIPS DSP Arithmetic */
403 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 404 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 405 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 406 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
407 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
408 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
409 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 410 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
411 /* MIPS DSP GPR-Based Shift Sub-class */
412 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 413 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
414 /* MIPS DSP Multiply Sub-class insns */
415 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
416 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
417 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 418 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
419 /* DSP Bit/Manipulation Sub-class */
420 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 421 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 422 /* MIPS DSP Append Sub-class */
26690560 423 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 424 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
425 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
426 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 427 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
428
429 /* R6 */
bf7910c6
LA
430 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
431 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
432 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
433 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
434 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
435 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
436};
437
7a387fff
TS
438/* BSHFL opcodes */
439#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
440
e37e863f 441enum {
15eacb9b
YK
442 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
443 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
444 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
445 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
446 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
447 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
448};
449
7a387fff
TS
450/* DBSHFL opcodes */
451#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
452
e37e863f 453enum {
15eacb9b
YK
454 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
455 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
456 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
457 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
458 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
459};
460
e45a93e2
JL
461/* MIPS DSP REGIMM opcodes */
462enum {
463 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 464 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
465};
466
9b1a1d68
JL
467#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
468/* MIPS DSP Load */
469enum {
470 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
471 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
472 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 473 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
474};
475
461c08df
JL
476#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
477enum {
478 /* MIPS DSP Arithmetic Sub-class */
479 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
485 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
492 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
494 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
496 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
497 /* MIPS DSP Multiply Sub-class insns */
498 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
503 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
504};
505
506#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
507#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
508enum {
509 /* MIPS DSP Arithmetic Sub-class */
510 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
521 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
522 /* MIPS DSP Multiply Sub-class insns */
523 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
526 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
527};
528
529#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
530enum {
531 /* MIPS DSP Arithmetic Sub-class */
532 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
545 /* DSP Bit/Manipulation Sub-class */
546 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
550 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
551};
552
553#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554enum {
555 /* MIPS DSP Arithmetic Sub-class */
556 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
563 /* DSP Compare-Pick Sub-class */
564 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 579};
a22260ae 580
77c5fa8b
JL
581#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
582enum {
583 /* MIPS DSP GPR-Based Shift Sub-class */
584 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
606};
461c08df 607
a22260ae
JL
608#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609enum {
610 /* MIPS DSP Multiply Sub-class insns */
611 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
627 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
633};
634
1cb6686c
JL
635#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636enum {
637 /* DSP Bit/Manipulation Sub-class */
638 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
639};
640
26690560
JL
641#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
642enum {
df6126a7 643 /* MIPS DSP Append Sub-class */
26690560
JL
644 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
645 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
646 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
647};
648
b53371ed
JL
649#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
650enum {
651 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
652 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
663 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
665 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
666 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
667 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
668 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
669};
670
461c08df
JL
671#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672enum {
673 /* MIPS DSP Arithmetic Sub-class */
674 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
691 /* DSP Bit/Manipulation Sub-class */
692 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 698};
461c08df 699
461c08df
JL
700#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701enum {
a22260ae
JL
702 /* MIPS DSP Multiply Sub-class insns */
703 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
707 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
708 /* MIPS DSP Arithmetic Sub-class */
709 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
719 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
729 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
730};
461c08df 731
461c08df
JL
732#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
733enum {
26690560
JL
734 /* DSP Compare-Pick Sub-class */
735 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
754 /* MIPS DSP Arithmetic Sub-class */
755 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
763};
461c08df 764
26690560
JL
765#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
766enum {
df6126a7 767 /* DSP Append Sub-class */
26690560
JL
768 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
770 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
771 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
772};
26690560 773
b53371ed
JL
774#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
775enum {
776 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
777 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
778 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
797 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
798};
799
1cb6686c
JL
800#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
801enum {
802 /* DSP Bit/Manipulation Sub-class */
803 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
804};
1cb6686c 805
a22260ae
JL
806#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
807enum {
808 /* MIPS DSP Multiply Sub-class insns */
809 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
835};
a22260ae 836
77c5fa8b
JL
837#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
838enum {
839 /* MIPS DSP GPR-Based Shift Sub-class */
840 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
866};
77c5fa8b 867
7a387fff
TS
868/* Coprocessor 0 (rs field) */
869#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
870
6ea83fed 871enum {
7a387fff
TS
872 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
873 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 874 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
875 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
876 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 877 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 878 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
879 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
880 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 881 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
882 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
883 OPC_C0 = (0x10 << 21) | OPC_CP0,
884 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
885 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 886};
7a387fff
TS
887
888/* MFMC0 opcodes */
b48cfdff 889#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
890
891enum {
ead9360e
TS
892 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
894 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
895 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
896 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
897 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
898 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
899 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
900};
901
902/* Coprocessor 0 (with rs == C0) */
903#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
904
905enum {
906 OPC_TLBR = 0x01 | OPC_C0,
907 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
908 OPC_TLBINV = 0x03 | OPC_C0,
909 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
910 OPC_TLBWR = 0x06 | OPC_C0,
911 OPC_TLBP = 0x08 | OPC_C0,
912 OPC_RFE = 0x10 | OPC_C0,
913 OPC_ERET = 0x18 | OPC_C0,
914 OPC_DERET = 0x1F | OPC_C0,
915 OPC_WAIT = 0x20 | OPC_C0,
916};
917
918/* Coprocessor 1 (rs field) */
919#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
920
bf4120ad
NF
921/* Values for the fmt field in FP instructions */
922enum {
923 /* 0 - 15 are reserved */
e459440a
AJ
924 FMT_S = 16, /* single fp */
925 FMT_D = 17, /* double fp */
926 FMT_E = 18, /* extended fp */
927 FMT_Q = 19, /* quad fp */
928 FMT_W = 20, /* 32-bit fixed */
929 FMT_L = 21, /* 64-bit fixed */
930 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
931 /* 23 - 31 are reserved */
932};
933
7a387fff
TS
934enum {
935 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
936 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
937 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 938 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
939 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
940 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
941 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 942 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 943 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
944 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
945 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
946 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
947 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
948 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
949 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
950 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
951 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
952 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
953 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
954 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
955 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
956 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
957 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
958 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
959 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
960 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
961 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
962 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
963 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
964 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
965};
966
5a5012ec
TS
967#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
968#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
969
7a387fff
TS
970enum {
971 OPC_BC1F = (0x00 << 16) | OPC_BC1,
972 OPC_BC1T = (0x01 << 16) | OPC_BC1,
973 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
974 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
975};
976
5a5012ec
TS
977enum {
978 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
979 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
980};
981
982enum {
983 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
984 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
985};
7a387fff
TS
986
987#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
988
989enum {
990 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
991 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
992 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
993 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
994 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
995 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
996 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
997 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
998 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
999 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1000 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1001};
1002
bd277fa1
RH
1003#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1004
1005enum {
1006 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1013 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1014
1015 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1022 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1023
1024 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1027 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1028 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1029 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1030 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1031 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1032
1033 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1036 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1040 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1041
1042 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1043 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1047 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1048
1049 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1054 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1055
1056 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1061 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1062
1063 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1068 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1069
1070 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1071 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1072 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1073 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1075 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1076
1077 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1078 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1079 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1080 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1082 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1083
1084 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1085 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1087 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1089 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1090
1091 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1092 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1093 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1094 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1095 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1096 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1097};
1098
1099
e0c84da7
TS
1100#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1101
1102enum {
1103 OPC_LWXC1 = 0x00 | OPC_CP3,
1104 OPC_LDXC1 = 0x01 | OPC_CP3,
1105 OPC_LUXC1 = 0x05 | OPC_CP3,
1106 OPC_SWXC1 = 0x08 | OPC_CP3,
1107 OPC_SDXC1 = 0x09 | OPC_CP3,
1108 OPC_SUXC1 = 0x0D | OPC_CP3,
1109 OPC_PREFX = 0x0F | OPC_CP3,
1110 OPC_ALNV_PS = 0x1E | OPC_CP3,
1111 OPC_MADD_S = 0x20 | OPC_CP3,
1112 OPC_MADD_D = 0x21 | OPC_CP3,
1113 OPC_MADD_PS = 0x26 | OPC_CP3,
1114 OPC_MSUB_S = 0x28 | OPC_CP3,
1115 OPC_MSUB_D = 0x29 | OPC_CP3,
1116 OPC_MSUB_PS = 0x2E | OPC_CP3,
1117 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1118 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1119 OPC_NMADD_PS= 0x36 | OPC_CP3,
1120 OPC_NMSUB_S = 0x38 | OPC_CP3,
1121 OPC_NMSUB_D = 0x39 | OPC_CP3,
1122 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1123};
1124
239dfebe
YK
1125/* MSA Opcodes */
1126#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1127enum {
1128 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1129 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1130 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1131 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1132 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1133 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1134 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1135 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1136 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1137 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1138 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1139 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1140 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1141 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1142 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1143 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1144 OPC_MSA_ELM = 0x19 | OPC_MSA,
1145 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1146 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1147 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1148 OPC_MSA_VEC = 0x1E | OPC_MSA,
1149
1150 /* MI10 instruction */
1151 OPC_LD_B = (0x20) | OPC_MSA,
1152 OPC_LD_H = (0x21) | OPC_MSA,
1153 OPC_LD_W = (0x22) | OPC_MSA,
1154 OPC_LD_D = (0x23) | OPC_MSA,
1155 OPC_ST_B = (0x24) | OPC_MSA,
1156 OPC_ST_H = (0x25) | OPC_MSA,
1157 OPC_ST_W = (0x26) | OPC_MSA,
1158 OPC_ST_D = (0x27) | OPC_MSA,
1159};
1160
1161enum {
1162 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1163 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1164 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1165 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1166 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1167 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1168 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1169 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1170 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1171 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1172 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1173 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1174 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1175
1176 /* I8 instruction */
1177 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1178 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1179 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1180 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1181 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1182 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1183 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1184 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1185 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1186 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1187
1188 /* VEC/2R/2RF instruction */
1189 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1190 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1191 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1192 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1193 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1194 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1195 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1196
1197 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1198 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1199
1200 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1201 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1202 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1203 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1204 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1205
1206 /* 2RF instruction df(bit 16) = _w, _d */
1207 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1209 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1210 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1211 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1212 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1213 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1214 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1216 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1217 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1218 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1220 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1222 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1223
1224 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1225 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1226 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1227 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1228 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1229 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1230 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1231 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1232 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1233 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1234 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1235 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1236 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1237 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1238 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1239 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1240 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1241 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1242 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1243 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1244 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1245 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1246 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1247 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1248 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1249 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1250 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1251 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1252 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1254 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1255 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1256 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1257 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1258 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1259 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1260 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1261 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1262 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1263 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1264 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1265 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1266 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1267 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1268 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1269 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1270 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1271 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1272 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1273 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1274 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1275 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1276 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1278 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1279 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1280 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1281 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1282 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1283 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1284 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1285 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1286 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1287 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1288
1289 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1290 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1292 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1294 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1295 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1296 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1299
1300 /* 3RF instruction _df(bit 21) = _w, _d */
1301 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1302 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1303 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1304 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1305 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1306 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1307 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1308 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1309 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1310 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1311 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1312 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1313 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1314 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1315 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1317 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1318 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1319 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1320 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1321 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1322 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1323 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1324 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1325 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1326 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1327 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1328 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1329 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1330 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1331 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1333 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1334 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1336 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1337 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1338 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1339 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1340 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1342
1343 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1344 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1345 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1346 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1347 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1348 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1349 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1350 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1351 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1352 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1353 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1355 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1356};
1357
39454628 1358/* global register indices */
1bcea73e 1359static TCGv_env cpu_env;
a7812ae4 1360static TCGv cpu_gpr[32], cpu_PC;
340fff72 1361static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1362static TCGv cpu_dspctrl, btarget, bcond;
1363static TCGv_i32 hflags;
a7812ae4 1364static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1365static TCGv_i64 fpu_f64[32];
863f264d 1366static TCGv_i64 msa_wr_d[64];
aa0bf00b 1367
022c62cb 1368#include "exec/gen-icount.h"
2e70f6ef 1369
895c2d04 1370#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1371 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1372 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1373 tcg_temp_free_i32(helper_tmp); \
1374 } while(0)
be24bb4f 1375
895c2d04 1376#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1377 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1378 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1379 tcg_temp_free_i32(helper_tmp); \
1380 } while(0)
be24bb4f 1381
895c2d04
BS
1382#define gen_helper_1e0i(name, ret, arg1) do { \
1383 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1384 gen_helper_##name(ret, cpu_env, helper_tmp); \
1385 tcg_temp_free_i32(helper_tmp); \
1386 } while(0)
1387
1388#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1389 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1390 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1391 tcg_temp_free_i32(helper_tmp); \
1392 } while(0)
1393
1394#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1395 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1396 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1397 tcg_temp_free_i32(helper_tmp); \
1398 } while(0)
1399
1400#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1401 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1402 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1403 tcg_temp_free_i32(helper_tmp); \
1404 } while(0)
be24bb4f 1405
895c2d04 1406#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1407 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1408 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1409 tcg_temp_free_i32(helper_tmp); \
1410 } while(0)
c239529e 1411
8e9ade68
TS
1412typedef struct DisasContext {
1413 struct TranslationBlock *tb;
1414 target_ulong pc, saved_pc;
1415 uint32_t opcode;
7b270ef2 1416 int singlestep_enabled;
d75c135e 1417 int insn_flags;
5ab5c041 1418 int32_t CP0_Config1;
8e9ade68
TS
1419 /* Routine used to access memory */
1420 int mem_idx;
be3a8c53 1421 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1422 uint32_t hflags, saved_hflags;
1423 int bstate;
1424 target_ulong btarget;
d279279e 1425 bool ulri;
e98c0d17 1426 int kscrexist;
7207c7f9 1427 bool rxi;
9456c2fb 1428 int ie;
aea14095
LA
1429 bool bi;
1430 bool bp;
5204ea79
LA
1431 uint64_t PAMask;
1432 bool mvh;
1433 int CP0_LLAddr_shift;
e29c9628 1434 bool ps;
01bc435b 1435 bool vp;
c870e3f5 1436 bool cmgcr;
f6d4dd81 1437 bool mrp;
87552089 1438 bool nan2008;
6be77480 1439 bool abs2008;
8e9ade68
TS
1440} DisasContext;
1441
1442enum {
1443 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1444 * exception condition */
8e9ade68
TS
1445 BS_STOP = 1, /* We want to stop translation for any reason */
1446 BS_BRANCH = 2, /* We reached a branch condition */
1447 BS_EXCP = 3, /* We reached an exception condition */
1448};
1449
d73ee8a2
RH
1450static const char * const regnames[] = {
1451 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1452 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1453 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1454 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1455};
6af0bf9c 1456
d73ee8a2
RH
1457static const char * const regnames_HI[] = {
1458 "HI0", "HI1", "HI2", "HI3",
1459};
4b2eb8d2 1460
d73ee8a2
RH
1461static const char * const regnames_LO[] = {
1462 "LO0", "LO1", "LO2", "LO3",
1463};
4b2eb8d2 1464
d73ee8a2
RH
1465static const char * const fregnames[] = {
1466 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1467 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1468 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1469 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1470};
958fb4a9 1471
863f264d
YK
1472static const char * const msaregnames[] = {
1473 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1474 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1475 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1476 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1477 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1478 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1479 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1480 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1481 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1482 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1483 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1484 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1485 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1486 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1487 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1488 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1489};
1490
9d68ac14 1491#define LOG_DISAS(...) \
fb7729e2
RH
1492 do { \
1493 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1494 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1495 } \
1496 } while (0)
1497
9d68ac14 1498#define MIPS_INVAL(op) \
fb7729e2
RH
1499 do { \
1500 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1501 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1502 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1503 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1504 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1505 } \
1506 } while (0)
958fb4a9 1507
8e9ade68
TS
1508/* General purpose registers moves. */
1509static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1510{
8e9ade68
TS
1511 if (reg == 0)
1512 tcg_gen_movi_tl(t, 0);
1513 else
4b2eb8d2 1514 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1515}
1516
8e9ade68 1517static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1518{
8e9ade68 1519 if (reg != 0)
4b2eb8d2 1520 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1521}
1522
8e9ade68 1523/* Moves to/from shadow registers. */
be24bb4f 1524static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1525{
d9bea114 1526 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1527
1528 if (from == 0)
d9bea114 1529 tcg_gen_movi_tl(t0, 0);
8e9ade68 1530 else {
d9bea114 1531 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1532 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1533
7db13fae 1534 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1535 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1536 tcg_gen_andi_i32(t2, t2, 0xf);
1537 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1538 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1539 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1540
d9bea114 1541 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1542 tcg_temp_free_ptr(addr);
d9bea114 1543 tcg_temp_free_i32(t2);
8e9ade68 1544 }
d9bea114
AJ
1545 gen_store_gpr(t0, to);
1546 tcg_temp_free(t0);
aaa9128a
TS
1547}
1548
be24bb4f 1549static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1550{
be24bb4f 1551 if (to != 0) {
d9bea114
AJ
1552 TCGv t0 = tcg_temp_new();
1553 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1554 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1555
d9bea114 1556 gen_load_gpr(t0, from);
7db13fae 1557 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1558 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1559 tcg_gen_andi_i32(t2, t2, 0xf);
1560 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1561 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1562 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1563
d9bea114 1564 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1565 tcg_temp_free_ptr(addr);
d9bea114
AJ
1566 tcg_temp_free_i32(t2);
1567 tcg_temp_free(t0);
8e9ade68 1568 }
aaa9128a
TS
1569}
1570
eab9944c
LA
1571/* Tests */
1572static inline void gen_save_pc(target_ulong pc)
1573{
1574 tcg_gen_movi_tl(cpu_PC, pc);
1575}
1576
1577static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1578{
1579 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1580 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1581 gen_save_pc(ctx->pc);
1582 ctx->saved_pc = ctx->pc;
1583 }
1584 if (ctx->hflags != ctx->saved_hflags) {
1585 tcg_gen_movi_i32(hflags, ctx->hflags);
1586 ctx->saved_hflags = ctx->hflags;
1587 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1588 case MIPS_HFLAG_BR:
1589 break;
1590 case MIPS_HFLAG_BC:
1591 case MIPS_HFLAG_BL:
1592 case MIPS_HFLAG_B:
1593 tcg_gen_movi_tl(btarget, ctx->btarget);
1594 break;
1595 }
1596 }
1597}
1598
1599static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1600{
1601 ctx->saved_hflags = ctx->hflags;
1602 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1603 case MIPS_HFLAG_BR:
1604 break;
1605 case MIPS_HFLAG_BC:
1606 case MIPS_HFLAG_BL:
1607 case MIPS_HFLAG_B:
1608 ctx->btarget = env->btarget;
1609 break;
1610 }
1611}
1612
1613static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1614{
1615 TCGv_i32 texcp = tcg_const_i32(excp);
1616 TCGv_i32 terr = tcg_const_i32(err);
1617 save_cpu_state(ctx, 1);
1618 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1619 tcg_temp_free_i32(terr);
1620 tcg_temp_free_i32(texcp);
9c708c7f 1621 ctx->bstate = BS_EXCP;
eab9944c
LA
1622}
1623
1624static inline void generate_exception(DisasContext *ctx, int excp)
1625{
eab9944c
LA
1626 gen_helper_0e0i(raise_exception, excp);
1627}
1628
9c708c7f
PD
1629static inline void generate_exception_end(DisasContext *ctx, int excp)
1630{
1631 generate_exception_err(ctx, excp, 0);
1632}
1633
aaa9128a 1634/* Floating point register moves. */
7c979afd 1635static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1636{
7c979afd
LA
1637 if (ctx->hflags & MIPS_HFLAG_FRE) {
1638 generate_exception(ctx, EXCP_RI);
1639 }
ecc7b3aa 1640 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1641}
1642
7c979afd 1643static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1644{
7c979afd
LA
1645 TCGv_i64 t64;
1646 if (ctx->hflags & MIPS_HFLAG_FRE) {
1647 generate_exception(ctx, EXCP_RI);
1648 }
1649 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1650 tcg_gen_extu_i32_i64(t64, t);
1651 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1652 tcg_temp_free_i64(t64);
6d066274
AJ
1653}
1654
7f6613ce 1655static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1656{
7f6613ce 1657 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1658 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1659 } else {
7c979afd 1660 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1661 }
6d066274
AJ
1662}
1663
7f6613ce 1664static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1665{
7f6613ce
PJ
1666 if (ctx->hflags & MIPS_HFLAG_F64) {
1667 TCGv_i64 t64 = tcg_temp_new_i64();
1668 tcg_gen_extu_i32_i64(t64, t);
1669 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1670 tcg_temp_free_i64(t64);
1671 } else {
7c979afd 1672 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1673 }
aa0bf00b 1674}
6ea83fed 1675
d73ee8a2 1676static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1677{
f364515c 1678 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1679 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1680 } else {
d73ee8a2 1681 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1682 }
1683}
6ea83fed 1684
d73ee8a2 1685static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1686{
f364515c 1687 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1688 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1689 } else {
d73ee8a2
RH
1690 TCGv_i64 t0;
1691 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1692 t0 = tcg_temp_new_i64();
6d066274 1693 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1694 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1695 tcg_temp_free_i64(t0);
aa0bf00b
TS
1696 }
1697}
6ea83fed 1698
d94536f4 1699static inline int get_fp_bit (int cc)
a16336e4 1700{
d94536f4
AJ
1701 if (cc)
1702 return 24 + cc;
1703 else
1704 return 23;
a16336e4
TS
1705}
1706
48d38ca5 1707/* Addresses computation */
941694d0 1708static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1709{
941694d0 1710 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1711
1712#if defined(TARGET_MIPS64)
01f72885 1713 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1714 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1715 }
1716#endif
4ad40f36
FB
1717}
1718
31837be3
YK
1719/* Addresses computation (translation time) */
1720static target_long addr_add(DisasContext *ctx, target_long base,
1721 target_long offset)
1722{
1723 target_long sum = base + offset;
1724
1725#if defined(TARGET_MIPS64)
1726 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1727 sum = (int32_t)sum;
1728 }
1729#endif
1730 return sum;
1731}
1732
71f303cd 1733/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1734static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1735{
1736#if defined(TARGET_MIPS64)
71f303cd
RH
1737 tcg_gen_ext32s_i64(ret, arg);
1738#else
1739 tcg_gen_extrl_i64_i32(ret, arg);
1740#endif
1741}
1742
1743/* Sign-extract the high 32-bits to a target_long. */
1744static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1745{
1746#if defined(TARGET_MIPS64)
1747 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1748#else
71f303cd 1749 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1750#endif
1751}
1752
356265ae 1753static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1754{
fe253235 1755 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1756 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1757}
1758
356265ae 1759static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1760{
fe253235 1761 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1762 generate_exception_err(ctx, EXCP_CpU, 1);
1763}
1764
b8aa4598
TS
1765/* Verify that the processor is running with COP1X instructions enabled.
1766 This is associated with the nabla symbol in the MIPS32 and MIPS64
1767 opcode tables. */
1768
356265ae 1769static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1770{
1771 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1772 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1773}
1774
1775/* Verify that the processor is running with 64-bit floating-point
1776 operations enabled. */
1777
356265ae 1778static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1779{
b8aa4598 1780 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1781 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1782}
1783
1784/*
1785 * Verify if floating point register is valid; an operation is not defined
1786 * if bit 0 of any register specification is set and the FR bit in the
1787 * Status register equals zero, since the register numbers specify an
1788 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1789 * in the Status register equals one, both even and odd register numbers
1790 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1791 *
1792 * Multiple 64 bit wide registers can be checked by calling
1793 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1794 */
356265ae 1795static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1796{
fe253235 1797 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1798 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1799}
1800
853c3240
JL
1801/* Verify that the processor is running with DSP instructions enabled.
1802 This is enabled by CP0 Status register MX(24) bit.
1803 */
1804
1805static inline void check_dsp(DisasContext *ctx)
1806{
1807 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1808 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1809 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1810 } else {
9c708c7f 1811 generate_exception_end(ctx, EXCP_RI);
ad153f15 1812 }
853c3240
JL
1813 }
1814}
1815
1816static inline void check_dspr2(DisasContext *ctx)
1817{
1818 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1819 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1820 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1821 } else {
9c708c7f 1822 generate_exception_end(ctx, EXCP_RI);
ad153f15 1823 }
853c3240
JL
1824 }
1825}
1826
3a95e3a7 1827/* This code generates a "reserved instruction" exception if the
e189e748 1828 CPU does not support the instruction set corresponding to flags. */
d75c135e 1829static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1830{
d75c135e 1831 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1832 generate_exception_end(ctx, EXCP_RI);
d75c135e 1833 }
3a95e3a7
TS
1834}
1835
fecd2646
LA
1836/* This code generates a "reserved instruction" exception if the
1837 CPU has corresponding flag set which indicates that the instruction
1838 has been removed. */
1839static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1840{
1841 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1842 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1843 }
1844}
1845
e29c9628
YK
1846/* This code generates a "reserved instruction" exception if the
1847 CPU does not support 64-bit paired-single (PS) floating point data type */
1848static inline void check_ps(DisasContext *ctx)
1849{
1850 if (unlikely(!ctx->ps)) {
1851 generate_exception(ctx, EXCP_RI);
1852 }
1853 check_cp1_64bitmode(ctx);
1854}
1855
c7986fd6 1856#ifdef TARGET_MIPS64
e189e748
TS
1857/* This code generates a "reserved instruction" exception if 64-bit
1858 instructions are not enabled. */
356265ae 1859static inline void check_mips_64(DisasContext *ctx)
e189e748 1860{
fe253235 1861 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1862 generate_exception_end(ctx, EXCP_RI);
e189e748 1863}
c7986fd6 1864#endif
e189e748 1865
5204ea79
LA
1866#ifndef CONFIG_USER_ONLY
1867static inline void check_mvh(DisasContext *ctx)
1868{
1869 if (unlikely(!ctx->mvh)) {
1870 generate_exception(ctx, EXCP_RI);
1871 }
1872}
1873#endif
1874
8153667c
NF
1875/* Define small wrappers for gen_load_fpr* so that we have a uniform
1876 calling interface for 32 and 64-bit FPRs. No sense in changing
1877 all callers for gen_load_fpr32 when we need the CTX parameter for
1878 this one use. */
7c979afd 1879#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1880#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1881#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1882static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1883 int ft, int fs, int cc) \
1884{ \
1885 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1886 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1887 switch (ifmt) { \
1888 case FMT_PS: \
e29c9628 1889 check_ps(ctx); \
8153667c
NF
1890 break; \
1891 case FMT_D: \
1892 if (abs) { \
1893 check_cop1x(ctx); \
1894 } \
1895 check_cp1_registers(ctx, fs | ft); \
1896 break; \
1897 case FMT_S: \
1898 if (abs) { \
1899 check_cop1x(ctx); \
1900 } \
1901 break; \
1902 } \
1903 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1904 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1905 switch (n) { \
895c2d04
BS
1906 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1907 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1908 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1909 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1910 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1911 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1912 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1913 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1914 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1915 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1916 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1917 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1918 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1919 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1920 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1921 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1922 default: abort(); \
1923 } \
1924 tcg_temp_free_i##bits (fp0); \
1925 tcg_temp_free_i##bits (fp1); \
1926}
1927
1928FOP_CONDS(, 0, d, FMT_D, 64)
1929FOP_CONDS(abs, 1, d, FMT_D, 64)
1930FOP_CONDS(, 0, s, FMT_S, 32)
1931FOP_CONDS(abs, 1, s, FMT_S, 32)
1932FOP_CONDS(, 0, ps, FMT_PS, 64)
1933FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1934#undef FOP_CONDS
3f493883
YK
1935
1936#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1937static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1938 int ft, int fs, int fd) \
1939{ \
1940 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1941 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1942 if (ifmt == FMT_D) { \
3f493883 1943 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1944 } \
1945 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1946 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1947 switch (n) { \
1948 case 0: \
1949 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 1: \
1952 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 2: \
1955 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 3: \
1958 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 4: \
1961 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 case 5: \
1964 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1965 break; \
1966 case 6: \
1967 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1968 break; \
1969 case 7: \
1970 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 case 8: \
1973 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1974 break; \
1975 case 9: \
1976 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1977 break; \
1978 case 10: \
1979 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 11: \
1982 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 12: \
1985 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 13: \
1988 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 14: \
1991 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 15: \
1994 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 17: \
1997 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 18: \
2000 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 19: \
2003 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 25: \
2006 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 26: \
2009 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 case 27: \
2012 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2013 break; \
2014 default: \
2015 abort(); \
2016 } \
2017 STORE; \
2018 tcg_temp_free_i ## bits (fp0); \
2019 tcg_temp_free_i ## bits (fp1); \
2020}
2021
2022FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2023FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2024#undef FOP_CONDNS
8153667c
NF
2025#undef gen_ldcmp_fpr32
2026#undef gen_ldcmp_fpr64
2027
958fb4a9 2028/* load/store instructions. */
e7139c44 2029#ifdef CONFIG_USER_ONLY
d9bea114 2030#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2031static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2032{ \
2033 TCGv t0 = tcg_temp_new(); \
2034 tcg_gen_mov_tl(t0, arg1); \
2035 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2036 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2037 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2038 tcg_temp_free(t0); \
aaa9128a 2039}
e7139c44
AJ
2040#else
2041#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2042static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2043{ \
895c2d04 2044 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2045}
2046#endif
aaa9128a
TS
2047OP_LD_ATOMIC(ll,ld32s);
2048#if defined(TARGET_MIPS64)
2049OP_LD_ATOMIC(lld,ld64);
2050#endif
2051#undef OP_LD_ATOMIC
2052
590bc601
PB
2053#ifdef CONFIG_USER_ONLY
2054#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2055static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2056{ \
2057 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2058 TCGLabel *l1 = gen_new_label(); \
2059 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2060 \
2061 tcg_gen_andi_tl(t0, arg2, almask); \
2062 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2063 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2064 generate_exception(ctx, EXCP_AdES); \
2065 gen_set_label(l1); \
7db13fae 2066 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2067 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2068 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2069 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2070 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2071 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2072 gen_set_label(l2); \
2073 tcg_gen_movi_tl(t0, 0); \
2074 gen_store_gpr(t0, rt); \
2075 tcg_temp_free(t0); \
2076}
2077#else
2078#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2079static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2080{ \
2081 TCGv t0 = tcg_temp_new(); \
895c2d04 2082 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2083 gen_store_gpr(t0, rt); \
590bc601
PB
2084 tcg_temp_free(t0); \
2085}
2086#endif
590bc601 2087OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2088#if defined(TARGET_MIPS64)
590bc601 2089OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2090#endif
2091#undef OP_ST_ATOMIC
2092
662d7485
NF
2093static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2094 int base, int16_t offset)
2095{
2096 if (base == 0) {
2097 tcg_gen_movi_tl(addr, offset);
2098 } else if (offset == 0) {
2099 gen_load_gpr(addr, base);
2100 } else {
2101 tcg_gen_movi_tl(addr, offset);
2102 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2103 }
2104}
2105
364d4831
NF
2106static target_ulong pc_relative_pc (DisasContext *ctx)
2107{
2108 target_ulong pc = ctx->pc;
2109
2110 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2111 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2112
2113 pc -= branch_bytes;
2114 }
2115
2116 pc &= ~(target_ulong)3;
2117 return pc;
2118}
2119
5c13fdfd 2120/* Load */
d75c135e
AJ
2121static void gen_ld(DisasContext *ctx, uint32_t opc,
2122 int rt, int base, int16_t offset)
6af0bf9c 2123{
fc40787a 2124 TCGv t0, t1, t2;
afa88c3a 2125
d75c135e 2126 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2127 /* Loongson CPU uses a load to zero register for prefetch.
2128 We emulate it as a NOP. On other CPU we must perform the
2129 actual memory access. */
afa88c3a
AJ
2130 return;
2131 }
6af0bf9c 2132
afa88c3a 2133 t0 = tcg_temp_new();
662d7485 2134 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2135
6af0bf9c 2136 switch (opc) {
d26bc211 2137#if defined(TARGET_MIPS64)
6e473128 2138 case OPC_LWU:
be3a8c53
YK
2139 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2140 ctx->default_tcg_memop_mask);
78723684 2141 gen_store_gpr(t0, rt);
6e473128 2142 break;
6af0bf9c 2143 case OPC_LD:
be3a8c53
YK
2144 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2145 ctx->default_tcg_memop_mask);
78723684 2146 gen_store_gpr(t0, rt);
6af0bf9c 2147 break;
7a387fff 2148 case OPC_LLD:
bf7910c6 2149 case R6_OPC_LLD:
5c13fdfd 2150 op_ld_lld(t0, t0, ctx);
78723684 2151 gen_store_gpr(t0, rt);
7a387fff 2152 break;
6af0bf9c 2153 case OPC_LDL:
3cee3050 2154 t1 = tcg_temp_new();
908680c6
AJ
2155 /* Do a byte access to possibly trigger a page
2156 fault with the unaligned address. */
2157 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2158 tcg_gen_andi_tl(t1, t0, 7);
2159#ifndef TARGET_WORDS_BIGENDIAN
2160 tcg_gen_xori_tl(t1, t1, 7);
2161#endif
2162 tcg_gen_shli_tl(t1, t1, 3);
2163 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2164 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a 2165 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2166 t2 = tcg_const_tl(-1);
2167 tcg_gen_shl_tl(t2, t2, t1);
78723684 2168 gen_load_gpr(t1, rt);
eb02cc3f 2169 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2170 tcg_temp_free(t2);
2171 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2172 tcg_temp_free(t1);
fc40787a 2173 gen_store_gpr(t0, rt);
6af0bf9c 2174 break;
6af0bf9c 2175 case OPC_LDR:
3cee3050 2176 t1 = tcg_temp_new();
908680c6
AJ
2177 /* Do a byte access to possibly trigger a page
2178 fault with the unaligned address. */
2179 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2180 tcg_gen_andi_tl(t1, t0, 7);
2181#ifdef TARGET_WORDS_BIGENDIAN
2182 tcg_gen_xori_tl(t1, t1, 7);
2183#endif
2184 tcg_gen_shli_tl(t1, t1, 3);
2185 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2187 tcg_gen_shr_tl(t0, t0, t1);
2188 tcg_gen_xori_tl(t1, t1, 63);
2189 t2 = tcg_const_tl(0xfffffffffffffffeull);
2190 tcg_gen_shl_tl(t2, t2, t1);
78723684 2191 gen_load_gpr(t1, rt);
fc40787a
AJ
2192 tcg_gen_and_tl(t1, t1, t2);
2193 tcg_temp_free(t2);
2194 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2195 tcg_temp_free(t1);
fc40787a 2196 gen_store_gpr(t0, rt);
6af0bf9c 2197 break;
364d4831 2198 case OPC_LDPC:
3cee3050 2199 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2200 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2201 tcg_temp_free(t1);
5f68f5ae 2202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831
NF
2203 gen_store_gpr(t0, rt);
2204 break;
6af0bf9c 2205#endif
364d4831 2206 case OPC_LWPC:
3cee3050 2207 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2208 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2209 tcg_temp_free(t1);
5f68f5ae 2210 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831
NF
2211 gen_store_gpr(t0, rt);
2212 break;
6af0bf9c 2213 case OPC_LW:
be3a8c53
YK
2214 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2215 ctx->default_tcg_memop_mask);
78723684 2216 gen_store_gpr(t0, rt);
6af0bf9c 2217 break;
6af0bf9c 2218 case OPC_LH:
be3a8c53
YK
2219 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2220 ctx->default_tcg_memop_mask);
78723684 2221 gen_store_gpr(t0, rt);
6af0bf9c 2222 break;
6af0bf9c 2223 case OPC_LHU:
be3a8c53
YK
2224 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2225 ctx->default_tcg_memop_mask);
78723684 2226 gen_store_gpr(t0, rt);
6af0bf9c
FB
2227 break;
2228 case OPC_LB:
5f68f5ae 2229 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2230 gen_store_gpr(t0, rt);
6af0bf9c 2231 break;
6af0bf9c 2232 case OPC_LBU:
5f68f5ae 2233 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2234 gen_store_gpr(t0, rt);
6af0bf9c
FB
2235 break;
2236 case OPC_LWL:
3cee3050 2237 t1 = tcg_temp_new();
908680c6
AJ
2238 /* Do a byte access to possibly trigger a page
2239 fault with the unaligned address. */
2240 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2241 tcg_gen_andi_tl(t1, t0, 3);
2242#ifndef TARGET_WORDS_BIGENDIAN
2243 tcg_gen_xori_tl(t1, t1, 3);
2244#endif
2245 tcg_gen_shli_tl(t1, t1, 3);
2246 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2247 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a 2248 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2249 t2 = tcg_const_tl(-1);
2250 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2251 gen_load_gpr(t1, rt);
eb02cc3f 2252 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2253 tcg_temp_free(t2);
2254 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2255 tcg_temp_free(t1);
fc40787a
AJ
2256 tcg_gen_ext32s_tl(t0, t0);
2257 gen_store_gpr(t0, rt);
6af0bf9c 2258 break;
6af0bf9c 2259 case OPC_LWR:
3cee3050 2260 t1 = tcg_temp_new();
908680c6
AJ
2261 /* Do a byte access to possibly trigger a page
2262 fault with the unaligned address. */
2263 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2264 tcg_gen_andi_tl(t1, t0, 3);
2265#ifdef TARGET_WORDS_BIGENDIAN
2266 tcg_gen_xori_tl(t1, t1, 3);
2267#endif
2268 tcg_gen_shli_tl(t1, t1, 3);
2269 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2270 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2271 tcg_gen_shr_tl(t0, t0, t1);
2272 tcg_gen_xori_tl(t1, t1, 31);
2273 t2 = tcg_const_tl(0xfffffffeull);
2274 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2275 gen_load_gpr(t1, rt);
fc40787a
AJ
2276 tcg_gen_and_tl(t1, t1, t2);
2277 tcg_temp_free(t2);
2278 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2279 tcg_temp_free(t1);
c728154b 2280 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2281 gen_store_gpr(t0, rt);
6af0bf9c 2282 break;
6af0bf9c 2283 case OPC_LL:
4368b29a 2284 case R6_OPC_LL:
5c13fdfd 2285 op_ld_ll(t0, t0, ctx);
78723684 2286 gen_store_gpr(t0, rt);
6af0bf9c 2287 break;
d66c7132 2288 }
d66c7132 2289 tcg_temp_free(t0);
d66c7132
AJ
2290}
2291
5c13fdfd
AJ
2292/* Store */
2293static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2294 int base, int16_t offset)
2295{
5c13fdfd
AJ
2296 TCGv t0 = tcg_temp_new();
2297 TCGv t1 = tcg_temp_new();
2298
2299 gen_base_offset_addr(ctx, t0, base, offset);
2300 gen_load_gpr(t1, rt);
2301 switch (opc) {
2302#if defined(TARGET_MIPS64)
2303 case OPC_SD:
be3a8c53
YK
2304 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2305 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2306 break;
2307 case OPC_SDL:
895c2d04 2308 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2309 break;
2310 case OPC_SDR:
895c2d04 2311 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2312 break;
2313#endif
2314 case OPC_SW:
be3a8c53
YK
2315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2316 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2317 break;
2318 case OPC_SH:
be3a8c53
YK
2319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2320 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2321 break;
2322 case OPC_SB:
5f68f5ae 2323 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2324 break;
2325 case OPC_SWL:
895c2d04 2326 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2327 break;
2328 case OPC_SWR:
895c2d04 2329 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2330 break;
2331 }
5c13fdfd
AJ
2332 tcg_temp_free(t0);
2333 tcg_temp_free(t1);
2334}
2335
2336
d66c7132
AJ
2337/* Store conditional */
2338static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2339 int base, int16_t offset)
2340{
d66c7132
AJ
2341 TCGv t0, t1;
2342
2d2826b9 2343#ifdef CONFIG_USER_ONLY
d66c7132 2344 t0 = tcg_temp_local_new();
d66c7132 2345 t1 = tcg_temp_local_new();
2d2826b9
AJ
2346#else
2347 t0 = tcg_temp_new();
2348 t1 = tcg_temp_new();
2349#endif
2350 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2351 gen_load_gpr(t1, rt);
2352 switch (opc) {
2353#if defined(TARGET_MIPS64)
2354 case OPC_SCD:
bf7910c6 2355 case R6_OPC_SCD:
5c13fdfd 2356 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2357 break;
2358#endif
6af0bf9c 2359 case OPC_SC:
4368b29a 2360 case R6_OPC_SC:
5c13fdfd 2361 op_st_sc(t1, t0, rt, ctx);
6af0bf9c 2362 break;
6af0bf9c 2363 }
78723684 2364 tcg_temp_free(t1);
d66c7132 2365 tcg_temp_free(t0);
6af0bf9c
FB
2366}
2367
6ea83fed 2368/* Load and store */
7a387fff 2369static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2370 int base, int16_t offset)
6ea83fed 2371{
4e2474d6 2372 TCGv t0 = tcg_temp_new();
6ea83fed 2373
662d7485 2374 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2375 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2376 memory access. */
6ea83fed
FB
2377 switch (opc) {
2378 case OPC_LWC1:
b6d96bed 2379 {
a7812ae4 2380 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2381 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2382 ctx->default_tcg_memop_mask);
7c979afd 2383 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2384 tcg_temp_free_i32(fp0);
b6d96bed 2385 }
6ea83fed
FB
2386 break;
2387 case OPC_SWC1:
b6d96bed 2388 {
a7812ae4 2389 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2390 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2391 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2392 ctx->default_tcg_memop_mask);
a7812ae4 2393 tcg_temp_free_i32(fp0);
b6d96bed 2394 }
6ea83fed
FB
2395 break;
2396 case OPC_LDC1:
b6d96bed 2397 {
a7812ae4 2398 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2399 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2400 ctx->default_tcg_memop_mask);
b6d96bed 2401 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2402 tcg_temp_free_i64(fp0);
b6d96bed 2403 }
6ea83fed
FB
2404 break;
2405 case OPC_SDC1:
b6d96bed 2406 {
a7812ae4 2407 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2408 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2409 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2410 ctx->default_tcg_memop_mask);
a7812ae4 2411 tcg_temp_free_i64(fp0);
b6d96bed 2412 }
6ea83fed
FB
2413 break;
2414 default:
9d68ac14 2415 MIPS_INVAL("flt_ldst");
9c708c7f 2416 generate_exception_end(ctx, EXCP_RI);
78723684 2417 goto out;
6ea83fed 2418 }
78723684
TS
2419 out:
2420 tcg_temp_free(t0);
6ea83fed 2421}
6ea83fed 2422
5ab5c041
AJ
2423static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2424 int rs, int16_t imm)
26ebe468 2425{
5ab5c041 2426 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2427 check_cp1_enabled(ctx);
d9224450
MR
2428 switch (op) {
2429 case OPC_LDC1:
2430 case OPC_SDC1:
2431 check_insn(ctx, ISA_MIPS2);
2432 /* Fallthrough */
2433 default:
2434 gen_flt_ldst(ctx, op, rt, rs, imm);
2435 }
26ebe468
NF
2436 } else {
2437 generate_exception_err(ctx, EXCP_CpU, 1);
2438 }
2439}
2440
6af0bf9c 2441/* Arithmetic with immediate operand */
d75c135e
AJ
2442static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2443 int rt, int rs, int16_t imm)
6af0bf9c 2444{
324d9e32 2445 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2446
7a387fff 2447 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2448 /* If no destination, treat it as a NOP.
2449 For addi, we must generate the overflow exception when needed. */
324d9e32 2450 return;
6af0bf9c
FB
2451 }
2452 switch (opc) {
2453 case OPC_ADDI:
48d38ca5 2454 {
324d9e32
AJ
2455 TCGv t0 = tcg_temp_local_new();
2456 TCGv t1 = tcg_temp_new();
2457 TCGv t2 = tcg_temp_new();
42a268c2 2458 TCGLabel *l1 = gen_new_label();
48d38ca5 2459
324d9e32
AJ
2460 gen_load_gpr(t1, rs);
2461 tcg_gen_addi_tl(t0, t1, uimm);
2462 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2463
324d9e32
AJ
2464 tcg_gen_xori_tl(t1, t1, ~uimm);
2465 tcg_gen_xori_tl(t2, t0, uimm);
2466 tcg_gen_and_tl(t1, t1, t2);
2467 tcg_temp_free(t2);
2468 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2469 tcg_temp_free(t1);
48d38ca5
TS
2470 /* operands of same sign, result different sign */
2471 generate_exception(ctx, EXCP_OVERFLOW);
2472 gen_set_label(l1);
78723684 2473 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2474 gen_store_gpr(t0, rt);
2475 tcg_temp_free(t0);
48d38ca5 2476 }
6af0bf9c
FB
2477 break;
2478 case OPC_ADDIU:
324d9e32
AJ
2479 if (rs != 0) {
2480 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2481 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2482 } else {
2483 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2484 }
6af0bf9c 2485 break;
d26bc211 2486#if defined(TARGET_MIPS64)
7a387fff 2487 case OPC_DADDI:
48d38ca5 2488 {
324d9e32
AJ
2489 TCGv t0 = tcg_temp_local_new();
2490 TCGv t1 = tcg_temp_new();
2491 TCGv t2 = tcg_temp_new();
42a268c2 2492 TCGLabel *l1 = gen_new_label();
48d38ca5 2493
324d9e32
AJ
2494 gen_load_gpr(t1, rs);
2495 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2496
324d9e32
AJ
2497 tcg_gen_xori_tl(t1, t1, ~uimm);
2498 tcg_gen_xori_tl(t2, t0, uimm);
2499 tcg_gen_and_tl(t1, t1, t2);
2500 tcg_temp_free(t2);
2501 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2502 tcg_temp_free(t1);
48d38ca5
TS
2503 /* operands of same sign, result different sign */
2504 generate_exception(ctx, EXCP_OVERFLOW);
2505 gen_set_label(l1);
324d9e32
AJ
2506 gen_store_gpr(t0, rt);
2507 tcg_temp_free(t0);
48d38ca5 2508 }
7a387fff
TS
2509 break;
2510 case OPC_DADDIU:
324d9e32
AJ
2511 if (rs != 0) {
2512 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2513 } else {
2514 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2515 }
7a387fff
TS
2516 break;
2517#endif
324d9e32 2518 }
324d9e32
AJ
2519}
2520
2521/* Logic with immediate operand */
d75c135e 2522static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2523 int rt, int rs, int16_t imm)
324d9e32
AJ
2524{
2525 target_ulong uimm;
324d9e32
AJ
2526
2527 if (rt == 0) {
2528 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2529 return;
2530 }
2531 uimm = (uint16_t)imm;
2532 switch (opc) {
6af0bf9c 2533 case OPC_ANDI:
324d9e32
AJ
2534 if (likely(rs != 0))
2535 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2536 else
2537 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2538 break;
2539 case OPC_ORI:
324d9e32
AJ
2540 if (rs != 0)
2541 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2542 else
2543 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2544 break;
2545 case OPC_XORI:
324d9e32
AJ
2546 if (likely(rs != 0))
2547 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2548 else
2549 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2550 break;
2551 case OPC_LUI:
d4ea6acd
LA
2552 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2553 /* OPC_AUI */
2554 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2555 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2556 } else {
2557 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2558 }
7c2c3ea3
EJ
2559 break;
2560
2561 default:
6af0bf9c 2562 break;
324d9e32 2563 }
324d9e32
AJ
2564}
2565
2566/* Set on less than with immediate operand */
d75c135e 2567static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2568 int rt, int rs, int16_t imm)
324d9e32
AJ
2569{
2570 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2571 TCGv t0;
2572
2573 if (rt == 0) {
2574 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2575 return;
2576 }
2577 t0 = tcg_temp_new();
2578 gen_load_gpr(t0, rs);
2579 switch (opc) {
2580 case OPC_SLTI:
e68dd28f 2581 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2582 break;
2583 case OPC_SLTIU:
e68dd28f 2584 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2585 break;
2586 }
324d9e32
AJ
2587 tcg_temp_free(t0);
2588}
2589
2590/* Shifts with immediate operand */
d75c135e 2591static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2592 int rt, int rs, int16_t imm)
2593{
2594 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2595 TCGv t0;
2596
2597 if (rt == 0) {
2598 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2599 return;
2600 }
2601
2602 t0 = tcg_temp_new();
2603 gen_load_gpr(t0, rs);
2604 switch (opc) {
6af0bf9c 2605 case OPC_SLL:
78723684 2606 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2607 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2608 break;
2609 case OPC_SRA:
324d9e32 2610 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2611 break;
2612 case OPC_SRL:
ea63e2c3
NF
2613 if (uimm != 0) {
2614 tcg_gen_ext32u_tl(t0, t0);
2615 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2616 } else {
2617 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2618 }
ea63e2c3
NF
2619 break;
2620 case OPC_ROTR:
2621 if (uimm != 0) {
2622 TCGv_i32 t1 = tcg_temp_new_i32();
2623
2624 tcg_gen_trunc_tl_i32(t1, t0);
2625 tcg_gen_rotri_i32(t1, t1, uimm);
2626 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2627 tcg_temp_free_i32(t1);
3399e30f
NF
2628 } else {
2629 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2630 }
7a387fff 2631 break;
d26bc211 2632#if defined(TARGET_MIPS64)
7a387fff 2633 case OPC_DSLL:
324d9e32 2634 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2635 break;
2636 case OPC_DSRA:
324d9e32 2637 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2638 break;
2639 case OPC_DSRL:
ea63e2c3 2640 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2641 break;
2642 case OPC_DROTR:
2643 if (uimm != 0) {
2644 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2645 } else {
2646 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2647 }
7a387fff
TS
2648 break;
2649 case OPC_DSLL32:
324d9e32 2650 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2651 break;
2652 case OPC_DSRA32:
324d9e32 2653 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2654 break;
2655 case OPC_DSRL32:
ea63e2c3 2656 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2657 break;
2658 case OPC_DROTR32:
2659 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2660 break;
7a387fff 2661#endif
6af0bf9c 2662 }
78723684 2663 tcg_temp_free(t0);
6af0bf9c
FB
2664}
2665
2666/* Arithmetic */
d75c135e
AJ
2667static void gen_arith(DisasContext *ctx, uint32_t opc,
2668 int rd, int rs, int rt)
6af0bf9c 2669{
7a387fff
TS
2670 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2671 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2672 /* If no destination, treat it as a NOP.
2673 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2674 return;
185f0762 2675 }
460f00c4 2676
6af0bf9c
FB
2677 switch (opc) {
2678 case OPC_ADD:
48d38ca5 2679 {
460f00c4
AJ
2680 TCGv t0 = tcg_temp_local_new();
2681 TCGv t1 = tcg_temp_new();
2682 TCGv t2 = tcg_temp_new();
42a268c2 2683 TCGLabel *l1 = gen_new_label();
48d38ca5 2684
460f00c4
AJ
2685 gen_load_gpr(t1, rs);
2686 gen_load_gpr(t2, rt);
2687 tcg_gen_add_tl(t0, t1, t2);
2688 tcg_gen_ext32s_tl(t0, t0);
2689 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2690 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2691 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2692 tcg_temp_free(t2);
2693 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2694 tcg_temp_free(t1);
48d38ca5
TS
2695 /* operands of same sign, result different sign */
2696 generate_exception(ctx, EXCP_OVERFLOW);
2697 gen_set_label(l1);
460f00c4
AJ
2698 gen_store_gpr(t0, rd);
2699 tcg_temp_free(t0);
48d38ca5 2700 }
6af0bf9c
FB
2701 break;
2702 case OPC_ADDU:
460f00c4
AJ
2703 if (rs != 0 && rt != 0) {
2704 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2705 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2706 } else if (rs == 0 && rt != 0) {
2707 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2708 } else if (rs != 0 && rt == 0) {
2709 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2710 } else {
2711 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2712 }
6af0bf9c
FB
2713 break;
2714 case OPC_SUB:
48d38ca5 2715 {
460f00c4
AJ
2716 TCGv t0 = tcg_temp_local_new();
2717 TCGv t1 = tcg_temp_new();
2718 TCGv t2 = tcg_temp_new();
42a268c2 2719 TCGLabel *l1 = gen_new_label();
48d38ca5 2720
460f00c4
AJ
2721 gen_load_gpr(t1, rs);
2722 gen_load_gpr(t2, rt);
2723 tcg_gen_sub_tl(t0, t1, t2);
2724 tcg_gen_ext32s_tl(t0, t0);
2725 tcg_gen_xor_tl(t2, t1, t2);
2726 tcg_gen_xor_tl(t1, t0, t1);
2727 tcg_gen_and_tl(t1, t1, t2);
2728 tcg_temp_free(t2);
2729 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2730 tcg_temp_free(t1);
31e3104f 2731 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2732 generate_exception(ctx, EXCP_OVERFLOW);
2733 gen_set_label(l1);
460f00c4
AJ
2734 gen_store_gpr(t0, rd);
2735 tcg_temp_free(t0);
48d38ca5 2736 }
6af0bf9c
FB
2737 break;
2738 case OPC_SUBU:
460f00c4
AJ
2739 if (rs != 0 && rt != 0) {
2740 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2741 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742 } else if (rs == 0 && rt != 0) {
2743 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2744 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2745 } else if (rs != 0 && rt == 0) {
2746 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2747 } else {
2748 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2749 }
6af0bf9c 2750 break;
d26bc211 2751#if defined(TARGET_MIPS64)
7a387fff 2752 case OPC_DADD:
48d38ca5 2753 {
460f00c4
AJ
2754 TCGv t0 = tcg_temp_local_new();
2755 TCGv t1 = tcg_temp_new();
2756 TCGv t2 = tcg_temp_new();
42a268c2 2757 TCGLabel *l1 = gen_new_label();
48d38ca5 2758
460f00c4
AJ
2759 gen_load_gpr(t1, rs);
2760 gen_load_gpr(t2, rt);
2761 tcg_gen_add_tl(t0, t1, t2);
2762 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2763 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2764 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2765 tcg_temp_free(t2);
2766 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2767 tcg_temp_free(t1);
48d38ca5
TS
2768 /* operands of same sign, result different sign */
2769 generate_exception(ctx, EXCP_OVERFLOW);
2770 gen_set_label(l1);
460f00c4
AJ
2771 gen_store_gpr(t0, rd);
2772 tcg_temp_free(t0);
48d38ca5 2773 }
7a387fff
TS
2774 break;
2775 case OPC_DADDU:
460f00c4
AJ
2776 if (rs != 0 && rt != 0) {
2777 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2778 } else if (rs == 0 && rt != 0) {
2779 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2780 } else if (rs != 0 && rt == 0) {
2781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2782 } else {
2783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2784 }
7a387fff
TS
2785 break;
2786 case OPC_DSUB:
48d38ca5 2787 {
460f00c4
AJ
2788 TCGv t0 = tcg_temp_local_new();
2789 TCGv t1 = tcg_temp_new();
2790 TCGv t2 = tcg_temp_new();
42a268c2 2791 TCGLabel *l1 = gen_new_label();
48d38ca5 2792
460f00c4
AJ
2793 gen_load_gpr(t1, rs);
2794 gen_load_gpr(t2, rt);
2795 tcg_gen_sub_tl(t0, t1, t2);
2796 tcg_gen_xor_tl(t2, t1, t2);
2797 tcg_gen_xor_tl(t1, t0, t1);
2798 tcg_gen_and_tl(t1, t1, t2);
2799 tcg_temp_free(t2);
2800 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2801 tcg_temp_free(t1);
31e3104f 2802 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2803 generate_exception(ctx, EXCP_OVERFLOW);
2804 gen_set_label(l1);
460f00c4
AJ
2805 gen_store_gpr(t0, rd);
2806 tcg_temp_free(t0);
48d38ca5 2807 }
7a387fff
TS
2808 break;
2809 case OPC_DSUBU:
460f00c4
AJ
2810 if (rs != 0 && rt != 0) {
2811 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2812 } else if (rs == 0 && rt != 0) {
2813 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2814 } else if (rs != 0 && rt == 0) {
2815 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2816 } else {
2817 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2818 }
7a387fff
TS
2819 break;
2820#endif
460f00c4
AJ
2821 case OPC_MUL:
2822 if (likely(rs != 0 && rt != 0)) {
2823 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2824 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2825 } else {
2826 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2827 }
6af0bf9c 2828 break;
460f00c4 2829 }
460f00c4
AJ
2830}
2831
2832/* Conditional move */
d75c135e 2833static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2834 int rd, int rs, int rt)
460f00c4 2835{
acf12465 2836 TCGv t0, t1, t2;
460f00c4
AJ
2837
2838 if (rd == 0) {
acf12465 2839 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2840 return;
2841 }
2842
acf12465
AJ
2843 t0 = tcg_temp_new();
2844 gen_load_gpr(t0, rt);
2845 t1 = tcg_const_tl(0);
2846 t2 = tcg_temp_new();
2847 gen_load_gpr(t2, rs);
460f00c4
AJ
2848 switch (opc) {
2849 case OPC_MOVN:
acf12465 2850 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2851 break;
460f00c4 2852 case OPC_MOVZ:
acf12465 2853 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2854 break;
b691d9d2
LA
2855 case OPC_SELNEZ:
2856 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2857 break;
2858 case OPC_SELEQZ:
2859 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2860 break;
460f00c4 2861 }
acf12465
AJ
2862 tcg_temp_free(t2);
2863 tcg_temp_free(t1);
2864 tcg_temp_free(t0);
460f00c4
AJ
2865}
2866
2867/* Logic */
d75c135e 2868static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2869 int rd, int rs, int rt)
460f00c4 2870{
460f00c4
AJ
2871 if (rd == 0) {
2872 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2873 return;
2874 }
2875
2876 switch (opc) {
6af0bf9c 2877 case OPC_AND:
460f00c4
AJ
2878 if (likely(rs != 0 && rt != 0)) {
2879 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2880 } else {
2881 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2882 }
6af0bf9c
FB
2883 break;
2884 case OPC_NOR:
460f00c4
AJ
2885 if (rs != 0 && rt != 0) {
2886 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2887 } else if (rs == 0 && rt != 0) {
2888 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2889 } else if (rs != 0 && rt == 0) {
2890 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2891 } else {
2892 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2893 }
6af0bf9c
FB
2894 break;
2895 case OPC_OR:
460f00c4
AJ
2896 if (likely(rs != 0 && rt != 0)) {
2897 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2898 } else if (rs == 0 && rt != 0) {
2899 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2900 } else if (rs != 0 && rt == 0) {
2901 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2902 } else {
2903 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2904 }
6af0bf9c
FB
2905 break;
2906 case OPC_XOR:
460f00c4
AJ
2907 if (likely(rs != 0 && rt != 0)) {
2908 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2909 } else if (rs == 0 && rt != 0) {
2910 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2911 } else if (rs != 0 && rt == 0) {
2912 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2913 } else {
2914 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2915 }
6af0bf9c 2916 break;
460f00c4 2917 }
460f00c4
AJ
2918}
2919
2920/* Set on lower than */
d75c135e 2921static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2922 int rd, int rs, int rt)
460f00c4 2923{
460f00c4
AJ
2924 TCGv t0, t1;
2925
2926 if (rd == 0) {
2927 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2928 return;
2929 }
2930
2931 t0 = tcg_temp_new();
2932 t1 = tcg_temp_new();
2933 gen_load_gpr(t0, rs);
2934 gen_load_gpr(t1, rt);
2935 switch (opc) {
2936 case OPC_SLT:
e68dd28f 2937 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2938 break;
460f00c4 2939 case OPC_SLTU:
e68dd28f 2940 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2941 break;
2942 }
460f00c4
AJ
2943 tcg_temp_free(t0);
2944 tcg_temp_free(t1);
2945}
20c4c97c 2946
460f00c4 2947/* Shifts */
d75c135e
AJ
2948static void gen_shift(DisasContext *ctx, uint32_t opc,
2949 int rd, int rs, int rt)
460f00c4 2950{
460f00c4 2951 TCGv t0, t1;
20c4c97c 2952
460f00c4
AJ
2953 if (rd == 0) {
2954 /* If no destination, treat it as a NOP.
2955 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
2956 return;
2957 }
2958
2959 t0 = tcg_temp_new();
2960 t1 = tcg_temp_new();
2961 gen_load_gpr(t0, rs);
2962 gen_load_gpr(t1, rt);
2963 switch (opc) {
6af0bf9c 2964 case OPC_SLLV:
78723684
TS
2965 tcg_gen_andi_tl(t0, t0, 0x1f);
2966 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2967 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2968 break;
2969 case OPC_SRAV:
78723684 2970 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2971 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2972 break;
2973 case OPC_SRLV:
ea63e2c3
NF
2974 tcg_gen_ext32u_tl(t1, t1);
2975 tcg_gen_andi_tl(t0, t0, 0x1f);
2976 tcg_gen_shr_tl(t0, t1, t0);
2977 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2978 break;
2979 case OPC_ROTRV:
2980 {
2981 TCGv_i32 t2 = tcg_temp_new_i32();
2982 TCGv_i32 t3 = tcg_temp_new_i32();
2983
2984 tcg_gen_trunc_tl_i32(t2, t0);
2985 tcg_gen_trunc_tl_i32(t3, t1);
2986 tcg_gen_andi_i32(t2, t2, 0x1f);
2987 tcg_gen_rotr_i32(t2, t3, t2);
2988 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2989 tcg_temp_free_i32(t2);
2990 tcg_temp_free_i32(t3);
5a63bcb2 2991 }
7a387fff 2992 break;
d26bc211 2993#if defined(TARGET_MIPS64)
7a387fff 2994 case OPC_DSLLV:
78723684 2995 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2996 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2997 break;
2998 case OPC_DSRAV:
78723684 2999 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3000 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3001 break;
3002 case OPC_DSRLV:
ea63e2c3
NF
3003 tcg_gen_andi_tl(t0, t0, 0x3f);
3004 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3005 break;
3006 case OPC_DROTRV:
3007 tcg_gen_andi_tl(t0, t0, 0x3f);
3008 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3009 break;
7a387fff 3010#endif
6af0bf9c 3011 }
78723684
TS
3012 tcg_temp_free(t0);
3013 tcg_temp_free(t1);
6af0bf9c
FB
3014}
3015
3016/* Arithmetic on HI/LO registers */
26135ead 3017static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3018{
6af0bf9c 3019 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3020 /* Treat as NOP. */
a1f6684d 3021 return;
6af0bf9c 3022 }
4133498f 3023
4133498f
JL
3024 if (acc != 0) {
3025 check_dsp(ctx);
3026 }
3027
6af0bf9c
FB
3028 switch (opc) {
3029 case OPC_MFHI:
4133498f
JL
3030#if defined(TARGET_MIPS64)
3031 if (acc != 0) {
3032 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3033 } else
3034#endif
3035 {
3036 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3037 }
6af0bf9c
FB
3038 break;
3039 case OPC_MFLO:
4133498f
JL
3040#if defined(TARGET_MIPS64)
3041 if (acc != 0) {
3042 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3043 } else
3044#endif
3045 {
3046 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3047 }
6af0bf9c
FB
3048 break;
3049 case OPC_MTHI:
4133498f
JL
3050 if (reg != 0) {
3051#if defined(TARGET_MIPS64)
3052 if (acc != 0) {
3053 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3054 } else
3055#endif
3056 {
3057 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3058 }
3059 } else {
3060 tcg_gen_movi_tl(cpu_HI[acc], 0);
3061 }
6af0bf9c
FB
3062 break;
3063 case OPC_MTLO:
4133498f
JL
3064 if (reg != 0) {
3065#if defined(TARGET_MIPS64)
3066 if (acc != 0) {
3067 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3068 } else
3069#endif
3070 {
3071 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3072 }
3073 } else {
3074 tcg_gen_movi_tl(cpu_LO[acc], 0);
3075 }
6af0bf9c 3076 break;
6af0bf9c 3077 }
6af0bf9c
FB
3078}
3079
d4ea6acd
LA
3080static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3081 TCGMemOp memop)
3082{
3083 TCGv t0 = tcg_const_tl(addr);
3084 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3085 gen_store_gpr(t0, reg);
3086 tcg_temp_free(t0);
3087}
3088
ab39ee45
YK
3089static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3090 int rs)
d4ea6acd
LA
3091{
3092 target_long offset;
3093 target_long addr;
3094
ab39ee45 3095 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3096 case OPC_ADDIUPC:
3097 if (rs != 0) {
3098 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3099 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3100 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3101 }
3102 break;
3103 case R6_OPC_LWPC:
3104 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3105 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3106 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3107 break;
3108#if defined(TARGET_MIPS64)
3109 case OPC_LWUPC:
3110 check_mips_64(ctx);
3111 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3112 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3113 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3114 break;
3115#endif
3116 default:
ab39ee45 3117 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3118 case OPC_AUIPC:
3119 if (rs != 0) {
ab39ee45
YK
3120 offset = sextract32(ctx->opcode, 0, 16) << 16;
3121 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3122 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3123 }
3124 break;
3125 case OPC_ALUIPC:
3126 if (rs != 0) {
ab39ee45
YK
3127 offset = sextract32(ctx->opcode, 0, 16) << 16;
3128 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3129 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3130 }
3131 break;
3132#if defined(TARGET_MIPS64)
3133 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3134 case R6_OPC_LDPC + (1 << 16):
3135 case R6_OPC_LDPC + (2 << 16):
3136 case R6_OPC_LDPC + (3 << 16):
3137 check_mips_64(ctx);
3138 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3139 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3140 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3141 break;
3142#endif
3143 default:
3144 MIPS_INVAL("OPC_PCREL");
9c708c7f 3145 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3146 break;
3147 }
3148 break;
3149 }
3150}
3151
b42ee5e1
LA
3152static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3153{
b42ee5e1
LA
3154 TCGv t0, t1;
3155
3156 if (rd == 0) {
3157 /* Treat as NOP. */
b42ee5e1
LA
3158 return;
3159 }
3160
3161 t0 = tcg_temp_new();
3162 t1 = tcg_temp_new();
3163
3164 gen_load_gpr(t0, rs);
3165 gen_load_gpr(t1, rt);
3166
3167 switch (opc) {
3168 case R6_OPC_DIV:
3169 {
3170 TCGv t2 = tcg_temp_new();
3171 TCGv t3 = tcg_temp_new();
3172 tcg_gen_ext32s_tl(t0, t0);
3173 tcg_gen_ext32s_tl(t1, t1);
3174 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3175 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3176 tcg_gen_and_tl(t2, t2, t3);
3177 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3178 tcg_gen_or_tl(t2, t2, t3);
3179 tcg_gen_movi_tl(t3, 0);
3180 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3181 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3182 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3183 tcg_temp_free(t3);
3184 tcg_temp_free(t2);
3185 }
b42ee5e1
LA
3186 break;
3187 case R6_OPC_MOD:
3188 {
3189 TCGv t2 = tcg_temp_new();
3190 TCGv t3 = tcg_temp_new();
3191 tcg_gen_ext32s_tl(t0, t0);
3192 tcg_gen_ext32s_tl(t1, t1);
3193 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3194 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3195 tcg_gen_and_tl(t2, t2, t3);
3196 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3197 tcg_gen_or_tl(t2, t2, t3);
3198 tcg_gen_movi_tl(t3, 0);
3199 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3200 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3201 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3202 tcg_temp_free(t3);
3203 tcg_temp_free(t2);
3204 }
b42ee5e1
LA
3205 break;
3206 case R6_OPC_DIVU:
3207 {
3208 TCGv t2 = tcg_const_tl(0);
3209 TCGv t3 = tcg_const_tl(1);
3210 tcg_gen_ext32u_tl(t0, t0);
3211 tcg_gen_ext32u_tl(t1, t1);
3212 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3213 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3214 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3215 tcg_temp_free(t3);
3216 tcg_temp_free(t2);
3217 }
b42ee5e1
LA
3218 break;
3219 case R6_OPC_MODU:
3220 {
3221 TCGv t2 = tcg_const_tl(0);
3222 TCGv t3 = tcg_const_tl(1);
3223 tcg_gen_ext32u_tl(t0, t0);
3224 tcg_gen_ext32u_tl(t1, t1);
3225 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3226 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3228 tcg_temp_free(t3);
3229 tcg_temp_free(t2);
3230 }
b42ee5e1
LA
3231 break;
3232 case R6_OPC_MUL:
3233 {
3234 TCGv_i32 t2 = tcg_temp_new_i32();
3235 TCGv_i32 t3 = tcg_temp_new_i32();
3236 tcg_gen_trunc_tl_i32(t2, t0);
3237 tcg_gen_trunc_tl_i32(t3, t1);
3238 tcg_gen_mul_i32(t2, t2, t3);
3239 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3240 tcg_temp_free_i32(t2);
3241 tcg_temp_free_i32(t3);
3242 }
b42ee5e1
LA
3243 break;
3244 case R6_OPC_MUH:
3245 {
3246 TCGv_i32 t2 = tcg_temp_new_i32();
3247 TCGv_i32 t3 = tcg_temp_new_i32();
3248 tcg_gen_trunc_tl_i32(t2, t0);
3249 tcg_gen_trunc_tl_i32(t3, t1);
3250 tcg_gen_muls2_i32(t2, t3, t2, t3);
3251 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3252 tcg_temp_free_i32(t2);
3253 tcg_temp_free_i32(t3);
3254 }
b42ee5e1
LA
3255 break;
3256 case R6_OPC_MULU:
3257 {
3258 TCGv_i32 t2 = tcg_temp_new_i32();
3259 TCGv_i32 t3 = tcg_temp_new_i32();
3260 tcg_gen_trunc_tl_i32(t2, t0);
3261 tcg_gen_trunc_tl_i32(t3, t1);
3262 tcg_gen_mul_i32(t2, t2, t3);
3263 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3264 tcg_temp_free_i32(t2);
3265 tcg_temp_free_i32(t3);
3266 }
b42ee5e1
LA
3267 break;
3268 case R6_OPC_MUHU:
3269 {
3270 TCGv_i32 t2 = tcg_temp_new_i32();
3271 TCGv_i32 t3 = tcg_temp_new_i32();
3272 tcg_gen_trunc_tl_i32(t2, t0);
3273 tcg_gen_trunc_tl_i32(t3, t1);
3274 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3275 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3276 tcg_temp_free_i32(t2);
3277 tcg_temp_free_i32(t3);
3278 }
b42ee5e1
LA
3279 break;
3280#if defined(TARGET_MIPS64)
3281 case R6_OPC_DDIV:
3282 {
3283 TCGv t2 = tcg_temp_new();
3284 TCGv t3 = tcg_temp_new();
3285 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3287 tcg_gen_and_tl(t2, t2, t3);
3288 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3289 tcg_gen_or_tl(t2, t2, t3);
3290 tcg_gen_movi_tl(t3, 0);
3291 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3292 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3293 tcg_temp_free(t3);
3294 tcg_temp_free(t2);
3295 }
b42ee5e1
LA
3296 break;
3297 case R6_OPC_DMOD:
3298 {
3299 TCGv t2 = tcg_temp_new();
3300 TCGv t3 = tcg_temp_new();
3301 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3302 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3303 tcg_gen_and_tl(t2, t2, t3);
3304 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3305 tcg_gen_or_tl(t2, t2, t3);
3306 tcg_gen_movi_tl(t3, 0);
3307 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3308 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3309 tcg_temp_free(t3);
3310 tcg_temp_free(t2);
3311 }
b42ee5e1
LA
3312 break;
3313 case R6_OPC_DDIVU:
3314 {
3315 TCGv t2 = tcg_const_tl(0);
3316 TCGv t3 = tcg_const_tl(1);
3317 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3319 tcg_temp_free(t3);
3320 tcg_temp_free(t2);
3321 }
b42ee5e1
LA
3322 break;
3323 case R6_OPC_DMODU:
3324 {
3325 TCGv t2 = tcg_const_tl(0);
3326 TCGv t3 = tcg_const_tl(1);
3327 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3328 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3329 tcg_temp_free(t3);
3330 tcg_temp_free(t2);
3331 }
b42ee5e1
LA
3332 break;
3333 case R6_OPC_DMUL:
3334 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3335 break;
3336 case R6_OPC_DMUH:
3337 {
3338 TCGv t2 = tcg_temp_new();
3339 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3340 tcg_temp_free(t2);
3341 }
b42ee5e1
LA
3342 break;
3343 case R6_OPC_DMULU:
3344 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3345 break;
3346 case R6_OPC_DMUHU:
3347 {
3348 TCGv t2 = tcg_temp_new();
3349 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3350 tcg_temp_free(t2);
3351 }
b42ee5e1
LA
3352 break;
3353#endif
3354 default:
9d68ac14 3355 MIPS_INVAL("r6 mul/div");
9c708c7f 3356 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3357 goto out;
3358 }
b42ee5e1
LA
3359 out:
3360 tcg_temp_free(t0);
3361 tcg_temp_free(t1);
3362}
3363
26135ead
RS
3364static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3365 int acc, int rs, int rt)
6af0bf9c 3366{
d45f89f4
AJ
3367 TCGv t0, t1;
3368
51127181
AJ
3369 t0 = tcg_temp_new();
3370 t1 = tcg_temp_new();
6af0bf9c 3371
78723684
TS
3372 gen_load_gpr(t0, rs);
3373 gen_load_gpr(t1, rt);
51127181 3374
26135ead
RS
3375 if (acc != 0) {
3376 check_dsp(ctx);
3377 }
3378
6af0bf9c
FB
3379 switch (opc) {
3380 case OPC_DIV:
48d38ca5 3381 {
51127181
AJ
3382 TCGv t2 = tcg_temp_new();
3383 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3384 tcg_gen_ext32s_tl(t0, t0);
3385 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3386 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3387 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3388 tcg_gen_and_tl(t2, t2, t3);
3389 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3390 tcg_gen_or_tl(t2, t2, t3);
3391 tcg_gen_movi_tl(t3, 0);
3392 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3393 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3394 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3395 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3396 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3397 tcg_temp_free(t3);
3398 tcg_temp_free(t2);
48d38ca5 3399 }
6af0bf9c
FB
3400 break;
3401 case OPC_DIVU:
48d38ca5 3402 {
51127181
AJ
3403 TCGv t2 = tcg_const_tl(0);
3404 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3405 tcg_gen_ext32u_tl(t0, t0);
3406 tcg_gen_ext32u_tl(t1, t1);
51127181 3407 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3408 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3409 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3410 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3411 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3412 tcg_temp_free(t3);
3413 tcg_temp_free(t2);
48d38ca5 3414 }
6af0bf9c
FB
3415 break;
3416 case OPC_MULT:
214c465f 3417 {
ce1dd5d1
RH
3418 TCGv_i32 t2 = tcg_temp_new_i32();
3419 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3420 tcg_gen_trunc_tl_i32(t2, t0);
3421 tcg_gen_trunc_tl_i32(t3, t1);
3422 tcg_gen_muls2_i32(t2, t3, t2, t3);
3423 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3424 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3425 tcg_temp_free_i32(t2);
3426 tcg_temp_free_i32(t3);
214c465f 3427 }
6af0bf9c
FB
3428 break;
3429 case OPC_MULTU:
214c465f 3430 {
ce1dd5d1
RH
3431 TCGv_i32 t2 = tcg_temp_new_i32();
3432 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3433 tcg_gen_trunc_tl_i32(t2, t0);
3434 tcg_gen_trunc_tl_i32(t3, t1);
3435 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3436 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3437 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3438 tcg_temp_free_i32(t2);
3439 tcg_temp_free_i32(t3);
214c465f 3440 }
6af0bf9c 3441 break;
d26bc211 3442#if defined(TARGET_MIPS64)
7a387fff 3443 case OPC_DDIV:
48d38ca5 3444 {
51127181
AJ
3445 TCGv t2 = tcg_temp_new();
3446 TCGv t3 = tcg_temp_new();
3447 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3448 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3449 tcg_gen_and_tl(t2, t2, t3);
3450 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3451 tcg_gen_or_tl(t2, t2, t3);
3452 tcg_gen_movi_tl(t3, 0);
3453 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3454 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3455 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3456 tcg_temp_free(t3);
3457 tcg_temp_free(t2);
48d38ca5 3458 }
7a387fff
TS
3459 break;
3460 case OPC_DDIVU:
48d38ca5 3461 {
51127181
AJ
3462 TCGv t2 = tcg_const_tl(0);
3463 TCGv t3 = tcg_const_tl(1);
3464 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3465 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3466 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3467 tcg_temp_free(t3);
3468 tcg_temp_free(t2);
48d38ca5 3469 }
7a387fff
TS
3470 break;
3471 case OPC_DMULT:
26135ead 3472 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3473 break;
3474 case OPC_DMULTU:
26135ead 3475 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3476 break;
3477#endif
6af0bf9c 3478 case OPC_MADD:
214c465f 3479 {
d45f89f4
AJ
3480 TCGv_i64 t2 = tcg_temp_new_i64();
3481 TCGv_i64 t3 = tcg_temp_new_i64();
3482
3483 tcg_gen_ext_tl_i64(t2, t0);
3484 tcg_gen_ext_tl_i64(t3, t1);
3485 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3486 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3487 tcg_gen_add_i64(t2, t2, t3);
3488 tcg_temp_free_i64(t3);
71f303cd
RH
3489 gen_move_low32(cpu_LO[acc], t2);
3490 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3491 tcg_temp_free_i64(t2);
214c465f 3492 }
6af0bf9c
FB
3493 break;
3494 case OPC_MADDU:
4133498f 3495 {
d45f89f4
AJ
3496 TCGv_i64 t2 = tcg_temp_new_i64();
3497 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3498
78723684
TS
3499 tcg_gen_ext32u_tl(t0, t0);
3500 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3501 tcg_gen_extu_tl_i64(t2, t0);
3502 tcg_gen_extu_tl_i64(t3, t1);
3503 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3504 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3505 tcg_gen_add_i64(t2, t2, t3);
3506 tcg_temp_free_i64(t3);
71f303cd
RH
3507 gen_move_low32(cpu_LO[acc], t2);
3508 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3509 tcg_temp_free_i64(t2);
214c465f 3510 }
6af0bf9c
FB
3511 break;
3512 case OPC_MSUB:
214c465f 3513 {
d45f89f4
AJ
3514 TCGv_i64 t2 = tcg_temp_new_i64();
3515 TCGv_i64 t3 = tcg_temp_new_i64();
3516
3517 tcg_gen_ext_tl_i64(t2, t0);
3518 tcg_gen_ext_tl_i64(t3, t1);
3519 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3520 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3521 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3522 tcg_temp_free_i64(t3);
71f303cd
RH
3523 gen_move_low32(cpu_LO[acc], t2);
3524 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3525 tcg_temp_free_i64(t2);
214c465f 3526 }
6af0bf9c
FB
3527 break;
3528 case OPC_MSUBU:
214c465f 3529 {
d45f89f4
AJ
3530 TCGv_i64 t2 = tcg_temp_new_i64();
3531 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3532
78723684
TS
3533 tcg_gen_ext32u_tl(t0, t0);
3534 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3535 tcg_gen_extu_tl_i64(t2, t0);
3536 tcg_gen_extu_tl_i64(t3, t1);
3537 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3538 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3539 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3540 tcg_temp_free_i64(t3);
71f303cd
RH
3541 gen_move_low32(cpu_LO[acc], t2);
3542 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3543 tcg_temp_free_i64(t2);
214c465f 3544 }
6af0bf9c
FB
3545 break;
3546 default:
9d68ac14 3547 MIPS_INVAL("mul/div");
9c708c7f 3548 generate_exception_end(ctx, EXCP_RI);
78723684 3549 goto out;
6af0bf9c 3550 }
78723684
TS
3551 out:
3552 tcg_temp_free(t0);
3553 tcg_temp_free(t1);
6af0bf9c
FB
3554}
3555
e9c71dd1
TS
3556static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3557 int rd, int rs, int rt)
3558{
f157bfe1
AJ
3559 TCGv t0 = tcg_temp_new();
3560 TCGv t1 = tcg_temp_new();
e9c71dd1 3561
6c5c1e20
TS
3562 gen_load_gpr(t0, rs);
3563 gen_load_gpr(t1, rt);
e9c71dd1
TS
3564
3565 switch (opc) {
3566 case OPC_VR54XX_MULS:
895c2d04 3567 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3568 break;
e9c71dd1 3569 case OPC_VR54XX_MULSU:
895c2d04 3570 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3571 break;
e9c71dd1 3572 case OPC_VR54XX_MACC:
895c2d04 3573 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3574 break;
e9c71dd1 3575 case OPC_VR54XX_MACCU:
895c2d04 3576 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3577 break;
e9c71dd1 3578 case OPC_VR54XX_MSAC:
895c2d04 3579 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3580 break;
e9c71dd1 3581 case OPC_VR54XX_MSACU:
895c2d04 3582 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3583 break;
e9c71dd1 3584 case OPC_VR54XX_MULHI:
895c2d04 3585 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3586 break;
e9c71dd1 3587 case OPC_VR54XX_MULHIU:
895c2d04 3588 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3589 break;
e9c71dd1 3590 case OPC_VR54XX_MULSHI:
895c2d04 3591 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3592 break;
e9c71dd1 3593 case OPC_VR54XX_MULSHIU:
895c2d04 3594 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3595 break;
e9c71dd1 3596 case OPC_VR54XX_MACCHI:
895c2d04 3597 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3598 break;
e9c71dd1 3599 case OPC_VR54XX_MACCHIU:
895c2d04 3600 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3601 break;
e9c71dd1 3602 case OPC_VR54XX_MSACHI:
895c2d04 3603 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3604 break;
e9c71dd1 3605 case OPC_VR54XX_MSACHIU:
895c2d04 3606 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3607 break;
e9c71dd1
TS
3608 default:
3609 MIPS_INVAL("mul vr54xx");
9c708c7f 3610 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3611 goto out;
e9c71dd1 3612 }
6c5c1e20 3613 gen_store_gpr(t0, rd);
6c5c1e20
TS
3614
3615 out:
3616 tcg_temp_free(t0);
3617 tcg_temp_free(t1);
e9c71dd1
TS
3618}
3619
7a387fff 3620static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3621 int rd, int rs)
3622{
20e1fb52 3623 TCGv t0;
6c5c1e20 3624
6af0bf9c 3625 if (rd == 0) {
ead9360e 3626 /* Treat as NOP. */
20e1fb52 3627 return;
6af0bf9c 3628 }
20e1fb52 3629 t0 = tcg_temp_new();
6c5c1e20 3630 gen_load_gpr(t0, rs);
6af0bf9c
FB
3631 switch (opc) {
3632 case OPC_CLO:
4267d3e6 3633 case R6_OPC_CLO:
20e1fb52 3634 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3635 break;
3636 case OPC_CLZ:
4267d3e6 3637 case R6_OPC_CLZ:
20e1fb52 3638 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c 3639 break;
d26bc211 3640#if defined(TARGET_MIPS64)
7a387fff 3641 case OPC_DCLO:
4267d3e6 3642 case R6_OPC_DCLO:
20e1fb52 3643 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3644 break;
3645 case OPC_DCLZ:
4267d3e6 3646 case R6_OPC_DCLZ:
20e1fb52 3647 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3648 break;
3649#endif
6af0bf9c 3650 }
6c5c1e20 3651 tcg_temp_free(t0);
6af0bf9c
FB
3652}
3653
161f85e6 3654/* Godson integer instructions */
bd277fa1
RH
3655static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3656 int rd, int rs, int rt)
161f85e6 3657{
161f85e6
AJ
3658 TCGv t0, t1;
3659
3660 if (rd == 0) {
3661 /* Treat as NOP. */
161f85e6
AJ
3662 return;
3663 }
3664
3665 switch (opc) {
3666 case OPC_MULT_G_2E:
3667 case OPC_MULT_G_2F:
3668 case OPC_MULTU_G_2E:
3669 case OPC_MULTU_G_2F:
3670#if defined(TARGET_MIPS64)
3671 case OPC_DMULT_G_2E:
3672 case OPC_DMULT_G_2F:
3673 case OPC_DMULTU_G_2E:
3674 case OPC_DMULTU_G_2F:
3675#endif
3676 t0 = tcg_temp_new();
3677 t1 = tcg_temp_new();
3678 break;
3679 default:
3680 t0 = tcg_temp_local_new();
3681 t1 = tcg_temp_local_new();
3682 break;
3683 }
3684
3685 gen_load_gpr(t0, rs);
3686 gen_load_gpr(t1, rt);
3687
3688 switch (opc) {
3689 case OPC_MULT_G_2E:
3690 case OPC_MULT_G_2F:
3691 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3692 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3693 break;
3694 case OPC_MULTU_G_2E:
3695 case OPC_MULTU_G_2F:
3696 tcg_gen_ext32u_tl(t0, t0);
3697 tcg_gen_ext32u_tl(t1, t1);
3698 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3699 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3700 break;
3701 case OPC_DIV_G_2E:
3702 case OPC_DIV_G_2F:
3703 {
42a268c2
RH
3704 TCGLabel *l1 = gen_new_label();
3705 TCGLabel *l2 = gen_new_label();
3706 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3707 tcg_gen_ext32s_tl(t0, t0);
3708 tcg_gen_ext32s_tl(t1, t1);
3709 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3710 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3711 tcg_gen_br(l3);
3712 gen_set_label(l1);
3713 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3714 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3715 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3716 tcg_gen_br(l3);
3717 gen_set_label(l2);
3718 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3719 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3720 gen_set_label(l3);
3721 }
161f85e6
AJ
3722 break;
3723 case OPC_DIVU_G_2E:
3724 case OPC_DIVU_G_2F:
3725 {
42a268c2
RH
3726 TCGLabel *l1 = gen_new_label();
3727 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3728 tcg_gen_ext32u_tl(t0, t0);
3729 tcg_gen_ext32u_tl(t1, t1);
3730 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3731 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3732 tcg_gen_br(l2);
3733 gen_set_label(l1);
3734 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3735 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3736 gen_set_label(l2);
3737 }
161f85e6
AJ
3738 break;
3739 case OPC_MOD_G_2E:
3740 case OPC_MOD_G_2F:
3741 {
42a268c2
RH
3742 TCGLabel *l1 = gen_new_label();
3743 TCGLabel *l2 = gen_new_label();
3744 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3745 tcg_gen_ext32u_tl(t0, t0);
3746 tcg_gen_ext32u_tl(t1, t1);
3747 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3748 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3749 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3750 gen_set_label(l1);
3751 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3752 tcg_gen_br(l3);
3753 gen_set_label(l2);
3754 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3755 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3756 gen_set_label(l3);
3757 }
161f85e6
AJ
3758 break;
3759 case OPC_MODU_G_2E:
3760 case OPC_MODU_G_2F:
3761 {
42a268c2
RH
3762 TCGLabel *l1 = gen_new_label();
3763 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3764 tcg_gen_ext32u_tl(t0, t0);
3765 tcg_gen_ext32u_tl(t1, t1);
3766 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3767 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3768 tcg_gen_br(l2);
3769 gen_set_label(l1);
3770 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3771 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3772 gen_set_label(l2);
3773 }
161f85e6
AJ
3774 break;
3775#if defined(TARGET_MIPS64)
3776 case OPC_DMULT_G_2E:
3777 case OPC_DMULT_G_2F:
3778 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3779 break;
3780 case OPC_DMULTU_G_2E:
3781 case OPC_DMULTU_G_2F:
3782 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3783 break;
3784 case OPC_DDIV_G_2E:
3785 case OPC_DDIV_G_2F:
3786 {
42a268c2
RH
3787 TCGLabel *l1 = gen_new_label();
3788 TCGLabel *l2 = gen_new_label();
3789 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3790 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3791 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3792 tcg_gen_br(l3);
3793 gen_set_label(l1);
3794 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3795 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3796 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3797 tcg_gen_br(l3);
3798 gen_set_label(l2);
3799 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3800 gen_set_label(l3);
3801 }
161f85e6
AJ
3802 break;
3803 case OPC_DDIVU_G_2E:
3804 case OPC_DDIVU_G_2F:
3805 {
42a268c2
RH
3806 TCGLabel *l1 = gen_new_label();
3807 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3808 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3809 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3810 tcg_gen_br(l2);
3811 gen_set_label(l1);
3812 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3813 gen_set_label(l2);
3814 }
161f85e6
AJ
3815 break;
3816 case OPC_DMOD_G_2E:
3817 case OPC_DMOD_G_2F:
3818 {
42a268c2
RH
3819 TCGLabel *l1 = gen_new_label();
3820 TCGLabel *l2 = gen_new_label();
3821 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3822 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3823 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3824 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3825 gen_set_label(l1);
3826 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3827 tcg_gen_br(l3);
3828 gen_set_label(l2);
3829 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3830 gen_set_label(l3);
3831 }
161f85e6
AJ
3832 break;
3833 case OPC_DMODU_G_2E:
3834 case OPC_DMODU_G_2F:
3835 {
42a268c2
RH
3836 TCGLabel *l1 = gen_new_label();
3837 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3838 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3839 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3840 tcg_gen_br(l2);
3841 gen_set_label(l1);
3842 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3843 gen_set_label(l2);
3844 }
161f85e6
AJ
3845 break;
3846#endif
3847 }
3848
161f85e6
AJ
3849 tcg_temp_free(t0);
3850 tcg_temp_free(t1);
3851}
3852
bd277fa1
RH
3853/* Loongson multimedia instructions */
3854static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3855{
bd277fa1
RH
3856 uint32_t opc, shift_max;
3857 TCGv_i64 t0, t1;
3858
3859 opc = MASK_LMI(ctx->opcode);
3860 switch (opc) {
3861 case OPC_ADD_CP2:
3862 case OPC_SUB_CP2:
3863 case OPC_DADD_CP2:
3864 case OPC_DSUB_CP2:
3865 t0 = tcg_temp_local_new_i64();
3866 t1 = tcg_temp_local_new_i64();
3867 break;
3868 default:
3869 t0 = tcg_temp_new_i64();
3870 t1 = tcg_temp_new_i64();
3871 break;
3872 }
3873
3874 gen_load_fpr64(ctx, t0, rs);
3875 gen_load_fpr64(ctx, t1, rt);
3876
3877#define LMI_HELPER(UP, LO) \
9d68ac14 3878 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3879#define LMI_HELPER_1(UP, LO) \
9d68ac14 3880 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3881#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3882 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3883
3884 switch (opc) {
3885 LMI_HELPER(PADDSH, paddsh);
3886 LMI_HELPER(PADDUSH, paddush);
3887 LMI_HELPER(PADDH, paddh);
3888 LMI_HELPER(PADDW, paddw);
3889 LMI_HELPER(PADDSB, paddsb);
3890 LMI_HELPER(PADDUSB, paddusb);
3891 LMI_HELPER(PADDB, paddb);
3892
3893 LMI_HELPER(PSUBSH, psubsh);
3894 LMI_HELPER(PSUBUSH, psubush);
3895 LMI_HELPER(PSUBH, psubh);
3896 LMI_HELPER(PSUBW, psubw);
3897 LMI_HELPER(PSUBSB, psubsb);
3898 LMI_HELPER(PSUBUSB, psubusb);
3899 LMI_HELPER(PSUBB, psubb);
3900
3901 LMI_HELPER(PSHUFH, pshufh);
3902 LMI_HELPER(PACKSSWH, packsswh);
3903 LMI_HELPER(PACKSSHB, packsshb);
3904 LMI_HELPER(PACKUSHB, packushb);
3905
3906 LMI_HELPER(PUNPCKLHW, punpcklhw);
3907 LMI_HELPER(PUNPCKHHW, punpckhhw);
3908 LMI_HELPER(PUNPCKLBH, punpcklbh);
3909 LMI_HELPER(PUNPCKHBH, punpckhbh);
3910 LMI_HELPER(PUNPCKLWD, punpcklwd);
3911 LMI_HELPER(PUNPCKHWD, punpckhwd);
3912
3913 LMI_HELPER(PAVGH, pavgh);
3914 LMI_HELPER(PAVGB, pavgb);
3915 LMI_HELPER(PMAXSH, pmaxsh);
3916 LMI_HELPER(PMINSH, pminsh);
3917 LMI_HELPER(PMAXUB, pmaxub);
3918 LMI_HELPER(PMINUB, pminub);
3919
3920 LMI_HELPER(PCMPEQW, pcmpeqw);
3921 LMI_HELPER(PCMPGTW, pcmpgtw);
3922 LMI_HELPER(PCMPEQH, pcmpeqh);
3923 LMI_HELPER(PCMPGTH, pcmpgth);
3924 LMI_HELPER(PCMPEQB, pcmpeqb);
3925 LMI_HELPER(PCMPGTB, pcmpgtb);
3926
3927 LMI_HELPER(PSLLW, psllw);
3928 LMI_HELPER(PSLLH, psllh);
3929 LMI_HELPER(PSRLW, psrlw);
3930 LMI_HELPER(PSRLH, psrlh);
3931 LMI_HELPER(PSRAW, psraw);
3932 LMI_HELPER(PSRAH, psrah);
3933
3934 LMI_HELPER(PMULLH, pmullh);
3935 LMI_HELPER(PMULHH, pmulhh);
3936 LMI_HELPER(PMULHUH, pmulhuh);
3937 LMI_HELPER(PMADDHW, pmaddhw);
3938
3939 LMI_HELPER(PASUBUB, pasubub);
3940 LMI_HELPER_1(BIADD, biadd);
3941 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3942
3943 LMI_DIRECT(PADDD, paddd, add);
3944 LMI_DIRECT(PSUBD, psubd, sub);
3945 LMI_DIRECT(XOR_CP2, xor, xor);
3946 LMI_DIRECT(NOR_CP2, nor, nor);
3947 LMI_DIRECT(AND_CP2, and, and);
3948 LMI_DIRECT(PANDN, pandn, andc);
3949 LMI_DIRECT(OR, or, or);
3950
3951 case OPC_PINSRH_0:
3952 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3953 break;
3954 case OPC_PINSRH_1:
3955 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3956 break;
3957 case OPC_PINSRH_2:
3958 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3959 break;
3960 case OPC_PINSRH_3:
3961 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3962 break;
3963
3964 case OPC_PEXTRH:
3965 tcg_gen_andi_i64(t1, t1, 3);
3966 tcg_gen_shli_i64(t1, t1, 4);
3967 tcg_gen_shr_i64(t0, t0, t1);
3968 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3969 break;
3970
3971 case OPC_ADDU_CP2:
3972 tcg_gen_add_i64(t0, t0, t1);
3973 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3974 break;
3975 case OPC_SUBU_CP2:
3976 tcg_gen_sub_i64(t0, t0, t1);
3977 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3978 break;
3979
3980 case OPC_SLL_CP2:
bd277fa1
RH
3981 shift_max = 32;
3982 goto do_shift;
3983 case OPC_SRL_CP2:
bd277fa1
RH
3984 shift_max = 32;
3985 goto do_shift;
3986 case OPC_SRA_CP2:
bd277fa1
RH
3987 shift_max = 32;
3988 goto do_shift;
3989 case OPC_DSLL_CP2:
bd277fa1
RH
3990 shift_max = 64;
3991 goto do_shift;
3992 case OPC_DSRL_CP2:
bd277fa1
RH
3993 shift_max = 64;
3994 goto do_shift;
3995 case OPC_DSRA_CP2:
bd277fa1
RH
3996 shift_max = 64;
3997 goto do_shift;
3998 do_shift:
3999 /* Make sure shift count isn't TCG undefined behaviour. */
4000 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4001
4002 switch (opc) {
4003 case OPC_SLL_CP2:
4004 case OPC_DSLL_CP2:
4005 tcg_gen_shl_i64(t0, t0, t1);
4006 break;
4007 case OPC_SRA_CP2:
4008 case OPC_DSRA_CP2:
4009 /* Since SRA is UndefinedResult without sign-extended inputs,
4010 we can treat SRA and DSRA the same. */
4011 tcg_gen_sar_i64(t0, t0, t1);
4012 break;
4013 case OPC_SRL_CP2:
4014 /* We want to shift in zeros for SRL; zero-extend first. */
4015 tcg_gen_ext32u_i64(t0, t0);
4016 /* FALLTHRU */
4017 case OPC_DSRL_CP2:
4018 tcg_gen_shr_i64(t0, t0, t1);
4019 break;
4020 }
4021
4022 if (shift_max == 32) {
4023 tcg_gen_ext32s_i64(t0, t0);
4024 }
4025
4026 /* Shifts larger than MAX produce zero. */
4027 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4028 tcg_gen_neg_i64(t1, t1);
4029 tcg_gen_and_i64(t0, t0, t1);
4030 break;
4031
4032 case OPC_ADD_CP2:
4033 case OPC_DADD_CP2:
4034 {
4035 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4036 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4037
4038 tcg_gen_mov_i64(t2, t0);
4039 tcg_gen_add_i64(t0, t1, t2);
4040 if (opc == OPC_ADD_CP2) {
4041 tcg_gen_ext32s_i64(t0, t0);
4042 }
4043 tcg_gen_xor_i64(t1, t1, t2);
4044 tcg_gen_xor_i64(t2, t2, t0);
4045 tcg_gen_andc_i64(t1, t2, t1);
4046 tcg_temp_free_i64(t2);
4047 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4048 generate_exception(ctx, EXCP_OVERFLOW);
4049 gen_set_label(lab);
bd277fa1
RH
4050 break;
4051 }
4052
4053 case OPC_SUB_CP2:
4054 case OPC_DSUB_CP2:
4055 {
4056 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4057 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4058
4059 tcg_gen_mov_i64(t2, t0);
4060 tcg_gen_sub_i64(t0, t1, t2);
4061 if (opc == OPC_SUB_CP2) {
4062 tcg_gen_ext32s_i64(t0, t0);
4063 }
4064 tcg_gen_xor_i64(t1, t1, t2);
4065 tcg_gen_xor_i64(t2, t2, t0);
4066 tcg_gen_and_i64(t1, t1, t2);
4067 tcg_temp_free_i64(t2);
4068 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4069 generate_exception(ctx, EXCP_OVERFLOW);
4070 gen_set_label(lab);
bd277fa1
RH
4071 break;
4072 }
4073
4074 case OPC_PMULUW:
4075 tcg_gen_ext32u_i64(t0, t0);
4076 tcg_gen_ext32u_i64(t1, t1);
4077 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4078 break;
4079
4080 case OPC_SEQU_CP2:
4081 case OPC_SEQ_CP2:
4082 case OPC_SLTU_CP2:
4083 case OPC_SLT_CP2:
4084 case OPC_SLEU_CP2:
4085 case OPC_SLE_CP2:
4086 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4087 FD field is the CC field? */
4088 default:
9d68ac14 4089 MIPS_INVAL("loongson_cp2");
9c708c7f 4090 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4091 return;
4092 }
4093
4094#undef LMI_HELPER
4095#undef LMI_DIRECT
4096
4097 gen_store_fpr64(ctx, t0, rd);
4098
bd277fa1
RH
4099 tcg_temp_free_i64(t0);
4100 tcg_temp_free_i64(t1);
4101}
4102
6af0bf9c 4103/* Traps */
7a387fff 4104static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4105 int rs, int rt, int16_t imm)
4106{
4107 int cond;
cdc0faa6 4108 TCGv t0 = tcg_temp_new();
1ba74fb8 4109 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4110
4111 cond = 0;
4112 /* Load needed operands */
4113 switch (opc) {
4114 case OPC_TEQ:
4115 case OPC_TGE:
4116 case OPC_TGEU:
4117 case OPC_TLT:
4118 case OPC_TLTU:
4119 case OPC_TNE:
4120 /* Compare two registers */
4121 if (rs != rt) {
be24bb4f
TS
4122 gen_load_gpr(t0, rs);
4123 gen_load_gpr(t1, rt);
6af0bf9c
FB
4124 cond = 1;
4125 }
179e32bb 4126 break;
6af0bf9c
FB
4127 case OPC_TEQI:
4128 case OPC_TGEI:
4129 case OPC_TGEIU:
4130 case OPC_TLTI:
4131 case OPC_TLTIU:
4132 case OPC_TNEI:
4133 /* Compare register to immediate */
4134 if (rs != 0 || imm != 0) {
be24bb4f
TS
4135 gen_load_gpr(t0, rs);
4136 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4137 cond = 1;
4138 }
4139 break;
4140 }
4141 if (cond == 0) {
4142 switch (opc) {
4143 case OPC_TEQ: /* rs == rs */
4144 case OPC_TEQI: /* r0 == 0 */
4145 case OPC_TGE: /* rs >= rs */
4146 case OPC_TGEI: /* r0 >= 0 */
4147 case OPC_TGEU: /* rs >= rs unsigned */
4148 case OPC_TGEIU: /* r0 >= 0 unsigned */
4149 /* Always trap */
9c708c7f 4150 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4151 break;
4152 case OPC_TLT: /* rs < rs */
4153 case OPC_TLTI: /* r0 < 0 */
4154 case OPC_TLTU: /* rs < rs unsigned */
4155 case OPC_TLTIU: /* r0 < 0 unsigned */
4156 case OPC_TNE: /* rs != rs */
4157 case OPC_TNEI: /* r0 != 0 */
ead9360e 4158 /* Never trap: treat as NOP. */
cdc0faa6 4159 break;
6af0bf9c
FB
4160 }
4161 } else {
42a268c2 4162 TCGLabel *l1 = gen_new_label();
cdc0faa6 4163
6af0bf9c
FB
4164 switch (opc) {
4165 case OPC_TEQ:
4166 case OPC_TEQI:
cdc0faa6 4167 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4168 break;
4169 case OPC_TGE:
4170 case OPC_TGEI:
cdc0faa6 4171 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4172 break;
4173 case OPC_TGEU:
4174 case OPC_TGEIU:
cdc0faa6 4175 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4176 break;
4177 case OPC_TLT:
4178 case OPC_TLTI:
cdc0faa6 4179 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4180 break;
4181 case OPC_TLTU:
4182 case OPC_TLTIU:
cdc0faa6 4183 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4184 break;
4185 case OPC_TNE:
4186 case OPC_TNEI:
cdc0faa6 4187 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4188 break;
6af0bf9c 4189 }
cdc0faa6 4190 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4191 gen_set_label(l1);
4192 }
be24bb4f
TS
4193 tcg_temp_free(t0);
4194 tcg_temp_free(t1);
6af0bf9c
FB
4195}
4196
90aa39a1
SF
4197static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4198{
4199 if (unlikely(ctx->singlestep_enabled)) {
4200 return false;
4201 }
4202
4203#ifndef CONFIG_USER_ONLY
4204 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4205#else
4206 return true;
4207#endif
4208}
4209
356265ae 4210static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4211{
90aa39a1 4212 if (use_goto_tb(ctx, dest)) {
57fec1fe 4213 tcg_gen_goto_tb(n);
9b9e4393 4214 gen_save_pc(dest);
90aa39a1 4215 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
6e256c93 4216 } else {
9b9e4393 4217 gen_save_pc(dest);
7b270ef2
NF
4218 if (ctx->singlestep_enabled) {
4219 save_cpu_state(ctx, 0);
9c708c7f 4220 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4221 }
57fec1fe 4222 tcg_gen_exit_tb(0);
6e256c93 4223 }
c53be334
FB
4224}
4225
6af0bf9c 4226/* Branches (before delay slot) */
7a387fff 4227static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4228 int insn_bytes,
b231c103
YK
4229 int rs, int rt, int32_t offset,
4230 int delayslot_size)
6af0bf9c 4231{
d077b6f7 4232 target_ulong btgt = -1;
3ad4bb2d 4233 int blink = 0;
2fdbad25 4234 int bcond_compute = 0;
1ba74fb8
AJ
4235 TCGv t0 = tcg_temp_new();
4236 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4237
4238 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4239#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4240 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4241 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4242#endif
9c708c7f 4243 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4244 goto out;
3ad4bb2d 4245 }
6af0bf9c 4246
6af0bf9c
FB
4247 /* Load needed operands */
4248 switch (opc) {
4249 case OPC_BEQ:
4250 case OPC_BEQL:
4251 case OPC_BNE:
4252 case OPC_BNEL:
4253 /* Compare two registers */
4254 if (rs != rt) {
6c5c1e20
TS
4255 gen_load_gpr(t0, rs);
4256 gen_load_gpr(t1, rt);
2fdbad25 4257 bcond_compute = 1;
6af0bf9c 4258 }
7dca4ad0 4259 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4260 break;
4261 case OPC_BGEZ:
4262 case OPC_BGEZAL:
4263 case OPC_BGEZALL:
4264 case OPC_BGEZL:
4265 case OPC_BGTZ:
4266 case OPC_BGTZL:
4267 case OPC_BLEZ:
4268 case OPC_BLEZL:
4269 case OPC_BLTZ:
4270 case OPC_BLTZAL:
4271 case OPC_BLTZALL:
4272 case OPC_BLTZL:
4273 /* Compare to zero */
4274 if (rs != 0) {
6c5c1e20 4275 gen_load_gpr(t0, rs);
2fdbad25 4276 bcond_compute = 1;
6af0bf9c 4277 }
7dca4ad0 4278 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4279 break;
e45a93e2
JL
4280 case OPC_BPOSGE32:
4281#if defined(TARGET_MIPS64)
4282 case OPC_BPOSGE64:
4283 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4284#else
4285 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4286#endif
4287 bcond_compute = 1;
4288 btgt = ctx->pc + insn_bytes + offset;
4289 break;
6af0bf9c
FB
4290 case OPC_J:
4291 case OPC_JAL:
364d4831 4292 case OPC_JALX:
6af0bf9c 4293 /* Jump to immediate */
7dca4ad0 4294 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4295 break;
4296 case OPC_JR:
4297 case OPC_JALR:
4298 /* Jump to register */
7a387fff
TS
4299 if (offset != 0 && offset != 16) {
4300 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4301 others are reserved. */
923617a3 4302 MIPS_INVAL("jump hint");
9c708c7f 4303 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4304 goto out;
6af0bf9c 4305 }
d077b6f7 4306 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4307 break;
4308 default:
4309 MIPS_INVAL("branch/jump");
9c708c7f 4310 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4311 goto out;
6af0bf9c 4312 }
2fdbad25 4313 if (bcond_compute == 0) {
6af0bf9c
FB
4314 /* No condition to be computed */
4315 switch (opc) {
4316 case OPC_BEQ: /* rx == rx */
4317 case OPC_BEQL: /* rx == rx likely */
4318 case OPC_BGEZ: /* 0 >= 0 */
4319 case OPC_BGEZL: /* 0 >= 0 likely */
4320 case OPC_BLEZ: /* 0 <= 0 */
4321 case OPC_BLEZL: /* 0 <= 0 likely */
4322 /* Always take */
4ad40f36 4323 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4324 break;
4325 case OPC_BGEZAL: /* 0 >= 0 */
4326 case OPC_BGEZALL: /* 0 >= 0 likely */
4327 /* Always take and link */
4328 blink = 31;
4ad40f36 4329 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4330 break;
4331 case OPC_BNE: /* rx != rx */
4332 case OPC_BGTZ: /* 0 > 0 */
4333 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4334 /* Treat as NOP. */
6c5c1e20 4335 goto out;
eeef26cd 4336 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4337 /* Handle as an unconditional branch to get correct delay
4338 slot checking. */
4339 blink = 31;
b231c103 4340 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4341 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4342 break;
eeef26cd 4343 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4344 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4345 /* Skip the instruction in the delay slot */
9898128f 4346 ctx->pc += 4;
6c5c1e20 4347 goto out;
6af0bf9c
FB
4348 case OPC_BNEL: /* rx != rx likely */
4349 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4350 case OPC_BLTZL: /* 0 < 0 likely */
4351 /* Skip the instruction in the delay slot */
9898128f 4352 ctx->pc += 4;
6c5c1e20 4353 goto out;
6af0bf9c 4354 case OPC_J:
4ad40f36 4355 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4356 break;
364d4831
NF
4357 case OPC_JALX:
4358 ctx->hflags |= MIPS_HFLAG_BX;
4359 /* Fallthrough */
6af0bf9c
FB
4360 case OPC_JAL:
4361 blink = 31;
4ad40f36 4362 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4363 break;
4364 case OPC_JR:
4ad40f36 4365 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4366 break;
4367 case OPC_JALR:
4368 blink = rt;
4ad40f36 4369 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4370 break;
4371 default:
4372 MIPS_INVAL("branch/jump");
9c708c7f 4373 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4374 goto out;
6af0bf9c
FB
4375 }
4376 } else {
4377 switch (opc) {
4378 case OPC_BEQ:
e68dd28f 4379 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4380 goto not_likely;
4381 case OPC_BEQL:
e68dd28f 4382 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4383 goto likely;
4384 case OPC_BNE:
e68dd28f 4385 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4386 goto not_likely;
4387 case OPC_BNEL:
e68dd28f 4388 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4389 goto likely;
4390 case OPC_BGEZ:
e68dd28f 4391 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4392 goto not_likely;
4393 case OPC_BGEZL:
e68dd28f 4394 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4395 goto likely;
4396 case OPC_BGEZAL:
e68dd28f 4397 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4398 blink = 31;
4399 goto not_likely;
4400 case OPC_BGEZALL:
e68dd28f 4401 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4402 blink = 31;
6af0bf9c
FB
4403 goto likely;
4404 case OPC_BGTZ:
e68dd28f 4405 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4406 goto not_likely;
4407 case OPC_BGTZL:
e68dd28f 4408 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4409 goto likely;
4410 case OPC_BLEZ:
e68dd28f 4411 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4412 goto not_likely;
4413 case OPC_BLEZL:
e68dd28f 4414 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4415 goto likely;
4416 case OPC_BLTZ:
e68dd28f 4417 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4418 goto not_likely;
4419 case OPC_BLTZL:
e68dd28f 4420 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4421 goto likely;
e45a93e2
JL
4422 case OPC_BPOSGE32:
4423 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4424 goto not_likely;
4425#if defined(TARGET_MIPS64)
4426 case OPC_BPOSGE64:
4427 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4428 goto not_likely;
4429#endif
6af0bf9c 4430 case OPC_BLTZAL:
e68dd28f 4431 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4432 blink = 31;
6af0bf9c 4433 not_likely:
4ad40f36 4434 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4435 break;
4436 case OPC_BLTZALL:
e68dd28f 4437 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4438 blink = 31;
6af0bf9c 4439 likely:
4ad40f36 4440 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4441 break;
c53f4a62
TS
4442 default:
4443 MIPS_INVAL("conditional branch/jump");
9c708c7f 4444 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4445 goto out;
6af0bf9c 4446 }
6af0bf9c 4447 }
9b9e4393 4448
d077b6f7 4449 ctx->btarget = btgt;
b231c103
YK
4450
4451 switch (delayslot_size) {
4452 case 2:
4453 ctx->hflags |= MIPS_HFLAG_BDS16;
4454 break;
4455 case 4:
4456 ctx->hflags |= MIPS_HFLAG_BDS32;
4457 break;
4458 }
4459
6af0bf9c 4460 if (blink > 0) {
b231c103 4461 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4462 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4463
364d4831 4464 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4465 }
6c5c1e20
TS
4466
4467 out:
364d4831
NF
4468 if (insn_bytes == 2)
4469 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4470 tcg_temp_free(t0);
4471 tcg_temp_free(t1);
6af0bf9c
FB
4472}
4473
7a387fff
TS
4474/* special3 bitfield operations */
4475static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4476 int rs, int lsb, int msb)
7a387fff 4477{
a7812ae4
PB
4478 TCGv t0 = tcg_temp_new();
4479 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4480
4481 gen_load_gpr(t1, rs);
7a387fff
TS
4482 switch (opc) {
4483 case OPC_EXT:
b7f26e52 4484 if (lsb + msb > 31) {
7a387fff 4485 goto fail;
b7f26e52 4486 }
505ad7c2
AJ
4487 tcg_gen_shri_tl(t0, t1, lsb);
4488 if (msb != 31) {
b7f26e52 4489 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
505ad7c2
AJ
4490 } else {
4491 tcg_gen_ext32s_tl(t0, t0);
4492 }
7a387fff 4493 break;
c6d6dd7c 4494#if defined(TARGET_MIPS64)
7a387fff 4495 case OPC_DEXTU:
b7f26e52
RH
4496 lsb += 32;
4497 goto do_dext;
4498 case OPC_DEXTM:
4499 msb += 32;
4500 goto do_dext;
7a387fff 4501 case OPC_DEXT:
b7f26e52
RH
4502 do_dext:
4503 if (lsb + msb > 63) {
4504 goto fail;
4505 }
505ad7c2 4506 tcg_gen_shri_tl(t0, t1, lsb);
b7f26e52
RH
4507 if (msb != 63) {
4508 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4509 }
7a387fff 4510 break;
c6d6dd7c 4511#endif
7a387fff 4512 case OPC_INS:
b7f26e52 4513 if (lsb > msb) {
7a387fff 4514 goto fail;
b7f26e52 4515 }
6c5c1e20 4516 gen_load_gpr(t0, rt);
e0d002f1 4517 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4518 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4519 break;
c6d6dd7c 4520#if defined(TARGET_MIPS64)
7a387fff 4521 case OPC_DINSU:
b7f26e52
RH
4522 lsb += 32;
4523 /* FALLTHRU */
4524 case OPC_DINSM:
4525 msb += 32;
4526 /* FALLTHRU */
7a387fff 4527 case OPC_DINS:
b7f26e52
RH
4528 if (lsb > msb) {
4529 goto fail;
4530 }
6c5c1e20 4531 gen_load_gpr(t0, rt);
e0d002f1 4532 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4533 break;
c6d6dd7c 4534#endif
7a387fff
TS
4535 default:
4536fail:
4537 MIPS_INVAL("bitops");
9c708c7f 4538 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4539 tcg_temp_free(t0);
4540 tcg_temp_free(t1);
7a387fff
TS
4541 return;
4542 }
6c5c1e20
TS
4543 gen_store_gpr(t0, rt);
4544 tcg_temp_free(t0);
4545 tcg_temp_free(t1);
7a387fff
TS
4546}
4547
49bcf33c
AJ
4548static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4549{
3a55fa47 4550 TCGv t0;
49bcf33c 4551
3a55fa47
AJ
4552 if (rd == 0) {
4553 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4554 return;
4555 }
4556
4557 t0 = tcg_temp_new();
4558 gen_load_gpr(t0, rt);
49bcf33c
AJ
4559 switch (op2) {
4560 case OPC_WSBH:
3a55fa47
AJ
4561 {
4562 TCGv t1 = tcg_temp_new();
4563
4564 tcg_gen_shri_tl(t1, t0, 8);
4565 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4566 tcg_gen_shli_tl(t0, t0, 8);
4567 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4568 tcg_gen_or_tl(t0, t0, t1);
4569 tcg_temp_free(t1);
4570 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4571 }
49bcf33c
AJ
4572 break;
4573 case OPC_SEB:
3a55fa47 4574 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4575 break;
4576 case OPC_SEH:
3a55fa47 4577 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4578 break;
4579#if defined(TARGET_MIPS64)
4580 case OPC_DSBH:
3a55fa47
AJ
4581 {
4582 TCGv t1 = tcg_temp_new();
4583
4584 tcg_gen_shri_tl(t1, t0, 8);
4585 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4586 tcg_gen_shli_tl(t0, t0, 8);
4587 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4588 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4589 tcg_temp_free(t1);
4590 }
49bcf33c
AJ
4591 break;
4592 case OPC_DSHD:
3a55fa47
AJ
4593 {
4594 TCGv t1 = tcg_temp_new();
4595
4596 tcg_gen_shri_tl(t1, t0, 16);
4597 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4598 tcg_gen_shli_tl(t0, t0, 16);
4599 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4600 tcg_gen_or_tl(t0, t0, t1);
4601 tcg_gen_shri_tl(t1, t0, 32);
4602 tcg_gen_shli_tl(t0, t0, 32);
4603 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4604 tcg_temp_free(t1);
4605 }
49bcf33c
AJ
4606 break;
4607#endif
4608 default:
4609 MIPS_INVAL("bsfhl");
9c708c7f 4610 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4611 tcg_temp_free(t0);
49bcf33c
AJ
4612 return;
4613 }
49bcf33c 4614 tcg_temp_free(t0);
49bcf33c
AJ
4615}
4616
1f1b4c00
YK
4617static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4618 int imm2)
4619{
4620 TCGv t0;
4621 TCGv t1;
4622 if (rd == 0) {
4623 /* Treat as NOP. */
4624 return;
4625 }
4626 t0 = tcg_temp_new();
4627 t1 = tcg_temp_new();
4628 gen_load_gpr(t0, rs);
4629 gen_load_gpr(t1, rt);
4630 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4631 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4632 if (opc == OPC_LSA) {
4633 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4634 }
4635
4636 tcg_temp_free(t1);
4637 tcg_temp_free(t0);
4638
4639 return;
4640}
4641
4642static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4643 int bp)
284b731a 4644{
1f1b4c00
YK
4645 TCGv t0;
4646 if (rd == 0) {
4647 /* Treat as NOP. */
4648 return;
4649 }
4650 t0 = tcg_temp_new();
4651 gen_load_gpr(t0, rt);
4652 if (bp == 0) {
51243852
MD
4653 switch (opc) {
4654 case OPC_ALIGN:
4655 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4656 break;
4657#if defined(TARGET_MIPS64)
4658 case OPC_DALIGN:
4659 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4660 break;
4661#endif
4662 }
1f1b4c00
YK
4663 } else {
4664 TCGv t1 = tcg_temp_new();
4665 gen_load_gpr(t1, rs);
4666 switch (opc) {
4667 case OPC_ALIGN:
4668 {
4669 TCGv_i64 t2 = tcg_temp_new_i64();
4670 tcg_gen_concat_tl_i64(t2, t1, t0);
4671 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4672 gen_move_low32(cpu_gpr[rd], t2);
4673 tcg_temp_free_i64(t2);
4674 }
4675 break;
284b731a 4676#if defined(TARGET_MIPS64)
1f1b4c00
YK
4677 case OPC_DALIGN:
4678 tcg_gen_shli_tl(t0, t0, 8 * bp);
4679 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4680 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4681 break;
284b731a 4682#endif
1f1b4c00
YK
4683 }
4684 tcg_temp_free(t1);
4685 }
4686
4687 tcg_temp_free(t0);
4688}
4689
4690static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4691{
4692 TCGv t0;
4693 if (rd == 0) {
4694 /* Treat as NOP. */
4695 return;
4696 }
4697 t0 = tcg_temp_new();
4698 gen_load_gpr(t0, rt);
4699 switch (opc) {
4700 case OPC_BITSWAP:
4701 gen_helper_bitswap(cpu_gpr[rd], t0);
4702 break;
4703#if defined(TARGET_MIPS64)
4704 case OPC_DBITSWAP:
4705 gen_helper_dbitswap(cpu_gpr[rd], t0);
4706 break;
4707#endif
4708 }
4709 tcg_temp_free(t0);
284b731a
LA
4710}
4711
1f1b4c00
YK
4712#ifndef CONFIG_USER_ONLY
4713/* CP0 (MMU and control) */
5204ea79
LA
4714static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4715{
4716 TCGv_i64 t0 = tcg_temp_new_i64();
4717 TCGv_i64 t1 = tcg_temp_new_i64();
4718
4719 tcg_gen_ext_tl_i64(t0, arg);
4720 tcg_gen_ld_i64(t1, cpu_env, off);
4721#if defined(TARGET_MIPS64)
4722 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4723#else
4724 tcg_gen_concat32_i64(t1, t1, t0);
4725#endif
4726 tcg_gen_st_i64(t1, cpu_env, off);
4727 tcg_temp_free_i64(t1);
4728 tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4732{
4733 TCGv_i64 t0 = tcg_temp_new_i64();
4734 TCGv_i64 t1 = tcg_temp_new_i64();
4735
4736 tcg_gen_ext_tl_i64(t0, arg);
4737 tcg_gen_ld_i64(t1, cpu_env, off);
4738 tcg_gen_concat32_i64(t1, t1, t0);
4739 tcg_gen_st_i64(t1, cpu_env, off);
4740 tcg_temp_free_i64(t1);
4741 tcg_temp_free_i64(t0);
4742}
4743
4744static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4745{
4746 TCGv_i64 t0 = tcg_temp_new_i64();
4747
4748 tcg_gen_ld_i64(t0, cpu_env, off);
4749#if defined(TARGET_MIPS64)
4750 tcg_gen_shri_i64(t0, t0, 30);
4751#else
4752 tcg_gen_shri_i64(t0, t0, 32);
4753#endif
4754 gen_move_low32(arg, t0);
4755 tcg_temp_free_i64(t0);
4756}
4757
4758static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4759{
4760 TCGv_i64 t0 = tcg_temp_new_i64();
4761
4762 tcg_gen_ld_i64(t0, cpu_env, off);
4763 tcg_gen_shri_i64(t0, t0, 32 + shift);
4764 gen_move_low32(arg, t0);
4765 tcg_temp_free_i64(t0);
4766}
4767
d9bea114 4768static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4769{
d9bea114 4770 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4771
d9bea114
AJ
4772 tcg_gen_ld_i32(t0, cpu_env, off);
4773 tcg_gen_ext_i32_tl(arg, t0);
4774 tcg_temp_free_i32(t0);
4f57689a
TS
4775}
4776
d9bea114 4777static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4778{
d9bea114
AJ
4779 tcg_gen_ld_tl(arg, cpu_env, off);
4780 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4781}
4782
d9bea114 4783static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4784{
d9bea114 4785 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4786
d9bea114
AJ
4787 tcg_gen_trunc_tl_i32(t0, arg);
4788 tcg_gen_st_i32(t0, cpu_env, off);
4789 tcg_temp_free_i32(t0);
f1aa6320
TS
4790}
4791
c98d3d79
YK
4792#define CP0_CHECK(c) \
4793 do { \
4794 if (!(c)) { \
4795 goto cp0_unimplemented; \
4796 } \
4797 } while (0)
4798
5204ea79
LA
4799static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4800{
4801 const char *rn = "invalid";
4802
c98d3d79 4803 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4804
4805 switch (reg) {
4806 case 2:
4807 switch (sel) {
4808 case 0:
4809 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4810 rn = "EntryLo0";
4811 break;
4812 default:
c98d3d79 4813 goto cp0_unimplemented;
5204ea79
LA
4814 }
4815 break;
4816 case 3:
4817 switch (sel) {
4818 case 0:
4819 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4820 rn = "EntryLo1";
4821 break;
4822 default:
c98d3d79 4823 goto cp0_unimplemented;
5204ea79
LA
4824 }
4825 break;
4826 case 17:
4827 switch (sel) {
4828 case 0:
4829 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4830 ctx->CP0_LLAddr_shift);
4831 rn = "LLAddr";
4832 break;
f6d4dd81
YK
4833 case 1:
4834 CP0_CHECK(ctx->mrp);
4835 gen_helper_mfhc0_maar(arg, cpu_env);
4836 rn = "MAAR";
4837 break;
5204ea79 4838 default:
c98d3d79 4839 goto cp0_unimplemented;
5204ea79
LA
4840 }
4841 break;
4842 case 28:
4843 switch (sel) {
4844 case 0:
4845 case 2:
4846 case 4:
4847 case 6:
4848 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4849 rn = "TagLo";
4850 break;
4851 default:
c98d3d79 4852 goto cp0_unimplemented;
5204ea79
LA
4853 }
4854 break;
4855 default:
c98d3d79 4856 goto cp0_unimplemented;
5204ea79
LA
4857 }
4858
4859 (void)rn; /* avoid a compiler warning */
4860 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4861 return;
4862
c98d3d79 4863cp0_unimplemented:
5204ea79
LA
4864 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4865 tcg_gen_movi_tl(arg, 0);
4866}
4867
4868static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4869{
4870 const char *rn = "invalid";
4871 uint64_t mask = ctx->PAMask >> 36;
4872
c98d3d79 4873 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4874
4875 switch (reg) {
4876 case 2:
4877 switch (sel) {
4878 case 0:
4879 tcg_gen_andi_tl(arg, arg, mask);
4880 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4881 rn = "EntryLo0";
4882 break;
4883 default:
c98d3d79 4884 goto cp0_unimplemented;
5204ea79
LA
4885 }
4886 break;
4887 case 3:
4888 switch (sel) {
4889 case 0:
4890 tcg_gen_andi_tl(arg, arg, mask);
4891 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4892 rn = "EntryLo1";
4893 break;
4894 default:
c98d3d79 4895 goto cp0_unimplemented;
5204ea79
LA
4896 }
4897 break;
4898 case 17:
4899 switch (sel) {
4900 case 0:
4901 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4902 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4903 relevant for modern MIPS cores supporting MTHC0, therefore
4904 treating MTHC0 to LLAddr as NOP. */
4905 rn = "LLAddr";
4906 break;
f6d4dd81
YK
4907 case 1:
4908 CP0_CHECK(ctx->mrp);
4909 gen_helper_mthc0_maar(cpu_env, arg);
4910 rn = "MAAR";
4911 break;
5204ea79 4912 default:
c98d3d79 4913 goto cp0_unimplemented;
5204ea79
LA
4914 }
4915 break;
4916 case 28:
4917 switch (sel) {
4918 case 0:
4919 case 2:
4920 case 4:
4921 case 6:
4922 tcg_gen_andi_tl(arg, arg, mask);
4923 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4924 rn = "TagLo";
4925 break;
4926 default:
c98d3d79 4927 goto cp0_unimplemented;
5204ea79
LA
4928 }
4929 break;
4930 default:
c98d3d79 4931 goto cp0_unimplemented;
5204ea79
LA
4932 }
4933
4934 (void)rn; /* avoid a compiler warning */
c98d3d79 4935cp0_unimplemented:
5204ea79
LA
4936 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4937}
4938
e98c0d17
LA
4939static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4940{
4941 if (ctx->insn_flags & ISA_MIPS32R6) {
4942 tcg_gen_movi_tl(arg, 0);
4943 } else {
4944 tcg_gen_movi_tl(arg, ~0);
4945 }
4946}
4947
d75c135e 4948static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4949{
7a387fff 4950 const char *rn = "invalid";
873eb012 4951
e189e748 4952 if (sel != 0)
d75c135e 4953 check_insn(ctx, ISA_MIPS32);
e189e748 4954
873eb012
TS
4955 switch (reg) {
4956 case 0:
7a387fff
TS
4957 switch (sel) {
4958 case 0:
7db13fae 4959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4960 rn = "Index";
4961 break;
4962 case 1:
f31b035a 4963 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4964 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4965 rn = "MVPControl";
ead9360e 4966 break;
7a387fff 4967 case 2:
f31b035a 4968 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4969 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4970 rn = "MVPConf0";
ead9360e 4971 break;
7a387fff 4972 case 3:
f31b035a 4973 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4974 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4975 rn = "MVPConf1";
ead9360e 4976 break;
01bc435b
YK
4977 case 4:
4978 CP0_CHECK(ctx->vp);
4979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4980 rn = "VPControl";
4981 break;
7a387fff 4982 default:
f31b035a 4983 goto cp0_unimplemented;
7a387fff 4984 }
873eb012
TS
4985 break;
4986 case 1:
7a387fff
TS
4987 switch (sel) {
4988 case 0:
f31b035a 4989 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4990 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4991 rn = "Random";
2423f660 4992 break;
7a387fff 4993 case 1:
f31b035a 4994 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4996 rn = "VPEControl";
ead9360e 4997 break;
7a387fff 4998 case 2:
f31b035a 4999 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5000 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5001 rn = "VPEConf0";
ead9360e 5002 break;
7a387fff 5003 case 3:
f31b035a 5004 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5006 rn = "VPEConf1";
ead9360e 5007 break;
7a387fff 5008 case 4:
f31b035a 5009 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5010 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5011 rn = "YQMask";
ead9360e 5012 break;
7a387fff 5013 case 5:
f31b035a 5014 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5015 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5016 rn = "VPESchedule";
ead9360e 5017 break;
7a387fff 5018 case 6:
f31b035a 5019 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5020 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5021 rn = "VPEScheFBack";
ead9360e 5022 break;
7a387fff 5023 case 7:
f31b035a 5024 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5026 rn = "VPEOpt";
ead9360e 5027 break;
7a387fff 5028 default:
f31b035a 5029 goto cp0_unimplemented;
7a387fff 5030 }
873eb012
TS
5031 break;
5032 case 2:
7a387fff
TS
5033 switch (sel) {
5034 case 0:
284b731a
LA
5035 {
5036 TCGv_i64 tmp = tcg_temp_new_i64();
5037 tcg_gen_ld_i64(tmp, cpu_env,
5038 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5039#if defined(TARGET_MIPS64)
284b731a
LA
5040 if (ctx->rxi) {
5041 /* Move RI/XI fields to bits 31:30 */
5042 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5043 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5044 }
7207c7f9 5045#endif
284b731a
LA
5046 gen_move_low32(arg, tmp);
5047 tcg_temp_free_i64(tmp);
5048 }
2423f660
TS
5049 rn = "EntryLo0";
5050 break;
7a387fff 5051 case 1:
f31b035a 5052 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5053 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5054 rn = "TCStatus";
ead9360e 5055 break;
7a387fff 5056 case 2:
f31b035a 5057 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5058 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5059 rn = "TCBind";
ead9360e 5060 break;
7a387fff 5061 case 3:
f31b035a 5062 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5063 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5064 rn = "TCRestart";
ead9360e 5065 break;
7a387fff 5066 case 4:
f31b035a 5067 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5068 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5069 rn = "TCHalt";
ead9360e 5070 break;
7a387fff 5071 case 5:
f31b035a 5072 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5073 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5074 rn = "TCContext";
ead9360e 5075 break;
7a387fff 5076 case 6:
f31b035a 5077 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5078 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5079 rn = "TCSchedule";
ead9360e 5080 break;
7a387fff 5081 case 7:
f31b035a 5082 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5083 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5084 rn = "TCScheFBack";
ead9360e 5085 break;
7a387fff 5086 default:
f31b035a 5087 goto cp0_unimplemented;
7a387fff 5088 }
873eb012
TS
5089 break;
5090 case 3:
7a387fff
TS
5091 switch (sel) {
5092 case 0:
284b731a
LA
5093 {
5094 TCGv_i64 tmp = tcg_temp_new_i64();
5095 tcg_gen_ld_i64(tmp, cpu_env,
5096 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5097#if defined(TARGET_MIPS64)
284b731a
LA
5098 if (ctx->rxi) {
5099 /* Move RI/XI fields to bits 31:30 */
5100 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5101 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5102 }
7207c7f9 5103#endif
284b731a
LA
5104 gen_move_low32(arg, tmp);
5105 tcg_temp_free_i64(tmp);
5106 }
2423f660
TS
5107 rn = "EntryLo1";
5108 break;
01bc435b
YK
5109 case 1:
5110 CP0_CHECK(ctx->vp);
5111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5112 rn = "GlobalNumber";
5113 break;
7a387fff 5114 default:
f31b035a 5115 goto cp0_unimplemented;
1579a72e 5116 }
873eb012
TS
5117 break;
5118 case 4:
7a387fff
TS
5119 switch (sel) {
5120 case 0:
7db13fae 5121 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5122 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5123 rn = "Context";
5124 break;
7a387fff 5125 case 1:
d9bea114 5126// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5127 rn = "ContextConfig";
f31b035a 5128 goto cp0_unimplemented;
2423f660 5129// break;
d279279e 5130 case 2:
f31b035a
LA
5131 CP0_CHECK(ctx->ulri);
5132 tcg_gen_ld32s_tl(arg, cpu_env,
5133 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5134 rn = "UserLocal";
d279279e 5135 break;
7a387fff 5136 default:
f31b035a 5137 goto cp0_unimplemented;
1579a72e 5138 }
873eb012
TS
5139 break;
5140 case 5:
7a387fff
TS
5141 switch (sel) {
5142 case 0:
7db13fae 5143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5144 rn = "PageMask";
5145 break;
7a387fff 5146 case 1:
d75c135e 5147 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5149 rn = "PageGrain";
5150 break;
7a387fff 5151 default:
f31b035a 5152 goto cp0_unimplemented;
1579a72e 5153 }
873eb012
TS
5154 break;
5155 case 6:
7a387fff
TS
5156 switch (sel) {
5157 case 0:
7db13fae 5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5159 rn = "Wired";
5160 break;
7a387fff 5161 case 1:
d75c135e 5162 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5164 rn = "SRSConf0";
ead9360e 5165 break;
7a387fff 5166 case 2:
d75c135e 5167 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5169 rn = "SRSConf1";
ead9360e 5170 break;
7a387fff 5171 case 3:
d75c135e 5172 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5174 rn = "SRSConf2";
ead9360e 5175 break;
7a387fff 5176 case 4:
d75c135e 5177 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5179 rn = "SRSConf3";
ead9360e 5180 break;
7a387fff 5181 case 5:
d75c135e 5182 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5184 rn = "SRSConf4";
ead9360e 5185 break;
7a387fff 5186 default:
f31b035a 5187 goto cp0_unimplemented;
1579a72e 5188 }
873eb012 5189 break;
8c0fdd85 5190 case 7:
7a387fff
TS
5191 switch (sel) {
5192 case 0:
d75c135e 5193 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5195 rn = "HWREna";
5196 break;
7a387fff 5197 default:
f31b035a 5198 goto cp0_unimplemented;
1579a72e 5199 }
8c0fdd85 5200 break;
873eb012 5201 case 8:
7a387fff
TS
5202 switch (sel) {
5203 case 0:
7db13fae 5204 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5205 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5206 rn = "BadVAddr";
2423f660 5207 break;
aea14095 5208 case 1:
f31b035a
LA
5209 CP0_CHECK(ctx->bi);
5210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5211 rn = "BadInstr";
aea14095
LA
5212 break;
5213 case 2:
f31b035a
LA
5214 CP0_CHECK(ctx->bp);
5215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5216 rn = "BadInstrP";
aea14095 5217 break;
7a387fff 5218 default:
f31b035a 5219 goto cp0_unimplemented;
aea14095 5220 }
873eb012
TS
5221 break;
5222 case 9:
7a387fff
TS
5223 switch (sel) {
5224 case 0:
2e70f6ef 5225 /* Mark as an IO operation because we read the time. */
bd79255d 5226 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5227 gen_io_start();
bd79255d 5228 }
895c2d04 5229 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5230 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5231 gen_io_end();
2e70f6ef 5232 }
55807224
EI
5233 /* Break the TB to be able to take timer interrupts immediately
5234 after reading count. */
5235 ctx->bstate = BS_STOP;
2423f660
TS
5236 rn = "Count";
5237 break;
5238 /* 6,7 are implementation dependent */
7a387fff 5239 default:
f31b035a 5240 goto cp0_unimplemented;
2423f660 5241 }
873eb012
TS
5242 break;
5243 case 10:
7a387fff
TS
5244 switch (sel) {
5245 case 0:
7db13fae 5246 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5247 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5248 rn = "EntryHi";
5249 break;
7a387fff 5250 default:
f31b035a 5251 goto cp0_unimplemented;
1579a72e 5252 }
873eb012
TS
5253 break;
5254 case 11:
7a387fff
TS
5255 switch (sel) {
5256 case 0:
7db13fae 5257 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5258 rn = "Compare";
5259 break;
5260 /* 6,7 are implementation dependent */
7a387fff 5261 default:
f31b035a 5262 goto cp0_unimplemented;
2423f660 5263 }
873eb012
TS
5264 break;
5265 case 12:
7a387fff
TS
5266 switch (sel) {
5267 case 0:
7db13fae 5268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5269 rn = "Status";
5270 break;
7a387fff 5271 case 1:
d75c135e 5272 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5274 rn = "IntCtl";
5275 break;
7a387fff 5276 case 2:
d75c135e 5277 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5279 rn = "SRSCtl";
5280 break;
7a387fff 5281 case 3:
d75c135e 5282 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5284 rn = "SRSMap";
fd88b6ab 5285 break;
7a387fff 5286 default:
f31b035a 5287 goto cp0_unimplemented;
7a387fff 5288 }
873eb012
TS
5289 break;
5290 case 13:
7a387fff
TS
5291 switch (sel) {
5292 case 0:
7db13fae 5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5294 rn = "Cause";
5295 break;
7a387fff 5296 default:
f31b035a 5297 goto cp0_unimplemented;
7a387fff 5298 }
873eb012
TS
5299 break;
5300 case 14:
7a387fff
TS
5301 switch (sel) {
5302 case 0:
7db13fae 5303 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5304 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5305 rn = "EPC";
5306 break;
7a387fff 5307 default:
f31b035a 5308 goto cp0_unimplemented;
1579a72e 5309 }
873eb012
TS
5310 break;
5311 case 15:
7a387fff
TS
5312 switch (sel) {
5313 case 0:
7db13fae 5314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5315 rn = "PRid";
5316 break;
7a387fff 5317 case 1:
d75c135e 5318 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5320 rn = "EBase";
5321 break;
c870e3f5
YK
5322 case 3:
5323 check_insn(ctx, ISA_MIPS32R2);
5324 CP0_CHECK(ctx->cmgcr);
5325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5326 tcg_gen_ext32s_tl(arg, arg);
5327 rn = "CMGCRBase";
5328 break;
7a387fff 5329 default:
f31b035a 5330 goto cp0_unimplemented;
7a387fff 5331 }
873eb012
TS
5332 break;
5333 case 16:
5334 switch (sel) {
5335 case 0:
7db13fae 5336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5337 rn = "Config";
5338 break;
5339 case 1:
7db13fae 5340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5341 rn = "Config1";
5342 break;
7a387fff 5343 case 2:
7db13fae 5344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5345 rn = "Config2";
5346 break;
5347 case 3:
7db13fae 5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5349 rn = "Config3";
5350 break;
b4160af1
PJ
5351 case 4:
5352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5353 rn = "Config4";
5354 break;
b4dd99a3
PJ
5355 case 5:
5356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5357 rn = "Config5";
5358 break;
e397ee33
TS
5359 /* 6,7 are implementation dependent */
5360 case 6:
7db13fae 5361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5362 rn = "Config6";
5363 break;
5364 case 7:
7db13fae 5365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5366 rn = "Config7";
5367 break;
873eb012 5368 default:
f31b035a 5369 goto cp0_unimplemented;
873eb012
TS
5370 }
5371 break;
5372 case 17:
7a387fff
TS
5373 switch (sel) {
5374 case 0:
895c2d04 5375 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5376 rn = "LLAddr";
5377 break;
f6d4dd81
YK
5378 case 1:
5379 CP0_CHECK(ctx->mrp);
5380 gen_helper_mfc0_maar(arg, cpu_env);
5381 rn = "MAAR";
5382 break;
5383 case 2:
5384 CP0_CHECK(ctx->mrp);
5385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5386 rn = "MAARI";
5387 break;
7a387fff 5388 default:
f31b035a 5389 goto cp0_unimplemented;
7a387fff 5390 }
873eb012
TS
5391 break;
5392 case 18:
7a387fff 5393 switch (sel) {
fd88b6ab 5394 case 0 ... 7:
895c2d04 5395 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5396 rn = "WatchLo";
5397 break;
7a387fff 5398 default:
f31b035a 5399 goto cp0_unimplemented;
7a387fff 5400 }
873eb012
TS
5401 break;
5402 case 19:
7a387fff 5403 switch (sel) {
fd88b6ab 5404 case 0 ...7:
895c2d04 5405 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5406 rn = "WatchHi";
5407 break;
7a387fff 5408 default:
f31b035a 5409 goto cp0_unimplemented;
7a387fff 5410 }
873eb012 5411 break;
8c0fdd85 5412 case 20:
7a387fff
TS
5413 switch (sel) {
5414 case 0:
d26bc211 5415#if defined(TARGET_MIPS64)
d75c135e 5416 check_insn(ctx, ISA_MIPS3);
7db13fae 5417 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5418 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5419 rn = "XContext";
5420 break;
703eaf37 5421#endif
7a387fff 5422 default:
f31b035a 5423 goto cp0_unimplemented;
7a387fff 5424 }
8c0fdd85
TS
5425 break;
5426 case 21:
7a387fff 5427 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5428 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5429 switch (sel) {
5430 case 0:
7db13fae 5431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5432 rn = "Framemask";
5433 break;
7a387fff 5434 default:
f31b035a 5435 goto cp0_unimplemented;
7a387fff 5436 }
8c0fdd85
TS
5437 break;
5438 case 22:
d9bea114 5439 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5440 rn = "'Diagnostic"; /* implementation dependent */
5441 break;
873eb012 5442 case 23:
7a387fff
TS
5443 switch (sel) {
5444 case 0:
895c2d04 5445 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5446 rn = "Debug";
5447 break;
7a387fff 5448 case 1:
d9bea114 5449// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5450 rn = "TraceControl";
5451// break;
7a387fff 5452 case 2:
d9bea114 5453// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5454 rn = "TraceControl2";
5455// break;
7a387fff 5456 case 3:
d9bea114 5457// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5458 rn = "UserTraceData";
5459// break;
7a387fff 5460 case 4:
d9bea114 5461// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5462 rn = "TraceBPC";
5463// break;
7a387fff 5464 default:
f31b035a 5465 goto cp0_unimplemented;
7a387fff 5466 }
873eb012
TS
5467 break;
5468 case 24:
7a387fff
TS
5469 switch (sel) {
5470 case 0:
f0b3f3ae 5471 /* EJTAG support */
7db13fae 5472 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5473 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5474 rn = "DEPC";
5475 break;
7a387fff 5476 default:
f31b035a 5477 goto cp0_unimplemented;
7a387fff 5478 }
873eb012 5479 break;
8c0fdd85 5480 case 25:
7a387fff
TS
5481 switch (sel) {
5482 case 0:
7db13fae 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5484 rn = "Performance0";
7a387fff
TS
5485 break;
5486 case 1:
d9bea114 5487// gen_helper_mfc0_performance1(arg);
2423f660
TS
5488 rn = "Performance1";
5489// break;
7a387fff 5490 case 2:
d9bea114 5491// gen_helper_mfc0_performance2(arg);
2423f660
TS
5492 rn = "Performance2";
5493// break;
7a387fff 5494 case 3:
d9bea114 5495// gen_helper_mfc0_performance3(arg);
2423f660
TS
5496 rn = "Performance3";
5497// break;
7a387fff 5498 case 4:
d9bea114 5499// gen_helper_mfc0_performance4(arg);
2423f660
TS
5500 rn = "Performance4";
5501// break;
7a387fff 5502 case 5:
d9bea114 5503// gen_helper_mfc0_performance5(arg);
2423f660
TS
5504 rn = "Performance5";
5505// break;
7a387fff 5506 case 6:
d9bea114 5507// gen_helper_mfc0_performance6(arg);
2423f660
TS
5508 rn = "Performance6";
5509// break;
7a387fff 5510 case 7:
d9bea114 5511// gen_helper_mfc0_performance7(arg);
2423f660
TS
5512 rn = "Performance7";
5513// break;
7a387fff 5514 default:
f31b035a 5515 goto cp0_unimplemented;
7a387fff 5516 }
8c0fdd85
TS
5517 break;
5518 case 26:
0d74a222
LA
5519 switch (sel) {
5520 case 0:
5521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5522 rn = "ErrCtl";
5523 break;
5524 default:
5525 goto cp0_unimplemented;
5526 }
da80682b 5527 break;
8c0fdd85 5528 case 27:
7a387fff 5529 switch (sel) {
7a387fff 5530 case 0 ... 3:
d9bea114 5531 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5532 rn = "CacheErr";
5533 break;
7a387fff 5534 default:
f31b035a 5535 goto cp0_unimplemented;
7a387fff 5536 }
8c0fdd85 5537 break;
873eb012
TS
5538 case 28:
5539 switch (sel) {
5540 case 0:
7a387fff
TS
5541 case 2:
5542 case 4:
5543 case 6:
284b731a
LA
5544 {
5545 TCGv_i64 tmp = tcg_temp_new_i64();
5546 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5547 gen_move_low32(arg, tmp);
5548 tcg_temp_free_i64(tmp);
5549 }
873eb012
TS
5550 rn = "TagLo";
5551 break;
5552 case 1:
7a387fff
TS
5553 case 3:
5554 case 5:
5555 case 7:
7db13fae 5556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5557 rn = "DataLo";
5558 break;
5559 default:
f31b035a 5560 goto cp0_unimplemented;
873eb012
TS
5561 }
5562 break;
8c0fdd85 5563 case 29:
7a387fff
TS
5564 switch (sel) {
5565 case 0:
5566 case 2:
5567 case 4:
5568 case 6:
7db13fae 5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5570 rn = "TagHi";
5571 break;
5572 case 1:
5573 case 3:
5574 case 5:
5575 case 7:
7db13fae 5576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5577 rn = "DataHi";
5578 break;
5579 default:
f31b035a 5580 goto cp0_unimplemented;
7a387fff 5581 }
8c0fdd85 5582 break;
873eb012 5583 case 30:
7a387fff
TS
5584 switch (sel) {
5585 case 0:
7db13fae 5586 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5587 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5588 rn = "ErrorEPC";
5589 break;
7a387fff 5590 default:
f31b035a 5591 goto cp0_unimplemented;
7a387fff 5592 }
873eb012
TS
5593 break;
5594 case 31:
7a387fff
TS
5595 switch (sel) {
5596 case 0:
f0b3f3ae 5597 /* EJTAG support */
7db13fae 5598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5599 rn = "DESAVE";
5600 break;
e98c0d17 5601 case 2 ... 7:
f31b035a
LA
5602 CP0_CHECK(ctx->kscrexist & (1 << sel));
5603 tcg_gen_ld_tl(arg, cpu_env,
5604 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5605 tcg_gen_ext32s_tl(arg, arg);
5606 rn = "KScratch";
e98c0d17 5607 break;
7a387fff 5608 default:
f31b035a 5609 goto cp0_unimplemented;
7a387fff 5610 }
873eb012
TS
5611 break;
5612 default:
f31b035a 5613 goto cp0_unimplemented;
873eb012 5614 }
2abf314d 5615 (void)rn; /* avoid a compiler warning */
d12d51d5 5616 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5617 return;
5618
f31b035a 5619cp0_unimplemented:
d12d51d5 5620 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5621 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5622}
5623
d75c135e 5624static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5625{
7a387fff
TS
5626 const char *rn = "invalid";
5627
e189e748 5628 if (sel != 0)
d75c135e 5629 check_insn(ctx, ISA_MIPS32);
e189e748 5630
bd79255d 5631 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5632 gen_io_start();
bd79255d 5633 }
2e70f6ef 5634
8c0fdd85
TS
5635 switch (reg) {
5636 case 0:
7a387fff
TS
5637 switch (sel) {
5638 case 0:
895c2d04 5639 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5640 rn = "Index";
5641 break;
5642 case 1:
f31b035a 5643 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5644 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5645 rn = "MVPControl";
ead9360e 5646 break;
7a387fff 5647 case 2:
f31b035a 5648 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5649 /* ignored */
7a387fff 5650 rn = "MVPConf0";
ead9360e 5651 break;
7a387fff 5652 case 3:
f31b035a 5653 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5654 /* ignored */
7a387fff 5655 rn = "MVPConf1";
ead9360e 5656 break;
01bc435b
YK
5657 case 4:
5658 CP0_CHECK(ctx->vp);
5659 /* ignored */
5660 rn = "VPControl";
5661 break;
7a387fff 5662 default:
f31b035a 5663 goto cp0_unimplemented;
7a387fff 5664 }
8c0fdd85
TS
5665 break;
5666 case 1:
7a387fff
TS
5667 switch (sel) {
5668 case 0:
2423f660 5669 /* ignored */
7a387fff 5670 rn = "Random";
2423f660 5671 break;
7a387fff 5672 case 1:
f31b035a 5673 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5674 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5675 rn = "VPEControl";
ead9360e 5676 break;
7a387fff 5677 case 2:
f31b035a 5678 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5679 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5680 rn = "VPEConf0";
ead9360e 5681 break;
7a387fff 5682 case 3:
f31b035a 5683 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5684 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5685 rn = "VPEConf1";
ead9360e 5686 break;
7a387fff 5687 case 4:
f31b035a 5688 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5689 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5690 rn = "YQMask";
ead9360e 5691 break;
7a387fff 5692 case 5:
f31b035a 5693 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5694 tcg_gen_st_tl(arg, cpu_env,
5695 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5696 rn = "VPESchedule";
ead9360e 5697 break;
7a387fff 5698 case 6:
f31b035a 5699 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5700 tcg_gen_st_tl(arg, cpu_env,
5701 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5702 rn = "VPEScheFBack";
ead9360e 5703 break;
7a387fff 5704 case 7:
f31b035a 5705 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5706 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5707 rn = "VPEOpt";
ead9360e 5708 break;
7a387fff 5709 default:
f31b035a 5710 goto cp0_unimplemented;
7a387fff 5711 }
8c0fdd85
TS
5712 break;
5713 case 2:
7a387fff
TS
5714 switch (sel) {
5715 case 0:
895c2d04 5716 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5717 rn = "EntryLo0";
5718 break;
7a387fff 5719 case 1:
f31b035a 5720 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5721 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5722 rn = "TCStatus";
ead9360e 5723 break;
7a387fff 5724 case 2:
f31b035a 5725 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5726 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5727 rn = "TCBind";
ead9360e 5728 break;
7a387fff 5729 case 3:
f31b035a 5730 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5731 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5732 rn = "TCRestart";
ead9360e 5733 break;
7a387fff 5734 case 4:
f31b035a 5735 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5736 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5737 rn = "TCHalt";
ead9360e 5738 break;
7a387fff 5739 case 5:
f31b035a 5740 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5741 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5742 rn = "TCContext";
ead9360e 5743 break;
7a387fff 5744 case 6:
f31b035a 5745 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5746 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5747 rn = "TCSchedule";
ead9360e 5748 break;
7a387fff 5749 case 7:
f31b035a 5750 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5751 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5752 rn = "TCScheFBack";
ead9360e 5753 break;
7a387fff 5754 default:
f31b035a 5755 goto cp0_unimplemented;
7a387fff 5756 }
8c0fdd85
TS
5757 break;
5758 case 3:
7a387fff
TS
5759 switch (sel) {
5760 case 0:
895c2d04 5761 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5762 rn = "EntryLo1";
5763 break;
01bc435b
YK
5764 case 1:
5765 CP0_CHECK(ctx->vp);
5766 /* ignored */
5767 rn = "GlobalNumber";
5768 break;
7a387fff 5769 default:
f31b035a 5770 goto cp0_unimplemented;
876d4b07 5771 }
8c0fdd85
TS
5772 break;
5773 case 4:
7a387fff
TS
5774 switch (sel) {
5775 case 0:
895c2d04 5776 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5777 rn = "Context";
5778 break;
7a387fff 5779 case 1:
895c2d04 5780// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5781 rn = "ContextConfig";
f31b035a 5782 goto cp0_unimplemented;
2423f660 5783// break;
d279279e 5784 case 2:
f31b035a
LA
5785 CP0_CHECK(ctx->ulri);
5786 tcg_gen_st_tl(arg, cpu_env,
5787 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5788 rn = "UserLocal";
d279279e 5789 break;
7a387fff 5790 default:
f31b035a 5791 goto cp0_unimplemented;
876d4b07 5792 }
8c0fdd85
TS
5793 break;
5794 case 5:
7a387fff
TS
5795 switch (sel) {
5796 case 0:
895c2d04 5797 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5798 rn = "PageMask";
5799 break;
7a387fff 5800 case 1:
d75c135e 5801 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5802 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5803 rn = "PageGrain";
e117f526 5804 ctx->bstate = BS_STOP;
2423f660 5805 break;
7a387fff 5806 default:
f31b035a 5807 goto cp0_unimplemented;
876d4b07 5808 }
8c0fdd85
TS
5809 break;
5810 case 6:
7a387fff
TS
5811 switch (sel) {
5812 case 0:
895c2d04 5813 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5814 rn = "Wired";
5815 break;
7a387fff 5816 case 1:
d75c135e 5817 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5818 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5819 rn = "SRSConf0";
ead9360e 5820 break;
7a387fff 5821 case 2:
d75c135e 5822 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5823 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5824 rn = "SRSConf1";
ead9360e 5825 break;
7a387fff 5826 case 3:
d75c135e 5827 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5828 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5829 rn = "SRSConf2";
ead9360e 5830 break;
7a387fff 5831 case 4:
d75c135e 5832 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5833 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5834 rn = "SRSConf3";
ead9360e 5835 break;
7a387fff 5836 case 5:
d75c135e 5837 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5838 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5839 rn = "SRSConf4";
ead9360e 5840 break;
7a387fff 5841 default:
f31b035a 5842 goto cp0_unimplemented;
876d4b07 5843 }
8c0fdd85
TS
5844 break;
5845 case 7:
7a387fff
TS
5846 switch (sel) {
5847 case 0:
d75c135e 5848 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5849 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5850 ctx->bstate = BS_STOP;
2423f660
TS
5851 rn = "HWREna";
5852 break;
7a387fff 5853 default:
f31b035a 5854 goto cp0_unimplemented;
876d4b07 5855 }
8c0fdd85
TS
5856 break;
5857 case 8:
aea14095
LA
5858 switch (sel) {
5859 case 0:
5860 /* ignored */
5861 rn = "BadVAddr";
5862 break;
5863 case 1:
5864 /* ignored */
5865 rn = "BadInstr";
5866 break;
5867 case 2:
5868 /* ignored */
5869 rn = "BadInstrP";
5870 break;
5871 default:
f31b035a 5872 goto cp0_unimplemented;
aea14095 5873 }
8c0fdd85
TS
5874 break;
5875 case 9:
7a387fff
TS
5876 switch (sel) {
5877 case 0:
895c2d04 5878 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5879 rn = "Count";
5880 break;
876d4b07 5881 /* 6,7 are implementation dependent */
7a387fff 5882 default:
f31b035a 5883 goto cp0_unimplemented;
876d4b07 5884 }
8c0fdd85
TS
5885 break;
5886 case 10:
7a387fff
TS
5887 switch (sel) {
5888 case 0:
895c2d04 5889 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5890 rn = "EntryHi";
5891 break;
7a387fff 5892 default:
f31b035a 5893 goto cp0_unimplemented;
876d4b07 5894 }
8c0fdd85
TS
5895 break;
5896 case 11:
7a387fff
TS
5897 switch (sel) {
5898 case 0:
895c2d04 5899 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5900 rn = "Compare";
5901 break;
5902 /* 6,7 are implementation dependent */
7a387fff 5903 default:
f31b035a 5904 goto cp0_unimplemented;
876d4b07 5905 }
8c0fdd85
TS
5906 break;
5907 case 12:
7a387fff
TS
5908 switch (sel) {
5909 case 0:
867abc7e 5910 save_cpu_state(ctx, 1);
895c2d04 5911 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5912 /* BS_STOP isn't good enough here, hflags may have changed. */
5913 gen_save_pc(ctx->pc + 4);
5914 ctx->bstate = BS_EXCP;
2423f660
TS
5915 rn = "Status";
5916 break;
7a387fff 5917 case 1:
d75c135e 5918 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5919 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5920 /* Stop translation as we may have switched the execution mode */
5921 ctx->bstate = BS_STOP;
2423f660
TS
5922 rn = "IntCtl";
5923 break;
7a387fff 5924 case 2:
d75c135e 5925 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5926 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5927 /* Stop translation as we may have switched the execution mode */
5928 ctx->bstate = BS_STOP;
2423f660
TS
5929 rn = "SRSCtl";
5930 break;
7a387fff 5931 case 3:
d75c135e 5932 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5933 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5934 /* Stop translation as we may have switched the execution mode */
5935 ctx->bstate = BS_STOP;
2423f660 5936 rn = "SRSMap";
fd88b6ab 5937 break;
7a387fff 5938 default:
f31b035a 5939 goto cp0_unimplemented;
876d4b07 5940 }
8c0fdd85
TS
5941 break;
5942 case 13:
7a387fff
TS
5943 switch (sel) {
5944 case 0:
867abc7e 5945 save_cpu_state(ctx, 1);
895c2d04 5946 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5947 rn = "Cause";
5948 break;
7a387fff 5949 default:
f31b035a 5950 goto cp0_unimplemented;
876d4b07 5951 }
8c0fdd85
TS
5952 break;
5953 case 14:
7a387fff
TS
5954 switch (sel) {
5955 case 0:
d54a299b 5956 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5957 rn = "EPC";
5958 break;
7a387fff 5959 default:
f31b035a 5960 goto cp0_unimplemented;
876d4b07 5961 }
8c0fdd85
TS
5962 break;
5963 case 15:
7a387fff
TS
5964 switch (sel) {
5965 case 0:
2423f660
TS
5966 /* ignored */
5967 rn = "PRid";
5968 break;
7a387fff 5969 case 1:
d75c135e 5970 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5971 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5972 rn = "EBase";
5973 break;
7a387fff 5974 default:
f31b035a 5975 goto cp0_unimplemented;
1579a72e 5976 }
8c0fdd85
TS
5977 break;
5978 case 16:
5979 switch (sel) {
5980 case 0:
895c2d04 5981 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5982 rn = "Config";
2423f660
TS
5983 /* Stop translation as we may have switched the execution mode */
5984 ctx->bstate = BS_STOP;
7a387fff
TS
5985 break;
5986 case 1:
e397ee33 5987 /* ignored, read only */
7a387fff
TS
5988 rn = "Config1";
5989 break;
5990 case 2:
895c2d04 5991 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5992 rn = "Config2";
2423f660
TS
5993 /* Stop translation as we may have switched the execution mode */
5994 ctx->bstate = BS_STOP;
8c0fdd85 5995 break;
7a387fff 5996 case 3:
90f12d73 5997 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5998 rn = "Config3";
90f12d73
MR
5999 /* Stop translation as we may have switched the execution mode */
6000 ctx->bstate = BS_STOP;
7a387fff 6001 break;
b4160af1
PJ
6002 case 4:
6003 gen_helper_mtc0_config4(cpu_env, arg);
6004 rn = "Config4";
6005 ctx->bstate = BS_STOP;
6006 break;
b4dd99a3
PJ
6007 case 5:
6008 gen_helper_mtc0_config5(cpu_env, arg);
6009 rn = "Config5";
6010 /* Stop translation as we may have switched the execution mode */
6011 ctx->bstate = BS_STOP;
6012 break;
e397ee33
TS
6013 /* 6,7 are implementation dependent */
6014 case 6:
6015 /* ignored */
6016 rn = "Config6";
6017 break;
6018 case 7:
6019 /* ignored */
6020 rn = "Config7";
6021 break;
8c0fdd85
TS
6022 default:
6023 rn = "Invalid config selector";
f31b035a 6024 goto cp0_unimplemented;
8c0fdd85
TS
6025 }
6026 break;
6027 case 17:
7a387fff
TS
6028 switch (sel) {
6029 case 0:
895c2d04 6030 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6031 rn = "LLAddr";
6032 break;
f6d4dd81
YK
6033 case 1:
6034 CP0_CHECK(ctx->mrp);
6035 gen_helper_mtc0_maar(cpu_env, arg);
6036 rn = "MAAR";
6037 break;
6038 case 2:
6039 CP0_CHECK(ctx->mrp);
6040 gen_helper_mtc0_maari(cpu_env, arg);
6041 rn = "MAARI";
6042 break;
7a387fff 6043 default:
f31b035a 6044 goto cp0_unimplemented;
7a387fff 6045 }
8c0fdd85
TS
6046 break;
6047 case 18:
7a387fff 6048 switch (sel) {
fd88b6ab 6049 case 0 ... 7:
895c2d04 6050 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6051 rn = "WatchLo";
6052 break;
7a387fff 6053 default:
f31b035a 6054 goto cp0_unimplemented;
7a387fff 6055 }
8c0fdd85
TS
6056 break;
6057 case 19:
7a387fff 6058 switch (sel) {
fd88b6ab 6059 case 0 ... 7:
895c2d04 6060 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6061 rn = "WatchHi";
6062 break;
7a387fff 6063 default:
f31b035a 6064 goto cp0_unimplemented;
7a387fff 6065 }
8c0fdd85
TS
6066 break;
6067 case 20:
7a387fff
TS
6068 switch (sel) {
6069 case 0:
d26bc211 6070#if defined(TARGET_MIPS64)
d75c135e 6071 check_insn(ctx, ISA_MIPS3);
895c2d04 6072 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6073 rn = "XContext";
6074 break;
703eaf37 6075#endif
7a387fff 6076 default:
f31b035a 6077 goto cp0_unimplemented;
7a387fff 6078 }
8c0fdd85
TS
6079 break;
6080 case 21:
7a387fff 6081 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6082 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6083 switch (sel) {
6084 case 0:
895c2d04 6085 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6086 rn = "Framemask";
6087 break;
7a387fff 6088 default:
f31b035a 6089 goto cp0_unimplemented;
7a387fff
TS
6090 }
6091 break;
8c0fdd85 6092 case 22:
7a387fff
TS
6093 /* ignored */
6094 rn = "Diagnostic"; /* implementation dependent */
2423f660 6095 break;
8c0fdd85 6096 case 23:
7a387fff
TS
6097 switch (sel) {
6098 case 0:
895c2d04 6099 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6100 /* BS_STOP isn't good enough here, hflags may have changed. */
6101 gen_save_pc(ctx->pc + 4);
6102 ctx->bstate = BS_EXCP;
2423f660
TS
6103 rn = "Debug";
6104 break;
7a387fff 6105 case 1:
895c2d04 6106// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6107 rn = "TraceControl";
8487327a
TS
6108 /* Stop translation as we may have switched the execution mode */
6109 ctx->bstate = BS_STOP;
2423f660 6110// break;
7a387fff 6111 case 2:
895c2d04 6112// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6113 rn = "TraceControl2";
8487327a
TS
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx->bstate = BS_STOP;
2423f660 6116// break;
7a387fff 6117 case 3:
8487327a
TS
6118 /* Stop translation as we may have switched the execution mode */
6119 ctx->bstate = BS_STOP;
895c2d04 6120// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6121 rn = "UserTraceData";
8487327a
TS
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx->bstate = BS_STOP;
2423f660 6124// break;
7a387fff 6125 case 4:
895c2d04 6126// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
2423f660
TS
6129 rn = "TraceBPC";
6130// break;
7a387fff 6131 default:
f31b035a 6132 goto cp0_unimplemented;
7a387fff 6133 }
8c0fdd85
TS
6134 break;
6135 case 24:
7a387fff
TS
6136 switch (sel) {
6137 case 0:
f1aa6320 6138 /* EJTAG support */
d54a299b 6139 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6140 rn = "DEPC";
6141 break;
7a387fff 6142 default:
f31b035a 6143 goto cp0_unimplemented;
7a387fff 6144 }
8c0fdd85
TS
6145 break;
6146 case 25:
7a387fff
TS
6147 switch (sel) {
6148 case 0:
895c2d04 6149 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6150 rn = "Performance0";
6151 break;
7a387fff 6152 case 1:
d9bea114 6153// gen_helper_mtc0_performance1(arg);
2423f660
TS
6154 rn = "Performance1";
6155// break;
7a387fff 6156 case 2:
d9bea114 6157// gen_helper_mtc0_performance2(arg);
2423f660
TS
6158 rn = "Performance2";
6159// break;
7a387fff 6160 case 3:
d9bea114 6161// gen_helper_mtc0_performance3(arg);
2423f660
TS
6162 rn = "Performance3";
6163// break;
7a387fff 6164 case 4:
d9bea114 6165// gen_helper_mtc0_performance4(arg);
2423f660
TS
6166 rn = "Performance4";
6167// break;
7a387fff 6168 case 5:
d9bea114 6169// gen_helper_mtc0_performance5(arg);
2423f660
TS
6170 rn = "Performance5";
6171// break;
7a387fff 6172 case 6:
d9bea114 6173// gen_helper_mtc0_performance6(arg);
2423f660
TS
6174 rn = "Performance6";
6175// break;
7a387fff 6176 case 7:
d9bea114 6177// gen_helper_mtc0_performance7(arg);
2423f660
TS
6178 rn = "Performance7";
6179// break;
7a387fff 6180 default:
f31b035a 6181 goto cp0_unimplemented;
7a387fff 6182 }
8c0fdd85
TS
6183 break;
6184 case 26:
0d74a222
LA
6185 switch (sel) {
6186 case 0:
6187 gen_helper_mtc0_errctl(cpu_env, arg);
6188 ctx->bstate = BS_STOP;
6189 rn = "ErrCtl";
6190 break;
6191 default:
6192 goto cp0_unimplemented;
6193 }
2423f660 6194 break;
8c0fdd85 6195 case 27:
7a387fff
TS
6196 switch (sel) {
6197 case 0 ... 3:
2423f660
TS
6198 /* ignored */
6199 rn = "CacheErr";
6200 break;
7a387fff 6201 default:
f31b035a 6202 goto cp0_unimplemented;
7a387fff 6203 }
8c0fdd85
TS
6204 break;
6205 case 28:
6206 switch (sel) {
6207 case 0:
7a387fff
TS
6208 case 2:
6209 case 4:
6210 case 6:
895c2d04 6211 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6212 rn = "TagLo";
6213 break;
7a387fff
TS
6214 case 1:
6215 case 3:
6216 case 5:
6217 case 7:
895c2d04 6218 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6219 rn = "DataLo";
6220 break;
8c0fdd85 6221 default:
f31b035a 6222 goto cp0_unimplemented;
8c0fdd85
TS
6223 }
6224 break;
6225 case 29:
7a387fff
TS
6226 switch (sel) {
6227 case 0:
6228 case 2:
6229 case 4:
6230 case 6:
895c2d04 6231 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6232 rn = "TagHi";
6233 break;
6234 case 1:
6235 case 3:
6236 case 5:
6237 case 7:
895c2d04 6238 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6239 rn = "DataHi";
6240 break;
6241 default:
6242 rn = "invalid sel";
f31b035a 6243 goto cp0_unimplemented;
7a387fff 6244 }
8c0fdd85
TS
6245 break;
6246 case 30:
7a387fff
TS
6247 switch (sel) {
6248 case 0:
d54a299b 6249 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6250 rn = "ErrorEPC";
6251 break;
7a387fff 6252 default:
f31b035a 6253 goto cp0_unimplemented;
7a387fff 6254 }
8c0fdd85
TS
6255 break;
6256 case 31:
7a387fff
TS
6257 switch (sel) {
6258 case 0:
f1aa6320 6259 /* EJTAG support */
7db13fae 6260 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6261 rn = "DESAVE";
6262 break;
e98c0d17 6263 case 2 ... 7:
f31b035a
LA
6264 CP0_CHECK(ctx->kscrexist & (1 << sel));
6265 tcg_gen_st_tl(arg, cpu_env,
6266 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6267 rn = "KScratch";
e98c0d17 6268 break;
7a387fff 6269 default:
f31b035a 6270 goto cp0_unimplemented;
7a387fff 6271 }
2423f660
TS
6272 /* Stop translation as we may have switched the execution mode */
6273 ctx->bstate = BS_STOP;
8c0fdd85
TS
6274 break;
6275 default:
f31b035a 6276 goto cp0_unimplemented;
8c0fdd85 6277 }
2abf314d 6278 (void)rn; /* avoid a compiler warning */
d12d51d5 6279 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6280 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6281 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6282 gen_io_end();
6283 ctx->bstate = BS_STOP;
6284 }
8c0fdd85
TS
6285 return;
6286
f31b035a 6287cp0_unimplemented:
d12d51d5 6288 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6289}
6290
d26bc211 6291#if defined(TARGET_MIPS64)
d75c135e 6292static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6293{
6294 const char *rn = "invalid";
6295
e189e748 6296 if (sel != 0)
d75c135e 6297 check_insn(ctx, ISA_MIPS64);
e189e748 6298
9c2149c8
TS
6299 switch (reg) {
6300 case 0:
6301 switch (sel) {
6302 case 0:
7db13fae 6303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6304 rn = "Index";
6305 break;
6306 case 1:
f31b035a 6307 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6308 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6309 rn = "MVPControl";
ead9360e 6310 break;
9c2149c8 6311 case 2:
f31b035a 6312 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6313 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6314 rn = "MVPConf0";
ead9360e 6315 break;
9c2149c8 6316 case 3:
f31b035a 6317 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6318 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6319 rn = "MVPConf1";
ead9360e 6320 break;
01bc435b
YK
6321 case 4:
6322 CP0_CHECK(ctx->vp);
6323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6324 rn = "VPControl";
6325 break;
9c2149c8 6326 default:
f31b035a 6327 goto cp0_unimplemented;
9c2149c8
TS
6328 }
6329 break;
6330 case 1:
6331 switch (sel) {
6332 case 0:
f31b035a 6333 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6334 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6335 rn = "Random";
2423f660 6336 break;
9c2149c8 6337 case 1:
f31b035a 6338 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6340 rn = "VPEControl";
ead9360e 6341 break;
9c2149c8 6342 case 2:
f31b035a 6343 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6345 rn = "VPEConf0";
ead9360e 6346 break;
9c2149c8 6347 case 3:
f31b035a 6348 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6350 rn = "VPEConf1";
ead9360e 6351 break;
9c2149c8 6352 case 4:
f31b035a 6353 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6355 rn = "YQMask";
ead9360e 6356 break;
9c2149c8 6357 case 5:
f31b035a 6358 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6359 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6360 rn = "VPESchedule";
ead9360e 6361 break;
9c2149c8 6362 case 6:
f31b035a 6363 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6365 rn = "VPEScheFBack";
ead9360e 6366 break;
9c2149c8 6367 case 7:
f31b035a 6368 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6370 rn = "VPEOpt";
ead9360e 6371 break;
9c2149c8 6372 default:
f31b035a 6373 goto cp0_unimplemented;
9c2149c8
TS
6374 }
6375 break;
6376 case 2:
6377 switch (sel) {
6378 case 0:
7db13fae 6379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6380 rn = "EntryLo0";
6381 break;
9c2149c8 6382 case 1:
f31b035a 6383 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6384 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6385 rn = "TCStatus";
ead9360e 6386 break;
9c2149c8 6387 case 2:
f31b035a 6388 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6389 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6390 rn = "TCBind";
ead9360e 6391 break;
9c2149c8 6392 case 3:
f31b035a 6393 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6394 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6395 rn = "TCRestart";
ead9360e 6396 break;
9c2149c8 6397 case 4:
f31b035a 6398 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6399 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6400 rn = "TCHalt";
ead9360e 6401 break;
9c2149c8 6402 case 5:
f31b035a 6403 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6404 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6405 rn = "TCContext";
ead9360e 6406 break;
9c2149c8 6407 case 6:
f31b035a 6408 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6409 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6410 rn = "TCSchedule";
ead9360e 6411 break;
9c2149c8 6412 case 7:
f31b035a 6413 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6414 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6415 rn = "TCScheFBack";
ead9360e 6416 break;
9c2149c8 6417 default:
f31b035a 6418 goto cp0_unimplemented;
9c2149c8
TS
6419 }
6420 break;
6421 case 3:
6422 switch (sel) {
6423 case 0:
7db13fae 6424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6425 rn = "EntryLo1";
6426 break;
01bc435b
YK
6427 case 1:
6428 CP0_CHECK(ctx->vp);
6429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6430 rn = "GlobalNumber";
6431 break;
9c2149c8 6432 default:
f31b035a 6433 goto cp0_unimplemented;
1579a72e 6434 }
9c2149c8
TS
6435 break;
6436 case 4:
6437 switch (sel) {
6438 case 0:
7db13fae 6439 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6440 rn = "Context";
6441 break;
9c2149c8 6442 case 1:
d9bea114 6443// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6444 rn = "ContextConfig";
f31b035a 6445 goto cp0_unimplemented;
2423f660 6446// break;
d279279e 6447 case 2:
f31b035a
LA
6448 CP0_CHECK(ctx->ulri);
6449 tcg_gen_ld_tl(arg, cpu_env,
6450 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6451 rn = "UserLocal";
d279279e 6452 break;
9c2149c8 6453 default:
f31b035a 6454 goto cp0_unimplemented;
876d4b07 6455 }
9c2149c8
TS
6456 break;
6457 case 5:
6458 switch (sel) {
6459 case 0:
7db13fae 6460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6461 rn = "PageMask";
6462 break;
9c2149c8 6463 case 1:
d75c135e 6464 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6466 rn = "PageGrain";
6467 break;
9c2149c8 6468 default:
f31b035a 6469 goto cp0_unimplemented;
876d4b07 6470 }
9c2149c8
TS
6471 break;
6472 case 6:
6473 switch (sel) {
6474 case 0:
7db13fae 6475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6476 rn = "Wired";
6477 break;
9c2149c8 6478 case 1:
d75c135e 6479 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6481 rn = "SRSConf0";
ead9360e 6482 break;
9c2149c8 6483 case 2:
d75c135e 6484 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6486 rn = "SRSConf1";
ead9360e 6487 break;
9c2149c8 6488 case 3:
d75c135e 6489 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6491 rn = "SRSConf2";
ead9360e 6492 break;
9c2149c8 6493 case 4:
d75c135e 6494 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6496 rn = "SRSConf3";
ead9360e 6497 break;
9c2149c8 6498 case 5:
d75c135e 6499 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6501 rn = "SRSConf4";
ead9360e 6502 break;
9c2149c8 6503 default:
f31b035a 6504 goto cp0_unimplemented;
876d4b07 6505 }
9c2149c8
TS
6506 break;
6507 case 7:
6508 switch (sel) {
6509 case 0:
d75c135e 6510 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6512 rn = "HWREna";
6513 break;
9c2149c8 6514 default:
f31b035a 6515 goto cp0_unimplemented;
876d4b07 6516 }
9c2149c8
TS
6517 break;
6518 case 8:
6519 switch (sel) {
6520 case 0:
7db13fae 6521 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6522 rn = "BadVAddr";
2423f660 6523 break;
aea14095 6524 case 1:
f31b035a
LA
6525 CP0_CHECK(ctx->bi);
6526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6527 rn = "BadInstr";
aea14095
LA
6528 break;
6529 case 2:
f31b035a
LA
6530 CP0_CHECK(ctx->bp);
6531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6532 rn = "BadInstrP";
aea14095 6533 break;
9c2149c8 6534 default:
f31b035a 6535 goto cp0_unimplemented;
876d4b07 6536 }
9c2149c8
TS
6537 break;
6538 case 9:
6539 switch (sel) {
6540 case 0:
2e70f6ef 6541 /* Mark as an IO operation because we read the time. */
bd79255d 6542 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6543 gen_io_start();
bd79255d 6544 }
895c2d04 6545 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6546 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6547 gen_io_end();
2e70f6ef 6548 }
55807224
EI
6549 /* Break the TB to be able to take timer interrupts immediately
6550 after reading count. */
6551 ctx->bstate = BS_STOP;
2423f660
TS
6552 rn = "Count";
6553 break;
6554 /* 6,7 are implementation dependent */
9c2149c8 6555 default:
f31b035a 6556 goto cp0_unimplemented;
876d4b07 6557 }
9c2149c8
TS
6558 break;
6559 case 10:
6560 switch (sel) {
6561 case 0:
7db13fae 6562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6563 rn = "EntryHi";
6564 break;
9c2149c8 6565 default:
f31b035a 6566 goto cp0_unimplemented;
876d4b07 6567 }
9c2149c8
TS
6568 break;
6569 case 11:
6570 switch (sel) {
6571 case 0:
7db13fae 6572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6573 rn = "Compare";
6574 break;
876d4b07 6575 /* 6,7 are implementation dependent */
9c2149c8 6576 default:
f31b035a 6577 goto cp0_unimplemented;
876d4b07 6578 }
9c2149c8
TS
6579 break;
6580 case 12:
6581 switch (sel) {
6582 case 0:
7db13fae 6583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6584 rn = "Status";
6585 break;
9c2149c8 6586 case 1:
d75c135e 6587 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6589 rn = "IntCtl";
6590 break;
9c2149c8 6591 case 2:
d75c135e 6592 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6594 rn = "SRSCtl";
6595 break;
9c2149c8 6596 case 3:
d75c135e 6597 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6599 rn = "SRSMap";
6600 break;
9c2149c8 6601 default:
f31b035a 6602 goto cp0_unimplemented;
876d4b07 6603 }
9c2149c8
TS
6604 break;
6605 case 13:
6606 switch (sel) {
6607 case 0:
7db13fae 6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6609 rn = "Cause";
6610 break;
9c2149c8 6611 default:
f31b035a 6612 goto cp0_unimplemented;
876d4b07 6613 }
9c2149c8
TS
6614 break;
6615 case 14:
6616 switch (sel) {
6617 case 0:
7db13fae 6618 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6619 rn = "EPC";
6620 break;
9c2149c8 6621 default:
f31b035a 6622 goto cp0_unimplemented;
876d4b07 6623 }
9c2149c8
TS
6624 break;
6625 case 15:
6626 switch (sel) {
6627 case 0:
7db13fae 6628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6629 rn = "PRid";
6630 break;
9c2149c8 6631 case 1:
d75c135e 6632 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6634 rn = "EBase";
6635 break;
c870e3f5
YK
6636 case 3:
6637 check_insn(ctx, ISA_MIPS32R2);
6638 CP0_CHECK(ctx->cmgcr);
6639 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6640 rn = "CMGCRBase";
6641 break;
9c2149c8 6642 default:
f31b035a 6643 goto cp0_unimplemented;
876d4b07 6644 }
9c2149c8
TS
6645 break;
6646 case 16:
6647 switch (sel) {
6648 case 0:
7db13fae 6649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6650 rn = "Config";
6651 break;
6652 case 1:
7db13fae 6653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6654 rn = "Config1";
6655 break;
6656 case 2:
7db13fae 6657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6658 rn = "Config2";
6659 break;
6660 case 3:
7db13fae 6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6662 rn = "Config3";
6663 break;
faf1f68b
LA
6664 case 4:
6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6666 rn = "Config4";
6667 break;
6668 case 5:
6669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6670 rn = "Config5";
6671 break;
9c2149c8 6672 /* 6,7 are implementation dependent */
f0b3f3ae 6673 case 6:
7db13fae 6674 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6675 rn = "Config6";
6676 break;
6677 case 7:
7db13fae 6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6679 rn = "Config7";
6680 break;
9c2149c8 6681 default:
f31b035a 6682 goto cp0_unimplemented;
9c2149c8
TS
6683 }
6684 break;
6685 case 17:
6686 switch (sel) {
6687 case 0:
895c2d04 6688 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6689 rn = "LLAddr";
6690 break;
f6d4dd81
YK
6691 case 1:
6692 CP0_CHECK(ctx->mrp);
6693 gen_helper_dmfc0_maar(arg, cpu_env);
6694 rn = "MAAR";
6695 break;
6696 case 2:
6697 CP0_CHECK(ctx->mrp);
6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6699 rn = "MAARI";
6700 break;
9c2149c8 6701 default:
f31b035a 6702 goto cp0_unimplemented;
9c2149c8
TS
6703 }
6704 break;
6705 case 18:
6706 switch (sel) {
fd88b6ab 6707 case 0 ... 7:
895c2d04 6708 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6709 rn = "WatchLo";
6710 break;
9c2149c8 6711 default:
f31b035a 6712 goto cp0_unimplemented;
9c2149c8
TS
6713 }
6714 break;
6715 case 19:
6716 switch (sel) {
fd88b6ab 6717 case 0 ... 7:
895c2d04 6718 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6719 rn = "WatchHi";
6720 break;
9c2149c8 6721 default:
f31b035a 6722 goto cp0_unimplemented;
9c2149c8
TS
6723 }
6724 break;
6725 case 20:
6726 switch (sel) {
6727 case 0:
d75c135e 6728 check_insn(ctx, ISA_MIPS3);
7db13fae 6729 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6730 rn = "XContext";
6731 break;
9c2149c8 6732 default:
f31b035a 6733 goto cp0_unimplemented;
9c2149c8
TS
6734 }
6735 break;
6736 case 21:
6737 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6738 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6739 switch (sel) {
6740 case 0:
7db13fae 6741 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6742 rn = "Framemask";
6743 break;
9c2149c8 6744 default:
f31b035a 6745 goto cp0_unimplemented;
9c2149c8
TS
6746 }
6747 break;
6748 case 22:
d9bea114 6749 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6750 rn = "'Diagnostic"; /* implementation dependent */
6751 break;
9c2149c8
TS
6752 case 23:
6753 switch (sel) {
6754 case 0:
895c2d04 6755 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6756 rn = "Debug";
6757 break;
9c2149c8 6758 case 1:
895c2d04 6759// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6760 rn = "TraceControl";
6761// break;
9c2149c8 6762 case 2:
895c2d04 6763// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6764 rn = "TraceControl2";
6765// break;
9c2149c8 6766 case 3:
895c2d04 6767// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6768 rn = "UserTraceData";
6769// break;
9c2149c8 6770 case 4:
895c2d04 6771// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6772 rn = "TraceBPC";
6773// break;
9c2149c8 6774 default:
f31b035a 6775 goto cp0_unimplemented;
9c2149c8
TS
6776 }
6777 break;
6778 case 24:
6779 switch (sel) {
6780 case 0:
f0b3f3ae 6781 /* EJTAG support */
7db13fae 6782 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6783 rn = "DEPC";
6784 break;
9c2149c8 6785 default:
f31b035a 6786 goto cp0_unimplemented;
9c2149c8
TS
6787 }
6788 break;
6789 case 25:
6790 switch (sel) {
6791 case 0:
7db13fae 6792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6793 rn = "Performance0";
9c2149c8
TS
6794 break;
6795 case 1:
d9bea114 6796// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6797 rn = "Performance1";
6798// break;
9c2149c8 6799 case 2:
d9bea114 6800// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6801 rn = "Performance2";
6802// break;
9c2149c8 6803 case 3:
d9bea114 6804// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6805 rn = "Performance3";
6806// break;
9c2149c8 6807 case 4:
d9bea114 6808// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6809 rn = "Performance4";
6810// break;
9c2149c8 6811 case 5:
d9bea114 6812// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6813 rn = "Performance5";
6814// break;
9c2149c8 6815 case 6:
d9bea114 6816// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6817 rn = "Performance6";
6818// break;
9c2149c8 6819 case 7:
d9bea114 6820// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6821 rn = "Performance7";
6822// break;
9c2149c8 6823 default:
f31b035a 6824 goto cp0_unimplemented;
9c2149c8
TS
6825 }
6826 break;
6827 case 26:
0d74a222
LA
6828 switch (sel) {
6829 case 0:
6830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6831 rn = "ErrCtl";
6832 break;
6833 default:
6834 goto cp0_unimplemented;
6835 }
da80682b 6836 break;
9c2149c8
TS
6837 case 27:
6838 switch (sel) {
6839 /* ignored */
6840 case 0 ... 3:
d9bea114 6841 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6842 rn = "CacheErr";
6843 break;
9c2149c8 6844 default:
f31b035a 6845 goto cp0_unimplemented;
9c2149c8
TS
6846 }
6847 break;
6848 case 28:
6849 switch (sel) {
6850 case 0:
6851 case 2:
6852 case 4:
6853 case 6:
7db13fae 6854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6855 rn = "TagLo";
6856 break;
6857 case 1:
6858 case 3:
6859 case 5:
6860 case 7:
7db13fae 6861 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6862 rn = "DataLo";
6863 break;
6864 default:
f31b035a 6865 goto cp0_unimplemented;
9c2149c8
TS
6866 }
6867 break;
6868 case 29:
6869 switch (sel) {
6870 case 0:
6871 case 2:
6872 case 4:
6873 case 6:
7db13fae 6874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6875 rn = "TagHi";
6876 break;
6877 case 1:
6878 case 3:
6879 case 5:
6880 case 7:
7db13fae 6881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6882 rn = "DataHi";
6883 break;
6884 default:
f31b035a 6885 goto cp0_unimplemented;
9c2149c8
TS
6886 }
6887 break;
6888 case 30:
6889 switch (sel) {
6890 case 0:
7db13fae 6891 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6892 rn = "ErrorEPC";
6893 break;
9c2149c8 6894 default:
f31b035a 6895 goto cp0_unimplemented;
9c2149c8
TS
6896 }
6897 break;
6898 case 31:
6899 switch (sel) {
6900 case 0:
f0b3f3ae 6901 /* EJTAG support */
7db13fae 6902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6903 rn = "DESAVE";
6904 break;
e98c0d17 6905 case 2 ... 7:
f31b035a
LA
6906 CP0_CHECK(ctx->kscrexist & (1 << sel));
6907 tcg_gen_ld_tl(arg, cpu_env,
6908 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6909 rn = "KScratch";
e98c0d17 6910 break;
9c2149c8 6911 default:
f31b035a 6912 goto cp0_unimplemented;
9c2149c8
TS
6913 }
6914 break;
6915 default:
f31b035a 6916 goto cp0_unimplemented;
9c2149c8 6917 }
2abf314d 6918 (void)rn; /* avoid a compiler warning */
d12d51d5 6919 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6920 return;
6921
f31b035a 6922cp0_unimplemented:
d12d51d5 6923 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6924 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6925}
6926
d75c135e 6927static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6928{
6929 const char *rn = "invalid";
6930
e189e748 6931 if (sel != 0)
d75c135e 6932 check_insn(ctx, ISA_MIPS64);
e189e748 6933
bd79255d 6934 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6935 gen_io_start();
bd79255d 6936 }
2e70f6ef 6937
9c2149c8
TS
6938 switch (reg) {
6939 case 0:
6940 switch (sel) {
6941 case 0:
895c2d04 6942 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6943 rn = "Index";
6944 break;
6945 case 1:
f31b035a 6946 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6947 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6948 rn = "MVPControl";
ead9360e 6949 break;
9c2149c8 6950 case 2:
f31b035a 6951 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6952 /* ignored */
9c2149c8 6953 rn = "MVPConf0";
ead9360e 6954 break;
9c2149c8 6955 case 3:
f31b035a 6956 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6957 /* ignored */
9c2149c8 6958 rn = "MVPConf1";
ead9360e 6959 break;
01bc435b
YK
6960 case 4:
6961 CP0_CHECK(ctx->vp);
6962 /* ignored */
6963 rn = "VPControl";
6964 break;
9c2149c8 6965 default:
f31b035a 6966 goto cp0_unimplemented;
9c2149c8
TS
6967 }
6968 break;
6969 case 1:
6970 switch (sel) {
6971 case 0:
2423f660 6972 /* ignored */
9c2149c8 6973 rn = "Random";
2423f660 6974 break;
9c2149c8 6975 case 1:
f31b035a 6976 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6977 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6978 rn = "VPEControl";
ead9360e 6979 break;
9c2149c8 6980 case 2:
f31b035a 6981 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6982 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6983 rn = "VPEConf0";
ead9360e 6984 break;
9c2149c8 6985 case 3:
f31b035a 6986 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6987 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6988 rn = "VPEConf1";
ead9360e 6989 break;
9c2149c8 6990 case 4:
f31b035a 6991 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6992 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6993 rn = "YQMask";
ead9360e 6994 break;
9c2149c8 6995 case 5:
f31b035a 6996 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6997 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6998 rn = "VPESchedule";
ead9360e 6999 break;
9c2149c8 7000 case 6:
f31b035a 7001 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7002 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7003 rn = "VPEScheFBack";
ead9360e 7004 break;
9c2149c8 7005 case 7:
f31b035a 7006 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7007 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7008 rn = "VPEOpt";
ead9360e 7009 break;
9c2149c8 7010 default:
f31b035a 7011 goto cp0_unimplemented;
9c2149c8
TS
7012 }
7013 break;
7014 case 2:
7015 switch (sel) {
7016 case 0:
7207c7f9 7017 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7018 rn = "EntryLo0";
7019 break;
9c2149c8 7020 case 1:
f31b035a 7021 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7022 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7023 rn = "TCStatus";
ead9360e 7024 break;
9c2149c8 7025 case 2:
f31b035a 7026 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7027 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7028 rn = "TCBind";
ead9360e 7029 break;
9c2149c8 7030 case 3:
f31b035a 7031 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7032 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7033 rn = "TCRestart";
ead9360e 7034 break;
9c2149c8 7035 case 4:
f31b035a 7036 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7037 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7038 rn = "TCHalt";
ead9360e 7039 break;
9c2149c8 7040 case 5:
f31b035a 7041 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7042 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7043 rn = "TCContext";
ead9360e 7044 break;
9c2149c8 7045 case 6:
f31b035a 7046 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7047 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7048 rn = "TCSchedule";
ead9360e 7049 break;
9c2149c8 7050 case 7:
f31b035a 7051 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7052 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7053 rn = "TCScheFBack";
ead9360e 7054 break;
9c2149c8 7055 default:
f31b035a 7056 goto cp0_unimplemented;
9c2149c8
TS
7057 }
7058 break;
7059 case 3:
7060 switch (sel) {
7061 case 0:
7207c7f9 7062 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7063 rn = "EntryLo1";
7064 break;
01bc435b
YK
7065 case 1:
7066 CP0_CHECK(ctx->vp);
7067 /* ignored */
7068 rn = "GlobalNumber";
7069 break;
9c2149c8 7070 default:
f31b035a 7071 goto cp0_unimplemented;
876d4b07 7072 }
9c2149c8
TS
7073 break;
7074 case 4:
7075 switch (sel) {
7076 case 0:
895c2d04 7077 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7078 rn = "Context";
7079 break;
9c2149c8 7080 case 1:
895c2d04 7081// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7082 rn = "ContextConfig";
f31b035a 7083 goto cp0_unimplemented;
2423f660 7084// break;
d279279e 7085 case 2:
f31b035a
LA
7086 CP0_CHECK(ctx->ulri);
7087 tcg_gen_st_tl(arg, cpu_env,
7088 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7089 rn = "UserLocal";
d279279e 7090 break;
9c2149c8 7091 default:
f31b035a 7092 goto cp0_unimplemented;
876d4b07 7093 }
9c2149c8
TS
7094 break;
7095 case 5:
7096 switch (sel) {
7097 case 0:
895c2d04 7098 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7099 rn = "PageMask";
7100 break;
9c2149c8 7101 case 1:
d75c135e 7102 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7103 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7104 rn = "PageGrain";
7105 break;
9c2149c8 7106 default:
f31b035a 7107 goto cp0_unimplemented;
876d4b07 7108 }
9c2149c8
TS
7109 break;
7110 case 6:
7111 switch (sel) {
7112 case 0:
895c2d04 7113 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7114 rn = "Wired";
7115 break;
9c2149c8 7116 case 1:
d75c135e 7117 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7118 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7119 rn = "SRSConf0";
ead9360e 7120 break;
9c2149c8 7121 case 2:
d75c135e 7122 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7123 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7124 rn = "SRSConf1";
ead9360e 7125 break;
9c2149c8 7126 case 3:
d75c135e 7127 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7128 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7129 rn = "SRSConf2";
ead9360e 7130 break;
9c2149c8 7131 case 4:
d75c135e 7132 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7133 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7134 rn = "SRSConf3";
ead9360e 7135 break;
9c2149c8 7136 case 5:
d75c135e 7137 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7138 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7139 rn = "SRSConf4";
ead9360e 7140 break;
9c2149c8 7141 default:
f31b035a 7142 goto cp0_unimplemented;
876d4b07 7143 }
9c2149c8
TS
7144 break;
7145 case 7:
7146 switch (sel) {
7147 case 0:
d75c135e 7148 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7149 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7150 ctx->bstate = BS_STOP;
2423f660
TS
7151 rn = "HWREna";
7152 break;
9c2149c8 7153 default:
f31b035a 7154 goto cp0_unimplemented;
876d4b07 7155 }
9c2149c8
TS
7156 break;
7157 case 8:
aea14095
LA
7158 switch (sel) {
7159 case 0:
7160 /* ignored */
7161 rn = "BadVAddr";
7162 break;
7163 case 1:
7164 /* ignored */
7165 rn = "BadInstr";
7166 break;
7167 case 2:
7168 /* ignored */
7169 rn = "BadInstrP";
7170 break;
7171 default:
f31b035a 7172 goto cp0_unimplemented;
aea14095 7173 }
9c2149c8
TS
7174 break;
7175 case 9:
7176 switch (sel) {
7177 case 0:
895c2d04 7178 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7179 rn = "Count";
7180 break;
876d4b07 7181 /* 6,7 are implementation dependent */
9c2149c8 7182 default:
f31b035a 7183 goto cp0_unimplemented;
876d4b07
TS
7184 }
7185 /* Stop translation as we may have switched the execution mode */
7186 ctx->bstate = BS_STOP;
9c2149c8
TS
7187 break;
7188 case 10:
7189 switch (sel) {
7190 case 0:
895c2d04 7191 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7192 rn = "EntryHi";
7193 break;
9c2149c8 7194 default:
f31b035a 7195 goto cp0_unimplemented;
876d4b07 7196 }
9c2149c8
TS
7197 break;
7198 case 11:
7199 switch (sel) {
7200 case 0:
895c2d04 7201 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7202 rn = "Compare";
7203 break;
876d4b07 7204 /* 6,7 are implementation dependent */
9c2149c8 7205 default:
f31b035a 7206 goto cp0_unimplemented;
876d4b07 7207 }
de9a95f0
AJ
7208 /* Stop translation as we may have switched the execution mode */
7209 ctx->bstate = BS_STOP;
9c2149c8
TS
7210 break;
7211 case 12:
7212 switch (sel) {
7213 case 0:
867abc7e 7214 save_cpu_state(ctx, 1);
895c2d04 7215 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7216 /* BS_STOP isn't good enough here, hflags may have changed. */
7217 gen_save_pc(ctx->pc + 4);
7218 ctx->bstate = BS_EXCP;
2423f660
TS
7219 rn = "Status";
7220 break;
9c2149c8 7221 case 1:
d75c135e 7222 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7223 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7224 /* Stop translation as we may have switched the execution mode */
7225 ctx->bstate = BS_STOP;
2423f660
TS
7226 rn = "IntCtl";
7227 break;
9c2149c8 7228 case 2:
d75c135e 7229 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7230 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7231 /* Stop translation as we may have switched the execution mode */
7232 ctx->bstate = BS_STOP;
2423f660
TS
7233 rn = "SRSCtl";
7234 break;
9c2149c8 7235 case 3:
d75c135e 7236 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7237 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx->bstate = BS_STOP;
2423f660
TS
7240 rn = "SRSMap";
7241 break;
7242 default:
f31b035a 7243 goto cp0_unimplemented;
876d4b07 7244 }
9c2149c8
TS
7245 break;
7246 case 13:
7247 switch (sel) {
7248 case 0:
867abc7e 7249 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7250 /* Mark as an IO operation because we may trigger a software
7251 interrupt. */
bd79255d 7252 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7253 gen_io_start();
7254 }
895c2d04 7255 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7256 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7257 gen_io_end();
7258 }
7259 /* Stop translation as we may have triggered an intetrupt */
7260 ctx->bstate = BS_STOP;
2423f660
TS
7261 rn = "Cause";
7262 break;
9c2149c8 7263 default:
f31b035a 7264 goto cp0_unimplemented;
876d4b07 7265 }
9c2149c8
TS
7266 break;
7267 case 14:
7268 switch (sel) {
7269 case 0:
7db13fae 7270 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7271 rn = "EPC";
7272 break;
9c2149c8 7273 default:
f31b035a 7274 goto cp0_unimplemented;
876d4b07 7275 }
9c2149c8
TS
7276 break;
7277 case 15:
7278 switch (sel) {
7279 case 0:
2423f660
TS
7280 /* ignored */
7281 rn = "PRid";
7282 break;
9c2149c8 7283 case 1:
d75c135e 7284 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7285 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7286 rn = "EBase";
7287 break;
9c2149c8 7288 default:
f31b035a 7289 goto cp0_unimplemented;
876d4b07 7290 }
9c2149c8
TS
7291 break;
7292 case 16:
7293 switch (sel) {
7294 case 0:
895c2d04 7295 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7296 rn = "Config";
2423f660
TS
7297 /* Stop translation as we may have switched the execution mode */
7298 ctx->bstate = BS_STOP;
9c2149c8
TS
7299 break;
7300 case 1:
1fc7bf6e 7301 /* ignored, read only */
9c2149c8
TS
7302 rn = "Config1";
7303 break;
7304 case 2:
895c2d04 7305 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7306 rn = "Config2";
2423f660
TS
7307 /* Stop translation as we may have switched the execution mode */
7308 ctx->bstate = BS_STOP;
9c2149c8
TS
7309 break;
7310 case 3:
90f12d73 7311 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7312 rn = "Config3";
90f12d73
MR
7313 /* Stop translation as we may have switched the execution mode */
7314 ctx->bstate = BS_STOP;
9c2149c8 7315 break;
faf1f68b
LA
7316 case 4:
7317 /* currently ignored */
7318 rn = "Config4";
7319 break;
7320 case 5:
7321 gen_helper_mtc0_config5(cpu_env, arg);
7322 rn = "Config5";
7323 /* Stop translation as we may have switched the execution mode */
7324 ctx->bstate = BS_STOP;
7325 break;
9c2149c8
TS
7326 /* 6,7 are implementation dependent */
7327 default:
7328 rn = "Invalid config selector";
f31b035a 7329 goto cp0_unimplemented;
9c2149c8 7330 }
9c2149c8
TS
7331 break;
7332 case 17:
7333 switch (sel) {
7334 case 0:
895c2d04 7335 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7336 rn = "LLAddr";
7337 break;
f6d4dd81
YK
7338 case 1:
7339 CP0_CHECK(ctx->mrp);
7340 gen_helper_mtc0_maar(cpu_env, arg);
7341 rn = "MAAR";
7342 break;
7343 case 2:
7344 CP0_CHECK(ctx->mrp);
7345 gen_helper_mtc0_maari(cpu_env, arg);
7346 rn = "MAARI";
7347 break;
9c2149c8 7348 default:
f31b035a 7349 goto cp0_unimplemented;
9c2149c8
TS
7350 }
7351 break;
7352 case 18:
7353 switch (sel) {
fd88b6ab 7354 case 0 ... 7:
895c2d04 7355 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7356 rn = "WatchLo";
7357 break;
9c2149c8 7358 default:
f31b035a 7359 goto cp0_unimplemented;
9c2149c8
TS
7360 }
7361 break;
7362 case 19:
7363 switch (sel) {
fd88b6ab 7364 case 0 ... 7:
895c2d04 7365 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7366 rn = "WatchHi";
7367 break;
9c2149c8 7368 default:
f31b035a 7369 goto cp0_unimplemented;
9c2149c8
TS
7370 }
7371 break;
7372 case 20:
7373 switch (sel) {
7374 case 0:
d75c135e 7375 check_insn(ctx, ISA_MIPS3);
895c2d04 7376 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7377 rn = "XContext";
7378 break;
9c2149c8 7379 default:
f31b035a 7380 goto cp0_unimplemented;
9c2149c8
TS
7381 }
7382 break;
7383 case 21:
7384 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7385 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7386 switch (sel) {
7387 case 0:
895c2d04 7388 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7389 rn = "Framemask";
7390 break;
9c2149c8 7391 default:
f31b035a 7392 goto cp0_unimplemented;
9c2149c8
TS
7393 }
7394 break;
7395 case 22:
7396 /* ignored */
7397 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7398 break;
9c2149c8
TS
7399 case 23:
7400 switch (sel) {
7401 case 0:
895c2d04 7402 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7403 /* BS_STOP isn't good enough here, hflags may have changed. */
7404 gen_save_pc(ctx->pc + 4);
7405 ctx->bstate = BS_EXCP;
2423f660
TS
7406 rn = "Debug";
7407 break;
9c2149c8 7408 case 1:
895c2d04 7409// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7410 /* Stop translation as we may have switched the execution mode */
7411 ctx->bstate = BS_STOP;
2423f660
TS
7412 rn = "TraceControl";
7413// break;
9c2149c8 7414 case 2:
895c2d04 7415// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7416 /* Stop translation as we may have switched the execution mode */
7417 ctx->bstate = BS_STOP;
2423f660
TS
7418 rn = "TraceControl2";
7419// break;
9c2149c8 7420 case 3:
895c2d04 7421// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7422 /* Stop translation as we may have switched the execution mode */
7423 ctx->bstate = BS_STOP;
2423f660
TS
7424 rn = "UserTraceData";
7425// break;
9c2149c8 7426 case 4:
895c2d04 7427// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7428 /* Stop translation as we may have switched the execution mode */
7429 ctx->bstate = BS_STOP;
2423f660
TS
7430 rn = "TraceBPC";
7431// break;
9c2149c8 7432 default:
f31b035a 7433 goto cp0_unimplemented;
9c2149c8 7434 }
9c2149c8
TS
7435 break;
7436 case 24:
7437 switch (sel) {
7438 case 0:
f1aa6320 7439 /* EJTAG support */
7db13fae 7440 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7441 rn = "DEPC";
7442 break;
9c2149c8 7443 default:
f31b035a 7444 goto cp0_unimplemented;
9c2149c8
TS
7445 }
7446 break;
7447 case 25:
7448 switch (sel) {
7449 case 0:
895c2d04 7450 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7451 rn = "Performance0";
7452 break;
9c2149c8 7453 case 1:
895c2d04 7454// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7455 rn = "Performance1";
7456// break;
9c2149c8 7457 case 2:
895c2d04 7458// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7459 rn = "Performance2";
7460// break;
9c2149c8 7461 case 3:
895c2d04 7462// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7463 rn = "Performance3";
7464// break;
9c2149c8 7465 case 4:
895c2d04 7466// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7467 rn = "Performance4";
7468// break;
9c2149c8 7469 case 5:
895c2d04 7470// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7471 rn = "Performance5";
7472// break;
9c2149c8 7473 case 6:
895c2d04 7474// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7475 rn = "Performance6";
7476// break;
9c2149c8 7477 case 7:
895c2d04 7478// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7479 rn = "Performance7";
7480// break;
9c2149c8 7481 default:
f31b035a 7482 goto cp0_unimplemented;
9c2149c8 7483 }
876d4b07 7484 break;
9c2149c8 7485 case 26:
0d74a222
LA
7486 switch (sel) {
7487 case 0:
7488 gen_helper_mtc0_errctl(cpu_env, arg);
7489 ctx->bstate = BS_STOP;
7490 rn = "ErrCtl";
7491 break;
7492 default:
7493 goto cp0_unimplemented;
7494 }
876d4b07 7495 break;
9c2149c8
TS
7496 case 27:
7497 switch (sel) {
7498 case 0 ... 3:
2423f660
TS
7499 /* ignored */
7500 rn = "CacheErr";
7501 break;
9c2149c8 7502 default:
f31b035a 7503 goto cp0_unimplemented;
9c2149c8 7504 }
876d4b07 7505 break;
9c2149c8
TS
7506 case 28:
7507 switch (sel) {
7508 case 0:
7509 case 2:
7510 case 4:
7511 case 6:
895c2d04 7512 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7513 rn = "TagLo";
7514 break;
7515 case 1:
7516 case 3:
7517 case 5:
7518 case 7:
895c2d04 7519 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7520 rn = "DataLo";
7521 break;
7522 default:
f31b035a 7523 goto cp0_unimplemented;
9c2149c8
TS
7524 }
7525 break;
7526 case 29:
7527 switch (sel) {
7528 case 0:
7529 case 2:
7530 case 4:
7531 case 6:
895c2d04 7532 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7533 rn = "TagHi";
7534 break;
7535 case 1:
7536 case 3:
7537 case 5:
7538 case 7:
895c2d04 7539 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7540 rn = "DataHi";
7541 break;
7542 default:
7543 rn = "invalid sel";
f31b035a 7544 goto cp0_unimplemented;
9c2149c8 7545 }
876d4b07 7546 break;
9c2149c8
TS
7547 case 30:
7548 switch (sel) {
7549 case 0:
7db13fae 7550 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7551 rn = "ErrorEPC";
7552 break;
9c2149c8 7553 default:
f31b035a 7554 goto cp0_unimplemented;
9c2149c8
TS
7555 }
7556 break;
7557 case 31:
7558 switch (sel) {
7559 case 0:
f1aa6320 7560 /* EJTAG support */
7db13fae 7561 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7562 rn = "DESAVE";
7563 break;
e98c0d17 7564 case 2 ... 7:
f31b035a
LA
7565 CP0_CHECK(ctx->kscrexist & (1 << sel));
7566 tcg_gen_st_tl(arg, cpu_env,
7567 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7568 rn = "KScratch";
e98c0d17 7569 break;
9c2149c8 7570 default:
f31b035a 7571 goto cp0_unimplemented;
9c2149c8 7572 }
876d4b07
TS
7573 /* Stop translation as we may have switched the execution mode */
7574 ctx->bstate = BS_STOP;
9c2149c8
TS
7575 break;
7576 default:
f31b035a 7577 goto cp0_unimplemented;
9c2149c8 7578 }
2abf314d 7579 (void)rn; /* avoid a compiler warning */
d12d51d5 7580 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7581 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7582 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7583 gen_io_end();
7584 ctx->bstate = BS_STOP;
7585 }
9c2149c8
TS
7586 return;
7587
f31b035a 7588cp0_unimplemented:
d12d51d5 7589 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7590}
d26bc211 7591#endif /* TARGET_MIPS64 */
9c2149c8 7592
7db13fae 7593static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7594 int u, int sel, int h)
7595{
7596 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7597 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7598
7599 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7600 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7601 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7602 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7603 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7604 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7605 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7606 else if (u == 0) {
7607 switch (rt) {
5a25ce94
EI
7608 case 1:
7609 switch (sel) {
7610 case 1:
895c2d04 7611 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7612 break;
7613 case 2:
895c2d04 7614 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7615 break;
7616 default:
7617 goto die;
7618 break;
7619 }
7620 break;
ead9360e
TS
7621 case 2:
7622 switch (sel) {
7623 case 1:
895c2d04 7624 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7625 break;
7626 case 2:
895c2d04 7627 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7628 break;
7629 case 3:
895c2d04 7630 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7631 break;
7632 case 4:
895c2d04 7633 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7634 break;
7635 case 5:
895c2d04 7636 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7637 break;
7638 case 6:
895c2d04 7639 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7640 break;
7641 case 7:
895c2d04 7642 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7643 break;
7644 default:
d75c135e 7645 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7646 break;
7647 }
7648 break;
7649 case 10:
7650 switch (sel) {
7651 case 0:
895c2d04 7652 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7653 break;
7654 default:
d75c135e 7655 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7656 break;
7657 }
7658 case 12:
7659 switch (sel) {
7660 case 0:
895c2d04 7661 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7662 break;
7663 default:
d75c135e 7664 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7665 break;
7666 }
5a25ce94
EI
7667 case 13:
7668 switch (sel) {
7669 case 0:
895c2d04 7670 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7671 break;
7672 default:
7673 goto die;
7674 break;
7675 }
7676 break;
7677 case 14:
7678 switch (sel) {
7679 case 0:
895c2d04 7680 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7681 break;
7682 default:
7683 goto die;
7684 break;
7685 }
7686 break;
7687 case 15:
7688 switch (sel) {
7689 case 1:
895c2d04 7690 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7691 break;
7692 default:
7693 goto die;
7694 break;
7695 }
7696 break;
7697 case 16:
7698 switch (sel) {
7699 case 0 ... 7:
895c2d04 7700 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7701 break;
7702 default:
7703 goto die;
7704 break;
7705 }
7706 break;
ead9360e
TS
7707 case 23:
7708 switch (sel) {
7709 case 0:
895c2d04 7710 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7711 break;
7712 default:
d75c135e 7713 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7714 break;
7715 }
7716 break;
7717 default:
d75c135e 7718 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7719 }
7720 } else switch (sel) {
7721 /* GPR registers. */
7722 case 0:
895c2d04 7723 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7724 break;
7725 /* Auxiliary CPU registers */
7726 case 1:
7727 switch (rt) {
7728 case 0:
895c2d04 7729 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7730 break;
7731 case 1:
895c2d04 7732 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7733 break;
7734 case 2:
895c2d04 7735 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7736 break;
7737 case 4:
895c2d04 7738 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7739 break;
7740 case 5:
895c2d04 7741 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7742 break;
7743 case 6:
895c2d04 7744 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7745 break;
7746 case 8:
895c2d04 7747 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7748 break;
7749 case 9:
895c2d04 7750 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7751 break;
7752 case 10:
895c2d04 7753 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7754 break;
7755 case 12:
895c2d04 7756 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7757 break;
7758 case 13:
895c2d04 7759 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7760 break;
7761 case 14:
895c2d04 7762 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7763 break;
7764 case 16:
895c2d04 7765 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7766 break;
7767 default:
7768 goto die;
7769 }
7770 break;
7771 /* Floating point (COP1). */
7772 case 2:
7773 /* XXX: For now we support only a single FPU context. */
7774 if (h == 0) {
a7812ae4 7775 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7776
7c979afd 7777 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7778 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7779 tcg_temp_free_i32(fp0);
ead9360e 7780 } else {
a7812ae4 7781 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7782
7f6613ce 7783 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7784 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7785 tcg_temp_free_i32(fp0);
ead9360e
TS
7786 }
7787 break;
7788 case 3:
7789 /* XXX: For now we support only a single FPU context. */
895c2d04 7790 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7791 break;
7792 /* COP2: Not implemented. */
7793 case 4:
7794 case 5:
7795 /* fall through */
7796 default:
7797 goto die;
7798 }
d12d51d5 7799 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7800 gen_store_gpr(t0, rd);
7801 tcg_temp_free(t0);
ead9360e
TS
7802 return;
7803
7804die:
1a3fd9c3 7805 tcg_temp_free(t0);
d12d51d5 7806 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7807 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7808}
7809
7db13fae 7810static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7811 int u, int sel, int h)
7812{
7813 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7814 TCGv t0 = tcg_temp_local_new();
ead9360e 7815
1a3fd9c3 7816 gen_load_gpr(t0, rt);
ead9360e 7817 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7818 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7819 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7820 /* NOP */ ;
7821 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7822 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7823 /* NOP */ ;
7824 else if (u == 0) {
7825 switch (rd) {
5a25ce94
EI
7826 case 1:
7827 switch (sel) {
7828 case 1:
895c2d04 7829 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7830 break;
7831 case 2:
895c2d04 7832 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7833 break;
7834 default:
7835 goto die;
7836 break;
7837 }
7838 break;
ead9360e
TS
7839 case 2:
7840 switch (sel) {
7841 case 1:
895c2d04 7842 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7843 break;
7844 case 2:
895c2d04 7845 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7846 break;
7847 case 3:
895c2d04 7848 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7849 break;
7850 case 4:
895c2d04 7851 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7852 break;
7853 case 5:
895c2d04 7854 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7855 break;
7856 case 6:
895c2d04 7857 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7858 break;
7859 case 7:
895c2d04 7860 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7861 break;
7862 default:
d75c135e 7863 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7864 break;
7865 }
7866 break;
7867 case 10:
7868 switch (sel) {
7869 case 0:
895c2d04 7870 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7871 break;
7872 default:
d75c135e 7873 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7874 break;
7875 }
7876 case 12:
7877 switch (sel) {
7878 case 0:
895c2d04 7879 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7880 break;
7881 default:
d75c135e 7882 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7883 break;
7884 }
5a25ce94
EI
7885 case 13:
7886 switch (sel) {
7887 case 0:
895c2d04 7888 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7889 break;
7890 default:
7891 goto die;
7892 break;
7893 }
7894 break;
7895 case 15:
7896 switch (sel) {
7897 case 1:
895c2d04 7898 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7899 break;
7900 default:
7901 goto die;
7902 break;
7903 }
7904 break;
ead9360e
TS
7905 case 23:
7906 switch (sel) {
7907 case 0:
895c2d04 7908 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7909 break;
7910 default:
d75c135e 7911 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7912 break;
7913 }
7914 break;
7915 default:
d75c135e 7916 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7917 }
7918 } else switch (sel) {
7919 /* GPR registers. */
7920 case 0:
895c2d04 7921 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7922 break;
7923 /* Auxiliary CPU registers */
7924 case 1:
7925 switch (rd) {
7926 case 0:
895c2d04 7927 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7928 break;
7929 case 1:
895c2d04 7930 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7931 break;
7932 case 2:
895c2d04 7933 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7934 break;
7935 case 4:
895c2d04 7936 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7937 break;
7938 case 5:
895c2d04 7939 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7940 break;
7941 case 6:
895c2d04 7942 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7943 break;
7944 case 8:
895c2d04 7945 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7946 break;
7947 case 9:
895c2d04 7948 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7949 break;
7950 case 10:
895c2d04 7951 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7952 break;
7953 case 12:
895c2d04 7954 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7955 break;
7956 case 13:
895c2d04 7957 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7958 break;
7959 case 14:
895c2d04 7960 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7961 break;
7962 case 16:
895c2d04 7963 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7964 break;
7965 default:
7966 goto die;
7967 }
7968 break;
7969 /* Floating point (COP1). */
7970 case 2:
7971 /* XXX: For now we support only a single FPU context. */
7972 if (h == 0) {
a7812ae4 7973 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7974
7975 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7976 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7977 tcg_temp_free_i32(fp0);
ead9360e 7978 } else {
a7812ae4 7979 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7980
7981 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7982 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7983 tcg_temp_free_i32(fp0);
ead9360e
TS
7984 }
7985 break;
7986 case 3:
7987 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7988 {
7989 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7990
7991 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7992 tcg_temp_free_i32(fs_tmp);
7993 }
4cf8a45f
YK
7994 /* Stop translation as we may have changed hflags */
7995 ctx->bstate = BS_STOP;
ead9360e
TS
7996 break;
7997 /* COP2: Not implemented. */
7998 case 4:
7999 case 5:
8000 /* fall through */
8001 default:
8002 goto die;
8003 }
d12d51d5 8004 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 8005 tcg_temp_free(t0);
ead9360e
TS
8006 return;
8007
8008die:
1a3fd9c3 8009 tcg_temp_free(t0);
d12d51d5 8010 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8011 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8012}
8013
7db13fae 8014static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8015{
287c4b84 8016 const char *opn = "ldst";
6af0bf9c 8017
2e15497c 8018 check_cp0_enabled(ctx);
6af0bf9c
FB
8019 switch (opc) {
8020 case OPC_MFC0:
8021 if (rt == 0) {
ead9360e 8022 /* Treat as NOP. */
6af0bf9c
FB
8023 return;
8024 }
d75c135e 8025 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8026 opn = "mfc0";
8027 break;
8028 case OPC_MTC0:
1a3fd9c3 8029 {
1fc7bf6e 8030 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8031
8032 gen_load_gpr(t0, rt);
d75c135e 8033 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8034 tcg_temp_free(t0);
8035 }
6af0bf9c
FB
8036 opn = "mtc0";
8037 break;
d26bc211 8038#if defined(TARGET_MIPS64)
9c2149c8 8039 case OPC_DMFC0:
d75c135e 8040 check_insn(ctx, ISA_MIPS3);
9c2149c8 8041 if (rt == 0) {
ead9360e 8042 /* Treat as NOP. */
9c2149c8
TS
8043 return;
8044 }
d75c135e 8045 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8046 opn = "dmfc0";
8047 break;
8048 case OPC_DMTC0:
d75c135e 8049 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8050 {
1fc7bf6e 8051 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8052
8053 gen_load_gpr(t0, rt);
d75c135e 8054 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8055 tcg_temp_free(t0);
8056 }
9c2149c8
TS
8057 opn = "dmtc0";
8058 break;
534ce69f 8059#endif
5204ea79
LA
8060 case OPC_MFHC0:
8061 check_mvh(ctx);
8062 if (rt == 0) {
8063 /* Treat as NOP. */
8064 return;
8065 }
8066 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8067 opn = "mfhc0";
8068 break;
8069 case OPC_MTHC0:
8070 check_mvh(ctx);
8071 {
8072 TCGv t0 = tcg_temp_new();
8073 gen_load_gpr(t0, rt);
8074 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8075 tcg_temp_free(t0);
8076 }
8077 opn = "mthc0";
8078 break;
ead9360e 8079 case OPC_MFTR:
d75c135e 8080 check_insn(ctx, ASE_MT);
ead9360e
TS
8081 if (rd == 0) {
8082 /* Treat as NOP. */
8083 return;
8084 }
6c5c1e20 8085 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8086 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8087 opn = "mftr";
8088 break;
8089 case OPC_MTTR:
d75c135e 8090 check_insn(ctx, ASE_MT);
6c5c1e20 8091 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8092 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8093 opn = "mttr";
8094 break;
6af0bf9c 8095 case OPC_TLBWI:
6af0bf9c 8096 opn = "tlbwi";
c01fccd2 8097 if (!env->tlb->helper_tlbwi)
29929e34 8098 goto die;
895c2d04 8099 gen_helper_tlbwi(cpu_env);
6af0bf9c 8100 break;
9456c2fb
LA
8101 case OPC_TLBINV:
8102 opn = "tlbinv";
8103 if (ctx->ie >= 2) {
8104 if (!env->tlb->helper_tlbinv) {
8105 goto die;
8106 }
8107 gen_helper_tlbinv(cpu_env);
8108 } /* treat as nop if TLBINV not supported */
8109 break;
8110 case OPC_TLBINVF:
8111 opn = "tlbinvf";
8112 if (ctx->ie >= 2) {
8113 if (!env->tlb->helper_tlbinvf) {
8114 goto die;
8115 }
8116 gen_helper_tlbinvf(cpu_env);
8117 } /* treat as nop if TLBINV not supported */
8118 break;
6af0bf9c 8119 case OPC_TLBWR:
6af0bf9c 8120 opn = "tlbwr";
c01fccd2 8121 if (!env->tlb->helper_tlbwr)
29929e34 8122 goto die;
895c2d04 8123 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8124 break;
8125 case OPC_TLBP:
6af0bf9c 8126 opn = "tlbp";
c01fccd2 8127 if (!env->tlb->helper_tlbp)
29929e34 8128 goto die;
895c2d04 8129 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8130 break;
8131 case OPC_TLBR:
6af0bf9c 8132 opn = "tlbr";
c01fccd2 8133 if (!env->tlb->helper_tlbr)
29929e34 8134 goto die;
895c2d04 8135 gen_helper_tlbr(cpu_env);
6af0bf9c 8136 break;
ce9782f4 8137 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8138 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8139 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8140 goto die;
ce9782f4
LA
8141 } else {
8142 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8143 if (ctx->opcode & (1 << bit_shift)) {
8144 /* OPC_ERETNC */
8145 opn = "eretnc";
8146 check_insn(ctx, ISA_MIPS32R5);
8147 gen_helper_eretnc(cpu_env);
8148 } else {
8149 /* OPC_ERET */
8150 opn = "eret";
8151 check_insn(ctx, ISA_MIPS2);
8152 gen_helper_eret(cpu_env);
8153 }
8154 ctx->bstate = BS_EXCP;
339cd2a8 8155 }
6af0bf9c
FB
8156 break;
8157 case OPC_DERET:
8158 opn = "deret";
d75c135e 8159 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8160 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8161 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8162 goto die;
8163 }
6af0bf9c 8164 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8165 MIPS_INVAL(opn);
9c708c7f 8166 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8167 } else {
895c2d04 8168 gen_helper_deret(cpu_env);
6af0bf9c
FB
8169 ctx->bstate = BS_EXCP;
8170 }
8171 break;
4ad40f36
FB
8172 case OPC_WAIT:
8173 opn = "wait";
d75c135e 8174 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8175 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8176 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8177 goto die;
8178 }
4ad40f36
FB
8179 /* If we get an exception, we want to restart at next instruction */
8180 ctx->pc += 4;
8181 save_cpu_state(ctx, 1);
8182 ctx->pc -= 4;
895c2d04 8183 gen_helper_wait(cpu_env);
4ad40f36
FB
8184 ctx->bstate = BS_EXCP;
8185 break;
6af0bf9c 8186 default:
29929e34 8187 die:
923617a3 8188 MIPS_INVAL(opn);
9c708c7f 8189 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8190 return;
8191 }
2abf314d 8192 (void)opn; /* avoid a compiler warning */
6af0bf9c 8193}
f1aa6320 8194#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8195
6ea83fed 8196/* CP1 Branches (before delay slot) */
d75c135e
AJ
8197static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8198 int32_t cc, int32_t offset)
6ea83fed
FB
8199{
8200 target_ulong btarget;
a7812ae4 8201 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8202
339cd2a8 8203 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8204 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8205 goto out;
8206 }
8207
e189e748 8208 if (cc != 0)
d75c135e 8209 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8210
6ea83fed
FB
8211 btarget = ctx->pc + 4 + offset;
8212
7a387fff
TS
8213 switch (op) {
8214 case OPC_BC1F:
d94536f4
AJ
8215 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8216 tcg_gen_not_i32(t0, t0);
8217 tcg_gen_andi_i32(t0, t0, 1);
8218 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8219 goto not_likely;
7a387fff 8220 case OPC_BC1FL:
d94536f4
AJ
8221 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8222 tcg_gen_not_i32(t0, t0);
8223 tcg_gen_andi_i32(t0, t0, 1);
8224 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8225 goto likely;
7a387fff 8226 case OPC_BC1T:
d94536f4
AJ
8227 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8228 tcg_gen_andi_i32(t0, t0, 1);
8229 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8230 goto not_likely;
7a387fff 8231 case OPC_BC1TL:
d94536f4
AJ
8232 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8233 tcg_gen_andi_i32(t0, t0, 1);
8234 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8235 likely:
8236 ctx->hflags |= MIPS_HFLAG_BL;
8237 break;
5a5012ec 8238 case OPC_BC1FANY2:
a16336e4 8239 {
d94536f4
AJ
8240 TCGv_i32 t1 = tcg_temp_new_i32();
8241 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8242 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8243 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8244 tcg_temp_free_i32(t1);
d94536f4
AJ
8245 tcg_gen_andi_i32(t0, t0, 1);
8246 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8247 }
5a5012ec
TS
8248 goto not_likely;
8249 case OPC_BC1TANY2:
a16336e4 8250 {
d94536f4
AJ
8251 TCGv_i32 t1 = tcg_temp_new_i32();
8252 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8253 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8254 tcg_gen_or_i32(t0, t0, t1);
8255 tcg_temp_free_i32(t1);
8256 tcg_gen_andi_i32(t0, t0, 1);
8257 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8258 }
5a5012ec
TS
8259 goto not_likely;
8260 case OPC_BC1FANY4:
a16336e4 8261 {
d94536f4
AJ
8262 TCGv_i32 t1 = tcg_temp_new_i32();
8263 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8264 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8265 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8266 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8267 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8268 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8269 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8270 tcg_temp_free_i32(t1);
d94536f4
AJ
8271 tcg_gen_andi_i32(t0, t0, 1);
8272 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8273 }
5a5012ec
TS
8274 goto not_likely;
8275 case OPC_BC1TANY4:
a16336e4 8276 {
d94536f4
AJ
8277 TCGv_i32 t1 = tcg_temp_new_i32();
8278 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8279 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8280 tcg_gen_or_i32(t0, t0, t1);
8281 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8282 tcg_gen_or_i32(t0, t0, t1);
8283 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8284 tcg_gen_or_i32(t0, t0, t1);
8285 tcg_temp_free_i32(t1);
8286 tcg_gen_andi_i32(t0, t0, 1);
8287 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8288 }
5a5012ec
TS
8289 not_likely:
8290 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8291 break;
8292 default:
9d68ac14 8293 MIPS_INVAL("cp1 cond branch");
9c708c7f 8294 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8295 goto out;
6ea83fed 8296 }
6ea83fed 8297 ctx->btarget = btarget;
b231c103 8298 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8299 out:
a7812ae4 8300 tcg_temp_free_i32(t0);
6ea83fed
FB
8301}
8302
31837be3
YK
8303/* R6 CP1 Branches */
8304static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8305 int32_t ft, int32_t offset,
8306 int delayslot_size)
31837be3
YK
8307{
8308 target_ulong btarget;
31837be3
YK
8309 TCGv_i64 t0 = tcg_temp_new_i64();
8310
8311 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8312#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8313 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8314 "\n", ctx->pc);
31837be3 8315#endif
9c708c7f 8316 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8317 goto out;
8318 }
8319
8320 gen_load_fpr64(ctx, t0, ft);
8321 tcg_gen_andi_i64(t0, t0, 1);
8322
8323 btarget = addr_add(ctx, ctx->pc + 4, offset);
8324
8325 switch (op) {
8326 case OPC_BC1EQZ:
8327 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8328 ctx->hflags |= MIPS_HFLAG_BC;
8329 break;
8330 case OPC_BC1NEZ:
8331 /* t0 already set */
31837be3
YK
8332 ctx->hflags |= MIPS_HFLAG_BC;
8333 break;
8334 default:
9d68ac14 8335 MIPS_INVAL("cp1 cond branch");
9c708c7f 8336 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8337 goto out;
8338 }
8339
8340 tcg_gen_trunc_i64_tl(bcond, t0);
8341
31837be3 8342 ctx->btarget = btarget;
65935f07
YK
8343
8344 switch (delayslot_size) {
8345 case 2:
8346 ctx->hflags |= MIPS_HFLAG_BDS16;
8347 break;
8348 case 4:
8349 ctx->hflags |= MIPS_HFLAG_BDS32;
8350 break;
8351 }
31837be3
YK
8352
8353out:
8354 tcg_temp_free_i64(t0);
8355}
8356
6af0bf9c 8357/* Coprocessor 1 (FPU) */
5a5012ec 8358
5a5012ec
TS
8359#define FOP(func, fmt) (((fmt) << 21) | (func))
8360
bf4120ad
NF
8361enum fopcode {
8362 OPC_ADD_S = FOP(0, FMT_S),
8363 OPC_SUB_S = FOP(1, FMT_S),
8364 OPC_MUL_S = FOP(2, FMT_S),
8365 OPC_DIV_S = FOP(3, FMT_S),
8366 OPC_SQRT_S = FOP(4, FMT_S),
8367 OPC_ABS_S = FOP(5, FMT_S),
8368 OPC_MOV_S = FOP(6, FMT_S),
8369 OPC_NEG_S = FOP(7, FMT_S),
8370 OPC_ROUND_L_S = FOP(8, FMT_S),
8371 OPC_TRUNC_L_S = FOP(9, FMT_S),
8372 OPC_CEIL_L_S = FOP(10, FMT_S),
8373 OPC_FLOOR_L_S = FOP(11, FMT_S),
8374 OPC_ROUND_W_S = FOP(12, FMT_S),
8375 OPC_TRUNC_W_S = FOP(13, FMT_S),
8376 OPC_CEIL_W_S = FOP(14, FMT_S),
8377 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8378 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8379 OPC_MOVCF_S = FOP(17, FMT_S),
8380 OPC_MOVZ_S = FOP(18, FMT_S),
8381 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8382 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8383 OPC_RECIP_S = FOP(21, FMT_S),
8384 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8385 OPC_SELNEZ_S = FOP(23, FMT_S),
8386 OPC_MADDF_S = FOP(24, FMT_S),
8387 OPC_MSUBF_S = FOP(25, FMT_S),
8388 OPC_RINT_S = FOP(26, FMT_S),
8389 OPC_CLASS_S = FOP(27, FMT_S),
8390 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8391 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8392 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8393 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8394 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8395 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8396 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8397 OPC_RSQRT2_S = FOP(31, FMT_S),
8398 OPC_CVT_D_S = FOP(33, FMT_S),
8399 OPC_CVT_W_S = FOP(36, FMT_S),
8400 OPC_CVT_L_S = FOP(37, FMT_S),
8401 OPC_CVT_PS_S = FOP(38, FMT_S),
8402 OPC_CMP_F_S = FOP (48, FMT_S),
8403 OPC_CMP_UN_S = FOP (49, FMT_S),
8404 OPC_CMP_EQ_S = FOP (50, FMT_S),
8405 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8406 OPC_CMP_OLT_S = FOP (52, FMT_S),
8407 OPC_CMP_ULT_S = FOP (53, FMT_S),
8408 OPC_CMP_OLE_S = FOP (54, FMT_S),
8409 OPC_CMP_ULE_S = FOP (55, FMT_S),
8410 OPC_CMP_SF_S = FOP (56, FMT_S),
8411 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8412 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8413 OPC_CMP_NGL_S = FOP (59, FMT_S),
8414 OPC_CMP_LT_S = FOP (60, FMT_S),
8415 OPC_CMP_NGE_S = FOP (61, FMT_S),
8416 OPC_CMP_LE_S = FOP (62, FMT_S),
8417 OPC_CMP_NGT_S = FOP (63, FMT_S),
8418
8419 OPC_ADD_D = FOP(0, FMT_D),
8420 OPC_SUB_D = FOP(1, FMT_D),
8421 OPC_MUL_D = FOP(2, FMT_D),
8422 OPC_DIV_D = FOP(3, FMT_D),
8423 OPC_SQRT_D = FOP(4, FMT_D),
8424 OPC_ABS_D = FOP(5, FMT_D),
8425 OPC_MOV_D = FOP(6, FMT_D),
8426 OPC_NEG_D = FOP(7, FMT_D),
8427 OPC_ROUND_L_D = FOP(8, FMT_D),
8428 OPC_TRUNC_L_D = FOP(9, FMT_D),
8429 OPC_CEIL_L_D = FOP(10, FMT_D),
8430 OPC_FLOOR_L_D = FOP(11, FMT_D),
8431 OPC_ROUND_W_D = FOP(12, FMT_D),
8432 OPC_TRUNC_W_D = FOP(13, FMT_D),
8433 OPC_CEIL_W_D = FOP(14, FMT_D),
8434 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8435 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8436 OPC_MOVCF_D = FOP(17, FMT_D),
8437 OPC_MOVZ_D = FOP(18, FMT_D),
8438 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8439 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8440 OPC_RECIP_D = FOP(21, FMT_D),
8441 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8442 OPC_SELNEZ_D = FOP(23, FMT_D),
8443 OPC_MADDF_D = FOP(24, FMT_D),
8444 OPC_MSUBF_D = FOP(25, FMT_D),
8445 OPC_RINT_D = FOP(26, FMT_D),
8446 OPC_CLASS_D = FOP(27, FMT_D),
8447 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8448 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8449 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8450 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8451 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8452 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8453 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8454 OPC_RSQRT2_D = FOP(31, FMT_D),
8455 OPC_CVT_S_D = FOP(32, FMT_D),
8456 OPC_CVT_W_D = FOP(36, FMT_D),
8457 OPC_CVT_L_D = FOP(37, FMT_D),
8458 OPC_CMP_F_D = FOP (48, FMT_D),
8459 OPC_CMP_UN_D = FOP (49, FMT_D),
8460 OPC_CMP_EQ_D = FOP (50, FMT_D),
8461 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8462 OPC_CMP_OLT_D = FOP (52, FMT_D),
8463 OPC_CMP_ULT_D = FOP (53, FMT_D),
8464 OPC_CMP_OLE_D = FOP (54, FMT_D),
8465 OPC_CMP_ULE_D = FOP (55, FMT_D),
8466 OPC_CMP_SF_D = FOP (56, FMT_D),
8467 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8468 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8469 OPC_CMP_NGL_D = FOP (59, FMT_D),
8470 OPC_CMP_LT_D = FOP (60, FMT_D),
8471 OPC_CMP_NGE_D = FOP (61, FMT_D),
8472 OPC_CMP_LE_D = FOP (62, FMT_D),
8473 OPC_CMP_NGT_D = FOP (63, FMT_D),
8474
8475 OPC_CVT_S_W = FOP(32, FMT_W),
8476 OPC_CVT_D_W = FOP(33, FMT_W),
8477 OPC_CVT_S_L = FOP(32, FMT_L),
8478 OPC_CVT_D_L = FOP(33, FMT_L),
8479 OPC_CVT_PS_PW = FOP(38, FMT_W),
8480
8481 OPC_ADD_PS = FOP(0, FMT_PS),
8482 OPC_SUB_PS = FOP(1, FMT_PS),
8483 OPC_MUL_PS = FOP(2, FMT_PS),
8484 OPC_DIV_PS = FOP(3, FMT_PS),
8485 OPC_ABS_PS = FOP(5, FMT_PS),
8486 OPC_MOV_PS = FOP(6, FMT_PS),
8487 OPC_NEG_PS = FOP(7, FMT_PS),
8488 OPC_MOVCF_PS = FOP(17, FMT_PS),
8489 OPC_MOVZ_PS = FOP(18, FMT_PS),
8490 OPC_MOVN_PS = FOP(19, FMT_PS),
8491 OPC_ADDR_PS = FOP(24, FMT_PS),
8492 OPC_MULR_PS = FOP(26, FMT_PS),
8493 OPC_RECIP2_PS = FOP(28, FMT_PS),
8494 OPC_RECIP1_PS = FOP(29, FMT_PS),
8495 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8496 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8497
8498 OPC_CVT_S_PU = FOP(32, FMT_PS),
8499 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8500 OPC_CVT_S_PL = FOP(40, FMT_PS),
8501 OPC_PLL_PS = FOP(44, FMT_PS),
8502 OPC_PLU_PS = FOP(45, FMT_PS),
8503 OPC_PUL_PS = FOP(46, FMT_PS),
8504 OPC_PUU_PS = FOP(47, FMT_PS),
8505 OPC_CMP_F_PS = FOP (48, FMT_PS),
8506 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8507 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8508 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8509 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8510 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8511 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8512 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8513 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8514 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8515 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8516 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8517 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8518 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8519 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8520 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8521};
8522
3f493883
YK
8523enum r6_f_cmp_op {
8524 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8525 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8526 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8527 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8528 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8529 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8530 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8531 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8532 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8533 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8534 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8535 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8536 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8537 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8538 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8539 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8540 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8541 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8542 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8543 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8544 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8545 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8546
8547 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8548 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8549 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8550 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8551 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8552 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8553 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8554 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8555 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8556 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8557 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8558 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8559 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8560 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8561 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8562 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8563 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8564 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8565 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8566 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8567 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8568 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8569};
7a387fff 8570static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8571{
72c3a3ee 8572 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8573
8574 switch (opc) {
8575 case OPC_MFC1:
b6d96bed 8576 {
a7812ae4 8577 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8578
7c979afd 8579 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8580 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8581 tcg_temp_free_i32(fp0);
6958549d 8582 }
6c5c1e20 8583 gen_store_gpr(t0, rt);
6ea83fed
FB
8584 break;
8585 case OPC_MTC1:
6c5c1e20 8586 gen_load_gpr(t0, rt);
b6d96bed 8587 {
a7812ae4 8588 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8589
8590 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8591 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8592 tcg_temp_free_i32(fp0);
6958549d 8593 }
6ea83fed
FB
8594 break;
8595 case OPC_CFC1:
895c2d04 8596 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8597 gen_store_gpr(t0, rt);
6ea83fed
FB
8598 break;
8599 case OPC_CTC1:
6c5c1e20 8600 gen_load_gpr(t0, rt);
9c708c7f 8601 save_cpu_state(ctx, 0);
736d120a
PJ
8602 {
8603 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8604
8605 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8606 tcg_temp_free_i32(fs_tmp);
8607 }
4cf8a45f
YK
8608 /* Stop translation as we may have changed hflags */
8609 ctx->bstate = BS_STOP;
6ea83fed 8610 break;
72c3a3ee 8611#if defined(TARGET_MIPS64)
9c2149c8 8612 case OPC_DMFC1:
72c3a3ee 8613 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8614 gen_store_gpr(t0, rt);
5a5012ec 8615 break;
9c2149c8 8616 case OPC_DMTC1:
6c5c1e20 8617 gen_load_gpr(t0, rt);
72c3a3ee 8618 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8619 break;
72c3a3ee 8620#endif
5a5012ec 8621 case OPC_MFHC1:
b6d96bed 8622 {
a7812ae4 8623 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8624
7f6613ce 8625 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8626 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8627 tcg_temp_free_i32(fp0);
6958549d 8628 }
6c5c1e20 8629 gen_store_gpr(t0, rt);
5a5012ec
TS
8630 break;
8631 case OPC_MTHC1:
6c5c1e20 8632 gen_load_gpr(t0, rt);
b6d96bed 8633 {
a7812ae4 8634 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8635
8636 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8637 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8638 tcg_temp_free_i32(fp0);
6958549d 8639 }
5a5012ec 8640 break;
6ea83fed 8641 default:
9d68ac14 8642 MIPS_INVAL("cp1 move");
9c708c7f 8643 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8644 goto out;
6ea83fed 8645 }
6c5c1e20
TS
8646
8647 out:
8648 tcg_temp_free(t0);
6ea83fed
FB
8649}
8650
5a5012ec
TS
8651static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8652{
42a268c2 8653 TCGLabel *l1;
e214b9bb 8654 TCGCond cond;
af58f9ca
AJ
8655 TCGv_i32 t0;
8656
8657 if (rd == 0) {
8658 /* Treat as NOP. */
8659 return;
8660 }
6ea83fed 8661
e214b9bb 8662 if (tf)
e214b9bb 8663 cond = TCG_COND_EQ;
27848470
TS
8664 else
8665 cond = TCG_COND_NE;
8666
af58f9ca
AJ
8667 l1 = gen_new_label();
8668 t0 = tcg_temp_new_i32();
fa31af0e 8669 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8670 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8671 tcg_temp_free_i32(t0);
af58f9ca
AJ
8672 if (rs == 0) {
8673 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8674 } else {
8675 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8676 }
e214b9bb 8677 gen_set_label(l1);
5a5012ec
TS
8678}
8679
7c979afd
LA
8680static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8681 int tf)
a16336e4 8682{
a16336e4 8683 int cond;
cbc37b28 8684 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8685 TCGLabel *l1 = gen_new_label();
a16336e4 8686
a16336e4
TS
8687 if (tf)
8688 cond = TCG_COND_EQ;
8689 else
8690 cond = TCG_COND_NE;
8691
fa31af0e 8692 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8693 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8694 gen_load_fpr32(ctx, t0, fs);
8695 gen_store_fpr32(ctx, t0, fd);
a16336e4 8696 gen_set_label(l1);
cbc37b28 8697 tcg_temp_free_i32(t0);
5a5012ec 8698}
a16336e4 8699
b6d96bed 8700static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8701{
a16336e4 8702 int cond;
cbc37b28
AJ
8703 TCGv_i32 t0 = tcg_temp_new_i32();
8704 TCGv_i64 fp0;
42a268c2 8705 TCGLabel *l1 = gen_new_label();
a16336e4 8706
a16336e4
TS
8707 if (tf)
8708 cond = TCG_COND_EQ;
8709 else
8710 cond = TCG_COND_NE;
8711
fa31af0e 8712 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8713 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8714 tcg_temp_free_i32(t0);
11f94258 8715 fp0 = tcg_temp_new_i64();
9bf3eb2c 8716 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8717 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8718 tcg_temp_free_i64(fp0);
cbc37b28 8719 gen_set_label(l1);
a16336e4
TS
8720}
8721
7f6613ce
PJ
8722static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8723 int cc, int tf)
a16336e4
TS
8724{
8725 int cond;
cbc37b28 8726 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8727 TCGLabel *l1 = gen_new_label();
8728 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8729
8730 if (tf)
8731 cond = TCG_COND_EQ;
8732 else
8733 cond = TCG_COND_NE;
8734
fa31af0e 8735 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8736 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8737 gen_load_fpr32(ctx, t0, fs);
8738 gen_store_fpr32(ctx, t0, fd);
a16336e4 8739 gen_set_label(l1);
9bf3eb2c 8740
fa31af0e 8741 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8742 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8743 gen_load_fpr32h(ctx, t0, fs);
8744 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8745 tcg_temp_free_i32(t0);
a16336e4 8746 gen_set_label(l2);
a16336e4
TS
8747}
8748
e7f16abb
LA
8749static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8750 int fs)
8751{
8752 TCGv_i32 t1 = tcg_const_i32(0);
8753 TCGv_i32 fp0 = tcg_temp_new_i32();
8754 TCGv_i32 fp1 = tcg_temp_new_i32();
8755 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8756 gen_load_fpr32(ctx, fp0, fd);
8757 gen_load_fpr32(ctx, fp1, ft);
8758 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8759
8760 switch (op1) {
8761 case OPC_SEL_S:
8762 tcg_gen_andi_i32(fp0, fp0, 1);
8763 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8764 break;
8765 case OPC_SELEQZ_S:
8766 tcg_gen_andi_i32(fp1, fp1, 1);
8767 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8768 break;
8769 case OPC_SELNEZ_S:
8770 tcg_gen_andi_i32(fp1, fp1, 1);
8771 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8772 break;
8773 default:
8774 MIPS_INVAL("gen_sel_s");
9c708c7f 8775 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8776 break;
8777 }
8778
7c979afd 8779 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8780 tcg_temp_free_i32(fp2);
8781 tcg_temp_free_i32(fp1);
8782 tcg_temp_free_i32(fp0);
8783 tcg_temp_free_i32(t1);
8784}
8785
8786static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8787 int fs)
8788{
8789 TCGv_i64 t1 = tcg_const_i64(0);
8790 TCGv_i64 fp0 = tcg_temp_new_i64();
8791 TCGv_i64 fp1 = tcg_temp_new_i64();
8792 TCGv_i64 fp2 = tcg_temp_new_i64();
8793 gen_load_fpr64(ctx, fp0, fd);
8794 gen_load_fpr64(ctx, fp1, ft);
8795 gen_load_fpr64(ctx, fp2, fs);
8796
8797 switch (op1) {
8798 case OPC_SEL_D:
8799 tcg_gen_andi_i64(fp0, fp0, 1);
8800 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8801 break;
8802 case OPC_SELEQZ_D:
8803 tcg_gen_andi_i64(fp1, fp1, 1);
8804 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8805 break;
8806 case OPC_SELNEZ_D:
8807 tcg_gen_andi_i64(fp1, fp1, 1);
8808 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8809 break;
8810 default:
8811 MIPS_INVAL("gen_sel_d");
9c708c7f 8812 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8813 break;
8814 }
8815
8816 gen_store_fpr64(ctx, fp0, fd);
8817 tcg_temp_free_i64(fp2);
8818 tcg_temp_free_i64(fp1);
8819 tcg_temp_free_i64(fp0);
8820 tcg_temp_free_i64(t1);
8821}
6ea83fed 8822
bf4120ad 8823static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8824 int ft, int fs, int fd, int cc)
6ea83fed 8825{
7a387fff 8826 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8827 switch (op1) {
8828 case OPC_ADD_S:
b6d96bed 8829 {
a7812ae4
PB
8830 TCGv_i32 fp0 = tcg_temp_new_i32();
8831 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8832
7c979afd
LA
8833 gen_load_fpr32(ctx, fp0, fs);
8834 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8835 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8836 tcg_temp_free_i32(fp1);
7c979afd 8837 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8838 tcg_temp_free_i32(fp0);
b6d96bed 8839 }
5a5012ec 8840 break;
bf4120ad 8841 case OPC_SUB_S:
b6d96bed 8842 {
a7812ae4
PB
8843 TCGv_i32 fp0 = tcg_temp_new_i32();
8844 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8845
7c979afd
LA
8846 gen_load_fpr32(ctx, fp0, fs);
8847 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8848 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8849 tcg_temp_free_i32(fp1);
7c979afd 8850 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8851 tcg_temp_free_i32(fp0);
b6d96bed 8852 }
5a5012ec 8853 break;
bf4120ad 8854 case OPC_MUL_S:
b6d96bed 8855 {
a7812ae4
PB
8856 TCGv_i32 fp0 = tcg_temp_new_i32();
8857 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8858
7c979afd
LA
8859 gen_load_fpr32(ctx, fp0, fs);
8860 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8861 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8862 tcg_temp_free_i32(fp1);
7c979afd 8863 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8864 tcg_temp_free_i32(fp0);
b6d96bed 8865 }
5a5012ec 8866 break;
bf4120ad 8867 case OPC_DIV_S:
b6d96bed 8868 {
a7812ae4
PB
8869 TCGv_i32 fp0 = tcg_temp_new_i32();
8870 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8871
7c979afd
LA
8872 gen_load_fpr32(ctx, fp0, fs);
8873 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8874 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8875 tcg_temp_free_i32(fp1);
7c979afd 8876 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8877 tcg_temp_free_i32(fp0);
b6d96bed 8878 }
5a5012ec 8879 break;
bf4120ad 8880 case OPC_SQRT_S:
b6d96bed 8881 {
a7812ae4 8882 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8883
7c979afd 8884 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8885 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8886 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8887 tcg_temp_free_i32(fp0);
b6d96bed 8888 }
5a5012ec 8889 break;
bf4120ad 8890 case OPC_ABS_S:
b6d96bed 8891 {
a7812ae4 8892 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8893
7c979afd 8894 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
8895 if (ctx->abs2008) {
8896 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8897 } else {
8898 gen_helper_float_abs_s(fp0, fp0);
8899 }
7c979afd 8900 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8901 tcg_temp_free_i32(fp0);
b6d96bed 8902 }
5a5012ec 8903 break;
bf4120ad 8904 case OPC_MOV_S:
b6d96bed 8905 {
a7812ae4 8906 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8907
7c979afd
LA
8908 gen_load_fpr32(ctx, fp0, fs);
8909 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8910 tcg_temp_free_i32(fp0);
b6d96bed 8911 }
5a5012ec 8912 break;
bf4120ad 8913 case OPC_NEG_S:
b6d96bed 8914 {
a7812ae4 8915 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8916
7c979afd 8917 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
8918 if (ctx->abs2008) {
8919 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8920 } else {
8921 gen_helper_float_chs_s(fp0, fp0);
8922 }
7c979afd 8923 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8924 tcg_temp_free_i32(fp0);
b6d96bed 8925 }
5a5012ec 8926 break;
bf4120ad 8927 case OPC_ROUND_L_S:
5e755519 8928 check_cp1_64bitmode(ctx);
b6d96bed 8929 {
a7812ae4
PB
8930 TCGv_i32 fp32 = tcg_temp_new_i32();
8931 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8932
7c979afd 8933 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8934 if (ctx->nan2008) {
8935 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8936 } else {
8937 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8938 }
a7812ae4 8939 tcg_temp_free_i32(fp32);
b6d96bed 8940 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8941 tcg_temp_free_i64(fp64);
b6d96bed 8942 }
5a5012ec 8943 break;
bf4120ad 8944 case OPC_TRUNC_L_S:
5e755519 8945 check_cp1_64bitmode(ctx);
b6d96bed 8946 {
a7812ae4
PB
8947 TCGv_i32 fp32 = tcg_temp_new_i32();
8948 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8949
7c979afd 8950 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8951 if (ctx->nan2008) {
8952 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8953 } else {
8954 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8955 }
a7812ae4 8956 tcg_temp_free_i32(fp32);
b6d96bed 8957 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8958 tcg_temp_free_i64(fp64);
b6d96bed 8959 }
5a5012ec 8960 break;
bf4120ad 8961 case OPC_CEIL_L_S:
5e755519 8962 check_cp1_64bitmode(ctx);
b6d96bed 8963 {
a7812ae4
PB
8964 TCGv_i32 fp32 = tcg_temp_new_i32();
8965 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8966
7c979afd 8967 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8968 if (ctx->nan2008) {
8969 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8970 } else {
8971 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8972 }
a7812ae4 8973 tcg_temp_free_i32(fp32);
b6d96bed 8974 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8975 tcg_temp_free_i64(fp64);
b6d96bed 8976 }
5a5012ec 8977 break;
bf4120ad 8978 case OPC_FLOOR_L_S:
5e755519 8979 check_cp1_64bitmode(ctx);
b6d96bed 8980 {
a7812ae4
PB
8981 TCGv_i32 fp32 = tcg_temp_new_i32();
8982 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8983
7c979afd 8984 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8985 if (ctx->nan2008) {
8986 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8987 } else {
8988 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8989 }
a7812ae4 8990 tcg_temp_free_i32(fp32);
b6d96bed 8991 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8992 tcg_temp_free_i64(fp64);
b6d96bed 8993 }
5a5012ec 8994 break;
bf4120ad 8995 case OPC_ROUND_W_S:
b6d96bed 8996 {
a7812ae4 8997 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8998
7c979afd 8999 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9000 if (ctx->nan2008) {
9001 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9002 } else {
9003 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9004 }
7c979afd 9005 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9006 tcg_temp_free_i32(fp0);
b6d96bed 9007 }
5a5012ec 9008 break;
bf4120ad 9009 case OPC_TRUNC_W_S:
b6d96bed 9010 {
a7812ae4 9011 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9012
7c979afd 9013 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9014 if (ctx->nan2008) {
9015 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9016 } else {
9017 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9018 }
7c979afd 9019 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9020 tcg_temp_free_i32(fp0);
b6d96bed 9021 }
5a5012ec 9022 break;
bf4120ad 9023 case OPC_CEIL_W_S:
b6d96bed 9024 {
a7812ae4 9025 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9026
7c979afd 9027 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9028 if (ctx->nan2008) {
9029 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9030 } else {
9031 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9032 }
7c979afd 9033 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9034 tcg_temp_free_i32(fp0);
b6d96bed 9035 }
5a5012ec 9036 break;
bf4120ad 9037 case OPC_FLOOR_W_S:
b6d96bed 9038 {
a7812ae4 9039 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9040
7c979afd 9041 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9042 if (ctx->nan2008) {
9043 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9044 } else {
9045 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9046 }
7c979afd 9047 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9048 tcg_temp_free_i32(fp0);
b6d96bed 9049 }
5a5012ec 9050 break;
e7f16abb
LA
9051 case OPC_SEL_S:
9052 check_insn(ctx, ISA_MIPS32R6);
9053 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9054 break;
9055 case OPC_SELEQZ_S:
9056 check_insn(ctx, ISA_MIPS32R6);
9057 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9058 break;
9059 case OPC_SELNEZ_S:
9060 check_insn(ctx, ISA_MIPS32R6);
9061 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9062 break;
bf4120ad 9063 case OPC_MOVCF_S:
fecd2646 9064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9065 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9066 break;
bf4120ad 9067 case OPC_MOVZ_S:
fecd2646 9068 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9069 {
42a268c2 9070 TCGLabel *l1 = gen_new_label();
c9297f4d 9071 TCGv_i32 fp0;
a16336e4 9072
c9297f4d
AJ
9073 if (ft != 0) {
9074 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9075 }
9076 fp0 = tcg_temp_new_i32();
7c979afd
LA
9077 gen_load_fpr32(ctx, fp0, fs);
9078 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9079 tcg_temp_free_i32(fp0);
a16336e4
TS
9080 gen_set_label(l1);
9081 }
5a5012ec 9082 break;
bf4120ad 9083 case OPC_MOVN_S:
fecd2646 9084 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9085 {
42a268c2 9086 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9087 TCGv_i32 fp0;
9088
9089 if (ft != 0) {
9090 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9091 fp0 = tcg_temp_new_i32();
7c979afd
LA
9092 gen_load_fpr32(ctx, fp0, fs);
9093 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9094 tcg_temp_free_i32(fp0);
9095 gen_set_label(l1);
9096 }
a16336e4 9097 }
5a5012ec 9098 break;
bf4120ad 9099 case OPC_RECIP_S:
b6d96bed 9100 {
a7812ae4 9101 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9102
7c979afd 9103 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9104 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9105 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9106 tcg_temp_free_i32(fp0);
b6d96bed 9107 }
57fa1fb3 9108 break;
bf4120ad 9109 case OPC_RSQRT_S:
b6d96bed 9110 {
a7812ae4 9111 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9112
7c979afd 9113 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9114 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9115 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9116 tcg_temp_free_i32(fp0);
b6d96bed 9117 }
57fa1fb3 9118 break;
e7f16abb
LA
9119 case OPC_MADDF_S:
9120 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9121 {
a7812ae4
PB
9122 TCGv_i32 fp0 = tcg_temp_new_i32();
9123 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9124 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9125 gen_load_fpr32(ctx, fp0, fs);
9126 gen_load_fpr32(ctx, fp1, ft);
9127 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9128 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9129 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9130 tcg_temp_free_i32(fp2);
a7812ae4 9131 tcg_temp_free_i32(fp1);
a7812ae4 9132 tcg_temp_free_i32(fp0);
b6d96bed 9133 }
57fa1fb3 9134 break;
e7f16abb
LA
9135 case OPC_MSUBF_S:
9136 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9137 {
a7812ae4 9138 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9139 TCGv_i32 fp1 = tcg_temp_new_i32();
9140 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9141 gen_load_fpr32(ctx, fp0, fs);
9142 gen_load_fpr32(ctx, fp1, ft);
9143 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9144 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9145 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9146 tcg_temp_free_i32(fp2);
9147 tcg_temp_free_i32(fp1);
a7812ae4 9148 tcg_temp_free_i32(fp0);
b6d96bed 9149 }
57fa1fb3 9150 break;
e7f16abb
LA
9151 case OPC_RINT_S:
9152 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9153 {
a7812ae4 9154 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9155 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9156 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9157 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9158 tcg_temp_free_i32(fp0);
b6d96bed 9159 }
57fa1fb3 9160 break;
e7f16abb
LA
9161 case OPC_CLASS_S:
9162 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9163 {
e7f16abb 9164 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9165 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9166 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9167 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9168 tcg_temp_free_i32(fp0);
e7f16abb
LA
9169 }
9170 break;
9171 case OPC_MIN_S: /* OPC_RECIP2_S */
9172 if (ctx->insn_flags & ISA_MIPS32R6) {
9173 /* OPC_MIN_S */
a7812ae4
PB
9174 TCGv_i32 fp0 = tcg_temp_new_i32();
9175 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9176 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9177 gen_load_fpr32(ctx, fp0, fs);
9178 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9179 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9180 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9181 tcg_temp_free_i32(fp2);
9182 tcg_temp_free_i32(fp1);
9183 tcg_temp_free_i32(fp0);
e7f16abb
LA
9184 } else {
9185 /* OPC_RECIP2_S */
9186 check_cp1_64bitmode(ctx);
9187 {
9188 TCGv_i32 fp0 = tcg_temp_new_i32();
9189 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9190
7c979afd
LA
9191 gen_load_fpr32(ctx, fp0, fs);
9192 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9193 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9194 tcg_temp_free_i32(fp1);
7c979afd 9195 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9196 tcg_temp_free_i32(fp0);
9197 }
e7f16abb
LA
9198 }
9199 break;
9200 case OPC_MINA_S: /* OPC_RECIP1_S */
9201 if (ctx->insn_flags & ISA_MIPS32R6) {
9202 /* OPC_MINA_S */
9203 TCGv_i32 fp0 = tcg_temp_new_i32();
9204 TCGv_i32 fp1 = tcg_temp_new_i32();
9205 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9206 gen_load_fpr32(ctx, fp0, fs);
9207 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9208 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9209 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9210 tcg_temp_free_i32(fp2);
9211 tcg_temp_free_i32(fp1);
9212 tcg_temp_free_i32(fp0);
e7f16abb
LA
9213 } else {
9214 /* OPC_RECIP1_S */
9215 check_cp1_64bitmode(ctx);
9216 {
9217 TCGv_i32 fp0 = tcg_temp_new_i32();
9218
7c979afd 9219 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9220 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9221 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9222 tcg_temp_free_i32(fp0);
9223 }
e7f16abb
LA
9224 }
9225 break;
9226 case OPC_MAX_S: /* OPC_RSQRT1_S */
9227 if (ctx->insn_flags & ISA_MIPS32R6) {
9228 /* OPC_MAX_S */
9229 TCGv_i32 fp0 = tcg_temp_new_i32();
9230 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9231 gen_load_fpr32(ctx, fp0, fs);
9232 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9233 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9234 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9235 tcg_temp_free_i32(fp1);
9236 tcg_temp_free_i32(fp0);
e7f16abb
LA
9237 } else {
9238 /* OPC_RSQRT1_S */
9239 check_cp1_64bitmode(ctx);
9240 {
9241 TCGv_i32 fp0 = tcg_temp_new_i32();
9242
7c979afd 9243 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9244 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9245 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9246 tcg_temp_free_i32(fp0);
9247 }
e7f16abb
LA
9248 }
9249 break;
9250 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9251 if (ctx->insn_flags & ISA_MIPS32R6) {
9252 /* OPC_MAXA_S */
9253 TCGv_i32 fp0 = tcg_temp_new_i32();
9254 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9255 gen_load_fpr32(ctx, fp0, fs);
9256 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9257 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9258 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9259 tcg_temp_free_i32(fp1);
a7812ae4 9260 tcg_temp_free_i32(fp0);
e7f16abb
LA
9261 } else {
9262 /* OPC_RSQRT2_S */
9263 check_cp1_64bitmode(ctx);
9264 {
9265 TCGv_i32 fp0 = tcg_temp_new_i32();
9266 TCGv_i32 fp1 = tcg_temp_new_i32();
9267
7c979afd
LA
9268 gen_load_fpr32(ctx, fp0, fs);
9269 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9270 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9271 tcg_temp_free_i32(fp1);
7c979afd 9272 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9273 tcg_temp_free_i32(fp0);
9274 }
b6d96bed 9275 }
57fa1fb3 9276 break;
bf4120ad 9277 case OPC_CVT_D_S:
5e755519 9278 check_cp1_registers(ctx, fd);
b6d96bed 9279 {
a7812ae4
PB
9280 TCGv_i32 fp32 = tcg_temp_new_i32();
9281 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9282
7c979afd 9283 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9284 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9285 tcg_temp_free_i32(fp32);
b6d96bed 9286 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9287 tcg_temp_free_i64(fp64);
b6d96bed 9288 }
5a5012ec 9289 break;
bf4120ad 9290 case OPC_CVT_W_S:
b6d96bed 9291 {
a7812ae4 9292 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9293
7c979afd 9294 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9295 if (ctx->nan2008) {
9296 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9297 } else {
9298 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9299 }
7c979afd 9300 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9301 tcg_temp_free_i32(fp0);
b6d96bed 9302 }
5a5012ec 9303 break;
bf4120ad 9304 case OPC_CVT_L_S:
5e755519 9305 check_cp1_64bitmode(ctx);
b6d96bed 9306 {
a7812ae4
PB
9307 TCGv_i32 fp32 = tcg_temp_new_i32();
9308 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9309
7c979afd 9310 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9311 if (ctx->nan2008) {
9312 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9313 } else {
9314 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9315 }
a7812ae4 9316 tcg_temp_free_i32(fp32);
b6d96bed 9317 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9318 tcg_temp_free_i64(fp64);
b6d96bed 9319 }
5a5012ec 9320 break;
bf4120ad 9321 case OPC_CVT_PS_S:
e29c9628 9322 check_ps(ctx);
b6d96bed 9323 {
a7812ae4
PB
9324 TCGv_i64 fp64 = tcg_temp_new_i64();
9325 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9326 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9327
7c979afd
LA
9328 gen_load_fpr32(ctx, fp32_0, fs);
9329 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9330 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9331 tcg_temp_free_i32(fp32_1);
9332 tcg_temp_free_i32(fp32_0);
36aa55dc 9333 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9334 tcg_temp_free_i64(fp64);
b6d96bed 9335 }
5a5012ec 9336 break;
bf4120ad
NF
9337 case OPC_CMP_F_S:
9338 case OPC_CMP_UN_S:
9339 case OPC_CMP_EQ_S:
9340 case OPC_CMP_UEQ_S:
9341 case OPC_CMP_OLT_S:
9342 case OPC_CMP_ULT_S:
9343 case OPC_CMP_OLE_S:
9344 case OPC_CMP_ULE_S:
9345 case OPC_CMP_SF_S:
9346 case OPC_CMP_NGLE_S:
9347 case OPC_CMP_SEQ_S:
9348 case OPC_CMP_NGL_S:
9349 case OPC_CMP_LT_S:
9350 case OPC_CMP_NGE_S:
9351 case OPC_CMP_LE_S:
9352 case OPC_CMP_NGT_S:
fecd2646 9353 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9354 if (ctx->opcode & (1 << 6)) {
9355 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9356 } else {
9357 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9358 }
5a5012ec 9359 break;
bf4120ad 9360 case OPC_ADD_D:
5e755519 9361 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9362 {
a7812ae4
PB
9363 TCGv_i64 fp0 = tcg_temp_new_i64();
9364 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9365
9366 gen_load_fpr64(ctx, fp0, fs);
9367 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9368 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9369 tcg_temp_free_i64(fp1);
b6d96bed 9370 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9371 tcg_temp_free_i64(fp0);
b6d96bed 9372 }
6ea83fed 9373 break;
bf4120ad 9374 case OPC_SUB_D:
5e755519 9375 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9376 {
a7812ae4
PB
9377 TCGv_i64 fp0 = tcg_temp_new_i64();
9378 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9379
9380 gen_load_fpr64(ctx, fp0, fs);
9381 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9382 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9383 tcg_temp_free_i64(fp1);
b6d96bed 9384 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9385 tcg_temp_free_i64(fp0);
b6d96bed 9386 }
6ea83fed 9387 break;
bf4120ad 9388 case OPC_MUL_D:
5e755519 9389 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9390 {
a7812ae4
PB
9391 TCGv_i64 fp0 = tcg_temp_new_i64();
9392 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9393
9394 gen_load_fpr64(ctx, fp0, fs);
9395 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9396 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9397 tcg_temp_free_i64(fp1);
b6d96bed 9398 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9399 tcg_temp_free_i64(fp0);
b6d96bed 9400 }
6ea83fed 9401 break;
bf4120ad 9402 case OPC_DIV_D:
5e755519 9403 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9404 {
a7812ae4
PB
9405 TCGv_i64 fp0 = tcg_temp_new_i64();
9406 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9407
9408 gen_load_fpr64(ctx, fp0, fs);
9409 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9410 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9411 tcg_temp_free_i64(fp1);
b6d96bed 9412 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9413 tcg_temp_free_i64(fp0);
b6d96bed 9414 }
6ea83fed 9415 break;
bf4120ad 9416 case OPC_SQRT_D:
5e755519 9417 check_cp1_registers(ctx, fs | fd);
b6d96bed 9418 {
a7812ae4 9419 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9420
9421 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9422 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9423 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9424 tcg_temp_free_i64(fp0);
b6d96bed 9425 }
6ea83fed 9426 break;
bf4120ad 9427 case OPC_ABS_D:
5e755519 9428 check_cp1_registers(ctx, fs | fd);
b6d96bed 9429 {
a7812ae4 9430 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9431
9432 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9433 if (ctx->abs2008) {
9434 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9435 } else {
9436 gen_helper_float_abs_d(fp0, fp0);
9437 }
b6d96bed 9438 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9439 tcg_temp_free_i64(fp0);
b6d96bed 9440 }
6ea83fed 9441 break;
bf4120ad 9442 case OPC_MOV_D:
5e755519 9443 check_cp1_registers(ctx, fs | fd);
b6d96bed 9444 {
a7812ae4 9445 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9446
9447 gen_load_fpr64(ctx, fp0, fs);
9448 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9449 tcg_temp_free_i64(fp0);
b6d96bed 9450 }
6ea83fed 9451 break;
bf4120ad 9452 case OPC_NEG_D:
5e755519 9453 check_cp1_registers(ctx, fs | fd);
b6d96bed 9454 {
a7812ae4 9455 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9456
9457 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9458 if (ctx->abs2008) {
9459 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9460 } else {
9461 gen_helper_float_chs_d(fp0, fp0);
9462 }
b6d96bed 9463 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9464 tcg_temp_free_i64(fp0);
b6d96bed 9465 }
6ea83fed 9466 break;
bf4120ad 9467 case OPC_ROUND_L_D:
5e755519 9468 check_cp1_64bitmode(ctx);
b6d96bed 9469 {
a7812ae4 9470 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9471
9472 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9473 if (ctx->nan2008) {
9474 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9475 } else {
9476 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9477 }
b6d96bed 9478 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9479 tcg_temp_free_i64(fp0);
b6d96bed 9480 }
5a5012ec 9481 break;
bf4120ad 9482 case OPC_TRUNC_L_D:
5e755519 9483 check_cp1_64bitmode(ctx);
b6d96bed 9484 {
a7812ae4 9485 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9486
9487 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9488 if (ctx->nan2008) {
9489 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9490 } else {
9491 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9492 }
b6d96bed 9493 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9494 tcg_temp_free_i64(fp0);
b6d96bed 9495 }
5a5012ec 9496 break;
bf4120ad 9497 case OPC_CEIL_L_D:
5e755519 9498 check_cp1_64bitmode(ctx);
b6d96bed 9499 {
a7812ae4 9500 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9501
9502 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9503 if (ctx->nan2008) {
9504 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9505 } else {
9506 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9507 }
b6d96bed 9508 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9509 tcg_temp_free_i64(fp0);
b6d96bed 9510 }
5a5012ec 9511 break;
bf4120ad 9512 case OPC_FLOOR_L_D:
5e755519 9513 check_cp1_64bitmode(ctx);
b6d96bed 9514 {
a7812ae4 9515 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9516
9517 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9518 if (ctx->nan2008) {
9519 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9520 } else {
9521 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9522 }
b6d96bed 9523 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9524 tcg_temp_free_i64(fp0);
b6d96bed 9525 }
5a5012ec 9526 break;
bf4120ad 9527 case OPC_ROUND_W_D:
5e755519 9528 check_cp1_registers(ctx, fs);
b6d96bed 9529 {
a7812ae4
PB
9530 TCGv_i32 fp32 = tcg_temp_new_i32();
9531 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9532
9533 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9534 if (ctx->nan2008) {
9535 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9536 } else {
9537 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9538 }
a7812ae4 9539 tcg_temp_free_i64(fp64);
7c979afd 9540 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9541 tcg_temp_free_i32(fp32);
b6d96bed 9542 }
6ea83fed 9543 break;
bf4120ad 9544 case OPC_TRUNC_W_D:
5e755519 9545 check_cp1_registers(ctx, fs);
b6d96bed 9546 {
a7812ae4
PB
9547 TCGv_i32 fp32 = tcg_temp_new_i32();
9548 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9549
9550 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9551 if (ctx->nan2008) {
9552 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9553 } else {
9554 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9555 }
a7812ae4 9556 tcg_temp_free_i64(fp64);
7c979afd 9557 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9558 tcg_temp_free_i32(fp32);
b6d96bed 9559 }
6ea83fed 9560 break;
bf4120ad 9561 case OPC_CEIL_W_D:
5e755519 9562 check_cp1_registers(ctx, fs);
b6d96bed 9563 {
a7812ae4
PB
9564 TCGv_i32 fp32 = tcg_temp_new_i32();
9565 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9566
9567 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9568 if (ctx->nan2008) {
9569 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9570 } else {
9571 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9572 }
a7812ae4 9573 tcg_temp_free_i64(fp64);
7c979afd 9574 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9575 tcg_temp_free_i32(fp32);
b6d96bed 9576 }
6ea83fed 9577 break;
bf4120ad 9578 case OPC_FLOOR_W_D:
5e755519 9579 check_cp1_registers(ctx, fs);
b6d96bed 9580 {
a7812ae4
PB
9581 TCGv_i32 fp32 = tcg_temp_new_i32();
9582 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9583
9584 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9585 if (ctx->nan2008) {
9586 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9587 } else {
9588 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9589 }
a7812ae4 9590 tcg_temp_free_i64(fp64);
7c979afd 9591 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9592 tcg_temp_free_i32(fp32);
b6d96bed 9593 }
6ea83fed 9594 break;
e7f16abb
LA
9595 case OPC_SEL_D:
9596 check_insn(ctx, ISA_MIPS32R6);
9597 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9598 break;
9599 case OPC_SELEQZ_D:
9600 check_insn(ctx, ISA_MIPS32R6);
9601 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9602 break;
9603 case OPC_SELNEZ_D:
9604 check_insn(ctx, ISA_MIPS32R6);
9605 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9606 break;
bf4120ad 9607 case OPC_MOVCF_D:
fecd2646 9608 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9609 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9610 break;
bf4120ad 9611 case OPC_MOVZ_D:
fecd2646 9612 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9613 {
42a268c2 9614 TCGLabel *l1 = gen_new_label();
c9297f4d 9615 TCGv_i64 fp0;
a16336e4 9616
c9297f4d
AJ
9617 if (ft != 0) {
9618 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9619 }
9620 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9621 gen_load_fpr64(ctx, fp0, fs);
9622 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9623 tcg_temp_free_i64(fp0);
a16336e4
TS
9624 gen_set_label(l1);
9625 }
5a5012ec 9626 break;
bf4120ad 9627 case OPC_MOVN_D:
fecd2646 9628 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9629 {
42a268c2 9630 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9631 TCGv_i64 fp0;
9632
9633 if (ft != 0) {
9634 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9635 fp0 = tcg_temp_new_i64();
9636 gen_load_fpr64(ctx, fp0, fs);
9637 gen_store_fpr64(ctx, fp0, fd);
9638 tcg_temp_free_i64(fp0);
9639 gen_set_label(l1);
9640 }
a16336e4 9641 }
6ea83fed 9642 break;
bf4120ad 9643 case OPC_RECIP_D:
ca6c7803 9644 check_cp1_registers(ctx, fs | fd);
b6d96bed 9645 {
a7812ae4 9646 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9647
9648 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9649 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9650 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9651 tcg_temp_free_i64(fp0);
b6d96bed 9652 }
57fa1fb3 9653 break;
bf4120ad 9654 case OPC_RSQRT_D:
ca6c7803 9655 check_cp1_registers(ctx, fs | fd);
b6d96bed 9656 {
a7812ae4 9657 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9658
9659 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9660 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9661 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9662 tcg_temp_free_i64(fp0);
b6d96bed 9663 }
57fa1fb3 9664 break;
e7f16abb
LA
9665 case OPC_MADDF_D:
9666 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9667 {
a7812ae4
PB
9668 TCGv_i64 fp0 = tcg_temp_new_i64();
9669 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9670 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9671 gen_load_fpr64(ctx, fp0, fs);
9672 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9673 gen_load_fpr64(ctx, fp2, fd);
9674 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9675 gen_store_fpr64(ctx, fp2, fd);
9676 tcg_temp_free_i64(fp2);
a7812ae4 9677 tcg_temp_free_i64(fp1);
a7812ae4 9678 tcg_temp_free_i64(fp0);
b6d96bed 9679 }
57fa1fb3 9680 break;
e7f16abb
LA
9681 case OPC_MSUBF_D:
9682 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9683 {
a7812ae4 9684 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9685 TCGv_i64 fp1 = tcg_temp_new_i64();
9686 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9687 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9688 gen_load_fpr64(ctx, fp1, ft);
9689 gen_load_fpr64(ctx, fp2, fd);
9690 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9691 gen_store_fpr64(ctx, fp2, fd);
9692 tcg_temp_free_i64(fp2);
9693 tcg_temp_free_i64(fp1);
a7812ae4 9694 tcg_temp_free_i64(fp0);
b6d96bed 9695 }
57fa1fb3 9696 break;
e7f16abb
LA
9697 case OPC_RINT_D:
9698 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9699 {
a7812ae4 9700 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9701 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9702 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9703 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9704 tcg_temp_free_i64(fp0);
b6d96bed 9705 }
57fa1fb3 9706 break;
e7f16abb
LA
9707 case OPC_CLASS_D:
9708 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9709 {
e7f16abb
LA
9710 TCGv_i64 fp0 = tcg_temp_new_i64();
9711 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9712 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9713 gen_store_fpr64(ctx, fp0, fd);
9714 tcg_temp_free_i64(fp0);
e7f16abb
LA
9715 }
9716 break;
9717 case OPC_MIN_D: /* OPC_RECIP2_D */
9718 if (ctx->insn_flags & ISA_MIPS32R6) {
9719 /* OPC_MIN_D */
a7812ae4
PB
9720 TCGv_i64 fp0 = tcg_temp_new_i64();
9721 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9722 gen_load_fpr64(ctx, fp0, fs);
9723 gen_load_fpr64(ctx, fp1, ft);
9724 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9725 gen_store_fpr64(ctx, fp1, fd);
9726 tcg_temp_free_i64(fp1);
9727 tcg_temp_free_i64(fp0);
e7f16abb
LA
9728 } else {
9729 /* OPC_RECIP2_D */
9730 check_cp1_64bitmode(ctx);
9731 {
9732 TCGv_i64 fp0 = tcg_temp_new_i64();
9733 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9734
e7f16abb
LA
9735 gen_load_fpr64(ctx, fp0, fs);
9736 gen_load_fpr64(ctx, fp1, ft);
9737 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9738 tcg_temp_free_i64(fp1);
9739 gen_store_fpr64(ctx, fp0, fd);
9740 tcg_temp_free_i64(fp0);
9741 }
e7f16abb
LA
9742 }
9743 break;
9744 case OPC_MINA_D: /* OPC_RECIP1_D */
9745 if (ctx->insn_flags & ISA_MIPS32R6) {
9746 /* OPC_MINA_D */
9747 TCGv_i64 fp0 = tcg_temp_new_i64();
9748 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9749 gen_load_fpr64(ctx, fp0, fs);
9750 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9751 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9752 gen_store_fpr64(ctx, fp1, fd);
9753 tcg_temp_free_i64(fp1);
9754 tcg_temp_free_i64(fp0);
e7f16abb
LA
9755 } else {
9756 /* OPC_RECIP1_D */
9757 check_cp1_64bitmode(ctx);
9758 {
9759 TCGv_i64 fp0 = tcg_temp_new_i64();
9760
9761 gen_load_fpr64(ctx, fp0, fs);
9762 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9763 gen_store_fpr64(ctx, fp0, fd);
9764 tcg_temp_free_i64(fp0);
9765 }
e7f16abb
LA
9766 }
9767 break;
9768 case OPC_MAX_D: /* OPC_RSQRT1_D */
9769 if (ctx->insn_flags & ISA_MIPS32R6) {
9770 /* OPC_MAX_D */
9771 TCGv_i64 fp0 = tcg_temp_new_i64();
9772 TCGv_i64 fp1 = tcg_temp_new_i64();
9773 gen_load_fpr64(ctx, fp0, fs);
9774 gen_load_fpr64(ctx, fp1, ft);
9775 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9776 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9777 tcg_temp_free_i64(fp1);
a7812ae4 9778 tcg_temp_free_i64(fp0);
e7f16abb
LA
9779 } else {
9780 /* OPC_RSQRT1_D */
9781 check_cp1_64bitmode(ctx);
9782 {
9783 TCGv_i64 fp0 = tcg_temp_new_i64();
9784
9785 gen_load_fpr64(ctx, fp0, fs);
9786 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9787 gen_store_fpr64(ctx, fp0, fd);
9788 tcg_temp_free_i64(fp0);
9789 }
e7f16abb
LA
9790 }
9791 break;
9792 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9793 if (ctx->insn_flags & ISA_MIPS32R6) {
9794 /* OPC_MAXA_D */
9795 TCGv_i64 fp0 = tcg_temp_new_i64();
9796 TCGv_i64 fp1 = tcg_temp_new_i64();
9797 gen_load_fpr64(ctx, fp0, fs);
9798 gen_load_fpr64(ctx, fp1, ft);
9799 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9800 gen_store_fpr64(ctx, fp1, fd);
9801 tcg_temp_free_i64(fp1);
9802 tcg_temp_free_i64(fp0);
e7f16abb
LA
9803 } else {
9804 /* OPC_RSQRT2_D */
9805 check_cp1_64bitmode(ctx);
9806 {
9807 TCGv_i64 fp0 = tcg_temp_new_i64();
9808 TCGv_i64 fp1 = tcg_temp_new_i64();
9809
9810 gen_load_fpr64(ctx, fp0, fs);
9811 gen_load_fpr64(ctx, fp1, ft);
9812 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9813 tcg_temp_free_i64(fp1);
9814 gen_store_fpr64(ctx, fp0, fd);
9815 tcg_temp_free_i64(fp0);
9816 }
b6d96bed 9817 }
57fa1fb3 9818 break;
bf4120ad
NF
9819 case OPC_CMP_F_D:
9820 case OPC_CMP_UN_D:
9821 case OPC_CMP_EQ_D:
9822 case OPC_CMP_UEQ_D:
9823 case OPC_CMP_OLT_D:
9824 case OPC_CMP_ULT_D:
9825 case OPC_CMP_OLE_D:
9826 case OPC_CMP_ULE_D:
9827 case OPC_CMP_SF_D:
9828 case OPC_CMP_NGLE_D:
9829 case OPC_CMP_SEQ_D:
9830 case OPC_CMP_NGL_D:
9831 case OPC_CMP_LT_D:
9832 case OPC_CMP_NGE_D:
9833 case OPC_CMP_LE_D:
9834 case OPC_CMP_NGT_D:
fecd2646 9835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9836 if (ctx->opcode & (1 << 6)) {
9837 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9838 } else {
9839 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9840 }
6ea83fed 9841 break;
bf4120ad 9842 case OPC_CVT_S_D:
5e755519 9843 check_cp1_registers(ctx, fs);
b6d96bed 9844 {
a7812ae4
PB
9845 TCGv_i32 fp32 = tcg_temp_new_i32();
9846 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9847
9848 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9849 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9850 tcg_temp_free_i64(fp64);
7c979afd 9851 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9852 tcg_temp_free_i32(fp32);
b6d96bed 9853 }
5a5012ec 9854 break;
bf4120ad 9855 case OPC_CVT_W_D:
5e755519 9856 check_cp1_registers(ctx, fs);
b6d96bed 9857 {
a7812ae4
PB
9858 TCGv_i32 fp32 = tcg_temp_new_i32();
9859 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9860
9861 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9862 if (ctx->nan2008) {
9863 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9864 } else {
9865 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9866 }
a7812ae4 9867 tcg_temp_free_i64(fp64);
7c979afd 9868 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9869 tcg_temp_free_i32(fp32);
b6d96bed 9870 }
5a5012ec 9871 break;
bf4120ad 9872 case OPC_CVT_L_D:
5e755519 9873 check_cp1_64bitmode(ctx);
b6d96bed 9874 {
a7812ae4 9875 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9876
9877 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9878 if (ctx->nan2008) {
9879 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9880 } else {
9881 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9882 }
b6d96bed 9883 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9884 tcg_temp_free_i64(fp0);
b6d96bed 9885 }
5a5012ec 9886 break;
bf4120ad 9887 case OPC_CVT_S_W:
b6d96bed 9888 {
a7812ae4 9889 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9890
7c979afd 9891 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9892 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9893 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9894 tcg_temp_free_i32(fp0);
b6d96bed 9895 }
6ea83fed 9896 break;
bf4120ad 9897 case OPC_CVT_D_W:
5e755519 9898 check_cp1_registers(ctx, fd);
b6d96bed 9899 {
a7812ae4
PB
9900 TCGv_i32 fp32 = tcg_temp_new_i32();
9901 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9902
7c979afd 9903 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9904 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9905 tcg_temp_free_i32(fp32);
b6d96bed 9906 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9907 tcg_temp_free_i64(fp64);
b6d96bed 9908 }
5a5012ec 9909 break;
bf4120ad 9910 case OPC_CVT_S_L:
5e755519 9911 check_cp1_64bitmode(ctx);
b6d96bed 9912 {
a7812ae4
PB
9913 TCGv_i32 fp32 = tcg_temp_new_i32();
9914 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9915
9916 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9917 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9918 tcg_temp_free_i64(fp64);
7c979afd 9919 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9920 tcg_temp_free_i32(fp32);
b6d96bed 9921 }
5a5012ec 9922 break;
bf4120ad 9923 case OPC_CVT_D_L:
5e755519 9924 check_cp1_64bitmode(ctx);
b6d96bed 9925 {
a7812ae4 9926 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9927
9928 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9929 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9930 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9931 tcg_temp_free_i64(fp0);
b6d96bed 9932 }
5a5012ec 9933 break;
bf4120ad 9934 case OPC_CVT_PS_PW:
e29c9628 9935 check_ps(ctx);
b6d96bed 9936 {
a7812ae4 9937 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9938
9939 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9940 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9941 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9942 tcg_temp_free_i64(fp0);
b6d96bed 9943 }
5a5012ec 9944 break;
bf4120ad 9945 case OPC_ADD_PS:
e29c9628 9946 check_ps(ctx);
b6d96bed 9947 {
a7812ae4
PB
9948 TCGv_i64 fp0 = tcg_temp_new_i64();
9949 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9950
9951 gen_load_fpr64(ctx, fp0, fs);
9952 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9953 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9954 tcg_temp_free_i64(fp1);
b6d96bed 9955 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9956 tcg_temp_free_i64(fp0);
b6d96bed 9957 }
6ea83fed 9958 break;
bf4120ad 9959 case OPC_SUB_PS:
e29c9628 9960 check_ps(ctx);
b6d96bed 9961 {
a7812ae4
PB
9962 TCGv_i64 fp0 = tcg_temp_new_i64();
9963 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9964
9965 gen_load_fpr64(ctx, fp0, fs);
9966 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9967 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9968 tcg_temp_free_i64(fp1);
b6d96bed 9969 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9970 tcg_temp_free_i64(fp0);
b6d96bed 9971 }
6ea83fed 9972 break;
bf4120ad 9973 case OPC_MUL_PS:
e29c9628 9974 check_ps(ctx);
b6d96bed 9975 {
a7812ae4
PB
9976 TCGv_i64 fp0 = tcg_temp_new_i64();
9977 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9978
9979 gen_load_fpr64(ctx, fp0, fs);
9980 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9981 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9982 tcg_temp_free_i64(fp1);
b6d96bed 9983 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9984 tcg_temp_free_i64(fp0);
b6d96bed 9985 }
6ea83fed 9986 break;
bf4120ad 9987 case OPC_ABS_PS:
e29c9628 9988 check_ps(ctx);
b6d96bed 9989 {
a7812ae4 9990 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9991
9992 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9993 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9994 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9995 tcg_temp_free_i64(fp0);
b6d96bed 9996 }
6ea83fed 9997 break;
bf4120ad 9998 case OPC_MOV_PS:
e29c9628 9999 check_ps(ctx);
b6d96bed 10000 {
a7812ae4 10001 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10002
10003 gen_load_fpr64(ctx, fp0, fs);
10004 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10005 tcg_temp_free_i64(fp0);
b6d96bed 10006 }
6ea83fed 10007 break;
bf4120ad 10008 case OPC_NEG_PS:
e29c9628 10009 check_ps(ctx);
b6d96bed 10010 {
a7812ae4 10011 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10012
10013 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10014 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10015 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10016 tcg_temp_free_i64(fp0);
b6d96bed 10017 }
6ea83fed 10018 break;
bf4120ad 10019 case OPC_MOVCF_PS:
e29c9628 10020 check_ps(ctx);
7f6613ce 10021 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10022 break;
bf4120ad 10023 case OPC_MOVZ_PS:
e29c9628 10024 check_ps(ctx);
a16336e4 10025 {
42a268c2 10026 TCGLabel *l1 = gen_new_label();
30a3848b 10027 TCGv_i64 fp0;
a16336e4 10028
c9297f4d
AJ
10029 if (ft != 0)
10030 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10031 fp0 = tcg_temp_new_i64();
10032 gen_load_fpr64(ctx, fp0, fs);
10033 gen_store_fpr64(ctx, fp0, fd);
10034 tcg_temp_free_i64(fp0);
a16336e4
TS
10035 gen_set_label(l1);
10036 }
6ea83fed 10037 break;
bf4120ad 10038 case OPC_MOVN_PS:
e29c9628 10039 check_ps(ctx);
a16336e4 10040 {
42a268c2 10041 TCGLabel *l1 = gen_new_label();
30a3848b 10042 TCGv_i64 fp0;
c9297f4d
AJ
10043
10044 if (ft != 0) {
10045 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10046 fp0 = tcg_temp_new_i64();
10047 gen_load_fpr64(ctx, fp0, fs);
10048 gen_store_fpr64(ctx, fp0, fd);
10049 tcg_temp_free_i64(fp0);
10050 gen_set_label(l1);
10051 }
a16336e4 10052 }
6ea83fed 10053 break;
bf4120ad 10054 case OPC_ADDR_PS:
e29c9628 10055 check_ps(ctx);
b6d96bed 10056 {
a7812ae4
PB
10057 TCGv_i64 fp0 = tcg_temp_new_i64();
10058 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10059
10060 gen_load_fpr64(ctx, fp0, ft);
10061 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10062 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10063 tcg_temp_free_i64(fp1);
b6d96bed 10064 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10065 tcg_temp_free_i64(fp0);
b6d96bed 10066 }
fbcc6828 10067 break;
bf4120ad 10068 case OPC_MULR_PS:
e29c9628 10069 check_ps(ctx);
b6d96bed 10070 {
a7812ae4
PB
10071 TCGv_i64 fp0 = tcg_temp_new_i64();
10072 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10073
10074 gen_load_fpr64(ctx, fp0, ft);
10075 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10076 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10077 tcg_temp_free_i64(fp1);
b6d96bed 10078 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10079 tcg_temp_free_i64(fp0);
b6d96bed 10080 }
57fa1fb3 10081 break;
bf4120ad 10082 case OPC_RECIP2_PS:
e29c9628 10083 check_ps(ctx);
b6d96bed 10084 {
a7812ae4
PB
10085 TCGv_i64 fp0 = tcg_temp_new_i64();
10086 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10087
10088 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10089 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10090 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10091 tcg_temp_free_i64(fp1);
b6d96bed 10092 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10093 tcg_temp_free_i64(fp0);
b6d96bed 10094 }
57fa1fb3 10095 break;
bf4120ad 10096 case OPC_RECIP1_PS:
e29c9628 10097 check_ps(ctx);
b6d96bed 10098 {
a7812ae4 10099 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10100
10101 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10102 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10103 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10104 tcg_temp_free_i64(fp0);
b6d96bed 10105 }
57fa1fb3 10106 break;
bf4120ad 10107 case OPC_RSQRT1_PS:
e29c9628 10108 check_ps(ctx);
b6d96bed 10109 {
a7812ae4 10110 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10111
10112 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10113 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10114 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10115 tcg_temp_free_i64(fp0);
b6d96bed 10116 }
57fa1fb3 10117 break;
bf4120ad 10118 case OPC_RSQRT2_PS:
e29c9628 10119 check_ps(ctx);
b6d96bed 10120 {
a7812ae4
PB
10121 TCGv_i64 fp0 = tcg_temp_new_i64();
10122 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10123
10124 gen_load_fpr64(ctx, fp0, fs);
10125 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10126 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10127 tcg_temp_free_i64(fp1);
b6d96bed 10128 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10129 tcg_temp_free_i64(fp0);
b6d96bed 10130 }
57fa1fb3 10131 break;
bf4120ad 10132 case OPC_CVT_S_PU:
5e755519 10133 check_cp1_64bitmode(ctx);
b6d96bed 10134 {
a7812ae4 10135 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10136
7f6613ce 10137 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10138 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10139 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10140 tcg_temp_free_i32(fp0);
b6d96bed 10141 }
dd016883 10142 break;
bf4120ad 10143 case OPC_CVT_PW_PS:
e29c9628 10144 check_ps(ctx);
b6d96bed 10145 {
a7812ae4 10146 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10147
10148 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10149 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10150 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10151 tcg_temp_free_i64(fp0);
b6d96bed 10152 }
6ea83fed 10153 break;
bf4120ad 10154 case OPC_CVT_S_PL:
5e755519 10155 check_cp1_64bitmode(ctx);
b6d96bed 10156 {
a7812ae4 10157 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10158
7c979afd 10159 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10160 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10161 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10162 tcg_temp_free_i32(fp0);
b6d96bed 10163 }
6ea83fed 10164 break;
bf4120ad 10165 case OPC_PLL_PS:
e29c9628 10166 check_ps(ctx);
b6d96bed 10167 {
a7812ae4
PB
10168 TCGv_i32 fp0 = tcg_temp_new_i32();
10169 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10170
7c979afd
LA
10171 gen_load_fpr32(ctx, fp0, fs);
10172 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10173 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10174 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10175 tcg_temp_free_i32(fp0);
10176 tcg_temp_free_i32(fp1);
b6d96bed 10177 }
6ea83fed 10178 break;
bf4120ad 10179 case OPC_PLU_PS:
e29c9628 10180 check_ps(ctx);
b6d96bed 10181 {
a7812ae4
PB
10182 TCGv_i32 fp0 = tcg_temp_new_i32();
10183 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10184
7c979afd 10185 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10186 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10187 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10188 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10189 tcg_temp_free_i32(fp0);
10190 tcg_temp_free_i32(fp1);
b6d96bed 10191 }
5a5012ec 10192 break;
bf4120ad 10193 case OPC_PUL_PS:
e29c9628 10194 check_ps(ctx);
b6d96bed 10195 {
a7812ae4
PB
10196 TCGv_i32 fp0 = tcg_temp_new_i32();
10197 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10198
7f6613ce 10199 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10200 gen_load_fpr32(ctx, fp1, ft);
10201 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10202 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10203 tcg_temp_free_i32(fp0);
10204 tcg_temp_free_i32(fp1);
b6d96bed 10205 }
5a5012ec 10206 break;
bf4120ad 10207 case OPC_PUU_PS:
e29c9628 10208 check_ps(ctx);
b6d96bed 10209 {
a7812ae4
PB
10210 TCGv_i32 fp0 = tcg_temp_new_i32();
10211 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10212
7f6613ce
PJ
10213 gen_load_fpr32h(ctx, fp0, fs);
10214 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10215 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10216 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10217 tcg_temp_free_i32(fp0);
10218 tcg_temp_free_i32(fp1);
b6d96bed 10219 }
5a5012ec 10220 break;
bf4120ad
NF
10221 case OPC_CMP_F_PS:
10222 case OPC_CMP_UN_PS:
10223 case OPC_CMP_EQ_PS:
10224 case OPC_CMP_UEQ_PS:
10225 case OPC_CMP_OLT_PS:
10226 case OPC_CMP_ULT_PS:
10227 case OPC_CMP_OLE_PS:
10228 case OPC_CMP_ULE_PS:
10229 case OPC_CMP_SF_PS:
10230 case OPC_CMP_NGLE_PS:
10231 case OPC_CMP_SEQ_PS:
10232 case OPC_CMP_NGL_PS:
10233 case OPC_CMP_LT_PS:
10234 case OPC_CMP_NGE_PS:
10235 case OPC_CMP_LE_PS:
10236 case OPC_CMP_NGT_PS:
8153667c
NF
10237 if (ctx->opcode & (1 << 6)) {
10238 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10239 } else {
10240 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10241 }
6ea83fed 10242 break;
5a5012ec 10243 default:
9d68ac14 10244 MIPS_INVAL("farith");
9c708c7f 10245 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10246 return;
10247 }
6ea83fed 10248}
6af0bf9c 10249
5a5012ec 10250/* Coprocessor 3 (FPU) */
5e755519
TS
10251static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10252 int fd, int fs, int base, int index)
7a387fff 10253{
4e2474d6 10254 TCGv t0 = tcg_temp_new();
7a387fff 10255
93b12ccc 10256 if (base == 0) {
6c5c1e20 10257 gen_load_gpr(t0, index);
93b12ccc 10258 } else if (index == 0) {
6c5c1e20 10259 gen_load_gpr(t0, base);
93b12ccc 10260 } else {
05168674 10261 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10262 }
5a5012ec 10263 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10264 memory access. */
5a5012ec
TS
10265 switch (opc) {
10266 case OPC_LWXC1:
8c0ab41f 10267 check_cop1x(ctx);
b6d96bed 10268 {
a7812ae4 10269 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10270
5f68f5ae 10271 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10272 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10273 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10274 tcg_temp_free_i32(fp0);
b6d96bed 10275 }
5a5012ec
TS
10276 break;
10277 case OPC_LDXC1:
8c0ab41f
AJ
10278 check_cop1x(ctx);
10279 check_cp1_registers(ctx, fd);
b6d96bed 10280 {
a7812ae4 10281 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10282 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10283 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10284 tcg_temp_free_i64(fp0);
b6d96bed 10285 }
5a5012ec
TS
10286 break;
10287 case OPC_LUXC1:
8c0ab41f 10288 check_cp1_64bitmode(ctx);
6c5c1e20 10289 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10290 {
a7812ae4 10291 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10292
5f68f5ae 10293 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10294 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10295 tcg_temp_free_i64(fp0);
b6d96bed 10296 }
5a5012ec
TS
10297 break;
10298 case OPC_SWXC1:
8c0ab41f 10299 check_cop1x(ctx);
b6d96bed 10300 {
a7812ae4 10301 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10302 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10303 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10304 tcg_temp_free_i32(fp0);
b6d96bed 10305 }
5a5012ec
TS
10306 break;
10307 case OPC_SDXC1:
8c0ab41f
AJ
10308 check_cop1x(ctx);
10309 check_cp1_registers(ctx, fs);
b6d96bed 10310 {
a7812ae4 10311 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10312 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10313 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10314 tcg_temp_free_i64(fp0);
b6d96bed 10315 }
5a5012ec
TS
10316 break;
10317 case OPC_SUXC1:
8c0ab41f 10318 check_cp1_64bitmode(ctx);
6c5c1e20 10319 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10320 {
a7812ae4 10321 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10322 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10323 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10324 tcg_temp_free_i64(fp0);
b6d96bed 10325 }
5a5012ec 10326 break;
5a5012ec 10327 }
6c5c1e20 10328 tcg_temp_free(t0);
5a5012ec
TS
10329}
10330
5e755519
TS
10331static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10332 int fd, int fr, int fs, int ft)
5a5012ec 10333{
5a5012ec
TS
10334 switch (opc) {
10335 case OPC_ALNV_PS:
e29c9628 10336 check_ps(ctx);
a16336e4 10337 {
a7812ae4 10338 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10339 TCGv_i32 fp = tcg_temp_new_i32();
10340 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10341 TCGLabel *l1 = gen_new_label();
10342 TCGLabel *l2 = gen_new_label();
a16336e4 10343
6c5c1e20
TS
10344 gen_load_gpr(t0, fr);
10345 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10346
10347 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10348 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10349 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10350 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10351 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10352 tcg_gen_br(l2);
10353 gen_set_label(l1);
6c5c1e20
TS
10354 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10355 tcg_temp_free(t0);
a16336e4 10356#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10357 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10358 gen_load_fpr32h(ctx, fph, ft);
10359 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10360 gen_store_fpr32(ctx, fph, fd);
a16336e4 10361#else
7f6613ce 10362 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10363 gen_load_fpr32(ctx, fp, ft);
10364 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10365 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10366#endif
10367 gen_set_label(l2);
c905fdac
AJ
10368 tcg_temp_free_i32(fp);
10369 tcg_temp_free_i32(fph);
a16336e4 10370 }
5a5012ec
TS
10371 break;
10372 case OPC_MADD_S:
b8aa4598 10373 check_cop1x(ctx);
b6d96bed 10374 {
a7812ae4
PB
10375 TCGv_i32 fp0 = tcg_temp_new_i32();
10376 TCGv_i32 fp1 = tcg_temp_new_i32();
10377 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10378
7c979afd
LA
10379 gen_load_fpr32(ctx, fp0, fs);
10380 gen_load_fpr32(ctx, fp1, ft);
10381 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10382 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10383 tcg_temp_free_i32(fp0);
10384 tcg_temp_free_i32(fp1);
7c979afd 10385 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10386 tcg_temp_free_i32(fp2);
b6d96bed 10387 }
5a5012ec
TS
10388 break;
10389 case OPC_MADD_D:
b8aa4598
TS
10390 check_cop1x(ctx);
10391 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10392 {
a7812ae4
PB
10393 TCGv_i64 fp0 = tcg_temp_new_i64();
10394 TCGv_i64 fp1 = tcg_temp_new_i64();
10395 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10396
10397 gen_load_fpr64(ctx, fp0, fs);
10398 gen_load_fpr64(ctx, fp1, ft);
10399 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10400 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10401 tcg_temp_free_i64(fp0);
10402 tcg_temp_free_i64(fp1);
b6d96bed 10403 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10404 tcg_temp_free_i64(fp2);
b6d96bed 10405 }
5a5012ec
TS
10406 break;
10407 case OPC_MADD_PS:
e29c9628 10408 check_ps(ctx);
b6d96bed 10409 {
a7812ae4
PB
10410 TCGv_i64 fp0 = tcg_temp_new_i64();
10411 TCGv_i64 fp1 = tcg_temp_new_i64();
10412 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10413
10414 gen_load_fpr64(ctx, fp0, fs);
10415 gen_load_fpr64(ctx, fp1, ft);
10416 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10417 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10418 tcg_temp_free_i64(fp0);
10419 tcg_temp_free_i64(fp1);
b6d96bed 10420 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10421 tcg_temp_free_i64(fp2);
b6d96bed 10422 }
5a5012ec
TS
10423 break;
10424 case OPC_MSUB_S:
b8aa4598 10425 check_cop1x(ctx);
b6d96bed 10426 {
a7812ae4
PB
10427 TCGv_i32 fp0 = tcg_temp_new_i32();
10428 TCGv_i32 fp1 = tcg_temp_new_i32();
10429 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10430
7c979afd
LA
10431 gen_load_fpr32(ctx, fp0, fs);
10432 gen_load_fpr32(ctx, fp1, ft);
10433 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10434 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10435 tcg_temp_free_i32(fp0);
10436 tcg_temp_free_i32(fp1);
7c979afd 10437 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10438 tcg_temp_free_i32(fp2);
b6d96bed 10439 }
5a5012ec
TS
10440 break;
10441 case OPC_MSUB_D:
b8aa4598
TS
10442 check_cop1x(ctx);
10443 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10444 {
a7812ae4
PB
10445 TCGv_i64 fp0 = tcg_temp_new_i64();
10446 TCGv_i64 fp1 = tcg_temp_new_i64();
10447 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10448
10449 gen_load_fpr64(ctx, fp0, fs);
10450 gen_load_fpr64(ctx, fp1, ft);
10451 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10452 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10453 tcg_temp_free_i64(fp0);
10454 tcg_temp_free_i64(fp1);
b6d96bed 10455 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10456 tcg_temp_free_i64(fp2);
b6d96bed 10457 }
5a5012ec
TS
10458 break;
10459 case OPC_MSUB_PS:
e29c9628 10460 check_ps(ctx);
b6d96bed 10461 {
a7812ae4
PB
10462 TCGv_i64 fp0 = tcg_temp_new_i64();
10463 TCGv_i64 fp1 = tcg_temp_new_i64();
10464 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10465
10466 gen_load_fpr64(ctx, fp0, fs);
10467 gen_load_fpr64(ctx, fp1, ft);
10468 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10469 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10470 tcg_temp_free_i64(fp0);
10471 tcg_temp_free_i64(fp1);
b6d96bed 10472 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10473 tcg_temp_free_i64(fp2);
b6d96bed 10474 }
5a5012ec
TS
10475 break;
10476 case OPC_NMADD_S:
b8aa4598 10477 check_cop1x(ctx);
b6d96bed 10478 {
a7812ae4
PB
10479 TCGv_i32 fp0 = tcg_temp_new_i32();
10480 TCGv_i32 fp1 = tcg_temp_new_i32();
10481 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10482
7c979afd
LA
10483 gen_load_fpr32(ctx, fp0, fs);
10484 gen_load_fpr32(ctx, fp1, ft);
10485 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10486 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10487 tcg_temp_free_i32(fp0);
10488 tcg_temp_free_i32(fp1);
7c979afd 10489 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10490 tcg_temp_free_i32(fp2);
b6d96bed 10491 }
5a5012ec
TS
10492 break;
10493 case OPC_NMADD_D:
b8aa4598
TS
10494 check_cop1x(ctx);
10495 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10496 {
a7812ae4
PB
10497 TCGv_i64 fp0 = tcg_temp_new_i64();
10498 TCGv_i64 fp1 = tcg_temp_new_i64();
10499 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10500
10501 gen_load_fpr64(ctx, fp0, fs);
10502 gen_load_fpr64(ctx, fp1, ft);
10503 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10504 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10505 tcg_temp_free_i64(fp0);
10506 tcg_temp_free_i64(fp1);
b6d96bed 10507 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10508 tcg_temp_free_i64(fp2);
b6d96bed 10509 }
5a5012ec
TS
10510 break;
10511 case OPC_NMADD_PS:
e29c9628 10512 check_ps(ctx);
b6d96bed 10513 {
a7812ae4
PB
10514 TCGv_i64 fp0 = tcg_temp_new_i64();
10515 TCGv_i64 fp1 = tcg_temp_new_i64();
10516 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10517
10518 gen_load_fpr64(ctx, fp0, fs);
10519 gen_load_fpr64(ctx, fp1, ft);
10520 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10521 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10522 tcg_temp_free_i64(fp0);
10523 tcg_temp_free_i64(fp1);
b6d96bed 10524 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10525 tcg_temp_free_i64(fp2);
b6d96bed 10526 }
5a5012ec
TS
10527 break;
10528 case OPC_NMSUB_S:
b8aa4598 10529 check_cop1x(ctx);
b6d96bed 10530 {
a7812ae4
PB
10531 TCGv_i32 fp0 = tcg_temp_new_i32();
10532 TCGv_i32 fp1 = tcg_temp_new_i32();
10533 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10534
7c979afd
LA
10535 gen_load_fpr32(ctx, fp0, fs);
10536 gen_load_fpr32(ctx, fp1, ft);
10537 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10538 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10539 tcg_temp_free_i32(fp0);
10540 tcg_temp_free_i32(fp1);
7c979afd 10541 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10542 tcg_temp_free_i32(fp2);
b6d96bed 10543 }
5a5012ec
TS
10544 break;
10545 case OPC_NMSUB_D:
b8aa4598
TS
10546 check_cop1x(ctx);
10547 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10548 {
a7812ae4
PB
10549 TCGv_i64 fp0 = tcg_temp_new_i64();
10550 TCGv_i64 fp1 = tcg_temp_new_i64();
10551 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10552
10553 gen_load_fpr64(ctx, fp0, fs);
10554 gen_load_fpr64(ctx, fp1, ft);
10555 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10556 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10557 tcg_temp_free_i64(fp0);
10558 tcg_temp_free_i64(fp1);
b6d96bed 10559 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10560 tcg_temp_free_i64(fp2);
b6d96bed 10561 }
5a5012ec
TS
10562 break;
10563 case OPC_NMSUB_PS:
e29c9628 10564 check_ps(ctx);
b6d96bed 10565 {
a7812ae4
PB
10566 TCGv_i64 fp0 = tcg_temp_new_i64();
10567 TCGv_i64 fp1 = tcg_temp_new_i64();
10568 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10569
10570 gen_load_fpr64(ctx, fp0, fs);
10571 gen_load_fpr64(ctx, fp1, ft);
10572 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10573 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10574 tcg_temp_free_i64(fp0);
10575 tcg_temp_free_i64(fp1);
b6d96bed 10576 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10577 tcg_temp_free_i64(fp2);
b6d96bed 10578 }
5a5012ec 10579 break;
923617a3 10580 default:
9d68ac14 10581 MIPS_INVAL("flt3_arith");
9c708c7f 10582 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10583 return;
10584 }
7a387fff
TS
10585}
10586
b00c7218 10587static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10588{
10589 TCGv t0;
10590
b3167288
RH
10591#if !defined(CONFIG_USER_ONLY)
10592 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10593 Therefore only check the ISA in system mode. */
d75c135e 10594 check_insn(ctx, ISA_MIPS32R2);
b3167288 10595#endif
26ebe468
NF
10596 t0 = tcg_temp_new();
10597
10598 switch (rd) {
10599 case 0:
895c2d04 10600 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10601 gen_store_gpr(t0, rt);
10602 break;
10603 case 1:
895c2d04 10604 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10605 gen_store_gpr(t0, rt);
10606 break;
10607 case 2:
895c2d04 10608 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10609 gen_store_gpr(t0, rt);
10610 break;
10611 case 3:
895c2d04 10612 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10613 gen_store_gpr(t0, rt);
10614 break;
b00c7218
YK
10615 case 4:
10616 check_insn(ctx, ISA_MIPS32R6);
10617 if (sel != 0) {
10618 /* Performance counter registers are not implemented other than
10619 * control register 0.
10620 */
10621 generate_exception(ctx, EXCP_RI);
10622 }
10623 gen_helper_rdhwr_performance(t0, cpu_env);
10624 gen_store_gpr(t0, rt);
10625 break;
10626 case 5:
10627 check_insn(ctx, ISA_MIPS32R6);
10628 gen_helper_rdhwr_xnp(t0, cpu_env);
10629 gen_store_gpr(t0, rt);
10630 break;
26ebe468
NF
10631 case 29:
10632#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10633 tcg_gen_ld_tl(t0, cpu_env,
10634 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10635 gen_store_gpr(t0, rt);
10636 break;
10637#else
d279279e
PJ
10638 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10639 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10640 tcg_gen_ld_tl(t0, cpu_env,
10641 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10642 gen_store_gpr(t0, rt);
10643 } else {
9c708c7f 10644 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10645 }
10646 break;
26ebe468
NF
10647#endif
10648 default: /* Invalid */
10649 MIPS_INVAL("rdhwr");
9c708c7f 10650 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10651 break;
10652 }
10653 tcg_temp_free(t0);
10654}
10655
a5f53390
LA
10656static inline void clear_branch_hflags(DisasContext *ctx)
10657{
10658 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10659 if (ctx->bstate == BS_NONE) {
10660 save_cpu_state(ctx, 0);
10661 } else {
10662 /* it is not safe to save ctx->hflags as hflags may be changed
10663 in execution time by the instruction in delay / forbidden slot. */
10664 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10665 }
10666}
10667
31837be3 10668static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10669{
10670 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10671 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10672 /* Branches completion */
a5f53390 10673 clear_branch_hflags(ctx);
c9602061 10674 ctx->bstate = BS_BRANCH;
c9602061 10675 /* FIXME: Need to clear can_do_io. */
364d4831 10676 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10677 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10678 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10679 break;
c9602061
NF
10680 case MIPS_HFLAG_B:
10681 /* unconditional branch */
364d4831
NF
10682 if (proc_hflags & MIPS_HFLAG_BX) {
10683 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10684 }
c9602061
NF
10685 gen_goto_tb(ctx, 0, ctx->btarget);
10686 break;
10687 case MIPS_HFLAG_BL:
10688 /* blikely taken case */
c9602061
NF
10689 gen_goto_tb(ctx, 0, ctx->btarget);
10690 break;
10691 case MIPS_HFLAG_BC:
10692 /* Conditional branch */
c9602061 10693 {
42a268c2 10694 TCGLabel *l1 = gen_new_label();
c9602061
NF
10695
10696 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10697 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10698 gen_set_label(l1);
10699 gen_goto_tb(ctx, 0, ctx->btarget);
10700 }
10701 break;
10702 case MIPS_HFLAG_BR:
10703 /* unconditional branch to register */
d75c135e 10704 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10705 TCGv t0 = tcg_temp_new();
10706 TCGv_i32 t1 = tcg_temp_new_i32();
10707
10708 tcg_gen_andi_tl(t0, btarget, 0x1);
10709 tcg_gen_trunc_tl_i32(t1, t0);
10710 tcg_temp_free(t0);
10711 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10712 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10713 tcg_gen_or_i32(hflags, hflags, t1);
10714 tcg_temp_free_i32(t1);
10715
10716 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10717 } else {
10718 tcg_gen_mov_tl(cpu_PC, btarget);
10719 }
c9602061
NF
10720 if (ctx->singlestep_enabled) {
10721 save_cpu_state(ctx, 0);
9c708c7f 10722 gen_helper_raise_exception_debug(cpu_env);
c9602061
NF
10723 }
10724 tcg_gen_exit_tb(0);
10725 break;
10726 default:
a5f53390
LA
10727 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10728 abort();
c9602061
NF
10729 }
10730 }
10731}
10732
6893f074
YK
10733/* Compact Branches */
10734static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10735 int rs, int rt, int32_t offset)
10736{
10737 int bcond_compute = 0;
10738 TCGv t0 = tcg_temp_new();
10739 TCGv t1 = tcg_temp_new();
65935f07 10740 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10741
10742 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10743#ifdef MIPS_DEBUG_DISAS
10744 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10745 "\n", ctx->pc);
10746#endif
9c708c7f 10747 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10748 goto out;
10749 }
10750
10751 /* Load needed operands and calculate btarget */
10752 switch (opc) {
10753 /* compact branch */
10754 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10755 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10756 gen_load_gpr(t0, rs);
10757 gen_load_gpr(t1, rt);
10758 bcond_compute = 1;
10759 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10760 if (rs <= rt && rs == 0) {
10761 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10762 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10763 }
10764 break;
10765 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10766 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10767 gen_load_gpr(t0, rs);
10768 gen_load_gpr(t1, rt);
10769 bcond_compute = 1;
10770 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10771 break;
10772 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10773 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10774 if (rs == 0 || rs == rt) {
10775 /* OPC_BLEZALC, OPC_BGEZALC */
10776 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10777 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10778 }
10779 gen_load_gpr(t0, rs);
10780 gen_load_gpr(t1, rt);
10781 bcond_compute = 1;
10782 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10783 break;
10784 case OPC_BC:
10785 case OPC_BALC:
10786 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10787 break;
10788 case OPC_BEQZC:
10789 case OPC_BNEZC:
10790 if (rs != 0) {
10791 /* OPC_BEQZC, OPC_BNEZC */
10792 gen_load_gpr(t0, rs);
10793 bcond_compute = 1;
10794 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10795 } else {
10796 /* OPC_JIC, OPC_JIALC */
10797 TCGv tbase = tcg_temp_new();
10798 TCGv toffset = tcg_temp_new();
10799
10800 gen_load_gpr(tbase, rt);
10801 tcg_gen_movi_tl(toffset, offset);
10802 gen_op_addr_add(ctx, btarget, tbase, toffset);
10803 tcg_temp_free(tbase);
10804 tcg_temp_free(toffset);
10805 }
10806 break;
10807 default:
10808 MIPS_INVAL("Compact branch/jump");
9c708c7f 10809 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10810 goto out;
10811 }
10812
10813 if (bcond_compute == 0) {
10814 /* Uncoditional compact branch */
10815 switch (opc) {
10816 case OPC_JIALC:
65935f07 10817 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10818 /* Fallthrough */
10819 case OPC_JIC:
10820 ctx->hflags |= MIPS_HFLAG_BR;
10821 break;
10822 case OPC_BALC:
65935f07 10823 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10824 /* Fallthrough */
10825 case OPC_BC:
10826 ctx->hflags |= MIPS_HFLAG_B;
10827 break;
10828 default:
10829 MIPS_INVAL("Compact branch/jump");
9c708c7f 10830 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10831 goto out;
10832 }
10833
10834 /* Generating branch here as compact branches don't have delay slot */
10835 gen_branch(ctx, 4);
10836 } else {
10837 /* Conditional compact branch */
10838 TCGLabel *fs = gen_new_label();
10839 save_cpu_state(ctx, 0);
10840
10841 switch (opc) {
10842 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10843 if (rs == 0 && rt != 0) {
10844 /* OPC_BLEZALC */
10845 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10846 } else if (rs != 0 && rt != 0 && rs == rt) {
10847 /* OPC_BGEZALC */
10848 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10849 } else {
10850 /* OPC_BGEUC */
10851 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10852 }
10853 break;
10854 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10855 if (rs == 0 && rt != 0) {
10856 /* OPC_BGTZALC */
10857 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10858 } else if (rs != 0 && rt != 0 && rs == rt) {
10859 /* OPC_BLTZALC */
10860 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10861 } else {
10862 /* OPC_BLTUC */
10863 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10864 }
10865 break;
10866 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10867 if (rs == 0 && rt != 0) {
10868 /* OPC_BLEZC */
10869 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10870 } else if (rs != 0 && rt != 0 && rs == rt) {
10871 /* OPC_BGEZC */
10872 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10873 } else {
10874 /* OPC_BGEC */
10875 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10876 }
10877 break;
10878 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10879 if (rs == 0 && rt != 0) {
10880 /* OPC_BGTZC */
10881 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10882 } else if (rs != 0 && rt != 0 && rs == rt) {
10883 /* OPC_BLTZC */
10884 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10885 } else {
10886 /* OPC_BLTC */
10887 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10888 }
10889 break;
10890 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10891 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10892 if (rs >= rt) {
10893 /* OPC_BOVC, OPC_BNVC */
10894 TCGv t2 = tcg_temp_new();
10895 TCGv t3 = tcg_temp_new();
10896 TCGv t4 = tcg_temp_new();
10897 TCGv input_overflow = tcg_temp_new();
10898
10899 gen_load_gpr(t0, rs);
10900 gen_load_gpr(t1, rt);
10901 tcg_gen_ext32s_tl(t2, t0);
10902 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10903 tcg_gen_ext32s_tl(t3, t1);
10904 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10905 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10906
10907 tcg_gen_add_tl(t4, t2, t3);
10908 tcg_gen_ext32s_tl(t4, t4);
10909 tcg_gen_xor_tl(t2, t2, t3);
10910 tcg_gen_xor_tl(t3, t4, t3);
10911 tcg_gen_andc_tl(t2, t3, t2);
10912 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10913 tcg_gen_or_tl(t4, t4, input_overflow);
10914 if (opc == OPC_BOVC) {
10915 /* OPC_BOVC */
10916 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10917 } else {
10918 /* OPC_BNVC */
10919 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10920 }
10921 tcg_temp_free(input_overflow);
10922 tcg_temp_free(t4);
10923 tcg_temp_free(t3);
10924 tcg_temp_free(t2);
10925 } else if (rs < rt && rs == 0) {
10926 /* OPC_BEQZALC, OPC_BNEZALC */
10927 if (opc == OPC_BEQZALC) {
10928 /* OPC_BEQZALC */
10929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10930 } else {
10931 /* OPC_BNEZALC */
10932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10933 }
10934 } else {
10935 /* OPC_BEQC, OPC_BNEC */
10936 if (opc == OPC_BEQC) {
10937 /* OPC_BEQC */
10938 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10939 } else {
10940 /* OPC_BNEC */
10941 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10942 }
10943 }
10944 break;
10945 case OPC_BEQZC:
10946 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10947 break;
10948 case OPC_BNEZC:
10949 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10950 break;
10951 default:
10952 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 10953 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10954 goto out;
10955 }
10956
10957 /* Generating branch here as compact branches don't have delay slot */
10958 gen_goto_tb(ctx, 1, ctx->btarget);
10959 gen_set_label(fs);
10960
10961 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10962 }
10963
10964out:
10965 tcg_temp_free(t0);
10966 tcg_temp_free(t1);
10967}
10968
7a387fff 10969/* ISA extensions (ASEs) */
6af0bf9c 10970/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10971
10972/* MIPS16 major opcodes */
10973enum {
10974 M16_OPC_ADDIUSP = 0x00,
10975 M16_OPC_ADDIUPC = 0x01,
10976 M16_OPC_B = 0x02,
10977 M16_OPC_JAL = 0x03,
10978 M16_OPC_BEQZ = 0x04,
10979 M16_OPC_BNEQZ = 0x05,
10980 M16_OPC_SHIFT = 0x06,
10981 M16_OPC_LD = 0x07,
10982 M16_OPC_RRIA = 0x08,
10983 M16_OPC_ADDIU8 = 0x09,
10984 M16_OPC_SLTI = 0x0a,
10985 M16_OPC_SLTIU = 0x0b,
10986 M16_OPC_I8 = 0x0c,
10987 M16_OPC_LI = 0x0d,
10988 M16_OPC_CMPI = 0x0e,
10989 M16_OPC_SD = 0x0f,
10990 M16_OPC_LB = 0x10,
10991 M16_OPC_LH = 0x11,
10992 M16_OPC_LWSP = 0x12,
10993 M16_OPC_LW = 0x13,
10994 M16_OPC_LBU = 0x14,
10995 M16_OPC_LHU = 0x15,
10996 M16_OPC_LWPC = 0x16,
10997 M16_OPC_LWU = 0x17,
10998 M16_OPC_SB = 0x18,
10999 M16_OPC_SH = 0x19,
11000 M16_OPC_SWSP = 0x1a,
11001 M16_OPC_SW = 0x1b,
11002 M16_OPC_RRR = 0x1c,
11003 M16_OPC_RR = 0x1d,
11004 M16_OPC_EXTEND = 0x1e,
11005 M16_OPC_I64 = 0x1f
11006};
11007
11008/* I8 funct field */
11009enum {
11010 I8_BTEQZ = 0x0,
11011 I8_BTNEZ = 0x1,
11012 I8_SWRASP = 0x2,
11013 I8_ADJSP = 0x3,
11014 I8_SVRS = 0x4,
11015 I8_MOV32R = 0x5,
11016 I8_MOVR32 = 0x7
11017};
11018
11019/* RRR f field */
11020enum {
11021 RRR_DADDU = 0x0,
11022 RRR_ADDU = 0x1,
11023 RRR_DSUBU = 0x2,
11024 RRR_SUBU = 0x3
11025};
11026
11027/* RR funct field */
11028enum {
11029 RR_JR = 0x00,
11030 RR_SDBBP = 0x01,
11031 RR_SLT = 0x02,
11032 RR_SLTU = 0x03,
11033 RR_SLLV = 0x04,
11034 RR_BREAK = 0x05,
11035 RR_SRLV = 0x06,
11036 RR_SRAV = 0x07,
11037 RR_DSRL = 0x08,
11038 RR_CMP = 0x0a,
11039 RR_NEG = 0x0b,
11040 RR_AND = 0x0c,
11041 RR_OR = 0x0d,
11042 RR_XOR = 0x0e,
11043 RR_NOT = 0x0f,
11044 RR_MFHI = 0x10,
11045 RR_CNVT = 0x11,
11046 RR_MFLO = 0x12,
11047 RR_DSRA = 0x13,
11048 RR_DSLLV = 0x14,
11049 RR_DSRLV = 0x16,
11050 RR_DSRAV = 0x17,
11051 RR_MULT = 0x18,
11052 RR_MULTU = 0x19,
11053 RR_DIV = 0x1a,
11054 RR_DIVU = 0x1b,
11055 RR_DMULT = 0x1c,
11056 RR_DMULTU = 0x1d,
11057 RR_DDIV = 0x1e,
11058 RR_DDIVU = 0x1f
11059};
11060
11061/* I64 funct field */
11062enum {
11063 I64_LDSP = 0x0,
11064 I64_SDSP = 0x1,
11065 I64_SDRASP = 0x2,
11066 I64_DADJSP = 0x3,
11067 I64_LDPC = 0x4,
364d4831 11068 I64_DADDIU5 = 0x5,
6ea219d0
NF
11069 I64_DADDIUPC = 0x6,
11070 I64_DADDIUSP = 0x7
11071};
11072
11073/* RR ry field for CNVT */
11074enum {
11075 RR_RY_CNVT_ZEB = 0x0,
11076 RR_RY_CNVT_ZEH = 0x1,
11077 RR_RY_CNVT_ZEW = 0x2,
11078 RR_RY_CNVT_SEB = 0x4,
11079 RR_RY_CNVT_SEH = 0x5,
11080 RR_RY_CNVT_SEW = 0x6,
11081};
11082
364d4831
NF
11083static int xlat (int r)
11084{
11085 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11086
11087 return map[r];
11088}
11089
11090static void gen_mips16_save (DisasContext *ctx,
11091 int xsregs, int aregs,
11092 int do_ra, int do_s0, int do_s1,
11093 int framesize)
11094{
11095 TCGv t0 = tcg_temp_new();
11096 TCGv t1 = tcg_temp_new();
c48245f0 11097 TCGv t2 = tcg_temp_new();
364d4831
NF
11098 int args, astatic;
11099
11100 switch (aregs) {
11101 case 0:
11102 case 1:
11103 case 2:
11104 case 3:
11105 case 11:
11106 args = 0;
11107 break;
11108 case 4:
11109 case 5:
11110 case 6:
11111 case 7:
11112 args = 1;
11113 break;
11114 case 8:
11115 case 9:
11116 case 10:
11117 args = 2;
11118 break;
11119 case 12:
11120 case 13:
11121 args = 3;
11122 break;
11123 case 14:
11124 args = 4;
11125 break;
11126 default:
9c708c7f 11127 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11128 return;
11129 }
11130
11131 switch (args) {
11132 case 4:
11133 gen_base_offset_addr(ctx, t0, 29, 12);
11134 gen_load_gpr(t1, 7);
5f68f5ae 11135 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11136 /* Fall through */
11137 case 3:
11138 gen_base_offset_addr(ctx, t0, 29, 8);
11139 gen_load_gpr(t1, 6);
5f68f5ae 11140 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11141 /* Fall through */
11142 case 2:
11143 gen_base_offset_addr(ctx, t0, 29, 4);
11144 gen_load_gpr(t1, 5);
5f68f5ae 11145 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11146 /* Fall through */
11147 case 1:
11148 gen_base_offset_addr(ctx, t0, 29, 0);
11149 gen_load_gpr(t1, 4);
5f68f5ae 11150 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11151 }
11152
11153 gen_load_gpr(t0, 29);
11154
5f68f5ae 11155#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11156 tcg_gen_movi_tl(t2, -4); \
11157 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11158 gen_load_gpr(t1, reg); \
11159 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11160 } while (0)
11161
11162 if (do_ra) {
11163 DECR_AND_STORE(31);
11164 }
11165
11166 switch (xsregs) {
11167 case 7:
11168 DECR_AND_STORE(30);
11169 /* Fall through */
11170 case 6:
11171 DECR_AND_STORE(23);
11172 /* Fall through */
11173 case 5:
11174 DECR_AND_STORE(22);
11175 /* Fall through */
11176 case 4:
11177 DECR_AND_STORE(21);
11178 /* Fall through */
11179 case 3:
11180 DECR_AND_STORE(20);
11181 /* Fall through */
11182 case 2:
11183 DECR_AND_STORE(19);
11184 /* Fall through */
11185 case 1:
11186 DECR_AND_STORE(18);
11187 }
11188
11189 if (do_s1) {
11190 DECR_AND_STORE(17);
11191 }
11192 if (do_s0) {
11193 DECR_AND_STORE(16);
11194 }
11195
11196 switch (aregs) {
11197 case 0:
11198 case 4:
11199 case 8:
11200 case 12:
11201 case 14:
11202 astatic = 0;
11203 break;
11204 case 1:
11205 case 5:
11206 case 9:
11207 case 13:
11208 astatic = 1;
11209 break;
11210 case 2:
11211 case 6:
11212 case 10:
11213 astatic = 2;
11214 break;
11215 case 3:
11216 case 7:
11217 astatic = 3;
11218 break;
11219 case 11:
11220 astatic = 4;
11221 break;
11222 default:
9c708c7f 11223 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11224 return;
11225 }
11226
11227 if (astatic > 0) {
11228 DECR_AND_STORE(7);
11229 if (astatic > 1) {
11230 DECR_AND_STORE(6);
11231 if (astatic > 2) {
11232 DECR_AND_STORE(5);
11233 if (astatic > 3) {
11234 DECR_AND_STORE(4);
11235 }
11236 }
11237 }
11238 }
11239#undef DECR_AND_STORE
11240
c48245f0
MR
11241 tcg_gen_movi_tl(t2, -framesize);
11242 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11243 tcg_temp_free(t0);
11244 tcg_temp_free(t1);
c48245f0 11245 tcg_temp_free(t2);
364d4831
NF
11246}
11247
11248static void gen_mips16_restore (DisasContext *ctx,
11249 int xsregs, int aregs,
11250 int do_ra, int do_s0, int do_s1,
11251 int framesize)
11252{
11253 int astatic;
11254 TCGv t0 = tcg_temp_new();
11255 TCGv t1 = tcg_temp_new();
c48245f0 11256 TCGv t2 = tcg_temp_new();
364d4831 11257
c48245f0
MR
11258 tcg_gen_movi_tl(t2, framesize);
11259 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11260
5f68f5ae 11261#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11262 tcg_gen_movi_tl(t2, -4); \
11263 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11264 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11265 gen_store_gpr(t1, reg); \
364d4831
NF
11266 } while (0)
11267
11268 if (do_ra) {
11269 DECR_AND_LOAD(31);
11270 }
11271
11272 switch (xsregs) {
11273 case 7:
11274 DECR_AND_LOAD(30);
11275 /* Fall through */
11276 case 6:
11277 DECR_AND_LOAD(23);
11278 /* Fall through */
11279 case 5:
11280 DECR_AND_LOAD(22);
11281 /* Fall through */
11282 case 4:
11283 DECR_AND_LOAD(21);
11284 /* Fall through */
11285 case 3:
11286 DECR_AND_LOAD(20);
11287 /* Fall through */
11288 case 2:
11289 DECR_AND_LOAD(19);
11290 /* Fall through */
11291 case 1:
11292 DECR_AND_LOAD(18);
11293 }
11294
11295 if (do_s1) {
11296 DECR_AND_LOAD(17);
11297 }
11298 if (do_s0) {
11299 DECR_AND_LOAD(16);
11300 }
11301
11302 switch (aregs) {
11303 case 0:
11304 case 4:
11305 case 8:
11306 case 12:
11307 case 14:
11308 astatic = 0;
11309 break;
11310 case 1:
11311 case 5:
11312 case 9:
11313 case 13:
11314 astatic = 1;
11315 break;
11316 case 2:
11317 case 6:
11318 case 10:
11319 astatic = 2;
11320 break;
11321 case 3:
11322 case 7:
11323 astatic = 3;
11324 break;
11325 case 11:
11326 astatic = 4;
11327 break;
11328 default:
9c708c7f 11329 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11330 return;
11331 }
11332
11333 if (astatic > 0) {
11334 DECR_AND_LOAD(7);
11335 if (astatic > 1) {
11336 DECR_AND_LOAD(6);
11337 if (astatic > 2) {
11338 DECR_AND_LOAD(5);
11339 if (astatic > 3) {
11340 DECR_AND_LOAD(4);
11341 }
11342 }
11343 }
11344 }
11345#undef DECR_AND_LOAD
11346
c48245f0
MR
11347 tcg_gen_movi_tl(t2, framesize);
11348 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11349 tcg_temp_free(t0);
11350 tcg_temp_free(t1);
c48245f0 11351 tcg_temp_free(t2);
364d4831
NF
11352}
11353
11354static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11355 int is_64_bit, int extended)
11356{
11357 TCGv t0;
11358
11359 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11360 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11361 return;
11362 }
11363
11364 t0 = tcg_temp_new();
11365
11366 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11367 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11368 if (!is_64_bit) {
11369 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11370 }
11371
11372 tcg_temp_free(t0);
11373}
11374
0d74a222
LA
11375static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11376 int16_t offset)
11377{
11378 TCGv_i32 t0 = tcg_const_i32(op);
11379 TCGv t1 = tcg_temp_new();
11380 gen_base_offset_addr(ctx, t1, base, offset);
11381 gen_helper_cache(cpu_env, t1, t0);
11382}
11383
364d4831 11384#if defined(TARGET_MIPS64)
d75c135e 11385static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11386 int ry, int funct, int16_t offset,
11387 int extended)
11388{
11389 switch (funct) {
11390 case I64_LDSP:
d9224450 11391 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11392 check_mips_64(ctx);
11393 offset = extended ? offset : offset << 3;
d75c135e 11394 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11395 break;
11396 case I64_SDSP:
d9224450 11397 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11398 check_mips_64(ctx);
11399 offset = extended ? offset : offset << 3;
5c13fdfd 11400 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11401 break;
11402 case I64_SDRASP:
d9224450 11403 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11404 check_mips_64(ctx);
11405 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11406 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11407 break;
11408 case I64_DADJSP:
d9224450 11409 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11410 check_mips_64(ctx);
11411 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11412 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11413 break;
11414 case I64_LDPC:
d9224450
MR
11415 check_insn(ctx, ISA_MIPS3);
11416 check_mips_64(ctx);
364d4831 11417 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11418 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11419 } else {
11420 offset = extended ? offset : offset << 3;
d75c135e 11421 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11422 }
11423 break;
11424 case I64_DADDIU5:
d9224450 11425 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11426 check_mips_64(ctx);
11427 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11428 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11429 break;
11430 case I64_DADDIUPC:
d9224450 11431 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11432 check_mips_64(ctx);
11433 offset = extended ? offset : offset << 2;
11434 gen_addiupc(ctx, ry, offset, 1, extended);
11435 break;
11436 case I64_DADDIUSP:
d9224450 11437 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11438 check_mips_64(ctx);
11439 offset = extended ? offset : offset << 2;
d75c135e 11440 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11441 break;
11442 }
11443}
11444#endif
11445
240ce26a 11446static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11447{
895c2d04 11448 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11449 int op, rx, ry, funct, sa;
11450 int16_t imm, offset;
11451
11452 ctx->opcode = (ctx->opcode << 16) | extend;
11453 op = (ctx->opcode >> 11) & 0x1f;
11454 sa = (ctx->opcode >> 22) & 0x1f;
11455 funct = (ctx->opcode >> 8) & 0x7;
11456 rx = xlat((ctx->opcode >> 8) & 0x7);
11457 ry = xlat((ctx->opcode >> 5) & 0x7);
11458 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11459 | ((ctx->opcode >> 21) & 0x3f) << 5
11460 | (ctx->opcode & 0x1f));
11461
11462 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11463 counterparts. */
11464 switch (op) {
11465 case M16_OPC_ADDIUSP:
d75c135e 11466 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11467 break;
11468 case M16_OPC_ADDIUPC:
11469 gen_addiupc(ctx, rx, imm, 0, 1);
11470 break;
11471 case M16_OPC_B:
b231c103 11472 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11473 /* No delay slot, so just process as a normal instruction */
11474 break;
11475 case M16_OPC_BEQZ:
b231c103 11476 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11477 /* No delay slot, so just process as a normal instruction */
11478 break;
11479 case M16_OPC_BNEQZ:
b231c103 11480 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11481 /* No delay slot, so just process as a normal instruction */
11482 break;
11483 case M16_OPC_SHIFT:
11484 switch (ctx->opcode & 0x3) {
11485 case 0x0:
d75c135e 11486 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11487 break;
11488 case 0x1:
11489#if defined(TARGET_MIPS64)
11490 check_mips_64(ctx);
d75c135e 11491 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11492#else
9c708c7f 11493 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11494#endif
11495 break;
11496 case 0x2:
d75c135e 11497 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11498 break;
11499 case 0x3:
d75c135e 11500 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11501 break;
11502 }
11503 break;
11504#if defined(TARGET_MIPS64)
11505 case M16_OPC_LD:
d9224450 11506 check_insn(ctx, ISA_MIPS3);
d75de749 11507 check_mips_64(ctx);
d75c135e 11508 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11509 break;
11510#endif
11511 case M16_OPC_RRIA:
11512 imm = ctx->opcode & 0xf;
11513 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11514 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11515 imm = (int16_t) (imm << 1) >> 1;
11516 if ((ctx->opcode >> 4) & 0x1) {
11517#if defined(TARGET_MIPS64)
11518 check_mips_64(ctx);
d75c135e 11519 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11520#else
9c708c7f 11521 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11522#endif
11523 } else {
d75c135e 11524 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11525 }
11526 break;
11527 case M16_OPC_ADDIU8:
d75c135e 11528 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11529 break;
11530 case M16_OPC_SLTI:
d75c135e 11531 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11532 break;
11533 case M16_OPC_SLTIU:
d75c135e 11534 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11535 break;
11536 case M16_OPC_I8:
11537 switch (funct) {
11538 case I8_BTEQZ:
b231c103 11539 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11540 break;
11541 case I8_BTNEZ:
b231c103 11542 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11543 break;
11544 case I8_SWRASP:
5c13fdfd 11545 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11546 break;
11547 case I8_ADJSP:
d75c135e 11548 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11549 break;
11550 case I8_SVRS:
d9224450 11551 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11552 {
11553 int xsregs = (ctx->opcode >> 24) & 0x7;
11554 int aregs = (ctx->opcode >> 16) & 0xf;
11555 int do_ra = (ctx->opcode >> 6) & 0x1;
11556 int do_s0 = (ctx->opcode >> 5) & 0x1;
11557 int do_s1 = (ctx->opcode >> 4) & 0x1;
11558 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11559 | (ctx->opcode & 0xf)) << 3;
11560
11561 if (ctx->opcode & (1 << 7)) {
11562 gen_mips16_save(ctx, xsregs, aregs,
11563 do_ra, do_s0, do_s1,
11564 framesize);
11565 } else {
11566 gen_mips16_restore(ctx, xsregs, aregs,
11567 do_ra, do_s0, do_s1,
11568 framesize);
11569 }
11570 }
11571 break;
11572 default:
9c708c7f 11573 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11574 break;
11575 }
11576 break;
11577 case M16_OPC_LI:
11578 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11579 break;
11580 case M16_OPC_CMPI:
11581 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11582 break;
11583#if defined(TARGET_MIPS64)
11584 case M16_OPC_SD:
d9224450
MR
11585 check_insn(ctx, ISA_MIPS3);
11586 check_mips_64(ctx);
5c13fdfd 11587 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11588 break;
11589#endif
11590 case M16_OPC_LB:
d75c135e 11591 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11592 break;
11593 case M16_OPC_LH:
d75c135e 11594 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11595 break;
11596 case M16_OPC_LWSP:
d75c135e 11597 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11598 break;
11599 case M16_OPC_LW:
d75c135e 11600 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11601 break;
11602 case M16_OPC_LBU:
d75c135e 11603 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11604 break;
11605 case M16_OPC_LHU:
d75c135e 11606 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11607 break;
11608 case M16_OPC_LWPC:
d75c135e 11609 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11610 break;
11611#if defined(TARGET_MIPS64)
11612 case M16_OPC_LWU:
d9224450
MR
11613 check_insn(ctx, ISA_MIPS3);
11614 check_mips_64(ctx);
d75c135e 11615 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11616 break;
11617#endif
11618 case M16_OPC_SB:
5c13fdfd 11619 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11620 break;
11621 case M16_OPC_SH:
5c13fdfd 11622 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11623 break;
11624 case M16_OPC_SWSP:
5c13fdfd 11625 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11626 break;
11627 case M16_OPC_SW:
5c13fdfd 11628 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11629 break;
11630#if defined(TARGET_MIPS64)
11631 case M16_OPC_I64:
d75c135e 11632 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11633 break;
11634#endif
11635 default:
9c708c7f 11636 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11637 break;
11638 }
11639
11640 return 4;
11641}
11642
3b3c1694
LA
11643static inline bool is_uhi(int sdbbp_code)
11644{
11645#ifdef CONFIG_USER_ONLY
11646 return false;
11647#else
11648 return semihosting_enabled() && sdbbp_code == 1;
11649#endif
11650}
11651
240ce26a 11652static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11653{
11654 int rx, ry;
11655 int sa;
11656 int op, cnvt_op, op1, offset;
11657 int funct;
11658 int n_bytes;
11659
11660 op = (ctx->opcode >> 11) & 0x1f;
11661 sa = (ctx->opcode >> 2) & 0x7;
11662 sa = sa == 0 ? 8 : sa;
11663 rx = xlat((ctx->opcode >> 8) & 0x7);
11664 cnvt_op = (ctx->opcode >> 5) & 0x7;
11665 ry = xlat((ctx->opcode >> 5) & 0x7);
11666 op1 = offset = ctx->opcode & 0x1f;
11667
11668 n_bytes = 2;
11669
11670 switch (op) {
11671 case M16_OPC_ADDIUSP:
11672 {
11673 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11674
d75c135e 11675 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11676 }
11677 break;
11678 case M16_OPC_ADDIUPC:
11679 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11680 break;
11681 case M16_OPC_B:
11682 offset = (ctx->opcode & 0x7ff) << 1;
11683 offset = (int16_t)(offset << 4) >> 4;
b231c103 11684 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11685 /* No delay slot, so just process as a normal instruction */
11686 break;
11687 case M16_OPC_JAL:
895c2d04 11688 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11689 offset = (((ctx->opcode & 0x1f) << 21)
11690 | ((ctx->opcode >> 5) & 0x1f) << 16
11691 | offset) << 2;
b231c103
YK
11692 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11693 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11694 n_bytes = 4;
364d4831
NF
11695 break;
11696 case M16_OPC_BEQZ:
b231c103
YK
11697 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11698 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11699 /* No delay slot, so just process as a normal instruction */
11700 break;
11701 case M16_OPC_BNEQZ:
b231c103
YK
11702 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11703 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11704 /* No delay slot, so just process as a normal instruction */
11705 break;
11706 case M16_OPC_SHIFT:
11707 switch (ctx->opcode & 0x3) {
11708 case 0x0:
d75c135e 11709 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11710 break;
11711 case 0x1:
11712#if defined(TARGET_MIPS64)
d9224450 11713 check_insn(ctx, ISA_MIPS3);
364d4831 11714 check_mips_64(ctx);
d75c135e 11715 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11716#else
9c708c7f 11717 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11718#endif
11719 break;
11720 case 0x2:
d75c135e 11721 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11722 break;
11723 case 0x3:
d75c135e 11724 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11725 break;
11726 }
11727 break;
11728#if defined(TARGET_MIPS64)
11729 case M16_OPC_LD:
d9224450 11730 check_insn(ctx, ISA_MIPS3);
364d4831 11731 check_mips_64(ctx);
d75c135e 11732 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11733 break;
11734#endif
11735 case M16_OPC_RRIA:
11736 {
11737 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11738
11739 if ((ctx->opcode >> 4) & 1) {
11740#if defined(TARGET_MIPS64)
d9224450 11741 check_insn(ctx, ISA_MIPS3);
364d4831 11742 check_mips_64(ctx);
d75c135e 11743 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11744#else
9c708c7f 11745 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11746#endif
11747 } else {
d75c135e 11748 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11749 }
11750 }
11751 break;
11752 case M16_OPC_ADDIU8:
11753 {
11754 int16_t imm = (int8_t) ctx->opcode;
11755
d75c135e 11756 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11757 }
11758 break;
11759 case M16_OPC_SLTI:
11760 {
11761 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11762 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11763 }
11764 break;
11765 case M16_OPC_SLTIU:
11766 {
11767 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11768 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11769 }
11770 break;
11771 case M16_OPC_I8:
11772 {
11773 int reg32;
11774
11775 funct = (ctx->opcode >> 8) & 0x7;
11776 switch (funct) {
11777 case I8_BTEQZ:
11778 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11779 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11780 break;
11781 case I8_BTNEZ:
11782 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11783 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11784 break;
11785 case I8_SWRASP:
5c13fdfd 11786 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11787 break;
11788 case I8_ADJSP:
d75c135e 11789 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11790 ((int8_t)ctx->opcode) << 3);
11791 break;
11792 case I8_SVRS:
d9224450 11793 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11794 {
11795 int do_ra = ctx->opcode & (1 << 6);
11796 int do_s0 = ctx->opcode & (1 << 5);
11797 int do_s1 = ctx->opcode & (1 << 4);
11798 int framesize = ctx->opcode & 0xf;
11799
11800 if (framesize == 0) {
11801 framesize = 128;
11802 } else {
11803 framesize = framesize << 3;
11804 }
11805
11806 if (ctx->opcode & (1 << 7)) {
11807 gen_mips16_save(ctx, 0, 0,
11808 do_ra, do_s0, do_s1, framesize);
11809 } else {
11810 gen_mips16_restore(ctx, 0, 0,
11811 do_ra, do_s0, do_s1, framesize);
11812 }
11813 }
11814 break;
11815 case I8_MOV32R:
11816 {
11817 int rz = xlat(ctx->opcode & 0x7);
11818
11819 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11820 ((ctx->opcode >> 5) & 0x7);
d75c135e 11821 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11822 }
11823 break;
11824 case I8_MOVR32:
11825 reg32 = ctx->opcode & 0x1f;
d75c135e 11826 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11827 break;
11828 default:
9c708c7f 11829 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11830 break;
11831 }
11832 }
11833 break;
11834 case M16_OPC_LI:
11835 {
11836 int16_t imm = (uint8_t) ctx->opcode;
11837
d75c135e 11838 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11839 }
11840 break;
11841 case M16_OPC_CMPI:
11842 {
11843 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11844 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11845 }
11846 break;
11847#if defined(TARGET_MIPS64)
11848 case M16_OPC_SD:
d9224450 11849 check_insn(ctx, ISA_MIPS3);
364d4831 11850 check_mips_64(ctx);
5c13fdfd 11851 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11852 break;
11853#endif
11854 case M16_OPC_LB:
d75c135e 11855 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11856 break;
11857 case M16_OPC_LH:
d75c135e 11858 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11859 break;
11860 case M16_OPC_LWSP:
d75c135e 11861 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11862 break;
11863 case M16_OPC_LW:
d75c135e 11864 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11865 break;
11866 case M16_OPC_LBU:
d75c135e 11867 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11868 break;
11869 case M16_OPC_LHU:
d75c135e 11870 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11871 break;
11872 case M16_OPC_LWPC:
d75c135e 11873 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11874 break;
11875#if defined (TARGET_MIPS64)
11876 case M16_OPC_LWU:
d9224450 11877 check_insn(ctx, ISA_MIPS3);
364d4831 11878 check_mips_64(ctx);
d75c135e 11879 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11880 break;
11881#endif
11882 case M16_OPC_SB:
5c13fdfd 11883 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11884 break;
11885 case M16_OPC_SH:
5c13fdfd 11886 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11887 break;
11888 case M16_OPC_SWSP:
5c13fdfd 11889 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11890 break;
11891 case M16_OPC_SW:
5c13fdfd 11892 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11893 break;
11894 case M16_OPC_RRR:
11895 {
11896 int rz = xlat((ctx->opcode >> 2) & 0x7);
11897 int mips32_op;
11898
11899 switch (ctx->opcode & 0x3) {
11900 case RRR_ADDU:
11901 mips32_op = OPC_ADDU;
11902 break;
11903 case RRR_SUBU:
11904 mips32_op = OPC_SUBU;
11905 break;
11906#if defined(TARGET_MIPS64)
11907 case RRR_DADDU:
11908 mips32_op = OPC_DADDU;
d9224450 11909 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11910 check_mips_64(ctx);
11911 break;
11912 case RRR_DSUBU:
11913 mips32_op = OPC_DSUBU;
d9224450 11914 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11915 check_mips_64(ctx);
11916 break;
11917#endif
11918 default:
9c708c7f 11919 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11920 goto done;
11921 }
11922
d75c135e 11923 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11924 done:
11925 ;
11926 }
11927 break;
11928 case M16_OPC_RR:
11929 switch (op1) {
11930 case RR_JR:
11931 {
11932 int nd = (ctx->opcode >> 7) & 0x1;
11933 int link = (ctx->opcode >> 6) & 0x1;
11934 int ra = (ctx->opcode >> 5) & 0x1;
11935
d9224450
MR
11936 if (nd) {
11937 check_insn(ctx, ISA_MIPS32);
11938 }
11939
364d4831 11940 if (link) {
b231c103 11941 op = OPC_JALR;
364d4831
NF
11942 } else {
11943 op = OPC_JR;
11944 }
11945
b231c103
YK
11946 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11947 (nd ? 0 : 2));
364d4831
NF
11948 }
11949 break;
11950 case RR_SDBBP:
3b3c1694
LA
11951 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11952 gen_helper_do_semihosting(cpu_env);
11953 } else {
11954 /* XXX: not clear which exception should be raised
11955 * when in debug mode...
11956 */
11957 check_insn(ctx, ISA_MIPS32);
9c708c7f 11958 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 11959 }
364d4831
NF
11960 break;
11961 case RR_SLT:
d75c135e 11962 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11963 break;
11964 case RR_SLTU:
d75c135e 11965 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11966 break;
11967 case RR_BREAK:
9c708c7f 11968 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
11969 break;
11970 case RR_SLLV:
d75c135e 11971 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11972 break;
11973 case RR_SRLV:
d75c135e 11974 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11975 break;
11976 case RR_SRAV:
d75c135e 11977 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11978 break;
11979#if defined (TARGET_MIPS64)
11980 case RR_DSRL:
d9224450 11981 check_insn(ctx, ISA_MIPS3);
364d4831 11982 check_mips_64(ctx);
d75c135e 11983 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11984 break;
11985#endif
11986 case RR_CMP:
d75c135e 11987 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11988 break;
11989 case RR_NEG:
d75c135e 11990 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11991 break;
11992 case RR_AND:
d75c135e 11993 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11994 break;
11995 case RR_OR:
d75c135e 11996 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11997 break;
11998 case RR_XOR:
d75c135e 11999 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12000 break;
12001 case RR_NOT:
d75c135e 12002 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12003 break;
12004 case RR_MFHI:
26135ead 12005 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12006 break;
12007 case RR_CNVT:
d9224450 12008 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12009 switch (cnvt_op) {
12010 case RR_RY_CNVT_ZEB:
12011 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12012 break;
12013 case RR_RY_CNVT_ZEH:
12014 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12015 break;
12016 case RR_RY_CNVT_SEB:
12017 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12018 break;
12019 case RR_RY_CNVT_SEH:
12020 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12021 break;
12022#if defined (TARGET_MIPS64)
12023 case RR_RY_CNVT_ZEW:
d9224450 12024 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12025 check_mips_64(ctx);
12026 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12027 break;
12028 case RR_RY_CNVT_SEW:
d9224450 12029 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12030 check_mips_64(ctx);
12031 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12032 break;
12033#endif
12034 default:
9c708c7f 12035 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12036 break;
12037 }
12038 break;
12039 case RR_MFLO:
26135ead 12040 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12041 break;
12042#if defined (TARGET_MIPS64)
12043 case RR_DSRA:
d9224450 12044 check_insn(ctx, ISA_MIPS3);
364d4831 12045 check_mips_64(ctx);
d75c135e 12046 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12047 break;
12048 case RR_DSLLV:
d9224450 12049 check_insn(ctx, ISA_MIPS3);
364d4831 12050 check_mips_64(ctx);
d75c135e 12051 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12052 break;
12053 case RR_DSRLV:
d9224450 12054 check_insn(ctx, ISA_MIPS3);
364d4831 12055 check_mips_64(ctx);
d75c135e 12056 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12057 break;
12058 case RR_DSRAV:
d9224450 12059 check_insn(ctx, ISA_MIPS3);
364d4831 12060 check_mips_64(ctx);
d75c135e 12061 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12062 break;
12063#endif
12064 case RR_MULT:
26135ead 12065 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12066 break;
12067 case RR_MULTU:
26135ead 12068 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12069 break;
12070 case RR_DIV:
26135ead 12071 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12072 break;
12073 case RR_DIVU:
26135ead 12074 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12075 break;
12076#if defined (TARGET_MIPS64)
12077 case RR_DMULT:
d9224450 12078 check_insn(ctx, ISA_MIPS3);
364d4831 12079 check_mips_64(ctx);
26135ead 12080 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12081 break;
12082 case RR_DMULTU:
d9224450 12083 check_insn(ctx, ISA_MIPS3);
364d4831 12084 check_mips_64(ctx);
26135ead 12085 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12086 break;
12087 case RR_DDIV:
d9224450 12088 check_insn(ctx, ISA_MIPS3);
364d4831 12089 check_mips_64(ctx);
26135ead 12090 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12091 break;
12092 case RR_DDIVU:
d9224450 12093 check_insn(ctx, ISA_MIPS3);
364d4831 12094 check_mips_64(ctx);
26135ead 12095 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12096 break;
12097#endif
12098 default:
9c708c7f 12099 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12100 break;
12101 }
12102 break;
12103 case M16_OPC_EXTEND:
240ce26a 12104 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12105 n_bytes = 4;
12106 break;
12107#if defined(TARGET_MIPS64)
12108 case M16_OPC_I64:
12109 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12110 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12111 break;
12112#endif
12113 default:
9c708c7f 12114 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12115 break;
12116 }
12117
12118 return n_bytes;
12119}
12120
211da992 12121/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12122
211da992
CWR
12123/*
12124 * microMIPS32/microMIPS64 major opcodes
12125 *
12126 * 1. MIPS Architecture for Programmers Volume II-B:
12127 * The microMIPS32 Instruction Set (Revision 3.05)
12128 *
12129 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12130 *
12131 * 2. MIPS Architecture For Programmers Volume II-A:
12132 * The MIPS64 Instruction Set (Revision 3.51)
12133 */
6af0bf9c 12134
3c824109
NF
12135enum {
12136 POOL32A = 0x00,
12137 POOL16A = 0x01,
12138 LBU16 = 0x02,
12139 MOVE16 = 0x03,
12140 ADDI32 = 0x04,
3a1f4268
YK
12141 R6_LUI = 0x04,
12142 AUI = 0x04,
3c824109
NF
12143 LBU32 = 0x05,
12144 SB32 = 0x06,
12145 LB32 = 0x07,
12146
12147 POOL32B = 0x08,
12148 POOL16B = 0x09,
12149 LHU16 = 0x0a,
12150 ANDI16 = 0x0b,
12151 ADDIU32 = 0x0c,
12152 LHU32 = 0x0d,
12153 SH32 = 0x0e,
12154 LH32 = 0x0f,
12155
12156 POOL32I = 0x10,
12157 POOL16C = 0x11,
12158 LWSP16 = 0x12,
12159 POOL16D = 0x13,
12160 ORI32 = 0x14,
12161 POOL32F = 0x15,
211da992
CWR
12162 POOL32S = 0x16, /* MIPS64 */
12163 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12164
12165 POOL32C = 0x18,
12166 LWGP16 = 0x19,
12167 LW16 = 0x1a,
12168 POOL16E = 0x1b,
12169 XORI32 = 0x1c,
12170 JALS32 = 0x1d,
3a1f4268
YK
12171 BOVC = 0x1d,
12172 BEQC = 0x1d,
12173 BEQZALC = 0x1d,
3c824109 12174 ADDIUPC = 0x1e,
3a1f4268
YK
12175 PCREL = 0x1e,
12176 BNVC = 0x1f,
12177 BNEC = 0x1f,
12178 BNEZALC = 0x1f,
3c824109 12179
3a1f4268
YK
12180 R6_BEQZC = 0x20,
12181 JIC = 0x20,
3c824109
NF
12182 POOL16F = 0x21,
12183 SB16 = 0x22,
12184 BEQZ16 = 0x23,
3a1f4268 12185 BEQZC16 = 0x23,
3c824109
NF
12186 SLTI32 = 0x24,
12187 BEQ32 = 0x25,
3a1f4268 12188 BC = 0x25,
3c824109
NF
12189 SWC132 = 0x26,
12190 LWC132 = 0x27,
12191
3a1f4268 12192 /* 0x29 is reserved */
3c824109 12193 RES_29 = 0x29,
3a1f4268
YK
12194 R6_BNEZC = 0x28,
12195 JIALC = 0x28,
3c824109
NF
12196 SH16 = 0x2a,
12197 BNEZ16 = 0x2b,
3a1f4268 12198 BNEZC16 = 0x2b,
3c824109
NF
12199 SLTIU32 = 0x2c,
12200 BNE32 = 0x2d,
3a1f4268 12201 BALC = 0x2d,
3c824109
NF
12202 SDC132 = 0x2e,
12203 LDC132 = 0x2f,
12204
3a1f4268 12205 /* 0x31 is reserved */
3c824109 12206 RES_31 = 0x31,
3a1f4268
YK
12207 BLEZALC = 0x30,
12208 BGEZALC = 0x30,
12209 BGEUC = 0x30,
3c824109
NF
12210 SWSP16 = 0x32,
12211 B16 = 0x33,
3a1f4268 12212 BC16 = 0x33,
3c824109
NF
12213 ANDI32 = 0x34,
12214 J32 = 0x35,
3a1f4268
YK
12215 BGTZC = 0x35,
12216 BLTZC = 0x35,
12217 BLTC = 0x35,
211da992
CWR
12218 SD32 = 0x36, /* MIPS64 */
12219 LD32 = 0x37, /* MIPS64 */
3c824109 12220
3a1f4268 12221 /* 0x39 is reserved */
3c824109 12222 RES_39 = 0x39,
3a1f4268
YK
12223 BGTZALC = 0x38,
12224 BLTZALC = 0x38,
12225 BLTUC = 0x38,
3c824109
NF
12226 SW16 = 0x3a,
12227 LI16 = 0x3b,
12228 JALX32 = 0x3c,
12229 JAL32 = 0x3d,
3a1f4268
YK
12230 BLEZC = 0x3d,
12231 BGEZC = 0x3d,
12232 BGEC = 0x3d,
3c824109
NF
12233 SW32 = 0x3e,
12234 LW32 = 0x3f
12235};
12236
3a1f4268
YK
12237/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12238enum {
12239 ADDIUPC_00 = 0x00,
12240 ADDIUPC_07 = 0x07,
12241 AUIPC = 0x1e,
12242 ALUIPC = 0x1f,
12243 LWPC_08 = 0x08,
12244 LWPC_0F = 0x0F,
12245};
12246
3c824109
NF
12247/* POOL32A encoding of minor opcode field */
12248
12249enum {
12250 /* These opcodes are distinguished only by bits 9..6; those bits are
12251 * what are recorded below. */
12252 SLL32 = 0x0,
12253 SRL32 = 0x1,
12254 SRA = 0x2,
12255 ROTR = 0x3,
3a1f4268
YK
12256 SELEQZ = 0x5,
12257 SELNEZ = 0x6,
b00c7218 12258 R6_RDHWR = 0x7,
3c824109
NF
12259
12260 SLLV = 0x0,
12261 SRLV = 0x1,
12262 SRAV = 0x2,
12263 ROTRV = 0x3,
12264 ADD = 0x4,
12265 ADDU32 = 0x5,
12266 SUB = 0x6,
12267 SUBU32 = 0x7,
12268 MUL = 0x8,
12269 AND = 0x9,
12270 OR32 = 0xa,
12271 NOR = 0xb,
12272 XOR32 = 0xc,
12273 SLT = 0xd,
12274 SLTU = 0xe,
12275
12276 MOVN = 0x0,
3a1f4268 12277 R6_MUL = 0x0,
3c824109 12278 MOVZ = 0x1,
3a1f4268
YK
12279 MUH = 0x1,
12280 MULU = 0x2,
12281 MUHU = 0x3,
3c824109 12282 LWXS = 0x4,
3a1f4268
YK
12283 R6_DIV = 0x4,
12284 MOD = 0x5,
12285 R6_DIVU = 0x6,
12286 MODU = 0x7,
3c824109
NF
12287
12288 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12289 BREAK32 = 0x07,
3c824109 12290 INS = 0x0c,
3a1f4268
YK
12291 LSA = 0x0f,
12292 ALIGN = 0x1f,
3c824109 12293 EXT = 0x2c,
bb238210
YK
12294 POOL32AXF = 0x3c,
12295 SIGRIE = 0x3f
3c824109
NF
12296};
12297
12298/* POOL32AXF encoding of minor opcode field extension */
12299
d132c79f
CWR
12300/*
12301 * 1. MIPS Architecture for Programmers Volume II-B:
12302 * The microMIPS32 Instruction Set (Revision 3.05)
12303 *
12304 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12305 *
12306 * 2. MIPS Architecture for Programmers VolumeIV-e:
12307 * The MIPS DSP Application-Specific Extension
12308 * to the microMIPS32 Architecture (Revision 2.34)
12309 *
12310 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12311 */
12312
3c824109
NF
12313enum {
12314 /* bits 11..6 */
12315 TEQ = 0x00,
12316 TGE = 0x08,
12317 TGEU = 0x10,
12318 TLT = 0x20,
12319 TLTU = 0x28,
12320 TNE = 0x30,
12321
12322 MFC0 = 0x03,
12323 MTC0 = 0x0b,
12324
d132c79f
CWR
12325 /* begin of microMIPS32 DSP */
12326
3c824109
NF
12327 /* bits 13..12 for 0x01 */
12328 MFHI_ACC = 0x0,
12329 MFLO_ACC = 0x1,
12330 MTHI_ACC = 0x2,
12331 MTLO_ACC = 0x3,
12332
12333 /* bits 13..12 for 0x2a */
12334 MADD_ACC = 0x0,
12335 MADDU_ACC = 0x1,
12336 MSUB_ACC = 0x2,
12337 MSUBU_ACC = 0x3,
12338
12339 /* bits 13..12 for 0x32 */
12340 MULT_ACC = 0x0,
6801038b 12341 MULTU_ACC = 0x1,
3c824109 12342
d132c79f
CWR
12343 /* end of microMIPS32 DSP */
12344
3c824109 12345 /* bits 15..12 for 0x2c */
3a1f4268 12346 BITSWAP = 0x0,
3c824109
NF
12347 SEB = 0x2,
12348 SEH = 0x3,
12349 CLO = 0x4,
12350 CLZ = 0x5,
12351 RDHWR = 0x6,
12352 WSBH = 0x7,
12353 MULT = 0x8,
12354 MULTU = 0x9,
12355 DIV = 0xa,
12356 DIVU = 0xb,
12357 MADD = 0xc,
12358 MADDU = 0xd,
12359 MSUB = 0xe,
12360 MSUBU = 0xf,
12361
12362 /* bits 15..12 for 0x34 */
12363 MFC2 = 0x4,
12364 MTC2 = 0x5,
12365 MFHC2 = 0x8,
12366 MTHC2 = 0x9,
12367 CFC2 = 0xc,
12368 CTC2 = 0xd,
12369
12370 /* bits 15..12 for 0x3c */
12371 JALR = 0x0,
12372 JR = 0x0, /* alias */
3a1f4268
YK
12373 JALRC = 0x0,
12374 JRC = 0x0,
3c824109 12375 JALR_HB = 0x1,
3a1f4268 12376 JALRC_HB = 0x1,
3c824109
NF
12377 JALRS = 0x4,
12378 JALRS_HB = 0x5,
12379
12380 /* bits 15..12 for 0x05 */
12381 RDPGPR = 0xe,
12382 WRPGPR = 0xf,
12383
12384 /* bits 15..12 for 0x0d */
12385 TLBP = 0x0,
12386 TLBR = 0x1,
12387 TLBWI = 0x2,
12388 TLBWR = 0x3,
e60ec063
YK
12389 TLBINV = 0x4,
12390 TLBINVF = 0x5,
3c824109
NF
12391 WAIT = 0x9,
12392 IRET = 0xd,
12393 DERET = 0xe,
12394 ERET = 0xf,
12395
12396 /* bits 15..12 for 0x15 */
12397 DMT = 0x0,
12398 DVPE = 0x1,
12399 EMT = 0x2,
12400 EVPE = 0x3,
12401
12402 /* bits 15..12 for 0x1d */
12403 DI = 0x4,
12404 EI = 0x5,
12405
12406 /* bits 15..12 for 0x2d */
12407 SYNC = 0x6,
12408 SYSCALL = 0x8,
12409 SDBBP = 0xd,
12410
12411 /* bits 15..12 for 0x35 */
12412 MFHI32 = 0x0,
12413 MFLO32 = 0x1,
12414 MTHI32 = 0x2,
12415 MTLO32 = 0x3,
12416};
12417
12418/* POOL32B encoding of minor opcode field (bits 15..12) */
12419
12420enum {
12421 LWC2 = 0x0,
12422 LWP = 0x1,
12423 LDP = 0x4,
12424 LWM32 = 0x5,
12425 CACHE = 0x6,
12426 LDM = 0x7,
12427 SWC2 = 0x8,
12428 SWP = 0x9,
12429 SDP = 0xc,
12430 SWM32 = 0xd,
12431 SDM = 0xf
12432};
12433
12434/* POOL32C encoding of minor opcode field (bits 15..12) */
12435
12436enum {
12437 LWL = 0x0,
12438 SWL = 0x8,
12439 LWR = 0x1,
12440 SWR = 0x9,
12441 PREF = 0x2,
12442 /* 0xa is reserved */
12443 LL = 0x3,
12444 SC = 0xb,
12445 LDL = 0x4,
12446 SDL = 0xc,
12447 LDR = 0x5,
12448 SDR = 0xd,
12449 /* 0x6 is reserved */
12450 LWU = 0xe,
12451 LLD = 0x7,
12452 SCD = 0xf
12453};
12454
12455/* POOL32F encoding of minor opcode field (bits 5..0) */
12456
12457enum {
12458 /* These are the bit 7..6 values */
12459 ADD_FMT = 0x0,
3c824109
NF
12460
12461 SUB_FMT = 0x1,
3c824109
NF
12462
12463 MUL_FMT = 0x2,
12464
12465 DIV_FMT = 0x3,
12466
12467 /* These are the bit 8..6 values */
3a1f4268 12468 MOVN_FMT = 0x0,
3c824109
NF
12469 RSQRT2_FMT = 0x0,
12470 MOVF_FMT = 0x0,
3a1f4268
YK
12471 RINT_FMT = 0x0,
12472 SELNEZ_FMT = 0x0,
3c824109 12473
3a1f4268 12474 MOVZ_FMT = 0x1,
3c824109
NF
12475 LWXC1 = 0x1,
12476 MOVT_FMT = 0x1,
3a1f4268
YK
12477 CLASS_FMT = 0x1,
12478 SELEQZ_FMT = 0x1,
3c824109
NF
12479
12480 PLL_PS = 0x2,
12481 SWXC1 = 0x2,
3a1f4268 12482 SEL_FMT = 0x2,
3c824109
NF
12483
12484 PLU_PS = 0x3,
12485 LDXC1 = 0x3,
12486
3a1f4268 12487 MOVN_FMT_04 = 0x4,
3c824109
NF
12488 PUL_PS = 0x4,
12489 SDXC1 = 0x4,
12490 RECIP2_FMT = 0x4,
12491
3a1f4268 12492 MOVZ_FMT_05 = 0x05,
3c824109
NF
12493 PUU_PS = 0x5,
12494 LUXC1 = 0x5,
12495
12496 CVT_PS_S = 0x6,
12497 SUXC1 = 0x6,
12498 ADDR_PS = 0x6,
12499 PREFX = 0x6,
3a1f4268 12500 MADDF_FMT = 0x6,
3c824109
NF
12501
12502 MULR_PS = 0x7,
3a1f4268 12503 MSUBF_FMT = 0x7,
3c824109
NF
12504
12505 MADD_S = 0x01,
12506 MADD_D = 0x09,
12507 MADD_PS = 0x11,
12508 ALNV_PS = 0x19,
12509 MSUB_S = 0x21,
12510 MSUB_D = 0x29,
12511 MSUB_PS = 0x31,
12512
12513 NMADD_S = 0x02,
12514 NMADD_D = 0x0a,
12515 NMADD_PS = 0x12,
12516 NMSUB_S = 0x22,
12517 NMSUB_D = 0x2a,
12518 NMSUB_PS = 0x32,
12519
3a1f4268
YK
12520 MIN_FMT = 0x3,
12521 MAX_FMT = 0xb,
12522 MINA_FMT = 0x23,
12523 MAXA_FMT = 0x2b,
3c824109
NF
12524 POOL32FXF = 0x3b,
12525
12526 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12527 C_COND_FMT = 0x3c,
12528
12529 CMP_CONDN_S = 0x5,
12530 CMP_CONDN_D = 0x15
3c824109
NF
12531};
12532
12533/* POOL32Fxf encoding of minor opcode extension field */
12534
12535enum {
12536 CVT_L = 0x04,
12537 RSQRT_FMT = 0x08,
12538 FLOOR_L = 0x0c,
12539 CVT_PW_PS = 0x1c,
12540 CVT_W = 0x24,
12541 SQRT_FMT = 0x28,
12542 FLOOR_W = 0x2c,
12543 CVT_PS_PW = 0x3c,
12544 CFC1 = 0x40,
12545 RECIP_FMT = 0x48,
12546 CEIL_L = 0x4c,
12547 CTC1 = 0x60,
12548 CEIL_W = 0x6c,
12549 MFC1 = 0x80,
12550 CVT_S_PL = 0x84,
12551 TRUNC_L = 0x8c,
12552 MTC1 = 0xa0,
12553 CVT_S_PU = 0xa4,
12554 TRUNC_W = 0xac,
12555 MFHC1 = 0xc0,
12556 ROUND_L = 0xcc,
12557 MTHC1 = 0xe0,
12558 ROUND_W = 0xec,
12559
12560 MOV_FMT = 0x01,
12561 MOVF = 0x05,
12562 ABS_FMT = 0x0d,
12563 RSQRT1_FMT = 0x1d,
12564 MOVT = 0x25,
12565 NEG_FMT = 0x2d,
12566 CVT_D = 0x4d,
12567 RECIP1_FMT = 0x5d,
12568 CVT_S = 0x6d
12569};
12570
12571/* POOL32I encoding of minor opcode field (bits 25..21) */
12572
12573enum {
12574 BLTZ = 0x00,
12575 BLTZAL = 0x01,
12576 BGEZ = 0x02,
12577 BGEZAL = 0x03,
12578 BLEZ = 0x04,
12579 BNEZC = 0x05,
12580 BGTZ = 0x06,
12581 BEQZC = 0x07,
12582 TLTI = 0x08,
3a1f4268 12583 BC1EQZC = 0x08,
3c824109 12584 TGEI = 0x09,
3a1f4268 12585 BC1NEZC = 0x09,
3c824109 12586 TLTIU = 0x0a,
3a1f4268 12587 BC2EQZC = 0x0a,
3c824109 12588 TGEIU = 0x0b,
3a1f4268 12589 BC2NEZC = 0x0a,
3c824109 12590 TNEI = 0x0c,
3a1f4268 12591 R6_SYNCI = 0x0c,
3c824109
NF
12592 LUI = 0x0d,
12593 TEQI = 0x0e,
12594 SYNCI = 0x10,
12595 BLTZALS = 0x11,
12596 BGEZALS = 0x13,
12597 BC2F = 0x14,
12598 BC2T = 0x15,
12599 BPOSGE64 = 0x1a,
12600 BPOSGE32 = 0x1b,
12601 /* These overlap and are distinguished by bit16 of the instruction */
12602 BC1F = 0x1c,
12603 BC1T = 0x1d,
12604 BC1ANY2F = 0x1c,
12605 BC1ANY2T = 0x1d,
12606 BC1ANY4F = 0x1e,
12607 BC1ANY4T = 0x1f
12608};
12609
12610/* POOL16A encoding of minor opcode field */
12611
12612enum {
12613 ADDU16 = 0x0,
12614 SUBU16 = 0x1
12615};
12616
12617/* POOL16B encoding of minor opcode field */
12618
12619enum {
12620 SLL16 = 0x0,
12621 SRL16 = 0x1
12622};
12623
12624/* POOL16C encoding of minor opcode field */
12625
12626enum {
12627 NOT16 = 0x00,
12628 XOR16 = 0x04,
12629 AND16 = 0x08,
12630 OR16 = 0x0c,
12631 LWM16 = 0x10,
12632 SWM16 = 0x14,
12633 JR16 = 0x18,
12634 JRC16 = 0x1a,
12635 JALR16 = 0x1c,
12636 JALR16S = 0x1e,
12637 MFHI16 = 0x20,
12638 MFLO16 = 0x24,
12639 BREAK16 = 0x28,
12640 SDBBP16 = 0x2c,
12641 JRADDIUSP = 0x30
12642};
12643
3a1f4268
YK
12644/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12645
12646enum {
12647 R6_NOT16 = 0x00,
12648 R6_AND16 = 0x01,
12649 R6_LWM16 = 0x02,
12650 R6_JRC16 = 0x03,
12651 MOVEP = 0x04,
12652 MOVEP_07 = 0x07,
12653 R6_XOR16 = 0x08,
12654 R6_OR16 = 0x09,
12655 R6_SWM16 = 0x0a,
12656 JALRC16 = 0x0b,
12657 MOVEP_0C = 0x0c,
12658 MOVEP_0F = 0x0f,
12659 JRCADDIUSP = 0x13,
12660 R6_BREAK16 = 0x1b,
12661 R6_SDBBP16 = 0x3b
12662};
12663
3c824109
NF
12664/* POOL16D encoding of minor opcode field */
12665
12666enum {
12667 ADDIUS5 = 0x0,
12668 ADDIUSP = 0x1
12669};
12670
12671/* POOL16E encoding of minor opcode field */
12672
12673enum {
12674 ADDIUR2 = 0x0,
12675 ADDIUR1SP = 0x1
12676};
12677
12678static int mmreg (int r)
12679{
12680 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12681
12682 return map[r];
12683}
12684
12685/* Used for 16-bit store instructions. */
12686static int mmreg2 (int r)
12687{
12688 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12689
12690 return map[r];
12691}
12692
12693#define uMIPS_RD(op) ((op >> 7) & 0x7)
12694#define uMIPS_RS(op) ((op >> 4) & 0x7)
12695#define uMIPS_RS2(op) uMIPS_RS(op)
12696#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12697#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12698#define uMIPS_RS5(op) (op & 0x1f)
12699
12700/* Signed immediate */
12701#define SIMM(op, start, width) \
12702 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12703 << (32-width)) \
12704 >> (32-width))
12705/* Zero-extended immediate */
12706#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12707
d75c135e 12708static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12709{
12710 int rd = mmreg(uMIPS_RD(ctx->opcode));
12711
d75c135e 12712 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12713}
12714
d75c135e 12715static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12716{
12717 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12718 int rd = mmreg(uMIPS_RD(ctx->opcode));
12719 int rs = mmreg(uMIPS_RS(ctx->opcode));
12720
d75c135e 12721 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12722}
12723
d75c135e 12724static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12725{
12726 int encoded = ZIMM(ctx->opcode, 1, 9);
12727 int decoded;
12728
12729 if (encoded <= 1) {
12730 decoded = 256 + encoded;
12731 } else if (encoded <= 255) {
12732 decoded = encoded;
12733 } else if (encoded <= 509) {
12734 decoded = encoded - 512;
12735 } else {
12736 decoded = encoded - 768;
12737 }
12738
d75c135e 12739 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12740}
12741
d75c135e 12742static void gen_addius5(DisasContext *ctx)
3c824109
NF
12743{
12744 int imm = SIMM(ctx->opcode, 1, 4);
12745 int rd = (ctx->opcode >> 5) & 0x1f;
12746
d75c135e 12747 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12748}
12749
d75c135e 12750static void gen_andi16(DisasContext *ctx)
3c824109
NF
12751{
12752 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12753 31, 32, 63, 64, 255, 32768, 65535 };
12754 int rd = mmreg(uMIPS_RD(ctx->opcode));
12755 int rs = mmreg(uMIPS_RS(ctx->opcode));
12756 int encoded = ZIMM(ctx->opcode, 0, 4);
12757
d75c135e 12758 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12759}
12760
12761static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12762 int base, int16_t offset)
12763{
12764 TCGv t0, t1;
12765 TCGv_i32 t2;
12766
12767 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12768 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12769 return;
12770 }
12771
12772 t0 = tcg_temp_new();
12773
12774 gen_base_offset_addr(ctx, t0, base, offset);
12775
12776 t1 = tcg_const_tl(reglist);
12777 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12778
3c824109
NF
12779 save_cpu_state(ctx, 1);
12780 switch (opc) {
12781 case LWM32:
895c2d04 12782 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12783 break;
12784 case SWM32:
895c2d04 12785 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12786 break;
12787#ifdef TARGET_MIPS64
12788 case LDM:
895c2d04 12789 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12790 break;
12791 case SDM:
895c2d04 12792 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12793 break;
6af0bf9c 12794#endif
3c824109 12795 }
3c824109 12796 tcg_temp_free(t0);
33087598 12797 tcg_temp_free(t1);
3c824109
NF
12798 tcg_temp_free_i32(t2);
12799}
6af0bf9c 12800
3c824109 12801
240ce26a 12802static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12803{
3c824109
NF
12804 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12805 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12806
3c824109
NF
12807 switch (((ctx->opcode) >> 4) & 0x3f) {
12808 case NOT16 + 0:
12809 case NOT16 + 1:
12810 case NOT16 + 2:
12811 case NOT16 + 3:
d75c135e 12812 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12813 break;
12814 case XOR16 + 0:
12815 case XOR16 + 1:
12816 case XOR16 + 2:
12817 case XOR16 + 3:
d75c135e 12818 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12819 break;
12820 case AND16 + 0:
12821 case AND16 + 1:
12822 case AND16 + 2:
12823 case AND16 + 3:
d75c135e 12824 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12825 break;
12826 case OR16 + 0:
12827 case OR16 + 1:
12828 case OR16 + 2:
12829 case OR16 + 3:
d75c135e 12830 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12831 break;
12832 case LWM16 + 0:
12833 case LWM16 + 1:
12834 case LWM16 + 2:
12835 case LWM16 + 3:
12836 {
12837 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12838 int offset = ZIMM(ctx->opcode, 0, 4);
12839
12840 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12841 29, offset << 2);
12842 }
12843 break;
12844 case SWM16 + 0:
12845 case SWM16 + 1:
12846 case SWM16 + 2:
12847 case SWM16 + 3:
12848 {
12849 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12850 int offset = ZIMM(ctx->opcode, 0, 4);
12851
12852 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12853 29, offset << 2);
12854 }
12855 break;
12856 case JR16 + 0:
12857 case JR16 + 1:
12858 {
12859 int reg = ctx->opcode & 0x1f;
12860
b231c103 12861 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12862 }
3c824109
NF
12863 break;
12864 case JRC16 + 0:
12865 case JRC16 + 1:
12866 {
12867 int reg = ctx->opcode & 0x1f;
b231c103 12868 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12869 /* Let normal delay slot handling in our caller take us
12870 to the branch target. */
12871 }
12872 break;
12873 case JALR16 + 0:
12874 case JALR16 + 1:
b231c103
YK
12875 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12876 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12877 break;
3c824109
NF
12878 case JALR16S + 0:
12879 case JALR16S + 1:
b231c103
YK
12880 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12881 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12882 break;
12883 case MFHI16 + 0:
12884 case MFHI16 + 1:
26135ead 12885 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12886 break;
12887 case MFLO16 + 0:
12888 case MFLO16 + 1:
26135ead 12889 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12890 break;
12891 case BREAK16:
9c708c7f 12892 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
12893 break;
12894 case SDBBP16:
3b3c1694
LA
12895 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12896 gen_helper_do_semihosting(cpu_env);
12897 } else {
12898 /* XXX: not clear which exception should be raised
12899 * when in debug mode...
12900 */
12901 check_insn(ctx, ISA_MIPS32);
9c708c7f 12902 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12903 }
3c824109
NF
12904 break;
12905 case JRADDIUSP + 0:
12906 case JRADDIUSP + 1:
12907 {
12908 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12909 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12910 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12911 /* Let normal delay slot handling in our caller take us
12912 to the branch target. */
12913 }
12914 break;
12915 default:
9c708c7f 12916 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12917 break;
12918 }
12919}
12920
ed7ce6c0
YK
12921static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12922 int enc_rs)
12923{
12924 int rd, rs, re, rt;
12925 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12926 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12927 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12928 rd = rd_enc[enc_dest];
12929 re = re_enc[enc_dest];
12930 rs = rs_rt_enc[enc_rs];
12931 rt = rs_rt_enc[enc_rt];
12932 if (rs) {
12933 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12934 } else {
12935 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12936 }
12937 if (rt) {
12938 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12939 } else {
12940 tcg_gen_movi_tl(cpu_gpr[re], 0);
12941 }
12942}
12943
12944static void gen_pool16c_r6_insn(DisasContext *ctx)
12945{
12946 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12947 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12948
12949 switch (ctx->opcode & 0xf) {
12950 case R6_NOT16:
12951 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12952 break;
12953 case R6_AND16:
12954 gen_logic(ctx, OPC_AND, rt, rt, rs);
12955 break;
12956 case R6_LWM16:
12957 {
12958 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12959 int offset = extract32(ctx->opcode, 4, 4);
12960 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12961 }
12962 break;
12963 case R6_JRC16: /* JRCADDIUSP */
12964 if ((ctx->opcode >> 4) & 1) {
12965 /* JRCADDIUSP */
12966 int imm = extract32(ctx->opcode, 5, 5);
12967 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12968 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12969 } else {
12970 /* JRC16 */
12971 int rs = extract32(ctx->opcode, 5, 5);
12972 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12973 }
12974 break;
12975 case MOVEP ... MOVEP_07:
12976 case MOVEP_0C ... MOVEP_0F:
12977 {
12978 int enc_dest = uMIPS_RD(ctx->opcode);
12979 int enc_rt = uMIPS_RS2(ctx->opcode);
12980 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12981 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12982 }
12983 break;
12984 case R6_XOR16:
12985 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12986 break;
12987 case R6_OR16:
12988 gen_logic(ctx, OPC_OR, rt, rt, rs);
12989 break;
12990 case R6_SWM16:
12991 {
12992 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12993 int offset = extract32(ctx->opcode, 4, 4);
12994 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12995 }
12996 break;
12997 case JALRC16: /* BREAK16, SDBBP16 */
12998 switch (ctx->opcode & 0x3f) {
12999 case JALRC16:
13000 case JALRC16 + 0x20:
13001 /* JALRC16 */
13002 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13003 31, 0, 0);
13004 break;
13005 case R6_BREAK16:
13006 /* BREAK16 */
13007 generate_exception(ctx, EXCP_BREAK);
13008 break;
13009 case R6_SDBBP16:
13010 /* SDBBP16 */
060ebfef
LA
13011 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13012 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13013 } else {
060ebfef
LA
13014 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13015 generate_exception(ctx, EXCP_RI);
13016 } else {
13017 generate_exception(ctx, EXCP_DBp);
13018 }
ed7ce6c0
YK
13019 }
13020 break;
13021 }
13022 break;
13023 default:
13024 generate_exception(ctx, EXCP_RI);
13025 break;
13026 }
13027}
13028
3c824109
NF
13029static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13030{
13031 TCGv t0 = tcg_temp_new();
13032 TCGv t1 = tcg_temp_new();
13033
13034 gen_load_gpr(t0, base);
13035
13036 if (index != 0) {
13037 gen_load_gpr(t1, index);
13038 tcg_gen_shli_tl(t1, t1, 2);
13039 gen_op_addr_add(ctx, t0, t1, t0);
13040 }
13041
5f68f5ae 13042 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13043 gen_store_gpr(t1, rd);
13044
13045 tcg_temp_free(t0);
13046 tcg_temp_free(t1);
13047}
13048
13049static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13050 int base, int16_t offset)
13051{
3c824109
NF
13052 TCGv t0, t1;
13053
36c6711b 13054 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13055 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13056 return;
13057 }
13058
3c824109
NF
13059 t0 = tcg_temp_new();
13060 t1 = tcg_temp_new();
8e9ade68 13061
3c824109
NF
13062 gen_base_offset_addr(ctx, t0, base, offset);
13063
13064 switch (opc) {
13065 case LWP:
36c6711b 13066 if (rd == base) {
9c708c7f 13067 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13068 return;
13069 }
5f68f5ae 13070 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13071 gen_store_gpr(t1, rd);
13072 tcg_gen_movi_tl(t1, 4);
13073 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13074 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13075 gen_store_gpr(t1, rd+1);
3c824109
NF
13076 break;
13077 case SWP:
3c824109 13078 gen_load_gpr(t1, rd);
5f68f5ae 13079 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13080 tcg_gen_movi_tl(t1, 4);
13081 gen_op_addr_add(ctx, t0, t0, t1);
13082 gen_load_gpr(t1, rd+1);
5f68f5ae 13083 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13084 break;
13085#ifdef TARGET_MIPS64
13086 case LDP:
36c6711b 13087 if (rd == base) {
9c708c7f 13088 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13089 return;
13090 }
5f68f5ae 13091 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13092 gen_store_gpr(t1, rd);
13093 tcg_gen_movi_tl(t1, 8);
13094 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13095 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13096 gen_store_gpr(t1, rd+1);
3c824109
NF
13097 break;
13098 case SDP:
3c824109 13099 gen_load_gpr(t1, rd);
5f68f5ae 13100 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13101 tcg_gen_movi_tl(t1, 8);
13102 gen_op_addr_add(ctx, t0, t0, t1);
13103 gen_load_gpr(t1, rd+1);
5f68f5ae 13104 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13105 break;
13106#endif
6af0bf9c 13107 }
3c824109
NF
13108 tcg_temp_free(t0);
13109 tcg_temp_free(t1);
13110}
618b0fe9 13111
240ce26a 13112static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13113{
13114 int extension = (ctx->opcode >> 6) & 0x3f;
13115 int minor = (ctx->opcode >> 12) & 0xf;
13116 uint32_t mips32_op;
13117
13118 switch (extension) {
13119 case TEQ:
13120 mips32_op = OPC_TEQ;
13121 goto do_trap;
13122 case TGE:
13123 mips32_op = OPC_TGE;
13124 goto do_trap;
13125 case TGEU:
13126 mips32_op = OPC_TGEU;
13127 goto do_trap;
13128 case TLT:
13129 mips32_op = OPC_TLT;
13130 goto do_trap;
13131 case TLTU:
13132 mips32_op = OPC_TLTU;
13133 goto do_trap;
13134 case TNE:
13135 mips32_op = OPC_TNE;
13136 do_trap:
13137 gen_trap(ctx, mips32_op, rs, rt, -1);
13138 break;
13139#ifndef CONFIG_USER_ONLY
13140 case MFC0:
13141 case MFC0 + 32:
2e15497c 13142 check_cp0_enabled(ctx);
3c824109
NF
13143 if (rt == 0) {
13144 /* Treat as NOP. */
13145 break;
13146 }
d75c135e 13147 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13148 break;
13149 case MTC0:
13150 case MTC0 + 32:
2e15497c 13151 check_cp0_enabled(ctx);
3c824109
NF
13152 {
13153 TCGv t0 = tcg_temp_new();
618b0fe9 13154
3c824109 13155 gen_load_gpr(t0, rt);
d75c135e 13156 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13157 tcg_temp_free(t0);
13158 }
13159 break;
13160#endif
a1fc6246
LA
13161 case 0x2a:
13162 switch (minor & 3) {
13163 case MADD_ACC:
13164 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13165 break;
13166 case MADDU_ACC:
13167 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13168 break;
13169 case MSUB_ACC:
13170 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13171 break;
13172 case MSUBU_ACC:
13173 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13174 break;
13175 default:
13176 goto pool32axf_invalid;
13177 }
13178 break;
13179 case 0x32:
13180 switch (minor & 3) {
13181 case MULT_ACC:
13182 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13183 break;
13184 case MULTU_ACC:
13185 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13186 break;
13187 default:
13188 goto pool32axf_invalid;
13189 }
13190 break;
3c824109
NF
13191 case 0x2c:
13192 switch (minor) {
e0332095
YK
13193 case BITSWAP:
13194 check_insn(ctx, ISA_MIPS32R6);
13195 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13196 break;
3c824109
NF
13197 case SEB:
13198 gen_bshfl(ctx, OPC_SEB, rs, rt);
13199 break;
13200 case SEH:
13201 gen_bshfl(ctx, OPC_SEH, rs, rt);
13202 break;
13203 case CLO:
13204 mips32_op = OPC_CLO;
13205 goto do_cl;
13206 case CLZ:
13207 mips32_op = OPC_CLZ;
13208 do_cl:
d75c135e 13209 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13210 gen_cl(ctx, mips32_op, rt, rs);
13211 break;
13212 case RDHWR:
b00c7218
YK
13213 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13214 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13215 break;
13216 case WSBH:
13217 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13218 break;
13219 case MULT:
9e8f441a 13220 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13221 mips32_op = OPC_MULT;
26135ead 13222 goto do_mul;
3c824109 13223 case MULTU:
9e8f441a 13224 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13225 mips32_op = OPC_MULTU;
26135ead 13226 goto do_mul;
3c824109 13227 case DIV:
9e8f441a 13228 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13229 mips32_op = OPC_DIV;
26135ead 13230 goto do_div;
3c824109 13231 case DIVU:
9e8f441a 13232 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13233 mips32_op = OPC_DIVU;
26135ead
RS
13234 goto do_div;
13235 do_div:
13236 check_insn(ctx, ISA_MIPS32);
13237 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13238 break;
3c824109 13239 case MADD:
9e8f441a 13240 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13241 mips32_op = OPC_MADD;
26135ead 13242 goto do_mul;
3c824109 13243 case MADDU:
9e8f441a 13244 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13245 mips32_op = OPC_MADDU;
26135ead 13246 goto do_mul;
3c824109 13247 case MSUB:
9e8f441a 13248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13249 mips32_op = OPC_MSUB;
26135ead 13250 goto do_mul;
3c824109 13251 case MSUBU:
9e8f441a 13252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13253 mips32_op = OPC_MSUBU;
26135ead 13254 do_mul:
d75c135e 13255 check_insn(ctx, ISA_MIPS32);
a1fc6246 13256 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13257 break;
13258 default:
13259 goto pool32axf_invalid;
13260 }
13261 break;
13262 case 0x34:
13263 switch (minor) {
13264 case MFC2:
13265 case MTC2:
13266 case MFHC2:
13267 case MTHC2:
13268 case CFC2:
13269 case CTC2:
13270 generate_exception_err(ctx, EXCP_CpU, 2);
13271 break;
13272 default:
13273 goto pool32axf_invalid;
13274 }
13275 break;
13276 case 0x3c:
13277 switch (minor) {
65935f07
YK
13278 case JALR: /* JALRC */
13279 case JALR_HB: /* JALRC_HB */
13280 if (ctx->insn_flags & ISA_MIPS32R6) {
13281 /* JALRC, JALRC_HB */
13282 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13283 } else {
13284 /* JALR, JALR_HB */
13285 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13286 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13287 }
3c824109
NF
13288 break;
13289 case JALRS:
13290 case JALRS_HB:
9e8f441a 13291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13292 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13293 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13294 break;
13295 default:
13296 goto pool32axf_invalid;
13297 }
13298 break;
13299 case 0x05:
13300 switch (minor) {
13301 case RDPGPR:
2e15497c 13302 check_cp0_enabled(ctx);
d75c135e 13303 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13304 gen_load_srsgpr(rs, rt);
3c824109
NF
13305 break;
13306 case WRPGPR:
2e15497c 13307 check_cp0_enabled(ctx);
d75c135e 13308 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13309 gen_store_srsgpr(rs, rt);
3c824109
NF
13310 break;
13311 default:
13312 goto pool32axf_invalid;
13313 }
13314 break;
13315#ifndef CONFIG_USER_ONLY
13316 case 0x0d:
13317 switch (minor) {
13318 case TLBP:
13319 mips32_op = OPC_TLBP;
13320 goto do_cp0;
13321 case TLBR:
13322 mips32_op = OPC_TLBR;
13323 goto do_cp0;
13324 case TLBWI:
13325 mips32_op = OPC_TLBWI;
13326 goto do_cp0;
13327 case TLBWR:
13328 mips32_op = OPC_TLBWR;
13329 goto do_cp0;
e60ec063
YK
13330 case TLBINV:
13331 mips32_op = OPC_TLBINV;
13332 goto do_cp0;
13333 case TLBINVF:
13334 mips32_op = OPC_TLBINVF;
13335 goto do_cp0;
3c824109
NF
13336 case WAIT:
13337 mips32_op = OPC_WAIT;
13338 goto do_cp0;
13339 case DERET:
13340 mips32_op = OPC_DERET;
13341 goto do_cp0;
13342 case ERET:
13343 mips32_op = OPC_ERET;
13344 do_cp0:
13345 gen_cp0(env, ctx, mips32_op, rt, rs);
13346 break;
13347 default:
13348 goto pool32axf_invalid;
13349 }
13350 break;
13351 case 0x1d:
13352 switch (minor) {
13353 case DI:
2e15497c 13354 check_cp0_enabled(ctx);
3c824109
NF
13355 {
13356 TCGv t0 = tcg_temp_new();
13357
13358 save_cpu_state(ctx, 1);
895c2d04 13359 gen_helper_di(t0, cpu_env);
3c824109
NF
13360 gen_store_gpr(t0, rs);
13361 /* Stop translation as we may have switched the execution mode */
13362 ctx->bstate = BS_STOP;
13363 tcg_temp_free(t0);
13364 }
13365 break;
13366 case EI:
2e15497c 13367 check_cp0_enabled(ctx);
3c824109
NF
13368 {
13369 TCGv t0 = tcg_temp_new();
13370
13371 save_cpu_state(ctx, 1);
895c2d04 13372 gen_helper_ei(t0, cpu_env);
3c824109
NF
13373 gen_store_gpr(t0, rs);
13374 /* Stop translation as we may have switched the execution mode */
13375 ctx->bstate = BS_STOP;
13376 tcg_temp_free(t0);
13377 }
13378 break;
13379 default:
13380 goto pool32axf_invalid;
13381 }
13382 break;
13383#endif
13384 case 0x2d:
13385 switch (minor) {
13386 case SYNC:
13387 /* NOP */
13388 break;
13389 case SYSCALL:
9c708c7f 13390 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13391 break;
13392 case SDBBP:
3b3c1694
LA
13393 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13394 gen_helper_do_semihosting(cpu_env);
13395 } else {
13396 check_insn(ctx, ISA_MIPS32);
e0332095 13397 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13398 generate_exception_end(ctx, EXCP_RI);
e0332095 13399 } else {
9c708c7f 13400 generate_exception_end(ctx, EXCP_DBp);
e0332095 13401 }
3b3c1694 13402 }
3c824109
NF
13403 break;
13404 default:
13405 goto pool32axf_invalid;
13406 }
13407 break;
a1fc6246 13408 case 0x01:
26135ead 13409 switch (minor & 3) {
a1fc6246 13410 case MFHI_ACC:
26135ead 13411 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13412 break;
a1fc6246 13413 case MFLO_ACC:
26135ead 13414 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13415 break;
a1fc6246 13416 case MTHI_ACC:
26135ead 13417 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13418 break;
a1fc6246 13419 case MTLO_ACC:
26135ead 13420 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13421 break;
13422 default:
13423 goto pool32axf_invalid;
13424 }
13425 break;
a1fc6246 13426 case 0x35:
9e8f441a 13427 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13428 switch (minor) {
13429 case MFHI32:
13430 gen_HILO(ctx, OPC_MFHI, 0, rs);
13431 break;
13432 case MFLO32:
13433 gen_HILO(ctx, OPC_MFLO, 0, rs);
13434 break;
13435 case MTHI32:
13436 gen_HILO(ctx, OPC_MTHI, 0, rs);
13437 break;
13438 case MTLO32:
13439 gen_HILO(ctx, OPC_MTLO, 0, rs);
13440 break;
13441 default:
13442 goto pool32axf_invalid;
13443 }
13444 break;
3c824109
NF
13445 default:
13446 pool32axf_invalid:
13447 MIPS_INVAL("pool32axf");
9c708c7f 13448 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13449 break;
13450 }
13451}
13452
13453/* Values for microMIPS fmt field. Variable-width, depending on which
13454 formats the instruction supports. */
13455
13456enum {
13457 FMT_SD_S = 0,
13458 FMT_SD_D = 1,
13459
13460 FMT_SDPS_S = 0,
13461 FMT_SDPS_D = 1,
13462 FMT_SDPS_PS = 2,
13463
13464 FMT_SWL_S = 0,
13465 FMT_SWL_W = 1,
13466 FMT_SWL_L = 2,
13467
13468 FMT_DWL_D = 0,
13469 FMT_DWL_W = 1,
13470 FMT_DWL_L = 2
13471};
13472
d75c135e 13473static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13474{
13475 int extension = (ctx->opcode >> 6) & 0x3ff;
13476 uint32_t mips32_op;
13477
13478#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13479#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13480#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13481
13482 switch (extension) {
13483 case FLOAT_1BIT_FMT(CFC1, 0):
13484 mips32_op = OPC_CFC1;
13485 goto do_cp1;
13486 case FLOAT_1BIT_FMT(CTC1, 0):
13487 mips32_op = OPC_CTC1;
13488 goto do_cp1;
13489 case FLOAT_1BIT_FMT(MFC1, 0):
13490 mips32_op = OPC_MFC1;
13491 goto do_cp1;
13492 case FLOAT_1BIT_FMT(MTC1, 0):
13493 mips32_op = OPC_MTC1;
13494 goto do_cp1;
13495 case FLOAT_1BIT_FMT(MFHC1, 0):
13496 mips32_op = OPC_MFHC1;
13497 goto do_cp1;
13498 case FLOAT_1BIT_FMT(MTHC1, 0):
13499 mips32_op = OPC_MTHC1;
13500 do_cp1:
13501 gen_cp1(ctx, mips32_op, rt, rs);
13502 break;
13503
13504 /* Reciprocal square root */
13505 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13506 mips32_op = OPC_RSQRT_S;
13507 goto do_unaryfp;
13508 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13509 mips32_op = OPC_RSQRT_D;
13510 goto do_unaryfp;
13511
13512 /* Square root */
13513 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13514 mips32_op = OPC_SQRT_S;
13515 goto do_unaryfp;
13516 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13517 mips32_op = OPC_SQRT_D;
13518 goto do_unaryfp;
13519
13520 /* Reciprocal */
13521 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13522 mips32_op = OPC_RECIP_S;
13523 goto do_unaryfp;
13524 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13525 mips32_op = OPC_RECIP_D;
13526 goto do_unaryfp;
13527
13528 /* Floor */
13529 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13530 mips32_op = OPC_FLOOR_L_S;
13531 goto do_unaryfp;
13532 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13533 mips32_op = OPC_FLOOR_L_D;
13534 goto do_unaryfp;
13535 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13536 mips32_op = OPC_FLOOR_W_S;
13537 goto do_unaryfp;
13538 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13539 mips32_op = OPC_FLOOR_W_D;
13540 goto do_unaryfp;
13541
13542 /* Ceiling */
13543 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13544 mips32_op = OPC_CEIL_L_S;
13545 goto do_unaryfp;
13546 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13547 mips32_op = OPC_CEIL_L_D;
13548 goto do_unaryfp;
13549 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13550 mips32_op = OPC_CEIL_W_S;
13551 goto do_unaryfp;
13552 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13553 mips32_op = OPC_CEIL_W_D;
13554 goto do_unaryfp;
13555
13556 /* Truncation */
13557 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13558 mips32_op = OPC_TRUNC_L_S;
13559 goto do_unaryfp;
13560 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13561 mips32_op = OPC_TRUNC_L_D;
13562 goto do_unaryfp;
13563 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13564 mips32_op = OPC_TRUNC_W_S;
13565 goto do_unaryfp;
13566 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13567 mips32_op = OPC_TRUNC_W_D;
13568 goto do_unaryfp;
13569
13570 /* Round */
13571 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13572 mips32_op = OPC_ROUND_L_S;
13573 goto do_unaryfp;
13574 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13575 mips32_op = OPC_ROUND_L_D;
13576 goto do_unaryfp;
13577 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13578 mips32_op = OPC_ROUND_W_S;
13579 goto do_unaryfp;
13580 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13581 mips32_op = OPC_ROUND_W_D;
13582 goto do_unaryfp;
13583
13584 /* Integer to floating-point conversion */
13585 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13586 mips32_op = OPC_CVT_L_S;
13587 goto do_unaryfp;
13588 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13589 mips32_op = OPC_CVT_L_D;
13590 goto do_unaryfp;
13591 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13592 mips32_op = OPC_CVT_W_S;
13593 goto do_unaryfp;
13594 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13595 mips32_op = OPC_CVT_W_D;
13596 goto do_unaryfp;
13597
13598 /* Paired-foo conversions */
13599 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13600 mips32_op = OPC_CVT_S_PL;
13601 goto do_unaryfp;
13602 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13603 mips32_op = OPC_CVT_S_PU;
13604 goto do_unaryfp;
13605 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13606 mips32_op = OPC_CVT_PW_PS;
13607 goto do_unaryfp;
13608 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13609 mips32_op = OPC_CVT_PS_PW;
13610 goto do_unaryfp;
13611
13612 /* Floating-point moves */
13613 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13614 mips32_op = OPC_MOV_S;
13615 goto do_unaryfp;
13616 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13617 mips32_op = OPC_MOV_D;
13618 goto do_unaryfp;
13619 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13620 mips32_op = OPC_MOV_PS;
13621 goto do_unaryfp;
13622
13623 /* Absolute value */
13624 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13625 mips32_op = OPC_ABS_S;
13626 goto do_unaryfp;
13627 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13628 mips32_op = OPC_ABS_D;
13629 goto do_unaryfp;
13630 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13631 mips32_op = OPC_ABS_PS;
13632 goto do_unaryfp;
13633
13634 /* Negation */
13635 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13636 mips32_op = OPC_NEG_S;
13637 goto do_unaryfp;
13638 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13639 mips32_op = OPC_NEG_D;
13640 goto do_unaryfp;
13641 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13642 mips32_op = OPC_NEG_PS;
13643 goto do_unaryfp;
13644
13645 /* Reciprocal square root step */
13646 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13647 mips32_op = OPC_RSQRT1_S;
13648 goto do_unaryfp;
13649 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13650 mips32_op = OPC_RSQRT1_D;
13651 goto do_unaryfp;
13652 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13653 mips32_op = OPC_RSQRT1_PS;
13654 goto do_unaryfp;
13655
13656 /* Reciprocal step */
13657 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13658 mips32_op = OPC_RECIP1_S;
13659 goto do_unaryfp;
13660 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13661 mips32_op = OPC_RECIP1_S;
13662 goto do_unaryfp;
13663 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13664 mips32_op = OPC_RECIP1_PS;
13665 goto do_unaryfp;
13666
13667 /* Conversions from double */
13668 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13669 mips32_op = OPC_CVT_D_S;
13670 goto do_unaryfp;
13671 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13672 mips32_op = OPC_CVT_D_W;
13673 goto do_unaryfp;
13674 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13675 mips32_op = OPC_CVT_D_L;
13676 goto do_unaryfp;
13677
13678 /* Conversions from single */
13679 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13680 mips32_op = OPC_CVT_S_D;
13681 goto do_unaryfp;
13682 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13683 mips32_op = OPC_CVT_S_W;
13684 goto do_unaryfp;
13685 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13686 mips32_op = OPC_CVT_S_L;
13687 do_unaryfp:
13688 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13689 break;
13690
13691 /* Conditional moves on floating-point codes */
13692 case COND_FLOAT_MOV(MOVT, 0):
13693 case COND_FLOAT_MOV(MOVT, 1):
13694 case COND_FLOAT_MOV(MOVT, 2):
13695 case COND_FLOAT_MOV(MOVT, 3):
13696 case COND_FLOAT_MOV(MOVT, 4):
13697 case COND_FLOAT_MOV(MOVT, 5):
13698 case COND_FLOAT_MOV(MOVT, 6):
13699 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13700 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13701 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13702 break;
13703 case COND_FLOAT_MOV(MOVF, 0):
13704 case COND_FLOAT_MOV(MOVF, 1):
13705 case COND_FLOAT_MOV(MOVF, 2):
13706 case COND_FLOAT_MOV(MOVF, 3):
13707 case COND_FLOAT_MOV(MOVF, 4):
13708 case COND_FLOAT_MOV(MOVF, 5):
13709 case COND_FLOAT_MOV(MOVF, 6):
13710 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13712 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13713 break;
13714 default:
13715 MIPS_INVAL("pool32fxf");
9c708c7f 13716 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13717 break;
13718 }
13719}
13720
f60eeb0c 13721static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13722{
13723 int32_t offset;
13724 uint16_t insn;
13725 int rt, rs, rd, rr;
13726 int16_t imm;
13727 uint32_t op, minor, mips32_op;
13728 uint32_t cond, fmt, cc;
13729
895c2d04 13730 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13731 ctx->opcode = (ctx->opcode << 16) | insn;
13732
13733 rt = (ctx->opcode >> 21) & 0x1f;
13734 rs = (ctx->opcode >> 16) & 0x1f;
13735 rd = (ctx->opcode >> 11) & 0x1f;
13736 rr = (ctx->opcode >> 6) & 0x1f;
13737 imm = (int16_t) ctx->opcode;
13738
13739 op = (ctx->opcode >> 26) & 0x3f;
13740 switch (op) {
13741 case POOL32A:
13742 minor = ctx->opcode & 0x3f;
13743 switch (minor) {
13744 case 0x00:
13745 minor = (ctx->opcode >> 6) & 0xf;
13746 switch (minor) {
13747 case SLL32:
13748 mips32_op = OPC_SLL;
13749 goto do_shifti;
13750 case SRA:
13751 mips32_op = OPC_SRA;
13752 goto do_shifti;
13753 case SRL32:
13754 mips32_op = OPC_SRL;
13755 goto do_shifti;
13756 case ROTR:
13757 mips32_op = OPC_ROTR;
13758 do_shifti:
d75c135e 13759 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13760 break;
e0332095
YK
13761 case SELEQZ:
13762 check_insn(ctx, ISA_MIPS32R6);
13763 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13764 break;
13765 case SELNEZ:
13766 check_insn(ctx, ISA_MIPS32R6);
13767 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13768 break;
b00c7218
YK
13769 case R6_RDHWR:
13770 check_insn(ctx, ISA_MIPS32R6);
13771 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13772 break;
3c824109
NF
13773 default:
13774 goto pool32a_invalid;
13775 }
13776 break;
13777 case 0x10:
13778 minor = (ctx->opcode >> 6) & 0xf;
13779 switch (minor) {
13780 /* Arithmetic */
13781 case ADD:
13782 mips32_op = OPC_ADD;
13783 goto do_arith;
13784 case ADDU32:
13785 mips32_op = OPC_ADDU;
13786 goto do_arith;
13787 case SUB:
13788 mips32_op = OPC_SUB;
13789 goto do_arith;
13790 case SUBU32:
13791 mips32_op = OPC_SUBU;
13792 goto do_arith;
13793 case MUL:
9e8f441a 13794 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13795 mips32_op = OPC_MUL;
13796 do_arith:
d75c135e 13797 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13798 break;
13799 /* Shifts */
13800 case SLLV:
13801 mips32_op = OPC_SLLV;
13802 goto do_shift;
13803 case SRLV:
13804 mips32_op = OPC_SRLV;
13805 goto do_shift;
13806 case SRAV:
13807 mips32_op = OPC_SRAV;
13808 goto do_shift;
13809 case ROTRV:
13810 mips32_op = OPC_ROTRV;
13811 do_shift:
d75c135e 13812 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13813 break;
13814 /* Logical operations */
13815 case AND:
13816 mips32_op = OPC_AND;
13817 goto do_logic;
13818 case OR32:
13819 mips32_op = OPC_OR;
13820 goto do_logic;
13821 case NOR:
13822 mips32_op = OPC_NOR;
13823 goto do_logic;
13824 case XOR32:
13825 mips32_op = OPC_XOR;
13826 do_logic:
d75c135e 13827 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13828 break;
13829 /* Set less than */
13830 case SLT:
13831 mips32_op = OPC_SLT;
13832 goto do_slt;
13833 case SLTU:
13834 mips32_op = OPC_SLTU;
13835 do_slt:
d75c135e 13836 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13837 break;
13838 default:
13839 goto pool32a_invalid;
13840 }
13841 break;
13842 case 0x18:
13843 minor = (ctx->opcode >> 6) & 0xf;
13844 switch (minor) {
13845 /* Conditional moves */
e0332095
YK
13846 case MOVN: /* MUL */
13847 if (ctx->insn_flags & ISA_MIPS32R6) {
13848 /* MUL */
13849 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13850 } else {
13851 /* MOVN */
13852 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13853 }
13854 break;
13855 case MOVZ: /* MUH */
13856 if (ctx->insn_flags & ISA_MIPS32R6) {
13857 /* MUH */
13858 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13859 } else {
13860 /* MOVZ */
13861 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13862 }
13863 break;
13864 case MULU:
13865 check_insn(ctx, ISA_MIPS32R6);
13866 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13867 break;
13868 case MUHU:
13869 check_insn(ctx, ISA_MIPS32R6);
13870 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13871 break;
13872 case LWXS: /* DIV */
13873 if (ctx->insn_flags & ISA_MIPS32R6) {
13874 /* DIV */
13875 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13876 } else {
13877 /* LWXS */
13878 gen_ldxs(ctx, rs, rt, rd);
13879 }
13880 break;
13881 case MOD:
13882 check_insn(ctx, ISA_MIPS32R6);
13883 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13884 break;
13885 case R6_DIVU:
13886 check_insn(ctx, ISA_MIPS32R6);
13887 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13888 break;
e0332095
YK
13889 case MODU:
13890 check_insn(ctx, ISA_MIPS32R6);
13891 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13892 break;
13893 default:
13894 goto pool32a_invalid;
13895 }
13896 break;
13897 case INS:
13898 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13899 return;
e0332095
YK
13900 case LSA:
13901 check_insn(ctx, ISA_MIPS32R6);
13902 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13903 extract32(ctx->opcode, 9, 2));
13904 break;
13905 case ALIGN:
13906 check_insn(ctx, ISA_MIPS32R6);
13907 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13908 extract32(ctx->opcode, 9, 2));
13909 break;
3c824109
NF
13910 case EXT:
13911 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13912 return;
13913 case POOL32AXF:
240ce26a 13914 gen_pool32axf(env, ctx, rt, rs);
3c824109 13915 break;
dbd8af98 13916 case BREAK32:
9c708c7f 13917 generate_exception_end(ctx, EXCP_BREAK);
3c824109 13918 break;
bb238210
YK
13919 case SIGRIE:
13920 check_insn(ctx, ISA_MIPS32R6);
13921 generate_exception_end(ctx, EXCP_RI);
13922 break;
3c824109
NF
13923 default:
13924 pool32a_invalid:
13925 MIPS_INVAL("pool32a");
9c708c7f 13926 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13927 break;
13928 }
13929 break;
13930 case POOL32B:
13931 minor = (ctx->opcode >> 12) & 0xf;
13932 switch (minor) {
13933 case CACHE:
2e15497c 13934 check_cp0_enabled(ctx);
0d74a222
LA
13935 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13936 gen_cache_operation(ctx, rt, rs, imm);
13937 }
3c824109
NF
13938 break;
13939 case LWC2:
13940 case SWC2:
13941 /* COP2: Not implemented. */
13942 generate_exception_err(ctx, EXCP_CpU, 2);
13943 break;
3c824109
NF
13944#ifdef TARGET_MIPS64
13945 case LDP:
13946 case SDP:
d9224450
MR
13947 check_insn(ctx, ISA_MIPS3);
13948 check_mips_64(ctx);
13949 /* Fallthrough */
3c824109 13950#endif
d9224450
MR
13951 case LWP:
13952 case SWP:
3c824109
NF
13953 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13954 break;
3c824109
NF
13955#ifdef TARGET_MIPS64
13956 case LDM:
13957 case SDM:
d9224450
MR
13958 check_insn(ctx, ISA_MIPS3);
13959 check_mips_64(ctx);
13960 /* Fallthrough */
3c824109 13961#endif
d9224450
MR
13962 case LWM32:
13963 case SWM32:
3c824109
NF
13964 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13965 break;
13966 default:
13967 MIPS_INVAL("pool32b");
9c708c7f 13968 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13969 break;
13970 }
13971 break;
13972 case POOL32F:
5ab5c041 13973 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13974 minor = ctx->opcode & 0x3f;
13975 check_cp1_enabled(ctx);
13976 switch (minor) {
13977 case ALNV_PS:
9e8f441a 13978 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13979 mips32_op = OPC_ALNV_PS;
13980 goto do_madd;
13981 case MADD_S:
9e8f441a 13982 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13983 mips32_op = OPC_MADD_S;
13984 goto do_madd;
13985 case MADD_D:
9e8f441a 13986 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13987 mips32_op = OPC_MADD_D;
13988 goto do_madd;
13989 case MADD_PS:
9e8f441a 13990 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13991 mips32_op = OPC_MADD_PS;
13992 goto do_madd;
13993 case MSUB_S:
9e8f441a 13994 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13995 mips32_op = OPC_MSUB_S;
13996 goto do_madd;
13997 case MSUB_D:
9e8f441a 13998 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13999 mips32_op = OPC_MSUB_D;
14000 goto do_madd;
14001 case MSUB_PS:
9e8f441a 14002 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14003 mips32_op = OPC_MSUB_PS;
14004 goto do_madd;
14005 case NMADD_S:
9e8f441a 14006 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14007 mips32_op = OPC_NMADD_S;
14008 goto do_madd;
14009 case NMADD_D:
9e8f441a 14010 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14011 mips32_op = OPC_NMADD_D;
14012 goto do_madd;
14013 case NMADD_PS:
9e8f441a 14014 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14015 mips32_op = OPC_NMADD_PS;
14016 goto do_madd;
14017 case NMSUB_S:
9e8f441a 14018 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14019 mips32_op = OPC_NMSUB_S;
14020 goto do_madd;
14021 case NMSUB_D:
9e8f441a 14022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14023 mips32_op = OPC_NMSUB_D;
14024 goto do_madd;
14025 case NMSUB_PS:
9e8f441a 14026 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14027 mips32_op = OPC_NMSUB_PS;
14028 do_madd:
14029 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14030 break;
14031 case CABS_COND_FMT:
9e8f441a 14032 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14033 cond = (ctx->opcode >> 6) & 0xf;
14034 cc = (ctx->opcode >> 13) & 0x7;
14035 fmt = (ctx->opcode >> 10) & 0x3;
14036 switch (fmt) {
14037 case 0x0:
14038 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14039 break;
14040 case 0x1:
14041 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14042 break;
14043 case 0x2:
14044 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14045 break;
14046 default:
14047 goto pool32f_invalid;
14048 }
14049 break;
14050 case C_COND_FMT:
9e8f441a 14051 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14052 cond = (ctx->opcode >> 6) & 0xf;
14053 cc = (ctx->opcode >> 13) & 0x7;
14054 fmt = (ctx->opcode >> 10) & 0x3;
14055 switch (fmt) {
14056 case 0x0:
14057 gen_cmp_s(ctx, cond, rt, rs, cc);
14058 break;
14059 case 0x1:
14060 gen_cmp_d(ctx, cond, rt, rs, cc);
14061 break;
14062 case 0x2:
14063 gen_cmp_ps(ctx, cond, rt, rs, cc);
14064 break;
14065 default:
14066 goto pool32f_invalid;
14067 }
14068 break;
2a24a7ba
YK
14069 case CMP_CONDN_S:
14070 check_insn(ctx, ISA_MIPS32R6);
14071 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14072 break;
14073 case CMP_CONDN_D:
14074 check_insn(ctx, ISA_MIPS32R6);
14075 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14076 break;
3c824109 14077 case POOL32FXF:
d75c135e 14078 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14079 break;
14080 case 0x00:
14081 /* PLL foo */
14082 switch ((ctx->opcode >> 6) & 0x7) {
14083 case PLL_PS:
14084 mips32_op = OPC_PLL_PS;
14085 goto do_ps;
14086 case PLU_PS:
14087 mips32_op = OPC_PLU_PS;
14088 goto do_ps;
14089 case PUL_PS:
14090 mips32_op = OPC_PUL_PS;
14091 goto do_ps;
14092 case PUU_PS:
14093 mips32_op = OPC_PUU_PS;
14094 goto do_ps;
14095 case CVT_PS_S:
9e8f441a 14096 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14097 mips32_op = OPC_CVT_PS_S;
14098 do_ps:
14099 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14100 break;
14101 default:
14102 goto pool32f_invalid;
14103 }
14104 break;
2a24a7ba
YK
14105 case MIN_FMT:
14106 check_insn(ctx, ISA_MIPS32R6);
14107 switch ((ctx->opcode >> 9) & 0x3) {
14108 case FMT_SDPS_S:
14109 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14110 break;
14111 case FMT_SDPS_D:
14112 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14113 break;
14114 default:
14115 goto pool32f_invalid;
14116 }
14117 break;
3c824109
NF
14118 case 0x08:
14119 /* [LS][WDU]XC1 */
14120 switch ((ctx->opcode >> 6) & 0x7) {
14121 case LWXC1:
9e8f441a 14122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14123 mips32_op = OPC_LWXC1;
14124 goto do_ldst_cp1;
14125 case SWXC1:
9e8f441a 14126 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14127 mips32_op = OPC_SWXC1;
14128 goto do_ldst_cp1;
14129 case LDXC1:
9e8f441a 14130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14131 mips32_op = OPC_LDXC1;
14132 goto do_ldst_cp1;
14133 case SDXC1:
9e8f441a 14134 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14135 mips32_op = OPC_SDXC1;
14136 goto do_ldst_cp1;
14137 case LUXC1:
9e8f441a 14138 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14139 mips32_op = OPC_LUXC1;
14140 goto do_ldst_cp1;
14141 case SUXC1:
9e8f441a 14142 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14143 mips32_op = OPC_SUXC1;
14144 do_ldst_cp1:
14145 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14146 break;
14147 default:
14148 goto pool32f_invalid;
14149 }
14150 break;
2a24a7ba
YK
14151 case MAX_FMT:
14152 check_insn(ctx, ISA_MIPS32R6);
14153 switch ((ctx->opcode >> 9) & 0x3) {
14154 case FMT_SDPS_S:
14155 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14156 break;
14157 case FMT_SDPS_D:
14158 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14159 break;
14160 default:
14161 goto pool32f_invalid;
14162 }
14163 break;
3c824109
NF
14164 case 0x18:
14165 /* 3D insns */
9e8f441a 14166 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14167 fmt = (ctx->opcode >> 9) & 0x3;
14168 switch ((ctx->opcode >> 6) & 0x7) {
14169 case RSQRT2_FMT:
14170 switch (fmt) {
14171 case FMT_SDPS_S:
14172 mips32_op = OPC_RSQRT2_S;
14173 goto do_3d;
14174 case FMT_SDPS_D:
14175 mips32_op = OPC_RSQRT2_D;
14176 goto do_3d;
14177 case FMT_SDPS_PS:
14178 mips32_op = OPC_RSQRT2_PS;
14179 goto do_3d;
14180 default:
14181 goto pool32f_invalid;
14182 }
14183 break;
14184 case RECIP2_FMT:
14185 switch (fmt) {
14186 case FMT_SDPS_S:
14187 mips32_op = OPC_RECIP2_S;
14188 goto do_3d;
14189 case FMT_SDPS_D:
14190 mips32_op = OPC_RECIP2_D;
14191 goto do_3d;
14192 case FMT_SDPS_PS:
14193 mips32_op = OPC_RECIP2_PS;
14194 goto do_3d;
14195 default:
14196 goto pool32f_invalid;
14197 }
14198 break;
14199 case ADDR_PS:
14200 mips32_op = OPC_ADDR_PS;
14201 goto do_3d;
14202 case MULR_PS:
14203 mips32_op = OPC_MULR_PS;
14204 do_3d:
14205 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14206 break;
14207 default:
14208 goto pool32f_invalid;
14209 }
14210 break;
14211 case 0x20:
2a24a7ba 14212 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14213 cc = (ctx->opcode >> 13) & 0x7;
14214 fmt = (ctx->opcode >> 9) & 0x3;
14215 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14216 case MOVF_FMT: /* RINT_FMT */
14217 if (ctx->insn_flags & ISA_MIPS32R6) {
14218 /* RINT_FMT */
14219 switch (fmt) {
14220 case FMT_SDPS_S:
14221 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14222 break;
14223 case FMT_SDPS_D:
14224 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14225 break;
14226 default:
14227 goto pool32f_invalid;
14228 }
14229 } else {
14230 /* MOVF_FMT */
14231 switch (fmt) {
14232 case FMT_SDPS_S:
14233 gen_movcf_s(ctx, rs, rt, cc, 0);
14234 break;
14235 case FMT_SDPS_D:
14236 gen_movcf_d(ctx, rs, rt, cc, 0);
14237 break;
14238 case FMT_SDPS_PS:
14239 check_ps(ctx);
14240 gen_movcf_ps(ctx, rs, rt, cc, 0);
14241 break;
14242 default:
14243 goto pool32f_invalid;
14244 }
3c824109
NF
14245 }
14246 break;
2a24a7ba
YK
14247 case MOVT_FMT: /* CLASS_FMT */
14248 if (ctx->insn_flags & ISA_MIPS32R6) {
14249 /* CLASS_FMT */
14250 switch (fmt) {
14251 case FMT_SDPS_S:
14252 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14253 break;
14254 case FMT_SDPS_D:
14255 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14256 break;
14257 default:
14258 goto pool32f_invalid;
14259 }
14260 } else {
14261 /* MOVT_FMT */
14262 switch (fmt) {
14263 case FMT_SDPS_S:
14264 gen_movcf_s(ctx, rs, rt, cc, 1);
14265 break;
14266 case FMT_SDPS_D:
14267 gen_movcf_d(ctx, rs, rt, cc, 1);
14268 break;
14269 case FMT_SDPS_PS:
14270 check_ps(ctx);
14271 gen_movcf_ps(ctx, rs, rt, cc, 1);
14272 break;
14273 default:
14274 goto pool32f_invalid;
14275 }
3c824109
NF
14276 }
14277 break;
14278 case PREFX:
9e8f441a 14279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14280 break;
14281 default:
14282 goto pool32f_invalid;
14283 }
14284 break;
14285#define FINSN_3ARG_SDPS(prfx) \
14286 switch ((ctx->opcode >> 8) & 0x3) { \
14287 case FMT_SDPS_S: \
14288 mips32_op = OPC_##prfx##_S; \
14289 goto do_fpop; \
14290 case FMT_SDPS_D: \
14291 mips32_op = OPC_##prfx##_D; \
14292 goto do_fpop; \
14293 case FMT_SDPS_PS: \
e29c9628 14294 check_ps(ctx); \
3c824109
NF
14295 mips32_op = OPC_##prfx##_PS; \
14296 goto do_fpop; \
14297 default: \
14298 goto pool32f_invalid; \
14299 }
2a24a7ba
YK
14300 case MINA_FMT:
14301 check_insn(ctx, ISA_MIPS32R6);
14302 switch ((ctx->opcode >> 9) & 0x3) {
14303 case FMT_SDPS_S:
14304 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14305 break;
14306 case FMT_SDPS_D:
14307 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14308 break;
14309 default:
14310 goto pool32f_invalid;
14311 }
14312 break;
14313 case MAXA_FMT:
14314 check_insn(ctx, ISA_MIPS32R6);
14315 switch ((ctx->opcode >> 9) & 0x3) {
14316 case FMT_SDPS_S:
14317 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14318 break;
14319 case FMT_SDPS_D:
14320 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14321 break;
14322 default:
14323 goto pool32f_invalid;
14324 }
14325 break;
3c824109
NF
14326 case 0x30:
14327 /* regular FP ops */
14328 switch ((ctx->opcode >> 6) & 0x3) {
14329 case ADD_FMT:
14330 FINSN_3ARG_SDPS(ADD);
14331 break;
14332 case SUB_FMT:
14333 FINSN_3ARG_SDPS(SUB);
14334 break;
14335 case MUL_FMT:
14336 FINSN_3ARG_SDPS(MUL);
14337 break;
14338 case DIV_FMT:
14339 fmt = (ctx->opcode >> 8) & 0x3;
14340 if (fmt == 1) {
14341 mips32_op = OPC_DIV_D;
14342 } else if (fmt == 0) {
14343 mips32_op = OPC_DIV_S;
14344 } else {
14345 goto pool32f_invalid;
14346 }
14347 goto do_fpop;
14348 default:
14349 goto pool32f_invalid;
14350 }
14351 break;
14352 case 0x38:
14353 /* cmovs */
2a24a7ba
YK
14354 switch ((ctx->opcode >> 6) & 0x7) {
14355 case MOVN_FMT: /* SELNEZ_FMT */
14356 if (ctx->insn_flags & ISA_MIPS32R6) {
14357 /* SELNEZ_FMT */
14358 switch ((ctx->opcode >> 9) & 0x3) {
14359 case FMT_SDPS_S:
14360 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14361 break;
14362 case FMT_SDPS_D:
14363 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14364 break;
14365 default:
14366 goto pool32f_invalid;
14367 }
14368 } else {
14369 /* MOVN_FMT */
14370 FINSN_3ARG_SDPS(MOVN);
14371 }
14372 break;
14373 case MOVN_FMT_04:
14374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14375 FINSN_3ARG_SDPS(MOVN);
14376 break;
2a24a7ba
YK
14377 case MOVZ_FMT: /* SELEQZ_FMT */
14378 if (ctx->insn_flags & ISA_MIPS32R6) {
14379 /* SELEQZ_FMT */
14380 switch ((ctx->opcode >> 9) & 0x3) {
14381 case FMT_SDPS_S:
14382 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14383 break;
14384 case FMT_SDPS_D:
14385 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14386 break;
14387 default:
14388 goto pool32f_invalid;
14389 }
14390 } else {
14391 /* MOVZ_FMT */
14392 FINSN_3ARG_SDPS(MOVZ);
14393 }
14394 break;
14395 case MOVZ_FMT_05:
14396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14397 FINSN_3ARG_SDPS(MOVZ);
14398 break;
2a24a7ba
YK
14399 case SEL_FMT:
14400 check_insn(ctx, ISA_MIPS32R6);
14401 switch ((ctx->opcode >> 9) & 0x3) {
14402 case FMT_SDPS_S:
14403 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14404 break;
14405 case FMT_SDPS_D:
14406 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14407 break;
14408 default:
14409 goto pool32f_invalid;
14410 }
14411 break;
14412 case MADDF_FMT:
14413 check_insn(ctx, ISA_MIPS32R6);
14414 switch ((ctx->opcode >> 9) & 0x3) {
14415 case FMT_SDPS_S:
14416 mips32_op = OPC_MADDF_S;
14417 goto do_fpop;
14418 case FMT_SDPS_D:
14419 mips32_op = OPC_MADDF_D;
14420 goto do_fpop;
14421 default:
14422 goto pool32f_invalid;
14423 }
14424 break;
14425 case MSUBF_FMT:
14426 check_insn(ctx, ISA_MIPS32R6);
14427 switch ((ctx->opcode >> 9) & 0x3) {
14428 case FMT_SDPS_S:
14429 mips32_op = OPC_MSUBF_S;
14430 goto do_fpop;
14431 case FMT_SDPS_D:
14432 mips32_op = OPC_MSUBF_D;
14433 goto do_fpop;
14434 default:
14435 goto pool32f_invalid;
14436 }
14437 break;
3c824109
NF
14438 default:
14439 goto pool32f_invalid;
14440 }
14441 break;
14442 do_fpop:
14443 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14444 break;
14445 default:
14446 pool32f_invalid:
14447 MIPS_INVAL("pool32f");
9c708c7f 14448 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14449 break;
14450 }
14451 } else {
14452 generate_exception_err(ctx, EXCP_CpU, 1);
14453 }
14454 break;
14455 case POOL32I:
14456 minor = (ctx->opcode >> 21) & 0x1f;
14457 switch (minor) {
14458 case BLTZ:
9e8f441a 14459 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14460 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14461 break;
3c824109 14462 case BLTZAL:
9e8f441a 14463 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14464 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14465 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14466 break;
3c824109 14467 case BLTZALS:
9e8f441a 14468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14469 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14470 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14471 break;
3c824109 14472 case BGEZ:
9e8f441a 14473 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14474 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14475 break;
3c824109 14476 case BGEZAL:
9e8f441a 14477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14478 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14479 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14480 break;
3c824109 14481 case BGEZALS:
9e8f441a 14482 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14483 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14484 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14485 break;
3c824109 14486 case BLEZ:
9e8f441a 14487 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14488 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14489 break;
3c824109 14490 case BGTZ:
9e8f441a 14491 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14492 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14493 break;
14494
14495 /* Traps */
65935f07
YK
14496 case TLTI: /* BC1EQZC */
14497 if (ctx->insn_flags & ISA_MIPS32R6) {
14498 /* BC1EQZC */
14499 check_cp1_enabled(ctx);
14500 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14501 } else {
14502 /* TLTI */
14503 mips32_op = OPC_TLTI;
14504 goto do_trapi;
14505 }
14506 break;
14507 case TGEI: /* BC1NEZC */
14508 if (ctx->insn_flags & ISA_MIPS32R6) {
14509 /* BC1NEZC */
14510 check_cp1_enabled(ctx);
14511 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14512 } else {
14513 /* TGEI */
14514 mips32_op = OPC_TGEI;
14515 goto do_trapi;
14516 }
14517 break;
3c824109 14518 case TLTIU:
9e8f441a 14519 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14520 mips32_op = OPC_TLTIU;
14521 goto do_trapi;
14522 case TGEIU:
9e8f441a 14523 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14524 mips32_op = OPC_TGEIU;
14525 goto do_trapi;
3b4a5489
YK
14526 case TNEI: /* SYNCI */
14527 if (ctx->insn_flags & ISA_MIPS32R6) {
14528 /* SYNCI */
14529 /* Break the TB to be able to sync copied instructions
14530 immediately */
14531 ctx->bstate = BS_STOP;
14532 } else {
14533 /* TNEI */
14534 mips32_op = OPC_TNEI;
14535 goto do_trapi;
14536 }
14537 break;
3c824109 14538 case TEQI:
9e8f441a 14539 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14540 mips32_op = OPC_TEQI;
14541 do_trapi:
14542 gen_trap(ctx, mips32_op, rs, -1, imm);
14543 break;
14544
14545 case BNEZC:
14546 case BEQZC:
9e8f441a 14547 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14548 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14549 4, rs, 0, imm << 1, 0);
3c824109
NF
14550 /* Compact branches don't have a delay slot, so just let
14551 the normal delay slot handling take us to the branch
14552 target. */
14553 break;
14554 case LUI:
9e8f441a 14555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14556 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14557 break;
14558 case SYNCI:
9e8f441a 14559 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14560 /* Break the TB to be able to sync copied instructions
14561 immediately */
14562 ctx->bstate = BS_STOP;
3c824109
NF
14563 break;
14564 case BC2F:
14565 case BC2T:
9e8f441a 14566 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14567 /* COP2: Not implemented. */
14568 generate_exception_err(ctx, EXCP_CpU, 2);
14569 break;
14570 case BC1F:
9e8f441a 14571 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14572 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14573 goto do_cp1branch;
14574 case BC1T:
9e8f441a 14575 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14576 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14577 goto do_cp1branch;
14578 case BC1ANY4F:
9e8f441a 14579 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14580 mips32_op = OPC_BC1FANY4;
14581 goto do_cp1mips3d;
14582 case BC1ANY4T:
9e8f441a 14583 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14584 mips32_op = OPC_BC1TANY4;
14585 do_cp1mips3d:
14586 check_cop1x(ctx);
d75c135e 14587 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14588 /* Fall through */
14589 do_cp1branch:
272f458d
MR
14590 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14591 check_cp1_enabled(ctx);
14592 gen_compute_branch1(ctx, mips32_op,
14593 (ctx->opcode >> 18) & 0x7, imm << 1);
14594 } else {
14595 generate_exception_err(ctx, EXCP_CpU, 1);
14596 }
3c824109
NF
14597 break;
14598 case BPOSGE64:
14599 case BPOSGE32:
14600 /* MIPS DSP: not implemented */
14601 /* Fall through */
14602 default:
14603 MIPS_INVAL("pool32i");
9c708c7f 14604 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14605 break;
14606 }
14607 break;
14608 case POOL32C:
14609 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14610 offset = sextract32(ctx->opcode, 0,
14611 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14612 switch (minor) {
14613 case LWL:
9e8f441a 14614 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14615 mips32_op = OPC_LWL;
5c13fdfd 14616 goto do_ld_lr;
3c824109 14617 case SWL:
9e8f441a 14618 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14619 mips32_op = OPC_SWL;
5c13fdfd 14620 goto do_st_lr;
3c824109 14621 case LWR:
9e8f441a 14622 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14623 mips32_op = OPC_LWR;
5c13fdfd 14624 goto do_ld_lr;
3c824109 14625 case SWR:
9e8f441a 14626 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14627 mips32_op = OPC_SWR;
5c13fdfd 14628 goto do_st_lr;
3c824109
NF
14629#if defined(TARGET_MIPS64)
14630 case LDL:
d9224450
MR
14631 check_insn(ctx, ISA_MIPS3);
14632 check_mips_64(ctx);
9e8f441a 14633 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14634 mips32_op = OPC_LDL;
5c13fdfd 14635 goto do_ld_lr;
3c824109 14636 case SDL:
d9224450
MR
14637 check_insn(ctx, ISA_MIPS3);
14638 check_mips_64(ctx);
9e8f441a 14639 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14640 mips32_op = OPC_SDL;
5c13fdfd 14641 goto do_st_lr;
3c824109 14642 case LDR:
d9224450
MR
14643 check_insn(ctx, ISA_MIPS3);
14644 check_mips_64(ctx);
9e8f441a 14645 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14646 mips32_op = OPC_LDR;
5c13fdfd 14647 goto do_ld_lr;
3c824109 14648 case SDR:
d9224450
MR
14649 check_insn(ctx, ISA_MIPS3);
14650 check_mips_64(ctx);
9e8f441a 14651 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14652 mips32_op = OPC_SDR;
5c13fdfd 14653 goto do_st_lr;
3c824109 14654 case LWU:
d9224450
MR
14655 check_insn(ctx, ISA_MIPS3);
14656 check_mips_64(ctx);
3c824109 14657 mips32_op = OPC_LWU;
5c13fdfd 14658 goto do_ld_lr;
3c824109 14659 case LLD:
d9224450
MR
14660 check_insn(ctx, ISA_MIPS3);
14661 check_mips_64(ctx);
3c824109 14662 mips32_op = OPC_LLD;
5c13fdfd 14663 goto do_ld_lr;
3c824109
NF
14664#endif
14665 case LL:
14666 mips32_op = OPC_LL;
5c13fdfd
AJ
14667 goto do_ld_lr;
14668 do_ld_lr:
3b4a5489 14669 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14670 break;
14671 do_st_lr:
14672 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14673 break;
14674 case SC:
3b4a5489 14675 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14676 break;
14677#if defined(TARGET_MIPS64)
14678 case SCD:
d9224450
MR
14679 check_insn(ctx, ISA_MIPS3);
14680 check_mips_64(ctx);
3b4a5489 14681 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14682 break;
14683#endif
14684 case PREF:
14685 /* Treat as no-op */
3b4a5489
YK
14686 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14687 /* hint codes 24-31 are reserved and signal RI */
14688 generate_exception(ctx, EXCP_RI);
14689 }
3c824109
NF
14690 break;
14691 default:
14692 MIPS_INVAL("pool32c");
9c708c7f 14693 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14694 break;
14695 }
14696 break;
ab39ee45
YK
14697 case ADDI32: /* AUI, LUI */
14698 if (ctx->insn_flags & ISA_MIPS32R6) {
14699 /* AUI, LUI */
14700 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14701 } else {
14702 /* ADDI32 */
14703 mips32_op = OPC_ADDI;
14704 goto do_addi;
14705 }
14706 break;
3c824109
NF
14707 case ADDIU32:
14708 mips32_op = OPC_ADDIU;
14709 do_addi:
d75c135e 14710 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14711 break;
14712
14713 /* Logical operations */
14714 case ORI32:
14715 mips32_op = OPC_ORI;
14716 goto do_logici;
14717 case XORI32:
14718 mips32_op = OPC_XORI;
14719 goto do_logici;
14720 case ANDI32:
14721 mips32_op = OPC_ANDI;
14722 do_logici:
d75c135e 14723 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14724 break;
14725
14726 /* Set less than immediate */
14727 case SLTI32:
14728 mips32_op = OPC_SLTI;
14729 goto do_slti;
14730 case SLTIU32:
14731 mips32_op = OPC_SLTIU;
14732 do_slti:
d75c135e 14733 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14734 break;
14735 case JALX32:
9e8f441a 14736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14737 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14738 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14739 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14740 break;
65935f07
YK
14741 case JALS32: /* BOVC, BEQC, BEQZALC */
14742 if (ctx->insn_flags & ISA_MIPS32R6) {
14743 if (rs >= rt) {
14744 /* BOVC */
14745 mips32_op = OPC_BOVC;
14746 } else if (rs < rt && rs == 0) {
14747 /* BEQZALC */
14748 mips32_op = OPC_BEQZALC;
14749 } else {
14750 /* BEQC */
14751 mips32_op = OPC_BEQC;
14752 }
14753 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14754 } else {
14755 /* JALS32 */
14756 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14757 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14758 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14759 }
3c824109 14760 break;
65935f07
YK
14761 case BEQ32: /* BC */
14762 if (ctx->insn_flags & ISA_MIPS32R6) {
14763 /* BC */
14764 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14765 sextract32(ctx->opcode << 1, 0, 27));
14766 } else {
14767 /* BEQ32 */
14768 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14769 }
3c824109 14770 break;
65935f07
YK
14771 case BNE32: /* BALC */
14772 if (ctx->insn_flags & ISA_MIPS32R6) {
14773 /* BALC */
14774 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14775 sextract32(ctx->opcode << 1, 0, 27));
14776 } else {
14777 /* BNE32 */
14778 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14779 }
3c824109 14780 break;
65935f07
YK
14781 case J32: /* BGTZC, BLTZC, BLTC */
14782 if (ctx->insn_flags & ISA_MIPS32R6) {
14783 if (rs == 0 && rt != 0) {
14784 /* BGTZC */
14785 mips32_op = OPC_BGTZC;
14786 } else if (rs != 0 && rt != 0 && rs == rt) {
14787 /* BLTZC */
14788 mips32_op = OPC_BLTZC;
14789 } else {
14790 /* BLTC */
14791 mips32_op = OPC_BLTC;
14792 }
14793 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14794 } else {
14795 /* J32 */
14796 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14797 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14798 }
3c824109 14799 break;
65935f07
YK
14800 case JAL32: /* BLEZC, BGEZC, BGEC */
14801 if (ctx->insn_flags & ISA_MIPS32R6) {
14802 if (rs == 0 && rt != 0) {
14803 /* BLEZC */
14804 mips32_op = OPC_BLEZC;
14805 } else if (rs != 0 && rt != 0 && rs == rt) {
14806 /* BGEZC */
14807 mips32_op = OPC_BGEZC;
14808 } else {
14809 /* BGEC */
14810 mips32_op = OPC_BGEC;
14811 }
14812 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14813 } else {
14814 /* JAL32 */
14815 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14816 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14817 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14818 }
3c824109
NF
14819 break;
14820 /* Floating point (COP1) */
14821 case LWC132:
14822 mips32_op = OPC_LWC1;
14823 goto do_cop1;
14824 case LDC132:
14825 mips32_op = OPC_LDC1;
14826 goto do_cop1;
14827 case SWC132:
14828 mips32_op = OPC_SWC1;
14829 goto do_cop1;
14830 case SDC132:
14831 mips32_op = OPC_SDC1;
14832 do_cop1:
5ab5c041 14833 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14834 break;
ab39ee45
YK
14835 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14836 if (ctx->insn_flags & ISA_MIPS32R6) {
14837 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14838 switch ((ctx->opcode >> 16) & 0x1f) {
14839 case ADDIUPC_00 ... ADDIUPC_07:
14840 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14841 break;
14842 case AUIPC:
14843 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14844 break;
14845 case ALUIPC:
14846 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14847 break;
14848 case LWPC_08 ... LWPC_0F:
14849 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14850 break;
14851 default:
14852 generate_exception(ctx, EXCP_RI);
14853 break;
14854 }
14855 } else {
14856 /* ADDIUPC */
3c824109
NF
14857 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14858 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14859
14860 gen_addiupc(ctx, reg, offset, 0, 0);
14861 }
14862 break;
65935f07
YK
14863 case BNVC: /* BNEC, BNEZALC */
14864 check_insn(ctx, ISA_MIPS32R6);
14865 if (rs >= rt) {
14866 /* BNVC */
14867 mips32_op = OPC_BNVC;
14868 } else if (rs < rt && rs == 0) {
14869 /* BNEZALC */
14870 mips32_op = OPC_BNEZALC;
14871 } else {
14872 /* BNEC */
14873 mips32_op = OPC_BNEC;
14874 }
14875 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14876 break;
14877 case R6_BNEZC: /* JIALC */
14878 check_insn(ctx, ISA_MIPS32R6);
14879 if (rt != 0) {
14880 /* BNEZC */
14881 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14882 sextract32(ctx->opcode << 1, 0, 22));
14883 } else {
14884 /* JIALC */
14885 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14886 }
14887 break;
14888 case R6_BEQZC: /* JIC */
14889 check_insn(ctx, ISA_MIPS32R6);
14890 if (rt != 0) {
14891 /* BEQZC */
14892 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14893 sextract32(ctx->opcode << 1, 0, 22));
14894 } else {
14895 /* JIC */
14896 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14897 }
14898 break;
14899 case BLEZALC: /* BGEZALC, BGEUC */
14900 check_insn(ctx, ISA_MIPS32R6);
14901 if (rs == 0 && rt != 0) {
14902 /* BLEZALC */
14903 mips32_op = OPC_BLEZALC;
14904 } else if (rs != 0 && rt != 0 && rs == rt) {
14905 /* BGEZALC */
14906 mips32_op = OPC_BGEZALC;
14907 } else {
14908 /* BGEUC */
14909 mips32_op = OPC_BGEUC;
14910 }
14911 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14912 break;
14913 case BGTZALC: /* BLTZALC, BLTUC */
14914 check_insn(ctx, ISA_MIPS32R6);
14915 if (rs == 0 && rt != 0) {
14916 /* BGTZALC */
14917 mips32_op = OPC_BGTZALC;
14918 } else if (rs != 0 && rt != 0 && rs == rt) {
14919 /* BLTZALC */
14920 mips32_op = OPC_BLTZALC;
14921 } else {
14922 /* BLTUC */
14923 mips32_op = OPC_BLTUC;
14924 }
14925 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14926 break;
3c824109
NF
14927 /* Loads and stores */
14928 case LB32:
14929 mips32_op = OPC_LB;
5c13fdfd 14930 goto do_ld;
3c824109
NF
14931 case LBU32:
14932 mips32_op = OPC_LBU;
5c13fdfd 14933 goto do_ld;
3c824109
NF
14934 case LH32:
14935 mips32_op = OPC_LH;
5c13fdfd 14936 goto do_ld;
3c824109
NF
14937 case LHU32:
14938 mips32_op = OPC_LHU;
5c13fdfd 14939 goto do_ld;
3c824109
NF
14940 case LW32:
14941 mips32_op = OPC_LW;
5c13fdfd 14942 goto do_ld;
3c824109
NF
14943#ifdef TARGET_MIPS64
14944 case LD32:
d9224450
MR
14945 check_insn(ctx, ISA_MIPS3);
14946 check_mips_64(ctx);
3c824109 14947 mips32_op = OPC_LD;
5c13fdfd 14948 goto do_ld;
3c824109 14949 case SD32:
d9224450
MR
14950 check_insn(ctx, ISA_MIPS3);
14951 check_mips_64(ctx);
3c824109 14952 mips32_op = OPC_SD;
5c13fdfd 14953 goto do_st;
3c824109
NF
14954#endif
14955 case SB32:
14956 mips32_op = OPC_SB;
5c13fdfd 14957 goto do_st;
3c824109
NF
14958 case SH32:
14959 mips32_op = OPC_SH;
5c13fdfd 14960 goto do_st;
3c824109
NF
14961 case SW32:
14962 mips32_op = OPC_SW;
5c13fdfd
AJ
14963 goto do_st;
14964 do_ld:
d75c135e 14965 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
14966 break;
14967 do_st:
14968 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14969 break;
14970 default:
9c708c7f 14971 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14972 break;
14973 }
14974}
14975
240ce26a 14976static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14977{
14978 uint32_t op;
14979
14980 /* make sure instructions are on a halfword boundary */
14981 if (ctx->pc & 0x1) {
14982 env->CP0_BadVAddr = ctx->pc;
9c708c7f 14983 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
14984 return 2;
14985 }
14986
14987 op = (ctx->opcode >> 10) & 0x3f;
14988 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
14989 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14990 switch (op & 0x7) { /* MSB-3..MSB-5 */
14991 case 0:
14992 /* POOL32A, POOL32B, POOL32I, POOL32C */
14993 case 4:
14994 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14995 case 5:
14996 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14997 case 6:
14998 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14999 case 7:
15000 /* LB32, LH32, LWC132, LDC132, LW32 */
15001 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15002 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15003 return 2;
15004 }
15005 break;
b231c103
YK
15006 case 1:
15007 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15008 case 2:
15009 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15010 case 3:
15011 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15012 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15013 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15014 return 2;
15015 }
15016 break;
3c824109
NF
15017 }
15018 }
b231c103 15019
3c824109
NF
15020 switch (op) {
15021 case POOL16A:
15022 {
15023 int rd = mmreg(uMIPS_RD(ctx->opcode));
15024 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15025 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15026 uint32_t opc = 0;
15027
15028 switch (ctx->opcode & 0x1) {
15029 case ADDU16:
15030 opc = OPC_ADDU;
15031 break;
15032 case SUBU16:
15033 opc = OPC_SUBU;
15034 break;
15035 }
ed7ce6c0
YK
15036 if (ctx->insn_flags & ISA_MIPS32R6) {
15037 /* In the Release 6 the register number location in
15038 * the instruction encoding has changed.
15039 */
15040 gen_arith(ctx, opc, rs1, rd, rs2);
15041 } else {
15042 gen_arith(ctx, opc, rd, rs1, rs2);
15043 }
3c824109
NF
15044 }
15045 break;
15046 case POOL16B:
15047 {
15048 int rd = mmreg(uMIPS_RD(ctx->opcode));
15049 int rs = mmreg(uMIPS_RS(ctx->opcode));
15050 int amount = (ctx->opcode >> 1) & 0x7;
15051 uint32_t opc = 0;
15052 amount = amount == 0 ? 8 : amount;
15053
15054 switch (ctx->opcode & 0x1) {
15055 case SLL16:
15056 opc = OPC_SLL;
15057 break;
15058 case SRL16:
15059 opc = OPC_SRL;
15060 break;
15061 }
15062
d75c135e 15063 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15064 }
15065 break;
15066 case POOL16C:
ed7ce6c0
YK
15067 if (ctx->insn_flags & ISA_MIPS32R6) {
15068 gen_pool16c_r6_insn(ctx);
15069 } else {
15070 gen_pool16c_insn(ctx);
15071 }
3c824109
NF
15072 break;
15073 case LWGP16:
15074 {
15075 int rd = mmreg(uMIPS_RD(ctx->opcode));
15076 int rb = 28; /* GP */
15077 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15078
d75c135e 15079 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15080 }
15081 break;
15082 case POOL16F:
9e8f441a 15083 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15084 if (ctx->opcode & 1) {
9c708c7f 15085 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15086 } else {
15087 /* MOVEP */
15088 int enc_dest = uMIPS_RD(ctx->opcode);
15089 int enc_rt = uMIPS_RS2(ctx->opcode);
15090 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15091 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15092 }
15093 break;
15094 case LBU16:
15095 {
15096 int rd = mmreg(uMIPS_RD(ctx->opcode));
15097 int rb = mmreg(uMIPS_RS(ctx->opcode));
15098 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15099 offset = (offset == 0xf ? -1 : offset);
15100
d75c135e 15101 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15102 }
15103 break;
15104 case LHU16:
15105 {
15106 int rd = mmreg(uMIPS_RD(ctx->opcode));
15107 int rb = mmreg(uMIPS_RS(ctx->opcode));
15108 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15109
d75c135e 15110 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15111 }
15112 break;
15113 case LWSP16:
15114 {
15115 int rd = (ctx->opcode >> 5) & 0x1f;
15116 int rb = 29; /* SP */
15117 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15118
d75c135e 15119 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15120 }
15121 break;
15122 case LW16:
15123 {
15124 int rd = mmreg(uMIPS_RD(ctx->opcode));
15125 int rb = mmreg(uMIPS_RS(ctx->opcode));
15126 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15127
d75c135e 15128 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15129 }
15130 break;
15131 case SB16:
15132 {
15133 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15134 int rb = mmreg(uMIPS_RS(ctx->opcode));
15135 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15136
5c13fdfd 15137 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15138 }
15139 break;
15140 case SH16:
15141 {
15142 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15143 int rb = mmreg(uMIPS_RS(ctx->opcode));
15144 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15145
5c13fdfd 15146 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15147 }
15148 break;
15149 case SWSP16:
15150 {
15151 int rd = (ctx->opcode >> 5) & 0x1f;
15152 int rb = 29; /* SP */
15153 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15154
5c13fdfd 15155 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15156 }
15157 break;
15158 case SW16:
15159 {
15160 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15161 int rb = mmreg(uMIPS_RS(ctx->opcode));
15162 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15163
5c13fdfd 15164 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15165 }
15166 break;
15167 case MOVE16:
15168 {
15169 int rd = uMIPS_RD5(ctx->opcode);
15170 int rs = uMIPS_RS5(ctx->opcode);
15171
7215d7e7 15172 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15173 }
15174 break;
15175 case ANDI16:
d75c135e 15176 gen_andi16(ctx);
3c824109
NF
15177 break;
15178 case POOL16D:
15179 switch (ctx->opcode & 0x1) {
15180 case ADDIUS5:
d75c135e 15181 gen_addius5(ctx);
3c824109
NF
15182 break;
15183 case ADDIUSP:
d75c135e 15184 gen_addiusp(ctx);
3c824109
NF
15185 break;
15186 }
15187 break;
15188 case POOL16E:
15189 switch (ctx->opcode & 0x1) {
15190 case ADDIUR2:
d75c135e 15191 gen_addiur2(ctx);
3c824109
NF
15192 break;
15193 case ADDIUR1SP:
d75c135e 15194 gen_addiur1sp(ctx);
3c824109
NF
15195 break;
15196 }
15197 break;
65935f07 15198 case B16: /* BC16 */
3c824109 15199 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15200 sextract32(ctx->opcode, 0, 10) << 1,
15201 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15202 break;
65935f07
YK
15203 case BNEZ16: /* BNEZC16 */
15204 case BEQZ16: /* BEQZC16 */
3c824109
NF
15205 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15206 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15207 0, sextract32(ctx->opcode, 0, 7) << 1,
15208 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15209
3c824109
NF
15210 break;
15211 case LI16:
15212 {
15213 int reg = mmreg(uMIPS_RD(ctx->opcode));
15214 int imm = ZIMM(ctx->opcode, 0, 7);
15215
15216 imm = (imm == 0x7f ? -1 : imm);
15217 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15218 }
15219 break;
3c824109 15220 case RES_29:
3c824109 15221 case RES_31:
3c824109 15222 case RES_39:
9c708c7f 15223 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15224 break;
15225 default:
f60eeb0c 15226 decode_micromips32_opc(env, ctx);
3c824109
NF
15227 return 4;
15228 }
15229
15230 return 2;
15231}
15232
15233/* SmartMIPS extension to MIPS32 */
15234
15235#if defined(TARGET_MIPS64)
15236
15237/* MDMX extension to MIPS64 */
15238
15239#endif
15240
9b1a1d68 15241/* MIPSDSP functions. */
d75c135e 15242static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15243 int rd, int base, int offset)
15244{
9b1a1d68
JL
15245 TCGv t0;
15246
9b1a1d68
JL
15247 check_dsp(ctx);
15248 t0 = tcg_temp_new();
15249
15250 if (base == 0) {
15251 gen_load_gpr(t0, offset);
15252 } else if (offset == 0) {
15253 gen_load_gpr(t0, base);
15254 } else {
15255 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15256 }
15257
9b1a1d68
JL
15258 switch (opc) {
15259 case OPC_LBUX:
5f68f5ae 15260 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15261 gen_store_gpr(t0, rd);
9b1a1d68
JL
15262 break;
15263 case OPC_LHX:
5f68f5ae 15264 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15265 gen_store_gpr(t0, rd);
9b1a1d68
JL
15266 break;
15267 case OPC_LWX:
5f68f5ae 15268 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15269 gen_store_gpr(t0, rd);
9b1a1d68
JL
15270 break;
15271#if defined(TARGET_MIPS64)
15272 case OPC_LDX:
5f68f5ae 15273 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15274 gen_store_gpr(t0, rd);
9b1a1d68
JL
15275 break;
15276#endif
15277 }
9b1a1d68
JL
15278 tcg_temp_free(t0);
15279}
15280
461c08df
JL
15281static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15282 int ret, int v1, int v2)
15283{
461c08df
JL
15284 TCGv v1_t;
15285 TCGv v2_t;
15286
15287 if (ret == 0) {
15288 /* Treat as NOP. */
461c08df
JL
15289 return;
15290 }
15291
15292 v1_t = tcg_temp_new();
15293 v2_t = tcg_temp_new();
15294
15295 gen_load_gpr(v1_t, v1);
15296 gen_load_gpr(v2_t, v2);
15297
15298 switch (op1) {
15299 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15300 case OPC_MULT_G_2E:
15301 check_dspr2(ctx);
15302 switch (op2) {
15303 case OPC_ADDUH_QB:
15304 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15305 break;
15306 case OPC_ADDUH_R_QB:
15307 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15308 break;
15309 case OPC_ADDQH_PH:
15310 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15311 break;
15312 case OPC_ADDQH_R_PH:
15313 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15314 break;
15315 case OPC_ADDQH_W:
15316 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15317 break;
15318 case OPC_ADDQH_R_W:
15319 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15320 break;
15321 case OPC_SUBUH_QB:
15322 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15323 break;
15324 case OPC_SUBUH_R_QB:
15325 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15326 break;
15327 case OPC_SUBQH_PH:
15328 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15329 break;
15330 case OPC_SUBQH_R_PH:
15331 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15332 break;
15333 case OPC_SUBQH_W:
15334 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15335 break;
15336 case OPC_SUBQH_R_W:
15337 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15338 break;
15339 }
15340 break;
15341 case OPC_ABSQ_S_PH_DSP:
15342 switch (op2) {
15343 case OPC_ABSQ_S_QB:
15344 check_dspr2(ctx);
15345 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15346 break;
15347 case OPC_ABSQ_S_PH:
15348 check_dsp(ctx);
15349 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15350 break;
15351 case OPC_ABSQ_S_W:
15352 check_dsp(ctx);
15353 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15354 break;
15355 case OPC_PRECEQ_W_PHL:
15356 check_dsp(ctx);
15357 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15358 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15359 break;
15360 case OPC_PRECEQ_W_PHR:
15361 check_dsp(ctx);
15362 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15363 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15364 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15365 break;
15366 case OPC_PRECEQU_PH_QBL:
15367 check_dsp(ctx);
15368 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15369 break;
15370 case OPC_PRECEQU_PH_QBR:
15371 check_dsp(ctx);
15372 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15373 break;
15374 case OPC_PRECEQU_PH_QBLA:
15375 check_dsp(ctx);
15376 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15377 break;
15378 case OPC_PRECEQU_PH_QBRA:
15379 check_dsp(ctx);
15380 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15381 break;
15382 case OPC_PRECEU_PH_QBL:
15383 check_dsp(ctx);
15384 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15385 break;
15386 case OPC_PRECEU_PH_QBR:
15387 check_dsp(ctx);
15388 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15389 break;
15390 case OPC_PRECEU_PH_QBLA:
15391 check_dsp(ctx);
15392 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15393 break;
15394 case OPC_PRECEU_PH_QBRA:
15395 check_dsp(ctx);
15396 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15397 break;
15398 }
15399 break;
15400 case OPC_ADDU_QB_DSP:
15401 switch (op2) {
15402 case OPC_ADDQ_PH:
15403 check_dsp(ctx);
15404 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15405 break;
15406 case OPC_ADDQ_S_PH:
15407 check_dsp(ctx);
15408 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15409 break;
15410 case OPC_ADDQ_S_W:
15411 check_dsp(ctx);
15412 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15413 break;
15414 case OPC_ADDU_QB:
15415 check_dsp(ctx);
15416 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15417 break;
15418 case OPC_ADDU_S_QB:
15419 check_dsp(ctx);
15420 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15421 break;
15422 case OPC_ADDU_PH:
15423 check_dspr2(ctx);
15424 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15425 break;
15426 case OPC_ADDU_S_PH:
15427 check_dspr2(ctx);
15428 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15429 break;
15430 case OPC_SUBQ_PH:
15431 check_dsp(ctx);
15432 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15433 break;
15434 case OPC_SUBQ_S_PH:
15435 check_dsp(ctx);
15436 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15437 break;
15438 case OPC_SUBQ_S_W:
15439 check_dsp(ctx);
15440 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15441 break;
15442 case OPC_SUBU_QB:
15443 check_dsp(ctx);
15444 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15445 break;
15446 case OPC_SUBU_S_QB:
15447 check_dsp(ctx);
15448 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15449 break;
15450 case OPC_SUBU_PH:
15451 check_dspr2(ctx);
15452 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15453 break;
15454 case OPC_SUBU_S_PH:
15455 check_dspr2(ctx);
15456 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15457 break;
15458 case OPC_ADDSC:
15459 check_dsp(ctx);
15460 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15461 break;
15462 case OPC_ADDWC:
15463 check_dsp(ctx);
15464 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15465 break;
15466 case OPC_MODSUB:
15467 check_dsp(ctx);
15468 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15469 break;
15470 case OPC_RADDU_W_QB:
15471 check_dsp(ctx);
15472 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15473 break;
15474 }
15475 break;
15476 case OPC_CMPU_EQ_QB_DSP:
15477 switch (op2) {
15478 case OPC_PRECR_QB_PH:
15479 check_dspr2(ctx);
15480 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15481 break;
15482 case OPC_PRECRQ_QB_PH:
15483 check_dsp(ctx);
15484 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15485 break;
15486 case OPC_PRECR_SRA_PH_W:
15487 check_dspr2(ctx);
15488 {
15489 TCGv_i32 sa_t = tcg_const_i32(v2);
15490 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15491 cpu_gpr[ret]);
15492 tcg_temp_free_i32(sa_t);
15493 break;
15494 }
15495 case OPC_PRECR_SRA_R_PH_W:
15496 check_dspr2(ctx);
15497 {
15498 TCGv_i32 sa_t = tcg_const_i32(v2);
15499 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15500 cpu_gpr[ret]);
15501 tcg_temp_free_i32(sa_t);
15502 break;
15503 }
15504 case OPC_PRECRQ_PH_W:
15505 check_dsp(ctx);
15506 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15507 break;
15508 case OPC_PRECRQ_RS_PH_W:
15509 check_dsp(ctx);
15510 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15511 break;
15512 case OPC_PRECRQU_S_QB_PH:
15513 check_dsp(ctx);
15514 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15515 break;
15516 }
15517 break;
15518#ifdef TARGET_MIPS64
15519 case OPC_ABSQ_S_QH_DSP:
15520 switch (op2) {
15521 case OPC_PRECEQ_L_PWL:
15522 check_dsp(ctx);
15523 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15524 break;
15525 case OPC_PRECEQ_L_PWR:
15526 check_dsp(ctx);
15527 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15528 break;
15529 case OPC_PRECEQ_PW_QHL:
15530 check_dsp(ctx);
15531 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15532 break;
15533 case OPC_PRECEQ_PW_QHR:
15534 check_dsp(ctx);
15535 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15536 break;
15537 case OPC_PRECEQ_PW_QHLA:
15538 check_dsp(ctx);
15539 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15540 break;
15541 case OPC_PRECEQ_PW_QHRA:
15542 check_dsp(ctx);
15543 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15544 break;
15545 case OPC_PRECEQU_QH_OBL:
15546 check_dsp(ctx);
15547 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15548 break;
15549 case OPC_PRECEQU_QH_OBR:
15550 check_dsp(ctx);
15551 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15552 break;
15553 case OPC_PRECEQU_QH_OBLA:
15554 check_dsp(ctx);
15555 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15556 break;
15557 case OPC_PRECEQU_QH_OBRA:
15558 check_dsp(ctx);
15559 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15560 break;
15561 case OPC_PRECEU_QH_OBL:
15562 check_dsp(ctx);
15563 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15564 break;
15565 case OPC_PRECEU_QH_OBR:
15566 check_dsp(ctx);
15567 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15568 break;
15569 case OPC_PRECEU_QH_OBLA:
15570 check_dsp(ctx);
15571 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15572 break;
15573 case OPC_PRECEU_QH_OBRA:
15574 check_dsp(ctx);
15575 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15576 break;
15577 case OPC_ABSQ_S_OB:
15578 check_dspr2(ctx);
15579 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15580 break;
15581 case OPC_ABSQ_S_PW:
15582 check_dsp(ctx);
15583 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15584 break;
15585 case OPC_ABSQ_S_QH:
15586 check_dsp(ctx);
15587 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15588 break;
15589 }
15590 break;
15591 case OPC_ADDU_OB_DSP:
15592 switch (op2) {
15593 case OPC_RADDU_L_OB:
15594 check_dsp(ctx);
15595 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15596 break;
15597 case OPC_SUBQ_PW:
15598 check_dsp(ctx);
15599 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15600 break;
15601 case OPC_SUBQ_S_PW:
15602 check_dsp(ctx);
15603 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15604 break;
15605 case OPC_SUBQ_QH:
15606 check_dsp(ctx);
15607 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15608 break;
15609 case OPC_SUBQ_S_QH:
15610 check_dsp(ctx);
15611 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15612 break;
15613 case OPC_SUBU_OB:
15614 check_dsp(ctx);
15615 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15616 break;
15617 case OPC_SUBU_S_OB:
15618 check_dsp(ctx);
15619 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15620 break;
15621 case OPC_SUBU_QH:
15622 check_dspr2(ctx);
15623 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15624 break;
15625 case OPC_SUBU_S_QH:
15626 check_dspr2(ctx);
15627 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15628 break;
15629 case OPC_SUBUH_OB:
15630 check_dspr2(ctx);
15631 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15632 break;
15633 case OPC_SUBUH_R_OB:
15634 check_dspr2(ctx);
15635 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15636 break;
15637 case OPC_ADDQ_PW:
15638 check_dsp(ctx);
15639 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15640 break;
15641 case OPC_ADDQ_S_PW:
15642 check_dsp(ctx);
15643 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15644 break;
15645 case OPC_ADDQ_QH:
15646 check_dsp(ctx);
15647 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15648 break;
15649 case OPC_ADDQ_S_QH:
15650 check_dsp(ctx);
15651 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15652 break;
15653 case OPC_ADDU_OB:
15654 check_dsp(ctx);
15655 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15656 break;
15657 case OPC_ADDU_S_OB:
15658 check_dsp(ctx);
15659 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15660 break;
15661 case OPC_ADDU_QH:
15662 check_dspr2(ctx);
15663 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15664 break;
15665 case OPC_ADDU_S_QH:
15666 check_dspr2(ctx);
15667 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15668 break;
15669 case OPC_ADDUH_OB:
15670 check_dspr2(ctx);
15671 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15672 break;
15673 case OPC_ADDUH_R_OB:
15674 check_dspr2(ctx);
15675 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15676 break;
15677 }
15678 break;
15679 case OPC_CMPU_EQ_OB_DSP:
15680 switch (op2) {
15681 case OPC_PRECR_OB_QH:
15682 check_dspr2(ctx);
15683 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15684 break;
15685 case OPC_PRECR_SRA_QH_PW:
15686 check_dspr2(ctx);
15687 {
15688 TCGv_i32 ret_t = tcg_const_i32(ret);
15689 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15690 tcg_temp_free_i32(ret_t);
15691 break;
15692 }
15693 case OPC_PRECR_SRA_R_QH_PW:
15694 check_dspr2(ctx);
15695 {
15696 TCGv_i32 sa_v = tcg_const_i32(ret);
15697 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15698 tcg_temp_free_i32(sa_v);
15699 break;
15700 }
15701 case OPC_PRECRQ_OB_QH:
15702 check_dsp(ctx);
15703 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15704 break;
15705 case OPC_PRECRQ_PW_L:
15706 check_dsp(ctx);
15707 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15708 break;
15709 case OPC_PRECRQ_QH_PW:
15710 check_dsp(ctx);
15711 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15712 break;
15713 case OPC_PRECRQ_RS_QH_PW:
15714 check_dsp(ctx);
15715 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15716 break;
15717 case OPC_PRECRQU_S_OB_QH:
15718 check_dsp(ctx);
15719 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15720 break;
15721 }
15722 break;
15723#endif
15724 }
15725
15726 tcg_temp_free(v1_t);
15727 tcg_temp_free(v2_t);
461c08df 15728}
9b1a1d68 15729
77c5fa8b
JL
15730static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15731 int ret, int v1, int v2)
15732{
15733 uint32_t op2;
77c5fa8b
JL
15734 TCGv t0;
15735 TCGv v1_t;
15736 TCGv v2_t;
15737
15738 if (ret == 0) {
15739 /* Treat as NOP. */
77c5fa8b
JL
15740 return;
15741 }
15742
15743 t0 = tcg_temp_new();
15744 v1_t = tcg_temp_new();
15745 v2_t = tcg_temp_new();
15746
15747 tcg_gen_movi_tl(t0, v1);
15748 gen_load_gpr(v1_t, v1);
15749 gen_load_gpr(v2_t, v2);
15750
15751 switch (opc) {
15752 case OPC_SHLL_QB_DSP:
15753 {
15754 op2 = MASK_SHLL_QB(ctx->opcode);
15755 switch (op2) {
15756 case OPC_SHLL_QB:
15757 check_dsp(ctx);
15758 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15759 break;
15760 case OPC_SHLLV_QB:
15761 check_dsp(ctx);
15762 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15763 break;
15764 case OPC_SHLL_PH:
15765 check_dsp(ctx);
15766 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15767 break;
15768 case OPC_SHLLV_PH:
15769 check_dsp(ctx);
15770 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15771 break;
15772 case OPC_SHLL_S_PH:
15773 check_dsp(ctx);
15774 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15775 break;
15776 case OPC_SHLLV_S_PH:
15777 check_dsp(ctx);
15778 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15779 break;
15780 case OPC_SHLL_S_W:
15781 check_dsp(ctx);
15782 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15783 break;
15784 case OPC_SHLLV_S_W:
15785 check_dsp(ctx);
15786 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15787 break;
15788 case OPC_SHRL_QB:
15789 check_dsp(ctx);
15790 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15791 break;
15792 case OPC_SHRLV_QB:
15793 check_dsp(ctx);
15794 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15795 break;
15796 case OPC_SHRL_PH:
15797 check_dspr2(ctx);
15798 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15799 break;
15800 case OPC_SHRLV_PH:
15801 check_dspr2(ctx);
15802 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15803 break;
15804 case OPC_SHRA_QB:
15805 check_dspr2(ctx);
15806 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15807 break;
15808 case OPC_SHRA_R_QB:
15809 check_dspr2(ctx);
15810 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15811 break;
15812 case OPC_SHRAV_QB:
15813 check_dspr2(ctx);
15814 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15815 break;
15816 case OPC_SHRAV_R_QB:
15817 check_dspr2(ctx);
15818 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15819 break;
15820 case OPC_SHRA_PH:
15821 check_dsp(ctx);
15822 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15823 break;
15824 case OPC_SHRA_R_PH:
15825 check_dsp(ctx);
15826 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15827 break;
15828 case OPC_SHRAV_PH:
15829 check_dsp(ctx);
15830 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15831 break;
15832 case OPC_SHRAV_R_PH:
15833 check_dsp(ctx);
15834 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15835 break;
15836 case OPC_SHRA_R_W:
15837 check_dsp(ctx);
15838 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15839 break;
15840 case OPC_SHRAV_R_W:
15841 check_dsp(ctx);
15842 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15843 break;
15844 default: /* Invalid */
15845 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 15846 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15847 break;
15848 }
15849 break;
15850 }
15851#ifdef TARGET_MIPS64
15852 case OPC_SHLL_OB_DSP:
15853 op2 = MASK_SHLL_OB(ctx->opcode);
15854 switch (op2) {
15855 case OPC_SHLL_PW:
15856 check_dsp(ctx);
15857 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15858 break;
15859 case OPC_SHLLV_PW:
15860 check_dsp(ctx);
15861 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15862 break;
15863 case OPC_SHLL_S_PW:
15864 check_dsp(ctx);
15865 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15866 break;
15867 case OPC_SHLLV_S_PW:
15868 check_dsp(ctx);
15869 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15870 break;
15871 case OPC_SHLL_OB:
15872 check_dsp(ctx);
15873 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15874 break;
15875 case OPC_SHLLV_OB:
15876 check_dsp(ctx);
15877 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15878 break;
15879 case OPC_SHLL_QH:
15880 check_dsp(ctx);
15881 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15882 break;
15883 case OPC_SHLLV_QH:
15884 check_dsp(ctx);
15885 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15886 break;
15887 case OPC_SHLL_S_QH:
15888 check_dsp(ctx);
15889 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15890 break;
15891 case OPC_SHLLV_S_QH:
15892 check_dsp(ctx);
15893 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15894 break;
15895 case OPC_SHRA_OB:
15896 check_dspr2(ctx);
15897 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15898 break;
15899 case OPC_SHRAV_OB:
15900 check_dspr2(ctx);
15901 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15902 break;
15903 case OPC_SHRA_R_OB:
15904 check_dspr2(ctx);
15905 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15906 break;
15907 case OPC_SHRAV_R_OB:
15908 check_dspr2(ctx);
15909 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15910 break;
15911 case OPC_SHRA_PW:
15912 check_dsp(ctx);
15913 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15914 break;
15915 case OPC_SHRAV_PW:
15916 check_dsp(ctx);
15917 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15918 break;
15919 case OPC_SHRA_R_PW:
15920 check_dsp(ctx);
15921 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15922 break;
15923 case OPC_SHRAV_R_PW:
15924 check_dsp(ctx);
15925 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15926 break;
15927 case OPC_SHRA_QH:
15928 check_dsp(ctx);
15929 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15930 break;
15931 case OPC_SHRAV_QH:
15932 check_dsp(ctx);
15933 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15934 break;
15935 case OPC_SHRA_R_QH:
15936 check_dsp(ctx);
15937 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15938 break;
15939 case OPC_SHRAV_R_QH:
15940 check_dsp(ctx);
15941 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15942 break;
15943 case OPC_SHRL_OB:
15944 check_dsp(ctx);
15945 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15946 break;
15947 case OPC_SHRLV_OB:
15948 check_dsp(ctx);
15949 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15950 break;
15951 case OPC_SHRL_QH:
15952 check_dspr2(ctx);
15953 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15954 break;
15955 case OPC_SHRLV_QH:
15956 check_dspr2(ctx);
15957 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15958 break;
15959 default: /* Invalid */
15960 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 15961 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15962 break;
15963 }
15964 break;
15965#endif
15966 }
15967
15968 tcg_temp_free(t0);
15969 tcg_temp_free(v1_t);
15970 tcg_temp_free(v2_t);
77c5fa8b
JL
15971}
15972
a22260ae
JL
15973static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15974 int ret, int v1, int v2, int check_ret)
15975{
a22260ae
JL
15976 TCGv_i32 t0;
15977 TCGv v1_t;
15978 TCGv v2_t;
15979
15980 if ((ret == 0) && (check_ret == 1)) {
15981 /* Treat as NOP. */
a22260ae
JL
15982 return;
15983 }
15984
15985 t0 = tcg_temp_new_i32();
15986 v1_t = tcg_temp_new();
15987 v2_t = tcg_temp_new();
15988
15989 tcg_gen_movi_i32(t0, ret);
15990 gen_load_gpr(v1_t, v1);
15991 gen_load_gpr(v2_t, v2);
15992
15993 switch (op1) {
15994 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15995 * the same mask and op1. */
15996 case OPC_MULT_G_2E:
639eadb9 15997 check_dspr2(ctx);
a22260ae
JL
15998 switch (op2) {
15999 case OPC_MUL_PH:
16000 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16001 break;
16002 case OPC_MUL_S_PH:
16003 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16004 break;
16005 case OPC_MULQ_S_W:
16006 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16007 break;
16008 case OPC_MULQ_RS_W:
16009 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16010 break;
16011 }
16012 break;
16013 case OPC_DPA_W_PH_DSP:
16014 switch (op2) {
16015 case OPC_DPAU_H_QBL:
16016 check_dsp(ctx);
16017 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16018 break;
16019 case OPC_DPAU_H_QBR:
16020 check_dsp(ctx);
16021 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16022 break;
16023 case OPC_DPSU_H_QBL:
16024 check_dsp(ctx);
16025 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16026 break;
16027 case OPC_DPSU_H_QBR:
16028 check_dsp(ctx);
16029 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16030 break;
16031 case OPC_DPA_W_PH:
16032 check_dspr2(ctx);
16033 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16034 break;
16035 case OPC_DPAX_W_PH:
16036 check_dspr2(ctx);
16037 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16038 break;
16039 case OPC_DPAQ_S_W_PH:
16040 check_dsp(ctx);
16041 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16042 break;
16043 case OPC_DPAQX_S_W_PH:
16044 check_dspr2(ctx);
16045 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16046 break;
16047 case OPC_DPAQX_SA_W_PH:
16048 check_dspr2(ctx);
16049 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16050 break;
16051 case OPC_DPS_W_PH:
16052 check_dspr2(ctx);
16053 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16054 break;
16055 case OPC_DPSX_W_PH:
16056 check_dspr2(ctx);
16057 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16058 break;
16059 case OPC_DPSQ_S_W_PH:
16060 check_dsp(ctx);
16061 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16062 break;
16063 case OPC_DPSQX_S_W_PH:
16064 check_dspr2(ctx);
16065 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16066 break;
16067 case OPC_DPSQX_SA_W_PH:
16068 check_dspr2(ctx);
16069 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16070 break;
16071 case OPC_MULSAQ_S_W_PH:
16072 check_dsp(ctx);
16073 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16074 break;
16075 case OPC_DPAQ_SA_L_W:
16076 check_dsp(ctx);
16077 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16078 break;
16079 case OPC_DPSQ_SA_L_W:
16080 check_dsp(ctx);
16081 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16082 break;
16083 case OPC_MAQ_S_W_PHL:
16084 check_dsp(ctx);
16085 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16086 break;
16087 case OPC_MAQ_S_W_PHR:
16088 check_dsp(ctx);
16089 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16090 break;
16091 case OPC_MAQ_SA_W_PHL:
16092 check_dsp(ctx);
16093 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16094 break;
16095 case OPC_MAQ_SA_W_PHR:
16096 check_dsp(ctx);
16097 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16098 break;
16099 case OPC_MULSA_W_PH:
16100 check_dspr2(ctx);
16101 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16102 break;
16103 }
16104 break;
16105#ifdef TARGET_MIPS64
16106 case OPC_DPAQ_W_QH_DSP:
16107 {
16108 int ac = ret & 0x03;
16109 tcg_gen_movi_i32(t0, ac);
16110
16111 switch (op2) {
16112 case OPC_DMADD:
16113 check_dsp(ctx);
16114 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16115 break;
16116 case OPC_DMADDU:
16117 check_dsp(ctx);
16118 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16119 break;
16120 case OPC_DMSUB:
16121 check_dsp(ctx);
16122 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16123 break;
16124 case OPC_DMSUBU:
16125 check_dsp(ctx);
16126 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16127 break;
16128 case OPC_DPA_W_QH:
16129 check_dspr2(ctx);
16130 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16131 break;
16132 case OPC_DPAQ_S_W_QH:
16133 check_dsp(ctx);
16134 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16135 break;
16136 case OPC_DPAQ_SA_L_PW:
16137 check_dsp(ctx);
16138 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16139 break;
16140 case OPC_DPAU_H_OBL:
16141 check_dsp(ctx);
16142 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16143 break;
16144 case OPC_DPAU_H_OBR:
16145 check_dsp(ctx);
16146 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16147 break;
16148 case OPC_DPS_W_QH:
16149 check_dspr2(ctx);
16150 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16151 break;
16152 case OPC_DPSQ_S_W_QH:
16153 check_dsp(ctx);
16154 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16155 break;
16156 case OPC_DPSQ_SA_L_PW:
16157 check_dsp(ctx);
16158 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16159 break;
16160 case OPC_DPSU_H_OBL:
16161 check_dsp(ctx);
16162 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16163 break;
16164 case OPC_DPSU_H_OBR:
16165 check_dsp(ctx);
16166 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16167 break;
16168 case OPC_MAQ_S_L_PWL:
16169 check_dsp(ctx);
16170 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16171 break;
16172 case OPC_MAQ_S_L_PWR:
16173 check_dsp(ctx);
16174 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16175 break;
16176 case OPC_MAQ_S_W_QHLL:
16177 check_dsp(ctx);
16178 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16179 break;
16180 case OPC_MAQ_SA_W_QHLL:
16181 check_dsp(ctx);
16182 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16183 break;
16184 case OPC_MAQ_S_W_QHLR:
16185 check_dsp(ctx);
16186 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16187 break;
16188 case OPC_MAQ_SA_W_QHLR:
16189 check_dsp(ctx);
16190 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16191 break;
16192 case OPC_MAQ_S_W_QHRL:
16193 check_dsp(ctx);
16194 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16195 break;
16196 case OPC_MAQ_SA_W_QHRL:
16197 check_dsp(ctx);
16198 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16199 break;
16200 case OPC_MAQ_S_W_QHRR:
16201 check_dsp(ctx);
16202 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16203 break;
16204 case OPC_MAQ_SA_W_QHRR:
16205 check_dsp(ctx);
16206 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16207 break;
16208 case OPC_MULSAQ_S_L_PW:
16209 check_dsp(ctx);
16210 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16211 break;
16212 case OPC_MULSAQ_S_W_QH:
16213 check_dsp(ctx);
16214 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16215 break;
16216 }
16217 }
16218 break;
16219#endif
16220 case OPC_ADDU_QB_DSP:
16221 switch (op2) {
16222 case OPC_MULEU_S_PH_QBL:
16223 check_dsp(ctx);
16224 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16225 break;
16226 case OPC_MULEU_S_PH_QBR:
16227 check_dsp(ctx);
16228 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16229 break;
16230 case OPC_MULQ_RS_PH:
16231 check_dsp(ctx);
16232 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16233 break;
16234 case OPC_MULEQ_S_W_PHL:
16235 check_dsp(ctx);
16236 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16237 break;
16238 case OPC_MULEQ_S_W_PHR:
16239 check_dsp(ctx);
16240 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16241 break;
16242 case OPC_MULQ_S_PH:
16243 check_dspr2(ctx);
16244 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16245 break;
16246 }
16247 break;
16248#ifdef TARGET_MIPS64
16249 case OPC_ADDU_OB_DSP:
16250 switch (op2) {
16251 case OPC_MULEQ_S_PW_QHL:
16252 check_dsp(ctx);
16253 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16254 break;
16255 case OPC_MULEQ_S_PW_QHR:
16256 check_dsp(ctx);
16257 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16258 break;
16259 case OPC_MULEU_S_QH_OBL:
16260 check_dsp(ctx);
16261 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16262 break;
16263 case OPC_MULEU_S_QH_OBR:
16264 check_dsp(ctx);
16265 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16266 break;
16267 case OPC_MULQ_RS_QH:
16268 check_dsp(ctx);
16269 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16270 break;
16271 }
16272 break;
16273#endif
16274 }
16275
16276 tcg_temp_free_i32(t0);
16277 tcg_temp_free(v1_t);
16278 tcg_temp_free(v2_t);
a22260ae
JL
16279}
16280
d75c135e 16281static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16282 int ret, int val)
16283{
1cb6686c
JL
16284 int16_t imm;
16285 TCGv t0;
16286 TCGv val_t;
16287
16288 if (ret == 0) {
16289 /* Treat as NOP. */
1cb6686c
JL
16290 return;
16291 }
16292
16293 t0 = tcg_temp_new();
16294 val_t = tcg_temp_new();
16295 gen_load_gpr(val_t, val);
16296
16297 switch (op1) {
16298 case OPC_ABSQ_S_PH_DSP:
16299 switch (op2) {
16300 case OPC_BITREV:
16301 check_dsp(ctx);
16302 gen_helper_bitrev(cpu_gpr[ret], val_t);
16303 break;
16304 case OPC_REPL_QB:
16305 check_dsp(ctx);
16306 {
16307 target_long result;
16308 imm = (ctx->opcode >> 16) & 0xFF;
16309 result = (uint32_t)imm << 24 |
16310 (uint32_t)imm << 16 |
16311 (uint32_t)imm << 8 |
16312 (uint32_t)imm;
16313 result = (int32_t)result;
16314 tcg_gen_movi_tl(cpu_gpr[ret], result);
16315 }
16316 break;
16317 case OPC_REPLV_QB:
16318 check_dsp(ctx);
16319 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16320 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16321 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16322 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16323 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16324 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16325 break;
16326 case OPC_REPL_PH:
16327 check_dsp(ctx);
16328 {
16329 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16330 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16331 tcg_gen_movi_tl(cpu_gpr[ret], \
16332 (target_long)((int32_t)imm << 16 | \
c4aaba92 16333 (uint16_t)imm));
1cb6686c
JL
16334 }
16335 break;
16336 case OPC_REPLV_PH:
16337 check_dsp(ctx);
16338 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16339 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16340 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16341 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16342 break;
16343 }
16344 break;
16345#ifdef TARGET_MIPS64
16346 case OPC_ABSQ_S_QH_DSP:
16347 switch (op2) {
16348 case OPC_REPL_OB:
16349 check_dsp(ctx);
16350 {
16351 target_long temp;
16352
16353 imm = (ctx->opcode >> 16) & 0xFF;
16354 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16355 temp = (temp << 16) | temp;
16356 temp = (temp << 32) | temp;
16357 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16358 break;
16359 }
16360 case OPC_REPL_PW:
16361 check_dsp(ctx);
16362 {
16363 target_long temp;
16364
16365 imm = (ctx->opcode >> 16) & 0x03FF;
16366 imm = (int16_t)(imm << 6) >> 6;
16367 temp = ((target_long)imm << 32) \
16368 | ((target_long)imm & 0xFFFFFFFF);
16369 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16370 break;
16371 }
16372 case OPC_REPL_QH:
16373 check_dsp(ctx);
16374 {
16375 target_long temp;
16376
16377 imm = (ctx->opcode >> 16) & 0x03FF;
16378 imm = (int16_t)(imm << 6) >> 6;
16379
16380 temp = ((uint64_t)(uint16_t)imm << 48) |
16381 ((uint64_t)(uint16_t)imm << 32) |
16382 ((uint64_t)(uint16_t)imm << 16) |
16383 (uint64_t)(uint16_t)imm;
16384 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16385 break;
16386 }
16387 case OPC_REPLV_OB:
16388 check_dsp(ctx);
16389 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16390 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16391 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16392 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16393 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16394 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16395 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16396 break;
16397 case OPC_REPLV_PW:
16398 check_dsp(ctx);
16399 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16400 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16401 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16402 break;
16403 case OPC_REPLV_QH:
16404 check_dsp(ctx);
16405 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16406 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16407 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16408 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16409 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16410 break;
16411 }
16412 break;
16413#endif
16414 }
16415 tcg_temp_free(t0);
16416 tcg_temp_free(val_t);
1cb6686c
JL
16417}
16418
26690560
JL
16419static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16420 uint32_t op1, uint32_t op2,
16421 int ret, int v1, int v2, int check_ret)
16422{
26690560
JL
16423 TCGv t1;
16424 TCGv v1_t;
16425 TCGv v2_t;
16426
16427 if ((ret == 0) && (check_ret == 1)) {
16428 /* Treat as NOP. */
26690560
JL
16429 return;
16430 }
16431
26690560
JL
16432 t1 = tcg_temp_new();
16433 v1_t = tcg_temp_new();
16434 v2_t = tcg_temp_new();
16435
16436 gen_load_gpr(v1_t, v1);
16437 gen_load_gpr(v2_t, v2);
16438
16439 switch (op1) {
26690560
JL
16440 case OPC_CMPU_EQ_QB_DSP:
16441 switch (op2) {
16442 case OPC_CMPU_EQ_QB:
16443 check_dsp(ctx);
16444 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16445 break;
16446 case OPC_CMPU_LT_QB:
16447 check_dsp(ctx);
16448 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16449 break;
16450 case OPC_CMPU_LE_QB:
16451 check_dsp(ctx);
16452 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16453 break;
16454 case OPC_CMPGU_EQ_QB:
16455 check_dsp(ctx);
16456 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16457 break;
16458 case OPC_CMPGU_LT_QB:
16459 check_dsp(ctx);
16460 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16461 break;
16462 case OPC_CMPGU_LE_QB:
16463 check_dsp(ctx);
16464 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16465 break;
16466 case OPC_CMPGDU_EQ_QB:
16467 check_dspr2(ctx);
16468 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16469 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16470 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16471 tcg_gen_shli_tl(t1, t1, 24);
16472 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16473 break;
16474 case OPC_CMPGDU_LT_QB:
16475 check_dspr2(ctx);
16476 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16477 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16478 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16479 tcg_gen_shli_tl(t1, t1, 24);
16480 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16481 break;
16482 case OPC_CMPGDU_LE_QB:
16483 check_dspr2(ctx);
16484 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16485 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16486 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16487 tcg_gen_shli_tl(t1, t1, 24);
16488 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16489 break;
16490 case OPC_CMP_EQ_PH:
16491 check_dsp(ctx);
16492 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16493 break;
16494 case OPC_CMP_LT_PH:
16495 check_dsp(ctx);
16496 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16497 break;
16498 case OPC_CMP_LE_PH:
16499 check_dsp(ctx);
16500 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16501 break;
16502 case OPC_PICK_QB:
16503 check_dsp(ctx);
16504 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16505 break;
16506 case OPC_PICK_PH:
16507 check_dsp(ctx);
16508 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16509 break;
16510 case OPC_PACKRL_PH:
16511 check_dsp(ctx);
16512 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16513 break;
16514 }
16515 break;
16516#ifdef TARGET_MIPS64
16517 case OPC_CMPU_EQ_OB_DSP:
16518 switch (op2) {
16519 case OPC_CMP_EQ_PW:
16520 check_dsp(ctx);
16521 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16522 break;
16523 case OPC_CMP_LT_PW:
16524 check_dsp(ctx);
16525 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16526 break;
16527 case OPC_CMP_LE_PW:
16528 check_dsp(ctx);
16529 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16530 break;
16531 case OPC_CMP_EQ_QH:
16532 check_dsp(ctx);
16533 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16534 break;
16535 case OPC_CMP_LT_QH:
16536 check_dsp(ctx);
16537 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16538 break;
16539 case OPC_CMP_LE_QH:
16540 check_dsp(ctx);
16541 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16542 break;
16543 case OPC_CMPGDU_EQ_OB:
16544 check_dspr2(ctx);
16545 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16546 break;
16547 case OPC_CMPGDU_LT_OB:
16548 check_dspr2(ctx);
16549 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16550 break;
16551 case OPC_CMPGDU_LE_OB:
16552 check_dspr2(ctx);
16553 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16554 break;
16555 case OPC_CMPGU_EQ_OB:
16556 check_dsp(ctx);
16557 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16558 break;
16559 case OPC_CMPGU_LT_OB:
16560 check_dsp(ctx);
16561 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16562 break;
16563 case OPC_CMPGU_LE_OB:
16564 check_dsp(ctx);
16565 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16566 break;
16567 case OPC_CMPU_EQ_OB:
16568 check_dsp(ctx);
16569 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16570 break;
16571 case OPC_CMPU_LT_OB:
16572 check_dsp(ctx);
16573 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16574 break;
16575 case OPC_CMPU_LE_OB:
16576 check_dsp(ctx);
16577 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16578 break;
16579 case OPC_PACKRL_PW:
16580 check_dsp(ctx);
16581 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16582 break;
16583 case OPC_PICK_OB:
16584 check_dsp(ctx);
16585 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16586 break;
16587 case OPC_PICK_PW:
16588 check_dsp(ctx);
16589 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16590 break;
16591 case OPC_PICK_QH:
16592 check_dsp(ctx);
16593 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16594 break;
16595 }
16596 break;
df6126a7
AJ
16597#endif
16598 }
16599
16600 tcg_temp_free(t1);
16601 tcg_temp_free(v1_t);
16602 tcg_temp_free(v2_t);
df6126a7
AJ
16603}
16604
16605static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16606 uint32_t op1, int rt, int rs, int sa)
16607{
df6126a7
AJ
16608 TCGv t0;
16609
16610 check_dspr2(ctx);
16611
16612 if (rt == 0) {
16613 /* Treat as NOP. */
df6126a7
AJ
16614 return;
16615 }
16616
16617 t0 = tcg_temp_new();
16618 gen_load_gpr(t0, rs);
16619
16620 switch (op1) {
16621 case OPC_APPEND_DSP:
16622 switch (MASK_APPEND(ctx->opcode)) {
16623 case OPC_APPEND:
16624 if (sa != 0) {
16625 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16626 }
16627 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16628 break;
16629 case OPC_PREPEND:
16630 if (sa != 0) {
16631 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16632 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16633 tcg_gen_shli_tl(t0, t0, 32 - sa);
16634 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16635 }
16636 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16637 break;
16638 case OPC_BALIGN:
16639 sa &= 3;
16640 if (sa != 0 && sa != 2) {
16641 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16642 tcg_gen_ext32u_tl(t0, t0);
16643 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16644 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16645 }
16646 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16647 break;
16648 default: /* Invalid */
16649 MIPS_INVAL("MASK APPEND");
9c708c7f 16650 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16651 break;
16652 }
16653 break;
16654#ifdef TARGET_MIPS64
26690560 16655 case OPC_DAPPEND_DSP:
df6126a7 16656 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16657 case OPC_DAPPEND:
df6126a7
AJ
16658 if (sa != 0) {
16659 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16660 }
26690560
JL
16661 break;
16662 case OPC_PREPENDD:
df6126a7
AJ
16663 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16664 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16665 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16666 break;
16667 case OPC_PREPENDW:
df6126a7
AJ
16668 if (sa != 0) {
16669 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16670 tcg_gen_shli_tl(t0, t0, 64 - sa);
16671 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16672 }
26690560
JL
16673 break;
16674 case OPC_DBALIGN:
df6126a7
AJ
16675 sa &= 7;
16676 if (sa != 0 && sa != 2 && sa != 4) {
16677 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16678 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16679 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16680 }
26690560
JL
16681 break;
16682 default: /* Invalid */
16683 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16684 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16685 break;
16686 }
16687 break;
16688#endif
16689 }
df6126a7 16690 tcg_temp_free(t0);
26690560
JL
16691}
16692
b53371ed
JL
16693static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16694 int ret, int v1, int v2, int check_ret)
16695
16696{
b53371ed
JL
16697 TCGv t0;
16698 TCGv t1;
16699 TCGv v1_t;
16700 TCGv v2_t;
16701 int16_t imm;
16702
16703 if ((ret == 0) && (check_ret == 1)) {
16704 /* Treat as NOP. */
b53371ed
JL
16705 return;
16706 }
16707
16708 t0 = tcg_temp_new();
16709 t1 = tcg_temp_new();
16710 v1_t = tcg_temp_new();
16711 v2_t = tcg_temp_new();
16712
16713 gen_load_gpr(v1_t, v1);
16714 gen_load_gpr(v2_t, v2);
16715
16716 switch (op1) {
16717 case OPC_EXTR_W_DSP:
16718 check_dsp(ctx);
16719 switch (op2) {
16720 case OPC_EXTR_W:
16721 tcg_gen_movi_tl(t0, v2);
16722 tcg_gen_movi_tl(t1, v1);
16723 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16724 break;
16725 case OPC_EXTR_R_W:
16726 tcg_gen_movi_tl(t0, v2);
16727 tcg_gen_movi_tl(t1, v1);
16728 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16729 break;
16730 case OPC_EXTR_RS_W:
16731 tcg_gen_movi_tl(t0, v2);
16732 tcg_gen_movi_tl(t1, v1);
16733 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16734 break;
16735 case OPC_EXTR_S_H:
16736 tcg_gen_movi_tl(t0, v2);
16737 tcg_gen_movi_tl(t1, v1);
16738 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16739 break;
16740 case OPC_EXTRV_S_H:
16741 tcg_gen_movi_tl(t0, v2);
16742 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16743 break;
16744 case OPC_EXTRV_W:
16745 tcg_gen_movi_tl(t0, v2);
16746 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16747 break;
16748 case OPC_EXTRV_R_W:
16749 tcg_gen_movi_tl(t0, v2);
16750 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16751 break;
16752 case OPC_EXTRV_RS_W:
16753 tcg_gen_movi_tl(t0, v2);
16754 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16755 break;
16756 case OPC_EXTP:
16757 tcg_gen_movi_tl(t0, v2);
16758 tcg_gen_movi_tl(t1, v1);
16759 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16760 break;
16761 case OPC_EXTPV:
16762 tcg_gen_movi_tl(t0, v2);
16763 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16764 break;
16765 case OPC_EXTPDP:
16766 tcg_gen_movi_tl(t0, v2);
16767 tcg_gen_movi_tl(t1, v1);
16768 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16769 break;
16770 case OPC_EXTPDPV:
16771 tcg_gen_movi_tl(t0, v2);
16772 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16773 break;
16774 case OPC_SHILO:
16775 imm = (ctx->opcode >> 20) & 0x3F;
16776 tcg_gen_movi_tl(t0, ret);
16777 tcg_gen_movi_tl(t1, imm);
16778 gen_helper_shilo(t0, t1, cpu_env);
16779 break;
16780 case OPC_SHILOV:
16781 tcg_gen_movi_tl(t0, ret);
16782 gen_helper_shilo(t0, v1_t, cpu_env);
16783 break;
16784 case OPC_MTHLIP:
16785 tcg_gen_movi_tl(t0, ret);
16786 gen_helper_mthlip(t0, v1_t, cpu_env);
16787 break;
16788 case OPC_WRDSP:
16789 imm = (ctx->opcode >> 11) & 0x3FF;
16790 tcg_gen_movi_tl(t0, imm);
16791 gen_helper_wrdsp(v1_t, t0, cpu_env);
16792 break;
16793 case OPC_RDDSP:
16794 imm = (ctx->opcode >> 16) & 0x03FF;
16795 tcg_gen_movi_tl(t0, imm);
16796 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16797 break;
16798 }
16799 break;
16800#ifdef TARGET_MIPS64
16801 case OPC_DEXTR_W_DSP:
16802 check_dsp(ctx);
16803 switch (op2) {
16804 case OPC_DMTHLIP:
16805 tcg_gen_movi_tl(t0, ret);
16806 gen_helper_dmthlip(v1_t, t0, cpu_env);
16807 break;
16808 case OPC_DSHILO:
16809 {
16810 int shift = (ctx->opcode >> 19) & 0x7F;
16811 int ac = (ctx->opcode >> 11) & 0x03;
16812 tcg_gen_movi_tl(t0, shift);
16813 tcg_gen_movi_tl(t1, ac);
16814 gen_helper_dshilo(t0, t1, cpu_env);
16815 break;
16816 }
16817 case OPC_DSHILOV:
16818 {
16819 int ac = (ctx->opcode >> 11) & 0x03;
16820 tcg_gen_movi_tl(t0, ac);
16821 gen_helper_dshilo(v1_t, t0, cpu_env);
16822 break;
16823 }
16824 case OPC_DEXTP:
16825 tcg_gen_movi_tl(t0, v2);
16826 tcg_gen_movi_tl(t1, v1);
16827
16828 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16829 break;
16830 case OPC_DEXTPV:
16831 tcg_gen_movi_tl(t0, v2);
16832 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16833 break;
16834 case OPC_DEXTPDP:
16835 tcg_gen_movi_tl(t0, v2);
16836 tcg_gen_movi_tl(t1, v1);
16837 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16838 break;
16839 case OPC_DEXTPDPV:
16840 tcg_gen_movi_tl(t0, v2);
16841 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16842 break;
16843 case OPC_DEXTR_L:
16844 tcg_gen_movi_tl(t0, v2);
16845 tcg_gen_movi_tl(t1, v1);
16846 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16847 break;
16848 case OPC_DEXTR_R_L:
16849 tcg_gen_movi_tl(t0, v2);
16850 tcg_gen_movi_tl(t1, v1);
16851 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16852 break;
16853 case OPC_DEXTR_RS_L:
16854 tcg_gen_movi_tl(t0, v2);
16855 tcg_gen_movi_tl(t1, v1);
16856 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16857 break;
16858 case OPC_DEXTR_W:
16859 tcg_gen_movi_tl(t0, v2);
16860 tcg_gen_movi_tl(t1, v1);
16861 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16862 break;
16863 case OPC_DEXTR_R_W:
16864 tcg_gen_movi_tl(t0, v2);
16865 tcg_gen_movi_tl(t1, v1);
16866 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16867 break;
16868 case OPC_DEXTR_RS_W:
16869 tcg_gen_movi_tl(t0, v2);
16870 tcg_gen_movi_tl(t1, v1);
16871 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16872 break;
16873 case OPC_DEXTR_S_H:
16874 tcg_gen_movi_tl(t0, v2);
16875 tcg_gen_movi_tl(t1, v1);
16876 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16877 break;
16878 case OPC_DEXTRV_S_H:
16879 tcg_gen_movi_tl(t0, v2);
16880 tcg_gen_movi_tl(t1, v1);
16881 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16882 break;
16883 case OPC_DEXTRV_L:
16884 tcg_gen_movi_tl(t0, v2);
16885 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16886 break;
16887 case OPC_DEXTRV_R_L:
16888 tcg_gen_movi_tl(t0, v2);
16889 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16890 break;
16891 case OPC_DEXTRV_RS_L:
16892 tcg_gen_movi_tl(t0, v2);
16893 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16894 break;
16895 case OPC_DEXTRV_W:
16896 tcg_gen_movi_tl(t0, v2);
16897 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16898 break;
16899 case OPC_DEXTRV_R_W:
16900 tcg_gen_movi_tl(t0, v2);
16901 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16902 break;
16903 case OPC_DEXTRV_RS_W:
16904 tcg_gen_movi_tl(t0, v2);
16905 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16906 break;
16907 }
16908 break;
16909#endif
16910 }
16911
16912 tcg_temp_free(t0);
16913 tcg_temp_free(t1);
16914 tcg_temp_free(v1_t);
16915 tcg_temp_free(v2_t);
b53371ed
JL
16916}
16917
9b1a1d68
JL
16918/* End MIPSDSP functions. */
16919
10dc65db
LA
16920static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16921{
4267d3e6 16922 int rs, rt, rd, sa;
b42ee5e1 16923 uint32_t op1, op2;
10dc65db
LA
16924
16925 rs = (ctx->opcode >> 21) & 0x1f;
16926 rt = (ctx->opcode >> 16) & 0x1f;
16927 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16928 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16929
16930 op1 = MASK_SPECIAL(ctx->opcode);
16931 switch (op1) {
d4ea6acd 16932 case OPC_LSA:
1f1b4c00 16933 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16934 break;
b42ee5e1
LA
16935 case OPC_MULT ... OPC_DIVU:
16936 op2 = MASK_R6_MULDIV(ctx->opcode);
16937 switch (op2) {
16938 case R6_OPC_MUL:
16939 case R6_OPC_MUH:
16940 case R6_OPC_MULU:
16941 case R6_OPC_MUHU:
16942 case R6_OPC_DIV:
16943 case R6_OPC_MOD:
16944 case R6_OPC_DIVU:
16945 case R6_OPC_MODU:
16946 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16947 break;
16948 default:
16949 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16950 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16951 break;
16952 }
16953 break;
10dc65db
LA
16954 case OPC_SELEQZ:
16955 case OPC_SELNEZ:
16956 gen_cond_move(ctx, op1, rd, rs, rt);
16957 break;
4267d3e6
LA
16958 case R6_OPC_CLO:
16959 case R6_OPC_CLZ:
16960 if (rt == 0 && sa == 1) {
16961 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16962 We need additionally to check other fields */
16963 gen_cl(ctx, op1, rd, rs);
16964 } else {
9c708c7f 16965 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16966 }
16967 break;
16968 case R6_OPC_SDBBP:
3b3c1694
LA
16969 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16970 gen_helper_do_semihosting(cpu_env);
faf1f68b 16971 } else {
3b3c1694 16972 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 16973 generate_exception_end(ctx, EXCP_RI);
3b3c1694 16974 } else {
9c708c7f 16975 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 16976 }
faf1f68b 16977 }
4267d3e6 16978 break;
b42ee5e1 16979#if defined(TARGET_MIPS64)
d4ea6acd
LA
16980 case OPC_DLSA:
16981 check_mips_64(ctx);
1f1b4c00 16982 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16983 break;
4267d3e6
LA
16984 case R6_OPC_DCLO:
16985 case R6_OPC_DCLZ:
16986 if (rt == 0 && sa == 1) {
16987 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16988 We need additionally to check other fields */
16989 check_mips_64(ctx);
16990 gen_cl(ctx, op1, rd, rs);
16991 } else {
9c708c7f 16992 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16993 }
16994 break;
b42ee5e1
LA
16995 case OPC_DMULT ... OPC_DDIVU:
16996 op2 = MASK_R6_MULDIV(ctx->opcode);
16997 switch (op2) {
16998 case R6_OPC_DMUL:
16999 case R6_OPC_DMUH:
17000 case R6_OPC_DMULU:
17001 case R6_OPC_DMUHU:
17002 case R6_OPC_DDIV:
17003 case R6_OPC_DMOD:
17004 case R6_OPC_DDIVU:
17005 case R6_OPC_DMODU:
17006 check_mips_64(ctx);
17007 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17008 break;
17009 default:
17010 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17011 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17012 break;
17013 }
17014 break;
17015#endif
10dc65db
LA
17016 default: /* Invalid */
17017 MIPS_INVAL("special_r6");
9c708c7f 17018 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17019 break;
17020 }
17021}
17022
17023static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17024{
b42ee5e1 17025 int rs, rt, rd, sa;
10dc65db
LA
17026 uint32_t op1;
17027
17028 rs = (ctx->opcode >> 21) & 0x1f;
17029 rt = (ctx->opcode >> 16) & 0x1f;
17030 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17031 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17032
17033 op1 = MASK_SPECIAL(ctx->opcode);
17034 switch (op1) {
17035 case OPC_MOVN: /* Conditional move */
17036 case OPC_MOVZ:
17037 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17038 INSN_LOONGSON2E | INSN_LOONGSON2F);
17039 gen_cond_move(ctx, op1, rd, rs, rt);
17040 break;
17041 case OPC_MFHI: /* Move from HI/LO */
17042 case OPC_MFLO:
17043 gen_HILO(ctx, op1, rs & 3, rd);
17044 break;
17045 case OPC_MTHI:
17046 case OPC_MTLO: /* Move to HI/LO */
17047 gen_HILO(ctx, op1, rd & 3, rs);
17048 break;
17049 case OPC_MOVCI:
17050 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17051 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17052 check_cp1_enabled(ctx);
17053 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17054 (ctx->opcode >> 16) & 1);
17055 } else {
17056 generate_exception_err(ctx, EXCP_CpU, 1);
17057 }
17058 break;
b42ee5e1
LA
17059 case OPC_MULT:
17060 case OPC_MULTU:
17061 if (sa) {
17062 check_insn(ctx, INSN_VR54XX);
17063 op1 = MASK_MUL_VR54XX(ctx->opcode);
17064 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17065 } else {
17066 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17067 }
17068 break;
17069 case OPC_DIV:
17070 case OPC_DIVU:
17071 gen_muldiv(ctx, op1, 0, rs, rt);
17072 break;
17073#if defined(TARGET_MIPS64)
17074 case OPC_DMULT ... OPC_DDIVU:
17075 check_insn(ctx, ISA_MIPS3);
17076 check_mips_64(ctx);
17077 gen_muldiv(ctx, op1, 0, rs, rt);
17078 break;
17079#endif
0aefa333 17080 case OPC_JR:
b231c103 17081 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17082 break;
4267d3e6
LA
17083 case OPC_SPIM:
17084#ifdef MIPS_STRICT_STANDARD
17085 MIPS_INVAL("SPIM");
9c708c7f 17086 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17087#else
17088 /* Implemented as RI exception for now. */
17089 MIPS_INVAL("spim (unofficial)");
9c708c7f 17090 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17091#endif
17092 break;
10dc65db
LA
17093 default: /* Invalid */
17094 MIPS_INVAL("special_legacy");
9c708c7f 17095 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17096 break;
17097 }
17098}
17099
099e5b4d 17100static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17101{
3c824109 17102 int rs, rt, rd, sa;
099e5b4d 17103 uint32_t op1;
3c824109 17104
3c824109
NF
17105 rs = (ctx->opcode >> 21) & 0x1f;
17106 rt = (ctx->opcode >> 16) & 0x1f;
17107 rd = (ctx->opcode >> 11) & 0x1f;
17108 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17109
17110 op1 = MASK_SPECIAL(ctx->opcode);
17111 switch (op1) {
17112 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17113 if (sa == 5 && rd == 0 &&
17114 rs == 0 && rt == 0) { /* PAUSE */
17115 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17116 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17117 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17118 break;
17119 }
17120 }
17121 /* Fallthrough */
099e5b4d
LA
17122 case OPC_SRA:
17123 gen_shift_imm(ctx, op1, rd, rt, sa);
17124 break;
17125 case OPC_SRL:
17126 switch ((ctx->opcode >> 21) & 0x1f) {
17127 case 1:
17128 /* rotr is decoded as srl on non-R2 CPUs */
17129 if (ctx->insn_flags & ISA_MIPS32R2) {
17130 op1 = OPC_ROTR;
ea63e2c3 17131 }
099e5b4d
LA
17132 /* Fallthrough */
17133 case 0:
17134 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17135 break;
099e5b4d 17136 default:
9c708c7f 17137 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17138 break;
099e5b4d
LA
17139 }
17140 break;
099e5b4d
LA
17141 case OPC_ADD ... OPC_SUBU:
17142 gen_arith(ctx, op1, rd, rs, rt);
17143 break;
17144 case OPC_SLLV: /* Shifts */
17145 case OPC_SRAV:
17146 gen_shift(ctx, op1, rd, rs, rt);
17147 break;
17148 case OPC_SRLV:
17149 switch ((ctx->opcode >> 6) & 0x1f) {
17150 case 1:
17151 /* rotrv is decoded as srlv on non-R2 CPUs */
17152 if (ctx->insn_flags & ISA_MIPS32R2) {
17153 op1 = OPC_ROTRV;
26135ead 17154 }
099e5b4d
LA
17155 /* Fallthrough */
17156 case 0:
17157 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17158 break;
099e5b4d 17159 default:
9c708c7f 17160 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17161 break;
099e5b4d
LA
17162 }
17163 break;
17164 case OPC_SLT: /* Set on less than */
17165 case OPC_SLTU:
17166 gen_slt(ctx, op1, rd, rs, rt);
17167 break;
17168 case OPC_AND: /* Logic*/
17169 case OPC_OR:
17170 case OPC_NOR:
17171 case OPC_XOR:
17172 gen_logic(ctx, op1, rd, rs, rt);
17173 break;
0aefa333 17174 case OPC_JALR:
b231c103 17175 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
17176 break;
17177 case OPC_TGE ... OPC_TEQ: /* Traps */
17178 case OPC_TNE:
d9224450 17179 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17180 gen_trap(ctx, op1, rs, rt, -1);
17181 break;
d4ea6acd 17182 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17183 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17184 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17185 decode_opc_special_r6(env, ctx);
17186 } else {
17187 /* Pmon entry point, also R4010 selsl */
b48cfdff 17188#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17189 MIPS_INVAL("PMON / selsl");
9c708c7f 17190 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17191#else
d4ea6acd 17192 gen_helper_0e0i(pmon, sa);
b48cfdff 17193#endif
d4ea6acd 17194 }
099e5b4d
LA
17195 break;
17196 case OPC_SYSCALL:
9c708c7f 17197 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17198 break;
17199 case OPC_BREAK:
9c708c7f 17200 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17201 break;
099e5b4d 17202 case OPC_SYNC:
d9224450 17203 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17204 /* Treat as NOP. */
17205 break;
4ad40f36 17206
d26bc211 17207#if defined(TARGET_MIPS64)
099e5b4d
LA
17208 /* MIPS64 specific opcodes */
17209 case OPC_DSLL:
17210 case OPC_DSRA:
17211 case OPC_DSLL32:
17212 case OPC_DSRA32:
17213 check_insn(ctx, ISA_MIPS3);
17214 check_mips_64(ctx);
17215 gen_shift_imm(ctx, op1, rd, rt, sa);
17216 break;
17217 case OPC_DSRL:
17218 switch ((ctx->opcode >> 21) & 0x1f) {
17219 case 1:
17220 /* drotr is decoded as dsrl on non-R2 CPUs */
17221 if (ctx->insn_flags & ISA_MIPS32R2) {
17222 op1 = OPC_DROTR;
ea63e2c3 17223 }
099e5b4d
LA
17224 /* Fallthrough */
17225 case 0:
d75c135e 17226 check_insn(ctx, ISA_MIPS3);
e189e748 17227 check_mips_64(ctx);
099e5b4d 17228 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17229 break;
099e5b4d 17230 default:
9c708c7f 17231 generate_exception_end(ctx, EXCP_RI);
460f00c4 17232 break;
099e5b4d
LA
17233 }
17234 break;
17235 case OPC_DSRL32:
17236 switch ((ctx->opcode >> 21) & 0x1f) {
17237 case 1:
17238 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17239 if (ctx->insn_flags & ISA_MIPS32R2) {
17240 op1 = OPC_DROTR32;
ea63e2c3 17241 }
099e5b4d
LA
17242 /* Fallthrough */
17243 case 0:
d75c135e 17244 check_insn(ctx, ISA_MIPS3);
e189e748 17245 check_mips_64(ctx);
099e5b4d 17246 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17247 break;
099e5b4d 17248 default:
9c708c7f 17249 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17250 break;
17251 }
17252 break;
099e5b4d
LA
17253 case OPC_DADD ... OPC_DSUBU:
17254 check_insn(ctx, ISA_MIPS3);
17255 check_mips_64(ctx);
17256 gen_arith(ctx, op1, rd, rs, rt);
17257 break;
17258 case OPC_DSLLV:
17259 case OPC_DSRAV:
17260 check_insn(ctx, ISA_MIPS3);
17261 check_mips_64(ctx);
17262 gen_shift(ctx, op1, rd, rs, rt);
17263 break;
17264 case OPC_DSRLV:
17265 switch ((ctx->opcode >> 6) & 0x1f) {
17266 case 1:
17267 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17268 if (ctx->insn_flags & ISA_MIPS32R2) {
17269 op1 = OPC_DROTRV;
6af0bf9c 17270 }
099e5b4d
LA
17271 /* Fallthrough */
17272 case 0:
17273 check_insn(ctx, ISA_MIPS3);
e189e748 17274 check_mips_64(ctx);
099e5b4d 17275 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17276 break;
099e5b4d 17277 default:
9c708c7f 17278 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17279 break;
17280 }
17281 break;
f7685877
YK
17282 case OPC_DLSA:
17283 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17284 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17285 decode_opc_special_r6(env, ctx);
17286 }
17287 break;
099e5b4d 17288#endif
10dc65db
LA
17289 default:
17290 if (ctx->insn_flags & ISA_MIPS32R6) {
17291 decode_opc_special_r6(env, ctx);
17292 } else {
17293 decode_opc_special_legacy(env, ctx);
17294 }
17295 }
17296}
17297
10dc65db 17298static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17299{
17300 int rs, rt, rd;
17301 uint32_t op1;
6c5c1e20 17302
4267d3e6
LA
17303 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17304
099e5b4d
LA
17305 rs = (ctx->opcode >> 21) & 0x1f;
17306 rt = (ctx->opcode >> 16) & 0x1f;
17307 rd = (ctx->opcode >> 11) & 0x1f;
17308
17309 op1 = MASK_SPECIAL2(ctx->opcode);
17310 switch (op1) {
17311 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17312 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17313 check_insn(ctx, ISA_MIPS32);
17314 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17315 break;
17316 case OPC_MUL:
099e5b4d
LA
17317 gen_arith(ctx, op1, rd, rs, rt);
17318 break;
fac5a073
LA
17319 case OPC_DIV_G_2F:
17320 case OPC_DIVU_G_2F:
17321 case OPC_MULT_G_2F:
17322 case OPC_MULTU_G_2F:
17323 case OPC_MOD_G_2F:
17324 case OPC_MODU_G_2F:
17325 check_insn(ctx, INSN_LOONGSON2F);
17326 gen_loongson_integer(ctx, op1, rd, rs, rt);
17327 break;
099e5b4d
LA
17328 case OPC_CLO:
17329 case OPC_CLZ:
17330 check_insn(ctx, ISA_MIPS32);
17331 gen_cl(ctx, op1, rd, rs);
17332 break;
17333 case OPC_SDBBP:
3b3c1694
LA
17334 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17335 gen_helper_do_semihosting(cpu_env);
17336 } else {
17337 /* XXX: not clear which exception should be raised
17338 * when in debug mode...
17339 */
17340 check_insn(ctx, ISA_MIPS32);
9c708c7f 17341 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17342 }
099e5b4d 17343 break;
9b1a1d68 17344#if defined(TARGET_MIPS64)
099e5b4d
LA
17345 case OPC_DCLO:
17346 case OPC_DCLZ:
17347 check_insn(ctx, ISA_MIPS64);
17348 check_mips_64(ctx);
17349 gen_cl(ctx, op1, rd, rs);
17350 break;
4267d3e6
LA
17351 case OPC_DMULT_G_2F:
17352 case OPC_DMULTU_G_2F:
17353 case OPC_DDIV_G_2F:
17354 case OPC_DDIVU_G_2F:
17355 case OPC_DMOD_G_2F:
17356 case OPC_DMODU_G_2F:
17357 check_insn(ctx, INSN_LOONGSON2F);
17358 gen_loongson_integer(ctx, op1, rd, rs, rt);
17359 break;
10dc65db 17360#endif
4267d3e6
LA
17361 default: /* Invalid */
17362 MIPS_INVAL("special2_legacy");
9c708c7f 17363 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17364 break;
10dc65db
LA
17365 }
17366}
17367
17368static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17369{
15eacb9b
YK
17370 int rs, rt, rd, sa;
17371 uint32_t op1, op2;
10dc65db
LA
17372 int16_t imm;
17373
17374 rs = (ctx->opcode >> 21) & 0x1f;
17375 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17376 rd = (ctx->opcode >> 11) & 0x1f;
17377 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17378 imm = (int16_t)ctx->opcode >> 7;
17379
17380 op1 = MASK_SPECIAL3(ctx->opcode);
17381 switch (op1) {
bf7910c6
LA
17382 case R6_OPC_PREF:
17383 if (rt >= 24) {
17384 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17385 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17386 }
17387 /* Treat as NOP. */
17388 break;
17389 case R6_OPC_CACHE:
40d48212 17390 check_cp0_enabled(ctx);
0d74a222
LA
17391 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17392 gen_cache_operation(ctx, rt, rs, imm);
17393 }
bf7910c6 17394 break;
10dc65db
LA
17395 case R6_OPC_SC:
17396 gen_st_cond(ctx, op1, rt, rs, imm);
17397 break;
17398 case R6_OPC_LL:
17399 gen_ld(ctx, op1, rt, rs, imm);
17400 break;
15eacb9b
YK
17401 case OPC_BSHFL:
17402 {
17403 if (rd == 0) {
17404 /* Treat as NOP. */
17405 break;
17406 }
15eacb9b
YK
17407 op2 = MASK_BSHFL(ctx->opcode);
17408 switch (op2) {
17409 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17410 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17411 break;
17412 case OPC_BITSWAP:
1f1b4c00 17413 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17414 break;
17415 }
15eacb9b
YK
17416 }
17417 break;
bf7910c6
LA
17418#if defined(TARGET_MIPS64)
17419 case R6_OPC_SCD:
17420 gen_st_cond(ctx, op1, rt, rs, imm);
17421 break;
17422 case R6_OPC_LLD:
17423 gen_ld(ctx, op1, rt, rs, imm);
17424 break;
15eacb9b
YK
17425 case OPC_DBSHFL:
17426 check_mips_64(ctx);
17427 {
17428 if (rd == 0) {
17429 /* Treat as NOP. */
17430 break;
17431 }
15eacb9b
YK
17432 op2 = MASK_DBSHFL(ctx->opcode);
17433 switch (op2) {
17434 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17435 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17436 break;
17437 case OPC_DBITSWAP:
1f1b4c00 17438 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17439 break;
17440 }
1f1b4c00 17441
15eacb9b
YK
17442 }
17443 break;
bf7910c6 17444#endif
10dc65db
LA
17445 default: /* Invalid */
17446 MIPS_INVAL("special3_r6");
9c708c7f 17447 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17448 break;
17449 }
17450}
17451
17452static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17453{
fac5a073 17454 int rs, rt, rd;
099e5b4d 17455 uint32_t op1, op2;
099e5b4d
LA
17456
17457 rs = (ctx->opcode >> 21) & 0x1f;
17458 rt = (ctx->opcode >> 16) & 0x1f;
17459 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17460
17461 op1 = MASK_SPECIAL3(ctx->opcode);
17462 switch (op1) {
099e5b4d
LA
17463 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17464 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17465 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17466 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17467 * the same mask and op1. */
17468 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17469 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17470 switch (op2) {
099e5b4d
LA
17471 case OPC_ADDUH_QB:
17472 case OPC_ADDUH_R_QB:
17473 case OPC_ADDQH_PH:
17474 case OPC_ADDQH_R_PH:
17475 case OPC_ADDQH_W:
17476 case OPC_ADDQH_R_W:
17477 case OPC_SUBUH_QB:
17478 case OPC_SUBUH_R_QB:
17479 case OPC_SUBQH_PH:
17480 case OPC_SUBQH_R_PH:
17481 case OPC_SUBQH_W:
17482 case OPC_SUBQH_R_W:
461c08df
JL
17483 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17484 break;
099e5b4d
LA
17485 case OPC_MUL_PH:
17486 case OPC_MUL_S_PH:
17487 case OPC_MULQ_S_W:
17488 case OPC_MULQ_RS_W:
17489 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17490 break;
461c08df 17491 default:
099e5b4d 17492 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17493 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17494 break;
17495 }
099e5b4d
LA
17496 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17497 gen_loongson_integer(ctx, op1, rd, rs, rt);
17498 } else {
9c708c7f 17499 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17500 }
17501 break;
17502 case OPC_LX_DSP:
17503 op2 = MASK_LX(ctx->opcode);
17504 switch (op2) {
17505#if defined(TARGET_MIPS64)
17506 case OPC_LDX:
17507#endif
17508 case OPC_LBUX:
17509 case OPC_LHX:
17510 case OPC_LWX:
17511 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17512 break;
17513 default: /* Invalid */
17514 MIPS_INVAL("MASK LX");
9c708c7f 17515 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17516 break;
17517 }
17518 break;
17519 case OPC_ABSQ_S_PH_DSP:
17520 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17521 switch (op2) {
17522 case OPC_ABSQ_S_QB:
17523 case OPC_ABSQ_S_PH:
17524 case OPC_ABSQ_S_W:
17525 case OPC_PRECEQ_W_PHL:
17526 case OPC_PRECEQ_W_PHR:
17527 case OPC_PRECEQU_PH_QBL:
17528 case OPC_PRECEQU_PH_QBR:
17529 case OPC_PRECEQU_PH_QBLA:
17530 case OPC_PRECEQU_PH_QBRA:
17531 case OPC_PRECEU_PH_QBL:
17532 case OPC_PRECEU_PH_QBR:
17533 case OPC_PRECEU_PH_QBLA:
17534 case OPC_PRECEU_PH_QBRA:
17535 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17536 break;
17537 case OPC_BITREV:
17538 case OPC_REPL_QB:
17539 case OPC_REPLV_QB:
17540 case OPC_REPL_PH:
17541 case OPC_REPLV_PH:
17542 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17543 break;
17544 default:
17545 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17546 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17547 break;
17548 }
17549 break;
17550 case OPC_ADDU_QB_DSP:
17551 op2 = MASK_ADDU_QB(ctx->opcode);
17552 switch (op2) {
17553 case OPC_ADDQ_PH:
17554 case OPC_ADDQ_S_PH:
17555 case OPC_ADDQ_S_W:
17556 case OPC_ADDU_QB:
17557 case OPC_ADDU_S_QB:
17558 case OPC_ADDU_PH:
17559 case OPC_ADDU_S_PH:
17560 case OPC_SUBQ_PH:
17561 case OPC_SUBQ_S_PH:
17562 case OPC_SUBQ_S_W:
17563 case OPC_SUBU_QB:
17564 case OPC_SUBU_S_QB:
17565 case OPC_SUBU_PH:
17566 case OPC_SUBU_S_PH:
17567 case OPC_ADDSC:
17568 case OPC_ADDWC:
17569 case OPC_MODSUB:
17570 case OPC_RADDU_W_QB:
17571 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17572 break;
17573 case OPC_MULEU_S_PH_QBL:
17574 case OPC_MULEU_S_PH_QBR:
17575 case OPC_MULQ_RS_PH:
17576 case OPC_MULEQ_S_W_PHL:
17577 case OPC_MULEQ_S_W_PHR:
17578 case OPC_MULQ_S_PH:
17579 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17580 break;
17581 default: /* Invalid */
17582 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17583 generate_exception_end(ctx, EXCP_RI);
461c08df 17584 break;
461c08df 17585
099e5b4d
LA
17586 }
17587 break;
17588 case OPC_CMPU_EQ_QB_DSP:
17589 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17590 switch (op2) {
17591 case OPC_PRECR_SRA_PH_W:
17592 case OPC_PRECR_SRA_R_PH_W:
17593 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17594 break;
099e5b4d
LA
17595 case OPC_PRECR_QB_PH:
17596 case OPC_PRECRQ_QB_PH:
17597 case OPC_PRECRQ_PH_W:
17598 case OPC_PRECRQ_RS_PH_W:
17599 case OPC_PRECRQU_S_QB_PH:
17600 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17601 break;
099e5b4d
LA
17602 case OPC_CMPU_EQ_QB:
17603 case OPC_CMPU_LT_QB:
17604 case OPC_CMPU_LE_QB:
17605 case OPC_CMP_EQ_PH:
17606 case OPC_CMP_LT_PH:
17607 case OPC_CMP_LE_PH:
17608 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17609 break;
099e5b4d
LA
17610 case OPC_CMPGU_EQ_QB:
17611 case OPC_CMPGU_LT_QB:
17612 case OPC_CMPGU_LE_QB:
17613 case OPC_CMPGDU_EQ_QB:
17614 case OPC_CMPGDU_LT_QB:
17615 case OPC_CMPGDU_LE_QB:
17616 case OPC_PICK_QB:
17617 case OPC_PICK_PH:
17618 case OPC_PACKRL_PH:
17619 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17620 break;
17621 default: /* Invalid */
17622 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17623 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17624 break;
17625 }
17626 break;
17627 case OPC_SHLL_QB_DSP:
17628 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17629 break;
17630 case OPC_DPA_W_PH_DSP:
17631 op2 = MASK_DPA_W_PH(ctx->opcode);
17632 switch (op2) {
17633 case OPC_DPAU_H_QBL:
17634 case OPC_DPAU_H_QBR:
17635 case OPC_DPSU_H_QBL:
17636 case OPC_DPSU_H_QBR:
17637 case OPC_DPA_W_PH:
17638 case OPC_DPAX_W_PH:
17639 case OPC_DPAQ_S_W_PH:
17640 case OPC_DPAQX_S_W_PH:
17641 case OPC_DPAQX_SA_W_PH:
17642 case OPC_DPS_W_PH:
17643 case OPC_DPSX_W_PH:
17644 case OPC_DPSQ_S_W_PH:
17645 case OPC_DPSQX_S_W_PH:
17646 case OPC_DPSQX_SA_W_PH:
17647 case OPC_MULSAQ_S_W_PH:
17648 case OPC_DPAQ_SA_L_W:
17649 case OPC_DPSQ_SA_L_W:
17650 case OPC_MAQ_S_W_PHL:
17651 case OPC_MAQ_S_W_PHR:
17652 case OPC_MAQ_SA_W_PHL:
17653 case OPC_MAQ_SA_W_PHR:
17654 case OPC_MULSA_W_PH:
17655 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17656 break;
17657 default: /* Invalid */
17658 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17659 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17660 break;
17661 }
17662 break;
17663 case OPC_INSV_DSP:
17664 op2 = MASK_INSV(ctx->opcode);
17665 switch (op2) {
17666 case OPC_INSV:
17667 check_dsp(ctx);
17668 {
17669 TCGv t0, t1;
17670
17671 if (rt == 0) {
099e5b4d
LA
17672 break;
17673 }
17674
17675 t0 = tcg_temp_new();
17676 t1 = tcg_temp_new();
17677
17678 gen_load_gpr(t0, rt);
17679 gen_load_gpr(t1, rs);
17680
17681 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17682
17683 tcg_temp_free(t0);
17684 tcg_temp_free(t1);
a22260ae
JL
17685 break;
17686 }
099e5b4d
LA
17687 default: /* Invalid */
17688 MIPS_INVAL("MASK INSV");
9c708c7f 17689 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17690 break;
17691 }
17692 break;
17693 case OPC_APPEND_DSP:
17694 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17695 break;
17696 case OPC_EXTR_W_DSP:
17697 op2 = MASK_EXTR_W(ctx->opcode);
17698 switch (op2) {
17699 case OPC_EXTR_W:
17700 case OPC_EXTR_R_W:
17701 case OPC_EXTR_RS_W:
17702 case OPC_EXTR_S_H:
17703 case OPC_EXTRV_S_H:
17704 case OPC_EXTRV_W:
17705 case OPC_EXTRV_R_W:
17706 case OPC_EXTRV_RS_W:
17707 case OPC_EXTP:
17708 case OPC_EXTPV:
17709 case OPC_EXTPDP:
17710 case OPC_EXTPDPV:
17711 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17712 break;
17713 case OPC_RDDSP:
17714 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17715 break;
17716 case OPC_SHILO:
17717 case OPC_SHILOV:
17718 case OPC_MTHLIP:
17719 case OPC_WRDSP:
17720 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17721 break;
17722 default: /* Invalid */
17723 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17724 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17725 break;
17726 }
17727 break;
099e5b4d 17728#if defined(TARGET_MIPS64)
fac5a073
LA
17729 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17730 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17731 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17732 check_insn(ctx, INSN_LOONGSON2E);
17733 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17734 break;
099e5b4d
LA
17735 case OPC_ABSQ_S_QH_DSP:
17736 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17737 switch (op2) {
17738 case OPC_PRECEQ_L_PWL:
17739 case OPC_PRECEQ_L_PWR:
17740 case OPC_PRECEQ_PW_QHL:
17741 case OPC_PRECEQ_PW_QHR:
17742 case OPC_PRECEQ_PW_QHLA:
17743 case OPC_PRECEQ_PW_QHRA:
17744 case OPC_PRECEQU_QH_OBL:
17745 case OPC_PRECEQU_QH_OBR:
17746 case OPC_PRECEQU_QH_OBLA:
17747 case OPC_PRECEQU_QH_OBRA:
17748 case OPC_PRECEU_QH_OBL:
17749 case OPC_PRECEU_QH_OBR:
17750 case OPC_PRECEU_QH_OBLA:
17751 case OPC_PRECEU_QH_OBRA:
17752 case OPC_ABSQ_S_OB:
17753 case OPC_ABSQ_S_PW:
17754 case OPC_ABSQ_S_QH:
17755 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17756 break;
17757 case OPC_REPL_OB:
17758 case OPC_REPL_PW:
17759 case OPC_REPL_QH:
17760 case OPC_REPLV_OB:
17761 case OPC_REPLV_PW:
17762 case OPC_REPLV_QH:
17763 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17764 break;
17765 default: /* Invalid */
17766 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 17767 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17768 break;
17769 }
17770 break;
17771 case OPC_ADDU_OB_DSP:
17772 op2 = MASK_ADDU_OB(ctx->opcode);
17773 switch (op2) {
17774 case OPC_RADDU_L_OB:
17775 case OPC_SUBQ_PW:
17776 case OPC_SUBQ_S_PW:
17777 case OPC_SUBQ_QH:
17778 case OPC_SUBQ_S_QH:
17779 case OPC_SUBU_OB:
17780 case OPC_SUBU_S_OB:
17781 case OPC_SUBU_QH:
17782 case OPC_SUBU_S_QH:
17783 case OPC_SUBUH_OB:
17784 case OPC_SUBUH_R_OB:
17785 case OPC_ADDQ_PW:
17786 case OPC_ADDQ_S_PW:
17787 case OPC_ADDQ_QH:
17788 case OPC_ADDQ_S_QH:
17789 case OPC_ADDU_OB:
17790 case OPC_ADDU_S_OB:
17791 case OPC_ADDU_QH:
17792 case OPC_ADDU_S_QH:
17793 case OPC_ADDUH_OB:
17794 case OPC_ADDUH_R_OB:
17795 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17796 break;
099e5b4d
LA
17797 case OPC_MULEQ_S_PW_QHL:
17798 case OPC_MULEQ_S_PW_QHR:
17799 case OPC_MULEU_S_QH_OBL:
17800 case OPC_MULEU_S_QH_OBR:
17801 case OPC_MULQ_RS_QH:
17802 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17803 break;
099e5b4d
LA
17804 default: /* Invalid */
17805 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 17806 generate_exception_end(ctx, EXCP_RI);
26690560 17807 break;
099e5b4d
LA
17808 }
17809 break;
17810 case OPC_CMPU_EQ_OB_DSP:
17811 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17812 switch (op2) {
17813 case OPC_PRECR_SRA_QH_PW:
17814 case OPC_PRECR_SRA_R_QH_PW:
17815 /* Return value is rt. */
17816 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17817 break;
099e5b4d
LA
17818 case OPC_PRECR_OB_QH:
17819 case OPC_PRECRQ_OB_QH:
17820 case OPC_PRECRQ_PW_L:
17821 case OPC_PRECRQ_QH_PW:
17822 case OPC_PRECRQ_RS_QH_PW:
17823 case OPC_PRECRQU_S_OB_QH:
17824 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17825 break;
099e5b4d
LA
17826 case OPC_CMPU_EQ_OB:
17827 case OPC_CMPU_LT_OB:
17828 case OPC_CMPU_LE_OB:
17829 case OPC_CMP_EQ_QH:
17830 case OPC_CMP_LT_QH:
17831 case OPC_CMP_LE_QH:
17832 case OPC_CMP_EQ_PW:
17833 case OPC_CMP_LT_PW:
17834 case OPC_CMP_LE_PW:
17835 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17836 break;
099e5b4d
LA
17837 case OPC_CMPGDU_EQ_OB:
17838 case OPC_CMPGDU_LT_OB:
17839 case OPC_CMPGDU_LE_OB:
17840 case OPC_CMPGU_EQ_OB:
17841 case OPC_CMPGU_LT_OB:
17842 case OPC_CMPGU_LE_OB:
17843 case OPC_PACKRL_PW:
17844 case OPC_PICK_OB:
17845 case OPC_PICK_PW:
17846 case OPC_PICK_QH:
17847 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17848 break;
099e5b4d
LA
17849 default: /* Invalid */
17850 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 17851 generate_exception_end(ctx, EXCP_RI);
161f85e6 17852 break;
099e5b4d
LA
17853 }
17854 break;
17855 case OPC_DAPPEND_DSP:
17856 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17857 break;
17858 case OPC_DEXTR_W_DSP:
17859 op2 = MASK_DEXTR_W(ctx->opcode);
17860 switch (op2) {
17861 case OPC_DEXTP:
17862 case OPC_DEXTPDP:
17863 case OPC_DEXTPDPV:
17864 case OPC_DEXTPV:
17865 case OPC_DEXTR_L:
17866 case OPC_DEXTR_R_L:
17867 case OPC_DEXTR_RS_L:
17868 case OPC_DEXTR_W:
17869 case OPC_DEXTR_R_W:
17870 case OPC_DEXTR_RS_W:
17871 case OPC_DEXTR_S_H:
17872 case OPC_DEXTRV_L:
17873 case OPC_DEXTRV_R_L:
17874 case OPC_DEXTRV_RS_L:
17875 case OPC_DEXTRV_S_H:
17876 case OPC_DEXTRV_W:
17877 case OPC_DEXTRV_R_W:
17878 case OPC_DEXTRV_RS_W:
17879 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17880 break;
099e5b4d
LA
17881 case OPC_DMTHLIP:
17882 case OPC_DSHILO:
17883 case OPC_DSHILOV:
17884 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17885 break;
099e5b4d
LA
17886 default: /* Invalid */
17887 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17888 generate_exception_end(ctx, EXCP_RI);
461c08df 17889 break;
099e5b4d
LA
17890 }
17891 break;
17892 case OPC_DPAQ_W_QH_DSP:
17893 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17894 switch (op2) {
17895 case OPC_DPAU_H_OBL:
17896 case OPC_DPAU_H_OBR:
17897 case OPC_DPSU_H_OBL:
17898 case OPC_DPSU_H_OBR:
17899 case OPC_DPA_W_QH:
17900 case OPC_DPAQ_S_W_QH:
17901 case OPC_DPS_W_QH:
17902 case OPC_DPSQ_S_W_QH:
17903 case OPC_MULSAQ_S_W_QH:
17904 case OPC_DPAQ_SA_L_PW:
17905 case OPC_DPSQ_SA_L_PW:
17906 case OPC_MULSAQ_S_L_PW:
17907 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17908 break;
17909 case OPC_MAQ_S_W_QHLL:
17910 case OPC_MAQ_S_W_QHLR:
17911 case OPC_MAQ_S_W_QHRL:
17912 case OPC_MAQ_S_W_QHRR:
17913 case OPC_MAQ_SA_W_QHLL:
17914 case OPC_MAQ_SA_W_QHLR:
17915 case OPC_MAQ_SA_W_QHRL:
17916 case OPC_MAQ_SA_W_QHRR:
17917 case OPC_MAQ_S_L_PWL:
17918 case OPC_MAQ_S_L_PWR:
17919 case OPC_DMADD:
17920 case OPC_DMADDU:
17921 case OPC_DMSUB:
17922 case OPC_DMSUBU:
17923 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17924 break;
099e5b4d
LA
17925 default: /* Invalid */
17926 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 17927 generate_exception_end(ctx, EXCP_RI);
b53371ed 17928 break;
099e5b4d
LA
17929 }
17930 break;
17931 case OPC_DINSV_DSP:
17932 op2 = MASK_INSV(ctx->opcode);
17933 switch (op2) {
17934 case OPC_DINSV:
17935 {
17936 TCGv t0, t1;
17937
17938 if (rt == 0) {
a22260ae
JL
17939 break;
17940 }
099e5b4d 17941 check_dsp(ctx);
1cb6686c 17942
099e5b4d
LA
17943 t0 = tcg_temp_new();
17944 t1 = tcg_temp_new();
1cb6686c 17945
099e5b4d
LA
17946 gen_load_gpr(t0, rt);
17947 gen_load_gpr(t1, rs);
1cb6686c 17948
099e5b4d 17949 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17950
099e5b4d
LA
17951 tcg_temp_free(t0);
17952 tcg_temp_free(t1);
77c5fa8b 17953 break;
099e5b4d 17954 }
7a387fff 17955 default: /* Invalid */
099e5b4d 17956 MIPS_INVAL("MASK DINSV");
9c708c7f 17957 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
17958 break;
17959 }
17960 break;
099e5b4d
LA
17961 case OPC_SHLL_OB_DSP:
17962 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17963 break;
17964#endif
fac5a073
LA
17965 default: /* Invalid */
17966 MIPS_INVAL("special3_legacy");
9c708c7f 17967 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
17968 break;
17969 }
17970}
17971
17972static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17973{
17974 int rs, rt, rd, sa;
17975 uint32_t op1, op2;
17976
17977 rs = (ctx->opcode >> 21) & 0x1f;
17978 rt = (ctx->opcode >> 16) & 0x1f;
17979 rd = (ctx->opcode >> 11) & 0x1f;
17980 sa = (ctx->opcode >> 6) & 0x1f;
17981
17982 op1 = MASK_SPECIAL3(ctx->opcode);
17983 switch (op1) {
17984 case OPC_EXT:
17985 case OPC_INS:
17986 check_insn(ctx, ISA_MIPS32R2);
17987 gen_bitops(ctx, op1, rt, rs, sa, rd);
17988 break;
17989 case OPC_BSHFL:
fac5a073 17990 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17991 switch (op2) {
17992 case OPC_ALIGN ... OPC_ALIGN_END:
17993 case OPC_BITSWAP:
17994 check_insn(ctx, ISA_MIPS32R6);
17995 decode_opc_special3_r6(env, ctx);
17996 break;
17997 default:
17998 check_insn(ctx, ISA_MIPS32R2);
17999 gen_bshfl(ctx, op2, rt, rd);
18000 break;
18001 }
fac5a073
LA
18002 break;
18003#if defined(TARGET_MIPS64)
18004 case OPC_DEXTM ... OPC_DEXT:
18005 case OPC_DINSM ... OPC_DINS:
18006 check_insn(ctx, ISA_MIPS64R2);
18007 check_mips_64(ctx);
18008 gen_bitops(ctx, op1, rt, rs, sa, rd);
18009 break;
18010 case OPC_DBSHFL:
fac5a073 18011 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
18012 switch (op2) {
18013 case OPC_DALIGN ... OPC_DALIGN_END:
18014 case OPC_DBITSWAP:
18015 check_insn(ctx, ISA_MIPS32R6);
18016 decode_opc_special3_r6(env, ctx);
18017 break;
18018 default:
18019 check_insn(ctx, ISA_MIPS64R2);
18020 check_mips_64(ctx);
18021 op2 = MASK_DBSHFL(ctx->opcode);
18022 gen_bshfl(ctx, op2, rt, rd);
18023 break;
18024 }
fac5a073
LA
18025 break;
18026#endif
18027 case OPC_RDHWR:
b00c7218 18028 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18029 break;
18030 case OPC_FORK:
18031 check_insn(ctx, ASE_MT);
18032 {
18033 TCGv t0 = tcg_temp_new();
18034 TCGv t1 = tcg_temp_new();
18035
18036 gen_load_gpr(t0, rt);
18037 gen_load_gpr(t1, rs);
18038 gen_helper_fork(t0, t1);
18039 tcg_temp_free(t0);
18040 tcg_temp_free(t1);
18041 }
18042 break;
18043 case OPC_YIELD:
18044 check_insn(ctx, ASE_MT);
18045 {
18046 TCGv t0 = tcg_temp_new();
18047
fac5a073
LA
18048 gen_load_gpr(t0, rs);
18049 gen_helper_yield(t0, cpu_env, t0);
18050 gen_store_gpr(t0, rd);
18051 tcg_temp_free(t0);
18052 }
18053 break;
10dc65db
LA
18054 default:
18055 if (ctx->insn_flags & ISA_MIPS32R6) {
18056 decode_opc_special3_r6(env, ctx);
18057 } else {
18058 decode_opc_special3_legacy(env, ctx);
18059 }
099e5b4d
LA
18060 }
18061}
18062
863f264d
YK
18063/* MIPS SIMD Architecture (MSA) */
18064static inline int check_msa_access(DisasContext *ctx)
18065{
18066 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18067 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18068 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18069 return 0;
18070 }
18071
18072 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18073 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18074 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18075 return 0;
18076 } else {
9c708c7f 18077 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18078 return 0;
18079 }
18080 }
18081 return 1;
18082}
18083
5692c6e1
YK
18084static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18085{
18086 /* generates tcg ops to check if any element is 0 */
18087 /* Note this function only works with MSA_WRLEN = 128 */
18088 uint64_t eval_zero_or_big = 0;
18089 uint64_t eval_big = 0;
18090 TCGv_i64 t0 = tcg_temp_new_i64();
18091 TCGv_i64 t1 = tcg_temp_new_i64();
18092 switch (df) {
18093 case DF_BYTE:
18094 eval_zero_or_big = 0x0101010101010101ULL;
18095 eval_big = 0x8080808080808080ULL;
18096 break;
18097 case DF_HALF:
18098 eval_zero_or_big = 0x0001000100010001ULL;
18099 eval_big = 0x8000800080008000ULL;
18100 break;
18101 case DF_WORD:
18102 eval_zero_or_big = 0x0000000100000001ULL;
18103 eval_big = 0x8000000080000000ULL;
18104 break;
18105 case DF_DOUBLE:
18106 eval_zero_or_big = 0x0000000000000001ULL;
18107 eval_big = 0x8000000000000000ULL;
18108 break;
18109 }
18110 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18111 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18112 tcg_gen_andi_i64(t0, t0, eval_big);
18113 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18114 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18115 tcg_gen_andi_i64(t1, t1, eval_big);
18116 tcg_gen_or_i64(t0, t0, t1);
18117 /* if all bits are zero then all elements are not zero */
18118 /* if some bit is non-zero then some element is zero */
18119 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18120 tcg_gen_trunc_i64_tl(tresult, t0);
18121 tcg_temp_free_i64(t0);
18122 tcg_temp_free_i64(t1);
18123}
18124
18125static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18126{
18127 uint8_t df = (ctx->opcode >> 21) & 0x3;
18128 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18129 int64_t s16 = (int16_t)ctx->opcode;
18130
18131 check_msa_access(ctx);
18132
18133 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18134 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18135 return;
18136 }
18137 switch (op1) {
18138 case OPC_BZ_V:
18139 case OPC_BNZ_V:
18140 {
18141 TCGv_i64 t0 = tcg_temp_new_i64();
18142 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18143 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18144 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18145 tcg_gen_trunc_i64_tl(bcond, t0);
18146 tcg_temp_free_i64(t0);
18147 }
18148 break;
18149 case OPC_BZ_B:
18150 case OPC_BZ_H:
18151 case OPC_BZ_W:
18152 case OPC_BZ_D:
18153 gen_check_zero_element(bcond, df, wt);
18154 break;
18155 case OPC_BNZ_B:
18156 case OPC_BNZ_H:
18157 case OPC_BNZ_W:
18158 case OPC_BNZ_D:
18159 gen_check_zero_element(bcond, df, wt);
18160 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18161 break;
18162 }
18163
18164 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18165
18166 ctx->hflags |= MIPS_HFLAG_BC;
18167 ctx->hflags |= MIPS_HFLAG_BDS32;
18168}
18169
4c789546
YK
18170static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18171{
18172#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18173 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18174 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18175 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18176
18177 TCGv_i32 twd = tcg_const_i32(wd);
18178 TCGv_i32 tws = tcg_const_i32(ws);
18179 TCGv_i32 ti8 = tcg_const_i32(i8);
18180
18181 switch (MASK_MSA_I8(ctx->opcode)) {
18182 case OPC_ANDI_B:
18183 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18184 break;
18185 case OPC_ORI_B:
18186 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18187 break;
18188 case OPC_NORI_B:
18189 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18190 break;
18191 case OPC_XORI_B:
18192 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18193 break;
18194 case OPC_BMNZI_B:
18195 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18196 break;
18197 case OPC_BMZI_B:
18198 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18199 break;
18200 case OPC_BSELI_B:
18201 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18202 break;
18203 case OPC_SHF_B:
18204 case OPC_SHF_H:
18205 case OPC_SHF_W:
18206 {
18207 uint8_t df = (ctx->opcode >> 24) & 0x3;
18208 if (df == DF_DOUBLE) {
9c708c7f 18209 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18210 } else {
18211 TCGv_i32 tdf = tcg_const_i32(df);
18212 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18213 tcg_temp_free_i32(tdf);
18214 }
18215 }
18216 break;
18217 default:
18218 MIPS_INVAL("MSA instruction");
9c708c7f 18219 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18220 break;
18221 }
18222
18223 tcg_temp_free_i32(twd);
18224 tcg_temp_free_i32(tws);
18225 tcg_temp_free_i32(ti8);
18226}
18227
80e71591
YK
18228static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18229{
18230#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18231 uint8_t df = (ctx->opcode >> 21) & 0x3;
18232 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18233 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18234 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18235 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18236
18237 TCGv_i32 tdf = tcg_const_i32(df);
18238 TCGv_i32 twd = tcg_const_i32(wd);
18239 TCGv_i32 tws = tcg_const_i32(ws);
18240 TCGv_i32 timm = tcg_temp_new_i32();
18241 tcg_gen_movi_i32(timm, u5);
18242
18243 switch (MASK_MSA_I5(ctx->opcode)) {
18244 case OPC_ADDVI_df:
18245 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18246 break;
18247 case OPC_SUBVI_df:
18248 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18249 break;
18250 case OPC_MAXI_S_df:
18251 tcg_gen_movi_i32(timm, s5);
18252 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18253 break;
18254 case OPC_MAXI_U_df:
18255 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18256 break;
18257 case OPC_MINI_S_df:
18258 tcg_gen_movi_i32(timm, s5);
18259 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18260 break;
18261 case OPC_MINI_U_df:
18262 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18263 break;
18264 case OPC_CEQI_df:
18265 tcg_gen_movi_i32(timm, s5);
18266 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18267 break;
18268 case OPC_CLTI_S_df:
18269 tcg_gen_movi_i32(timm, s5);
18270 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18271 break;
18272 case OPC_CLTI_U_df:
18273 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18274 break;
18275 case OPC_CLEI_S_df:
18276 tcg_gen_movi_i32(timm, s5);
18277 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18278 break;
18279 case OPC_CLEI_U_df:
18280 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18281 break;
18282 case OPC_LDI_df:
18283 {
18284 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18285 tcg_gen_movi_i32(timm, s10);
18286 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18287 }
18288 break;
18289 default:
18290 MIPS_INVAL("MSA instruction");
9c708c7f 18291 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18292 break;
18293 }
18294
18295 tcg_temp_free_i32(tdf);
18296 tcg_temp_free_i32(twd);
18297 tcg_temp_free_i32(tws);
18298 tcg_temp_free_i32(timm);
18299}
18300
d4cf28de
YK
18301static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18302{
18303#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18304 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18305 uint32_t df = 0, m = 0;
18306 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18307 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18308
18309 TCGv_i32 tdf;
18310 TCGv_i32 tm;
18311 TCGv_i32 twd;
18312 TCGv_i32 tws;
18313
18314 if ((dfm & 0x40) == 0x00) {
18315 m = dfm & 0x3f;
18316 df = DF_DOUBLE;
18317 } else if ((dfm & 0x60) == 0x40) {
18318 m = dfm & 0x1f;
18319 df = DF_WORD;
18320 } else if ((dfm & 0x70) == 0x60) {
18321 m = dfm & 0x0f;
18322 df = DF_HALF;
18323 } else if ((dfm & 0x78) == 0x70) {
18324 m = dfm & 0x7;
18325 df = DF_BYTE;
18326 } else {
9c708c7f 18327 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18328 return;
18329 }
18330
18331 tdf = tcg_const_i32(df);
18332 tm = tcg_const_i32(m);
18333 twd = tcg_const_i32(wd);
18334 tws = tcg_const_i32(ws);
18335
18336 switch (MASK_MSA_BIT(ctx->opcode)) {
18337 case OPC_SLLI_df:
18338 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18339 break;
18340 case OPC_SRAI_df:
18341 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18342 break;
18343 case OPC_SRLI_df:
18344 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18345 break;
18346 case OPC_BCLRI_df:
18347 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18348 break;
18349 case OPC_BSETI_df:
18350 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18351 break;
18352 case OPC_BNEGI_df:
18353 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18354 break;
18355 case OPC_BINSLI_df:
18356 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18357 break;
18358 case OPC_BINSRI_df:
18359 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18360 break;
18361 case OPC_SAT_S_df:
18362 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18363 break;
18364 case OPC_SAT_U_df:
18365 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18366 break;
18367 case OPC_SRARI_df:
18368 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18369 break;
18370 case OPC_SRLRI_df:
18371 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18372 break;
18373 default:
18374 MIPS_INVAL("MSA instruction");
9c708c7f 18375 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18376 break;
18377 }
18378
18379 tcg_temp_free_i32(tdf);
18380 tcg_temp_free_i32(tm);
18381 tcg_temp_free_i32(twd);
18382 tcg_temp_free_i32(tws);
18383}
18384
28f99f08
YK
18385static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18386{
18387#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18388 uint8_t df = (ctx->opcode >> 21) & 0x3;
18389 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18390 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18391 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18392
18393 TCGv_i32 tdf = tcg_const_i32(df);
18394 TCGv_i32 twd = tcg_const_i32(wd);
18395 TCGv_i32 tws = tcg_const_i32(ws);
18396 TCGv_i32 twt = tcg_const_i32(wt);
18397
18398 switch (MASK_MSA_3R(ctx->opcode)) {
18399 case OPC_SLL_df:
18400 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18401 break;
18402 case OPC_ADDV_df:
18403 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18404 break;
18405 case OPC_CEQ_df:
18406 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18407 break;
18408 case OPC_ADD_A_df:
18409 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18410 break;
18411 case OPC_SUBS_S_df:
18412 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18413 break;
18414 case OPC_MULV_df:
18415 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18416 break;
18417 case OPC_SLD_df:
18418 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18419 break;
18420 case OPC_VSHF_df:
18421 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18422 break;
18423 case OPC_SRA_df:
18424 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18425 break;
18426 case OPC_SUBV_df:
18427 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18428 break;
18429 case OPC_ADDS_A_df:
18430 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18431 break;
18432 case OPC_SUBS_U_df:
18433 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18434 break;
18435 case OPC_MADDV_df:
18436 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18437 break;
18438 case OPC_SPLAT_df:
18439 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18440 break;
18441 case OPC_SRAR_df:
18442 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18443 break;
18444 case OPC_SRL_df:
18445 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18446 break;
18447 case OPC_MAX_S_df:
18448 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18449 break;
18450 case OPC_CLT_S_df:
18451 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18452 break;
18453 case OPC_ADDS_S_df:
18454 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18455 break;
18456 case OPC_SUBSUS_U_df:
18457 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18458 break;
18459 case OPC_MSUBV_df:
18460 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18461 break;
18462 case OPC_PCKEV_df:
18463 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18464 break;
18465 case OPC_SRLR_df:
18466 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18467 break;
18468 case OPC_BCLR_df:
18469 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18470 break;
18471 case OPC_MAX_U_df:
18472 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18473 break;
18474 case OPC_CLT_U_df:
18475 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18476 break;
18477 case OPC_ADDS_U_df:
18478 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18479 break;
18480 case OPC_SUBSUU_S_df:
18481 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18482 break;
18483 case OPC_PCKOD_df:
18484 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18485 break;
18486 case OPC_BSET_df:
18487 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18488 break;
18489 case OPC_MIN_S_df:
18490 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18491 break;
18492 case OPC_CLE_S_df:
18493 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18494 break;
18495 case OPC_AVE_S_df:
18496 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18497 break;
18498 case OPC_ASUB_S_df:
18499 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18500 break;
18501 case OPC_DIV_S_df:
18502 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18503 break;
18504 case OPC_ILVL_df:
18505 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18506 break;
18507 case OPC_BNEG_df:
18508 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18509 break;
18510 case OPC_MIN_U_df:
18511 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18512 break;
18513 case OPC_CLE_U_df:
18514 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18515 break;
18516 case OPC_AVE_U_df:
18517 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18518 break;
18519 case OPC_ASUB_U_df:
18520 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18521 break;
18522 case OPC_DIV_U_df:
18523 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18524 break;
18525 case OPC_ILVR_df:
18526 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18527 break;
18528 case OPC_BINSL_df:
18529 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18530 break;
18531 case OPC_MAX_A_df:
18532 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18533 break;
18534 case OPC_AVER_S_df:
18535 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18536 break;
18537 case OPC_MOD_S_df:
18538 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18539 break;
18540 case OPC_ILVEV_df:
18541 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18542 break;
18543 case OPC_BINSR_df:
18544 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18545 break;
18546 case OPC_MIN_A_df:
18547 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18548 break;
18549 case OPC_AVER_U_df:
18550 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18551 break;
18552 case OPC_MOD_U_df:
18553 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18554 break;
18555 case OPC_ILVOD_df:
18556 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18557 break;
18558
18559 case OPC_DOTP_S_df:
18560 case OPC_DOTP_U_df:
18561 case OPC_DPADD_S_df:
18562 case OPC_DPADD_U_df:
18563 case OPC_DPSUB_S_df:
18564 case OPC_HADD_S_df:
18565 case OPC_DPSUB_U_df:
18566 case OPC_HADD_U_df:
18567 case OPC_HSUB_S_df:
18568 case OPC_HSUB_U_df:
18569 if (df == DF_BYTE) {
9c708c7f
PD
18570 generate_exception_end(ctx, EXCP_RI);
18571 break;
28f99f08
YK
18572 }
18573 switch (MASK_MSA_3R(ctx->opcode)) {
18574 case OPC_DOTP_S_df:
18575 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18576 break;
18577 case OPC_DOTP_U_df:
18578 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18579 break;
18580 case OPC_DPADD_S_df:
18581 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18582 break;
18583 case OPC_DPADD_U_df:
18584 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18585 break;
18586 case OPC_DPSUB_S_df:
18587 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18588 break;
18589 case OPC_HADD_S_df:
18590 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18591 break;
18592 case OPC_DPSUB_U_df:
18593 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18594 break;
18595 case OPC_HADD_U_df:
18596 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18597 break;
18598 case OPC_HSUB_S_df:
18599 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18600 break;
18601 case OPC_HSUB_U_df:
18602 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18603 break;
18604 }
18605 break;
18606 default:
18607 MIPS_INVAL("MSA instruction");
9c708c7f 18608 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18609 break;
18610 }
18611 tcg_temp_free_i32(twd);
18612 tcg_temp_free_i32(tws);
18613 tcg_temp_free_i32(twt);
18614 tcg_temp_free_i32(tdf);
18615}
18616
1e608ec1
YK
18617static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18618{
18619#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18620 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18621 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18622 TCGv telm = tcg_temp_new();
18623 TCGv_i32 tsr = tcg_const_i32(source);
18624 TCGv_i32 tdt = tcg_const_i32(dest);
18625
18626 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18627 case OPC_CTCMSA:
18628 gen_load_gpr(telm, source);
18629 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18630 break;
18631 case OPC_CFCMSA:
18632 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18633 gen_store_gpr(telm, dest);
18634 break;
18635 case OPC_MOVE_V:
18636 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18637 break;
18638 default:
18639 MIPS_INVAL("MSA instruction");
9c708c7f 18640 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18641 break;
18642 }
18643
18644 tcg_temp_free(telm);
18645 tcg_temp_free_i32(tdt);
18646 tcg_temp_free_i32(tsr);
18647}
18648
18649static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18650 uint32_t n)
18651{
18652#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18653 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18654 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18655
18656 TCGv_i32 tws = tcg_const_i32(ws);
18657 TCGv_i32 twd = tcg_const_i32(wd);
18658 TCGv_i32 tn = tcg_const_i32(n);
18659 TCGv_i32 tdf = tcg_const_i32(df);
18660
18661 switch (MASK_MSA_ELM(ctx->opcode)) {
18662 case OPC_SLDI_df:
18663 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18664 break;
18665 case OPC_SPLATI_df:
18666 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18667 break;
18668 case OPC_INSVE_df:
18669 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18670 break;
18671 case OPC_COPY_S_df:
18672 case OPC_COPY_U_df:
18673 case OPC_INSERT_df:
18674#if !defined(TARGET_MIPS64)
18675 /* Double format valid only for MIPS64 */
18676 if (df == DF_DOUBLE) {
9c708c7f 18677 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18678 break;
18679 }
18680#endif
18681 switch (MASK_MSA_ELM(ctx->opcode)) {
18682 case OPC_COPY_S_df:
18683 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18684 break;
18685 case OPC_COPY_U_df:
18686 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18687 break;
18688 case OPC_INSERT_df:
18689 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18690 break;
18691 }
18692 break;
18693 default:
18694 MIPS_INVAL("MSA instruction");
9c708c7f 18695 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18696 }
18697 tcg_temp_free_i32(twd);
18698 tcg_temp_free_i32(tws);
18699 tcg_temp_free_i32(tn);
18700 tcg_temp_free_i32(tdf);
18701}
18702
18703static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18704{
18705 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18706 uint32_t df = 0, n = 0;
18707
18708 if ((dfn & 0x30) == 0x00) {
18709 n = dfn & 0x0f;
18710 df = DF_BYTE;
18711 } else if ((dfn & 0x38) == 0x20) {
18712 n = dfn & 0x07;
18713 df = DF_HALF;
18714 } else if ((dfn & 0x3c) == 0x30) {
18715 n = dfn & 0x03;
18716 df = DF_WORD;
18717 } else if ((dfn & 0x3e) == 0x38) {
18718 n = dfn & 0x01;
18719 df = DF_DOUBLE;
18720 } else if (dfn == 0x3E) {
18721 /* CTCMSA, CFCMSA, MOVE.V */
18722 gen_msa_elm_3e(env, ctx);
18723 return;
18724 } else {
9c708c7f 18725 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18726 return;
18727 }
18728
18729 gen_msa_elm_df(env, ctx, df, n);
18730}
18731
7d05b9c8
YK
18732static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18733{
18734#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18735 uint8_t df = (ctx->opcode >> 21) & 0x1;
18736 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18737 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18738 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18739
18740 TCGv_i32 twd = tcg_const_i32(wd);
18741 TCGv_i32 tws = tcg_const_i32(ws);
18742 TCGv_i32 twt = tcg_const_i32(wt);
18743 TCGv_i32 tdf = tcg_temp_new_i32();
18744
18745 /* adjust df value for floating-point instruction */
18746 tcg_gen_movi_i32(tdf, df + 2);
18747
18748 switch (MASK_MSA_3RF(ctx->opcode)) {
18749 case OPC_FCAF_df:
18750 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18751 break;
18752 case OPC_FADD_df:
18753 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18754 break;
18755 case OPC_FCUN_df:
18756 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18757 break;
18758 case OPC_FSUB_df:
18759 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18760 break;
18761 case OPC_FCOR_df:
18762 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18763 break;
18764 case OPC_FCEQ_df:
18765 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18766 break;
18767 case OPC_FMUL_df:
18768 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18769 break;
18770 case OPC_FCUNE_df:
18771 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18772 break;
18773 case OPC_FCUEQ_df:
18774 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18775 break;
18776 case OPC_FDIV_df:
18777 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18778 break;
18779 case OPC_FCNE_df:
18780 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18781 break;
18782 case OPC_FCLT_df:
18783 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18784 break;
18785 case OPC_FMADD_df:
18786 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18787 break;
18788 case OPC_MUL_Q_df:
18789 tcg_gen_movi_i32(tdf, df + 1);
18790 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18791 break;
18792 case OPC_FCULT_df:
18793 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18794 break;
18795 case OPC_FMSUB_df:
18796 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18797 break;
18798 case OPC_MADD_Q_df:
18799 tcg_gen_movi_i32(tdf, df + 1);
18800 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18801 break;
18802 case OPC_FCLE_df:
18803 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18804 break;
18805 case OPC_MSUB_Q_df:
18806 tcg_gen_movi_i32(tdf, df + 1);
18807 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18808 break;
18809 case OPC_FCULE_df:
18810 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18811 break;
18812 case OPC_FEXP2_df:
18813 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18814 break;
18815 case OPC_FSAF_df:
18816 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18817 break;
18818 case OPC_FEXDO_df:
18819 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18820 break;
18821 case OPC_FSUN_df:
18822 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18823 break;
18824 case OPC_FSOR_df:
18825 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18826 break;
18827 case OPC_FSEQ_df:
18828 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18829 break;
18830 case OPC_FTQ_df:
18831 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18832 break;
18833 case OPC_FSUNE_df:
18834 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18835 break;
18836 case OPC_FSUEQ_df:
18837 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18838 break;
18839 case OPC_FSNE_df:
18840 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18841 break;
18842 case OPC_FSLT_df:
18843 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18844 break;
18845 case OPC_FMIN_df:
18846 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18847 break;
18848 case OPC_MULR_Q_df:
18849 tcg_gen_movi_i32(tdf, df + 1);
18850 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18851 break;
18852 case OPC_FSULT_df:
18853 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18854 break;
18855 case OPC_FMIN_A_df:
18856 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18857 break;
18858 case OPC_MADDR_Q_df:
18859 tcg_gen_movi_i32(tdf, df + 1);
18860 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18861 break;
18862 case OPC_FSLE_df:
18863 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18864 break;
18865 case OPC_FMAX_df:
18866 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18867 break;
18868 case OPC_MSUBR_Q_df:
18869 tcg_gen_movi_i32(tdf, df + 1);
18870 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18871 break;
18872 case OPC_FSULE_df:
18873 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18874 break;
18875 case OPC_FMAX_A_df:
18876 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18877 break;
18878 default:
18879 MIPS_INVAL("MSA instruction");
9c708c7f 18880 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
18881 break;
18882 }
18883
18884 tcg_temp_free_i32(twd);
18885 tcg_temp_free_i32(tws);
18886 tcg_temp_free_i32(twt);
18887 tcg_temp_free_i32(tdf);
18888}
18889
cbe50b9a
YK
18890static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18891{
18892#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18893 (op & (0x7 << 18)))
18894 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18895 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18896 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18897 uint8_t df = (ctx->opcode >> 16) & 0x3;
18898 TCGv_i32 twd = tcg_const_i32(wd);
18899 TCGv_i32 tws = tcg_const_i32(ws);
18900 TCGv_i32 twt = tcg_const_i32(wt);
18901 TCGv_i32 tdf = tcg_const_i32(df);
18902
18903 switch (MASK_MSA_2R(ctx->opcode)) {
18904 case OPC_FILL_df:
18905#if !defined(TARGET_MIPS64)
18906 /* Double format valid only for MIPS64 */
18907 if (df == DF_DOUBLE) {
9c708c7f 18908 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18909 break;
18910 }
18911#endif
18912 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18913 break;
18914 case OPC_PCNT_df:
18915 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18916 break;
18917 case OPC_NLOC_df:
18918 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18919 break;
18920 case OPC_NLZC_df:
18921 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18922 break;
18923 default:
18924 MIPS_INVAL("MSA instruction");
9c708c7f 18925 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18926 break;
18927 }
18928
18929 tcg_temp_free_i32(twd);
18930 tcg_temp_free_i32(tws);
18931 tcg_temp_free_i32(twt);
18932 tcg_temp_free_i32(tdf);
18933}
18934
3bdeb688
YK
18935static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18936{
18937#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18938 (op & (0xf << 17)))
18939 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18940 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18941 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18942 uint8_t df = (ctx->opcode >> 16) & 0x1;
18943 TCGv_i32 twd = tcg_const_i32(wd);
18944 TCGv_i32 tws = tcg_const_i32(ws);
18945 TCGv_i32 twt = tcg_const_i32(wt);
18946 /* adjust df value for floating-point instruction */
18947 TCGv_i32 tdf = tcg_const_i32(df + 2);
18948
18949 switch (MASK_MSA_2RF(ctx->opcode)) {
18950 case OPC_FCLASS_df:
18951 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18952 break;
18953 case OPC_FTRUNC_S_df:
18954 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18955 break;
18956 case OPC_FTRUNC_U_df:
18957 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18958 break;
18959 case OPC_FSQRT_df:
18960 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18961 break;
18962 case OPC_FRSQRT_df:
18963 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18964 break;
18965 case OPC_FRCP_df:
18966 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18967 break;
18968 case OPC_FRINT_df:
18969 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18970 break;
18971 case OPC_FLOG2_df:
18972 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18973 break;
18974 case OPC_FEXUPL_df:
18975 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18976 break;
18977 case OPC_FEXUPR_df:
18978 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18979 break;
18980 case OPC_FFQL_df:
18981 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18982 break;
18983 case OPC_FFQR_df:
18984 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18985 break;
18986 case OPC_FTINT_S_df:
18987 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18988 break;
18989 case OPC_FTINT_U_df:
18990 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18991 break;
18992 case OPC_FFINT_S_df:
18993 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18994 break;
18995 case OPC_FFINT_U_df:
18996 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18997 break;
18998 }
18999
19000 tcg_temp_free_i32(twd);
19001 tcg_temp_free_i32(tws);
19002 tcg_temp_free_i32(twt);
19003 tcg_temp_free_i32(tdf);
19004}
19005
cbe50b9a
YK
19006static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19007{
19008#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19009 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19010 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19011 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19012 TCGv_i32 twd = tcg_const_i32(wd);
19013 TCGv_i32 tws = tcg_const_i32(ws);
19014 TCGv_i32 twt = tcg_const_i32(wt);
19015
19016 switch (MASK_MSA_VEC(ctx->opcode)) {
19017 case OPC_AND_V:
19018 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19019 break;
19020 case OPC_OR_V:
19021 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19022 break;
19023 case OPC_NOR_V:
19024 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19025 break;
19026 case OPC_XOR_V:
19027 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19028 break;
19029 case OPC_BMNZ_V:
19030 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19031 break;
19032 case OPC_BMZ_V:
19033 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19034 break;
19035 case OPC_BSEL_V:
19036 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19037 break;
19038 default:
19039 MIPS_INVAL("MSA instruction");
9c708c7f 19040 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19041 break;
19042 }
19043
19044 tcg_temp_free_i32(twd);
19045 tcg_temp_free_i32(tws);
19046 tcg_temp_free_i32(twt);
19047}
19048
19049static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19050{
19051 switch (MASK_MSA_VEC(ctx->opcode)) {
19052 case OPC_AND_V:
19053 case OPC_OR_V:
19054 case OPC_NOR_V:
19055 case OPC_XOR_V:
19056 case OPC_BMNZ_V:
19057 case OPC_BMZ_V:
19058 case OPC_BSEL_V:
19059 gen_msa_vec_v(env, ctx);
19060 break;
19061 case OPC_MSA_2R:
19062 gen_msa_2r(env, ctx);
19063 break;
3bdeb688
YK
19064 case OPC_MSA_2RF:
19065 gen_msa_2rf(env, ctx);
19066 break;
cbe50b9a
YK
19067 default:
19068 MIPS_INVAL("MSA instruction");
9c708c7f 19069 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19070 break;
19071 }
19072}
19073
4c789546
YK
19074static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19075{
19076 uint32_t opcode = ctx->opcode;
19077 check_insn(ctx, ASE_MSA);
19078 check_msa_access(ctx);
19079
19080 switch (MASK_MSA_MINOR(opcode)) {
19081 case OPC_MSA_I8_00:
19082 case OPC_MSA_I8_01:
19083 case OPC_MSA_I8_02:
19084 gen_msa_i8(env, ctx);
19085 break;
80e71591
YK
19086 case OPC_MSA_I5_06:
19087 case OPC_MSA_I5_07:
19088 gen_msa_i5(env, ctx);
19089 break;
d4cf28de
YK
19090 case OPC_MSA_BIT_09:
19091 case OPC_MSA_BIT_0A:
19092 gen_msa_bit(env, ctx);
19093 break;
28f99f08
YK
19094 case OPC_MSA_3R_0D:
19095 case OPC_MSA_3R_0E:
19096 case OPC_MSA_3R_0F:
19097 case OPC_MSA_3R_10:
19098 case OPC_MSA_3R_11:
19099 case OPC_MSA_3R_12:
19100 case OPC_MSA_3R_13:
19101 case OPC_MSA_3R_14:
19102 case OPC_MSA_3R_15:
19103 gen_msa_3r(env, ctx);
19104 break;
1e608ec1
YK
19105 case OPC_MSA_ELM:
19106 gen_msa_elm(env, ctx);
19107 break;
7d05b9c8
YK
19108 case OPC_MSA_3RF_1A:
19109 case OPC_MSA_3RF_1B:
19110 case OPC_MSA_3RF_1C:
19111 gen_msa_3rf(env, ctx);
19112 break;
cbe50b9a
YK
19113 case OPC_MSA_VEC:
19114 gen_msa_vec(env, ctx);
19115 break;
f7685877
YK
19116 case OPC_LD_B:
19117 case OPC_LD_H:
19118 case OPC_LD_W:
19119 case OPC_LD_D:
19120 case OPC_ST_B:
19121 case OPC_ST_H:
19122 case OPC_ST_W:
19123 case OPC_ST_D:
19124 {
19125 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19126 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19127 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19128 uint8_t df = (ctx->opcode >> 0) & 0x3;
19129
f7685877 19130 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19131 TCGv taddr = tcg_temp_new();
19132 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19133
19134 switch (MASK_MSA_MINOR(opcode)) {
19135 case OPC_LD_B:
adc370a4
YK
19136 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19137 break;
f7685877 19138 case OPC_LD_H:
adc370a4
YK
19139 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19140 break;
f7685877 19141 case OPC_LD_W:
adc370a4
YK
19142 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19143 break;
f7685877 19144 case OPC_LD_D:
adc370a4 19145 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19146 break;
19147 case OPC_ST_B:
adc370a4
YK
19148 gen_helper_msa_st_b(cpu_env, twd, taddr);
19149 break;
f7685877 19150 case OPC_ST_H:
adc370a4
YK
19151 gen_helper_msa_st_h(cpu_env, twd, taddr);
19152 break;
f7685877 19153 case OPC_ST_W:
adc370a4
YK
19154 gen_helper_msa_st_w(cpu_env, twd, taddr);
19155 break;
f7685877 19156 case OPC_ST_D:
adc370a4 19157 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19158 break;
19159 }
19160
19161 tcg_temp_free_i32(twd);
adc370a4 19162 tcg_temp_free(taddr);
f7685877
YK
19163 }
19164 break;
4c789546
YK
19165 default:
19166 MIPS_INVAL("MSA instruction");
9c708c7f 19167 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19168 break;
19169 }
19170
19171}
19172
d2bfa6e6 19173static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19174{
19175 int32_t offset;
19176 int rs, rt, rd, sa;
19177 uint32_t op, op1;
19178 int16_t imm;
19179
19180 /* make sure instructions are on a word boundary */
19181 if (ctx->pc & 0x3) {
19182 env->CP0_BadVAddr = ctx->pc;
aea14095 19183 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19184 return;
19185 }
19186
19187 /* Handle blikely not taken case */
19188 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19189 TCGLabel *l1 = gen_new_label();
099e5b4d 19190
099e5b4d
LA
19191 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19192 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19193 gen_goto_tb(ctx, 1, ctx->pc + 4);
19194 gen_set_label(l1);
19195 }
19196
099e5b4d
LA
19197 op = MASK_OP_MAJOR(ctx->opcode);
19198 rs = (ctx->opcode >> 21) & 0x1f;
19199 rt = (ctx->opcode >> 16) & 0x1f;
19200 rd = (ctx->opcode >> 11) & 0x1f;
19201 sa = (ctx->opcode >> 6) & 0x1f;
19202 imm = (int16_t)ctx->opcode;
19203 switch (op) {
19204 case OPC_SPECIAL:
19205 decode_opc_special(env, ctx);
19206 break;
19207 case OPC_SPECIAL2:
4267d3e6 19208 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19209 break;
19210 case OPC_SPECIAL3:
19211 decode_opc_special3(env, ctx);
19212 break;
7a387fff
TS
19213 case OPC_REGIMM:
19214 op1 = MASK_REGIMM(ctx->opcode);
19215 switch (op1) {
fecd2646
LA
19216 case OPC_BLTZL: /* REGIMM branches */
19217 case OPC_BGEZL:
19218 case OPC_BLTZALL:
19219 case OPC_BGEZALL:
d9224450 19220 check_insn(ctx, ISA_MIPS2);
fecd2646 19221 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19222 /* Fallthrough */
fecd2646
LA
19223 case OPC_BLTZ:
19224 case OPC_BGEZ:
b231c103 19225 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19226 break;
fecd2646
LA
19227 case OPC_BLTZAL:
19228 case OPC_BGEZAL:
0aefa333
YK
19229 if (ctx->insn_flags & ISA_MIPS32R6) {
19230 if (rs == 0) {
19231 /* OPC_NAL, OPC_BAL */
b231c103 19232 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19233 } else {
9c708c7f 19234 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19235 }
19236 } else {
b231c103 19237 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19238 }
c9602061 19239 break;
7a387fff
TS
19240 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19241 case OPC_TNEI:
d9224450 19242 check_insn(ctx, ISA_MIPS2);
fecd2646 19243 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19244 gen_trap(ctx, op1, rs, -1, imm);
19245 break;
bb238210
YK
19246 case OPC_SIGRIE:
19247 check_insn(ctx, ISA_MIPS32R6);
19248 generate_exception_end(ctx, EXCP_RI);
19249 break;
7a387fff 19250 case OPC_SYNCI:
d75c135e 19251 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19252 /* Break the TB to be able to sync copied instructions
19253 immediately */
19254 ctx->bstate = BS_STOP;
6af0bf9c 19255 break;
e45a93e2
JL
19256 case OPC_BPOSGE32: /* MIPS DSP branch */
19257#if defined(TARGET_MIPS64)
19258 case OPC_BPOSGE64:
19259#endif
19260 check_dsp(ctx);
b231c103 19261 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19262 break;
d4ea6acd
LA
19263#if defined(TARGET_MIPS64)
19264 case OPC_DAHI:
19265 check_insn(ctx, ISA_MIPS32R6);
19266 check_mips_64(ctx);
19267 if (rs != 0) {
19268 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19269 }
d4ea6acd
LA
19270 break;
19271 case OPC_DATI:
19272 check_insn(ctx, ISA_MIPS32R6);
19273 check_mips_64(ctx);
19274 if (rs != 0) {
19275 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19276 }
d4ea6acd
LA
19277 break;
19278#endif
6af0bf9c 19279 default: /* Invalid */
923617a3 19280 MIPS_INVAL("regimm");
9c708c7f 19281 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19282 break;
19283 }
19284 break;
7a387fff 19285 case OPC_CP0:
387a8fe5 19286 check_cp0_enabled(ctx);
7a387fff 19287 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19288 switch (op1) {
7a387fff
TS
19289 case OPC_MFC0:
19290 case OPC_MTC0:
ead9360e
TS
19291 case OPC_MFTR:
19292 case OPC_MTTR:
5204ea79
LA
19293 case OPC_MFHC0:
19294 case OPC_MTHC0:
d26bc211 19295#if defined(TARGET_MIPS64)
7a387fff
TS
19296 case OPC_DMFC0:
19297 case OPC_DMTC0:
19298#endif
f1aa6320 19299#ifndef CONFIG_USER_ONLY
932e71cd 19300 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19301#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19302 break;
19303 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19304#ifndef CONFIG_USER_ONLY
932e71cd 19305 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19306#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19307 break;
19308 case OPC_MFMC0:
8706c382 19309#ifndef CONFIG_USER_ONLY
932e71cd 19310 {
099e5b4d 19311 uint32_t op2;
35fbce2c 19312 TCGv t0 = tcg_temp_new();
6c5c1e20 19313
0eaef5aa 19314 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19315 switch (op2) {
19316 case OPC_DMT:
d75c135e 19317 check_insn(ctx, ASE_MT);
9ed5726c 19318 gen_helper_dmt(t0);
35fbce2c 19319 gen_store_gpr(t0, rt);
6c5c1e20
TS
19320 break;
19321 case OPC_EMT:
d75c135e 19322 check_insn(ctx, ASE_MT);
9ed5726c 19323 gen_helper_emt(t0);
35fbce2c 19324 gen_store_gpr(t0, rt);
da80682b 19325 break;
6c5c1e20 19326 case OPC_DVPE:
d75c135e 19327 check_insn(ctx, ASE_MT);
895c2d04 19328 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19329 gen_store_gpr(t0, rt);
6c5c1e20
TS
19330 break;
19331 case OPC_EVPE:
d75c135e 19332 check_insn(ctx, ASE_MT);
895c2d04 19333 gen_helper_evpe(t0, cpu_env);
35fbce2c 19334 gen_store_gpr(t0, rt);
6c5c1e20 19335 break;
01bc435b
YK
19336 case OPC_DVP:
19337 check_insn(ctx, ISA_MIPS32R6);
19338 if (ctx->vp) {
19339 gen_helper_dvp(t0, cpu_env);
19340 gen_store_gpr(t0, rt);
19341 }
19342 break;
19343 case OPC_EVP:
19344 check_insn(ctx, ISA_MIPS32R6);
19345 if (ctx->vp) {
19346 gen_helper_evp(t0, cpu_env);
19347 gen_store_gpr(t0, rt);
19348 }
19349 break;
6c5c1e20 19350 case OPC_DI:
d75c135e 19351 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19352 save_cpu_state(ctx, 1);
895c2d04 19353 gen_helper_di(t0, cpu_env);
35fbce2c 19354 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19355 /* Stop translation as we may have switched
19356 the execution mode. */
6c5c1e20
TS
19357 ctx->bstate = BS_STOP;
19358 break;
19359 case OPC_EI:
d75c135e 19360 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19361 save_cpu_state(ctx, 1);
895c2d04 19362 gen_helper_ei(t0, cpu_env);
35fbce2c 19363 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19364 /* Stop translation as we may have switched
19365 the execution mode. */
6c5c1e20
TS
19366 ctx->bstate = BS_STOP;
19367 break;
19368 default: /* Invalid */
19369 MIPS_INVAL("mfmc0");
9c708c7f 19370 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19371 break;
19372 }
6c5c1e20 19373 tcg_temp_free(t0);
7a387fff 19374 }
0eaef5aa 19375#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19376 break;
7a387fff 19377 case OPC_RDPGPR:
d75c135e 19378 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19379 gen_load_srsgpr(rt, rd);
ead9360e 19380 break;
7a387fff 19381 case OPC_WRPGPR:
d75c135e 19382 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19383 gen_store_srsgpr(rt, rd);
38121543 19384 break;
6af0bf9c 19385 default:
923617a3 19386 MIPS_INVAL("cp0");
9c708c7f 19387 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19388 break;
19389 }
19390 break;
31837be3
YK
19391 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19392 if (ctx->insn_flags & ISA_MIPS32R6) {
19393 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19394 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19395 } else {
19396 /* OPC_ADDI */
19397 /* Arithmetic with immediate opcode */
19398 gen_arith_imm(ctx, op, rt, rs, imm);
19399 }
19400 break;
324d9e32 19401 case OPC_ADDIU:
d75c135e 19402 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19403 break;
324d9e32
AJ
19404 case OPC_SLTI: /* Set on less than with immediate opcode */
19405 case OPC_SLTIU:
d75c135e 19406 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19407 break;
19408 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19409 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19410 case OPC_ORI:
19411 case OPC_XORI:
d75c135e 19412 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19413 break;
7a387fff
TS
19414 case OPC_J ... OPC_JAL: /* Jump */
19415 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19416 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19417 break;
31837be3
YK
19418 /* Branch */
19419 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19420 if (ctx->insn_flags & ISA_MIPS32R6) {
19421 if (rt == 0) {
9c708c7f 19422 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19423 break;
19424 }
19425 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19426 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19427 } else {
19428 /* OPC_BLEZL */
b231c103 19429 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19430 }
19431 break;
19432 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19433 if (ctx->insn_flags & ISA_MIPS32R6) {
19434 if (rt == 0) {
9c708c7f 19435 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19436 break;
19437 }
19438 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19439 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19440 } else {
19441 /* OPC_BGTZL */
b231c103 19442 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19443 }
19444 break;
19445 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19446 if (rt == 0) {
19447 /* OPC_BLEZ */
b231c103 19448 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19449 } else {
19450 check_insn(ctx, ISA_MIPS32R6);
19451 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19452 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19453 }
19454 break;
19455 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19456 if (rt == 0) {
19457 /* OPC_BGTZ */
b231c103 19458 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19459 } else {
19460 check_insn(ctx, ISA_MIPS32R6);
19461 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19462 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19463 }
19464 break;
19465 case OPC_BEQL:
19466 case OPC_BNEL:
d9224450 19467 check_insn(ctx, ISA_MIPS2);
fecd2646 19468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19469 /* Fallthrough */
31837be3
YK
19470 case OPC_BEQ:
19471 case OPC_BNE:
b231c103 19472 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19473 break;
d9224450
MR
19474 case OPC_LL: /* Load and stores */
19475 check_insn(ctx, ISA_MIPS2);
19476 /* Fallthrough */
19477 case OPC_LWL:
fecd2646
LA
19478 case OPC_LWR:
19479 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19480 /* Fallthrough */
fecd2646
LA
19481 case OPC_LB ... OPC_LH:
19482 case OPC_LW ... OPC_LHU:
d75c135e 19483 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19484 break;
fecd2646 19485 case OPC_SWL:
7a387fff 19486 case OPC_SWR:
fecd2646 19487 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19488 /* fall through */
fecd2646
LA
19489 case OPC_SB ... OPC_SH:
19490 case OPC_SW:
5c13fdfd 19491 gen_st(ctx, op, rt, rs, imm);
7a387fff 19492 break;
d66c7132 19493 case OPC_SC:
d9224450 19494 check_insn(ctx, ISA_MIPS2);
4368b29a 19495 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19496 gen_st_cond(ctx, op, rt, rs, imm);
19497 break;
7a387fff 19498 case OPC_CACHE:
bf7910c6 19499 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19500 check_cp0_enabled(ctx);
d75c135e 19501 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
19502 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19503 gen_cache_operation(ctx, rt, rs, imm);
19504 }
ead9360e 19505 /* Treat as NOP. */
34ae7b51 19506 break;
7a387fff 19507 case OPC_PREF:
bf7910c6 19508 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19509 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19510 /* Treat as NOP. */
6af0bf9c 19511 break;
4ad40f36 19512
923617a3 19513 /* Floating point (COP1). */
7a387fff
TS
19514 case OPC_LWC1:
19515 case OPC_LDC1:
19516 case OPC_SWC1:
19517 case OPC_SDC1:
5ab5c041 19518 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19519 break;
19520
7a387fff 19521 case OPC_CP1:
5692c6e1
YK
19522 op1 = MASK_CP1(ctx->opcode);
19523
19524 switch (op1) {
19525 case OPC_MFHC1:
19526 case OPC_MTHC1:
5e755519 19527 check_cp1_enabled(ctx);
5692c6e1
YK
19528 check_insn(ctx, ISA_MIPS32R2);
19529 case OPC_MFC1:
19530 case OPC_CFC1:
19531 case OPC_MTC1:
19532 case OPC_CTC1:
19533 check_cp1_enabled(ctx);
19534 gen_cp1(ctx, op1, rt, rd);
19535 break;
d26bc211 19536#if defined(TARGET_MIPS64)
5692c6e1
YK
19537 case OPC_DMFC1:
19538 case OPC_DMTC1:
19539 check_cp1_enabled(ctx);
19540 check_insn(ctx, ISA_MIPS3);
d9224450 19541 check_mips_64(ctx);
5692c6e1
YK
19542 gen_cp1(ctx, op1, rt, rd);
19543 break;
e189e748 19544#endif
5692c6e1
YK
19545 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19546 check_cp1_enabled(ctx);
19547 if (ctx->insn_flags & ISA_MIPS32R6) {
19548 /* OPC_BC1EQZ */
31837be3 19549 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19550 rt, imm << 2, 4);
5692c6e1
YK
19551 } else {
19552 /* OPC_BC1ANY2 */
b8aa4598 19553 check_cop1x(ctx);
d75c135e 19554 check_insn(ctx, ASE_MIPS3D);
d75c135e 19555 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19556 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19557 }
19558 break;
19559 case OPC_BC1NEZ:
19560 check_cp1_enabled(ctx);
19561 check_insn(ctx, ISA_MIPS32R6);
19562 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19563 rt, imm << 2, 4);
5692c6e1
YK
19564 break;
19565 case OPC_BC1ANY4:
19566 check_cp1_enabled(ctx);
19567 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19568 check_cop1x(ctx);
19569 check_insn(ctx, ASE_MIPS3D);
19570 /* fall through */
19571 case OPC_BC1:
19572 check_cp1_enabled(ctx);
19573 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19574 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19575 (rt >> 2) & 0x7, imm << 2);
19576 break;
19577 case OPC_PS_FMT:
e29c9628 19578 check_ps(ctx);
b6f3b233 19579 /* fall through */
5692c6e1
YK
19580 case OPC_S_FMT:
19581 case OPC_D_FMT:
19582 check_cp1_enabled(ctx);
19583 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19584 (imm >> 8) & 0x7);
19585 break;
19586 case OPC_W_FMT:
19587 case OPC_L_FMT:
19588 {
19589 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19590 check_cp1_enabled(ctx);
19591 if (ctx->insn_flags & ISA_MIPS32R6) {
19592 switch (r6_op) {
19593 case R6_OPC_CMP_AF_S:
19594 case R6_OPC_CMP_UN_S:
19595 case R6_OPC_CMP_EQ_S:
19596 case R6_OPC_CMP_UEQ_S:
19597 case R6_OPC_CMP_LT_S:
19598 case R6_OPC_CMP_ULT_S:
19599 case R6_OPC_CMP_LE_S:
19600 case R6_OPC_CMP_ULE_S:
19601 case R6_OPC_CMP_SAF_S:
19602 case R6_OPC_CMP_SUN_S:
19603 case R6_OPC_CMP_SEQ_S:
19604 case R6_OPC_CMP_SEUQ_S:
19605 case R6_OPC_CMP_SLT_S:
19606 case R6_OPC_CMP_SULT_S:
19607 case R6_OPC_CMP_SLE_S:
19608 case R6_OPC_CMP_SULE_S:
19609 case R6_OPC_CMP_OR_S:
19610 case R6_OPC_CMP_UNE_S:
19611 case R6_OPC_CMP_NE_S:
19612 case R6_OPC_CMP_SOR_S:
19613 case R6_OPC_CMP_SUNE_S:
19614 case R6_OPC_CMP_SNE_S:
19615 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19616 break;
19617 case R6_OPC_CMP_AF_D:
19618 case R6_OPC_CMP_UN_D:
19619 case R6_OPC_CMP_EQ_D:
19620 case R6_OPC_CMP_UEQ_D:
19621 case R6_OPC_CMP_LT_D:
19622 case R6_OPC_CMP_ULT_D:
19623 case R6_OPC_CMP_LE_D:
19624 case R6_OPC_CMP_ULE_D:
19625 case R6_OPC_CMP_SAF_D:
19626 case R6_OPC_CMP_SUN_D:
19627 case R6_OPC_CMP_SEQ_D:
19628 case R6_OPC_CMP_SEUQ_D:
19629 case R6_OPC_CMP_SLT_D:
19630 case R6_OPC_CMP_SULT_D:
19631 case R6_OPC_CMP_SLE_D:
19632 case R6_OPC_CMP_SULE_D:
19633 case R6_OPC_CMP_OR_D:
19634 case R6_OPC_CMP_UNE_D:
19635 case R6_OPC_CMP_NE_D:
19636 case R6_OPC_CMP_SOR_D:
19637 case R6_OPC_CMP_SUNE_D:
19638 case R6_OPC_CMP_SNE_D:
19639 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19640 break;
19641 default:
d2bfa6e6
MR
19642 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19643 rt, rd, sa, (imm >> 8) & 0x7);
19644
5692c6e1 19645 break;
3f493883 19646 }
5692c6e1
YK
19647 } else {
19648 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19649 (imm >> 8) & 0x7);
36d23958 19650 }
5692c6e1
YK
19651 break;
19652 }
19653 case OPC_BZ_V:
19654 case OPC_BNZ_V:
19655 case OPC_BZ_B:
19656 case OPC_BZ_H:
19657 case OPC_BZ_W:
19658 case OPC_BZ_D:
19659 case OPC_BNZ_B:
19660 case OPC_BNZ_H:
19661 case OPC_BNZ_W:
19662 case OPC_BNZ_D:
19663 check_insn(ctx, ASE_MSA);
19664 gen_msa_branch(env, ctx, op1);
19665 break;
19666 default:
19667 MIPS_INVAL("cp1");
9c708c7f 19668 generate_exception_end(ctx, EXCP_RI);
5692c6e1 19669 break;
6ea83fed 19670 }
4ad40f36
FB
19671 break;
19672
31837be3
YK
19673 /* Compact branches [R6] and COP2 [non-R6] */
19674 case OPC_BC: /* OPC_LWC2 */
19675 case OPC_BALC: /* OPC_SWC2 */
19676 if (ctx->insn_flags & ISA_MIPS32R6) {
19677 /* OPC_BC, OPC_BALC */
19678 gen_compute_compact_branch(ctx, op, 0, 0,
19679 sextract32(ctx->opcode << 2, 0, 28));
19680 } else {
19681 /* OPC_LWC2, OPC_SWC2 */
19682 /* COP2: Not implemented. */
19683 generate_exception_err(ctx, EXCP_CpU, 2);
19684 }
19685 break;
19686 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19687 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19688 if (ctx->insn_flags & ISA_MIPS32R6) {
19689 if (rs != 0) {
19690 /* OPC_BEQZC, OPC_BNEZC */
19691 gen_compute_compact_branch(ctx, op, rs, 0,
19692 sextract32(ctx->opcode << 2, 0, 23));
19693 } else {
19694 /* OPC_JIC, OPC_JIALC */
19695 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19696 }
19697 } else {
19698 /* OPC_LWC2, OPC_SWC2 */
19699 /* COP2: Not implemented. */
19700 generate_exception_err(ctx, EXCP_CpU, 2);
19701 }
4ad40f36 19702 break;
bd277fa1 19703 case OPC_CP2:
d75c135e 19704 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19705 /* Note that these instructions use different fields. */
19706 gen_loongson_multimedia(ctx, sa, rd, rt);
19707 break;
4ad40f36 19708
7a387fff 19709 case OPC_CP3:
fecd2646 19710 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19711 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19712 check_cp1_enabled(ctx);
36d23958
TS
19713 op1 = MASK_CP3(ctx->opcode);
19714 switch (op1) {
d9224450
MR
19715 case OPC_LUXC1:
19716 case OPC_SUXC1:
19717 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19718 /* Fallthrough */
5a5012ec
TS
19719 case OPC_LWXC1:
19720 case OPC_LDXC1:
5a5012ec
TS
19721 case OPC_SWXC1:
19722 case OPC_SDXC1:
d9224450 19723 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19724 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19725 break;
e0c84da7 19726 case OPC_PREFX:
d9224450 19727 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19728 /* Treat as NOP. */
e0c84da7 19729 break;
5a5012ec 19730 case OPC_ALNV_PS:
d9224450
MR
19731 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19732 /* Fallthrough */
5a5012ec
TS
19733 case OPC_MADD_S:
19734 case OPC_MADD_D:
19735 case OPC_MADD_PS:
19736 case OPC_MSUB_S:
19737 case OPC_MSUB_D:
19738 case OPC_MSUB_PS:
19739 case OPC_NMADD_S:
19740 case OPC_NMADD_D:
19741 case OPC_NMADD_PS:
19742 case OPC_NMSUB_S:
19743 case OPC_NMSUB_D:
19744 case OPC_NMSUB_PS:
d9224450 19745 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19746 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19747 break;
36d23958 19748 default:
923617a3 19749 MIPS_INVAL("cp3");
9c708c7f 19750 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
19751 break;
19752 }
19753 } else {
e397ee33 19754 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19755 }
4ad40f36
FB
19756 break;
19757
d26bc211 19758#if defined(TARGET_MIPS64)
7a387fff 19759 /* MIPS64 opcodes */
7a387fff 19760 case OPC_LDL ... OPC_LDR:
bf7910c6 19761 case OPC_LLD:
fecd2646 19762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19763 /* fall through */
fecd2646 19764 case OPC_LWU:
7a387fff 19765 case OPC_LD:
d75c135e 19766 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19767 check_mips_64(ctx);
d75c135e 19768 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19769 break;
19770 case OPC_SDL ... OPC_SDR:
fecd2646 19771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19772 /* fall through */
7a387fff 19773 case OPC_SD:
d75c135e 19774 check_insn(ctx, ISA_MIPS3);
e189e748 19775 check_mips_64(ctx);
5c13fdfd 19776 gen_st(ctx, op, rt, rs, imm);
7a387fff 19777 break;
d66c7132 19778 case OPC_SCD:
bf7910c6 19779 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19780 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19781 check_mips_64(ctx);
19782 gen_st_cond(ctx, op, rt, rs, imm);
19783 break;
31837be3
YK
19784 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19785 if (ctx->insn_flags & ISA_MIPS32R6) {
19786 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19787 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19788 } else {
19789 /* OPC_DADDI */
19790 check_insn(ctx, ISA_MIPS3);
19791 check_mips_64(ctx);
19792 gen_arith_imm(ctx, op, rt, rs, imm);
19793 }
19794 break;
324d9e32 19795 case OPC_DADDIU:
d75c135e 19796 check_insn(ctx, ISA_MIPS3);
e189e748 19797 check_mips_64(ctx);
d75c135e 19798 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19799 break;
31837be3
YK
19800#else
19801 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19802 if (ctx->insn_flags & ISA_MIPS32R6) {
19803 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19804 } else {
19805 MIPS_INVAL("major opcode");
9c708c7f 19806 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19807 }
19808 break;
6af0bf9c 19809#endif
d4ea6acd
LA
19810 case OPC_DAUI: /* OPC_JALX */
19811 if (ctx->insn_flags & ISA_MIPS32R6) {
19812#if defined(TARGET_MIPS64)
19813 /* OPC_DAUI */
19814 check_mips_64(ctx);
db77d852
LA
19815 if (rs == 0) {
19816 generate_exception(ctx, EXCP_RI);
19817 } else if (rt != 0) {
d4ea6acd
LA
19818 TCGv t0 = tcg_temp_new();
19819 gen_load_gpr(t0, rs);
19820 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19821 tcg_temp_free(t0);
19822 }
d4ea6acd 19823#else
9c708c7f 19824 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
19825 MIPS_INVAL("major opcode");
19826#endif
19827 } else {
19828 /* OPC_JALX */
19829 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19830 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19831 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19832 }
364d4831 19833 break;
4c789546 19834 case OPC_MSA: /* OPC_MDMX */
7a387fff 19835 /* MDMX: Not implemented. */
4c789546 19836 gen_msa(env, ctx);
d4ea6acd
LA
19837 break;
19838 case OPC_PCREL:
19839 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19840 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19841 break;
6af0bf9c 19842 default: /* Invalid */
923617a3 19843 MIPS_INVAL("major opcode");
9c708c7f 19844 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19845 break;
19846 }
6af0bf9c
FB
19847}
19848
4e5e1215 19849void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19850{
4e5e1215 19851 MIPSCPU *cpu = mips_env_get_cpu(env);
ed2803da 19852 CPUState *cs = CPU(cpu);
278d0702 19853 DisasContext ctx;
6af0bf9c 19854 target_ulong pc_start;
fe237291 19855 target_ulong next_page_start;
2e70f6ef
PB
19856 int num_insns;
19857 int max_insns;
c9602061 19858 int insn_bytes;
339cd2a8 19859 int is_slot;
6af0bf9c
FB
19860
19861 pc_start = tb->pc;
fe237291 19862 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19863 ctx.pc = pc_start;
4ad40f36 19864 ctx.saved_pc = -1;
ed2803da 19865 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19866 ctx.insn_flags = env->insn_flags;
5ab5c041 19867 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19868 ctx.tb = tb;
19869 ctx.bstate = BS_NONE;
c20d594e 19870 ctx.btarget = 0;
e98c0d17 19871 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19872 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19873 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19874 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19875 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19876 ctx.PAMask = env->PAMask;
19877 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19878 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
c870e3f5 19879 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 19880 /* Restore delay slot state from the tb context. */
c068688b 19881 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19882 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19883 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19884 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 19885 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
f6d4dd81 19886 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
87552089 19887 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
6be77480 19888 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
fd4a04eb 19889 restore_cpu_state(env, &ctx);
932e71cd 19890#ifdef CONFIG_USER_ONLY
0eaef5aa 19891 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19892#else
0eaef5aa 19893 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19894#endif
be3a8c53
YK
19895 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19896 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19897 num_insns = 0;
19898 max_insns = tb->cflags & CF_COUNT_MASK;
190ce7fb 19899 if (max_insns == 0) {
2e70f6ef 19900 max_insns = CF_COUNT_MASK;
190ce7fb
RH
19901 }
19902 if (max_insns > TCG_MAX_INSNS) {
19903 max_insns = TCG_MAX_INSNS;
19904 }
19905
d12d51d5 19906 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19907 gen_tb_start(tb);
faf7aaa9 19908 while (ctx.bstate == BS_NONE) {
c20d594e 19909 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
959082fc 19910 num_insns++;
667b8e29 19911
b933066a
RH
19912 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19913 save_cpu_state(&ctx, 1);
19914 ctx.bstate = BS_BRANCH;
19915 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
19916 /* The address covered by the breakpoint must be included in
19917 [tb->pc, tb->pc + tb->size) in order to for it to be
19918 properly cleared -- thus we increment the PC here so that
19919 the logic setting tb->size below does the right thing. */
b933066a
RH
19920 ctx.pc += 4;
19921 goto done_generating;
19922 }
19923
959082fc 19924 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 19925 gen_io_start();
667b8e29 19926 }
c9602061 19927
339cd2a8 19928 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19929 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19930 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19931 insn_bytes = 4;
240ce26a 19932 decode_opc(env, &ctx);
d75c135e 19933 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19934 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19935 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19936 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19937 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19938 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 19939 } else {
9c708c7f 19940 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
19941 break;
19942 }
31837be3 19943
b231c103 19944 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19945 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19946 MIPS_HFLAG_FBNSLOT))) {
19947 /* force to generate branch as there is neither delay nor
19948 forbidden slot */
19949 is_slot = 1;
b231c103 19950 }
65935f07
YK
19951 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19952 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19953 /* Force to generate branch as microMIPS R6 doesn't restrict
19954 branches in the forbidden slot. */
19955 is_slot = 1;
19956 }
b231c103 19957 }
339cd2a8 19958 if (is_slot) {
31837be3 19959 gen_branch(&ctx, insn_bytes);
c9602061
NF
19960 }
19961 ctx.pc += insn_bytes;
19962
7b270ef2
NF
19963 /* Execute a branch and its delay slot as a single instruction.
19964 This is what GDB expects and is consistent with what the
19965 hardware does (e.g. if a delay slot instruction faults, the
19966 reported PC is the PC of the branch). */
ed2803da 19967 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19968 break;
ed2803da 19969 }
4ad40f36 19970
fe237291 19971 if (ctx.pc >= next_page_start) {
6af0bf9c 19972 break;
fe237291 19973 }
4ad40f36 19974
fe700adb 19975 if (tcg_op_buf_full()) {
faf7aaa9 19976 break;
efd7f486 19977 }
faf7aaa9 19978
2e70f6ef
PB
19979 if (num_insns >= max_insns)
19980 break;
1b530a6d
AJ
19981
19982 if (singlestep)
19983 break;
6af0bf9c 19984 }
ed2803da 19985 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19986 gen_io_end();
ed2803da
AF
19987 }
19988 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19989 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 19990 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 19991 } else {
6958549d 19992 switch (ctx.bstate) {
16c00cb2 19993 case BS_STOP:
df1561e2
TS
19994 gen_goto_tb(&ctx, 0, ctx.pc);
19995 break;
16c00cb2 19996 case BS_NONE:
278d0702 19997 save_cpu_state(&ctx, 0);
16c00cb2
TS
19998 gen_goto_tb(&ctx, 0, ctx.pc);
19999 break;
5a5012ec 20000 case BS_EXCP:
57fec1fe 20001 tcg_gen_exit_tb(0);
16c00cb2 20002 break;
5a5012ec
TS
20003 case BS_BRANCH:
20004 default:
20005 break;
6958549d 20006 }
6af0bf9c 20007 }
4ad40f36 20008done_generating:
806f352d 20009 gen_tb_end(tb, num_insns);
0a7df5da 20010
4e5e1215
RH
20011 tb->size = ctx.pc - pc_start;
20012 tb->icount = num_insns;
20013
6af0bf9c 20014#ifdef DEBUG_DISAS
d12d51d5 20015 LOG_DISAS("\n");
4910e6e4
RH
20016 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20017 && qemu_log_in_addr_range(pc_start)) {
93fcfe39 20018 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 20019 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 20020 qemu_log("\n");
6af0bf9c
FB
20021 }
20022#endif
6af0bf9c
FB
20023}
20024
7db13fae 20025static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20026 int flags)
6ea83fed
FB
20027{
20028 int i;
5e755519 20029 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20030
2a5612e6
SW
20031#define printfpr(fp) \
20032 do { \
20033 if (is_fpu64) \
20034 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20035 " fd:%13g fs:%13g psu: %13g\n", \
20036 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20037 (double)(fp)->fd, \
20038 (double)(fp)->fs[FP_ENDIAN_IDX], \
20039 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20040 else { \
20041 fpr_t tmp; \
20042 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20043 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20044 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20045 " fd:%13g fs:%13g psu:%13g\n", \
20046 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20047 (double)tmp.fd, \
20048 (double)tmp.fs[FP_ENDIAN_IDX], \
20049 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20050 } \
6ea83fed
FB
20051 } while(0)
20052
5a5012ec 20053
9a78eead
SW
20054 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20055 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20056 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20057 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20058 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20059 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20060 }
20061
20062#undef printfpr
20063}
20064
878096ee
AF
20065void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20066 int flags)
6af0bf9c 20067{
878096ee
AF
20068 MIPSCPU *cpu = MIPS_CPU(cs);
20069 CPUMIPSState *env = &cpu->env;
6af0bf9c 20070 int i;
3b46e624 20071
a7200c9f
SW
20072 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20073 " LO=0x" TARGET_FMT_lx " ds %04x "
20074 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20075 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20076 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20077 for (i = 0; i < 32; i++) {
20078 if ((i & 3) == 0)
20079 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20080 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20081 if ((i & 3) == 3)
20082 cpu_fprintf(f, "\n");
20083 }
568b600d 20084
3594c774 20085 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20086 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20087 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20088 PRIx64 "\n",
5499b6ff 20089 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20090 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20091 env->CP0_Config2, env->CP0_Config3);
20092 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20093 env->CP0_Config4, env->CP0_Config5);
5e755519 20094 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 20095 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
20096}
20097
78ce64f4 20098void mips_tcg_init(void)
39454628 20099{
f01be154 20100 int i;
39454628
TS
20101 static int inited;
20102
20103 /* Initialize various static tables. */
20104 if (inited)
6958549d 20105 return;
39454628 20106
a7812ae4 20107 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7c255043 20108 tcg_ctx.tcg_env = cpu_env;
e1ccc054 20109
f2c94b92 20110 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 20111 for (i = 1; i < 32; i++)
e1ccc054 20112 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20113 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20114 regnames[i]);
d73ee8a2 20115
863f264d
YK
20116 for (i = 0; i < 32; i++) {
20117 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20118 msa_wr_d[i * 2] =
e1ccc054 20119 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20120 /* The scalar floating-point unit (FPU) registers are mapped on
20121 * the MSA vector registers. */
20122 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20123 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20124 msa_wr_d[i * 2 + 1] =
e1ccc054 20125 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20126 }
20127
e1ccc054 20128 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20129 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20130 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20131 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20132 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20133 regnames_HI[i]);
e1ccc054 20134 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20135 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20136 regnames_LO[i]);
4b2eb8d2 20137 }
e1ccc054 20138 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20139 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20140 "DSPControl");
e1ccc054 20141 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20142 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20143 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20144 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20145 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20146 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20147
e1ccc054 20148 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20149 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20150 "fcr0");
e1ccc054 20151 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20152 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20153 "fcr31");
39454628
TS
20154
20155 inited = 1;
20156}
20157
aaed909a
FB
20158#include "translate_init.c"
20159
30bf942d 20160MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 20161{
0f71a709 20162 MIPSCPU *cpu;
6af0bf9c 20163 CPUMIPSState *env;
c227f099 20164 const mips_def_t *def;
6af0bf9c 20165
aaed909a
FB
20166 def = cpu_mips_find_by_name(cpu_model);
20167 if (!def)
20168 return NULL;
0f71a709
AF
20169 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20170 env = &cpu->env;
aaed909a 20171 env->cpu_model = def;
89777fd1 20172 env->exception_base = (int32_t)0xBFC00000;
aaed909a 20173
51cc2e78
BS
20174#ifndef CONFIG_USER_ONLY
20175 mmu_init(env, def);
20176#endif
20177 fpu_init(env, def);
20178 mvp_init(env, def);
c1caf1d9
AF
20179
20180 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20181
30bf942d 20182 return cpu;
6ae81775
TS
20183}
20184
bff384a4
LA
20185bool cpu_supports_cps_smp(const char *cpu_model)
20186{
20187 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20188 if (!def) {
20189 return false;
20190 }
20191
20192 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20193}
20194
89777fd1
LA
20195void cpu_set_exception_base(int vp_index, target_ulong address)
20196{
20197 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20198 vp->env.exception_base = address;
20199}
20200
1bba0dc9 20201void cpu_state_reset(CPUMIPSState *env)
6ae81775 20202{
55e5c285
AF
20203 MIPSCPU *cpu = mips_env_get_cpu(env);
20204 CPUState *cs = CPU(cpu);
6ae81775 20205
51cc2e78
BS
20206 /* Reset registers to their default values */
20207 env->CP0_PRid = env->cpu_model->CP0_PRid;
20208 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20209#ifdef TARGET_WORDS_BIGENDIAN
20210 env->CP0_Config0 |= (1 << CP0C0_BE);
20211#endif
20212 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20213 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20214 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20215 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20216 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20217 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20218 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20219 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20220 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20221 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20222 << env->cpu_model->CP0_LLAddr_shift;
20223 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20224 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20225 env->CCRes = env->cpu_model->CCRes;
20226 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20227 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20228 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20229 env->current_tc = 0;
20230 env->SEGBITS = env->cpu_model->SEGBITS;
20231 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20232#if defined(TARGET_MIPS64)
20233 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20234 env->SEGMask |= 3ULL << 62;
20235 }
20236#endif
20237 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20238 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20239 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20240 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20241 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20242 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20243 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20244 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20245 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20246 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20247 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20248 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20249 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 20250 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20251 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20252 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20253 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20254 env->insn_flags = env->cpu_model->insn_flags;
20255
0eaef5aa 20256#if defined(CONFIG_USER_ONLY)
03e6e501 20257 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20258# ifdef TARGET_MIPS64
20259 /* Enable 64-bit register mode. */
20260 env->CP0_Status |= (1 << CP0St_PX);
20261# endif
20262# ifdef TARGET_ABI_MIPSN64
20263 /* Enable 64-bit address mode. */
20264 env->CP0_Status |= (1 << CP0St_UX);
20265# endif
94159135
MI
20266 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20267 hardware registers. */
20268 env->CP0_HWREna |= 0x0000000F;
91a75935 20269 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20270 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20271 }
6f0af304
PJ
20272 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20273 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20274 }
4d66261f
PJ
20275# if defined(TARGET_MIPS64)
20276 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20277 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20278 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20279 env->CP0_Status |= (1 << CP0St_FR);
20280 }
4d66261f 20281# endif
932e71cd
AJ
20282#else
20283 if (env->hflags & MIPS_HFLAG_BMASK) {
20284 /* If the exception was raised from a delay slot,
20285 come back to the jump. */
c3577479
MR
20286 env->CP0_ErrorEPC = (env->active_tc.PC
20287 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20288 } else {
932e71cd
AJ
20289 env->CP0_ErrorEPC = env->active_tc.PC;
20290 }
89777fd1 20291 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20292 env->CP0_Random = env->tlb->nb_tlb - 1;
20293 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20294 env->CP0_Wired = 0;
01bc435b 20295 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7
JH
20296 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20297 if (kvm_enabled()) {
20298 env->CP0_EBase |= 0x40000000;
20299 } else {
20300 env->CP0_EBase |= 0x80000000;
20301 }
c870e3f5
YK
20302 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20303 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20304 }
a0c80608
PB
20305 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20306 0x3ff : 0xff;
932e71cd
AJ
20307 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20308 /* vectored interrupts not implemented, timer on int 7,
20309 no performance counters. */
20310 env->CP0_IntCtl = 0xe0000000;
20311 {
20312 int i;
20313
20314 for (i = 0; i < 7; i++) {
20315 env->CP0_WatchLo[i] = 0;
20316 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20317 }
932e71cd
AJ
20318 env->CP0_WatchLo[7] = 0;
20319 env->CP0_WatchHi[7] = 0;
fd88b6ab 20320 }
932e71cd
AJ
20321 /* Count register increments in debug mode, EJTAG version 1 */
20322 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20323
4b69c7e2
JH
20324 cpu_mips_store_count(env, 1);
20325
9e56e756
EI
20326 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20327 int i;
20328
20329 /* Only TC0 on VPE 0 starts as active. */
20330 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20331 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20332 env->tcs[i].CP0_TCHalt = 1;
20333 }
20334 env->active_tc.CP0_TCHalt = 1;
259186a7 20335 cs->halted = 1;
9e56e756 20336
55e5c285 20337 if (cs->cpu_index == 0) {
9e56e756
EI
20338 /* VPE0 starts up enabled. */
20339 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20340 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20341
20342 /* TC0 starts up unhalted. */
259186a7 20343 cs->halted = 0;
9e56e756
EI
20344 env->active_tc.CP0_TCHalt = 0;
20345 env->tcs[0].CP0_TCHalt = 0;
20346 /* With thread 0 active. */
20347 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20348 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20349 }
20350 }
51cc2e78 20351#endif
ddc584bd
LA
20352 if ((env->insn_flags & ISA_MIPS32R6) &&
20353 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20354 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20355 env->CP0_Status |= (1 << CP0St_FR);
20356 }
20357
863f264d
YK
20358 /* MSA */
20359 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20360 msa_reset(env);
20361 }
20362
03e6e501 20363 compute_hflags(env);
599bc5e8 20364 restore_fp_status(env);
e117f526 20365 restore_pamask(env);
27103424 20366 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20367
20368 if (semihosting_get_argc()) {
20369 /* UHI interface can be used to obtain argc and argv */
20370 env->active_tc.gpr[4] = -1;
20371 }
6af0bf9c 20372}
d2856f1a 20373
bad729e2
RH
20374void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20375 target_ulong *data)
d2856f1a 20376{
bad729e2 20377 env->active_tc.PC = data[0];
d2856f1a 20378 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20379 env->hflags |= data[1];
4636401d
AJ
20380 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20381 case MIPS_HFLAG_BR:
20382 break;
20383 case MIPS_HFLAG_BC:
20384 case MIPS_HFLAG_BL:
20385 case MIPS_HFLAG_B:
bad729e2 20386 env->btarget = data[2];
4636401d
AJ
20387 break;
20388 }
d2856f1a 20389}