]> Git Repo - qemu.git/blame - target/mips/translate.c
target-mips: log bad coprocessor0 register accesses with LOG_UNIMP
[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 }
1a0196c5 3629 t0 = cpu_gpr[rd];
6c5c1e20 3630 gen_load_gpr(t0, rs);
1a0196c5 3631
6af0bf9c
FB
3632 switch (opc) {
3633 case OPC_CLO:
4267d3e6 3634 case R6_OPC_CLO:
1a0196c5
RH
3635#if defined(TARGET_MIPS64)
3636 case OPC_DCLO:
3637 case R6_OPC_DCLO:
3638#endif
3639 tcg_gen_not_tl(t0, t0);
6af0bf9c 3640 break;
1a0196c5
RH
3641 }
3642
3643 switch (opc) {
3644 case OPC_CLO:
3645 case R6_OPC_CLO:
6af0bf9c 3646 case OPC_CLZ:
4267d3e6 3647 case R6_OPC_CLZ:
1a0196c5
RH
3648 tcg_gen_ext32u_tl(t0, t0);
3649 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3650 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3651 break;
d26bc211 3652#if defined(TARGET_MIPS64)
7a387fff 3653 case OPC_DCLO:
4267d3e6 3654 case R6_OPC_DCLO:
7a387fff 3655 case OPC_DCLZ:
4267d3e6 3656 case R6_OPC_DCLZ:
1a0196c5 3657 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3658 break;
3659#endif
6af0bf9c 3660 }
6af0bf9c
FB
3661}
3662
161f85e6 3663/* Godson integer instructions */
bd277fa1
RH
3664static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3665 int rd, int rs, int rt)
161f85e6 3666{
161f85e6
AJ
3667 TCGv t0, t1;
3668
3669 if (rd == 0) {
3670 /* Treat as NOP. */
161f85e6
AJ
3671 return;
3672 }
3673
3674 switch (opc) {
3675 case OPC_MULT_G_2E:
3676 case OPC_MULT_G_2F:
3677 case OPC_MULTU_G_2E:
3678 case OPC_MULTU_G_2F:
3679#if defined(TARGET_MIPS64)
3680 case OPC_DMULT_G_2E:
3681 case OPC_DMULT_G_2F:
3682 case OPC_DMULTU_G_2E:
3683 case OPC_DMULTU_G_2F:
3684#endif
3685 t0 = tcg_temp_new();
3686 t1 = tcg_temp_new();
3687 break;
3688 default:
3689 t0 = tcg_temp_local_new();
3690 t1 = tcg_temp_local_new();
3691 break;
3692 }
3693
3694 gen_load_gpr(t0, rs);
3695 gen_load_gpr(t1, rt);
3696
3697 switch (opc) {
3698 case OPC_MULT_G_2E:
3699 case OPC_MULT_G_2F:
3700 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3702 break;
3703 case OPC_MULTU_G_2E:
3704 case OPC_MULTU_G_2F:
3705 tcg_gen_ext32u_tl(t0, t0);
3706 tcg_gen_ext32u_tl(t1, t1);
3707 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3708 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3709 break;
3710 case OPC_DIV_G_2E:
3711 case OPC_DIV_G_2F:
3712 {
42a268c2
RH
3713 TCGLabel *l1 = gen_new_label();
3714 TCGLabel *l2 = gen_new_label();
3715 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3716 tcg_gen_ext32s_tl(t0, t0);
3717 tcg_gen_ext32s_tl(t1, t1);
3718 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3719 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3720 tcg_gen_br(l3);
3721 gen_set_label(l1);
3722 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3723 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3724 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3725 tcg_gen_br(l3);
3726 gen_set_label(l2);
3727 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3728 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3729 gen_set_label(l3);
3730 }
161f85e6
AJ
3731 break;
3732 case OPC_DIVU_G_2E:
3733 case OPC_DIVU_G_2F:
3734 {
42a268c2
RH
3735 TCGLabel *l1 = gen_new_label();
3736 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3737 tcg_gen_ext32u_tl(t0, t0);
3738 tcg_gen_ext32u_tl(t1, t1);
3739 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3741 tcg_gen_br(l2);
3742 gen_set_label(l1);
3743 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3744 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3745 gen_set_label(l2);
3746 }
161f85e6
AJ
3747 break;
3748 case OPC_MOD_G_2E:
3749 case OPC_MOD_G_2F:
3750 {
42a268c2
RH
3751 TCGLabel *l1 = gen_new_label();
3752 TCGLabel *l2 = gen_new_label();
3753 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3754 tcg_gen_ext32u_tl(t0, t0);
3755 tcg_gen_ext32u_tl(t1, t1);
3756 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3757 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3758 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3759 gen_set_label(l1);
3760 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3761 tcg_gen_br(l3);
3762 gen_set_label(l2);
3763 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3764 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3765 gen_set_label(l3);
3766 }
161f85e6
AJ
3767 break;
3768 case OPC_MODU_G_2E:
3769 case OPC_MODU_G_2F:
3770 {
42a268c2
RH
3771 TCGLabel *l1 = gen_new_label();
3772 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3773 tcg_gen_ext32u_tl(t0, t0);
3774 tcg_gen_ext32u_tl(t1, t1);
3775 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3776 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3777 tcg_gen_br(l2);
3778 gen_set_label(l1);
3779 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3780 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3781 gen_set_label(l2);
3782 }
161f85e6
AJ
3783 break;
3784#if defined(TARGET_MIPS64)
3785 case OPC_DMULT_G_2E:
3786 case OPC_DMULT_G_2F:
3787 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3788 break;
3789 case OPC_DMULTU_G_2E:
3790 case OPC_DMULTU_G_2F:
3791 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3792 break;
3793 case OPC_DDIV_G_2E:
3794 case OPC_DDIV_G_2F:
3795 {
42a268c2
RH
3796 TCGLabel *l1 = gen_new_label();
3797 TCGLabel *l2 = gen_new_label();
3798 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3799 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3800 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3801 tcg_gen_br(l3);
3802 gen_set_label(l1);
3803 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3805 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3806 tcg_gen_br(l3);
3807 gen_set_label(l2);
3808 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3809 gen_set_label(l3);
3810 }
161f85e6
AJ
3811 break;
3812 case OPC_DDIVU_G_2E:
3813 case OPC_DDIVU_G_2F:
3814 {
42a268c2
RH
3815 TCGLabel *l1 = gen_new_label();
3816 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3817 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3819 tcg_gen_br(l2);
3820 gen_set_label(l1);
3821 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3822 gen_set_label(l2);
3823 }
161f85e6
AJ
3824 break;
3825 case OPC_DMOD_G_2E:
3826 case OPC_DMOD_G_2F:
3827 {
42a268c2
RH
3828 TCGLabel *l1 = gen_new_label();
3829 TCGLabel *l2 = gen_new_label();
3830 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3831 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3832 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3834 gen_set_label(l1);
3835 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3836 tcg_gen_br(l3);
3837 gen_set_label(l2);
3838 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3839 gen_set_label(l3);
3840 }
161f85e6
AJ
3841 break;
3842 case OPC_DMODU_G_2E:
3843 case OPC_DMODU_G_2F:
3844 {
42a268c2
RH
3845 TCGLabel *l1 = gen_new_label();
3846 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3847 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3848 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3849 tcg_gen_br(l2);
3850 gen_set_label(l1);
3851 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3852 gen_set_label(l2);
3853 }
161f85e6
AJ
3854 break;
3855#endif
3856 }
3857
161f85e6
AJ
3858 tcg_temp_free(t0);
3859 tcg_temp_free(t1);
3860}
3861
bd277fa1
RH
3862/* Loongson multimedia instructions */
3863static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3864{
bd277fa1
RH
3865 uint32_t opc, shift_max;
3866 TCGv_i64 t0, t1;
3867
3868 opc = MASK_LMI(ctx->opcode);
3869 switch (opc) {
3870 case OPC_ADD_CP2:
3871 case OPC_SUB_CP2:
3872 case OPC_DADD_CP2:
3873 case OPC_DSUB_CP2:
3874 t0 = tcg_temp_local_new_i64();
3875 t1 = tcg_temp_local_new_i64();
3876 break;
3877 default:
3878 t0 = tcg_temp_new_i64();
3879 t1 = tcg_temp_new_i64();
3880 break;
3881 }
3882
b5a587b6 3883 check_cp1_enabled(ctx);
bd277fa1
RH
3884 gen_load_fpr64(ctx, t0, rs);
3885 gen_load_fpr64(ctx, t1, rt);
3886
3887#define LMI_HELPER(UP, LO) \
9d68ac14 3888 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3889#define LMI_HELPER_1(UP, LO) \
9d68ac14 3890 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3891#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3892 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3893
3894 switch (opc) {
3895 LMI_HELPER(PADDSH, paddsh);
3896 LMI_HELPER(PADDUSH, paddush);
3897 LMI_HELPER(PADDH, paddh);
3898 LMI_HELPER(PADDW, paddw);
3899 LMI_HELPER(PADDSB, paddsb);
3900 LMI_HELPER(PADDUSB, paddusb);
3901 LMI_HELPER(PADDB, paddb);
3902
3903 LMI_HELPER(PSUBSH, psubsh);
3904 LMI_HELPER(PSUBUSH, psubush);
3905 LMI_HELPER(PSUBH, psubh);
3906 LMI_HELPER(PSUBW, psubw);
3907 LMI_HELPER(PSUBSB, psubsb);
3908 LMI_HELPER(PSUBUSB, psubusb);
3909 LMI_HELPER(PSUBB, psubb);
3910
3911 LMI_HELPER(PSHUFH, pshufh);
3912 LMI_HELPER(PACKSSWH, packsswh);
3913 LMI_HELPER(PACKSSHB, packsshb);
3914 LMI_HELPER(PACKUSHB, packushb);
3915
3916 LMI_HELPER(PUNPCKLHW, punpcklhw);
3917 LMI_HELPER(PUNPCKHHW, punpckhhw);
3918 LMI_HELPER(PUNPCKLBH, punpcklbh);
3919 LMI_HELPER(PUNPCKHBH, punpckhbh);
3920 LMI_HELPER(PUNPCKLWD, punpcklwd);
3921 LMI_HELPER(PUNPCKHWD, punpckhwd);
3922
3923 LMI_HELPER(PAVGH, pavgh);
3924 LMI_HELPER(PAVGB, pavgb);
3925 LMI_HELPER(PMAXSH, pmaxsh);
3926 LMI_HELPER(PMINSH, pminsh);
3927 LMI_HELPER(PMAXUB, pmaxub);
3928 LMI_HELPER(PMINUB, pminub);
3929
3930 LMI_HELPER(PCMPEQW, pcmpeqw);
3931 LMI_HELPER(PCMPGTW, pcmpgtw);
3932 LMI_HELPER(PCMPEQH, pcmpeqh);
3933 LMI_HELPER(PCMPGTH, pcmpgth);
3934 LMI_HELPER(PCMPEQB, pcmpeqb);
3935 LMI_HELPER(PCMPGTB, pcmpgtb);
3936
3937 LMI_HELPER(PSLLW, psllw);
3938 LMI_HELPER(PSLLH, psllh);
3939 LMI_HELPER(PSRLW, psrlw);
3940 LMI_HELPER(PSRLH, psrlh);
3941 LMI_HELPER(PSRAW, psraw);
3942 LMI_HELPER(PSRAH, psrah);
3943
3944 LMI_HELPER(PMULLH, pmullh);
3945 LMI_HELPER(PMULHH, pmulhh);
3946 LMI_HELPER(PMULHUH, pmulhuh);
3947 LMI_HELPER(PMADDHW, pmaddhw);
3948
3949 LMI_HELPER(PASUBUB, pasubub);
3950 LMI_HELPER_1(BIADD, biadd);
3951 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3952
3953 LMI_DIRECT(PADDD, paddd, add);
3954 LMI_DIRECT(PSUBD, psubd, sub);
3955 LMI_DIRECT(XOR_CP2, xor, xor);
3956 LMI_DIRECT(NOR_CP2, nor, nor);
3957 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 3958 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 3959
9099a36b
H
3960 case OPC_PANDN:
3961 tcg_gen_andc_i64(t0, t1, t0);
3962 break;
3963
bd277fa1
RH
3964 case OPC_PINSRH_0:
3965 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3966 break;
3967 case OPC_PINSRH_1:
3968 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3969 break;
3970 case OPC_PINSRH_2:
3971 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3972 break;
3973 case OPC_PINSRH_3:
3974 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3975 break;
3976
3977 case OPC_PEXTRH:
3978 tcg_gen_andi_i64(t1, t1, 3);
3979 tcg_gen_shli_i64(t1, t1, 4);
3980 tcg_gen_shr_i64(t0, t0, t1);
3981 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3982 break;
3983
3984 case OPC_ADDU_CP2:
3985 tcg_gen_add_i64(t0, t0, t1);
3986 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3987 break;
3988 case OPC_SUBU_CP2:
3989 tcg_gen_sub_i64(t0, t0, t1);
3990 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3991 break;
3992
3993 case OPC_SLL_CP2:
bd277fa1
RH
3994 shift_max = 32;
3995 goto do_shift;
3996 case OPC_SRL_CP2:
bd277fa1
RH
3997 shift_max = 32;
3998 goto do_shift;
3999 case OPC_SRA_CP2:
bd277fa1
RH
4000 shift_max = 32;
4001 goto do_shift;
4002 case OPC_DSLL_CP2:
bd277fa1
RH
4003 shift_max = 64;
4004 goto do_shift;
4005 case OPC_DSRL_CP2:
bd277fa1
RH
4006 shift_max = 64;
4007 goto do_shift;
4008 case OPC_DSRA_CP2:
bd277fa1
RH
4009 shift_max = 64;
4010 goto do_shift;
4011 do_shift:
4012 /* Make sure shift count isn't TCG undefined behaviour. */
4013 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4014
4015 switch (opc) {
4016 case OPC_SLL_CP2:
4017 case OPC_DSLL_CP2:
4018 tcg_gen_shl_i64(t0, t0, t1);
4019 break;
4020 case OPC_SRA_CP2:
4021 case OPC_DSRA_CP2:
4022 /* Since SRA is UndefinedResult without sign-extended inputs,
4023 we can treat SRA and DSRA the same. */
4024 tcg_gen_sar_i64(t0, t0, t1);
4025 break;
4026 case OPC_SRL_CP2:
4027 /* We want to shift in zeros for SRL; zero-extend first. */
4028 tcg_gen_ext32u_i64(t0, t0);
4029 /* FALLTHRU */
4030 case OPC_DSRL_CP2:
4031 tcg_gen_shr_i64(t0, t0, t1);
4032 break;
4033 }
4034
4035 if (shift_max == 32) {
4036 tcg_gen_ext32s_i64(t0, t0);
4037 }
4038
4039 /* Shifts larger than MAX produce zero. */
4040 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4041 tcg_gen_neg_i64(t1, t1);
4042 tcg_gen_and_i64(t0, t0, t1);
4043 break;
4044
4045 case OPC_ADD_CP2:
4046 case OPC_DADD_CP2:
4047 {
4048 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4049 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4050
4051 tcg_gen_mov_i64(t2, t0);
4052 tcg_gen_add_i64(t0, t1, t2);
4053 if (opc == OPC_ADD_CP2) {
4054 tcg_gen_ext32s_i64(t0, t0);
4055 }
4056 tcg_gen_xor_i64(t1, t1, t2);
4057 tcg_gen_xor_i64(t2, t2, t0);
4058 tcg_gen_andc_i64(t1, t2, t1);
4059 tcg_temp_free_i64(t2);
4060 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4061 generate_exception(ctx, EXCP_OVERFLOW);
4062 gen_set_label(lab);
bd277fa1
RH
4063 break;
4064 }
4065
4066 case OPC_SUB_CP2:
4067 case OPC_DSUB_CP2:
4068 {
4069 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4070 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4071
4072 tcg_gen_mov_i64(t2, t0);
4073 tcg_gen_sub_i64(t0, t1, t2);
4074 if (opc == OPC_SUB_CP2) {
4075 tcg_gen_ext32s_i64(t0, t0);
4076 }
4077 tcg_gen_xor_i64(t1, t1, t2);
4078 tcg_gen_xor_i64(t2, t2, t0);
4079 tcg_gen_and_i64(t1, t1, t2);
4080 tcg_temp_free_i64(t2);
4081 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4082 generate_exception(ctx, EXCP_OVERFLOW);
4083 gen_set_label(lab);
bd277fa1
RH
4084 break;
4085 }
4086
4087 case OPC_PMULUW:
4088 tcg_gen_ext32u_i64(t0, t0);
4089 tcg_gen_ext32u_i64(t1, t1);
4090 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4091 break;
4092
4093 case OPC_SEQU_CP2:
4094 case OPC_SEQ_CP2:
4095 case OPC_SLTU_CP2:
4096 case OPC_SLT_CP2:
4097 case OPC_SLEU_CP2:
4098 case OPC_SLE_CP2:
4099 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4100 FD field is the CC field? */
4101 default:
9d68ac14 4102 MIPS_INVAL("loongson_cp2");
9c708c7f 4103 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4104 return;
4105 }
4106
4107#undef LMI_HELPER
4108#undef LMI_DIRECT
4109
4110 gen_store_fpr64(ctx, t0, rd);
4111
bd277fa1
RH
4112 tcg_temp_free_i64(t0);
4113 tcg_temp_free_i64(t1);
4114}
4115
6af0bf9c 4116/* Traps */
7a387fff 4117static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4118 int rs, int rt, int16_t imm)
4119{
4120 int cond;
cdc0faa6 4121 TCGv t0 = tcg_temp_new();
1ba74fb8 4122 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4123
4124 cond = 0;
4125 /* Load needed operands */
4126 switch (opc) {
4127 case OPC_TEQ:
4128 case OPC_TGE:
4129 case OPC_TGEU:
4130 case OPC_TLT:
4131 case OPC_TLTU:
4132 case OPC_TNE:
4133 /* Compare two registers */
4134 if (rs != rt) {
be24bb4f
TS
4135 gen_load_gpr(t0, rs);
4136 gen_load_gpr(t1, rt);
6af0bf9c
FB
4137 cond = 1;
4138 }
179e32bb 4139 break;
6af0bf9c
FB
4140 case OPC_TEQI:
4141 case OPC_TGEI:
4142 case OPC_TGEIU:
4143 case OPC_TLTI:
4144 case OPC_TLTIU:
4145 case OPC_TNEI:
4146 /* Compare register to immediate */
4147 if (rs != 0 || imm != 0) {
be24bb4f
TS
4148 gen_load_gpr(t0, rs);
4149 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4150 cond = 1;
4151 }
4152 break;
4153 }
4154 if (cond == 0) {
4155 switch (opc) {
4156 case OPC_TEQ: /* rs == rs */
4157 case OPC_TEQI: /* r0 == 0 */
4158 case OPC_TGE: /* rs >= rs */
4159 case OPC_TGEI: /* r0 >= 0 */
4160 case OPC_TGEU: /* rs >= rs unsigned */
4161 case OPC_TGEIU: /* r0 >= 0 unsigned */
4162 /* Always trap */
9c708c7f 4163 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4164 break;
4165 case OPC_TLT: /* rs < rs */
4166 case OPC_TLTI: /* r0 < 0 */
4167 case OPC_TLTU: /* rs < rs unsigned */
4168 case OPC_TLTIU: /* r0 < 0 unsigned */
4169 case OPC_TNE: /* rs != rs */
4170 case OPC_TNEI: /* r0 != 0 */
ead9360e 4171 /* Never trap: treat as NOP. */
cdc0faa6 4172 break;
6af0bf9c
FB
4173 }
4174 } else {
42a268c2 4175 TCGLabel *l1 = gen_new_label();
cdc0faa6 4176
6af0bf9c
FB
4177 switch (opc) {
4178 case OPC_TEQ:
4179 case OPC_TEQI:
cdc0faa6 4180 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4181 break;
4182 case OPC_TGE:
4183 case OPC_TGEI:
cdc0faa6 4184 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4185 break;
4186 case OPC_TGEU:
4187 case OPC_TGEIU:
cdc0faa6 4188 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4189 break;
4190 case OPC_TLT:
4191 case OPC_TLTI:
cdc0faa6 4192 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4193 break;
4194 case OPC_TLTU:
4195 case OPC_TLTIU:
cdc0faa6 4196 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4197 break;
4198 case OPC_TNE:
4199 case OPC_TNEI:
cdc0faa6 4200 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4201 break;
6af0bf9c 4202 }
cdc0faa6 4203 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4204 gen_set_label(l1);
4205 }
be24bb4f
TS
4206 tcg_temp_free(t0);
4207 tcg_temp_free(t1);
6af0bf9c
FB
4208}
4209
90aa39a1
SF
4210static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4211{
4212 if (unlikely(ctx->singlestep_enabled)) {
4213 return false;
4214 }
4215
4216#ifndef CONFIG_USER_ONLY
4217 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4218#else
4219 return true;
4220#endif
4221}
4222
356265ae 4223static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4224{
90aa39a1 4225 if (use_goto_tb(ctx, dest)) {
57fec1fe 4226 tcg_gen_goto_tb(n);
9b9e4393 4227 gen_save_pc(dest);
90aa39a1 4228 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
6e256c93 4229 } else {
9b9e4393 4230 gen_save_pc(dest);
7b270ef2
NF
4231 if (ctx->singlestep_enabled) {
4232 save_cpu_state(ctx, 0);
9c708c7f 4233 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4234 }
57fec1fe 4235 tcg_gen_exit_tb(0);
6e256c93 4236 }
c53be334
FB
4237}
4238
6af0bf9c 4239/* Branches (before delay slot) */
7a387fff 4240static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4241 int insn_bytes,
b231c103
YK
4242 int rs, int rt, int32_t offset,
4243 int delayslot_size)
6af0bf9c 4244{
d077b6f7 4245 target_ulong btgt = -1;
3ad4bb2d 4246 int blink = 0;
2fdbad25 4247 int bcond_compute = 0;
1ba74fb8
AJ
4248 TCGv t0 = tcg_temp_new();
4249 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4250
4251 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4252#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4253 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4254 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4255#endif
9c708c7f 4256 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4257 goto out;
3ad4bb2d 4258 }
6af0bf9c 4259
6af0bf9c
FB
4260 /* Load needed operands */
4261 switch (opc) {
4262 case OPC_BEQ:
4263 case OPC_BEQL:
4264 case OPC_BNE:
4265 case OPC_BNEL:
4266 /* Compare two registers */
4267 if (rs != rt) {
6c5c1e20
TS
4268 gen_load_gpr(t0, rs);
4269 gen_load_gpr(t1, rt);
2fdbad25 4270 bcond_compute = 1;
6af0bf9c 4271 }
7dca4ad0 4272 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4273 break;
4274 case OPC_BGEZ:
4275 case OPC_BGEZAL:
4276 case OPC_BGEZALL:
4277 case OPC_BGEZL:
4278 case OPC_BGTZ:
4279 case OPC_BGTZL:
4280 case OPC_BLEZ:
4281 case OPC_BLEZL:
4282 case OPC_BLTZ:
4283 case OPC_BLTZAL:
4284 case OPC_BLTZALL:
4285 case OPC_BLTZL:
4286 /* Compare to zero */
4287 if (rs != 0) {
6c5c1e20 4288 gen_load_gpr(t0, rs);
2fdbad25 4289 bcond_compute = 1;
6af0bf9c 4290 }
7dca4ad0 4291 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4292 break;
e45a93e2
JL
4293 case OPC_BPOSGE32:
4294#if defined(TARGET_MIPS64)
4295 case OPC_BPOSGE64:
4296 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4297#else
4298 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4299#endif
4300 bcond_compute = 1;
4301 btgt = ctx->pc + insn_bytes + offset;
4302 break;
6af0bf9c
FB
4303 case OPC_J:
4304 case OPC_JAL:
364d4831 4305 case OPC_JALX:
6af0bf9c 4306 /* Jump to immediate */
7dca4ad0 4307 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4308 break;
4309 case OPC_JR:
4310 case OPC_JALR:
4311 /* Jump to register */
7a387fff
TS
4312 if (offset != 0 && offset != 16) {
4313 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4314 others are reserved. */
923617a3 4315 MIPS_INVAL("jump hint");
9c708c7f 4316 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4317 goto out;
6af0bf9c 4318 }
d077b6f7 4319 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4320 break;
4321 default:
4322 MIPS_INVAL("branch/jump");
9c708c7f 4323 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4324 goto out;
6af0bf9c 4325 }
2fdbad25 4326 if (bcond_compute == 0) {
6af0bf9c
FB
4327 /* No condition to be computed */
4328 switch (opc) {
4329 case OPC_BEQ: /* rx == rx */
4330 case OPC_BEQL: /* rx == rx likely */
4331 case OPC_BGEZ: /* 0 >= 0 */
4332 case OPC_BGEZL: /* 0 >= 0 likely */
4333 case OPC_BLEZ: /* 0 <= 0 */
4334 case OPC_BLEZL: /* 0 <= 0 likely */
4335 /* Always take */
4ad40f36 4336 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4337 break;
4338 case OPC_BGEZAL: /* 0 >= 0 */
4339 case OPC_BGEZALL: /* 0 >= 0 likely */
4340 /* Always take and link */
4341 blink = 31;
4ad40f36 4342 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4343 break;
4344 case OPC_BNE: /* rx != rx */
4345 case OPC_BGTZ: /* 0 > 0 */
4346 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4347 /* Treat as NOP. */
6c5c1e20 4348 goto out;
eeef26cd 4349 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4350 /* Handle as an unconditional branch to get correct delay
4351 slot checking. */
4352 blink = 31;
b231c103 4353 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4354 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4355 break;
eeef26cd 4356 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4357 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4358 /* Skip the instruction in the delay slot */
9898128f 4359 ctx->pc += 4;
6c5c1e20 4360 goto out;
6af0bf9c
FB
4361 case OPC_BNEL: /* rx != rx likely */
4362 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4363 case OPC_BLTZL: /* 0 < 0 likely */
4364 /* Skip the instruction in the delay slot */
9898128f 4365 ctx->pc += 4;
6c5c1e20 4366 goto out;
6af0bf9c 4367 case OPC_J:
4ad40f36 4368 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4369 break;
364d4831
NF
4370 case OPC_JALX:
4371 ctx->hflags |= MIPS_HFLAG_BX;
4372 /* Fallthrough */
6af0bf9c
FB
4373 case OPC_JAL:
4374 blink = 31;
4ad40f36 4375 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4376 break;
4377 case OPC_JR:
4ad40f36 4378 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4379 break;
4380 case OPC_JALR:
4381 blink = rt;
4ad40f36 4382 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4383 break;
4384 default:
4385 MIPS_INVAL("branch/jump");
9c708c7f 4386 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4387 goto out;
6af0bf9c
FB
4388 }
4389 } else {
4390 switch (opc) {
4391 case OPC_BEQ:
e68dd28f 4392 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4393 goto not_likely;
4394 case OPC_BEQL:
e68dd28f 4395 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4396 goto likely;
4397 case OPC_BNE:
e68dd28f 4398 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4399 goto not_likely;
4400 case OPC_BNEL:
e68dd28f 4401 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4402 goto likely;
4403 case OPC_BGEZ:
e68dd28f 4404 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4405 goto not_likely;
4406 case OPC_BGEZL:
e68dd28f 4407 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4408 goto likely;
4409 case OPC_BGEZAL:
e68dd28f 4410 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4411 blink = 31;
4412 goto not_likely;
4413 case OPC_BGEZALL:
e68dd28f 4414 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4415 blink = 31;
6af0bf9c
FB
4416 goto likely;
4417 case OPC_BGTZ:
e68dd28f 4418 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4419 goto not_likely;
4420 case OPC_BGTZL:
e68dd28f 4421 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4422 goto likely;
4423 case OPC_BLEZ:
e68dd28f 4424 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4425 goto not_likely;
4426 case OPC_BLEZL:
e68dd28f 4427 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4428 goto likely;
4429 case OPC_BLTZ:
e68dd28f 4430 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4431 goto not_likely;
4432 case OPC_BLTZL:
e68dd28f 4433 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4434 goto likely;
e45a93e2
JL
4435 case OPC_BPOSGE32:
4436 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4437 goto not_likely;
4438#if defined(TARGET_MIPS64)
4439 case OPC_BPOSGE64:
4440 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4441 goto not_likely;
4442#endif
6af0bf9c 4443 case OPC_BLTZAL:
e68dd28f 4444 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4445 blink = 31;
6af0bf9c 4446 not_likely:
4ad40f36 4447 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4448 break;
4449 case OPC_BLTZALL:
e68dd28f 4450 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4451 blink = 31;
6af0bf9c 4452 likely:
4ad40f36 4453 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4454 break;
c53f4a62
TS
4455 default:
4456 MIPS_INVAL("conditional branch/jump");
9c708c7f 4457 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4458 goto out;
6af0bf9c 4459 }
6af0bf9c 4460 }
9b9e4393 4461
d077b6f7 4462 ctx->btarget = btgt;
b231c103
YK
4463
4464 switch (delayslot_size) {
4465 case 2:
4466 ctx->hflags |= MIPS_HFLAG_BDS16;
4467 break;
4468 case 4:
4469 ctx->hflags |= MIPS_HFLAG_BDS32;
4470 break;
4471 }
4472
6af0bf9c 4473 if (blink > 0) {
b231c103 4474 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4475 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4476
364d4831 4477 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4478 }
6c5c1e20
TS
4479
4480 out:
364d4831
NF
4481 if (insn_bytes == 2)
4482 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4483 tcg_temp_free(t0);
4484 tcg_temp_free(t1);
6af0bf9c
FB
4485}
4486
7a387fff
TS
4487/* special3 bitfield operations */
4488static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4489 int rs, int lsb, int msb)
7a387fff 4490{
a7812ae4
PB
4491 TCGv t0 = tcg_temp_new();
4492 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4493
4494 gen_load_gpr(t1, rs);
7a387fff
TS
4495 switch (opc) {
4496 case OPC_EXT:
b7f26e52 4497 if (lsb + msb > 31) {
7a387fff 4498 goto fail;
b7f26e52 4499 }
505ad7c2 4500 if (msb != 31) {
6eebb7a4 4501 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 4502 } else {
6eebb7a4
RH
4503 /* The two checks together imply that lsb == 0,
4504 so this is a simple sign-extension. */
4505 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 4506 }
7a387fff 4507 break;
c6d6dd7c 4508#if defined(TARGET_MIPS64)
7a387fff 4509 case OPC_DEXTU:
b7f26e52
RH
4510 lsb += 32;
4511 goto do_dext;
4512 case OPC_DEXTM:
4513 msb += 32;
4514 goto do_dext;
7a387fff 4515 case OPC_DEXT:
b7f26e52
RH
4516 do_dext:
4517 if (lsb + msb > 63) {
4518 goto fail;
4519 }
6eebb7a4 4520 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 4521 break;
c6d6dd7c 4522#endif
7a387fff 4523 case OPC_INS:
b7f26e52 4524 if (lsb > msb) {
7a387fff 4525 goto fail;
b7f26e52 4526 }
6c5c1e20 4527 gen_load_gpr(t0, rt);
e0d002f1 4528 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4529 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4530 break;
c6d6dd7c 4531#if defined(TARGET_MIPS64)
7a387fff 4532 case OPC_DINSU:
b7f26e52
RH
4533 lsb += 32;
4534 /* FALLTHRU */
4535 case OPC_DINSM:
4536 msb += 32;
4537 /* FALLTHRU */
7a387fff 4538 case OPC_DINS:
b7f26e52
RH
4539 if (lsb > msb) {
4540 goto fail;
4541 }
6c5c1e20 4542 gen_load_gpr(t0, rt);
e0d002f1 4543 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4544 break;
c6d6dd7c 4545#endif
7a387fff
TS
4546 default:
4547fail:
4548 MIPS_INVAL("bitops");
9c708c7f 4549 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4550 tcg_temp_free(t0);
4551 tcg_temp_free(t1);
7a387fff
TS
4552 return;
4553 }
6c5c1e20
TS
4554 gen_store_gpr(t0, rt);
4555 tcg_temp_free(t0);
4556 tcg_temp_free(t1);
7a387fff
TS
4557}
4558
49bcf33c
AJ
4559static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4560{
3a55fa47 4561 TCGv t0;
49bcf33c 4562
3a55fa47
AJ
4563 if (rd == 0) {
4564 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4565 return;
4566 }
4567
4568 t0 = tcg_temp_new();
4569 gen_load_gpr(t0, rt);
49bcf33c
AJ
4570 switch (op2) {
4571 case OPC_WSBH:
3a55fa47
AJ
4572 {
4573 TCGv t1 = tcg_temp_new();
4574
4575 tcg_gen_shri_tl(t1, t0, 8);
4576 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4577 tcg_gen_shli_tl(t0, t0, 8);
4578 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4579 tcg_gen_or_tl(t0, t0, t1);
4580 tcg_temp_free(t1);
4581 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4582 }
49bcf33c
AJ
4583 break;
4584 case OPC_SEB:
3a55fa47 4585 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4586 break;
4587 case OPC_SEH:
3a55fa47 4588 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4589 break;
4590#if defined(TARGET_MIPS64)
4591 case OPC_DSBH:
3a55fa47
AJ
4592 {
4593 TCGv t1 = tcg_temp_new();
4594
4595 tcg_gen_shri_tl(t1, t0, 8);
4596 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4597 tcg_gen_shli_tl(t0, t0, 8);
4598 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4599 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4600 tcg_temp_free(t1);
4601 }
49bcf33c
AJ
4602 break;
4603 case OPC_DSHD:
3a55fa47
AJ
4604 {
4605 TCGv t1 = tcg_temp_new();
4606
4607 tcg_gen_shri_tl(t1, t0, 16);
4608 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4609 tcg_gen_shli_tl(t0, t0, 16);
4610 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4611 tcg_gen_or_tl(t0, t0, t1);
4612 tcg_gen_shri_tl(t1, t0, 32);
4613 tcg_gen_shli_tl(t0, t0, 32);
4614 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4615 tcg_temp_free(t1);
4616 }
49bcf33c
AJ
4617 break;
4618#endif
4619 default:
4620 MIPS_INVAL("bsfhl");
9c708c7f 4621 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4622 tcg_temp_free(t0);
49bcf33c
AJ
4623 return;
4624 }
49bcf33c 4625 tcg_temp_free(t0);
49bcf33c
AJ
4626}
4627
1f1b4c00
YK
4628static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4629 int imm2)
4630{
4631 TCGv t0;
4632 TCGv t1;
4633 if (rd == 0) {
4634 /* Treat as NOP. */
4635 return;
4636 }
4637 t0 = tcg_temp_new();
4638 t1 = tcg_temp_new();
4639 gen_load_gpr(t0, rs);
4640 gen_load_gpr(t1, rt);
4641 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4642 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4643 if (opc == OPC_LSA) {
4644 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4645 }
4646
4647 tcg_temp_free(t1);
4648 tcg_temp_free(t0);
4649
4650 return;
4651}
4652
4653static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4654 int bp)
284b731a 4655{
1f1b4c00
YK
4656 TCGv t0;
4657 if (rd == 0) {
4658 /* Treat as NOP. */
4659 return;
4660 }
4661 t0 = tcg_temp_new();
4662 gen_load_gpr(t0, rt);
4663 if (bp == 0) {
51243852
MD
4664 switch (opc) {
4665 case OPC_ALIGN:
4666 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4667 break;
4668#if defined(TARGET_MIPS64)
4669 case OPC_DALIGN:
4670 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4671 break;
4672#endif
4673 }
1f1b4c00
YK
4674 } else {
4675 TCGv t1 = tcg_temp_new();
4676 gen_load_gpr(t1, rs);
4677 switch (opc) {
4678 case OPC_ALIGN:
4679 {
4680 TCGv_i64 t2 = tcg_temp_new_i64();
4681 tcg_gen_concat_tl_i64(t2, t1, t0);
4682 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4683 gen_move_low32(cpu_gpr[rd], t2);
4684 tcg_temp_free_i64(t2);
4685 }
4686 break;
284b731a 4687#if defined(TARGET_MIPS64)
1f1b4c00
YK
4688 case OPC_DALIGN:
4689 tcg_gen_shli_tl(t0, t0, 8 * bp);
4690 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4691 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4692 break;
284b731a 4693#endif
1f1b4c00
YK
4694 }
4695 tcg_temp_free(t1);
4696 }
4697
4698 tcg_temp_free(t0);
4699}
4700
4701static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4702{
4703 TCGv t0;
4704 if (rd == 0) {
4705 /* Treat as NOP. */
4706 return;
4707 }
4708 t0 = tcg_temp_new();
4709 gen_load_gpr(t0, rt);
4710 switch (opc) {
4711 case OPC_BITSWAP:
4712 gen_helper_bitswap(cpu_gpr[rd], t0);
4713 break;
4714#if defined(TARGET_MIPS64)
4715 case OPC_DBITSWAP:
4716 gen_helper_dbitswap(cpu_gpr[rd], t0);
4717 break;
4718#endif
4719 }
4720 tcg_temp_free(t0);
284b731a
LA
4721}
4722
1f1b4c00
YK
4723#ifndef CONFIG_USER_ONLY
4724/* CP0 (MMU and control) */
5204ea79
LA
4725static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4726{
4727 TCGv_i64 t0 = tcg_temp_new_i64();
4728 TCGv_i64 t1 = tcg_temp_new_i64();
4729
4730 tcg_gen_ext_tl_i64(t0, arg);
4731 tcg_gen_ld_i64(t1, cpu_env, off);
4732#if defined(TARGET_MIPS64)
4733 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4734#else
4735 tcg_gen_concat32_i64(t1, t1, t0);
4736#endif
4737 tcg_gen_st_i64(t1, cpu_env, off);
4738 tcg_temp_free_i64(t1);
4739 tcg_temp_free_i64(t0);
4740}
4741
4742static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4743{
4744 TCGv_i64 t0 = tcg_temp_new_i64();
4745 TCGv_i64 t1 = tcg_temp_new_i64();
4746
4747 tcg_gen_ext_tl_i64(t0, arg);
4748 tcg_gen_ld_i64(t1, cpu_env, off);
4749 tcg_gen_concat32_i64(t1, t1, t0);
4750 tcg_gen_st_i64(t1, cpu_env, off);
4751 tcg_temp_free_i64(t1);
4752 tcg_temp_free_i64(t0);
4753}
4754
4755static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4756{
4757 TCGv_i64 t0 = tcg_temp_new_i64();
4758
4759 tcg_gen_ld_i64(t0, cpu_env, off);
4760#if defined(TARGET_MIPS64)
4761 tcg_gen_shri_i64(t0, t0, 30);
4762#else
4763 tcg_gen_shri_i64(t0, t0, 32);
4764#endif
4765 gen_move_low32(arg, t0);
4766 tcg_temp_free_i64(t0);
4767}
4768
4769static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4770{
4771 TCGv_i64 t0 = tcg_temp_new_i64();
4772
4773 tcg_gen_ld_i64(t0, cpu_env, off);
4774 tcg_gen_shri_i64(t0, t0, 32 + shift);
4775 gen_move_low32(arg, t0);
4776 tcg_temp_free_i64(t0);
4777}
4778
d9bea114 4779static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4780{
d9bea114 4781 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4782
d9bea114
AJ
4783 tcg_gen_ld_i32(t0, cpu_env, off);
4784 tcg_gen_ext_i32_tl(arg, t0);
4785 tcg_temp_free_i32(t0);
4f57689a
TS
4786}
4787
d9bea114 4788static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4789{
d9bea114
AJ
4790 tcg_gen_ld_tl(arg, cpu_env, off);
4791 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4792}
4793
d9bea114 4794static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4795{
d9bea114 4796 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4797
d9bea114
AJ
4798 tcg_gen_trunc_tl_i32(t0, arg);
4799 tcg_gen_st_i32(t0, cpu_env, off);
4800 tcg_temp_free_i32(t0);
f1aa6320
TS
4801}
4802
c98d3d79
YK
4803#define CP0_CHECK(c) \
4804 do { \
4805 if (!(c)) { \
4806 goto cp0_unimplemented; \
4807 } \
4808 } while (0)
4809
5204ea79
LA
4810static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4811{
4812 const char *rn = "invalid";
4813
c98d3d79 4814 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4815
4816 switch (reg) {
4817 case 2:
4818 switch (sel) {
4819 case 0:
4820 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4821 rn = "EntryLo0";
4822 break;
4823 default:
c98d3d79 4824 goto cp0_unimplemented;
5204ea79
LA
4825 }
4826 break;
4827 case 3:
4828 switch (sel) {
4829 case 0:
4830 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4831 rn = "EntryLo1";
4832 break;
4833 default:
c98d3d79 4834 goto cp0_unimplemented;
5204ea79
LA
4835 }
4836 break;
4837 case 17:
4838 switch (sel) {
4839 case 0:
4840 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4841 ctx->CP0_LLAddr_shift);
4842 rn = "LLAddr";
4843 break;
f6d4dd81
YK
4844 case 1:
4845 CP0_CHECK(ctx->mrp);
4846 gen_helper_mfhc0_maar(arg, cpu_env);
4847 rn = "MAAR";
4848 break;
5204ea79 4849 default:
c98d3d79 4850 goto cp0_unimplemented;
5204ea79
LA
4851 }
4852 break;
4853 case 28:
4854 switch (sel) {
4855 case 0:
4856 case 2:
4857 case 4:
4858 case 6:
4859 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4860 rn = "TagLo";
4861 break;
4862 default:
c98d3d79 4863 goto cp0_unimplemented;
5204ea79
LA
4864 }
4865 break;
4866 default:
c98d3d79 4867 goto cp0_unimplemented;
5204ea79
LA
4868 }
4869
4870 (void)rn; /* avoid a compiler warning */
4871 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4872 return;
4873
c98d3d79 4874cp0_unimplemented:
965447ee 4875 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
4876 tcg_gen_movi_tl(arg, 0);
4877}
4878
4879static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4880{
4881 const char *rn = "invalid";
4882 uint64_t mask = ctx->PAMask >> 36;
4883
c98d3d79 4884 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4885
4886 switch (reg) {
4887 case 2:
4888 switch (sel) {
4889 case 0:
4890 tcg_gen_andi_tl(arg, arg, mask);
4891 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4892 rn = "EntryLo0";
4893 break;
4894 default:
c98d3d79 4895 goto cp0_unimplemented;
5204ea79
LA
4896 }
4897 break;
4898 case 3:
4899 switch (sel) {
4900 case 0:
4901 tcg_gen_andi_tl(arg, arg, mask);
4902 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4903 rn = "EntryLo1";
4904 break;
4905 default:
c98d3d79 4906 goto cp0_unimplemented;
5204ea79
LA
4907 }
4908 break;
4909 case 17:
4910 switch (sel) {
4911 case 0:
4912 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4913 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4914 relevant for modern MIPS cores supporting MTHC0, therefore
4915 treating MTHC0 to LLAddr as NOP. */
4916 rn = "LLAddr";
4917 break;
f6d4dd81
YK
4918 case 1:
4919 CP0_CHECK(ctx->mrp);
4920 gen_helper_mthc0_maar(cpu_env, arg);
4921 rn = "MAAR";
4922 break;
5204ea79 4923 default:
c98d3d79 4924 goto cp0_unimplemented;
5204ea79
LA
4925 }
4926 break;
4927 case 28:
4928 switch (sel) {
4929 case 0:
4930 case 2:
4931 case 4:
4932 case 6:
4933 tcg_gen_andi_tl(arg, arg, mask);
4934 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4935 rn = "TagLo";
4936 break;
4937 default:
c98d3d79 4938 goto cp0_unimplemented;
5204ea79
LA
4939 }
4940 break;
4941 default:
c98d3d79 4942 goto cp0_unimplemented;
5204ea79
LA
4943 }
4944
4945 (void)rn; /* avoid a compiler warning */
c98d3d79 4946cp0_unimplemented:
965447ee 4947 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
4948}
4949
e98c0d17
LA
4950static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4951{
4952 if (ctx->insn_flags & ISA_MIPS32R6) {
4953 tcg_gen_movi_tl(arg, 0);
4954 } else {
4955 tcg_gen_movi_tl(arg, ~0);
4956 }
4957}
4958
d75c135e 4959static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4960{
7a387fff 4961 const char *rn = "invalid";
873eb012 4962
e189e748 4963 if (sel != 0)
d75c135e 4964 check_insn(ctx, ISA_MIPS32);
e189e748 4965
873eb012
TS
4966 switch (reg) {
4967 case 0:
7a387fff
TS
4968 switch (sel) {
4969 case 0:
7db13fae 4970 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4971 rn = "Index";
4972 break;
4973 case 1:
f31b035a 4974 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4975 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4976 rn = "MVPControl";
ead9360e 4977 break;
7a387fff 4978 case 2:
f31b035a 4979 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4980 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4981 rn = "MVPConf0";
ead9360e 4982 break;
7a387fff 4983 case 3:
f31b035a 4984 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4985 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4986 rn = "MVPConf1";
ead9360e 4987 break;
01bc435b
YK
4988 case 4:
4989 CP0_CHECK(ctx->vp);
4990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4991 rn = "VPControl";
4992 break;
7a387fff 4993 default:
f31b035a 4994 goto cp0_unimplemented;
7a387fff 4995 }
873eb012
TS
4996 break;
4997 case 1:
7a387fff
TS
4998 switch (sel) {
4999 case 0:
f31b035a 5000 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5001 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5002 rn = "Random";
2423f660 5003 break;
7a387fff 5004 case 1:
f31b035a 5005 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5006 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5007 rn = "VPEControl";
ead9360e 5008 break;
7a387fff 5009 case 2:
f31b035a 5010 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5012 rn = "VPEConf0";
ead9360e 5013 break;
7a387fff 5014 case 3:
f31b035a 5015 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5017 rn = "VPEConf1";
ead9360e 5018 break;
7a387fff 5019 case 4:
f31b035a 5020 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5021 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5022 rn = "YQMask";
ead9360e 5023 break;
7a387fff 5024 case 5:
f31b035a 5025 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5026 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5027 rn = "VPESchedule";
ead9360e 5028 break;
7a387fff 5029 case 6:
f31b035a 5030 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5031 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5032 rn = "VPEScheFBack";
ead9360e 5033 break;
7a387fff 5034 case 7:
f31b035a 5035 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5036 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5037 rn = "VPEOpt";
ead9360e 5038 break;
7a387fff 5039 default:
f31b035a 5040 goto cp0_unimplemented;
7a387fff 5041 }
873eb012
TS
5042 break;
5043 case 2:
7a387fff
TS
5044 switch (sel) {
5045 case 0:
284b731a
LA
5046 {
5047 TCGv_i64 tmp = tcg_temp_new_i64();
5048 tcg_gen_ld_i64(tmp, cpu_env,
5049 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5050#if defined(TARGET_MIPS64)
284b731a
LA
5051 if (ctx->rxi) {
5052 /* Move RI/XI fields to bits 31:30 */
5053 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5054 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5055 }
7207c7f9 5056#endif
284b731a
LA
5057 gen_move_low32(arg, tmp);
5058 tcg_temp_free_i64(tmp);
5059 }
2423f660
TS
5060 rn = "EntryLo0";
5061 break;
7a387fff 5062 case 1:
f31b035a 5063 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5064 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5065 rn = "TCStatus";
ead9360e 5066 break;
7a387fff 5067 case 2:
f31b035a 5068 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5069 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5070 rn = "TCBind";
ead9360e 5071 break;
7a387fff 5072 case 3:
f31b035a 5073 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5074 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5075 rn = "TCRestart";
ead9360e 5076 break;
7a387fff 5077 case 4:
f31b035a 5078 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5079 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5080 rn = "TCHalt";
ead9360e 5081 break;
7a387fff 5082 case 5:
f31b035a 5083 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5084 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5085 rn = "TCContext";
ead9360e 5086 break;
7a387fff 5087 case 6:
f31b035a 5088 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5089 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5090 rn = "TCSchedule";
ead9360e 5091 break;
7a387fff 5092 case 7:
f31b035a 5093 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5094 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5095 rn = "TCScheFBack";
ead9360e 5096 break;
7a387fff 5097 default:
f31b035a 5098 goto cp0_unimplemented;
7a387fff 5099 }
873eb012
TS
5100 break;
5101 case 3:
7a387fff
TS
5102 switch (sel) {
5103 case 0:
284b731a
LA
5104 {
5105 TCGv_i64 tmp = tcg_temp_new_i64();
5106 tcg_gen_ld_i64(tmp, cpu_env,
5107 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5108#if defined(TARGET_MIPS64)
284b731a
LA
5109 if (ctx->rxi) {
5110 /* Move RI/XI fields to bits 31:30 */
5111 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5112 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5113 }
7207c7f9 5114#endif
284b731a
LA
5115 gen_move_low32(arg, tmp);
5116 tcg_temp_free_i64(tmp);
5117 }
2423f660
TS
5118 rn = "EntryLo1";
5119 break;
01bc435b
YK
5120 case 1:
5121 CP0_CHECK(ctx->vp);
5122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5123 rn = "GlobalNumber";
5124 break;
7a387fff 5125 default:
f31b035a 5126 goto cp0_unimplemented;
1579a72e 5127 }
873eb012
TS
5128 break;
5129 case 4:
7a387fff
TS
5130 switch (sel) {
5131 case 0:
7db13fae 5132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5133 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5134 rn = "Context";
5135 break;
7a387fff 5136 case 1:
d9bea114 5137// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5138 rn = "ContextConfig";
f31b035a 5139 goto cp0_unimplemented;
d279279e 5140 case 2:
f31b035a
LA
5141 CP0_CHECK(ctx->ulri);
5142 tcg_gen_ld32s_tl(arg, cpu_env,
5143 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5144 rn = "UserLocal";
d279279e 5145 break;
7a387fff 5146 default:
f31b035a 5147 goto cp0_unimplemented;
1579a72e 5148 }
873eb012
TS
5149 break;
5150 case 5:
7a387fff
TS
5151 switch (sel) {
5152 case 0:
7db13fae 5153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5154 rn = "PageMask";
5155 break;
7a387fff 5156 case 1:
d75c135e 5157 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5159 rn = "PageGrain";
5160 break;
7a387fff 5161 default:
f31b035a 5162 goto cp0_unimplemented;
1579a72e 5163 }
873eb012
TS
5164 break;
5165 case 6:
7a387fff
TS
5166 switch (sel) {
5167 case 0:
7db13fae 5168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5169 rn = "Wired";
5170 break;
7a387fff 5171 case 1:
d75c135e 5172 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5174 rn = "SRSConf0";
ead9360e 5175 break;
7a387fff 5176 case 2:
d75c135e 5177 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5179 rn = "SRSConf1";
ead9360e 5180 break;
7a387fff 5181 case 3:
d75c135e 5182 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5184 rn = "SRSConf2";
ead9360e 5185 break;
7a387fff 5186 case 4:
d75c135e 5187 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5188 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5189 rn = "SRSConf3";
ead9360e 5190 break;
7a387fff 5191 case 5:
d75c135e 5192 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5194 rn = "SRSConf4";
ead9360e 5195 break;
7a387fff 5196 default:
f31b035a 5197 goto cp0_unimplemented;
1579a72e 5198 }
873eb012 5199 break;
8c0fdd85 5200 case 7:
7a387fff
TS
5201 switch (sel) {
5202 case 0:
d75c135e 5203 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5205 rn = "HWREna";
5206 break;
7a387fff 5207 default:
f31b035a 5208 goto cp0_unimplemented;
1579a72e 5209 }
8c0fdd85 5210 break;
873eb012 5211 case 8:
7a387fff
TS
5212 switch (sel) {
5213 case 0:
7db13fae 5214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5215 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5216 rn = "BadVAddr";
2423f660 5217 break;
aea14095 5218 case 1:
f31b035a
LA
5219 CP0_CHECK(ctx->bi);
5220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5221 rn = "BadInstr";
aea14095
LA
5222 break;
5223 case 2:
f31b035a
LA
5224 CP0_CHECK(ctx->bp);
5225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5226 rn = "BadInstrP";
aea14095 5227 break;
7a387fff 5228 default:
f31b035a 5229 goto cp0_unimplemented;
aea14095 5230 }
873eb012
TS
5231 break;
5232 case 9:
7a387fff
TS
5233 switch (sel) {
5234 case 0:
2e70f6ef 5235 /* Mark as an IO operation because we read the time. */
bd79255d 5236 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5237 gen_io_start();
bd79255d 5238 }
895c2d04 5239 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5240 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5241 gen_io_end();
2e70f6ef 5242 }
55807224
EI
5243 /* Break the TB to be able to take timer interrupts immediately
5244 after reading count. */
5245 ctx->bstate = BS_STOP;
2423f660
TS
5246 rn = "Count";
5247 break;
5248 /* 6,7 are implementation dependent */
7a387fff 5249 default:
f31b035a 5250 goto cp0_unimplemented;
2423f660 5251 }
873eb012
TS
5252 break;
5253 case 10:
7a387fff
TS
5254 switch (sel) {
5255 case 0:
7db13fae 5256 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5257 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5258 rn = "EntryHi";
5259 break;
7a387fff 5260 default:
f31b035a 5261 goto cp0_unimplemented;
1579a72e 5262 }
873eb012
TS
5263 break;
5264 case 11:
7a387fff
TS
5265 switch (sel) {
5266 case 0:
7db13fae 5267 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5268 rn = "Compare";
5269 break;
5270 /* 6,7 are implementation dependent */
7a387fff 5271 default:
f31b035a 5272 goto cp0_unimplemented;
2423f660 5273 }
873eb012
TS
5274 break;
5275 case 12:
7a387fff
TS
5276 switch (sel) {
5277 case 0:
7db13fae 5278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5279 rn = "Status";
5280 break;
7a387fff 5281 case 1:
d75c135e 5282 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5284 rn = "IntCtl";
5285 break;
7a387fff 5286 case 2:
d75c135e 5287 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5289 rn = "SRSCtl";
5290 break;
7a387fff 5291 case 3:
d75c135e 5292 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5294 rn = "SRSMap";
fd88b6ab 5295 break;
7a387fff 5296 default:
f31b035a 5297 goto cp0_unimplemented;
7a387fff 5298 }
873eb012
TS
5299 break;
5300 case 13:
7a387fff
TS
5301 switch (sel) {
5302 case 0:
7db13fae 5303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5304 rn = "Cause";
5305 break;
7a387fff 5306 default:
f31b035a 5307 goto cp0_unimplemented;
7a387fff 5308 }
873eb012
TS
5309 break;
5310 case 14:
7a387fff
TS
5311 switch (sel) {
5312 case 0:
7db13fae 5313 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5314 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5315 rn = "EPC";
5316 break;
7a387fff 5317 default:
f31b035a 5318 goto cp0_unimplemented;
1579a72e 5319 }
873eb012
TS
5320 break;
5321 case 15:
7a387fff
TS
5322 switch (sel) {
5323 case 0:
7db13fae 5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5325 rn = "PRid";
5326 break;
7a387fff 5327 case 1:
d75c135e 5328 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5330 rn = "EBase";
5331 break;
c870e3f5
YK
5332 case 3:
5333 check_insn(ctx, ISA_MIPS32R2);
5334 CP0_CHECK(ctx->cmgcr);
5335 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5336 tcg_gen_ext32s_tl(arg, arg);
5337 rn = "CMGCRBase";
5338 break;
7a387fff 5339 default:
f31b035a 5340 goto cp0_unimplemented;
7a387fff 5341 }
873eb012
TS
5342 break;
5343 case 16:
5344 switch (sel) {
5345 case 0:
7db13fae 5346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5347 rn = "Config";
5348 break;
5349 case 1:
7db13fae 5350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5351 rn = "Config1";
5352 break;
7a387fff 5353 case 2:
7db13fae 5354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5355 rn = "Config2";
5356 break;
5357 case 3:
7db13fae 5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5359 rn = "Config3";
5360 break;
b4160af1
PJ
5361 case 4:
5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5363 rn = "Config4";
5364 break;
b4dd99a3
PJ
5365 case 5:
5366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5367 rn = "Config5";
5368 break;
e397ee33
TS
5369 /* 6,7 are implementation dependent */
5370 case 6:
7db13fae 5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5372 rn = "Config6";
5373 break;
5374 case 7:
7db13fae 5375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5376 rn = "Config7";
5377 break;
873eb012 5378 default:
f31b035a 5379 goto cp0_unimplemented;
873eb012
TS
5380 }
5381 break;
5382 case 17:
7a387fff
TS
5383 switch (sel) {
5384 case 0:
895c2d04 5385 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5386 rn = "LLAddr";
5387 break;
f6d4dd81
YK
5388 case 1:
5389 CP0_CHECK(ctx->mrp);
5390 gen_helper_mfc0_maar(arg, cpu_env);
5391 rn = "MAAR";
5392 break;
5393 case 2:
5394 CP0_CHECK(ctx->mrp);
5395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5396 rn = "MAARI";
5397 break;
7a387fff 5398 default:
f31b035a 5399 goto cp0_unimplemented;
7a387fff 5400 }
873eb012
TS
5401 break;
5402 case 18:
7a387fff 5403 switch (sel) {
fd88b6ab 5404 case 0 ... 7:
895c2d04 5405 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5406 rn = "WatchLo";
5407 break;
7a387fff 5408 default:
f31b035a 5409 goto cp0_unimplemented;
7a387fff 5410 }
873eb012
TS
5411 break;
5412 case 19:
7a387fff 5413 switch (sel) {
fd88b6ab 5414 case 0 ...7:
895c2d04 5415 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5416 rn = "WatchHi";
5417 break;
7a387fff 5418 default:
f31b035a 5419 goto cp0_unimplemented;
7a387fff 5420 }
873eb012 5421 break;
8c0fdd85 5422 case 20:
7a387fff
TS
5423 switch (sel) {
5424 case 0:
d26bc211 5425#if defined(TARGET_MIPS64)
d75c135e 5426 check_insn(ctx, ISA_MIPS3);
7db13fae 5427 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5428 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5429 rn = "XContext";
5430 break;
703eaf37 5431#endif
7a387fff 5432 default:
f31b035a 5433 goto cp0_unimplemented;
7a387fff 5434 }
8c0fdd85
TS
5435 break;
5436 case 21:
7a387fff 5437 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5438 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5439 switch (sel) {
5440 case 0:
7db13fae 5441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5442 rn = "Framemask";
5443 break;
7a387fff 5444 default:
f31b035a 5445 goto cp0_unimplemented;
7a387fff 5446 }
8c0fdd85
TS
5447 break;
5448 case 22:
d9bea114 5449 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5450 rn = "'Diagnostic"; /* implementation dependent */
5451 break;
873eb012 5452 case 23:
7a387fff
TS
5453 switch (sel) {
5454 case 0:
895c2d04 5455 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5456 rn = "Debug";
5457 break;
7a387fff 5458 case 1:
d9bea114 5459// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5460 rn = "TraceControl";
5461// break;
7a387fff 5462 case 2:
d9bea114 5463// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5464 rn = "TraceControl2";
5465// break;
7a387fff 5466 case 3:
d9bea114 5467// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5468 rn = "UserTraceData";
5469// break;
7a387fff 5470 case 4:
d9bea114 5471// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5472 rn = "TraceBPC";
5473// break;
7a387fff 5474 default:
f31b035a 5475 goto cp0_unimplemented;
7a387fff 5476 }
873eb012
TS
5477 break;
5478 case 24:
7a387fff
TS
5479 switch (sel) {
5480 case 0:
f0b3f3ae 5481 /* EJTAG support */
7db13fae 5482 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5483 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5484 rn = "DEPC";
5485 break;
7a387fff 5486 default:
f31b035a 5487 goto cp0_unimplemented;
7a387fff 5488 }
873eb012 5489 break;
8c0fdd85 5490 case 25:
7a387fff
TS
5491 switch (sel) {
5492 case 0:
7db13fae 5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5494 rn = "Performance0";
7a387fff
TS
5495 break;
5496 case 1:
d9bea114 5497// gen_helper_mfc0_performance1(arg);
2423f660
TS
5498 rn = "Performance1";
5499// break;
7a387fff 5500 case 2:
d9bea114 5501// gen_helper_mfc0_performance2(arg);
2423f660
TS
5502 rn = "Performance2";
5503// break;
7a387fff 5504 case 3:
d9bea114 5505// gen_helper_mfc0_performance3(arg);
2423f660
TS
5506 rn = "Performance3";
5507// break;
7a387fff 5508 case 4:
d9bea114 5509// gen_helper_mfc0_performance4(arg);
2423f660
TS
5510 rn = "Performance4";
5511// break;
7a387fff 5512 case 5:
d9bea114 5513// gen_helper_mfc0_performance5(arg);
2423f660
TS
5514 rn = "Performance5";
5515// break;
7a387fff 5516 case 6:
d9bea114 5517// gen_helper_mfc0_performance6(arg);
2423f660
TS
5518 rn = "Performance6";
5519// break;
7a387fff 5520 case 7:
d9bea114 5521// gen_helper_mfc0_performance7(arg);
2423f660
TS
5522 rn = "Performance7";
5523// break;
7a387fff 5524 default:
f31b035a 5525 goto cp0_unimplemented;
7a387fff 5526 }
8c0fdd85
TS
5527 break;
5528 case 26:
0d74a222
LA
5529 switch (sel) {
5530 case 0:
5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5532 rn = "ErrCtl";
5533 break;
5534 default:
5535 goto cp0_unimplemented;
5536 }
da80682b 5537 break;
8c0fdd85 5538 case 27:
7a387fff 5539 switch (sel) {
7a387fff 5540 case 0 ... 3:
d9bea114 5541 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5542 rn = "CacheErr";
5543 break;
7a387fff 5544 default:
f31b035a 5545 goto cp0_unimplemented;
7a387fff 5546 }
8c0fdd85 5547 break;
873eb012
TS
5548 case 28:
5549 switch (sel) {
5550 case 0:
7a387fff
TS
5551 case 2:
5552 case 4:
5553 case 6:
284b731a
LA
5554 {
5555 TCGv_i64 tmp = tcg_temp_new_i64();
5556 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5557 gen_move_low32(arg, tmp);
5558 tcg_temp_free_i64(tmp);
5559 }
873eb012
TS
5560 rn = "TagLo";
5561 break;
5562 case 1:
7a387fff
TS
5563 case 3:
5564 case 5:
5565 case 7:
7db13fae 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5567 rn = "DataLo";
5568 break;
5569 default:
f31b035a 5570 goto cp0_unimplemented;
873eb012
TS
5571 }
5572 break;
8c0fdd85 5573 case 29:
7a387fff
TS
5574 switch (sel) {
5575 case 0:
5576 case 2:
5577 case 4:
5578 case 6:
7db13fae 5579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5580 rn = "TagHi";
5581 break;
5582 case 1:
5583 case 3:
5584 case 5:
5585 case 7:
7db13fae 5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5587 rn = "DataHi";
5588 break;
5589 default:
f31b035a 5590 goto cp0_unimplemented;
7a387fff 5591 }
8c0fdd85 5592 break;
873eb012 5593 case 30:
7a387fff
TS
5594 switch (sel) {
5595 case 0:
7db13fae 5596 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5597 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5598 rn = "ErrorEPC";
5599 break;
7a387fff 5600 default:
f31b035a 5601 goto cp0_unimplemented;
7a387fff 5602 }
873eb012
TS
5603 break;
5604 case 31:
7a387fff
TS
5605 switch (sel) {
5606 case 0:
f0b3f3ae 5607 /* EJTAG support */
7db13fae 5608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5609 rn = "DESAVE";
5610 break;
e98c0d17 5611 case 2 ... 7:
f31b035a
LA
5612 CP0_CHECK(ctx->kscrexist & (1 << sel));
5613 tcg_gen_ld_tl(arg, cpu_env,
5614 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5615 tcg_gen_ext32s_tl(arg, arg);
5616 rn = "KScratch";
e98c0d17 5617 break;
7a387fff 5618 default:
f31b035a 5619 goto cp0_unimplemented;
7a387fff 5620 }
873eb012
TS
5621 break;
5622 default:
f31b035a 5623 goto cp0_unimplemented;
873eb012 5624 }
2abf314d 5625 (void)rn; /* avoid a compiler warning */
d12d51d5 5626 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5627 return;
5628
f31b035a 5629cp0_unimplemented:
965447ee 5630 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5631 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5632}
5633
d75c135e 5634static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5635{
7a387fff
TS
5636 const char *rn = "invalid";
5637
e189e748 5638 if (sel != 0)
d75c135e 5639 check_insn(ctx, ISA_MIPS32);
e189e748 5640
bd79255d 5641 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5642 gen_io_start();
bd79255d 5643 }
2e70f6ef 5644
8c0fdd85
TS
5645 switch (reg) {
5646 case 0:
7a387fff
TS
5647 switch (sel) {
5648 case 0:
895c2d04 5649 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5650 rn = "Index";
5651 break;
5652 case 1:
f31b035a 5653 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5654 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5655 rn = "MVPControl";
ead9360e 5656 break;
7a387fff 5657 case 2:
f31b035a 5658 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5659 /* ignored */
7a387fff 5660 rn = "MVPConf0";
ead9360e 5661 break;
7a387fff 5662 case 3:
f31b035a 5663 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5664 /* ignored */
7a387fff 5665 rn = "MVPConf1";
ead9360e 5666 break;
01bc435b
YK
5667 case 4:
5668 CP0_CHECK(ctx->vp);
5669 /* ignored */
5670 rn = "VPControl";
5671 break;
7a387fff 5672 default:
f31b035a 5673 goto cp0_unimplemented;
7a387fff 5674 }
8c0fdd85
TS
5675 break;
5676 case 1:
7a387fff
TS
5677 switch (sel) {
5678 case 0:
2423f660 5679 /* ignored */
7a387fff 5680 rn = "Random";
2423f660 5681 break;
7a387fff 5682 case 1:
f31b035a 5683 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5684 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5685 rn = "VPEControl";
ead9360e 5686 break;
7a387fff 5687 case 2:
f31b035a 5688 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5689 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5690 rn = "VPEConf0";
ead9360e 5691 break;
7a387fff 5692 case 3:
f31b035a 5693 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5694 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5695 rn = "VPEConf1";
ead9360e 5696 break;
7a387fff 5697 case 4:
f31b035a 5698 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5699 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5700 rn = "YQMask";
ead9360e 5701 break;
7a387fff 5702 case 5:
f31b035a 5703 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5704 tcg_gen_st_tl(arg, cpu_env,
5705 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5706 rn = "VPESchedule";
ead9360e 5707 break;
7a387fff 5708 case 6:
f31b035a 5709 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5710 tcg_gen_st_tl(arg, cpu_env,
5711 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5712 rn = "VPEScheFBack";
ead9360e 5713 break;
7a387fff 5714 case 7:
f31b035a 5715 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5716 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5717 rn = "VPEOpt";
ead9360e 5718 break;
7a387fff 5719 default:
f31b035a 5720 goto cp0_unimplemented;
7a387fff 5721 }
8c0fdd85
TS
5722 break;
5723 case 2:
7a387fff
TS
5724 switch (sel) {
5725 case 0:
895c2d04 5726 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5727 rn = "EntryLo0";
5728 break;
7a387fff 5729 case 1:
f31b035a 5730 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5731 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5732 rn = "TCStatus";
ead9360e 5733 break;
7a387fff 5734 case 2:
f31b035a 5735 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5736 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5737 rn = "TCBind";
ead9360e 5738 break;
7a387fff 5739 case 3:
f31b035a 5740 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5741 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5742 rn = "TCRestart";
ead9360e 5743 break;
7a387fff 5744 case 4:
f31b035a 5745 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5746 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5747 rn = "TCHalt";
ead9360e 5748 break;
7a387fff 5749 case 5:
f31b035a 5750 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5751 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5752 rn = "TCContext";
ead9360e 5753 break;
7a387fff 5754 case 6:
f31b035a 5755 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5756 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5757 rn = "TCSchedule";
ead9360e 5758 break;
7a387fff 5759 case 7:
f31b035a 5760 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5761 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5762 rn = "TCScheFBack";
ead9360e 5763 break;
7a387fff 5764 default:
f31b035a 5765 goto cp0_unimplemented;
7a387fff 5766 }
8c0fdd85
TS
5767 break;
5768 case 3:
7a387fff
TS
5769 switch (sel) {
5770 case 0:
895c2d04 5771 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5772 rn = "EntryLo1";
5773 break;
01bc435b
YK
5774 case 1:
5775 CP0_CHECK(ctx->vp);
5776 /* ignored */
5777 rn = "GlobalNumber";
5778 break;
7a387fff 5779 default:
f31b035a 5780 goto cp0_unimplemented;
876d4b07 5781 }
8c0fdd85
TS
5782 break;
5783 case 4:
7a387fff
TS
5784 switch (sel) {
5785 case 0:
895c2d04 5786 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5787 rn = "Context";
5788 break;
7a387fff 5789 case 1:
895c2d04 5790// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5791 rn = "ContextConfig";
f31b035a 5792 goto cp0_unimplemented;
d279279e 5793 case 2:
f31b035a
LA
5794 CP0_CHECK(ctx->ulri);
5795 tcg_gen_st_tl(arg, cpu_env,
5796 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5797 rn = "UserLocal";
d279279e 5798 break;
7a387fff 5799 default:
f31b035a 5800 goto cp0_unimplemented;
876d4b07 5801 }
8c0fdd85
TS
5802 break;
5803 case 5:
7a387fff
TS
5804 switch (sel) {
5805 case 0:
895c2d04 5806 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5807 rn = "PageMask";
5808 break;
7a387fff 5809 case 1:
d75c135e 5810 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5811 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5812 rn = "PageGrain";
e117f526 5813 ctx->bstate = BS_STOP;
2423f660 5814 break;
7a387fff 5815 default:
f31b035a 5816 goto cp0_unimplemented;
876d4b07 5817 }
8c0fdd85
TS
5818 break;
5819 case 6:
7a387fff
TS
5820 switch (sel) {
5821 case 0:
895c2d04 5822 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5823 rn = "Wired";
5824 break;
7a387fff 5825 case 1:
d75c135e 5826 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5827 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5828 rn = "SRSConf0";
ead9360e 5829 break;
7a387fff 5830 case 2:
d75c135e 5831 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5832 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5833 rn = "SRSConf1";
ead9360e 5834 break;
7a387fff 5835 case 3:
d75c135e 5836 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5837 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5838 rn = "SRSConf2";
ead9360e 5839 break;
7a387fff 5840 case 4:
d75c135e 5841 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5842 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5843 rn = "SRSConf3";
ead9360e 5844 break;
7a387fff 5845 case 5:
d75c135e 5846 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5847 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5848 rn = "SRSConf4";
ead9360e 5849 break;
7a387fff 5850 default:
f31b035a 5851 goto cp0_unimplemented;
876d4b07 5852 }
8c0fdd85
TS
5853 break;
5854 case 7:
7a387fff
TS
5855 switch (sel) {
5856 case 0:
d75c135e 5857 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5858 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5859 ctx->bstate = BS_STOP;
2423f660
TS
5860 rn = "HWREna";
5861 break;
7a387fff 5862 default:
f31b035a 5863 goto cp0_unimplemented;
876d4b07 5864 }
8c0fdd85
TS
5865 break;
5866 case 8:
aea14095
LA
5867 switch (sel) {
5868 case 0:
5869 /* ignored */
5870 rn = "BadVAddr";
5871 break;
5872 case 1:
5873 /* ignored */
5874 rn = "BadInstr";
5875 break;
5876 case 2:
5877 /* ignored */
5878 rn = "BadInstrP";
5879 break;
5880 default:
f31b035a 5881 goto cp0_unimplemented;
aea14095 5882 }
8c0fdd85
TS
5883 break;
5884 case 9:
7a387fff
TS
5885 switch (sel) {
5886 case 0:
895c2d04 5887 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5888 rn = "Count";
5889 break;
876d4b07 5890 /* 6,7 are implementation dependent */
7a387fff 5891 default:
f31b035a 5892 goto cp0_unimplemented;
876d4b07 5893 }
8c0fdd85
TS
5894 break;
5895 case 10:
7a387fff
TS
5896 switch (sel) {
5897 case 0:
895c2d04 5898 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5899 rn = "EntryHi";
5900 break;
7a387fff 5901 default:
f31b035a 5902 goto cp0_unimplemented;
876d4b07 5903 }
8c0fdd85
TS
5904 break;
5905 case 11:
7a387fff
TS
5906 switch (sel) {
5907 case 0:
895c2d04 5908 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5909 rn = "Compare";
5910 break;
5911 /* 6,7 are implementation dependent */
7a387fff 5912 default:
f31b035a 5913 goto cp0_unimplemented;
876d4b07 5914 }
8c0fdd85
TS
5915 break;
5916 case 12:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
867abc7e 5919 save_cpu_state(ctx, 1);
895c2d04 5920 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5921 /* BS_STOP isn't good enough here, hflags may have changed. */
5922 gen_save_pc(ctx->pc + 4);
5923 ctx->bstate = BS_EXCP;
2423f660
TS
5924 rn = "Status";
5925 break;
7a387fff 5926 case 1:
d75c135e 5927 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5928 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5929 /* Stop translation as we may have switched the execution mode */
5930 ctx->bstate = BS_STOP;
2423f660
TS
5931 rn = "IntCtl";
5932 break;
7a387fff 5933 case 2:
d75c135e 5934 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5935 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5936 /* Stop translation as we may have switched the execution mode */
5937 ctx->bstate = BS_STOP;
2423f660
TS
5938 rn = "SRSCtl";
5939 break;
7a387fff 5940 case 3:
d75c135e 5941 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5942 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5943 /* Stop translation as we may have switched the execution mode */
5944 ctx->bstate = BS_STOP;
2423f660 5945 rn = "SRSMap";
fd88b6ab 5946 break;
7a387fff 5947 default:
f31b035a 5948 goto cp0_unimplemented;
876d4b07 5949 }
8c0fdd85
TS
5950 break;
5951 case 13:
7a387fff
TS
5952 switch (sel) {
5953 case 0:
867abc7e 5954 save_cpu_state(ctx, 1);
895c2d04 5955 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5956 rn = "Cause";
5957 break;
7a387fff 5958 default:
f31b035a 5959 goto cp0_unimplemented;
876d4b07 5960 }
8c0fdd85
TS
5961 break;
5962 case 14:
7a387fff
TS
5963 switch (sel) {
5964 case 0:
d54a299b 5965 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5966 rn = "EPC";
5967 break;
7a387fff 5968 default:
f31b035a 5969 goto cp0_unimplemented;
876d4b07 5970 }
8c0fdd85
TS
5971 break;
5972 case 15:
7a387fff
TS
5973 switch (sel) {
5974 case 0:
2423f660
TS
5975 /* ignored */
5976 rn = "PRid";
5977 break;
7a387fff 5978 case 1:
d75c135e 5979 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5980 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5981 rn = "EBase";
5982 break;
7a387fff 5983 default:
f31b035a 5984 goto cp0_unimplemented;
1579a72e 5985 }
8c0fdd85
TS
5986 break;
5987 case 16:
5988 switch (sel) {
5989 case 0:
895c2d04 5990 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5991 rn = "Config";
2423f660
TS
5992 /* Stop translation as we may have switched the execution mode */
5993 ctx->bstate = BS_STOP;
7a387fff
TS
5994 break;
5995 case 1:
e397ee33 5996 /* ignored, read only */
7a387fff
TS
5997 rn = "Config1";
5998 break;
5999 case 2:
895c2d04 6000 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6001 rn = "Config2";
2423f660
TS
6002 /* Stop translation as we may have switched the execution mode */
6003 ctx->bstate = BS_STOP;
8c0fdd85 6004 break;
7a387fff 6005 case 3:
90f12d73 6006 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6007 rn = "Config3";
90f12d73
MR
6008 /* Stop translation as we may have switched the execution mode */
6009 ctx->bstate = BS_STOP;
7a387fff 6010 break;
b4160af1
PJ
6011 case 4:
6012 gen_helper_mtc0_config4(cpu_env, arg);
6013 rn = "Config4";
6014 ctx->bstate = BS_STOP;
6015 break;
b4dd99a3
PJ
6016 case 5:
6017 gen_helper_mtc0_config5(cpu_env, arg);
6018 rn = "Config5";
6019 /* Stop translation as we may have switched the execution mode */
6020 ctx->bstate = BS_STOP;
6021 break;
e397ee33
TS
6022 /* 6,7 are implementation dependent */
6023 case 6:
6024 /* ignored */
6025 rn = "Config6";
6026 break;
6027 case 7:
6028 /* ignored */
6029 rn = "Config7";
6030 break;
8c0fdd85
TS
6031 default:
6032 rn = "Invalid config selector";
f31b035a 6033 goto cp0_unimplemented;
8c0fdd85
TS
6034 }
6035 break;
6036 case 17:
7a387fff
TS
6037 switch (sel) {
6038 case 0:
895c2d04 6039 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6040 rn = "LLAddr";
6041 break;
f6d4dd81
YK
6042 case 1:
6043 CP0_CHECK(ctx->mrp);
6044 gen_helper_mtc0_maar(cpu_env, arg);
6045 rn = "MAAR";
6046 break;
6047 case 2:
6048 CP0_CHECK(ctx->mrp);
6049 gen_helper_mtc0_maari(cpu_env, arg);
6050 rn = "MAARI";
6051 break;
7a387fff 6052 default:
f31b035a 6053 goto cp0_unimplemented;
7a387fff 6054 }
8c0fdd85
TS
6055 break;
6056 case 18:
7a387fff 6057 switch (sel) {
fd88b6ab 6058 case 0 ... 7:
895c2d04 6059 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6060 rn = "WatchLo";
6061 break;
7a387fff 6062 default:
f31b035a 6063 goto cp0_unimplemented;
7a387fff 6064 }
8c0fdd85
TS
6065 break;
6066 case 19:
7a387fff 6067 switch (sel) {
fd88b6ab 6068 case 0 ... 7:
895c2d04 6069 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6070 rn = "WatchHi";
6071 break;
7a387fff 6072 default:
f31b035a 6073 goto cp0_unimplemented;
7a387fff 6074 }
8c0fdd85
TS
6075 break;
6076 case 20:
7a387fff
TS
6077 switch (sel) {
6078 case 0:
d26bc211 6079#if defined(TARGET_MIPS64)
d75c135e 6080 check_insn(ctx, ISA_MIPS3);
895c2d04 6081 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6082 rn = "XContext";
6083 break;
703eaf37 6084#endif
7a387fff 6085 default:
f31b035a 6086 goto cp0_unimplemented;
7a387fff 6087 }
8c0fdd85
TS
6088 break;
6089 case 21:
7a387fff 6090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6091 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6092 switch (sel) {
6093 case 0:
895c2d04 6094 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6095 rn = "Framemask";
6096 break;
7a387fff 6097 default:
f31b035a 6098 goto cp0_unimplemented;
7a387fff
TS
6099 }
6100 break;
8c0fdd85 6101 case 22:
7a387fff
TS
6102 /* ignored */
6103 rn = "Diagnostic"; /* implementation dependent */
2423f660 6104 break;
8c0fdd85 6105 case 23:
7a387fff
TS
6106 switch (sel) {
6107 case 0:
895c2d04 6108 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6109 /* BS_STOP isn't good enough here, hflags may have changed. */
6110 gen_save_pc(ctx->pc + 4);
6111 ctx->bstate = BS_EXCP;
2423f660
TS
6112 rn = "Debug";
6113 break;
7a387fff 6114 case 1:
895c2d04 6115// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6116 rn = "TraceControl";
8487327a
TS
6117 /* Stop translation as we may have switched the execution mode */
6118 ctx->bstate = BS_STOP;
2423f660 6119// break;
7a387fff 6120 case 2:
895c2d04 6121// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6122 rn = "TraceControl2";
8487327a
TS
6123 /* Stop translation as we may have switched the execution mode */
6124 ctx->bstate = BS_STOP;
2423f660 6125// break;
7a387fff 6126 case 3:
8487327a
TS
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
895c2d04 6129// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6130 rn = "UserTraceData";
8487327a
TS
6131 /* Stop translation as we may have switched the execution mode */
6132 ctx->bstate = BS_STOP;
2423f660 6133// break;
7a387fff 6134 case 4:
895c2d04 6135// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6136 /* Stop translation as we may have switched the execution mode */
6137 ctx->bstate = BS_STOP;
2423f660
TS
6138 rn = "TraceBPC";
6139// break;
7a387fff 6140 default:
f31b035a 6141 goto cp0_unimplemented;
7a387fff 6142 }
8c0fdd85
TS
6143 break;
6144 case 24:
7a387fff
TS
6145 switch (sel) {
6146 case 0:
f1aa6320 6147 /* EJTAG support */
d54a299b 6148 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6149 rn = "DEPC";
6150 break;
7a387fff 6151 default:
f31b035a 6152 goto cp0_unimplemented;
7a387fff 6153 }
8c0fdd85
TS
6154 break;
6155 case 25:
7a387fff
TS
6156 switch (sel) {
6157 case 0:
895c2d04 6158 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6159 rn = "Performance0";
6160 break;
7a387fff 6161 case 1:
d9bea114 6162// gen_helper_mtc0_performance1(arg);
2423f660
TS
6163 rn = "Performance1";
6164// break;
7a387fff 6165 case 2:
d9bea114 6166// gen_helper_mtc0_performance2(arg);
2423f660
TS
6167 rn = "Performance2";
6168// break;
7a387fff 6169 case 3:
d9bea114 6170// gen_helper_mtc0_performance3(arg);
2423f660
TS
6171 rn = "Performance3";
6172// break;
7a387fff 6173 case 4:
d9bea114 6174// gen_helper_mtc0_performance4(arg);
2423f660
TS
6175 rn = "Performance4";
6176// break;
7a387fff 6177 case 5:
d9bea114 6178// gen_helper_mtc0_performance5(arg);
2423f660
TS
6179 rn = "Performance5";
6180// break;
7a387fff 6181 case 6:
d9bea114 6182// gen_helper_mtc0_performance6(arg);
2423f660
TS
6183 rn = "Performance6";
6184// break;
7a387fff 6185 case 7:
d9bea114 6186// gen_helper_mtc0_performance7(arg);
2423f660
TS
6187 rn = "Performance7";
6188// break;
7a387fff 6189 default:
f31b035a 6190 goto cp0_unimplemented;
7a387fff 6191 }
8c0fdd85
TS
6192 break;
6193 case 26:
0d74a222
LA
6194 switch (sel) {
6195 case 0:
6196 gen_helper_mtc0_errctl(cpu_env, arg);
6197 ctx->bstate = BS_STOP;
6198 rn = "ErrCtl";
6199 break;
6200 default:
6201 goto cp0_unimplemented;
6202 }
2423f660 6203 break;
8c0fdd85 6204 case 27:
7a387fff
TS
6205 switch (sel) {
6206 case 0 ... 3:
2423f660
TS
6207 /* ignored */
6208 rn = "CacheErr";
6209 break;
7a387fff 6210 default:
f31b035a 6211 goto cp0_unimplemented;
7a387fff 6212 }
8c0fdd85
TS
6213 break;
6214 case 28:
6215 switch (sel) {
6216 case 0:
7a387fff
TS
6217 case 2:
6218 case 4:
6219 case 6:
895c2d04 6220 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6221 rn = "TagLo";
6222 break;
7a387fff
TS
6223 case 1:
6224 case 3:
6225 case 5:
6226 case 7:
895c2d04 6227 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6228 rn = "DataLo";
6229 break;
8c0fdd85 6230 default:
f31b035a 6231 goto cp0_unimplemented;
8c0fdd85
TS
6232 }
6233 break;
6234 case 29:
7a387fff
TS
6235 switch (sel) {
6236 case 0:
6237 case 2:
6238 case 4:
6239 case 6:
895c2d04 6240 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6241 rn = "TagHi";
6242 break;
6243 case 1:
6244 case 3:
6245 case 5:
6246 case 7:
895c2d04 6247 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6248 rn = "DataHi";
6249 break;
6250 default:
6251 rn = "invalid sel";
f31b035a 6252 goto cp0_unimplemented;
7a387fff 6253 }
8c0fdd85
TS
6254 break;
6255 case 30:
7a387fff
TS
6256 switch (sel) {
6257 case 0:
d54a299b 6258 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6259 rn = "ErrorEPC";
6260 break;
7a387fff 6261 default:
f31b035a 6262 goto cp0_unimplemented;
7a387fff 6263 }
8c0fdd85
TS
6264 break;
6265 case 31:
7a387fff
TS
6266 switch (sel) {
6267 case 0:
f1aa6320 6268 /* EJTAG support */
7db13fae 6269 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6270 rn = "DESAVE";
6271 break;
e98c0d17 6272 case 2 ... 7:
f31b035a
LA
6273 CP0_CHECK(ctx->kscrexist & (1 << sel));
6274 tcg_gen_st_tl(arg, cpu_env,
6275 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6276 rn = "KScratch";
e98c0d17 6277 break;
7a387fff 6278 default:
f31b035a 6279 goto cp0_unimplemented;
7a387fff 6280 }
2423f660
TS
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
8c0fdd85
TS
6283 break;
6284 default:
f31b035a 6285 goto cp0_unimplemented;
8c0fdd85 6286 }
2abf314d 6287 (void)rn; /* avoid a compiler warning */
d12d51d5 6288 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6289 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6290 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6291 gen_io_end();
6292 ctx->bstate = BS_STOP;
6293 }
8c0fdd85
TS
6294 return;
6295
f31b035a 6296cp0_unimplemented:
965447ee 6297 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6298}
6299
d26bc211 6300#if defined(TARGET_MIPS64)
d75c135e 6301static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6302{
6303 const char *rn = "invalid";
6304
e189e748 6305 if (sel != 0)
d75c135e 6306 check_insn(ctx, ISA_MIPS64);
e189e748 6307
9c2149c8
TS
6308 switch (reg) {
6309 case 0:
6310 switch (sel) {
6311 case 0:
7db13fae 6312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6313 rn = "Index";
6314 break;
6315 case 1:
f31b035a 6316 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6317 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6318 rn = "MVPControl";
ead9360e 6319 break;
9c2149c8 6320 case 2:
f31b035a 6321 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6322 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6323 rn = "MVPConf0";
ead9360e 6324 break;
9c2149c8 6325 case 3:
f31b035a 6326 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6327 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6328 rn = "MVPConf1";
ead9360e 6329 break;
01bc435b
YK
6330 case 4:
6331 CP0_CHECK(ctx->vp);
6332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6333 rn = "VPControl";
6334 break;
9c2149c8 6335 default:
f31b035a 6336 goto cp0_unimplemented;
9c2149c8
TS
6337 }
6338 break;
6339 case 1:
6340 switch (sel) {
6341 case 0:
f31b035a 6342 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6343 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6344 rn = "Random";
2423f660 6345 break;
9c2149c8 6346 case 1:
f31b035a 6347 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6349 rn = "VPEControl";
ead9360e 6350 break;
9c2149c8 6351 case 2:
f31b035a 6352 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6354 rn = "VPEConf0";
ead9360e 6355 break;
9c2149c8 6356 case 3:
f31b035a 6357 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6359 rn = "VPEConf1";
ead9360e 6360 break;
9c2149c8 6361 case 4:
f31b035a 6362 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6364 rn = "YQMask";
ead9360e 6365 break;
9c2149c8 6366 case 5:
f31b035a 6367 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6369 rn = "VPESchedule";
ead9360e 6370 break;
9c2149c8 6371 case 6:
f31b035a 6372 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6374 rn = "VPEScheFBack";
ead9360e 6375 break;
9c2149c8 6376 case 7:
f31b035a 6377 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6379 rn = "VPEOpt";
ead9360e 6380 break;
9c2149c8 6381 default:
f31b035a 6382 goto cp0_unimplemented;
9c2149c8
TS
6383 }
6384 break;
6385 case 2:
6386 switch (sel) {
6387 case 0:
7db13fae 6388 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6389 rn = "EntryLo0";
6390 break;
9c2149c8 6391 case 1:
f31b035a 6392 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6393 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6394 rn = "TCStatus";
ead9360e 6395 break;
9c2149c8 6396 case 2:
f31b035a 6397 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6398 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6399 rn = "TCBind";
ead9360e 6400 break;
9c2149c8 6401 case 3:
f31b035a 6402 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6403 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6404 rn = "TCRestart";
ead9360e 6405 break;
9c2149c8 6406 case 4:
f31b035a 6407 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6408 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6409 rn = "TCHalt";
ead9360e 6410 break;
9c2149c8 6411 case 5:
f31b035a 6412 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6413 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6414 rn = "TCContext";
ead9360e 6415 break;
9c2149c8 6416 case 6:
f31b035a 6417 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6418 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6419 rn = "TCSchedule";
ead9360e 6420 break;
9c2149c8 6421 case 7:
f31b035a 6422 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6423 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6424 rn = "TCScheFBack";
ead9360e 6425 break;
9c2149c8 6426 default:
f31b035a 6427 goto cp0_unimplemented;
9c2149c8
TS
6428 }
6429 break;
6430 case 3:
6431 switch (sel) {
6432 case 0:
7db13fae 6433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6434 rn = "EntryLo1";
6435 break;
01bc435b
YK
6436 case 1:
6437 CP0_CHECK(ctx->vp);
6438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6439 rn = "GlobalNumber";
6440 break;
9c2149c8 6441 default:
f31b035a 6442 goto cp0_unimplemented;
1579a72e 6443 }
9c2149c8
TS
6444 break;
6445 case 4:
6446 switch (sel) {
6447 case 0:
7db13fae 6448 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6449 rn = "Context";
6450 break;
9c2149c8 6451 case 1:
d9bea114 6452// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6453 rn = "ContextConfig";
f31b035a 6454 goto cp0_unimplemented;
d279279e 6455 case 2:
f31b035a
LA
6456 CP0_CHECK(ctx->ulri);
6457 tcg_gen_ld_tl(arg, cpu_env,
6458 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6459 rn = "UserLocal";
d279279e 6460 break;
9c2149c8 6461 default:
f31b035a 6462 goto cp0_unimplemented;
876d4b07 6463 }
9c2149c8
TS
6464 break;
6465 case 5:
6466 switch (sel) {
6467 case 0:
7db13fae 6468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6469 rn = "PageMask";
6470 break;
9c2149c8 6471 case 1:
d75c135e 6472 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6474 rn = "PageGrain";
6475 break;
9c2149c8 6476 default:
f31b035a 6477 goto cp0_unimplemented;
876d4b07 6478 }
9c2149c8
TS
6479 break;
6480 case 6:
6481 switch (sel) {
6482 case 0:
7db13fae 6483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6484 rn = "Wired";
6485 break;
9c2149c8 6486 case 1:
d75c135e 6487 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6489 rn = "SRSConf0";
ead9360e 6490 break;
9c2149c8 6491 case 2:
d75c135e 6492 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6494 rn = "SRSConf1";
ead9360e 6495 break;
9c2149c8 6496 case 3:
d75c135e 6497 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6499 rn = "SRSConf2";
ead9360e 6500 break;
9c2149c8 6501 case 4:
d75c135e 6502 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6504 rn = "SRSConf3";
ead9360e 6505 break;
9c2149c8 6506 case 5:
d75c135e 6507 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6509 rn = "SRSConf4";
ead9360e 6510 break;
9c2149c8 6511 default:
f31b035a 6512 goto cp0_unimplemented;
876d4b07 6513 }
9c2149c8
TS
6514 break;
6515 case 7:
6516 switch (sel) {
6517 case 0:
d75c135e 6518 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6520 rn = "HWREna";
6521 break;
9c2149c8 6522 default:
f31b035a 6523 goto cp0_unimplemented;
876d4b07 6524 }
9c2149c8
TS
6525 break;
6526 case 8:
6527 switch (sel) {
6528 case 0:
7db13fae 6529 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6530 rn = "BadVAddr";
2423f660 6531 break;
aea14095 6532 case 1:
f31b035a
LA
6533 CP0_CHECK(ctx->bi);
6534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6535 rn = "BadInstr";
aea14095
LA
6536 break;
6537 case 2:
f31b035a
LA
6538 CP0_CHECK(ctx->bp);
6539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6540 rn = "BadInstrP";
aea14095 6541 break;
9c2149c8 6542 default:
f31b035a 6543 goto cp0_unimplemented;
876d4b07 6544 }
9c2149c8
TS
6545 break;
6546 case 9:
6547 switch (sel) {
6548 case 0:
2e70f6ef 6549 /* Mark as an IO operation because we read the time. */
bd79255d 6550 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6551 gen_io_start();
bd79255d 6552 }
895c2d04 6553 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6554 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6555 gen_io_end();
2e70f6ef 6556 }
55807224
EI
6557 /* Break the TB to be able to take timer interrupts immediately
6558 after reading count. */
6559 ctx->bstate = BS_STOP;
2423f660
TS
6560 rn = "Count";
6561 break;
6562 /* 6,7 are implementation dependent */
9c2149c8 6563 default:
f31b035a 6564 goto cp0_unimplemented;
876d4b07 6565 }
9c2149c8
TS
6566 break;
6567 case 10:
6568 switch (sel) {
6569 case 0:
7db13fae 6570 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6571 rn = "EntryHi";
6572 break;
9c2149c8 6573 default:
f31b035a 6574 goto cp0_unimplemented;
876d4b07 6575 }
9c2149c8
TS
6576 break;
6577 case 11:
6578 switch (sel) {
6579 case 0:
7db13fae 6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6581 rn = "Compare";
6582 break;
876d4b07 6583 /* 6,7 are implementation dependent */
9c2149c8 6584 default:
f31b035a 6585 goto cp0_unimplemented;
876d4b07 6586 }
9c2149c8
TS
6587 break;
6588 case 12:
6589 switch (sel) {
6590 case 0:
7db13fae 6591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6592 rn = "Status";
6593 break;
9c2149c8 6594 case 1:
d75c135e 6595 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6597 rn = "IntCtl";
6598 break;
9c2149c8 6599 case 2:
d75c135e 6600 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6602 rn = "SRSCtl";
6603 break;
9c2149c8 6604 case 3:
d75c135e 6605 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6607 rn = "SRSMap";
6608 break;
9c2149c8 6609 default:
f31b035a 6610 goto cp0_unimplemented;
876d4b07 6611 }
9c2149c8
TS
6612 break;
6613 case 13:
6614 switch (sel) {
6615 case 0:
7db13fae 6616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6617 rn = "Cause";
6618 break;
9c2149c8 6619 default:
f31b035a 6620 goto cp0_unimplemented;
876d4b07 6621 }
9c2149c8
TS
6622 break;
6623 case 14:
6624 switch (sel) {
6625 case 0:
7db13fae 6626 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6627 rn = "EPC";
6628 break;
9c2149c8 6629 default:
f31b035a 6630 goto cp0_unimplemented;
876d4b07 6631 }
9c2149c8
TS
6632 break;
6633 case 15:
6634 switch (sel) {
6635 case 0:
7db13fae 6636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6637 rn = "PRid";
6638 break;
9c2149c8 6639 case 1:
d75c135e 6640 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6642 rn = "EBase";
6643 break;
c870e3f5
YK
6644 case 3:
6645 check_insn(ctx, ISA_MIPS32R2);
6646 CP0_CHECK(ctx->cmgcr);
6647 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6648 rn = "CMGCRBase";
6649 break;
9c2149c8 6650 default:
f31b035a 6651 goto cp0_unimplemented;
876d4b07 6652 }
9c2149c8
TS
6653 break;
6654 case 16:
6655 switch (sel) {
6656 case 0:
7db13fae 6657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6658 rn = "Config";
6659 break;
6660 case 1:
7db13fae 6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6662 rn = "Config1";
6663 break;
6664 case 2:
7db13fae 6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6666 rn = "Config2";
6667 break;
6668 case 3:
7db13fae 6669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6670 rn = "Config3";
6671 break;
faf1f68b
LA
6672 case 4:
6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6674 rn = "Config4";
6675 break;
6676 case 5:
6677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6678 rn = "Config5";
6679 break;
9c2149c8 6680 /* 6,7 are implementation dependent */
f0b3f3ae 6681 case 6:
7db13fae 6682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6683 rn = "Config6";
6684 break;
6685 case 7:
7db13fae 6686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6687 rn = "Config7";
6688 break;
9c2149c8 6689 default:
f31b035a 6690 goto cp0_unimplemented;
9c2149c8
TS
6691 }
6692 break;
6693 case 17:
6694 switch (sel) {
6695 case 0:
895c2d04 6696 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6697 rn = "LLAddr";
6698 break;
f6d4dd81
YK
6699 case 1:
6700 CP0_CHECK(ctx->mrp);
6701 gen_helper_dmfc0_maar(arg, cpu_env);
6702 rn = "MAAR";
6703 break;
6704 case 2:
6705 CP0_CHECK(ctx->mrp);
6706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6707 rn = "MAARI";
6708 break;
9c2149c8 6709 default:
f31b035a 6710 goto cp0_unimplemented;
9c2149c8
TS
6711 }
6712 break;
6713 case 18:
6714 switch (sel) {
fd88b6ab 6715 case 0 ... 7:
895c2d04 6716 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6717 rn = "WatchLo";
6718 break;
9c2149c8 6719 default:
f31b035a 6720 goto cp0_unimplemented;
9c2149c8
TS
6721 }
6722 break;
6723 case 19:
6724 switch (sel) {
fd88b6ab 6725 case 0 ... 7:
895c2d04 6726 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6727 rn = "WatchHi";
6728 break;
9c2149c8 6729 default:
f31b035a 6730 goto cp0_unimplemented;
9c2149c8
TS
6731 }
6732 break;
6733 case 20:
6734 switch (sel) {
6735 case 0:
d75c135e 6736 check_insn(ctx, ISA_MIPS3);
7db13fae 6737 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6738 rn = "XContext";
6739 break;
9c2149c8 6740 default:
f31b035a 6741 goto cp0_unimplemented;
9c2149c8
TS
6742 }
6743 break;
6744 case 21:
6745 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6746 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6747 switch (sel) {
6748 case 0:
7db13fae 6749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6750 rn = "Framemask";
6751 break;
9c2149c8 6752 default:
f31b035a 6753 goto cp0_unimplemented;
9c2149c8
TS
6754 }
6755 break;
6756 case 22:
d9bea114 6757 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6758 rn = "'Diagnostic"; /* implementation dependent */
6759 break;
9c2149c8
TS
6760 case 23:
6761 switch (sel) {
6762 case 0:
895c2d04 6763 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6764 rn = "Debug";
6765 break;
9c2149c8 6766 case 1:
895c2d04 6767// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6768 rn = "TraceControl";
6769// break;
9c2149c8 6770 case 2:
895c2d04 6771// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6772 rn = "TraceControl2";
6773// break;
9c2149c8 6774 case 3:
895c2d04 6775// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6776 rn = "UserTraceData";
6777// break;
9c2149c8 6778 case 4:
895c2d04 6779// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6780 rn = "TraceBPC";
6781// break;
9c2149c8 6782 default:
f31b035a 6783 goto cp0_unimplemented;
9c2149c8
TS
6784 }
6785 break;
6786 case 24:
6787 switch (sel) {
6788 case 0:
f0b3f3ae 6789 /* EJTAG support */
7db13fae 6790 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6791 rn = "DEPC";
6792 break;
9c2149c8 6793 default:
f31b035a 6794 goto cp0_unimplemented;
9c2149c8
TS
6795 }
6796 break;
6797 case 25:
6798 switch (sel) {
6799 case 0:
7db13fae 6800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6801 rn = "Performance0";
9c2149c8
TS
6802 break;
6803 case 1:
d9bea114 6804// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6805 rn = "Performance1";
6806// break;
9c2149c8 6807 case 2:
d9bea114 6808// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6809 rn = "Performance2";
6810// break;
9c2149c8 6811 case 3:
d9bea114 6812// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6813 rn = "Performance3";
6814// break;
9c2149c8 6815 case 4:
d9bea114 6816// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6817 rn = "Performance4";
6818// break;
9c2149c8 6819 case 5:
d9bea114 6820// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6821 rn = "Performance5";
6822// break;
9c2149c8 6823 case 6:
d9bea114 6824// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6825 rn = "Performance6";
6826// break;
9c2149c8 6827 case 7:
d9bea114 6828// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6829 rn = "Performance7";
6830// break;
9c2149c8 6831 default:
f31b035a 6832 goto cp0_unimplemented;
9c2149c8
TS
6833 }
6834 break;
6835 case 26:
0d74a222
LA
6836 switch (sel) {
6837 case 0:
6838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6839 rn = "ErrCtl";
6840 break;
6841 default:
6842 goto cp0_unimplemented;
6843 }
da80682b 6844 break;
9c2149c8
TS
6845 case 27:
6846 switch (sel) {
6847 /* ignored */
6848 case 0 ... 3:
d9bea114 6849 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6850 rn = "CacheErr";
6851 break;
9c2149c8 6852 default:
f31b035a 6853 goto cp0_unimplemented;
9c2149c8
TS
6854 }
6855 break;
6856 case 28:
6857 switch (sel) {
6858 case 0:
6859 case 2:
6860 case 4:
6861 case 6:
7db13fae 6862 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6863 rn = "TagLo";
6864 break;
6865 case 1:
6866 case 3:
6867 case 5:
6868 case 7:
7db13fae 6869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6870 rn = "DataLo";
6871 break;
6872 default:
f31b035a 6873 goto cp0_unimplemented;
9c2149c8
TS
6874 }
6875 break;
6876 case 29:
6877 switch (sel) {
6878 case 0:
6879 case 2:
6880 case 4:
6881 case 6:
7db13fae 6882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6883 rn = "TagHi";
6884 break;
6885 case 1:
6886 case 3:
6887 case 5:
6888 case 7:
7db13fae 6889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6890 rn = "DataHi";
6891 break;
6892 default:
f31b035a 6893 goto cp0_unimplemented;
9c2149c8
TS
6894 }
6895 break;
6896 case 30:
6897 switch (sel) {
6898 case 0:
7db13fae 6899 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6900 rn = "ErrorEPC";
6901 break;
9c2149c8 6902 default:
f31b035a 6903 goto cp0_unimplemented;
9c2149c8
TS
6904 }
6905 break;
6906 case 31:
6907 switch (sel) {
6908 case 0:
f0b3f3ae 6909 /* EJTAG support */
7db13fae 6910 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6911 rn = "DESAVE";
6912 break;
e98c0d17 6913 case 2 ... 7:
f31b035a
LA
6914 CP0_CHECK(ctx->kscrexist & (1 << sel));
6915 tcg_gen_ld_tl(arg, cpu_env,
6916 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6917 rn = "KScratch";
e98c0d17 6918 break;
9c2149c8 6919 default:
f31b035a 6920 goto cp0_unimplemented;
9c2149c8
TS
6921 }
6922 break;
6923 default:
f31b035a 6924 goto cp0_unimplemented;
9c2149c8 6925 }
2abf314d 6926 (void)rn; /* avoid a compiler warning */
d12d51d5 6927 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6928 return;
6929
f31b035a 6930cp0_unimplemented:
965447ee 6931 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6932 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6933}
6934
d75c135e 6935static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6936{
6937 const char *rn = "invalid";
6938
e189e748 6939 if (sel != 0)
d75c135e 6940 check_insn(ctx, ISA_MIPS64);
e189e748 6941
bd79255d 6942 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6943 gen_io_start();
bd79255d 6944 }
2e70f6ef 6945
9c2149c8
TS
6946 switch (reg) {
6947 case 0:
6948 switch (sel) {
6949 case 0:
895c2d04 6950 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6951 rn = "Index";
6952 break;
6953 case 1:
f31b035a 6954 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6955 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6956 rn = "MVPControl";
ead9360e 6957 break;
9c2149c8 6958 case 2:
f31b035a 6959 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6960 /* ignored */
9c2149c8 6961 rn = "MVPConf0";
ead9360e 6962 break;
9c2149c8 6963 case 3:
f31b035a 6964 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6965 /* ignored */
9c2149c8 6966 rn = "MVPConf1";
ead9360e 6967 break;
01bc435b
YK
6968 case 4:
6969 CP0_CHECK(ctx->vp);
6970 /* ignored */
6971 rn = "VPControl";
6972 break;
9c2149c8 6973 default:
f31b035a 6974 goto cp0_unimplemented;
9c2149c8
TS
6975 }
6976 break;
6977 case 1:
6978 switch (sel) {
6979 case 0:
2423f660 6980 /* ignored */
9c2149c8 6981 rn = "Random";
2423f660 6982 break;
9c2149c8 6983 case 1:
f31b035a 6984 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6985 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6986 rn = "VPEControl";
ead9360e 6987 break;
9c2149c8 6988 case 2:
f31b035a 6989 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6990 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6991 rn = "VPEConf0";
ead9360e 6992 break;
9c2149c8 6993 case 3:
f31b035a 6994 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6995 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6996 rn = "VPEConf1";
ead9360e 6997 break;
9c2149c8 6998 case 4:
f31b035a 6999 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7000 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7001 rn = "YQMask";
ead9360e 7002 break;
9c2149c8 7003 case 5:
f31b035a 7004 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7005 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7006 rn = "VPESchedule";
ead9360e 7007 break;
9c2149c8 7008 case 6:
f31b035a 7009 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7010 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7011 rn = "VPEScheFBack";
ead9360e 7012 break;
9c2149c8 7013 case 7:
f31b035a 7014 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7015 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7016 rn = "VPEOpt";
ead9360e 7017 break;
9c2149c8 7018 default:
f31b035a 7019 goto cp0_unimplemented;
9c2149c8
TS
7020 }
7021 break;
7022 case 2:
7023 switch (sel) {
7024 case 0:
7207c7f9 7025 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7026 rn = "EntryLo0";
7027 break;
9c2149c8 7028 case 1:
f31b035a 7029 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7030 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7031 rn = "TCStatus";
ead9360e 7032 break;
9c2149c8 7033 case 2:
f31b035a 7034 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7035 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7036 rn = "TCBind";
ead9360e 7037 break;
9c2149c8 7038 case 3:
f31b035a 7039 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7040 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7041 rn = "TCRestart";
ead9360e 7042 break;
9c2149c8 7043 case 4:
f31b035a 7044 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7045 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7046 rn = "TCHalt";
ead9360e 7047 break;
9c2149c8 7048 case 5:
f31b035a 7049 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7050 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7051 rn = "TCContext";
ead9360e 7052 break;
9c2149c8 7053 case 6:
f31b035a 7054 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7055 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7056 rn = "TCSchedule";
ead9360e 7057 break;
9c2149c8 7058 case 7:
f31b035a 7059 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7060 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7061 rn = "TCScheFBack";
ead9360e 7062 break;
9c2149c8 7063 default:
f31b035a 7064 goto cp0_unimplemented;
9c2149c8
TS
7065 }
7066 break;
7067 case 3:
7068 switch (sel) {
7069 case 0:
7207c7f9 7070 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7071 rn = "EntryLo1";
7072 break;
01bc435b
YK
7073 case 1:
7074 CP0_CHECK(ctx->vp);
7075 /* ignored */
7076 rn = "GlobalNumber";
7077 break;
9c2149c8 7078 default:
f31b035a 7079 goto cp0_unimplemented;
876d4b07 7080 }
9c2149c8
TS
7081 break;
7082 case 4:
7083 switch (sel) {
7084 case 0:
895c2d04 7085 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7086 rn = "Context";
7087 break;
9c2149c8 7088 case 1:
895c2d04 7089// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7090 rn = "ContextConfig";
f31b035a 7091 goto cp0_unimplemented;
d279279e 7092 case 2:
f31b035a
LA
7093 CP0_CHECK(ctx->ulri);
7094 tcg_gen_st_tl(arg, cpu_env,
7095 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7096 rn = "UserLocal";
d279279e 7097 break;
9c2149c8 7098 default:
f31b035a 7099 goto cp0_unimplemented;
876d4b07 7100 }
9c2149c8
TS
7101 break;
7102 case 5:
7103 switch (sel) {
7104 case 0:
895c2d04 7105 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7106 rn = "PageMask";
7107 break;
9c2149c8 7108 case 1:
d75c135e 7109 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7110 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7111 rn = "PageGrain";
7112 break;
9c2149c8 7113 default:
f31b035a 7114 goto cp0_unimplemented;
876d4b07 7115 }
9c2149c8
TS
7116 break;
7117 case 6:
7118 switch (sel) {
7119 case 0:
895c2d04 7120 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7121 rn = "Wired";
7122 break;
9c2149c8 7123 case 1:
d75c135e 7124 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7125 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7126 rn = "SRSConf0";
ead9360e 7127 break;
9c2149c8 7128 case 2:
d75c135e 7129 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7130 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7131 rn = "SRSConf1";
ead9360e 7132 break;
9c2149c8 7133 case 3:
d75c135e 7134 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7135 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7136 rn = "SRSConf2";
ead9360e 7137 break;
9c2149c8 7138 case 4:
d75c135e 7139 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7140 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7141 rn = "SRSConf3";
ead9360e 7142 break;
9c2149c8 7143 case 5:
d75c135e 7144 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7145 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7146 rn = "SRSConf4";
ead9360e 7147 break;
9c2149c8 7148 default:
f31b035a 7149 goto cp0_unimplemented;
876d4b07 7150 }
9c2149c8
TS
7151 break;
7152 case 7:
7153 switch (sel) {
7154 case 0:
d75c135e 7155 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7156 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7157 ctx->bstate = BS_STOP;
2423f660
TS
7158 rn = "HWREna";
7159 break;
9c2149c8 7160 default:
f31b035a 7161 goto cp0_unimplemented;
876d4b07 7162 }
9c2149c8
TS
7163 break;
7164 case 8:
aea14095
LA
7165 switch (sel) {
7166 case 0:
7167 /* ignored */
7168 rn = "BadVAddr";
7169 break;
7170 case 1:
7171 /* ignored */
7172 rn = "BadInstr";
7173 break;
7174 case 2:
7175 /* ignored */
7176 rn = "BadInstrP";
7177 break;
7178 default:
f31b035a 7179 goto cp0_unimplemented;
aea14095 7180 }
9c2149c8
TS
7181 break;
7182 case 9:
7183 switch (sel) {
7184 case 0:
895c2d04 7185 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7186 rn = "Count";
7187 break;
876d4b07 7188 /* 6,7 are implementation dependent */
9c2149c8 7189 default:
f31b035a 7190 goto cp0_unimplemented;
876d4b07
TS
7191 }
7192 /* Stop translation as we may have switched the execution mode */
7193 ctx->bstate = BS_STOP;
9c2149c8
TS
7194 break;
7195 case 10:
7196 switch (sel) {
7197 case 0:
895c2d04 7198 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7199 rn = "EntryHi";
7200 break;
9c2149c8 7201 default:
f31b035a 7202 goto cp0_unimplemented;
876d4b07 7203 }
9c2149c8
TS
7204 break;
7205 case 11:
7206 switch (sel) {
7207 case 0:
895c2d04 7208 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7209 rn = "Compare";
7210 break;
876d4b07 7211 /* 6,7 are implementation dependent */
9c2149c8 7212 default:
f31b035a 7213 goto cp0_unimplemented;
876d4b07 7214 }
de9a95f0
AJ
7215 /* Stop translation as we may have switched the execution mode */
7216 ctx->bstate = BS_STOP;
9c2149c8
TS
7217 break;
7218 case 12:
7219 switch (sel) {
7220 case 0:
867abc7e 7221 save_cpu_state(ctx, 1);
895c2d04 7222 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7223 /* BS_STOP isn't good enough here, hflags may have changed. */
7224 gen_save_pc(ctx->pc + 4);
7225 ctx->bstate = BS_EXCP;
2423f660
TS
7226 rn = "Status";
7227 break;
9c2149c8 7228 case 1:
d75c135e 7229 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7230 gen_helper_mtc0_intctl(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 = "IntCtl";
7234 break;
9c2149c8 7235 case 2:
d75c135e 7236 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7237 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx->bstate = BS_STOP;
2423f660
TS
7240 rn = "SRSCtl";
7241 break;
9c2149c8 7242 case 3:
d75c135e 7243 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7244 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7245 /* Stop translation as we may have switched the execution mode */
7246 ctx->bstate = BS_STOP;
2423f660
TS
7247 rn = "SRSMap";
7248 break;
7249 default:
f31b035a 7250 goto cp0_unimplemented;
876d4b07 7251 }
9c2149c8
TS
7252 break;
7253 case 13:
7254 switch (sel) {
7255 case 0:
867abc7e 7256 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7257 /* Mark as an IO operation because we may trigger a software
7258 interrupt. */
bd79255d 7259 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7260 gen_io_start();
7261 }
895c2d04 7262 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7263 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7264 gen_io_end();
7265 }
7266 /* Stop translation as we may have triggered an intetrupt */
7267 ctx->bstate = BS_STOP;
2423f660
TS
7268 rn = "Cause";
7269 break;
9c2149c8 7270 default:
f31b035a 7271 goto cp0_unimplemented;
876d4b07 7272 }
9c2149c8
TS
7273 break;
7274 case 14:
7275 switch (sel) {
7276 case 0:
7db13fae 7277 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7278 rn = "EPC";
7279 break;
9c2149c8 7280 default:
f31b035a 7281 goto cp0_unimplemented;
876d4b07 7282 }
9c2149c8
TS
7283 break;
7284 case 15:
7285 switch (sel) {
7286 case 0:
2423f660
TS
7287 /* ignored */
7288 rn = "PRid";
7289 break;
9c2149c8 7290 case 1:
d75c135e 7291 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7292 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7293 rn = "EBase";
7294 break;
9c2149c8 7295 default:
f31b035a 7296 goto cp0_unimplemented;
876d4b07 7297 }
9c2149c8
TS
7298 break;
7299 case 16:
7300 switch (sel) {
7301 case 0:
895c2d04 7302 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7303 rn = "Config";
2423f660
TS
7304 /* Stop translation as we may have switched the execution mode */
7305 ctx->bstate = BS_STOP;
9c2149c8
TS
7306 break;
7307 case 1:
1fc7bf6e 7308 /* ignored, read only */
9c2149c8
TS
7309 rn = "Config1";
7310 break;
7311 case 2:
895c2d04 7312 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7313 rn = "Config2";
2423f660
TS
7314 /* Stop translation as we may have switched the execution mode */
7315 ctx->bstate = BS_STOP;
9c2149c8
TS
7316 break;
7317 case 3:
90f12d73 7318 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7319 rn = "Config3";
90f12d73
MR
7320 /* Stop translation as we may have switched the execution mode */
7321 ctx->bstate = BS_STOP;
9c2149c8 7322 break;
faf1f68b
LA
7323 case 4:
7324 /* currently ignored */
7325 rn = "Config4";
7326 break;
7327 case 5:
7328 gen_helper_mtc0_config5(cpu_env, arg);
7329 rn = "Config5";
7330 /* Stop translation as we may have switched the execution mode */
7331 ctx->bstate = BS_STOP;
7332 break;
9c2149c8
TS
7333 /* 6,7 are implementation dependent */
7334 default:
7335 rn = "Invalid config selector";
f31b035a 7336 goto cp0_unimplemented;
9c2149c8 7337 }
9c2149c8
TS
7338 break;
7339 case 17:
7340 switch (sel) {
7341 case 0:
895c2d04 7342 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7343 rn = "LLAddr";
7344 break;
f6d4dd81
YK
7345 case 1:
7346 CP0_CHECK(ctx->mrp);
7347 gen_helper_mtc0_maar(cpu_env, arg);
7348 rn = "MAAR";
7349 break;
7350 case 2:
7351 CP0_CHECK(ctx->mrp);
7352 gen_helper_mtc0_maari(cpu_env, arg);
7353 rn = "MAARI";
7354 break;
9c2149c8 7355 default:
f31b035a 7356 goto cp0_unimplemented;
9c2149c8
TS
7357 }
7358 break;
7359 case 18:
7360 switch (sel) {
fd88b6ab 7361 case 0 ... 7:
895c2d04 7362 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7363 rn = "WatchLo";
7364 break;
9c2149c8 7365 default:
f31b035a 7366 goto cp0_unimplemented;
9c2149c8
TS
7367 }
7368 break;
7369 case 19:
7370 switch (sel) {
fd88b6ab 7371 case 0 ... 7:
895c2d04 7372 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7373 rn = "WatchHi";
7374 break;
9c2149c8 7375 default:
f31b035a 7376 goto cp0_unimplemented;
9c2149c8
TS
7377 }
7378 break;
7379 case 20:
7380 switch (sel) {
7381 case 0:
d75c135e 7382 check_insn(ctx, ISA_MIPS3);
895c2d04 7383 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7384 rn = "XContext";
7385 break;
9c2149c8 7386 default:
f31b035a 7387 goto cp0_unimplemented;
9c2149c8
TS
7388 }
7389 break;
7390 case 21:
7391 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7392 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7393 switch (sel) {
7394 case 0:
895c2d04 7395 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7396 rn = "Framemask";
7397 break;
9c2149c8 7398 default:
f31b035a 7399 goto cp0_unimplemented;
9c2149c8
TS
7400 }
7401 break;
7402 case 22:
7403 /* ignored */
7404 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7405 break;
9c2149c8
TS
7406 case 23:
7407 switch (sel) {
7408 case 0:
895c2d04 7409 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7410 /* BS_STOP isn't good enough here, hflags may have changed. */
7411 gen_save_pc(ctx->pc + 4);
7412 ctx->bstate = BS_EXCP;
2423f660
TS
7413 rn = "Debug";
7414 break;
9c2149c8 7415 case 1:
895c2d04 7416// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7417 /* Stop translation as we may have switched the execution mode */
7418 ctx->bstate = BS_STOP;
2423f660
TS
7419 rn = "TraceControl";
7420// break;
9c2149c8 7421 case 2:
895c2d04 7422// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7423 /* Stop translation as we may have switched the execution mode */
7424 ctx->bstate = BS_STOP;
2423f660
TS
7425 rn = "TraceControl2";
7426// break;
9c2149c8 7427 case 3:
895c2d04 7428// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7429 /* Stop translation as we may have switched the execution mode */
7430 ctx->bstate = BS_STOP;
2423f660
TS
7431 rn = "UserTraceData";
7432// break;
9c2149c8 7433 case 4:
895c2d04 7434// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7435 /* Stop translation as we may have switched the execution mode */
7436 ctx->bstate = BS_STOP;
2423f660
TS
7437 rn = "TraceBPC";
7438// break;
9c2149c8 7439 default:
f31b035a 7440 goto cp0_unimplemented;
9c2149c8 7441 }
9c2149c8
TS
7442 break;
7443 case 24:
7444 switch (sel) {
7445 case 0:
f1aa6320 7446 /* EJTAG support */
7db13fae 7447 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7448 rn = "DEPC";
7449 break;
9c2149c8 7450 default:
f31b035a 7451 goto cp0_unimplemented;
9c2149c8
TS
7452 }
7453 break;
7454 case 25:
7455 switch (sel) {
7456 case 0:
895c2d04 7457 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7458 rn = "Performance0";
7459 break;
9c2149c8 7460 case 1:
895c2d04 7461// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7462 rn = "Performance1";
7463// break;
9c2149c8 7464 case 2:
895c2d04 7465// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7466 rn = "Performance2";
7467// break;
9c2149c8 7468 case 3:
895c2d04 7469// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7470 rn = "Performance3";
7471// break;
9c2149c8 7472 case 4:
895c2d04 7473// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7474 rn = "Performance4";
7475// break;
9c2149c8 7476 case 5:
895c2d04 7477// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7478 rn = "Performance5";
7479// break;
9c2149c8 7480 case 6:
895c2d04 7481// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7482 rn = "Performance6";
7483// break;
9c2149c8 7484 case 7:
895c2d04 7485// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7486 rn = "Performance7";
7487// break;
9c2149c8 7488 default:
f31b035a 7489 goto cp0_unimplemented;
9c2149c8 7490 }
876d4b07 7491 break;
9c2149c8 7492 case 26:
0d74a222
LA
7493 switch (sel) {
7494 case 0:
7495 gen_helper_mtc0_errctl(cpu_env, arg);
7496 ctx->bstate = BS_STOP;
7497 rn = "ErrCtl";
7498 break;
7499 default:
7500 goto cp0_unimplemented;
7501 }
876d4b07 7502 break;
9c2149c8
TS
7503 case 27:
7504 switch (sel) {
7505 case 0 ... 3:
2423f660
TS
7506 /* ignored */
7507 rn = "CacheErr";
7508 break;
9c2149c8 7509 default:
f31b035a 7510 goto cp0_unimplemented;
9c2149c8 7511 }
876d4b07 7512 break;
9c2149c8
TS
7513 case 28:
7514 switch (sel) {
7515 case 0:
7516 case 2:
7517 case 4:
7518 case 6:
895c2d04 7519 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7520 rn = "TagLo";
7521 break;
7522 case 1:
7523 case 3:
7524 case 5:
7525 case 7:
895c2d04 7526 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7527 rn = "DataLo";
7528 break;
7529 default:
f31b035a 7530 goto cp0_unimplemented;
9c2149c8
TS
7531 }
7532 break;
7533 case 29:
7534 switch (sel) {
7535 case 0:
7536 case 2:
7537 case 4:
7538 case 6:
895c2d04 7539 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7540 rn = "TagHi";
7541 break;
7542 case 1:
7543 case 3:
7544 case 5:
7545 case 7:
895c2d04 7546 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7547 rn = "DataHi";
7548 break;
7549 default:
7550 rn = "invalid sel";
f31b035a 7551 goto cp0_unimplemented;
9c2149c8 7552 }
876d4b07 7553 break;
9c2149c8
TS
7554 case 30:
7555 switch (sel) {
7556 case 0:
7db13fae 7557 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7558 rn = "ErrorEPC";
7559 break;
9c2149c8 7560 default:
f31b035a 7561 goto cp0_unimplemented;
9c2149c8
TS
7562 }
7563 break;
7564 case 31:
7565 switch (sel) {
7566 case 0:
f1aa6320 7567 /* EJTAG support */
7db13fae 7568 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7569 rn = "DESAVE";
7570 break;
e98c0d17 7571 case 2 ... 7:
f31b035a
LA
7572 CP0_CHECK(ctx->kscrexist & (1 << sel));
7573 tcg_gen_st_tl(arg, cpu_env,
7574 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7575 rn = "KScratch";
e98c0d17 7576 break;
9c2149c8 7577 default:
f31b035a 7578 goto cp0_unimplemented;
9c2149c8 7579 }
876d4b07
TS
7580 /* Stop translation as we may have switched the execution mode */
7581 ctx->bstate = BS_STOP;
9c2149c8
TS
7582 break;
7583 default:
f31b035a 7584 goto cp0_unimplemented;
9c2149c8 7585 }
2abf314d 7586 (void)rn; /* avoid a compiler warning */
d12d51d5 7587 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7588 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7589 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7590 gen_io_end();
7591 ctx->bstate = BS_STOP;
7592 }
9c2149c8
TS
7593 return;
7594
f31b035a 7595cp0_unimplemented:
965447ee 7596 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7597}
d26bc211 7598#endif /* TARGET_MIPS64 */
9c2149c8 7599
7db13fae 7600static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7601 int u, int sel, int h)
7602{
7603 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7604 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7605
7606 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7607 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7608 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7609 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7610 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7611 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7612 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7613 else if (u == 0) {
7614 switch (rt) {
5a25ce94
EI
7615 case 1:
7616 switch (sel) {
7617 case 1:
895c2d04 7618 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7619 break;
7620 case 2:
895c2d04 7621 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7622 break;
7623 default:
7624 goto die;
7625 break;
7626 }
7627 break;
ead9360e
TS
7628 case 2:
7629 switch (sel) {
7630 case 1:
895c2d04 7631 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7632 break;
7633 case 2:
895c2d04 7634 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7635 break;
7636 case 3:
895c2d04 7637 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7638 break;
7639 case 4:
895c2d04 7640 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7641 break;
7642 case 5:
895c2d04 7643 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7644 break;
7645 case 6:
895c2d04 7646 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7647 break;
7648 case 7:
895c2d04 7649 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7650 break;
7651 default:
d75c135e 7652 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7653 break;
7654 }
7655 break;
7656 case 10:
7657 switch (sel) {
7658 case 0:
895c2d04 7659 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7660 break;
7661 default:
d75c135e 7662 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7663 break;
7664 }
7665 case 12:
7666 switch (sel) {
7667 case 0:
895c2d04 7668 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7669 break;
7670 default:
d75c135e 7671 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7672 break;
7673 }
5a25ce94
EI
7674 case 13:
7675 switch (sel) {
7676 case 0:
895c2d04 7677 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7678 break;
7679 default:
7680 goto die;
7681 break;
7682 }
7683 break;
7684 case 14:
7685 switch (sel) {
7686 case 0:
895c2d04 7687 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7688 break;
7689 default:
7690 goto die;
7691 break;
7692 }
7693 break;
7694 case 15:
7695 switch (sel) {
7696 case 1:
895c2d04 7697 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7698 break;
7699 default:
7700 goto die;
7701 break;
7702 }
7703 break;
7704 case 16:
7705 switch (sel) {
7706 case 0 ... 7:
895c2d04 7707 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7708 break;
7709 default:
7710 goto die;
7711 break;
7712 }
7713 break;
ead9360e
TS
7714 case 23:
7715 switch (sel) {
7716 case 0:
895c2d04 7717 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7718 break;
7719 default:
d75c135e 7720 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7721 break;
7722 }
7723 break;
7724 default:
d75c135e 7725 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7726 }
7727 } else switch (sel) {
7728 /* GPR registers. */
7729 case 0:
895c2d04 7730 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7731 break;
7732 /* Auxiliary CPU registers */
7733 case 1:
7734 switch (rt) {
7735 case 0:
895c2d04 7736 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7737 break;
7738 case 1:
895c2d04 7739 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7740 break;
7741 case 2:
895c2d04 7742 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7743 break;
7744 case 4:
895c2d04 7745 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7746 break;
7747 case 5:
895c2d04 7748 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7749 break;
7750 case 6:
895c2d04 7751 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7752 break;
7753 case 8:
895c2d04 7754 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7755 break;
7756 case 9:
895c2d04 7757 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7758 break;
7759 case 10:
895c2d04 7760 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7761 break;
7762 case 12:
895c2d04 7763 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7764 break;
7765 case 13:
895c2d04 7766 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7767 break;
7768 case 14:
895c2d04 7769 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7770 break;
7771 case 16:
895c2d04 7772 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7773 break;
7774 default:
7775 goto die;
7776 }
7777 break;
7778 /* Floating point (COP1). */
7779 case 2:
7780 /* XXX: For now we support only a single FPU context. */
7781 if (h == 0) {
a7812ae4 7782 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7783
7c979afd 7784 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7785 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7786 tcg_temp_free_i32(fp0);
ead9360e 7787 } else {
a7812ae4 7788 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7789
7f6613ce 7790 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7791 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7792 tcg_temp_free_i32(fp0);
ead9360e
TS
7793 }
7794 break;
7795 case 3:
7796 /* XXX: For now we support only a single FPU context. */
895c2d04 7797 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7798 break;
7799 /* COP2: Not implemented. */
7800 case 4:
7801 case 5:
7802 /* fall through */
7803 default:
7804 goto die;
7805 }
d12d51d5 7806 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7807 gen_store_gpr(t0, rd);
7808 tcg_temp_free(t0);
ead9360e
TS
7809 return;
7810
7811die:
1a3fd9c3 7812 tcg_temp_free(t0);
d12d51d5 7813 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7814 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7815}
7816
7db13fae 7817static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7818 int u, int sel, int h)
7819{
7820 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7821 TCGv t0 = tcg_temp_local_new();
ead9360e 7822
1a3fd9c3 7823 gen_load_gpr(t0, rt);
ead9360e 7824 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7825 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7826 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7827 /* NOP */ ;
7828 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7829 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7830 /* NOP */ ;
7831 else if (u == 0) {
7832 switch (rd) {
5a25ce94
EI
7833 case 1:
7834 switch (sel) {
7835 case 1:
895c2d04 7836 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7837 break;
7838 case 2:
895c2d04 7839 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7840 break;
7841 default:
7842 goto die;
7843 break;
7844 }
7845 break;
ead9360e
TS
7846 case 2:
7847 switch (sel) {
7848 case 1:
895c2d04 7849 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7850 break;
7851 case 2:
895c2d04 7852 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7853 break;
7854 case 3:
895c2d04 7855 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7856 break;
7857 case 4:
895c2d04 7858 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7859 break;
7860 case 5:
895c2d04 7861 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7862 break;
7863 case 6:
895c2d04 7864 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7865 break;
7866 case 7:
895c2d04 7867 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7868 break;
7869 default:
d75c135e 7870 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7871 break;
7872 }
7873 break;
7874 case 10:
7875 switch (sel) {
7876 case 0:
895c2d04 7877 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7878 break;
7879 default:
d75c135e 7880 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7881 break;
7882 }
7883 case 12:
7884 switch (sel) {
7885 case 0:
895c2d04 7886 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7887 break;
7888 default:
d75c135e 7889 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7890 break;
7891 }
5a25ce94
EI
7892 case 13:
7893 switch (sel) {
7894 case 0:
895c2d04 7895 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7896 break;
7897 default:
7898 goto die;
7899 break;
7900 }
7901 break;
7902 case 15:
7903 switch (sel) {
7904 case 1:
895c2d04 7905 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7906 break;
7907 default:
7908 goto die;
7909 break;
7910 }
7911 break;
ead9360e
TS
7912 case 23:
7913 switch (sel) {
7914 case 0:
895c2d04 7915 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7916 break;
7917 default:
d75c135e 7918 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7919 break;
7920 }
7921 break;
7922 default:
d75c135e 7923 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7924 }
7925 } else switch (sel) {
7926 /* GPR registers. */
7927 case 0:
895c2d04 7928 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7929 break;
7930 /* Auxiliary CPU registers */
7931 case 1:
7932 switch (rd) {
7933 case 0:
895c2d04 7934 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7935 break;
7936 case 1:
895c2d04 7937 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7938 break;
7939 case 2:
895c2d04 7940 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7941 break;
7942 case 4:
895c2d04 7943 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7944 break;
7945 case 5:
895c2d04 7946 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7947 break;
7948 case 6:
895c2d04 7949 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7950 break;
7951 case 8:
895c2d04 7952 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7953 break;
7954 case 9:
895c2d04 7955 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7956 break;
7957 case 10:
895c2d04 7958 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7959 break;
7960 case 12:
895c2d04 7961 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7962 break;
7963 case 13:
895c2d04 7964 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7965 break;
7966 case 14:
895c2d04 7967 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7968 break;
7969 case 16:
895c2d04 7970 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7971 break;
7972 default:
7973 goto die;
7974 }
7975 break;
7976 /* Floating point (COP1). */
7977 case 2:
7978 /* XXX: For now we support only a single FPU context. */
7979 if (h == 0) {
a7812ae4 7980 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7981
7982 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7983 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7984 tcg_temp_free_i32(fp0);
ead9360e 7985 } else {
a7812ae4 7986 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7987
7988 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7989 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7990 tcg_temp_free_i32(fp0);
ead9360e
TS
7991 }
7992 break;
7993 case 3:
7994 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7995 {
7996 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7997
7998 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7999 tcg_temp_free_i32(fs_tmp);
8000 }
4cf8a45f
YK
8001 /* Stop translation as we may have changed hflags */
8002 ctx->bstate = BS_STOP;
ead9360e
TS
8003 break;
8004 /* COP2: Not implemented. */
8005 case 4:
8006 case 5:
8007 /* fall through */
8008 default:
8009 goto die;
8010 }
d12d51d5 8011 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 8012 tcg_temp_free(t0);
ead9360e
TS
8013 return;
8014
8015die:
1a3fd9c3 8016 tcg_temp_free(t0);
d12d51d5 8017 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8018 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8019}
8020
7db13fae 8021static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8022{
287c4b84 8023 const char *opn = "ldst";
6af0bf9c 8024
2e15497c 8025 check_cp0_enabled(ctx);
6af0bf9c
FB
8026 switch (opc) {
8027 case OPC_MFC0:
8028 if (rt == 0) {
ead9360e 8029 /* Treat as NOP. */
6af0bf9c
FB
8030 return;
8031 }
d75c135e 8032 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8033 opn = "mfc0";
8034 break;
8035 case OPC_MTC0:
1a3fd9c3 8036 {
1fc7bf6e 8037 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8038
8039 gen_load_gpr(t0, rt);
d75c135e 8040 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8041 tcg_temp_free(t0);
8042 }
6af0bf9c
FB
8043 opn = "mtc0";
8044 break;
d26bc211 8045#if defined(TARGET_MIPS64)
9c2149c8 8046 case OPC_DMFC0:
d75c135e 8047 check_insn(ctx, ISA_MIPS3);
9c2149c8 8048 if (rt == 0) {
ead9360e 8049 /* Treat as NOP. */
9c2149c8
TS
8050 return;
8051 }
d75c135e 8052 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8053 opn = "dmfc0";
8054 break;
8055 case OPC_DMTC0:
d75c135e 8056 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8057 {
1fc7bf6e 8058 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8059
8060 gen_load_gpr(t0, rt);
d75c135e 8061 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8062 tcg_temp_free(t0);
8063 }
9c2149c8
TS
8064 opn = "dmtc0";
8065 break;
534ce69f 8066#endif
5204ea79
LA
8067 case OPC_MFHC0:
8068 check_mvh(ctx);
8069 if (rt == 0) {
8070 /* Treat as NOP. */
8071 return;
8072 }
8073 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8074 opn = "mfhc0";
8075 break;
8076 case OPC_MTHC0:
8077 check_mvh(ctx);
8078 {
8079 TCGv t0 = tcg_temp_new();
8080 gen_load_gpr(t0, rt);
8081 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8082 tcg_temp_free(t0);
8083 }
8084 opn = "mthc0";
8085 break;
ead9360e 8086 case OPC_MFTR:
d75c135e 8087 check_insn(ctx, ASE_MT);
ead9360e
TS
8088 if (rd == 0) {
8089 /* Treat as NOP. */
8090 return;
8091 }
6c5c1e20 8092 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8093 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8094 opn = "mftr";
8095 break;
8096 case OPC_MTTR:
d75c135e 8097 check_insn(ctx, ASE_MT);
6c5c1e20 8098 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8099 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8100 opn = "mttr";
8101 break;
6af0bf9c 8102 case OPC_TLBWI:
6af0bf9c 8103 opn = "tlbwi";
c01fccd2 8104 if (!env->tlb->helper_tlbwi)
29929e34 8105 goto die;
895c2d04 8106 gen_helper_tlbwi(cpu_env);
6af0bf9c 8107 break;
9456c2fb
LA
8108 case OPC_TLBINV:
8109 opn = "tlbinv";
8110 if (ctx->ie >= 2) {
8111 if (!env->tlb->helper_tlbinv) {
8112 goto die;
8113 }
8114 gen_helper_tlbinv(cpu_env);
8115 } /* treat as nop if TLBINV not supported */
8116 break;
8117 case OPC_TLBINVF:
8118 opn = "tlbinvf";
8119 if (ctx->ie >= 2) {
8120 if (!env->tlb->helper_tlbinvf) {
8121 goto die;
8122 }
8123 gen_helper_tlbinvf(cpu_env);
8124 } /* treat as nop if TLBINV not supported */
8125 break;
6af0bf9c 8126 case OPC_TLBWR:
6af0bf9c 8127 opn = "tlbwr";
c01fccd2 8128 if (!env->tlb->helper_tlbwr)
29929e34 8129 goto die;
895c2d04 8130 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8131 break;
8132 case OPC_TLBP:
6af0bf9c 8133 opn = "tlbp";
c01fccd2 8134 if (!env->tlb->helper_tlbp)
29929e34 8135 goto die;
895c2d04 8136 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8137 break;
8138 case OPC_TLBR:
6af0bf9c 8139 opn = "tlbr";
c01fccd2 8140 if (!env->tlb->helper_tlbr)
29929e34 8141 goto die;
895c2d04 8142 gen_helper_tlbr(cpu_env);
6af0bf9c 8143 break;
ce9782f4 8144 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8145 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8146 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8147 goto die;
ce9782f4
LA
8148 } else {
8149 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8150 if (ctx->opcode & (1 << bit_shift)) {
8151 /* OPC_ERETNC */
8152 opn = "eretnc";
8153 check_insn(ctx, ISA_MIPS32R5);
8154 gen_helper_eretnc(cpu_env);
8155 } else {
8156 /* OPC_ERET */
8157 opn = "eret";
8158 check_insn(ctx, ISA_MIPS2);
8159 gen_helper_eret(cpu_env);
8160 }
8161 ctx->bstate = BS_EXCP;
339cd2a8 8162 }
6af0bf9c
FB
8163 break;
8164 case OPC_DERET:
8165 opn = "deret";
d75c135e 8166 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8167 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8168 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8169 goto die;
8170 }
6af0bf9c 8171 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8172 MIPS_INVAL(opn);
9c708c7f 8173 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8174 } else {
895c2d04 8175 gen_helper_deret(cpu_env);
6af0bf9c
FB
8176 ctx->bstate = BS_EXCP;
8177 }
8178 break;
4ad40f36
FB
8179 case OPC_WAIT:
8180 opn = "wait";
d75c135e 8181 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8182 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8183 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8184 goto die;
8185 }
4ad40f36
FB
8186 /* If we get an exception, we want to restart at next instruction */
8187 ctx->pc += 4;
8188 save_cpu_state(ctx, 1);
8189 ctx->pc -= 4;
895c2d04 8190 gen_helper_wait(cpu_env);
4ad40f36
FB
8191 ctx->bstate = BS_EXCP;
8192 break;
6af0bf9c 8193 default:
29929e34 8194 die:
923617a3 8195 MIPS_INVAL(opn);
9c708c7f 8196 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8197 return;
8198 }
2abf314d 8199 (void)opn; /* avoid a compiler warning */
6af0bf9c 8200}
f1aa6320 8201#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8202
6ea83fed 8203/* CP1 Branches (before delay slot) */
d75c135e
AJ
8204static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8205 int32_t cc, int32_t offset)
6ea83fed
FB
8206{
8207 target_ulong btarget;
a7812ae4 8208 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8209
339cd2a8 8210 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8211 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8212 goto out;
8213 }
8214
e189e748 8215 if (cc != 0)
d75c135e 8216 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8217
6ea83fed
FB
8218 btarget = ctx->pc + 4 + offset;
8219
7a387fff
TS
8220 switch (op) {
8221 case OPC_BC1F:
d94536f4
AJ
8222 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8223 tcg_gen_not_i32(t0, t0);
8224 tcg_gen_andi_i32(t0, t0, 1);
8225 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8226 goto not_likely;
7a387fff 8227 case OPC_BC1FL:
d94536f4
AJ
8228 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8229 tcg_gen_not_i32(t0, t0);
8230 tcg_gen_andi_i32(t0, t0, 1);
8231 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8232 goto likely;
7a387fff 8233 case OPC_BC1T:
d94536f4
AJ
8234 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8235 tcg_gen_andi_i32(t0, t0, 1);
8236 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8237 goto not_likely;
7a387fff 8238 case OPC_BC1TL:
d94536f4
AJ
8239 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8240 tcg_gen_andi_i32(t0, t0, 1);
8241 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8242 likely:
8243 ctx->hflags |= MIPS_HFLAG_BL;
8244 break;
5a5012ec 8245 case OPC_BC1FANY2:
a16336e4 8246 {
d94536f4
AJ
8247 TCGv_i32 t1 = tcg_temp_new_i32();
8248 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8249 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8250 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8251 tcg_temp_free_i32(t1);
d94536f4
AJ
8252 tcg_gen_andi_i32(t0, t0, 1);
8253 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8254 }
5a5012ec
TS
8255 goto not_likely;
8256 case OPC_BC1TANY2:
a16336e4 8257 {
d94536f4
AJ
8258 TCGv_i32 t1 = tcg_temp_new_i32();
8259 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8260 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8261 tcg_gen_or_i32(t0, t0, t1);
8262 tcg_temp_free_i32(t1);
8263 tcg_gen_andi_i32(t0, t0, 1);
8264 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8265 }
5a5012ec
TS
8266 goto not_likely;
8267 case OPC_BC1FANY4:
a16336e4 8268 {
d94536f4
AJ
8269 TCGv_i32 t1 = tcg_temp_new_i32();
8270 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8271 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8272 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8273 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8274 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8275 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8276 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8277 tcg_temp_free_i32(t1);
d94536f4
AJ
8278 tcg_gen_andi_i32(t0, t0, 1);
8279 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8280 }
5a5012ec
TS
8281 goto not_likely;
8282 case OPC_BC1TANY4:
a16336e4 8283 {
d94536f4
AJ
8284 TCGv_i32 t1 = tcg_temp_new_i32();
8285 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8286 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8287 tcg_gen_or_i32(t0, t0, t1);
8288 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8289 tcg_gen_or_i32(t0, t0, t1);
8290 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8291 tcg_gen_or_i32(t0, t0, t1);
8292 tcg_temp_free_i32(t1);
8293 tcg_gen_andi_i32(t0, t0, 1);
8294 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8295 }
5a5012ec
TS
8296 not_likely:
8297 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8298 break;
8299 default:
9d68ac14 8300 MIPS_INVAL("cp1 cond branch");
9c708c7f 8301 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8302 goto out;
6ea83fed 8303 }
6ea83fed 8304 ctx->btarget = btarget;
b231c103 8305 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8306 out:
a7812ae4 8307 tcg_temp_free_i32(t0);
6ea83fed
FB
8308}
8309
31837be3
YK
8310/* R6 CP1 Branches */
8311static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8312 int32_t ft, int32_t offset,
8313 int delayslot_size)
31837be3
YK
8314{
8315 target_ulong btarget;
31837be3
YK
8316 TCGv_i64 t0 = tcg_temp_new_i64();
8317
8318 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8319#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8320 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8321 "\n", ctx->pc);
31837be3 8322#endif
9c708c7f 8323 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8324 goto out;
8325 }
8326
8327 gen_load_fpr64(ctx, t0, ft);
8328 tcg_gen_andi_i64(t0, t0, 1);
8329
8330 btarget = addr_add(ctx, ctx->pc + 4, offset);
8331
8332 switch (op) {
8333 case OPC_BC1EQZ:
8334 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8335 ctx->hflags |= MIPS_HFLAG_BC;
8336 break;
8337 case OPC_BC1NEZ:
8338 /* t0 already set */
31837be3
YK
8339 ctx->hflags |= MIPS_HFLAG_BC;
8340 break;
8341 default:
9d68ac14 8342 MIPS_INVAL("cp1 cond branch");
9c708c7f 8343 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8344 goto out;
8345 }
8346
8347 tcg_gen_trunc_i64_tl(bcond, t0);
8348
31837be3 8349 ctx->btarget = btarget;
65935f07
YK
8350
8351 switch (delayslot_size) {
8352 case 2:
8353 ctx->hflags |= MIPS_HFLAG_BDS16;
8354 break;
8355 case 4:
8356 ctx->hflags |= MIPS_HFLAG_BDS32;
8357 break;
8358 }
31837be3
YK
8359
8360out:
8361 tcg_temp_free_i64(t0);
8362}
8363
6af0bf9c 8364/* Coprocessor 1 (FPU) */
5a5012ec 8365
5a5012ec
TS
8366#define FOP(func, fmt) (((fmt) << 21) | (func))
8367
bf4120ad
NF
8368enum fopcode {
8369 OPC_ADD_S = FOP(0, FMT_S),
8370 OPC_SUB_S = FOP(1, FMT_S),
8371 OPC_MUL_S = FOP(2, FMT_S),
8372 OPC_DIV_S = FOP(3, FMT_S),
8373 OPC_SQRT_S = FOP(4, FMT_S),
8374 OPC_ABS_S = FOP(5, FMT_S),
8375 OPC_MOV_S = FOP(6, FMT_S),
8376 OPC_NEG_S = FOP(7, FMT_S),
8377 OPC_ROUND_L_S = FOP(8, FMT_S),
8378 OPC_TRUNC_L_S = FOP(9, FMT_S),
8379 OPC_CEIL_L_S = FOP(10, FMT_S),
8380 OPC_FLOOR_L_S = FOP(11, FMT_S),
8381 OPC_ROUND_W_S = FOP(12, FMT_S),
8382 OPC_TRUNC_W_S = FOP(13, FMT_S),
8383 OPC_CEIL_W_S = FOP(14, FMT_S),
8384 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8385 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8386 OPC_MOVCF_S = FOP(17, FMT_S),
8387 OPC_MOVZ_S = FOP(18, FMT_S),
8388 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8389 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8390 OPC_RECIP_S = FOP(21, FMT_S),
8391 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8392 OPC_SELNEZ_S = FOP(23, FMT_S),
8393 OPC_MADDF_S = FOP(24, FMT_S),
8394 OPC_MSUBF_S = FOP(25, FMT_S),
8395 OPC_RINT_S = FOP(26, FMT_S),
8396 OPC_CLASS_S = FOP(27, FMT_S),
8397 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8398 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8399 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8400 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8401 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8402 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8403 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8404 OPC_RSQRT2_S = FOP(31, FMT_S),
8405 OPC_CVT_D_S = FOP(33, FMT_S),
8406 OPC_CVT_W_S = FOP(36, FMT_S),
8407 OPC_CVT_L_S = FOP(37, FMT_S),
8408 OPC_CVT_PS_S = FOP(38, FMT_S),
8409 OPC_CMP_F_S = FOP (48, FMT_S),
8410 OPC_CMP_UN_S = FOP (49, FMT_S),
8411 OPC_CMP_EQ_S = FOP (50, FMT_S),
8412 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8413 OPC_CMP_OLT_S = FOP (52, FMT_S),
8414 OPC_CMP_ULT_S = FOP (53, FMT_S),
8415 OPC_CMP_OLE_S = FOP (54, FMT_S),
8416 OPC_CMP_ULE_S = FOP (55, FMT_S),
8417 OPC_CMP_SF_S = FOP (56, FMT_S),
8418 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8419 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8420 OPC_CMP_NGL_S = FOP (59, FMT_S),
8421 OPC_CMP_LT_S = FOP (60, FMT_S),
8422 OPC_CMP_NGE_S = FOP (61, FMT_S),
8423 OPC_CMP_LE_S = FOP (62, FMT_S),
8424 OPC_CMP_NGT_S = FOP (63, FMT_S),
8425
8426 OPC_ADD_D = FOP(0, FMT_D),
8427 OPC_SUB_D = FOP(1, FMT_D),
8428 OPC_MUL_D = FOP(2, FMT_D),
8429 OPC_DIV_D = FOP(3, FMT_D),
8430 OPC_SQRT_D = FOP(4, FMT_D),
8431 OPC_ABS_D = FOP(5, FMT_D),
8432 OPC_MOV_D = FOP(6, FMT_D),
8433 OPC_NEG_D = FOP(7, FMT_D),
8434 OPC_ROUND_L_D = FOP(8, FMT_D),
8435 OPC_TRUNC_L_D = FOP(9, FMT_D),
8436 OPC_CEIL_L_D = FOP(10, FMT_D),
8437 OPC_FLOOR_L_D = FOP(11, FMT_D),
8438 OPC_ROUND_W_D = FOP(12, FMT_D),
8439 OPC_TRUNC_W_D = FOP(13, FMT_D),
8440 OPC_CEIL_W_D = FOP(14, FMT_D),
8441 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8442 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8443 OPC_MOVCF_D = FOP(17, FMT_D),
8444 OPC_MOVZ_D = FOP(18, FMT_D),
8445 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8446 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8447 OPC_RECIP_D = FOP(21, FMT_D),
8448 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8449 OPC_SELNEZ_D = FOP(23, FMT_D),
8450 OPC_MADDF_D = FOP(24, FMT_D),
8451 OPC_MSUBF_D = FOP(25, FMT_D),
8452 OPC_RINT_D = FOP(26, FMT_D),
8453 OPC_CLASS_D = FOP(27, FMT_D),
8454 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8455 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8456 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8457 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8458 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8459 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8460 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8461 OPC_RSQRT2_D = FOP(31, FMT_D),
8462 OPC_CVT_S_D = FOP(32, FMT_D),
8463 OPC_CVT_W_D = FOP(36, FMT_D),
8464 OPC_CVT_L_D = FOP(37, FMT_D),
8465 OPC_CMP_F_D = FOP (48, FMT_D),
8466 OPC_CMP_UN_D = FOP (49, FMT_D),
8467 OPC_CMP_EQ_D = FOP (50, FMT_D),
8468 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8469 OPC_CMP_OLT_D = FOP (52, FMT_D),
8470 OPC_CMP_ULT_D = FOP (53, FMT_D),
8471 OPC_CMP_OLE_D = FOP (54, FMT_D),
8472 OPC_CMP_ULE_D = FOP (55, FMT_D),
8473 OPC_CMP_SF_D = FOP (56, FMT_D),
8474 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8475 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8476 OPC_CMP_NGL_D = FOP (59, FMT_D),
8477 OPC_CMP_LT_D = FOP (60, FMT_D),
8478 OPC_CMP_NGE_D = FOP (61, FMT_D),
8479 OPC_CMP_LE_D = FOP (62, FMT_D),
8480 OPC_CMP_NGT_D = FOP (63, FMT_D),
8481
8482 OPC_CVT_S_W = FOP(32, FMT_W),
8483 OPC_CVT_D_W = FOP(33, FMT_W),
8484 OPC_CVT_S_L = FOP(32, FMT_L),
8485 OPC_CVT_D_L = FOP(33, FMT_L),
8486 OPC_CVT_PS_PW = FOP(38, FMT_W),
8487
8488 OPC_ADD_PS = FOP(0, FMT_PS),
8489 OPC_SUB_PS = FOP(1, FMT_PS),
8490 OPC_MUL_PS = FOP(2, FMT_PS),
8491 OPC_DIV_PS = FOP(3, FMT_PS),
8492 OPC_ABS_PS = FOP(5, FMT_PS),
8493 OPC_MOV_PS = FOP(6, FMT_PS),
8494 OPC_NEG_PS = FOP(7, FMT_PS),
8495 OPC_MOVCF_PS = FOP(17, FMT_PS),
8496 OPC_MOVZ_PS = FOP(18, FMT_PS),
8497 OPC_MOVN_PS = FOP(19, FMT_PS),
8498 OPC_ADDR_PS = FOP(24, FMT_PS),
8499 OPC_MULR_PS = FOP(26, FMT_PS),
8500 OPC_RECIP2_PS = FOP(28, FMT_PS),
8501 OPC_RECIP1_PS = FOP(29, FMT_PS),
8502 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8503 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8504
8505 OPC_CVT_S_PU = FOP(32, FMT_PS),
8506 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8507 OPC_CVT_S_PL = FOP(40, FMT_PS),
8508 OPC_PLL_PS = FOP(44, FMT_PS),
8509 OPC_PLU_PS = FOP(45, FMT_PS),
8510 OPC_PUL_PS = FOP(46, FMT_PS),
8511 OPC_PUU_PS = FOP(47, FMT_PS),
8512 OPC_CMP_F_PS = FOP (48, FMT_PS),
8513 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8514 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8515 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8516 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8517 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8518 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8519 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8520 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8521 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8522 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8523 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8524 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8525 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8526 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8527 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8528};
8529
3f493883
YK
8530enum r6_f_cmp_op {
8531 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8532 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8533 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8534 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8535 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8536 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8537 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8538 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8539 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8540 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8541 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8542 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8543 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8544 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8545 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8546 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8547 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8548 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8549 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8550 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8551 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8552 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8553
8554 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8555 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8556 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8557 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8558 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8559 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8560 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8561 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8562 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8563 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8564 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8565 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8566 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8567 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8568 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8569 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8570 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8571 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8572 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8573 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8574 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8575 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8576};
7a387fff 8577static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8578{
72c3a3ee 8579 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8580
8581 switch (opc) {
8582 case OPC_MFC1:
b6d96bed 8583 {
a7812ae4 8584 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8585
7c979afd 8586 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8587 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8588 tcg_temp_free_i32(fp0);
6958549d 8589 }
6c5c1e20 8590 gen_store_gpr(t0, rt);
6ea83fed
FB
8591 break;
8592 case OPC_MTC1:
6c5c1e20 8593 gen_load_gpr(t0, rt);
b6d96bed 8594 {
a7812ae4 8595 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8596
8597 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8598 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8599 tcg_temp_free_i32(fp0);
6958549d 8600 }
6ea83fed
FB
8601 break;
8602 case OPC_CFC1:
895c2d04 8603 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8604 gen_store_gpr(t0, rt);
6ea83fed
FB
8605 break;
8606 case OPC_CTC1:
6c5c1e20 8607 gen_load_gpr(t0, rt);
9c708c7f 8608 save_cpu_state(ctx, 0);
736d120a
PJ
8609 {
8610 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8611
8612 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8613 tcg_temp_free_i32(fs_tmp);
8614 }
4cf8a45f
YK
8615 /* Stop translation as we may have changed hflags */
8616 ctx->bstate = BS_STOP;
6ea83fed 8617 break;
72c3a3ee 8618#if defined(TARGET_MIPS64)
9c2149c8 8619 case OPC_DMFC1:
72c3a3ee 8620 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8621 gen_store_gpr(t0, rt);
5a5012ec 8622 break;
9c2149c8 8623 case OPC_DMTC1:
6c5c1e20 8624 gen_load_gpr(t0, rt);
72c3a3ee 8625 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8626 break;
72c3a3ee 8627#endif
5a5012ec 8628 case OPC_MFHC1:
b6d96bed 8629 {
a7812ae4 8630 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8631
7f6613ce 8632 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8633 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8634 tcg_temp_free_i32(fp0);
6958549d 8635 }
6c5c1e20 8636 gen_store_gpr(t0, rt);
5a5012ec
TS
8637 break;
8638 case OPC_MTHC1:
6c5c1e20 8639 gen_load_gpr(t0, rt);
b6d96bed 8640 {
a7812ae4 8641 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8642
8643 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8644 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8645 tcg_temp_free_i32(fp0);
6958549d 8646 }
5a5012ec 8647 break;
6ea83fed 8648 default:
9d68ac14 8649 MIPS_INVAL("cp1 move");
9c708c7f 8650 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8651 goto out;
6ea83fed 8652 }
6c5c1e20
TS
8653
8654 out:
8655 tcg_temp_free(t0);
6ea83fed
FB
8656}
8657
5a5012ec
TS
8658static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8659{
42a268c2 8660 TCGLabel *l1;
e214b9bb 8661 TCGCond cond;
af58f9ca
AJ
8662 TCGv_i32 t0;
8663
8664 if (rd == 0) {
8665 /* Treat as NOP. */
8666 return;
8667 }
6ea83fed 8668
e214b9bb 8669 if (tf)
e214b9bb 8670 cond = TCG_COND_EQ;
27848470
TS
8671 else
8672 cond = TCG_COND_NE;
8673
af58f9ca
AJ
8674 l1 = gen_new_label();
8675 t0 = tcg_temp_new_i32();
fa31af0e 8676 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8677 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8678 tcg_temp_free_i32(t0);
af58f9ca
AJ
8679 if (rs == 0) {
8680 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8681 } else {
8682 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8683 }
e214b9bb 8684 gen_set_label(l1);
5a5012ec
TS
8685}
8686
7c979afd
LA
8687static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8688 int tf)
a16336e4 8689{
a16336e4 8690 int cond;
cbc37b28 8691 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8692 TCGLabel *l1 = gen_new_label();
a16336e4 8693
a16336e4
TS
8694 if (tf)
8695 cond = TCG_COND_EQ;
8696 else
8697 cond = TCG_COND_NE;
8698
fa31af0e 8699 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8700 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8701 gen_load_fpr32(ctx, t0, fs);
8702 gen_store_fpr32(ctx, t0, fd);
a16336e4 8703 gen_set_label(l1);
cbc37b28 8704 tcg_temp_free_i32(t0);
5a5012ec 8705}
a16336e4 8706
b6d96bed 8707static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8708{
a16336e4 8709 int cond;
cbc37b28
AJ
8710 TCGv_i32 t0 = tcg_temp_new_i32();
8711 TCGv_i64 fp0;
42a268c2 8712 TCGLabel *l1 = gen_new_label();
a16336e4 8713
a16336e4
TS
8714 if (tf)
8715 cond = TCG_COND_EQ;
8716 else
8717 cond = TCG_COND_NE;
8718
fa31af0e 8719 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8720 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8721 tcg_temp_free_i32(t0);
11f94258 8722 fp0 = tcg_temp_new_i64();
9bf3eb2c 8723 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8724 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8725 tcg_temp_free_i64(fp0);
cbc37b28 8726 gen_set_label(l1);
a16336e4
TS
8727}
8728
7f6613ce
PJ
8729static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8730 int cc, int tf)
a16336e4
TS
8731{
8732 int cond;
cbc37b28 8733 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8734 TCGLabel *l1 = gen_new_label();
8735 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8736
8737 if (tf)
8738 cond = TCG_COND_EQ;
8739 else
8740 cond = TCG_COND_NE;
8741
fa31af0e 8742 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8743 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8744 gen_load_fpr32(ctx, t0, fs);
8745 gen_store_fpr32(ctx, t0, fd);
a16336e4 8746 gen_set_label(l1);
9bf3eb2c 8747
fa31af0e 8748 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8749 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8750 gen_load_fpr32h(ctx, t0, fs);
8751 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8752 tcg_temp_free_i32(t0);
a16336e4 8753 gen_set_label(l2);
a16336e4
TS
8754}
8755
e7f16abb
LA
8756static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8757 int fs)
8758{
8759 TCGv_i32 t1 = tcg_const_i32(0);
8760 TCGv_i32 fp0 = tcg_temp_new_i32();
8761 TCGv_i32 fp1 = tcg_temp_new_i32();
8762 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8763 gen_load_fpr32(ctx, fp0, fd);
8764 gen_load_fpr32(ctx, fp1, ft);
8765 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8766
8767 switch (op1) {
8768 case OPC_SEL_S:
8769 tcg_gen_andi_i32(fp0, fp0, 1);
8770 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8771 break;
8772 case OPC_SELEQZ_S:
8773 tcg_gen_andi_i32(fp1, fp1, 1);
8774 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8775 break;
8776 case OPC_SELNEZ_S:
8777 tcg_gen_andi_i32(fp1, fp1, 1);
8778 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8779 break;
8780 default:
8781 MIPS_INVAL("gen_sel_s");
9c708c7f 8782 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8783 break;
8784 }
8785
7c979afd 8786 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8787 tcg_temp_free_i32(fp2);
8788 tcg_temp_free_i32(fp1);
8789 tcg_temp_free_i32(fp0);
8790 tcg_temp_free_i32(t1);
8791}
8792
8793static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8794 int fs)
8795{
8796 TCGv_i64 t1 = tcg_const_i64(0);
8797 TCGv_i64 fp0 = tcg_temp_new_i64();
8798 TCGv_i64 fp1 = tcg_temp_new_i64();
8799 TCGv_i64 fp2 = tcg_temp_new_i64();
8800 gen_load_fpr64(ctx, fp0, fd);
8801 gen_load_fpr64(ctx, fp1, ft);
8802 gen_load_fpr64(ctx, fp2, fs);
8803
8804 switch (op1) {
8805 case OPC_SEL_D:
8806 tcg_gen_andi_i64(fp0, fp0, 1);
8807 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8808 break;
8809 case OPC_SELEQZ_D:
8810 tcg_gen_andi_i64(fp1, fp1, 1);
8811 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8812 break;
8813 case OPC_SELNEZ_D:
8814 tcg_gen_andi_i64(fp1, fp1, 1);
8815 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8816 break;
8817 default:
8818 MIPS_INVAL("gen_sel_d");
9c708c7f 8819 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8820 break;
8821 }
8822
8823 gen_store_fpr64(ctx, fp0, fd);
8824 tcg_temp_free_i64(fp2);
8825 tcg_temp_free_i64(fp1);
8826 tcg_temp_free_i64(fp0);
8827 tcg_temp_free_i64(t1);
8828}
6ea83fed 8829
bf4120ad 8830static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8831 int ft, int fs, int fd, int cc)
6ea83fed 8832{
7a387fff 8833 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8834 switch (op1) {
8835 case OPC_ADD_S:
b6d96bed 8836 {
a7812ae4
PB
8837 TCGv_i32 fp0 = tcg_temp_new_i32();
8838 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8839
7c979afd
LA
8840 gen_load_fpr32(ctx, fp0, fs);
8841 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8842 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8843 tcg_temp_free_i32(fp1);
7c979afd 8844 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8845 tcg_temp_free_i32(fp0);
b6d96bed 8846 }
5a5012ec 8847 break;
bf4120ad 8848 case OPC_SUB_S:
b6d96bed 8849 {
a7812ae4
PB
8850 TCGv_i32 fp0 = tcg_temp_new_i32();
8851 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8852
7c979afd
LA
8853 gen_load_fpr32(ctx, fp0, fs);
8854 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8855 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8856 tcg_temp_free_i32(fp1);
7c979afd 8857 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8858 tcg_temp_free_i32(fp0);
b6d96bed 8859 }
5a5012ec 8860 break;
bf4120ad 8861 case OPC_MUL_S:
b6d96bed 8862 {
a7812ae4
PB
8863 TCGv_i32 fp0 = tcg_temp_new_i32();
8864 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8865
7c979afd
LA
8866 gen_load_fpr32(ctx, fp0, fs);
8867 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8868 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8869 tcg_temp_free_i32(fp1);
7c979afd 8870 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8871 tcg_temp_free_i32(fp0);
b6d96bed 8872 }
5a5012ec 8873 break;
bf4120ad 8874 case OPC_DIV_S:
b6d96bed 8875 {
a7812ae4
PB
8876 TCGv_i32 fp0 = tcg_temp_new_i32();
8877 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8878
7c979afd
LA
8879 gen_load_fpr32(ctx, fp0, fs);
8880 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8881 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8882 tcg_temp_free_i32(fp1);
7c979afd 8883 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8884 tcg_temp_free_i32(fp0);
b6d96bed 8885 }
5a5012ec 8886 break;
bf4120ad 8887 case OPC_SQRT_S:
b6d96bed 8888 {
a7812ae4 8889 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8890
7c979afd 8891 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8892 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8893 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8894 tcg_temp_free_i32(fp0);
b6d96bed 8895 }
5a5012ec 8896 break;
bf4120ad 8897 case OPC_ABS_S:
b6d96bed 8898 {
a7812ae4 8899 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8900
7c979afd 8901 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
8902 if (ctx->abs2008) {
8903 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8904 } else {
8905 gen_helper_float_abs_s(fp0, fp0);
8906 }
7c979afd 8907 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8908 tcg_temp_free_i32(fp0);
b6d96bed 8909 }
5a5012ec 8910 break;
bf4120ad 8911 case OPC_MOV_S:
b6d96bed 8912 {
a7812ae4 8913 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8914
7c979afd
LA
8915 gen_load_fpr32(ctx, fp0, fs);
8916 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8917 tcg_temp_free_i32(fp0);
b6d96bed 8918 }
5a5012ec 8919 break;
bf4120ad 8920 case OPC_NEG_S:
b6d96bed 8921 {
a7812ae4 8922 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8923
7c979afd 8924 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
8925 if (ctx->abs2008) {
8926 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8927 } else {
8928 gen_helper_float_chs_s(fp0, fp0);
8929 }
7c979afd 8930 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8931 tcg_temp_free_i32(fp0);
b6d96bed 8932 }
5a5012ec 8933 break;
bf4120ad 8934 case OPC_ROUND_L_S:
5e755519 8935 check_cp1_64bitmode(ctx);
b6d96bed 8936 {
a7812ae4
PB
8937 TCGv_i32 fp32 = tcg_temp_new_i32();
8938 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8939
7c979afd 8940 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8941 if (ctx->nan2008) {
8942 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8943 } else {
8944 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8945 }
a7812ae4 8946 tcg_temp_free_i32(fp32);
b6d96bed 8947 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8948 tcg_temp_free_i64(fp64);
b6d96bed 8949 }
5a5012ec 8950 break;
bf4120ad 8951 case OPC_TRUNC_L_S:
5e755519 8952 check_cp1_64bitmode(ctx);
b6d96bed 8953 {
a7812ae4
PB
8954 TCGv_i32 fp32 = tcg_temp_new_i32();
8955 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8956
7c979afd 8957 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8958 if (ctx->nan2008) {
8959 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8960 } else {
8961 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8962 }
a7812ae4 8963 tcg_temp_free_i32(fp32);
b6d96bed 8964 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8965 tcg_temp_free_i64(fp64);
b6d96bed 8966 }
5a5012ec 8967 break;
bf4120ad 8968 case OPC_CEIL_L_S:
5e755519 8969 check_cp1_64bitmode(ctx);
b6d96bed 8970 {
a7812ae4
PB
8971 TCGv_i32 fp32 = tcg_temp_new_i32();
8972 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8973
7c979afd 8974 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8975 if (ctx->nan2008) {
8976 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8977 } else {
8978 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8979 }
a7812ae4 8980 tcg_temp_free_i32(fp32);
b6d96bed 8981 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8982 tcg_temp_free_i64(fp64);
b6d96bed 8983 }
5a5012ec 8984 break;
bf4120ad 8985 case OPC_FLOOR_L_S:
5e755519 8986 check_cp1_64bitmode(ctx);
b6d96bed 8987 {
a7812ae4
PB
8988 TCGv_i32 fp32 = tcg_temp_new_i32();
8989 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8990
7c979afd 8991 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
8992 if (ctx->nan2008) {
8993 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8994 } else {
8995 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8996 }
a7812ae4 8997 tcg_temp_free_i32(fp32);
b6d96bed 8998 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8999 tcg_temp_free_i64(fp64);
b6d96bed 9000 }
5a5012ec 9001 break;
bf4120ad 9002 case OPC_ROUND_W_S:
b6d96bed 9003 {
a7812ae4 9004 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9005
7c979afd 9006 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9007 if (ctx->nan2008) {
9008 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9009 } else {
9010 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9011 }
7c979afd 9012 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9013 tcg_temp_free_i32(fp0);
b6d96bed 9014 }
5a5012ec 9015 break;
bf4120ad 9016 case OPC_TRUNC_W_S:
b6d96bed 9017 {
a7812ae4 9018 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9019
7c979afd 9020 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9021 if (ctx->nan2008) {
9022 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9023 } else {
9024 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9025 }
7c979afd 9026 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9027 tcg_temp_free_i32(fp0);
b6d96bed 9028 }
5a5012ec 9029 break;
bf4120ad 9030 case OPC_CEIL_W_S:
b6d96bed 9031 {
a7812ae4 9032 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9033
7c979afd 9034 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9035 if (ctx->nan2008) {
9036 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9037 } else {
9038 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9039 }
7c979afd 9040 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9041 tcg_temp_free_i32(fp0);
b6d96bed 9042 }
5a5012ec 9043 break;
bf4120ad 9044 case OPC_FLOOR_W_S:
b6d96bed 9045 {
a7812ae4 9046 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9047
7c979afd 9048 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9049 if (ctx->nan2008) {
9050 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9051 } else {
9052 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9053 }
7c979afd 9054 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9055 tcg_temp_free_i32(fp0);
b6d96bed 9056 }
5a5012ec 9057 break;
e7f16abb
LA
9058 case OPC_SEL_S:
9059 check_insn(ctx, ISA_MIPS32R6);
9060 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9061 break;
9062 case OPC_SELEQZ_S:
9063 check_insn(ctx, ISA_MIPS32R6);
9064 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9065 break;
9066 case OPC_SELNEZ_S:
9067 check_insn(ctx, ISA_MIPS32R6);
9068 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9069 break;
bf4120ad 9070 case OPC_MOVCF_S:
fecd2646 9071 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9072 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9073 break;
bf4120ad 9074 case OPC_MOVZ_S:
fecd2646 9075 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9076 {
42a268c2 9077 TCGLabel *l1 = gen_new_label();
c9297f4d 9078 TCGv_i32 fp0;
a16336e4 9079
c9297f4d
AJ
9080 if (ft != 0) {
9081 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9082 }
9083 fp0 = tcg_temp_new_i32();
7c979afd
LA
9084 gen_load_fpr32(ctx, fp0, fs);
9085 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9086 tcg_temp_free_i32(fp0);
a16336e4
TS
9087 gen_set_label(l1);
9088 }
5a5012ec 9089 break;
bf4120ad 9090 case OPC_MOVN_S:
fecd2646 9091 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9092 {
42a268c2 9093 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9094 TCGv_i32 fp0;
9095
9096 if (ft != 0) {
9097 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9098 fp0 = tcg_temp_new_i32();
7c979afd
LA
9099 gen_load_fpr32(ctx, fp0, fs);
9100 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9101 tcg_temp_free_i32(fp0);
9102 gen_set_label(l1);
9103 }
a16336e4 9104 }
5a5012ec 9105 break;
bf4120ad 9106 case OPC_RECIP_S:
b6d96bed 9107 {
a7812ae4 9108 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9109
7c979afd 9110 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9111 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9112 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9113 tcg_temp_free_i32(fp0);
b6d96bed 9114 }
57fa1fb3 9115 break;
bf4120ad 9116 case OPC_RSQRT_S:
b6d96bed 9117 {
a7812ae4 9118 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9119
7c979afd 9120 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9121 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9122 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9123 tcg_temp_free_i32(fp0);
b6d96bed 9124 }
57fa1fb3 9125 break;
e7f16abb
LA
9126 case OPC_MADDF_S:
9127 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9128 {
a7812ae4
PB
9129 TCGv_i32 fp0 = tcg_temp_new_i32();
9130 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9131 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9132 gen_load_fpr32(ctx, fp0, fs);
9133 gen_load_fpr32(ctx, fp1, ft);
9134 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9135 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9136 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9137 tcg_temp_free_i32(fp2);
a7812ae4 9138 tcg_temp_free_i32(fp1);
a7812ae4 9139 tcg_temp_free_i32(fp0);
b6d96bed 9140 }
57fa1fb3 9141 break;
e7f16abb
LA
9142 case OPC_MSUBF_S:
9143 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9144 {
a7812ae4 9145 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9146 TCGv_i32 fp1 = tcg_temp_new_i32();
9147 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9148 gen_load_fpr32(ctx, fp0, fs);
9149 gen_load_fpr32(ctx, fp1, ft);
9150 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9151 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9152 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9153 tcg_temp_free_i32(fp2);
9154 tcg_temp_free_i32(fp1);
a7812ae4 9155 tcg_temp_free_i32(fp0);
b6d96bed 9156 }
57fa1fb3 9157 break;
e7f16abb
LA
9158 case OPC_RINT_S:
9159 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9160 {
a7812ae4 9161 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9162 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9163 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9164 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9165 tcg_temp_free_i32(fp0);
b6d96bed 9166 }
57fa1fb3 9167 break;
e7f16abb
LA
9168 case OPC_CLASS_S:
9169 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9170 {
e7f16abb 9171 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9172 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9173 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9174 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9175 tcg_temp_free_i32(fp0);
e7f16abb
LA
9176 }
9177 break;
9178 case OPC_MIN_S: /* OPC_RECIP2_S */
9179 if (ctx->insn_flags & ISA_MIPS32R6) {
9180 /* OPC_MIN_S */
a7812ae4
PB
9181 TCGv_i32 fp0 = tcg_temp_new_i32();
9182 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9183 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9184 gen_load_fpr32(ctx, fp0, fs);
9185 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9186 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9187 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9188 tcg_temp_free_i32(fp2);
9189 tcg_temp_free_i32(fp1);
9190 tcg_temp_free_i32(fp0);
e7f16abb
LA
9191 } else {
9192 /* OPC_RECIP2_S */
9193 check_cp1_64bitmode(ctx);
9194 {
9195 TCGv_i32 fp0 = tcg_temp_new_i32();
9196 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9197
7c979afd
LA
9198 gen_load_fpr32(ctx, fp0, fs);
9199 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9200 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9201 tcg_temp_free_i32(fp1);
7c979afd 9202 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9203 tcg_temp_free_i32(fp0);
9204 }
e7f16abb
LA
9205 }
9206 break;
9207 case OPC_MINA_S: /* OPC_RECIP1_S */
9208 if (ctx->insn_flags & ISA_MIPS32R6) {
9209 /* OPC_MINA_S */
9210 TCGv_i32 fp0 = tcg_temp_new_i32();
9211 TCGv_i32 fp1 = tcg_temp_new_i32();
9212 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9213 gen_load_fpr32(ctx, fp0, fs);
9214 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9215 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9216 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9217 tcg_temp_free_i32(fp2);
9218 tcg_temp_free_i32(fp1);
9219 tcg_temp_free_i32(fp0);
e7f16abb
LA
9220 } else {
9221 /* OPC_RECIP1_S */
9222 check_cp1_64bitmode(ctx);
9223 {
9224 TCGv_i32 fp0 = tcg_temp_new_i32();
9225
7c979afd 9226 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9227 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9228 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9229 tcg_temp_free_i32(fp0);
9230 }
e7f16abb
LA
9231 }
9232 break;
9233 case OPC_MAX_S: /* OPC_RSQRT1_S */
9234 if (ctx->insn_flags & ISA_MIPS32R6) {
9235 /* OPC_MAX_S */
9236 TCGv_i32 fp0 = tcg_temp_new_i32();
9237 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9238 gen_load_fpr32(ctx, fp0, fs);
9239 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9240 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9241 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9242 tcg_temp_free_i32(fp1);
9243 tcg_temp_free_i32(fp0);
e7f16abb
LA
9244 } else {
9245 /* OPC_RSQRT1_S */
9246 check_cp1_64bitmode(ctx);
9247 {
9248 TCGv_i32 fp0 = tcg_temp_new_i32();
9249
7c979afd 9250 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9251 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9252 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9253 tcg_temp_free_i32(fp0);
9254 }
e7f16abb
LA
9255 }
9256 break;
9257 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9258 if (ctx->insn_flags & ISA_MIPS32R6) {
9259 /* OPC_MAXA_S */
9260 TCGv_i32 fp0 = tcg_temp_new_i32();
9261 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9262 gen_load_fpr32(ctx, fp0, fs);
9263 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9264 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9265 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9266 tcg_temp_free_i32(fp1);
a7812ae4 9267 tcg_temp_free_i32(fp0);
e7f16abb
LA
9268 } else {
9269 /* OPC_RSQRT2_S */
9270 check_cp1_64bitmode(ctx);
9271 {
9272 TCGv_i32 fp0 = tcg_temp_new_i32();
9273 TCGv_i32 fp1 = tcg_temp_new_i32();
9274
7c979afd
LA
9275 gen_load_fpr32(ctx, fp0, fs);
9276 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9277 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9278 tcg_temp_free_i32(fp1);
7c979afd 9279 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9280 tcg_temp_free_i32(fp0);
9281 }
b6d96bed 9282 }
57fa1fb3 9283 break;
bf4120ad 9284 case OPC_CVT_D_S:
5e755519 9285 check_cp1_registers(ctx, fd);
b6d96bed 9286 {
a7812ae4
PB
9287 TCGv_i32 fp32 = tcg_temp_new_i32();
9288 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9289
7c979afd 9290 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9291 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9292 tcg_temp_free_i32(fp32);
b6d96bed 9293 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9294 tcg_temp_free_i64(fp64);
b6d96bed 9295 }
5a5012ec 9296 break;
bf4120ad 9297 case OPC_CVT_W_S:
b6d96bed 9298 {
a7812ae4 9299 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9300
7c979afd 9301 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9302 if (ctx->nan2008) {
9303 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9304 } else {
9305 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9306 }
7c979afd 9307 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i32(fp0);
b6d96bed 9309 }
5a5012ec 9310 break;
bf4120ad 9311 case OPC_CVT_L_S:
5e755519 9312 check_cp1_64bitmode(ctx);
b6d96bed 9313 {
a7812ae4
PB
9314 TCGv_i32 fp32 = tcg_temp_new_i32();
9315 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9316
7c979afd 9317 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9318 if (ctx->nan2008) {
9319 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9320 } else {
9321 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9322 }
a7812ae4 9323 tcg_temp_free_i32(fp32);
b6d96bed 9324 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9325 tcg_temp_free_i64(fp64);
b6d96bed 9326 }
5a5012ec 9327 break;
bf4120ad 9328 case OPC_CVT_PS_S:
e29c9628 9329 check_ps(ctx);
b6d96bed 9330 {
a7812ae4
PB
9331 TCGv_i64 fp64 = tcg_temp_new_i64();
9332 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9333 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9334
7c979afd
LA
9335 gen_load_fpr32(ctx, fp32_0, fs);
9336 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9337 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9338 tcg_temp_free_i32(fp32_1);
9339 tcg_temp_free_i32(fp32_0);
36aa55dc 9340 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9341 tcg_temp_free_i64(fp64);
b6d96bed 9342 }
5a5012ec 9343 break;
bf4120ad
NF
9344 case OPC_CMP_F_S:
9345 case OPC_CMP_UN_S:
9346 case OPC_CMP_EQ_S:
9347 case OPC_CMP_UEQ_S:
9348 case OPC_CMP_OLT_S:
9349 case OPC_CMP_ULT_S:
9350 case OPC_CMP_OLE_S:
9351 case OPC_CMP_ULE_S:
9352 case OPC_CMP_SF_S:
9353 case OPC_CMP_NGLE_S:
9354 case OPC_CMP_SEQ_S:
9355 case OPC_CMP_NGL_S:
9356 case OPC_CMP_LT_S:
9357 case OPC_CMP_NGE_S:
9358 case OPC_CMP_LE_S:
9359 case OPC_CMP_NGT_S:
fecd2646 9360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9361 if (ctx->opcode & (1 << 6)) {
9362 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9363 } else {
9364 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9365 }
5a5012ec 9366 break;
bf4120ad 9367 case OPC_ADD_D:
5e755519 9368 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9369 {
a7812ae4
PB
9370 TCGv_i64 fp0 = tcg_temp_new_i64();
9371 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9372
9373 gen_load_fpr64(ctx, fp0, fs);
9374 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9375 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9376 tcg_temp_free_i64(fp1);
b6d96bed 9377 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9378 tcg_temp_free_i64(fp0);
b6d96bed 9379 }
6ea83fed 9380 break;
bf4120ad 9381 case OPC_SUB_D:
5e755519 9382 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9383 {
a7812ae4
PB
9384 TCGv_i64 fp0 = tcg_temp_new_i64();
9385 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9386
9387 gen_load_fpr64(ctx, fp0, fs);
9388 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9389 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9390 tcg_temp_free_i64(fp1);
b6d96bed 9391 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9392 tcg_temp_free_i64(fp0);
b6d96bed 9393 }
6ea83fed 9394 break;
bf4120ad 9395 case OPC_MUL_D:
5e755519 9396 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9397 {
a7812ae4
PB
9398 TCGv_i64 fp0 = tcg_temp_new_i64();
9399 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9400
9401 gen_load_fpr64(ctx, fp0, fs);
9402 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9403 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9404 tcg_temp_free_i64(fp1);
b6d96bed 9405 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9406 tcg_temp_free_i64(fp0);
b6d96bed 9407 }
6ea83fed 9408 break;
bf4120ad 9409 case OPC_DIV_D:
5e755519 9410 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9411 {
a7812ae4
PB
9412 TCGv_i64 fp0 = tcg_temp_new_i64();
9413 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9414
9415 gen_load_fpr64(ctx, fp0, fs);
9416 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9417 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9418 tcg_temp_free_i64(fp1);
b6d96bed 9419 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9420 tcg_temp_free_i64(fp0);
b6d96bed 9421 }
6ea83fed 9422 break;
bf4120ad 9423 case OPC_SQRT_D:
5e755519 9424 check_cp1_registers(ctx, fs | fd);
b6d96bed 9425 {
a7812ae4 9426 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9427
9428 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9429 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9430 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9431 tcg_temp_free_i64(fp0);
b6d96bed 9432 }
6ea83fed 9433 break;
bf4120ad 9434 case OPC_ABS_D:
5e755519 9435 check_cp1_registers(ctx, fs | fd);
b6d96bed 9436 {
a7812ae4 9437 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9438
9439 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9440 if (ctx->abs2008) {
9441 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9442 } else {
9443 gen_helper_float_abs_d(fp0, fp0);
9444 }
b6d96bed 9445 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9446 tcg_temp_free_i64(fp0);
b6d96bed 9447 }
6ea83fed 9448 break;
bf4120ad 9449 case OPC_MOV_D:
5e755519 9450 check_cp1_registers(ctx, fs | fd);
b6d96bed 9451 {
a7812ae4 9452 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9453
9454 gen_load_fpr64(ctx, fp0, fs);
9455 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9456 tcg_temp_free_i64(fp0);
b6d96bed 9457 }
6ea83fed 9458 break;
bf4120ad 9459 case OPC_NEG_D:
5e755519 9460 check_cp1_registers(ctx, fs | fd);
b6d96bed 9461 {
a7812ae4 9462 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9463
9464 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9465 if (ctx->abs2008) {
9466 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9467 } else {
9468 gen_helper_float_chs_d(fp0, fp0);
9469 }
b6d96bed 9470 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9471 tcg_temp_free_i64(fp0);
b6d96bed 9472 }
6ea83fed 9473 break;
bf4120ad 9474 case OPC_ROUND_L_D:
5e755519 9475 check_cp1_64bitmode(ctx);
b6d96bed 9476 {
a7812ae4 9477 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9478
9479 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9480 if (ctx->nan2008) {
9481 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9482 } else {
9483 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9484 }
b6d96bed 9485 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9486 tcg_temp_free_i64(fp0);
b6d96bed 9487 }
5a5012ec 9488 break;
bf4120ad 9489 case OPC_TRUNC_L_D:
5e755519 9490 check_cp1_64bitmode(ctx);
b6d96bed 9491 {
a7812ae4 9492 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9493
9494 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9495 if (ctx->nan2008) {
9496 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9497 } else {
9498 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9499 }
b6d96bed 9500 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9501 tcg_temp_free_i64(fp0);
b6d96bed 9502 }
5a5012ec 9503 break;
bf4120ad 9504 case OPC_CEIL_L_D:
5e755519 9505 check_cp1_64bitmode(ctx);
b6d96bed 9506 {
a7812ae4 9507 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9508
9509 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9510 if (ctx->nan2008) {
9511 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9512 } else {
9513 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9514 }
b6d96bed 9515 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9516 tcg_temp_free_i64(fp0);
b6d96bed 9517 }
5a5012ec 9518 break;
bf4120ad 9519 case OPC_FLOOR_L_D:
5e755519 9520 check_cp1_64bitmode(ctx);
b6d96bed 9521 {
a7812ae4 9522 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9523
9524 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9525 if (ctx->nan2008) {
9526 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9527 } else {
9528 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9529 }
b6d96bed 9530 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9531 tcg_temp_free_i64(fp0);
b6d96bed 9532 }
5a5012ec 9533 break;
bf4120ad 9534 case OPC_ROUND_W_D:
5e755519 9535 check_cp1_registers(ctx, fs);
b6d96bed 9536 {
a7812ae4
PB
9537 TCGv_i32 fp32 = tcg_temp_new_i32();
9538 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9539
9540 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9541 if (ctx->nan2008) {
9542 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9543 } else {
9544 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9545 }
a7812ae4 9546 tcg_temp_free_i64(fp64);
7c979afd 9547 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9548 tcg_temp_free_i32(fp32);
b6d96bed 9549 }
6ea83fed 9550 break;
bf4120ad 9551 case OPC_TRUNC_W_D:
5e755519 9552 check_cp1_registers(ctx, fs);
b6d96bed 9553 {
a7812ae4
PB
9554 TCGv_i32 fp32 = tcg_temp_new_i32();
9555 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9556
9557 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9558 if (ctx->nan2008) {
9559 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9560 } else {
9561 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9562 }
a7812ae4 9563 tcg_temp_free_i64(fp64);
7c979afd 9564 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9565 tcg_temp_free_i32(fp32);
b6d96bed 9566 }
6ea83fed 9567 break;
bf4120ad 9568 case OPC_CEIL_W_D:
5e755519 9569 check_cp1_registers(ctx, fs);
b6d96bed 9570 {
a7812ae4
PB
9571 TCGv_i32 fp32 = tcg_temp_new_i32();
9572 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9573
9574 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9575 if (ctx->nan2008) {
9576 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9577 } else {
9578 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9579 }
a7812ae4 9580 tcg_temp_free_i64(fp64);
7c979afd 9581 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9582 tcg_temp_free_i32(fp32);
b6d96bed 9583 }
6ea83fed 9584 break;
bf4120ad 9585 case OPC_FLOOR_W_D:
5e755519 9586 check_cp1_registers(ctx, fs);
b6d96bed 9587 {
a7812ae4
PB
9588 TCGv_i32 fp32 = tcg_temp_new_i32();
9589 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9590
9591 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9592 if (ctx->nan2008) {
9593 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9594 } else {
9595 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9596 }
a7812ae4 9597 tcg_temp_free_i64(fp64);
7c979afd 9598 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9599 tcg_temp_free_i32(fp32);
b6d96bed 9600 }
6ea83fed 9601 break;
e7f16abb
LA
9602 case OPC_SEL_D:
9603 check_insn(ctx, ISA_MIPS32R6);
9604 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9605 break;
9606 case OPC_SELEQZ_D:
9607 check_insn(ctx, ISA_MIPS32R6);
9608 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9609 break;
9610 case OPC_SELNEZ_D:
9611 check_insn(ctx, ISA_MIPS32R6);
9612 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9613 break;
bf4120ad 9614 case OPC_MOVCF_D:
fecd2646 9615 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9616 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9617 break;
bf4120ad 9618 case OPC_MOVZ_D:
fecd2646 9619 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9620 {
42a268c2 9621 TCGLabel *l1 = gen_new_label();
c9297f4d 9622 TCGv_i64 fp0;
a16336e4 9623
c9297f4d
AJ
9624 if (ft != 0) {
9625 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9626 }
9627 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9628 gen_load_fpr64(ctx, fp0, fs);
9629 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9630 tcg_temp_free_i64(fp0);
a16336e4
TS
9631 gen_set_label(l1);
9632 }
5a5012ec 9633 break;
bf4120ad 9634 case OPC_MOVN_D:
fecd2646 9635 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9636 {
42a268c2 9637 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9638 TCGv_i64 fp0;
9639
9640 if (ft != 0) {
9641 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9642 fp0 = tcg_temp_new_i64();
9643 gen_load_fpr64(ctx, fp0, fs);
9644 gen_store_fpr64(ctx, fp0, fd);
9645 tcg_temp_free_i64(fp0);
9646 gen_set_label(l1);
9647 }
a16336e4 9648 }
6ea83fed 9649 break;
bf4120ad 9650 case OPC_RECIP_D:
ca6c7803 9651 check_cp1_registers(ctx, fs | fd);
b6d96bed 9652 {
a7812ae4 9653 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9654
9655 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9656 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9657 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9658 tcg_temp_free_i64(fp0);
b6d96bed 9659 }
57fa1fb3 9660 break;
bf4120ad 9661 case OPC_RSQRT_D:
ca6c7803 9662 check_cp1_registers(ctx, fs | fd);
b6d96bed 9663 {
a7812ae4 9664 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9665
9666 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9667 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9668 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9669 tcg_temp_free_i64(fp0);
b6d96bed 9670 }
57fa1fb3 9671 break;
e7f16abb
LA
9672 case OPC_MADDF_D:
9673 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9674 {
a7812ae4
PB
9675 TCGv_i64 fp0 = tcg_temp_new_i64();
9676 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9677 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9678 gen_load_fpr64(ctx, fp0, fs);
9679 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9680 gen_load_fpr64(ctx, fp2, fd);
9681 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9682 gen_store_fpr64(ctx, fp2, fd);
9683 tcg_temp_free_i64(fp2);
a7812ae4 9684 tcg_temp_free_i64(fp1);
a7812ae4 9685 tcg_temp_free_i64(fp0);
b6d96bed 9686 }
57fa1fb3 9687 break;
e7f16abb
LA
9688 case OPC_MSUBF_D:
9689 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9690 {
a7812ae4 9691 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9692 TCGv_i64 fp1 = tcg_temp_new_i64();
9693 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9694 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9695 gen_load_fpr64(ctx, fp1, ft);
9696 gen_load_fpr64(ctx, fp2, fd);
9697 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9698 gen_store_fpr64(ctx, fp2, fd);
9699 tcg_temp_free_i64(fp2);
9700 tcg_temp_free_i64(fp1);
a7812ae4 9701 tcg_temp_free_i64(fp0);
b6d96bed 9702 }
57fa1fb3 9703 break;
e7f16abb
LA
9704 case OPC_RINT_D:
9705 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9706 {
a7812ae4 9707 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9708 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9709 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9710 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9711 tcg_temp_free_i64(fp0);
b6d96bed 9712 }
57fa1fb3 9713 break;
e7f16abb
LA
9714 case OPC_CLASS_D:
9715 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9716 {
e7f16abb
LA
9717 TCGv_i64 fp0 = tcg_temp_new_i64();
9718 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9719 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9720 gen_store_fpr64(ctx, fp0, fd);
9721 tcg_temp_free_i64(fp0);
e7f16abb
LA
9722 }
9723 break;
9724 case OPC_MIN_D: /* OPC_RECIP2_D */
9725 if (ctx->insn_flags & ISA_MIPS32R6) {
9726 /* OPC_MIN_D */
a7812ae4
PB
9727 TCGv_i64 fp0 = tcg_temp_new_i64();
9728 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9729 gen_load_fpr64(ctx, fp0, fs);
9730 gen_load_fpr64(ctx, fp1, ft);
9731 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9732 gen_store_fpr64(ctx, fp1, fd);
9733 tcg_temp_free_i64(fp1);
9734 tcg_temp_free_i64(fp0);
e7f16abb
LA
9735 } else {
9736 /* OPC_RECIP2_D */
9737 check_cp1_64bitmode(ctx);
9738 {
9739 TCGv_i64 fp0 = tcg_temp_new_i64();
9740 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9741
e7f16abb
LA
9742 gen_load_fpr64(ctx, fp0, fs);
9743 gen_load_fpr64(ctx, fp1, ft);
9744 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9745 tcg_temp_free_i64(fp1);
9746 gen_store_fpr64(ctx, fp0, fd);
9747 tcg_temp_free_i64(fp0);
9748 }
e7f16abb
LA
9749 }
9750 break;
9751 case OPC_MINA_D: /* OPC_RECIP1_D */
9752 if (ctx->insn_flags & ISA_MIPS32R6) {
9753 /* OPC_MINA_D */
9754 TCGv_i64 fp0 = tcg_temp_new_i64();
9755 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9756 gen_load_fpr64(ctx, fp0, fs);
9757 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9758 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9759 gen_store_fpr64(ctx, fp1, fd);
9760 tcg_temp_free_i64(fp1);
9761 tcg_temp_free_i64(fp0);
e7f16abb
LA
9762 } else {
9763 /* OPC_RECIP1_D */
9764 check_cp1_64bitmode(ctx);
9765 {
9766 TCGv_i64 fp0 = tcg_temp_new_i64();
9767
9768 gen_load_fpr64(ctx, fp0, fs);
9769 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9770 gen_store_fpr64(ctx, fp0, fd);
9771 tcg_temp_free_i64(fp0);
9772 }
e7f16abb
LA
9773 }
9774 break;
9775 case OPC_MAX_D: /* OPC_RSQRT1_D */
9776 if (ctx->insn_flags & ISA_MIPS32R6) {
9777 /* OPC_MAX_D */
9778 TCGv_i64 fp0 = tcg_temp_new_i64();
9779 TCGv_i64 fp1 = tcg_temp_new_i64();
9780 gen_load_fpr64(ctx, fp0, fs);
9781 gen_load_fpr64(ctx, fp1, ft);
9782 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9783 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9784 tcg_temp_free_i64(fp1);
a7812ae4 9785 tcg_temp_free_i64(fp0);
e7f16abb
LA
9786 } else {
9787 /* OPC_RSQRT1_D */
9788 check_cp1_64bitmode(ctx);
9789 {
9790 TCGv_i64 fp0 = tcg_temp_new_i64();
9791
9792 gen_load_fpr64(ctx, fp0, fs);
9793 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9794 gen_store_fpr64(ctx, fp0, fd);
9795 tcg_temp_free_i64(fp0);
9796 }
e7f16abb
LA
9797 }
9798 break;
9799 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9800 if (ctx->insn_flags & ISA_MIPS32R6) {
9801 /* OPC_MAXA_D */
9802 TCGv_i64 fp0 = tcg_temp_new_i64();
9803 TCGv_i64 fp1 = tcg_temp_new_i64();
9804 gen_load_fpr64(ctx, fp0, fs);
9805 gen_load_fpr64(ctx, fp1, ft);
9806 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9807 gen_store_fpr64(ctx, fp1, fd);
9808 tcg_temp_free_i64(fp1);
9809 tcg_temp_free_i64(fp0);
e7f16abb
LA
9810 } else {
9811 /* OPC_RSQRT2_D */
9812 check_cp1_64bitmode(ctx);
9813 {
9814 TCGv_i64 fp0 = tcg_temp_new_i64();
9815 TCGv_i64 fp1 = tcg_temp_new_i64();
9816
9817 gen_load_fpr64(ctx, fp0, fs);
9818 gen_load_fpr64(ctx, fp1, ft);
9819 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9820 tcg_temp_free_i64(fp1);
9821 gen_store_fpr64(ctx, fp0, fd);
9822 tcg_temp_free_i64(fp0);
9823 }
b6d96bed 9824 }
57fa1fb3 9825 break;
bf4120ad
NF
9826 case OPC_CMP_F_D:
9827 case OPC_CMP_UN_D:
9828 case OPC_CMP_EQ_D:
9829 case OPC_CMP_UEQ_D:
9830 case OPC_CMP_OLT_D:
9831 case OPC_CMP_ULT_D:
9832 case OPC_CMP_OLE_D:
9833 case OPC_CMP_ULE_D:
9834 case OPC_CMP_SF_D:
9835 case OPC_CMP_NGLE_D:
9836 case OPC_CMP_SEQ_D:
9837 case OPC_CMP_NGL_D:
9838 case OPC_CMP_LT_D:
9839 case OPC_CMP_NGE_D:
9840 case OPC_CMP_LE_D:
9841 case OPC_CMP_NGT_D:
fecd2646 9842 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9843 if (ctx->opcode & (1 << 6)) {
9844 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9845 } else {
9846 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9847 }
6ea83fed 9848 break;
bf4120ad 9849 case OPC_CVT_S_D:
5e755519 9850 check_cp1_registers(ctx, fs);
b6d96bed 9851 {
a7812ae4
PB
9852 TCGv_i32 fp32 = tcg_temp_new_i32();
9853 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9854
9855 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9856 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9857 tcg_temp_free_i64(fp64);
7c979afd 9858 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9859 tcg_temp_free_i32(fp32);
b6d96bed 9860 }
5a5012ec 9861 break;
bf4120ad 9862 case OPC_CVT_W_D:
5e755519 9863 check_cp1_registers(ctx, fs);
b6d96bed 9864 {
a7812ae4
PB
9865 TCGv_i32 fp32 = tcg_temp_new_i32();
9866 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9867
9868 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9869 if (ctx->nan2008) {
9870 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9871 } else {
9872 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9873 }
a7812ae4 9874 tcg_temp_free_i64(fp64);
7c979afd 9875 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9876 tcg_temp_free_i32(fp32);
b6d96bed 9877 }
5a5012ec 9878 break;
bf4120ad 9879 case OPC_CVT_L_D:
5e755519 9880 check_cp1_64bitmode(ctx);
b6d96bed 9881 {
a7812ae4 9882 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9883
9884 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9885 if (ctx->nan2008) {
9886 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9887 } else {
9888 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9889 }
b6d96bed 9890 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9891 tcg_temp_free_i64(fp0);
b6d96bed 9892 }
5a5012ec 9893 break;
bf4120ad 9894 case OPC_CVT_S_W:
b6d96bed 9895 {
a7812ae4 9896 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9897
7c979afd 9898 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9899 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9900 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9901 tcg_temp_free_i32(fp0);
b6d96bed 9902 }
6ea83fed 9903 break;
bf4120ad 9904 case OPC_CVT_D_W:
5e755519 9905 check_cp1_registers(ctx, fd);
b6d96bed 9906 {
a7812ae4
PB
9907 TCGv_i32 fp32 = tcg_temp_new_i32();
9908 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9909
7c979afd 9910 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9911 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9912 tcg_temp_free_i32(fp32);
b6d96bed 9913 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9914 tcg_temp_free_i64(fp64);
b6d96bed 9915 }
5a5012ec 9916 break;
bf4120ad 9917 case OPC_CVT_S_L:
5e755519 9918 check_cp1_64bitmode(ctx);
b6d96bed 9919 {
a7812ae4
PB
9920 TCGv_i32 fp32 = tcg_temp_new_i32();
9921 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9922
9923 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9924 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9925 tcg_temp_free_i64(fp64);
7c979afd 9926 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9927 tcg_temp_free_i32(fp32);
b6d96bed 9928 }
5a5012ec 9929 break;
bf4120ad 9930 case OPC_CVT_D_L:
5e755519 9931 check_cp1_64bitmode(ctx);
b6d96bed 9932 {
a7812ae4 9933 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9934
9935 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9936 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9937 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9938 tcg_temp_free_i64(fp0);
b6d96bed 9939 }
5a5012ec 9940 break;
bf4120ad 9941 case OPC_CVT_PS_PW:
e29c9628 9942 check_ps(ctx);
b6d96bed 9943 {
a7812ae4 9944 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9945
9946 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9947 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9948 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9949 tcg_temp_free_i64(fp0);
b6d96bed 9950 }
5a5012ec 9951 break;
bf4120ad 9952 case OPC_ADD_PS:
e29c9628 9953 check_ps(ctx);
b6d96bed 9954 {
a7812ae4
PB
9955 TCGv_i64 fp0 = tcg_temp_new_i64();
9956 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9957
9958 gen_load_fpr64(ctx, fp0, fs);
9959 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9960 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9961 tcg_temp_free_i64(fp1);
b6d96bed 9962 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9963 tcg_temp_free_i64(fp0);
b6d96bed 9964 }
6ea83fed 9965 break;
bf4120ad 9966 case OPC_SUB_PS:
e29c9628 9967 check_ps(ctx);
b6d96bed 9968 {
a7812ae4
PB
9969 TCGv_i64 fp0 = tcg_temp_new_i64();
9970 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9971
9972 gen_load_fpr64(ctx, fp0, fs);
9973 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9974 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9975 tcg_temp_free_i64(fp1);
b6d96bed 9976 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9977 tcg_temp_free_i64(fp0);
b6d96bed 9978 }
6ea83fed 9979 break;
bf4120ad 9980 case OPC_MUL_PS:
e29c9628 9981 check_ps(ctx);
b6d96bed 9982 {
a7812ae4
PB
9983 TCGv_i64 fp0 = tcg_temp_new_i64();
9984 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9985
9986 gen_load_fpr64(ctx, fp0, fs);
9987 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9988 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9989 tcg_temp_free_i64(fp1);
b6d96bed 9990 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9991 tcg_temp_free_i64(fp0);
b6d96bed 9992 }
6ea83fed 9993 break;
bf4120ad 9994 case OPC_ABS_PS:
e29c9628 9995 check_ps(ctx);
b6d96bed 9996 {
a7812ae4 9997 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9998
9999 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10000 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10001 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10002 tcg_temp_free_i64(fp0);
b6d96bed 10003 }
6ea83fed 10004 break;
bf4120ad 10005 case OPC_MOV_PS:
e29c9628 10006 check_ps(ctx);
b6d96bed 10007 {
a7812ae4 10008 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10009
10010 gen_load_fpr64(ctx, fp0, fs);
10011 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10012 tcg_temp_free_i64(fp0);
b6d96bed 10013 }
6ea83fed 10014 break;
bf4120ad 10015 case OPC_NEG_PS:
e29c9628 10016 check_ps(ctx);
b6d96bed 10017 {
a7812ae4 10018 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10019
10020 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10021 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10022 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10023 tcg_temp_free_i64(fp0);
b6d96bed 10024 }
6ea83fed 10025 break;
bf4120ad 10026 case OPC_MOVCF_PS:
e29c9628 10027 check_ps(ctx);
7f6613ce 10028 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10029 break;
bf4120ad 10030 case OPC_MOVZ_PS:
e29c9628 10031 check_ps(ctx);
a16336e4 10032 {
42a268c2 10033 TCGLabel *l1 = gen_new_label();
30a3848b 10034 TCGv_i64 fp0;
a16336e4 10035
c9297f4d
AJ
10036 if (ft != 0)
10037 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10038 fp0 = tcg_temp_new_i64();
10039 gen_load_fpr64(ctx, fp0, fs);
10040 gen_store_fpr64(ctx, fp0, fd);
10041 tcg_temp_free_i64(fp0);
a16336e4
TS
10042 gen_set_label(l1);
10043 }
6ea83fed 10044 break;
bf4120ad 10045 case OPC_MOVN_PS:
e29c9628 10046 check_ps(ctx);
a16336e4 10047 {
42a268c2 10048 TCGLabel *l1 = gen_new_label();
30a3848b 10049 TCGv_i64 fp0;
c9297f4d
AJ
10050
10051 if (ft != 0) {
10052 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10053 fp0 = tcg_temp_new_i64();
10054 gen_load_fpr64(ctx, fp0, fs);
10055 gen_store_fpr64(ctx, fp0, fd);
10056 tcg_temp_free_i64(fp0);
10057 gen_set_label(l1);
10058 }
a16336e4 10059 }
6ea83fed 10060 break;
bf4120ad 10061 case OPC_ADDR_PS:
e29c9628 10062 check_ps(ctx);
b6d96bed 10063 {
a7812ae4
PB
10064 TCGv_i64 fp0 = tcg_temp_new_i64();
10065 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10066
10067 gen_load_fpr64(ctx, fp0, ft);
10068 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10069 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10070 tcg_temp_free_i64(fp1);
b6d96bed 10071 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10072 tcg_temp_free_i64(fp0);
b6d96bed 10073 }
fbcc6828 10074 break;
bf4120ad 10075 case OPC_MULR_PS:
e29c9628 10076 check_ps(ctx);
b6d96bed 10077 {
a7812ae4
PB
10078 TCGv_i64 fp0 = tcg_temp_new_i64();
10079 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10080
10081 gen_load_fpr64(ctx, fp0, ft);
10082 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10083 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10084 tcg_temp_free_i64(fp1);
b6d96bed 10085 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10086 tcg_temp_free_i64(fp0);
b6d96bed 10087 }
57fa1fb3 10088 break;
bf4120ad 10089 case OPC_RECIP2_PS:
e29c9628 10090 check_ps(ctx);
b6d96bed 10091 {
a7812ae4
PB
10092 TCGv_i64 fp0 = tcg_temp_new_i64();
10093 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10094
10095 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10096 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10097 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10098 tcg_temp_free_i64(fp1);
b6d96bed 10099 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10100 tcg_temp_free_i64(fp0);
b6d96bed 10101 }
57fa1fb3 10102 break;
bf4120ad 10103 case OPC_RECIP1_PS:
e29c9628 10104 check_ps(ctx);
b6d96bed 10105 {
a7812ae4 10106 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10107
10108 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10109 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10110 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10111 tcg_temp_free_i64(fp0);
b6d96bed 10112 }
57fa1fb3 10113 break;
bf4120ad 10114 case OPC_RSQRT1_PS:
e29c9628 10115 check_ps(ctx);
b6d96bed 10116 {
a7812ae4 10117 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10118
10119 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10120 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10121 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10122 tcg_temp_free_i64(fp0);
b6d96bed 10123 }
57fa1fb3 10124 break;
bf4120ad 10125 case OPC_RSQRT2_PS:
e29c9628 10126 check_ps(ctx);
b6d96bed 10127 {
a7812ae4
PB
10128 TCGv_i64 fp0 = tcg_temp_new_i64();
10129 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10130
10131 gen_load_fpr64(ctx, fp0, fs);
10132 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10133 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10134 tcg_temp_free_i64(fp1);
b6d96bed 10135 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10136 tcg_temp_free_i64(fp0);
b6d96bed 10137 }
57fa1fb3 10138 break;
bf4120ad 10139 case OPC_CVT_S_PU:
5e755519 10140 check_cp1_64bitmode(ctx);
b6d96bed 10141 {
a7812ae4 10142 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10143
7f6613ce 10144 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10145 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10146 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10147 tcg_temp_free_i32(fp0);
b6d96bed 10148 }
dd016883 10149 break;
bf4120ad 10150 case OPC_CVT_PW_PS:
e29c9628 10151 check_ps(ctx);
b6d96bed 10152 {
a7812ae4 10153 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10154
10155 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10156 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10157 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10158 tcg_temp_free_i64(fp0);
b6d96bed 10159 }
6ea83fed 10160 break;
bf4120ad 10161 case OPC_CVT_S_PL:
5e755519 10162 check_cp1_64bitmode(ctx);
b6d96bed 10163 {
a7812ae4 10164 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10165
7c979afd 10166 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10167 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10168 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10169 tcg_temp_free_i32(fp0);
b6d96bed 10170 }
6ea83fed 10171 break;
bf4120ad 10172 case OPC_PLL_PS:
e29c9628 10173 check_ps(ctx);
b6d96bed 10174 {
a7812ae4
PB
10175 TCGv_i32 fp0 = tcg_temp_new_i32();
10176 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10177
7c979afd
LA
10178 gen_load_fpr32(ctx, fp0, fs);
10179 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10180 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10181 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10182 tcg_temp_free_i32(fp0);
10183 tcg_temp_free_i32(fp1);
b6d96bed 10184 }
6ea83fed 10185 break;
bf4120ad 10186 case OPC_PLU_PS:
e29c9628 10187 check_ps(ctx);
b6d96bed 10188 {
a7812ae4
PB
10189 TCGv_i32 fp0 = tcg_temp_new_i32();
10190 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10191
7c979afd 10192 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10193 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10194 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10195 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10196 tcg_temp_free_i32(fp0);
10197 tcg_temp_free_i32(fp1);
b6d96bed 10198 }
5a5012ec 10199 break;
bf4120ad 10200 case OPC_PUL_PS:
e29c9628 10201 check_ps(ctx);
b6d96bed 10202 {
a7812ae4
PB
10203 TCGv_i32 fp0 = tcg_temp_new_i32();
10204 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10205
7f6613ce 10206 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10207 gen_load_fpr32(ctx, fp1, ft);
10208 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10209 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10210 tcg_temp_free_i32(fp0);
10211 tcg_temp_free_i32(fp1);
b6d96bed 10212 }
5a5012ec 10213 break;
bf4120ad 10214 case OPC_PUU_PS:
e29c9628 10215 check_ps(ctx);
b6d96bed 10216 {
a7812ae4
PB
10217 TCGv_i32 fp0 = tcg_temp_new_i32();
10218 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10219
7f6613ce
PJ
10220 gen_load_fpr32h(ctx, fp0, fs);
10221 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10222 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10223 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10224 tcg_temp_free_i32(fp0);
10225 tcg_temp_free_i32(fp1);
b6d96bed 10226 }
5a5012ec 10227 break;
bf4120ad
NF
10228 case OPC_CMP_F_PS:
10229 case OPC_CMP_UN_PS:
10230 case OPC_CMP_EQ_PS:
10231 case OPC_CMP_UEQ_PS:
10232 case OPC_CMP_OLT_PS:
10233 case OPC_CMP_ULT_PS:
10234 case OPC_CMP_OLE_PS:
10235 case OPC_CMP_ULE_PS:
10236 case OPC_CMP_SF_PS:
10237 case OPC_CMP_NGLE_PS:
10238 case OPC_CMP_SEQ_PS:
10239 case OPC_CMP_NGL_PS:
10240 case OPC_CMP_LT_PS:
10241 case OPC_CMP_NGE_PS:
10242 case OPC_CMP_LE_PS:
10243 case OPC_CMP_NGT_PS:
8153667c
NF
10244 if (ctx->opcode & (1 << 6)) {
10245 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10246 } else {
10247 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10248 }
6ea83fed 10249 break;
5a5012ec 10250 default:
9d68ac14 10251 MIPS_INVAL("farith");
9c708c7f 10252 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10253 return;
10254 }
6ea83fed 10255}
6af0bf9c 10256
5a5012ec 10257/* Coprocessor 3 (FPU) */
5e755519
TS
10258static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10259 int fd, int fs, int base, int index)
7a387fff 10260{
4e2474d6 10261 TCGv t0 = tcg_temp_new();
7a387fff 10262
93b12ccc 10263 if (base == 0) {
6c5c1e20 10264 gen_load_gpr(t0, index);
93b12ccc 10265 } else if (index == 0) {
6c5c1e20 10266 gen_load_gpr(t0, base);
93b12ccc 10267 } else {
05168674 10268 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10269 }
5a5012ec 10270 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10271 memory access. */
5a5012ec
TS
10272 switch (opc) {
10273 case OPC_LWXC1:
8c0ab41f 10274 check_cop1x(ctx);
b6d96bed 10275 {
a7812ae4 10276 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10277
5f68f5ae 10278 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10279 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10280 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10281 tcg_temp_free_i32(fp0);
b6d96bed 10282 }
5a5012ec
TS
10283 break;
10284 case OPC_LDXC1:
8c0ab41f
AJ
10285 check_cop1x(ctx);
10286 check_cp1_registers(ctx, fd);
b6d96bed 10287 {
a7812ae4 10288 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10289 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10290 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10291 tcg_temp_free_i64(fp0);
b6d96bed 10292 }
5a5012ec
TS
10293 break;
10294 case OPC_LUXC1:
8c0ab41f 10295 check_cp1_64bitmode(ctx);
6c5c1e20 10296 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10297 {
a7812ae4 10298 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10299
5f68f5ae 10300 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10301 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10302 tcg_temp_free_i64(fp0);
b6d96bed 10303 }
5a5012ec
TS
10304 break;
10305 case OPC_SWXC1:
8c0ab41f 10306 check_cop1x(ctx);
b6d96bed 10307 {
a7812ae4 10308 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10309 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10310 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10311 tcg_temp_free_i32(fp0);
b6d96bed 10312 }
5a5012ec
TS
10313 break;
10314 case OPC_SDXC1:
8c0ab41f
AJ
10315 check_cop1x(ctx);
10316 check_cp1_registers(ctx, fs);
b6d96bed 10317 {
a7812ae4 10318 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10319 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10320 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10321 tcg_temp_free_i64(fp0);
b6d96bed 10322 }
5a5012ec
TS
10323 break;
10324 case OPC_SUXC1:
8c0ab41f 10325 check_cp1_64bitmode(ctx);
6c5c1e20 10326 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10327 {
a7812ae4 10328 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10329 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10330 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10331 tcg_temp_free_i64(fp0);
b6d96bed 10332 }
5a5012ec 10333 break;
5a5012ec 10334 }
6c5c1e20 10335 tcg_temp_free(t0);
5a5012ec
TS
10336}
10337
5e755519
TS
10338static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10339 int fd, int fr, int fs, int ft)
5a5012ec 10340{
5a5012ec
TS
10341 switch (opc) {
10342 case OPC_ALNV_PS:
e29c9628 10343 check_ps(ctx);
a16336e4 10344 {
a7812ae4 10345 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10346 TCGv_i32 fp = tcg_temp_new_i32();
10347 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10348 TCGLabel *l1 = gen_new_label();
10349 TCGLabel *l2 = gen_new_label();
a16336e4 10350
6c5c1e20
TS
10351 gen_load_gpr(t0, fr);
10352 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10353
10354 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10355 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10356 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10357 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10358 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10359 tcg_gen_br(l2);
10360 gen_set_label(l1);
6c5c1e20
TS
10361 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10362 tcg_temp_free(t0);
a16336e4 10363#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10364 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10365 gen_load_fpr32h(ctx, fph, ft);
10366 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10367 gen_store_fpr32(ctx, fph, fd);
a16336e4 10368#else
7f6613ce 10369 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10370 gen_load_fpr32(ctx, fp, ft);
10371 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10372 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10373#endif
10374 gen_set_label(l2);
c905fdac
AJ
10375 tcg_temp_free_i32(fp);
10376 tcg_temp_free_i32(fph);
a16336e4 10377 }
5a5012ec
TS
10378 break;
10379 case OPC_MADD_S:
b8aa4598 10380 check_cop1x(ctx);
b6d96bed 10381 {
a7812ae4
PB
10382 TCGv_i32 fp0 = tcg_temp_new_i32();
10383 TCGv_i32 fp1 = tcg_temp_new_i32();
10384 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10385
7c979afd
LA
10386 gen_load_fpr32(ctx, fp0, fs);
10387 gen_load_fpr32(ctx, fp1, ft);
10388 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10389 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10390 tcg_temp_free_i32(fp0);
10391 tcg_temp_free_i32(fp1);
7c979afd 10392 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10393 tcg_temp_free_i32(fp2);
b6d96bed 10394 }
5a5012ec
TS
10395 break;
10396 case OPC_MADD_D:
b8aa4598
TS
10397 check_cop1x(ctx);
10398 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10399 {
a7812ae4
PB
10400 TCGv_i64 fp0 = tcg_temp_new_i64();
10401 TCGv_i64 fp1 = tcg_temp_new_i64();
10402 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10403
10404 gen_load_fpr64(ctx, fp0, fs);
10405 gen_load_fpr64(ctx, fp1, ft);
10406 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10407 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10408 tcg_temp_free_i64(fp0);
10409 tcg_temp_free_i64(fp1);
b6d96bed 10410 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10411 tcg_temp_free_i64(fp2);
b6d96bed 10412 }
5a5012ec
TS
10413 break;
10414 case OPC_MADD_PS:
e29c9628 10415 check_ps(ctx);
b6d96bed 10416 {
a7812ae4
PB
10417 TCGv_i64 fp0 = tcg_temp_new_i64();
10418 TCGv_i64 fp1 = tcg_temp_new_i64();
10419 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10420
10421 gen_load_fpr64(ctx, fp0, fs);
10422 gen_load_fpr64(ctx, fp1, ft);
10423 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10424 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10425 tcg_temp_free_i64(fp0);
10426 tcg_temp_free_i64(fp1);
b6d96bed 10427 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10428 tcg_temp_free_i64(fp2);
b6d96bed 10429 }
5a5012ec
TS
10430 break;
10431 case OPC_MSUB_S:
b8aa4598 10432 check_cop1x(ctx);
b6d96bed 10433 {
a7812ae4
PB
10434 TCGv_i32 fp0 = tcg_temp_new_i32();
10435 TCGv_i32 fp1 = tcg_temp_new_i32();
10436 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10437
7c979afd
LA
10438 gen_load_fpr32(ctx, fp0, fs);
10439 gen_load_fpr32(ctx, fp1, ft);
10440 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10441 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10442 tcg_temp_free_i32(fp0);
10443 tcg_temp_free_i32(fp1);
7c979afd 10444 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10445 tcg_temp_free_i32(fp2);
b6d96bed 10446 }
5a5012ec
TS
10447 break;
10448 case OPC_MSUB_D:
b8aa4598
TS
10449 check_cop1x(ctx);
10450 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10451 {
a7812ae4
PB
10452 TCGv_i64 fp0 = tcg_temp_new_i64();
10453 TCGv_i64 fp1 = tcg_temp_new_i64();
10454 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10455
10456 gen_load_fpr64(ctx, fp0, fs);
10457 gen_load_fpr64(ctx, fp1, ft);
10458 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10459 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10460 tcg_temp_free_i64(fp0);
10461 tcg_temp_free_i64(fp1);
b6d96bed 10462 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10463 tcg_temp_free_i64(fp2);
b6d96bed 10464 }
5a5012ec
TS
10465 break;
10466 case OPC_MSUB_PS:
e29c9628 10467 check_ps(ctx);
b6d96bed 10468 {
a7812ae4
PB
10469 TCGv_i64 fp0 = tcg_temp_new_i64();
10470 TCGv_i64 fp1 = tcg_temp_new_i64();
10471 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10472
10473 gen_load_fpr64(ctx, fp0, fs);
10474 gen_load_fpr64(ctx, fp1, ft);
10475 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10476 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10477 tcg_temp_free_i64(fp0);
10478 tcg_temp_free_i64(fp1);
b6d96bed 10479 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10480 tcg_temp_free_i64(fp2);
b6d96bed 10481 }
5a5012ec
TS
10482 break;
10483 case OPC_NMADD_S:
b8aa4598 10484 check_cop1x(ctx);
b6d96bed 10485 {
a7812ae4
PB
10486 TCGv_i32 fp0 = tcg_temp_new_i32();
10487 TCGv_i32 fp1 = tcg_temp_new_i32();
10488 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10489
7c979afd
LA
10490 gen_load_fpr32(ctx, fp0, fs);
10491 gen_load_fpr32(ctx, fp1, ft);
10492 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10493 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10494 tcg_temp_free_i32(fp0);
10495 tcg_temp_free_i32(fp1);
7c979afd 10496 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10497 tcg_temp_free_i32(fp2);
b6d96bed 10498 }
5a5012ec
TS
10499 break;
10500 case OPC_NMADD_D:
b8aa4598
TS
10501 check_cop1x(ctx);
10502 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10503 {
a7812ae4
PB
10504 TCGv_i64 fp0 = tcg_temp_new_i64();
10505 TCGv_i64 fp1 = tcg_temp_new_i64();
10506 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10507
10508 gen_load_fpr64(ctx, fp0, fs);
10509 gen_load_fpr64(ctx, fp1, ft);
10510 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10511 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10512 tcg_temp_free_i64(fp0);
10513 tcg_temp_free_i64(fp1);
b6d96bed 10514 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10515 tcg_temp_free_i64(fp2);
b6d96bed 10516 }
5a5012ec
TS
10517 break;
10518 case OPC_NMADD_PS:
e29c9628 10519 check_ps(ctx);
b6d96bed 10520 {
a7812ae4
PB
10521 TCGv_i64 fp0 = tcg_temp_new_i64();
10522 TCGv_i64 fp1 = tcg_temp_new_i64();
10523 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10524
10525 gen_load_fpr64(ctx, fp0, fs);
10526 gen_load_fpr64(ctx, fp1, ft);
10527 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10528 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10529 tcg_temp_free_i64(fp0);
10530 tcg_temp_free_i64(fp1);
b6d96bed 10531 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10532 tcg_temp_free_i64(fp2);
b6d96bed 10533 }
5a5012ec
TS
10534 break;
10535 case OPC_NMSUB_S:
b8aa4598 10536 check_cop1x(ctx);
b6d96bed 10537 {
a7812ae4
PB
10538 TCGv_i32 fp0 = tcg_temp_new_i32();
10539 TCGv_i32 fp1 = tcg_temp_new_i32();
10540 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10541
7c979afd
LA
10542 gen_load_fpr32(ctx, fp0, fs);
10543 gen_load_fpr32(ctx, fp1, ft);
10544 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10545 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10546 tcg_temp_free_i32(fp0);
10547 tcg_temp_free_i32(fp1);
7c979afd 10548 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10549 tcg_temp_free_i32(fp2);
b6d96bed 10550 }
5a5012ec
TS
10551 break;
10552 case OPC_NMSUB_D:
b8aa4598
TS
10553 check_cop1x(ctx);
10554 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10555 {
a7812ae4
PB
10556 TCGv_i64 fp0 = tcg_temp_new_i64();
10557 TCGv_i64 fp1 = tcg_temp_new_i64();
10558 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10559
10560 gen_load_fpr64(ctx, fp0, fs);
10561 gen_load_fpr64(ctx, fp1, ft);
10562 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10563 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10564 tcg_temp_free_i64(fp0);
10565 tcg_temp_free_i64(fp1);
b6d96bed 10566 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10567 tcg_temp_free_i64(fp2);
b6d96bed 10568 }
5a5012ec
TS
10569 break;
10570 case OPC_NMSUB_PS:
e29c9628 10571 check_ps(ctx);
b6d96bed 10572 {
a7812ae4
PB
10573 TCGv_i64 fp0 = tcg_temp_new_i64();
10574 TCGv_i64 fp1 = tcg_temp_new_i64();
10575 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10576
10577 gen_load_fpr64(ctx, fp0, fs);
10578 gen_load_fpr64(ctx, fp1, ft);
10579 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10580 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10581 tcg_temp_free_i64(fp0);
10582 tcg_temp_free_i64(fp1);
b6d96bed 10583 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10584 tcg_temp_free_i64(fp2);
b6d96bed 10585 }
5a5012ec 10586 break;
923617a3 10587 default:
9d68ac14 10588 MIPS_INVAL("flt3_arith");
9c708c7f 10589 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10590 return;
10591 }
7a387fff
TS
10592}
10593
b00c7218 10594static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10595{
10596 TCGv t0;
10597
b3167288
RH
10598#if !defined(CONFIG_USER_ONLY)
10599 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10600 Therefore only check the ISA in system mode. */
d75c135e 10601 check_insn(ctx, ISA_MIPS32R2);
b3167288 10602#endif
26ebe468
NF
10603 t0 = tcg_temp_new();
10604
10605 switch (rd) {
10606 case 0:
895c2d04 10607 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10608 gen_store_gpr(t0, rt);
10609 break;
10610 case 1:
895c2d04 10611 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10612 gen_store_gpr(t0, rt);
10613 break;
10614 case 2:
895c2d04 10615 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10616 gen_store_gpr(t0, rt);
10617 break;
10618 case 3:
895c2d04 10619 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10620 gen_store_gpr(t0, rt);
10621 break;
b00c7218
YK
10622 case 4:
10623 check_insn(ctx, ISA_MIPS32R6);
10624 if (sel != 0) {
10625 /* Performance counter registers are not implemented other than
10626 * control register 0.
10627 */
10628 generate_exception(ctx, EXCP_RI);
10629 }
10630 gen_helper_rdhwr_performance(t0, cpu_env);
10631 gen_store_gpr(t0, rt);
10632 break;
10633 case 5:
10634 check_insn(ctx, ISA_MIPS32R6);
10635 gen_helper_rdhwr_xnp(t0, cpu_env);
10636 gen_store_gpr(t0, rt);
10637 break;
26ebe468
NF
10638 case 29:
10639#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10640 tcg_gen_ld_tl(t0, cpu_env,
10641 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10642 gen_store_gpr(t0, rt);
10643 break;
10644#else
d279279e
PJ
10645 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10646 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10647 tcg_gen_ld_tl(t0, cpu_env,
10648 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10649 gen_store_gpr(t0, rt);
10650 } else {
9c708c7f 10651 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10652 }
10653 break;
26ebe468
NF
10654#endif
10655 default: /* Invalid */
10656 MIPS_INVAL("rdhwr");
9c708c7f 10657 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10658 break;
10659 }
10660 tcg_temp_free(t0);
10661}
10662
a5f53390
LA
10663static inline void clear_branch_hflags(DisasContext *ctx)
10664{
10665 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10666 if (ctx->bstate == BS_NONE) {
10667 save_cpu_state(ctx, 0);
10668 } else {
10669 /* it is not safe to save ctx->hflags as hflags may be changed
10670 in execution time by the instruction in delay / forbidden slot. */
10671 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10672 }
10673}
10674
31837be3 10675static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10676{
10677 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10678 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10679 /* Branches completion */
a5f53390 10680 clear_branch_hflags(ctx);
c9602061 10681 ctx->bstate = BS_BRANCH;
c9602061 10682 /* FIXME: Need to clear can_do_io. */
364d4831 10683 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10684 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10685 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10686 break;
c9602061
NF
10687 case MIPS_HFLAG_B:
10688 /* unconditional branch */
364d4831
NF
10689 if (proc_hflags & MIPS_HFLAG_BX) {
10690 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10691 }
c9602061
NF
10692 gen_goto_tb(ctx, 0, ctx->btarget);
10693 break;
10694 case MIPS_HFLAG_BL:
10695 /* blikely taken case */
c9602061
NF
10696 gen_goto_tb(ctx, 0, ctx->btarget);
10697 break;
10698 case MIPS_HFLAG_BC:
10699 /* Conditional branch */
c9602061 10700 {
42a268c2 10701 TCGLabel *l1 = gen_new_label();
c9602061
NF
10702
10703 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10704 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10705 gen_set_label(l1);
10706 gen_goto_tb(ctx, 0, ctx->btarget);
10707 }
10708 break;
10709 case MIPS_HFLAG_BR:
10710 /* unconditional branch to register */
d75c135e 10711 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10712 TCGv t0 = tcg_temp_new();
10713 TCGv_i32 t1 = tcg_temp_new_i32();
10714
10715 tcg_gen_andi_tl(t0, btarget, 0x1);
10716 tcg_gen_trunc_tl_i32(t1, t0);
10717 tcg_temp_free(t0);
10718 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10719 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10720 tcg_gen_or_i32(hflags, hflags, t1);
10721 tcg_temp_free_i32(t1);
10722
10723 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10724 } else {
10725 tcg_gen_mov_tl(cpu_PC, btarget);
10726 }
c9602061
NF
10727 if (ctx->singlestep_enabled) {
10728 save_cpu_state(ctx, 0);
9c708c7f 10729 gen_helper_raise_exception_debug(cpu_env);
c9602061
NF
10730 }
10731 tcg_gen_exit_tb(0);
10732 break;
10733 default:
a5f53390
LA
10734 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10735 abort();
c9602061
NF
10736 }
10737 }
10738}
10739
6893f074
YK
10740/* Compact Branches */
10741static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10742 int rs, int rt, int32_t offset)
10743{
10744 int bcond_compute = 0;
10745 TCGv t0 = tcg_temp_new();
10746 TCGv t1 = tcg_temp_new();
65935f07 10747 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10748
10749 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10750#ifdef MIPS_DEBUG_DISAS
10751 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10752 "\n", ctx->pc);
10753#endif
9c708c7f 10754 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10755 goto out;
10756 }
10757
10758 /* Load needed operands and calculate btarget */
10759 switch (opc) {
10760 /* compact branch */
10761 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10762 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10763 gen_load_gpr(t0, rs);
10764 gen_load_gpr(t1, rt);
10765 bcond_compute = 1;
10766 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10767 if (rs <= rt && rs == 0) {
10768 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10769 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10770 }
10771 break;
10772 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10773 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10774 gen_load_gpr(t0, rs);
10775 gen_load_gpr(t1, rt);
10776 bcond_compute = 1;
10777 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10778 break;
10779 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10780 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10781 if (rs == 0 || rs == rt) {
10782 /* OPC_BLEZALC, OPC_BGEZALC */
10783 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10784 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10785 }
10786 gen_load_gpr(t0, rs);
10787 gen_load_gpr(t1, rt);
10788 bcond_compute = 1;
10789 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10790 break;
10791 case OPC_BC:
10792 case OPC_BALC:
10793 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10794 break;
10795 case OPC_BEQZC:
10796 case OPC_BNEZC:
10797 if (rs != 0) {
10798 /* OPC_BEQZC, OPC_BNEZC */
10799 gen_load_gpr(t0, rs);
10800 bcond_compute = 1;
10801 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10802 } else {
10803 /* OPC_JIC, OPC_JIALC */
10804 TCGv tbase = tcg_temp_new();
10805 TCGv toffset = tcg_temp_new();
10806
10807 gen_load_gpr(tbase, rt);
10808 tcg_gen_movi_tl(toffset, offset);
10809 gen_op_addr_add(ctx, btarget, tbase, toffset);
10810 tcg_temp_free(tbase);
10811 tcg_temp_free(toffset);
10812 }
10813 break;
10814 default:
10815 MIPS_INVAL("Compact branch/jump");
9c708c7f 10816 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10817 goto out;
10818 }
10819
10820 if (bcond_compute == 0) {
10821 /* Uncoditional compact branch */
10822 switch (opc) {
10823 case OPC_JIALC:
65935f07 10824 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10825 /* Fallthrough */
10826 case OPC_JIC:
10827 ctx->hflags |= MIPS_HFLAG_BR;
10828 break;
10829 case OPC_BALC:
65935f07 10830 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10831 /* Fallthrough */
10832 case OPC_BC:
10833 ctx->hflags |= MIPS_HFLAG_B;
10834 break;
10835 default:
10836 MIPS_INVAL("Compact branch/jump");
9c708c7f 10837 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10838 goto out;
10839 }
10840
10841 /* Generating branch here as compact branches don't have delay slot */
10842 gen_branch(ctx, 4);
10843 } else {
10844 /* Conditional compact branch */
10845 TCGLabel *fs = gen_new_label();
10846 save_cpu_state(ctx, 0);
10847
10848 switch (opc) {
10849 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10850 if (rs == 0 && rt != 0) {
10851 /* OPC_BLEZALC */
10852 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10853 } else if (rs != 0 && rt != 0 && rs == rt) {
10854 /* OPC_BGEZALC */
10855 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10856 } else {
10857 /* OPC_BGEUC */
10858 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10859 }
10860 break;
10861 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10862 if (rs == 0 && rt != 0) {
10863 /* OPC_BGTZALC */
10864 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10865 } else if (rs != 0 && rt != 0 && rs == rt) {
10866 /* OPC_BLTZALC */
10867 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10868 } else {
10869 /* OPC_BLTUC */
10870 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10871 }
10872 break;
10873 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10874 if (rs == 0 && rt != 0) {
10875 /* OPC_BLEZC */
10876 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10877 } else if (rs != 0 && rt != 0 && rs == rt) {
10878 /* OPC_BGEZC */
10879 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10880 } else {
10881 /* OPC_BGEC */
10882 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10883 }
10884 break;
10885 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10886 if (rs == 0 && rt != 0) {
10887 /* OPC_BGTZC */
10888 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10889 } else if (rs != 0 && rt != 0 && rs == rt) {
10890 /* OPC_BLTZC */
10891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10892 } else {
10893 /* OPC_BLTC */
10894 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10895 }
10896 break;
10897 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10898 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10899 if (rs >= rt) {
10900 /* OPC_BOVC, OPC_BNVC */
10901 TCGv t2 = tcg_temp_new();
10902 TCGv t3 = tcg_temp_new();
10903 TCGv t4 = tcg_temp_new();
10904 TCGv input_overflow = tcg_temp_new();
10905
10906 gen_load_gpr(t0, rs);
10907 gen_load_gpr(t1, rt);
10908 tcg_gen_ext32s_tl(t2, t0);
10909 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10910 tcg_gen_ext32s_tl(t3, t1);
10911 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10912 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10913
10914 tcg_gen_add_tl(t4, t2, t3);
10915 tcg_gen_ext32s_tl(t4, t4);
10916 tcg_gen_xor_tl(t2, t2, t3);
10917 tcg_gen_xor_tl(t3, t4, t3);
10918 tcg_gen_andc_tl(t2, t3, t2);
10919 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10920 tcg_gen_or_tl(t4, t4, input_overflow);
10921 if (opc == OPC_BOVC) {
10922 /* OPC_BOVC */
10923 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10924 } else {
10925 /* OPC_BNVC */
10926 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10927 }
10928 tcg_temp_free(input_overflow);
10929 tcg_temp_free(t4);
10930 tcg_temp_free(t3);
10931 tcg_temp_free(t2);
10932 } else if (rs < rt && rs == 0) {
10933 /* OPC_BEQZALC, OPC_BNEZALC */
10934 if (opc == OPC_BEQZALC) {
10935 /* OPC_BEQZALC */
10936 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10937 } else {
10938 /* OPC_BNEZALC */
10939 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10940 }
10941 } else {
10942 /* OPC_BEQC, OPC_BNEC */
10943 if (opc == OPC_BEQC) {
10944 /* OPC_BEQC */
10945 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10946 } else {
10947 /* OPC_BNEC */
10948 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10949 }
10950 }
10951 break;
10952 case OPC_BEQZC:
10953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10954 break;
10955 case OPC_BNEZC:
10956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10957 break;
10958 default:
10959 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 10960 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10961 goto out;
10962 }
10963
10964 /* Generating branch here as compact branches don't have delay slot */
10965 gen_goto_tb(ctx, 1, ctx->btarget);
10966 gen_set_label(fs);
10967
10968 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10969 }
10970
10971out:
10972 tcg_temp_free(t0);
10973 tcg_temp_free(t1);
10974}
10975
7a387fff 10976/* ISA extensions (ASEs) */
6af0bf9c 10977/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10978
10979/* MIPS16 major opcodes */
10980enum {
10981 M16_OPC_ADDIUSP = 0x00,
10982 M16_OPC_ADDIUPC = 0x01,
10983 M16_OPC_B = 0x02,
10984 M16_OPC_JAL = 0x03,
10985 M16_OPC_BEQZ = 0x04,
10986 M16_OPC_BNEQZ = 0x05,
10987 M16_OPC_SHIFT = 0x06,
10988 M16_OPC_LD = 0x07,
10989 M16_OPC_RRIA = 0x08,
10990 M16_OPC_ADDIU8 = 0x09,
10991 M16_OPC_SLTI = 0x0a,
10992 M16_OPC_SLTIU = 0x0b,
10993 M16_OPC_I8 = 0x0c,
10994 M16_OPC_LI = 0x0d,
10995 M16_OPC_CMPI = 0x0e,
10996 M16_OPC_SD = 0x0f,
10997 M16_OPC_LB = 0x10,
10998 M16_OPC_LH = 0x11,
10999 M16_OPC_LWSP = 0x12,
11000 M16_OPC_LW = 0x13,
11001 M16_OPC_LBU = 0x14,
11002 M16_OPC_LHU = 0x15,
11003 M16_OPC_LWPC = 0x16,
11004 M16_OPC_LWU = 0x17,
11005 M16_OPC_SB = 0x18,
11006 M16_OPC_SH = 0x19,
11007 M16_OPC_SWSP = 0x1a,
11008 M16_OPC_SW = 0x1b,
11009 M16_OPC_RRR = 0x1c,
11010 M16_OPC_RR = 0x1d,
11011 M16_OPC_EXTEND = 0x1e,
11012 M16_OPC_I64 = 0x1f
11013};
11014
11015/* I8 funct field */
11016enum {
11017 I8_BTEQZ = 0x0,
11018 I8_BTNEZ = 0x1,
11019 I8_SWRASP = 0x2,
11020 I8_ADJSP = 0x3,
11021 I8_SVRS = 0x4,
11022 I8_MOV32R = 0x5,
11023 I8_MOVR32 = 0x7
11024};
11025
11026/* RRR f field */
11027enum {
11028 RRR_DADDU = 0x0,
11029 RRR_ADDU = 0x1,
11030 RRR_DSUBU = 0x2,
11031 RRR_SUBU = 0x3
11032};
11033
11034/* RR funct field */
11035enum {
11036 RR_JR = 0x00,
11037 RR_SDBBP = 0x01,
11038 RR_SLT = 0x02,
11039 RR_SLTU = 0x03,
11040 RR_SLLV = 0x04,
11041 RR_BREAK = 0x05,
11042 RR_SRLV = 0x06,
11043 RR_SRAV = 0x07,
11044 RR_DSRL = 0x08,
11045 RR_CMP = 0x0a,
11046 RR_NEG = 0x0b,
11047 RR_AND = 0x0c,
11048 RR_OR = 0x0d,
11049 RR_XOR = 0x0e,
11050 RR_NOT = 0x0f,
11051 RR_MFHI = 0x10,
11052 RR_CNVT = 0x11,
11053 RR_MFLO = 0x12,
11054 RR_DSRA = 0x13,
11055 RR_DSLLV = 0x14,
11056 RR_DSRLV = 0x16,
11057 RR_DSRAV = 0x17,
11058 RR_MULT = 0x18,
11059 RR_MULTU = 0x19,
11060 RR_DIV = 0x1a,
11061 RR_DIVU = 0x1b,
11062 RR_DMULT = 0x1c,
11063 RR_DMULTU = 0x1d,
11064 RR_DDIV = 0x1e,
11065 RR_DDIVU = 0x1f
11066};
11067
11068/* I64 funct field */
11069enum {
11070 I64_LDSP = 0x0,
11071 I64_SDSP = 0x1,
11072 I64_SDRASP = 0x2,
11073 I64_DADJSP = 0x3,
11074 I64_LDPC = 0x4,
364d4831 11075 I64_DADDIU5 = 0x5,
6ea219d0
NF
11076 I64_DADDIUPC = 0x6,
11077 I64_DADDIUSP = 0x7
11078};
11079
11080/* RR ry field for CNVT */
11081enum {
11082 RR_RY_CNVT_ZEB = 0x0,
11083 RR_RY_CNVT_ZEH = 0x1,
11084 RR_RY_CNVT_ZEW = 0x2,
11085 RR_RY_CNVT_SEB = 0x4,
11086 RR_RY_CNVT_SEH = 0x5,
11087 RR_RY_CNVT_SEW = 0x6,
11088};
11089
364d4831
NF
11090static int xlat (int r)
11091{
11092 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11093
11094 return map[r];
11095}
11096
11097static void gen_mips16_save (DisasContext *ctx,
11098 int xsregs, int aregs,
11099 int do_ra, int do_s0, int do_s1,
11100 int framesize)
11101{
11102 TCGv t0 = tcg_temp_new();
11103 TCGv t1 = tcg_temp_new();
c48245f0 11104 TCGv t2 = tcg_temp_new();
364d4831
NF
11105 int args, astatic;
11106
11107 switch (aregs) {
11108 case 0:
11109 case 1:
11110 case 2:
11111 case 3:
11112 case 11:
11113 args = 0;
11114 break;
11115 case 4:
11116 case 5:
11117 case 6:
11118 case 7:
11119 args = 1;
11120 break;
11121 case 8:
11122 case 9:
11123 case 10:
11124 args = 2;
11125 break;
11126 case 12:
11127 case 13:
11128 args = 3;
11129 break;
11130 case 14:
11131 args = 4;
11132 break;
11133 default:
9c708c7f 11134 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11135 return;
11136 }
11137
11138 switch (args) {
11139 case 4:
11140 gen_base_offset_addr(ctx, t0, 29, 12);
11141 gen_load_gpr(t1, 7);
5f68f5ae 11142 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11143 /* Fall through */
11144 case 3:
11145 gen_base_offset_addr(ctx, t0, 29, 8);
11146 gen_load_gpr(t1, 6);
5f68f5ae 11147 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11148 /* Fall through */
11149 case 2:
11150 gen_base_offset_addr(ctx, t0, 29, 4);
11151 gen_load_gpr(t1, 5);
5f68f5ae 11152 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11153 /* Fall through */
11154 case 1:
11155 gen_base_offset_addr(ctx, t0, 29, 0);
11156 gen_load_gpr(t1, 4);
5f68f5ae 11157 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11158 }
11159
11160 gen_load_gpr(t0, 29);
11161
5f68f5ae 11162#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11163 tcg_gen_movi_tl(t2, -4); \
11164 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11165 gen_load_gpr(t1, reg); \
11166 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11167 } while (0)
11168
11169 if (do_ra) {
11170 DECR_AND_STORE(31);
11171 }
11172
11173 switch (xsregs) {
11174 case 7:
11175 DECR_AND_STORE(30);
11176 /* Fall through */
11177 case 6:
11178 DECR_AND_STORE(23);
11179 /* Fall through */
11180 case 5:
11181 DECR_AND_STORE(22);
11182 /* Fall through */
11183 case 4:
11184 DECR_AND_STORE(21);
11185 /* Fall through */
11186 case 3:
11187 DECR_AND_STORE(20);
11188 /* Fall through */
11189 case 2:
11190 DECR_AND_STORE(19);
11191 /* Fall through */
11192 case 1:
11193 DECR_AND_STORE(18);
11194 }
11195
11196 if (do_s1) {
11197 DECR_AND_STORE(17);
11198 }
11199 if (do_s0) {
11200 DECR_AND_STORE(16);
11201 }
11202
11203 switch (aregs) {
11204 case 0:
11205 case 4:
11206 case 8:
11207 case 12:
11208 case 14:
11209 astatic = 0;
11210 break;
11211 case 1:
11212 case 5:
11213 case 9:
11214 case 13:
11215 astatic = 1;
11216 break;
11217 case 2:
11218 case 6:
11219 case 10:
11220 astatic = 2;
11221 break;
11222 case 3:
11223 case 7:
11224 astatic = 3;
11225 break;
11226 case 11:
11227 astatic = 4;
11228 break;
11229 default:
9c708c7f 11230 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11231 return;
11232 }
11233
11234 if (astatic > 0) {
11235 DECR_AND_STORE(7);
11236 if (astatic > 1) {
11237 DECR_AND_STORE(6);
11238 if (astatic > 2) {
11239 DECR_AND_STORE(5);
11240 if (astatic > 3) {
11241 DECR_AND_STORE(4);
11242 }
11243 }
11244 }
11245 }
11246#undef DECR_AND_STORE
11247
c48245f0
MR
11248 tcg_gen_movi_tl(t2, -framesize);
11249 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11250 tcg_temp_free(t0);
11251 tcg_temp_free(t1);
c48245f0 11252 tcg_temp_free(t2);
364d4831
NF
11253}
11254
11255static void gen_mips16_restore (DisasContext *ctx,
11256 int xsregs, int aregs,
11257 int do_ra, int do_s0, int do_s1,
11258 int framesize)
11259{
11260 int astatic;
11261 TCGv t0 = tcg_temp_new();
11262 TCGv t1 = tcg_temp_new();
c48245f0 11263 TCGv t2 = tcg_temp_new();
364d4831 11264
c48245f0
MR
11265 tcg_gen_movi_tl(t2, framesize);
11266 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11267
5f68f5ae 11268#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11269 tcg_gen_movi_tl(t2, -4); \
11270 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11271 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11272 gen_store_gpr(t1, reg); \
364d4831
NF
11273 } while (0)
11274
11275 if (do_ra) {
11276 DECR_AND_LOAD(31);
11277 }
11278
11279 switch (xsregs) {
11280 case 7:
11281 DECR_AND_LOAD(30);
11282 /* Fall through */
11283 case 6:
11284 DECR_AND_LOAD(23);
11285 /* Fall through */
11286 case 5:
11287 DECR_AND_LOAD(22);
11288 /* Fall through */
11289 case 4:
11290 DECR_AND_LOAD(21);
11291 /* Fall through */
11292 case 3:
11293 DECR_AND_LOAD(20);
11294 /* Fall through */
11295 case 2:
11296 DECR_AND_LOAD(19);
11297 /* Fall through */
11298 case 1:
11299 DECR_AND_LOAD(18);
11300 }
11301
11302 if (do_s1) {
11303 DECR_AND_LOAD(17);
11304 }
11305 if (do_s0) {
11306 DECR_AND_LOAD(16);
11307 }
11308
11309 switch (aregs) {
11310 case 0:
11311 case 4:
11312 case 8:
11313 case 12:
11314 case 14:
11315 astatic = 0;
11316 break;
11317 case 1:
11318 case 5:
11319 case 9:
11320 case 13:
11321 astatic = 1;
11322 break;
11323 case 2:
11324 case 6:
11325 case 10:
11326 astatic = 2;
11327 break;
11328 case 3:
11329 case 7:
11330 astatic = 3;
11331 break;
11332 case 11:
11333 astatic = 4;
11334 break;
11335 default:
9c708c7f 11336 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11337 return;
11338 }
11339
11340 if (astatic > 0) {
11341 DECR_AND_LOAD(7);
11342 if (astatic > 1) {
11343 DECR_AND_LOAD(6);
11344 if (astatic > 2) {
11345 DECR_AND_LOAD(5);
11346 if (astatic > 3) {
11347 DECR_AND_LOAD(4);
11348 }
11349 }
11350 }
11351 }
11352#undef DECR_AND_LOAD
11353
c48245f0
MR
11354 tcg_gen_movi_tl(t2, framesize);
11355 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11356 tcg_temp_free(t0);
11357 tcg_temp_free(t1);
c48245f0 11358 tcg_temp_free(t2);
364d4831
NF
11359}
11360
11361static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11362 int is_64_bit, int extended)
11363{
11364 TCGv t0;
11365
11366 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11367 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11368 return;
11369 }
11370
11371 t0 = tcg_temp_new();
11372
11373 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11374 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11375 if (!is_64_bit) {
11376 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11377 }
11378
11379 tcg_temp_free(t0);
11380}
11381
0d74a222
LA
11382static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11383 int16_t offset)
11384{
11385 TCGv_i32 t0 = tcg_const_i32(op);
11386 TCGv t1 = tcg_temp_new();
11387 gen_base_offset_addr(ctx, t1, base, offset);
11388 gen_helper_cache(cpu_env, t1, t0);
11389}
11390
364d4831 11391#if defined(TARGET_MIPS64)
d75c135e 11392static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11393 int ry, int funct, int16_t offset,
11394 int extended)
11395{
11396 switch (funct) {
11397 case I64_LDSP:
d9224450 11398 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11399 check_mips_64(ctx);
11400 offset = extended ? offset : offset << 3;
d75c135e 11401 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11402 break;
11403 case I64_SDSP:
d9224450 11404 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11405 check_mips_64(ctx);
11406 offset = extended ? offset : offset << 3;
5c13fdfd 11407 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11408 break;
11409 case I64_SDRASP:
d9224450 11410 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11411 check_mips_64(ctx);
11412 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11413 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11414 break;
11415 case I64_DADJSP:
d9224450 11416 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11417 check_mips_64(ctx);
11418 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11419 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11420 break;
11421 case I64_LDPC:
d9224450
MR
11422 check_insn(ctx, ISA_MIPS3);
11423 check_mips_64(ctx);
364d4831 11424 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11425 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11426 } else {
11427 offset = extended ? offset : offset << 3;
d75c135e 11428 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11429 }
11430 break;
11431 case I64_DADDIU5:
d9224450 11432 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11433 check_mips_64(ctx);
11434 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11435 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11436 break;
11437 case I64_DADDIUPC:
d9224450 11438 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11439 check_mips_64(ctx);
11440 offset = extended ? offset : offset << 2;
11441 gen_addiupc(ctx, ry, offset, 1, extended);
11442 break;
11443 case I64_DADDIUSP:
d9224450 11444 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11445 check_mips_64(ctx);
11446 offset = extended ? offset : offset << 2;
d75c135e 11447 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11448 break;
11449 }
11450}
11451#endif
11452
240ce26a 11453static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11454{
895c2d04 11455 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11456 int op, rx, ry, funct, sa;
11457 int16_t imm, offset;
11458
11459 ctx->opcode = (ctx->opcode << 16) | extend;
11460 op = (ctx->opcode >> 11) & 0x1f;
11461 sa = (ctx->opcode >> 22) & 0x1f;
11462 funct = (ctx->opcode >> 8) & 0x7;
11463 rx = xlat((ctx->opcode >> 8) & 0x7);
11464 ry = xlat((ctx->opcode >> 5) & 0x7);
11465 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11466 | ((ctx->opcode >> 21) & 0x3f) << 5
11467 | (ctx->opcode & 0x1f));
11468
11469 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11470 counterparts. */
11471 switch (op) {
11472 case M16_OPC_ADDIUSP:
d75c135e 11473 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11474 break;
11475 case M16_OPC_ADDIUPC:
11476 gen_addiupc(ctx, rx, imm, 0, 1);
11477 break;
11478 case M16_OPC_B:
b231c103 11479 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11480 /* No delay slot, so just process as a normal instruction */
11481 break;
11482 case M16_OPC_BEQZ:
b231c103 11483 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11484 /* No delay slot, so just process as a normal instruction */
11485 break;
11486 case M16_OPC_BNEQZ:
b231c103 11487 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11488 /* No delay slot, so just process as a normal instruction */
11489 break;
11490 case M16_OPC_SHIFT:
11491 switch (ctx->opcode & 0x3) {
11492 case 0x0:
d75c135e 11493 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11494 break;
11495 case 0x1:
11496#if defined(TARGET_MIPS64)
11497 check_mips_64(ctx);
d75c135e 11498 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11499#else
9c708c7f 11500 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11501#endif
11502 break;
11503 case 0x2:
d75c135e 11504 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11505 break;
11506 case 0x3:
d75c135e 11507 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11508 break;
11509 }
11510 break;
11511#if defined(TARGET_MIPS64)
11512 case M16_OPC_LD:
d9224450 11513 check_insn(ctx, ISA_MIPS3);
d75de749 11514 check_mips_64(ctx);
d75c135e 11515 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11516 break;
11517#endif
11518 case M16_OPC_RRIA:
11519 imm = ctx->opcode & 0xf;
11520 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11521 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11522 imm = (int16_t) (imm << 1) >> 1;
11523 if ((ctx->opcode >> 4) & 0x1) {
11524#if defined(TARGET_MIPS64)
11525 check_mips_64(ctx);
d75c135e 11526 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11527#else
9c708c7f 11528 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11529#endif
11530 } else {
d75c135e 11531 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11532 }
11533 break;
11534 case M16_OPC_ADDIU8:
d75c135e 11535 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11536 break;
11537 case M16_OPC_SLTI:
d75c135e 11538 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11539 break;
11540 case M16_OPC_SLTIU:
d75c135e 11541 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11542 break;
11543 case M16_OPC_I8:
11544 switch (funct) {
11545 case I8_BTEQZ:
b231c103 11546 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11547 break;
11548 case I8_BTNEZ:
b231c103 11549 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11550 break;
11551 case I8_SWRASP:
5c13fdfd 11552 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11553 break;
11554 case I8_ADJSP:
d75c135e 11555 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11556 break;
11557 case I8_SVRS:
d9224450 11558 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11559 {
11560 int xsregs = (ctx->opcode >> 24) & 0x7;
11561 int aregs = (ctx->opcode >> 16) & 0xf;
11562 int do_ra = (ctx->opcode >> 6) & 0x1;
11563 int do_s0 = (ctx->opcode >> 5) & 0x1;
11564 int do_s1 = (ctx->opcode >> 4) & 0x1;
11565 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11566 | (ctx->opcode & 0xf)) << 3;
11567
11568 if (ctx->opcode & (1 << 7)) {
11569 gen_mips16_save(ctx, xsregs, aregs,
11570 do_ra, do_s0, do_s1,
11571 framesize);
11572 } else {
11573 gen_mips16_restore(ctx, xsregs, aregs,
11574 do_ra, do_s0, do_s1,
11575 framesize);
11576 }
11577 }
11578 break;
11579 default:
9c708c7f 11580 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11581 break;
11582 }
11583 break;
11584 case M16_OPC_LI:
11585 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11586 break;
11587 case M16_OPC_CMPI:
11588 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11589 break;
11590#if defined(TARGET_MIPS64)
11591 case M16_OPC_SD:
d9224450
MR
11592 check_insn(ctx, ISA_MIPS3);
11593 check_mips_64(ctx);
5c13fdfd 11594 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11595 break;
11596#endif
11597 case M16_OPC_LB:
d75c135e 11598 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11599 break;
11600 case M16_OPC_LH:
d75c135e 11601 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11602 break;
11603 case M16_OPC_LWSP:
d75c135e 11604 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11605 break;
11606 case M16_OPC_LW:
d75c135e 11607 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11608 break;
11609 case M16_OPC_LBU:
d75c135e 11610 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11611 break;
11612 case M16_OPC_LHU:
d75c135e 11613 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11614 break;
11615 case M16_OPC_LWPC:
d75c135e 11616 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11617 break;
11618#if defined(TARGET_MIPS64)
11619 case M16_OPC_LWU:
d9224450
MR
11620 check_insn(ctx, ISA_MIPS3);
11621 check_mips_64(ctx);
d75c135e 11622 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11623 break;
11624#endif
11625 case M16_OPC_SB:
5c13fdfd 11626 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11627 break;
11628 case M16_OPC_SH:
5c13fdfd 11629 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11630 break;
11631 case M16_OPC_SWSP:
5c13fdfd 11632 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11633 break;
11634 case M16_OPC_SW:
5c13fdfd 11635 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11636 break;
11637#if defined(TARGET_MIPS64)
11638 case M16_OPC_I64:
d75c135e 11639 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11640 break;
11641#endif
11642 default:
9c708c7f 11643 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11644 break;
11645 }
11646
11647 return 4;
11648}
11649
3b3c1694
LA
11650static inline bool is_uhi(int sdbbp_code)
11651{
11652#ifdef CONFIG_USER_ONLY
11653 return false;
11654#else
11655 return semihosting_enabled() && sdbbp_code == 1;
11656#endif
11657}
11658
240ce26a 11659static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11660{
11661 int rx, ry;
11662 int sa;
11663 int op, cnvt_op, op1, offset;
11664 int funct;
11665 int n_bytes;
11666
11667 op = (ctx->opcode >> 11) & 0x1f;
11668 sa = (ctx->opcode >> 2) & 0x7;
11669 sa = sa == 0 ? 8 : sa;
11670 rx = xlat((ctx->opcode >> 8) & 0x7);
11671 cnvt_op = (ctx->opcode >> 5) & 0x7;
11672 ry = xlat((ctx->opcode >> 5) & 0x7);
11673 op1 = offset = ctx->opcode & 0x1f;
11674
11675 n_bytes = 2;
11676
11677 switch (op) {
11678 case M16_OPC_ADDIUSP:
11679 {
11680 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11681
d75c135e 11682 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11683 }
11684 break;
11685 case M16_OPC_ADDIUPC:
11686 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11687 break;
11688 case M16_OPC_B:
11689 offset = (ctx->opcode & 0x7ff) << 1;
11690 offset = (int16_t)(offset << 4) >> 4;
b231c103 11691 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11692 /* No delay slot, so just process as a normal instruction */
11693 break;
11694 case M16_OPC_JAL:
895c2d04 11695 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11696 offset = (((ctx->opcode & 0x1f) << 21)
11697 | ((ctx->opcode >> 5) & 0x1f) << 16
11698 | offset) << 2;
b231c103
YK
11699 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11700 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11701 n_bytes = 4;
364d4831
NF
11702 break;
11703 case M16_OPC_BEQZ:
b231c103
YK
11704 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11705 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11706 /* No delay slot, so just process as a normal instruction */
11707 break;
11708 case M16_OPC_BNEQZ:
b231c103
YK
11709 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11710 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11711 /* No delay slot, so just process as a normal instruction */
11712 break;
11713 case M16_OPC_SHIFT:
11714 switch (ctx->opcode & 0x3) {
11715 case 0x0:
d75c135e 11716 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11717 break;
11718 case 0x1:
11719#if defined(TARGET_MIPS64)
d9224450 11720 check_insn(ctx, ISA_MIPS3);
364d4831 11721 check_mips_64(ctx);
d75c135e 11722 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11723#else
9c708c7f 11724 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11725#endif
11726 break;
11727 case 0x2:
d75c135e 11728 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11729 break;
11730 case 0x3:
d75c135e 11731 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11732 break;
11733 }
11734 break;
11735#if defined(TARGET_MIPS64)
11736 case M16_OPC_LD:
d9224450 11737 check_insn(ctx, ISA_MIPS3);
364d4831 11738 check_mips_64(ctx);
d75c135e 11739 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11740 break;
11741#endif
11742 case M16_OPC_RRIA:
11743 {
11744 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11745
11746 if ((ctx->opcode >> 4) & 1) {
11747#if defined(TARGET_MIPS64)
d9224450 11748 check_insn(ctx, ISA_MIPS3);
364d4831 11749 check_mips_64(ctx);
d75c135e 11750 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11751#else
9c708c7f 11752 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11753#endif
11754 } else {
d75c135e 11755 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11756 }
11757 }
11758 break;
11759 case M16_OPC_ADDIU8:
11760 {
11761 int16_t imm = (int8_t) ctx->opcode;
11762
d75c135e 11763 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11764 }
11765 break;
11766 case M16_OPC_SLTI:
11767 {
11768 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11769 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11770 }
11771 break;
11772 case M16_OPC_SLTIU:
11773 {
11774 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11775 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11776 }
11777 break;
11778 case M16_OPC_I8:
11779 {
11780 int reg32;
11781
11782 funct = (ctx->opcode >> 8) & 0x7;
11783 switch (funct) {
11784 case I8_BTEQZ:
11785 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11786 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11787 break;
11788 case I8_BTNEZ:
11789 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11790 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11791 break;
11792 case I8_SWRASP:
5c13fdfd 11793 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11794 break;
11795 case I8_ADJSP:
d75c135e 11796 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11797 ((int8_t)ctx->opcode) << 3);
11798 break;
11799 case I8_SVRS:
d9224450 11800 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11801 {
11802 int do_ra = ctx->opcode & (1 << 6);
11803 int do_s0 = ctx->opcode & (1 << 5);
11804 int do_s1 = ctx->opcode & (1 << 4);
11805 int framesize = ctx->opcode & 0xf;
11806
11807 if (framesize == 0) {
11808 framesize = 128;
11809 } else {
11810 framesize = framesize << 3;
11811 }
11812
11813 if (ctx->opcode & (1 << 7)) {
11814 gen_mips16_save(ctx, 0, 0,
11815 do_ra, do_s0, do_s1, framesize);
11816 } else {
11817 gen_mips16_restore(ctx, 0, 0,
11818 do_ra, do_s0, do_s1, framesize);
11819 }
11820 }
11821 break;
11822 case I8_MOV32R:
11823 {
11824 int rz = xlat(ctx->opcode & 0x7);
11825
11826 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11827 ((ctx->opcode >> 5) & 0x7);
d75c135e 11828 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11829 }
11830 break;
11831 case I8_MOVR32:
11832 reg32 = ctx->opcode & 0x1f;
d75c135e 11833 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11834 break;
11835 default:
9c708c7f 11836 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11837 break;
11838 }
11839 }
11840 break;
11841 case M16_OPC_LI:
11842 {
11843 int16_t imm = (uint8_t) ctx->opcode;
11844
d75c135e 11845 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11846 }
11847 break;
11848 case M16_OPC_CMPI:
11849 {
11850 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11851 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11852 }
11853 break;
11854#if defined(TARGET_MIPS64)
11855 case M16_OPC_SD:
d9224450 11856 check_insn(ctx, ISA_MIPS3);
364d4831 11857 check_mips_64(ctx);
5c13fdfd 11858 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11859 break;
11860#endif
11861 case M16_OPC_LB:
d75c135e 11862 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11863 break;
11864 case M16_OPC_LH:
d75c135e 11865 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11866 break;
11867 case M16_OPC_LWSP:
d75c135e 11868 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11869 break;
11870 case M16_OPC_LW:
d75c135e 11871 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11872 break;
11873 case M16_OPC_LBU:
d75c135e 11874 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11875 break;
11876 case M16_OPC_LHU:
d75c135e 11877 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11878 break;
11879 case M16_OPC_LWPC:
d75c135e 11880 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11881 break;
11882#if defined (TARGET_MIPS64)
11883 case M16_OPC_LWU:
d9224450 11884 check_insn(ctx, ISA_MIPS3);
364d4831 11885 check_mips_64(ctx);
d75c135e 11886 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11887 break;
11888#endif
11889 case M16_OPC_SB:
5c13fdfd 11890 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11891 break;
11892 case M16_OPC_SH:
5c13fdfd 11893 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11894 break;
11895 case M16_OPC_SWSP:
5c13fdfd 11896 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11897 break;
11898 case M16_OPC_SW:
5c13fdfd 11899 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11900 break;
11901 case M16_OPC_RRR:
11902 {
11903 int rz = xlat((ctx->opcode >> 2) & 0x7);
11904 int mips32_op;
11905
11906 switch (ctx->opcode & 0x3) {
11907 case RRR_ADDU:
11908 mips32_op = OPC_ADDU;
11909 break;
11910 case RRR_SUBU:
11911 mips32_op = OPC_SUBU;
11912 break;
11913#if defined(TARGET_MIPS64)
11914 case RRR_DADDU:
11915 mips32_op = OPC_DADDU;
d9224450 11916 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11917 check_mips_64(ctx);
11918 break;
11919 case RRR_DSUBU:
11920 mips32_op = OPC_DSUBU;
d9224450 11921 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11922 check_mips_64(ctx);
11923 break;
11924#endif
11925 default:
9c708c7f 11926 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11927 goto done;
11928 }
11929
d75c135e 11930 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11931 done:
11932 ;
11933 }
11934 break;
11935 case M16_OPC_RR:
11936 switch (op1) {
11937 case RR_JR:
11938 {
11939 int nd = (ctx->opcode >> 7) & 0x1;
11940 int link = (ctx->opcode >> 6) & 0x1;
11941 int ra = (ctx->opcode >> 5) & 0x1;
11942
d9224450
MR
11943 if (nd) {
11944 check_insn(ctx, ISA_MIPS32);
11945 }
11946
364d4831 11947 if (link) {
b231c103 11948 op = OPC_JALR;
364d4831
NF
11949 } else {
11950 op = OPC_JR;
11951 }
11952
b231c103
YK
11953 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11954 (nd ? 0 : 2));
364d4831
NF
11955 }
11956 break;
11957 case RR_SDBBP:
3b3c1694
LA
11958 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11959 gen_helper_do_semihosting(cpu_env);
11960 } else {
11961 /* XXX: not clear which exception should be raised
11962 * when in debug mode...
11963 */
11964 check_insn(ctx, ISA_MIPS32);
9c708c7f 11965 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 11966 }
364d4831
NF
11967 break;
11968 case RR_SLT:
d75c135e 11969 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11970 break;
11971 case RR_SLTU:
d75c135e 11972 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11973 break;
11974 case RR_BREAK:
9c708c7f 11975 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
11976 break;
11977 case RR_SLLV:
d75c135e 11978 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11979 break;
11980 case RR_SRLV:
d75c135e 11981 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11982 break;
11983 case RR_SRAV:
d75c135e 11984 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11985 break;
11986#if defined (TARGET_MIPS64)
11987 case RR_DSRL:
d9224450 11988 check_insn(ctx, ISA_MIPS3);
364d4831 11989 check_mips_64(ctx);
d75c135e 11990 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11991 break;
11992#endif
11993 case RR_CMP:
d75c135e 11994 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11995 break;
11996 case RR_NEG:
d75c135e 11997 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11998 break;
11999 case RR_AND:
d75c135e 12000 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12001 break;
12002 case RR_OR:
d75c135e 12003 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12004 break;
12005 case RR_XOR:
d75c135e 12006 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12007 break;
12008 case RR_NOT:
d75c135e 12009 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12010 break;
12011 case RR_MFHI:
26135ead 12012 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12013 break;
12014 case RR_CNVT:
d9224450 12015 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12016 switch (cnvt_op) {
12017 case RR_RY_CNVT_ZEB:
12018 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12019 break;
12020 case RR_RY_CNVT_ZEH:
12021 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12022 break;
12023 case RR_RY_CNVT_SEB:
12024 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12025 break;
12026 case RR_RY_CNVT_SEH:
12027 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12028 break;
12029#if defined (TARGET_MIPS64)
12030 case RR_RY_CNVT_ZEW:
d9224450 12031 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12032 check_mips_64(ctx);
12033 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12034 break;
12035 case RR_RY_CNVT_SEW:
d9224450 12036 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12037 check_mips_64(ctx);
12038 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12039 break;
12040#endif
12041 default:
9c708c7f 12042 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12043 break;
12044 }
12045 break;
12046 case RR_MFLO:
26135ead 12047 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12048 break;
12049#if defined (TARGET_MIPS64)
12050 case RR_DSRA:
d9224450 12051 check_insn(ctx, ISA_MIPS3);
364d4831 12052 check_mips_64(ctx);
d75c135e 12053 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12054 break;
12055 case RR_DSLLV:
d9224450 12056 check_insn(ctx, ISA_MIPS3);
364d4831 12057 check_mips_64(ctx);
d75c135e 12058 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12059 break;
12060 case RR_DSRLV:
d9224450 12061 check_insn(ctx, ISA_MIPS3);
364d4831 12062 check_mips_64(ctx);
d75c135e 12063 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12064 break;
12065 case RR_DSRAV:
d9224450 12066 check_insn(ctx, ISA_MIPS3);
364d4831 12067 check_mips_64(ctx);
d75c135e 12068 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12069 break;
12070#endif
12071 case RR_MULT:
26135ead 12072 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12073 break;
12074 case RR_MULTU:
26135ead 12075 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12076 break;
12077 case RR_DIV:
26135ead 12078 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12079 break;
12080 case RR_DIVU:
26135ead 12081 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12082 break;
12083#if defined (TARGET_MIPS64)
12084 case RR_DMULT:
d9224450 12085 check_insn(ctx, ISA_MIPS3);
364d4831 12086 check_mips_64(ctx);
26135ead 12087 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12088 break;
12089 case RR_DMULTU:
d9224450 12090 check_insn(ctx, ISA_MIPS3);
364d4831 12091 check_mips_64(ctx);
26135ead 12092 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12093 break;
12094 case RR_DDIV:
d9224450 12095 check_insn(ctx, ISA_MIPS3);
364d4831 12096 check_mips_64(ctx);
26135ead 12097 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12098 break;
12099 case RR_DDIVU:
d9224450 12100 check_insn(ctx, ISA_MIPS3);
364d4831 12101 check_mips_64(ctx);
26135ead 12102 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12103 break;
12104#endif
12105 default:
9c708c7f 12106 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12107 break;
12108 }
12109 break;
12110 case M16_OPC_EXTEND:
240ce26a 12111 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12112 n_bytes = 4;
12113 break;
12114#if defined(TARGET_MIPS64)
12115 case M16_OPC_I64:
12116 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12117 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12118 break;
12119#endif
12120 default:
9c708c7f 12121 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12122 break;
12123 }
12124
12125 return n_bytes;
12126}
12127
211da992 12128/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12129
211da992
CWR
12130/*
12131 * microMIPS32/microMIPS64 major opcodes
12132 *
12133 * 1. MIPS Architecture for Programmers Volume II-B:
12134 * The microMIPS32 Instruction Set (Revision 3.05)
12135 *
12136 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12137 *
12138 * 2. MIPS Architecture For Programmers Volume II-A:
12139 * The MIPS64 Instruction Set (Revision 3.51)
12140 */
6af0bf9c 12141
3c824109
NF
12142enum {
12143 POOL32A = 0x00,
12144 POOL16A = 0x01,
12145 LBU16 = 0x02,
12146 MOVE16 = 0x03,
12147 ADDI32 = 0x04,
3a1f4268
YK
12148 R6_LUI = 0x04,
12149 AUI = 0x04,
3c824109
NF
12150 LBU32 = 0x05,
12151 SB32 = 0x06,
12152 LB32 = 0x07,
12153
12154 POOL32B = 0x08,
12155 POOL16B = 0x09,
12156 LHU16 = 0x0a,
12157 ANDI16 = 0x0b,
12158 ADDIU32 = 0x0c,
12159 LHU32 = 0x0d,
12160 SH32 = 0x0e,
12161 LH32 = 0x0f,
12162
12163 POOL32I = 0x10,
12164 POOL16C = 0x11,
12165 LWSP16 = 0x12,
12166 POOL16D = 0x13,
12167 ORI32 = 0x14,
12168 POOL32F = 0x15,
211da992
CWR
12169 POOL32S = 0x16, /* MIPS64 */
12170 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12171
12172 POOL32C = 0x18,
12173 LWGP16 = 0x19,
12174 LW16 = 0x1a,
12175 POOL16E = 0x1b,
12176 XORI32 = 0x1c,
12177 JALS32 = 0x1d,
3a1f4268
YK
12178 BOVC = 0x1d,
12179 BEQC = 0x1d,
12180 BEQZALC = 0x1d,
3c824109 12181 ADDIUPC = 0x1e,
3a1f4268
YK
12182 PCREL = 0x1e,
12183 BNVC = 0x1f,
12184 BNEC = 0x1f,
12185 BNEZALC = 0x1f,
3c824109 12186
3a1f4268
YK
12187 R6_BEQZC = 0x20,
12188 JIC = 0x20,
3c824109
NF
12189 POOL16F = 0x21,
12190 SB16 = 0x22,
12191 BEQZ16 = 0x23,
3a1f4268 12192 BEQZC16 = 0x23,
3c824109
NF
12193 SLTI32 = 0x24,
12194 BEQ32 = 0x25,
3a1f4268 12195 BC = 0x25,
3c824109
NF
12196 SWC132 = 0x26,
12197 LWC132 = 0x27,
12198
3a1f4268 12199 /* 0x29 is reserved */
3c824109 12200 RES_29 = 0x29,
3a1f4268
YK
12201 R6_BNEZC = 0x28,
12202 JIALC = 0x28,
3c824109
NF
12203 SH16 = 0x2a,
12204 BNEZ16 = 0x2b,
3a1f4268 12205 BNEZC16 = 0x2b,
3c824109
NF
12206 SLTIU32 = 0x2c,
12207 BNE32 = 0x2d,
3a1f4268 12208 BALC = 0x2d,
3c824109
NF
12209 SDC132 = 0x2e,
12210 LDC132 = 0x2f,
12211
3a1f4268 12212 /* 0x31 is reserved */
3c824109 12213 RES_31 = 0x31,
3a1f4268
YK
12214 BLEZALC = 0x30,
12215 BGEZALC = 0x30,
12216 BGEUC = 0x30,
3c824109
NF
12217 SWSP16 = 0x32,
12218 B16 = 0x33,
3a1f4268 12219 BC16 = 0x33,
3c824109
NF
12220 ANDI32 = 0x34,
12221 J32 = 0x35,
3a1f4268
YK
12222 BGTZC = 0x35,
12223 BLTZC = 0x35,
12224 BLTC = 0x35,
211da992
CWR
12225 SD32 = 0x36, /* MIPS64 */
12226 LD32 = 0x37, /* MIPS64 */
3c824109 12227
3a1f4268 12228 /* 0x39 is reserved */
3c824109 12229 RES_39 = 0x39,
3a1f4268
YK
12230 BGTZALC = 0x38,
12231 BLTZALC = 0x38,
12232 BLTUC = 0x38,
3c824109
NF
12233 SW16 = 0x3a,
12234 LI16 = 0x3b,
12235 JALX32 = 0x3c,
12236 JAL32 = 0x3d,
3a1f4268
YK
12237 BLEZC = 0x3d,
12238 BGEZC = 0x3d,
12239 BGEC = 0x3d,
3c824109
NF
12240 SW32 = 0x3e,
12241 LW32 = 0x3f
12242};
12243
3a1f4268
YK
12244/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12245enum {
12246 ADDIUPC_00 = 0x00,
12247 ADDIUPC_07 = 0x07,
12248 AUIPC = 0x1e,
12249 ALUIPC = 0x1f,
12250 LWPC_08 = 0x08,
12251 LWPC_0F = 0x0F,
12252};
12253
3c824109
NF
12254/* POOL32A encoding of minor opcode field */
12255
12256enum {
12257 /* These opcodes are distinguished only by bits 9..6; those bits are
12258 * what are recorded below. */
12259 SLL32 = 0x0,
12260 SRL32 = 0x1,
12261 SRA = 0x2,
12262 ROTR = 0x3,
3a1f4268
YK
12263 SELEQZ = 0x5,
12264 SELNEZ = 0x6,
b00c7218 12265 R6_RDHWR = 0x7,
3c824109
NF
12266
12267 SLLV = 0x0,
12268 SRLV = 0x1,
12269 SRAV = 0x2,
12270 ROTRV = 0x3,
12271 ADD = 0x4,
12272 ADDU32 = 0x5,
12273 SUB = 0x6,
12274 SUBU32 = 0x7,
12275 MUL = 0x8,
12276 AND = 0x9,
12277 OR32 = 0xa,
12278 NOR = 0xb,
12279 XOR32 = 0xc,
12280 SLT = 0xd,
12281 SLTU = 0xe,
12282
12283 MOVN = 0x0,
3a1f4268 12284 R6_MUL = 0x0,
3c824109 12285 MOVZ = 0x1,
3a1f4268
YK
12286 MUH = 0x1,
12287 MULU = 0x2,
12288 MUHU = 0x3,
3c824109 12289 LWXS = 0x4,
3a1f4268
YK
12290 R6_DIV = 0x4,
12291 MOD = 0x5,
12292 R6_DIVU = 0x6,
12293 MODU = 0x7,
3c824109
NF
12294
12295 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12296 BREAK32 = 0x07,
3c824109 12297 INS = 0x0c,
3a1f4268
YK
12298 LSA = 0x0f,
12299 ALIGN = 0x1f,
3c824109 12300 EXT = 0x2c,
bb238210
YK
12301 POOL32AXF = 0x3c,
12302 SIGRIE = 0x3f
3c824109
NF
12303};
12304
12305/* POOL32AXF encoding of minor opcode field extension */
12306
d132c79f
CWR
12307/*
12308 * 1. MIPS Architecture for Programmers Volume II-B:
12309 * The microMIPS32 Instruction Set (Revision 3.05)
12310 *
12311 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12312 *
12313 * 2. MIPS Architecture for Programmers VolumeIV-e:
12314 * The MIPS DSP Application-Specific Extension
12315 * to the microMIPS32 Architecture (Revision 2.34)
12316 *
12317 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12318 */
12319
3c824109
NF
12320enum {
12321 /* bits 11..6 */
12322 TEQ = 0x00,
12323 TGE = 0x08,
12324 TGEU = 0x10,
12325 TLT = 0x20,
12326 TLTU = 0x28,
12327 TNE = 0x30,
12328
12329 MFC0 = 0x03,
12330 MTC0 = 0x0b,
12331
d132c79f
CWR
12332 /* begin of microMIPS32 DSP */
12333
3c824109
NF
12334 /* bits 13..12 for 0x01 */
12335 MFHI_ACC = 0x0,
12336 MFLO_ACC = 0x1,
12337 MTHI_ACC = 0x2,
12338 MTLO_ACC = 0x3,
12339
12340 /* bits 13..12 for 0x2a */
12341 MADD_ACC = 0x0,
12342 MADDU_ACC = 0x1,
12343 MSUB_ACC = 0x2,
12344 MSUBU_ACC = 0x3,
12345
12346 /* bits 13..12 for 0x32 */
12347 MULT_ACC = 0x0,
6801038b 12348 MULTU_ACC = 0x1,
3c824109 12349
d132c79f
CWR
12350 /* end of microMIPS32 DSP */
12351
3c824109 12352 /* bits 15..12 for 0x2c */
3a1f4268 12353 BITSWAP = 0x0,
3c824109
NF
12354 SEB = 0x2,
12355 SEH = 0x3,
12356 CLO = 0x4,
12357 CLZ = 0x5,
12358 RDHWR = 0x6,
12359 WSBH = 0x7,
12360 MULT = 0x8,
12361 MULTU = 0x9,
12362 DIV = 0xa,
12363 DIVU = 0xb,
12364 MADD = 0xc,
12365 MADDU = 0xd,
12366 MSUB = 0xe,
12367 MSUBU = 0xf,
12368
12369 /* bits 15..12 for 0x34 */
12370 MFC2 = 0x4,
12371 MTC2 = 0x5,
12372 MFHC2 = 0x8,
12373 MTHC2 = 0x9,
12374 CFC2 = 0xc,
12375 CTC2 = 0xd,
12376
12377 /* bits 15..12 for 0x3c */
12378 JALR = 0x0,
12379 JR = 0x0, /* alias */
3a1f4268
YK
12380 JALRC = 0x0,
12381 JRC = 0x0,
3c824109 12382 JALR_HB = 0x1,
3a1f4268 12383 JALRC_HB = 0x1,
3c824109
NF
12384 JALRS = 0x4,
12385 JALRS_HB = 0x5,
12386
12387 /* bits 15..12 for 0x05 */
12388 RDPGPR = 0xe,
12389 WRPGPR = 0xf,
12390
12391 /* bits 15..12 for 0x0d */
12392 TLBP = 0x0,
12393 TLBR = 0x1,
12394 TLBWI = 0x2,
12395 TLBWR = 0x3,
e60ec063
YK
12396 TLBINV = 0x4,
12397 TLBINVF = 0x5,
3c824109
NF
12398 WAIT = 0x9,
12399 IRET = 0xd,
12400 DERET = 0xe,
12401 ERET = 0xf,
12402
12403 /* bits 15..12 for 0x15 */
12404 DMT = 0x0,
12405 DVPE = 0x1,
12406 EMT = 0x2,
12407 EVPE = 0x3,
12408
12409 /* bits 15..12 for 0x1d */
12410 DI = 0x4,
12411 EI = 0x5,
12412
12413 /* bits 15..12 for 0x2d */
12414 SYNC = 0x6,
12415 SYSCALL = 0x8,
12416 SDBBP = 0xd,
12417
12418 /* bits 15..12 for 0x35 */
12419 MFHI32 = 0x0,
12420 MFLO32 = 0x1,
12421 MTHI32 = 0x2,
12422 MTLO32 = 0x3,
12423};
12424
12425/* POOL32B encoding of minor opcode field (bits 15..12) */
12426
12427enum {
12428 LWC2 = 0x0,
12429 LWP = 0x1,
12430 LDP = 0x4,
12431 LWM32 = 0x5,
12432 CACHE = 0x6,
12433 LDM = 0x7,
12434 SWC2 = 0x8,
12435 SWP = 0x9,
12436 SDP = 0xc,
12437 SWM32 = 0xd,
12438 SDM = 0xf
12439};
12440
12441/* POOL32C encoding of minor opcode field (bits 15..12) */
12442
12443enum {
12444 LWL = 0x0,
12445 SWL = 0x8,
12446 LWR = 0x1,
12447 SWR = 0x9,
12448 PREF = 0x2,
12449 /* 0xa is reserved */
12450 LL = 0x3,
12451 SC = 0xb,
12452 LDL = 0x4,
12453 SDL = 0xc,
12454 LDR = 0x5,
12455 SDR = 0xd,
12456 /* 0x6 is reserved */
12457 LWU = 0xe,
12458 LLD = 0x7,
12459 SCD = 0xf
12460};
12461
12462/* POOL32F encoding of minor opcode field (bits 5..0) */
12463
12464enum {
12465 /* These are the bit 7..6 values */
12466 ADD_FMT = 0x0,
3c824109
NF
12467
12468 SUB_FMT = 0x1,
3c824109
NF
12469
12470 MUL_FMT = 0x2,
12471
12472 DIV_FMT = 0x3,
12473
12474 /* These are the bit 8..6 values */
3a1f4268 12475 MOVN_FMT = 0x0,
3c824109
NF
12476 RSQRT2_FMT = 0x0,
12477 MOVF_FMT = 0x0,
3a1f4268
YK
12478 RINT_FMT = 0x0,
12479 SELNEZ_FMT = 0x0,
3c824109 12480
3a1f4268 12481 MOVZ_FMT = 0x1,
3c824109
NF
12482 LWXC1 = 0x1,
12483 MOVT_FMT = 0x1,
3a1f4268
YK
12484 CLASS_FMT = 0x1,
12485 SELEQZ_FMT = 0x1,
3c824109
NF
12486
12487 PLL_PS = 0x2,
12488 SWXC1 = 0x2,
3a1f4268 12489 SEL_FMT = 0x2,
3c824109
NF
12490
12491 PLU_PS = 0x3,
12492 LDXC1 = 0x3,
12493
3a1f4268 12494 MOVN_FMT_04 = 0x4,
3c824109
NF
12495 PUL_PS = 0x4,
12496 SDXC1 = 0x4,
12497 RECIP2_FMT = 0x4,
12498
3a1f4268 12499 MOVZ_FMT_05 = 0x05,
3c824109
NF
12500 PUU_PS = 0x5,
12501 LUXC1 = 0x5,
12502
12503 CVT_PS_S = 0x6,
12504 SUXC1 = 0x6,
12505 ADDR_PS = 0x6,
12506 PREFX = 0x6,
3a1f4268 12507 MADDF_FMT = 0x6,
3c824109
NF
12508
12509 MULR_PS = 0x7,
3a1f4268 12510 MSUBF_FMT = 0x7,
3c824109
NF
12511
12512 MADD_S = 0x01,
12513 MADD_D = 0x09,
12514 MADD_PS = 0x11,
12515 ALNV_PS = 0x19,
12516 MSUB_S = 0x21,
12517 MSUB_D = 0x29,
12518 MSUB_PS = 0x31,
12519
12520 NMADD_S = 0x02,
12521 NMADD_D = 0x0a,
12522 NMADD_PS = 0x12,
12523 NMSUB_S = 0x22,
12524 NMSUB_D = 0x2a,
12525 NMSUB_PS = 0x32,
12526
3a1f4268
YK
12527 MIN_FMT = 0x3,
12528 MAX_FMT = 0xb,
12529 MINA_FMT = 0x23,
12530 MAXA_FMT = 0x2b,
3c824109
NF
12531 POOL32FXF = 0x3b,
12532
12533 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12534 C_COND_FMT = 0x3c,
12535
12536 CMP_CONDN_S = 0x5,
12537 CMP_CONDN_D = 0x15
3c824109
NF
12538};
12539
12540/* POOL32Fxf encoding of minor opcode extension field */
12541
12542enum {
12543 CVT_L = 0x04,
12544 RSQRT_FMT = 0x08,
12545 FLOOR_L = 0x0c,
12546 CVT_PW_PS = 0x1c,
12547 CVT_W = 0x24,
12548 SQRT_FMT = 0x28,
12549 FLOOR_W = 0x2c,
12550 CVT_PS_PW = 0x3c,
12551 CFC1 = 0x40,
12552 RECIP_FMT = 0x48,
12553 CEIL_L = 0x4c,
12554 CTC1 = 0x60,
12555 CEIL_W = 0x6c,
12556 MFC1 = 0x80,
12557 CVT_S_PL = 0x84,
12558 TRUNC_L = 0x8c,
12559 MTC1 = 0xa0,
12560 CVT_S_PU = 0xa4,
12561 TRUNC_W = 0xac,
12562 MFHC1 = 0xc0,
12563 ROUND_L = 0xcc,
12564 MTHC1 = 0xe0,
12565 ROUND_W = 0xec,
12566
12567 MOV_FMT = 0x01,
12568 MOVF = 0x05,
12569 ABS_FMT = 0x0d,
12570 RSQRT1_FMT = 0x1d,
12571 MOVT = 0x25,
12572 NEG_FMT = 0x2d,
12573 CVT_D = 0x4d,
12574 RECIP1_FMT = 0x5d,
12575 CVT_S = 0x6d
12576};
12577
12578/* POOL32I encoding of minor opcode field (bits 25..21) */
12579
12580enum {
12581 BLTZ = 0x00,
12582 BLTZAL = 0x01,
12583 BGEZ = 0x02,
12584 BGEZAL = 0x03,
12585 BLEZ = 0x04,
12586 BNEZC = 0x05,
12587 BGTZ = 0x06,
12588 BEQZC = 0x07,
12589 TLTI = 0x08,
3a1f4268 12590 BC1EQZC = 0x08,
3c824109 12591 TGEI = 0x09,
3a1f4268 12592 BC1NEZC = 0x09,
3c824109 12593 TLTIU = 0x0a,
3a1f4268 12594 BC2EQZC = 0x0a,
3c824109 12595 TGEIU = 0x0b,
3a1f4268 12596 BC2NEZC = 0x0a,
3c824109 12597 TNEI = 0x0c,
3a1f4268 12598 R6_SYNCI = 0x0c,
3c824109
NF
12599 LUI = 0x0d,
12600 TEQI = 0x0e,
12601 SYNCI = 0x10,
12602 BLTZALS = 0x11,
12603 BGEZALS = 0x13,
12604 BC2F = 0x14,
12605 BC2T = 0x15,
12606 BPOSGE64 = 0x1a,
12607 BPOSGE32 = 0x1b,
12608 /* These overlap and are distinguished by bit16 of the instruction */
12609 BC1F = 0x1c,
12610 BC1T = 0x1d,
12611 BC1ANY2F = 0x1c,
12612 BC1ANY2T = 0x1d,
12613 BC1ANY4F = 0x1e,
12614 BC1ANY4T = 0x1f
12615};
12616
12617/* POOL16A encoding of minor opcode field */
12618
12619enum {
12620 ADDU16 = 0x0,
12621 SUBU16 = 0x1
12622};
12623
12624/* POOL16B encoding of minor opcode field */
12625
12626enum {
12627 SLL16 = 0x0,
12628 SRL16 = 0x1
12629};
12630
12631/* POOL16C encoding of minor opcode field */
12632
12633enum {
12634 NOT16 = 0x00,
12635 XOR16 = 0x04,
12636 AND16 = 0x08,
12637 OR16 = 0x0c,
12638 LWM16 = 0x10,
12639 SWM16 = 0x14,
12640 JR16 = 0x18,
12641 JRC16 = 0x1a,
12642 JALR16 = 0x1c,
12643 JALR16S = 0x1e,
12644 MFHI16 = 0x20,
12645 MFLO16 = 0x24,
12646 BREAK16 = 0x28,
12647 SDBBP16 = 0x2c,
12648 JRADDIUSP = 0x30
12649};
12650
3a1f4268
YK
12651/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12652
12653enum {
12654 R6_NOT16 = 0x00,
12655 R6_AND16 = 0x01,
12656 R6_LWM16 = 0x02,
12657 R6_JRC16 = 0x03,
12658 MOVEP = 0x04,
12659 MOVEP_07 = 0x07,
12660 R6_XOR16 = 0x08,
12661 R6_OR16 = 0x09,
12662 R6_SWM16 = 0x0a,
12663 JALRC16 = 0x0b,
12664 MOVEP_0C = 0x0c,
12665 MOVEP_0F = 0x0f,
12666 JRCADDIUSP = 0x13,
12667 R6_BREAK16 = 0x1b,
12668 R6_SDBBP16 = 0x3b
12669};
12670
3c824109
NF
12671/* POOL16D encoding of minor opcode field */
12672
12673enum {
12674 ADDIUS5 = 0x0,
12675 ADDIUSP = 0x1
12676};
12677
12678/* POOL16E encoding of minor opcode field */
12679
12680enum {
12681 ADDIUR2 = 0x0,
12682 ADDIUR1SP = 0x1
12683};
12684
12685static int mmreg (int r)
12686{
12687 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12688
12689 return map[r];
12690}
12691
12692/* Used for 16-bit store instructions. */
12693static int mmreg2 (int r)
12694{
12695 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12696
12697 return map[r];
12698}
12699
12700#define uMIPS_RD(op) ((op >> 7) & 0x7)
12701#define uMIPS_RS(op) ((op >> 4) & 0x7)
12702#define uMIPS_RS2(op) uMIPS_RS(op)
12703#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12704#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12705#define uMIPS_RS5(op) (op & 0x1f)
12706
12707/* Signed immediate */
12708#define SIMM(op, start, width) \
12709 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12710 << (32-width)) \
12711 >> (32-width))
12712/* Zero-extended immediate */
12713#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12714
d75c135e 12715static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12716{
12717 int rd = mmreg(uMIPS_RD(ctx->opcode));
12718
d75c135e 12719 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12720}
12721
d75c135e 12722static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12723{
12724 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12725 int rd = mmreg(uMIPS_RD(ctx->opcode));
12726 int rs = mmreg(uMIPS_RS(ctx->opcode));
12727
d75c135e 12728 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12729}
12730
d75c135e 12731static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12732{
12733 int encoded = ZIMM(ctx->opcode, 1, 9);
12734 int decoded;
12735
12736 if (encoded <= 1) {
12737 decoded = 256 + encoded;
12738 } else if (encoded <= 255) {
12739 decoded = encoded;
12740 } else if (encoded <= 509) {
12741 decoded = encoded - 512;
12742 } else {
12743 decoded = encoded - 768;
12744 }
12745
d75c135e 12746 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12747}
12748
d75c135e 12749static void gen_addius5(DisasContext *ctx)
3c824109
NF
12750{
12751 int imm = SIMM(ctx->opcode, 1, 4);
12752 int rd = (ctx->opcode >> 5) & 0x1f;
12753
d75c135e 12754 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12755}
12756
d75c135e 12757static void gen_andi16(DisasContext *ctx)
3c824109
NF
12758{
12759 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12760 31, 32, 63, 64, 255, 32768, 65535 };
12761 int rd = mmreg(uMIPS_RD(ctx->opcode));
12762 int rs = mmreg(uMIPS_RS(ctx->opcode));
12763 int encoded = ZIMM(ctx->opcode, 0, 4);
12764
d75c135e 12765 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12766}
12767
12768static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12769 int base, int16_t offset)
12770{
12771 TCGv t0, t1;
12772 TCGv_i32 t2;
12773
12774 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12775 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12776 return;
12777 }
12778
12779 t0 = tcg_temp_new();
12780
12781 gen_base_offset_addr(ctx, t0, base, offset);
12782
12783 t1 = tcg_const_tl(reglist);
12784 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12785
3c824109
NF
12786 save_cpu_state(ctx, 1);
12787 switch (opc) {
12788 case LWM32:
895c2d04 12789 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12790 break;
12791 case SWM32:
895c2d04 12792 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12793 break;
12794#ifdef TARGET_MIPS64
12795 case LDM:
895c2d04 12796 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12797 break;
12798 case SDM:
895c2d04 12799 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12800 break;
6af0bf9c 12801#endif
3c824109 12802 }
3c824109 12803 tcg_temp_free(t0);
33087598 12804 tcg_temp_free(t1);
3c824109
NF
12805 tcg_temp_free_i32(t2);
12806}
6af0bf9c 12807
3c824109 12808
240ce26a 12809static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12810{
3c824109
NF
12811 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12812 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12813
3c824109
NF
12814 switch (((ctx->opcode) >> 4) & 0x3f) {
12815 case NOT16 + 0:
12816 case NOT16 + 1:
12817 case NOT16 + 2:
12818 case NOT16 + 3:
d75c135e 12819 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12820 break;
12821 case XOR16 + 0:
12822 case XOR16 + 1:
12823 case XOR16 + 2:
12824 case XOR16 + 3:
d75c135e 12825 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12826 break;
12827 case AND16 + 0:
12828 case AND16 + 1:
12829 case AND16 + 2:
12830 case AND16 + 3:
d75c135e 12831 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12832 break;
12833 case OR16 + 0:
12834 case OR16 + 1:
12835 case OR16 + 2:
12836 case OR16 + 3:
d75c135e 12837 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12838 break;
12839 case LWM16 + 0:
12840 case LWM16 + 1:
12841 case LWM16 + 2:
12842 case LWM16 + 3:
12843 {
12844 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12845 int offset = ZIMM(ctx->opcode, 0, 4);
12846
12847 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12848 29, offset << 2);
12849 }
12850 break;
12851 case SWM16 + 0:
12852 case SWM16 + 1:
12853 case SWM16 + 2:
12854 case SWM16 + 3:
12855 {
12856 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12857 int offset = ZIMM(ctx->opcode, 0, 4);
12858
12859 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12860 29, offset << 2);
12861 }
12862 break;
12863 case JR16 + 0:
12864 case JR16 + 1:
12865 {
12866 int reg = ctx->opcode & 0x1f;
12867
b231c103 12868 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12869 }
3c824109
NF
12870 break;
12871 case JRC16 + 0:
12872 case JRC16 + 1:
12873 {
12874 int reg = ctx->opcode & 0x1f;
b231c103 12875 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12876 /* Let normal delay slot handling in our caller take us
12877 to the branch target. */
12878 }
12879 break;
12880 case JALR16 + 0:
12881 case JALR16 + 1:
b231c103
YK
12882 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12883 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12884 break;
3c824109
NF
12885 case JALR16S + 0:
12886 case JALR16S + 1:
b231c103
YK
12887 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12888 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12889 break;
12890 case MFHI16 + 0:
12891 case MFHI16 + 1:
26135ead 12892 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12893 break;
12894 case MFLO16 + 0:
12895 case MFLO16 + 1:
26135ead 12896 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12897 break;
12898 case BREAK16:
9c708c7f 12899 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
12900 break;
12901 case SDBBP16:
3b3c1694
LA
12902 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12903 gen_helper_do_semihosting(cpu_env);
12904 } else {
12905 /* XXX: not clear which exception should be raised
12906 * when in debug mode...
12907 */
12908 check_insn(ctx, ISA_MIPS32);
9c708c7f 12909 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12910 }
3c824109
NF
12911 break;
12912 case JRADDIUSP + 0:
12913 case JRADDIUSP + 1:
12914 {
12915 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12916 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12917 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12918 /* Let normal delay slot handling in our caller take us
12919 to the branch target. */
12920 }
12921 break;
12922 default:
9c708c7f 12923 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12924 break;
12925 }
12926}
12927
ed7ce6c0
YK
12928static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12929 int enc_rs)
12930{
12931 int rd, rs, re, rt;
12932 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12933 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12934 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12935 rd = rd_enc[enc_dest];
12936 re = re_enc[enc_dest];
12937 rs = rs_rt_enc[enc_rs];
12938 rt = rs_rt_enc[enc_rt];
12939 if (rs) {
12940 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12941 } else {
12942 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12943 }
12944 if (rt) {
12945 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12946 } else {
12947 tcg_gen_movi_tl(cpu_gpr[re], 0);
12948 }
12949}
12950
12951static void gen_pool16c_r6_insn(DisasContext *ctx)
12952{
12953 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12954 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12955
12956 switch (ctx->opcode & 0xf) {
12957 case R6_NOT16:
12958 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12959 break;
12960 case R6_AND16:
12961 gen_logic(ctx, OPC_AND, rt, rt, rs);
12962 break;
12963 case R6_LWM16:
12964 {
12965 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12966 int offset = extract32(ctx->opcode, 4, 4);
12967 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12968 }
12969 break;
12970 case R6_JRC16: /* JRCADDIUSP */
12971 if ((ctx->opcode >> 4) & 1) {
12972 /* JRCADDIUSP */
12973 int imm = extract32(ctx->opcode, 5, 5);
12974 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12975 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12976 } else {
12977 /* JRC16 */
12978 int rs = extract32(ctx->opcode, 5, 5);
12979 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12980 }
12981 break;
12982 case MOVEP ... MOVEP_07:
12983 case MOVEP_0C ... MOVEP_0F:
12984 {
12985 int enc_dest = uMIPS_RD(ctx->opcode);
12986 int enc_rt = uMIPS_RS2(ctx->opcode);
12987 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12988 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12989 }
12990 break;
12991 case R6_XOR16:
12992 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12993 break;
12994 case R6_OR16:
12995 gen_logic(ctx, OPC_OR, rt, rt, rs);
12996 break;
12997 case R6_SWM16:
12998 {
12999 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13000 int offset = extract32(ctx->opcode, 4, 4);
13001 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13002 }
13003 break;
13004 case JALRC16: /* BREAK16, SDBBP16 */
13005 switch (ctx->opcode & 0x3f) {
13006 case JALRC16:
13007 case JALRC16 + 0x20:
13008 /* JALRC16 */
13009 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13010 31, 0, 0);
13011 break;
13012 case R6_BREAK16:
13013 /* BREAK16 */
13014 generate_exception(ctx, EXCP_BREAK);
13015 break;
13016 case R6_SDBBP16:
13017 /* SDBBP16 */
060ebfef
LA
13018 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13019 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13020 } else {
060ebfef
LA
13021 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13022 generate_exception(ctx, EXCP_RI);
13023 } else {
13024 generate_exception(ctx, EXCP_DBp);
13025 }
ed7ce6c0
YK
13026 }
13027 break;
13028 }
13029 break;
13030 default:
13031 generate_exception(ctx, EXCP_RI);
13032 break;
13033 }
13034}
13035
3c824109
NF
13036static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13037{
13038 TCGv t0 = tcg_temp_new();
13039 TCGv t1 = tcg_temp_new();
13040
13041 gen_load_gpr(t0, base);
13042
13043 if (index != 0) {
13044 gen_load_gpr(t1, index);
13045 tcg_gen_shli_tl(t1, t1, 2);
13046 gen_op_addr_add(ctx, t0, t1, t0);
13047 }
13048
5f68f5ae 13049 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13050 gen_store_gpr(t1, rd);
13051
13052 tcg_temp_free(t0);
13053 tcg_temp_free(t1);
13054}
13055
13056static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13057 int base, int16_t offset)
13058{
3c824109
NF
13059 TCGv t0, t1;
13060
36c6711b 13061 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13062 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13063 return;
13064 }
13065
3c824109
NF
13066 t0 = tcg_temp_new();
13067 t1 = tcg_temp_new();
8e9ade68 13068
3c824109
NF
13069 gen_base_offset_addr(ctx, t0, base, offset);
13070
13071 switch (opc) {
13072 case LWP:
36c6711b 13073 if (rd == base) {
9c708c7f 13074 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13075 return;
13076 }
5f68f5ae 13077 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13078 gen_store_gpr(t1, rd);
13079 tcg_gen_movi_tl(t1, 4);
13080 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13081 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13082 gen_store_gpr(t1, rd+1);
3c824109
NF
13083 break;
13084 case SWP:
3c824109 13085 gen_load_gpr(t1, rd);
5f68f5ae 13086 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13087 tcg_gen_movi_tl(t1, 4);
13088 gen_op_addr_add(ctx, t0, t0, t1);
13089 gen_load_gpr(t1, rd+1);
5f68f5ae 13090 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13091 break;
13092#ifdef TARGET_MIPS64
13093 case LDP:
36c6711b 13094 if (rd == base) {
9c708c7f 13095 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13096 return;
13097 }
5f68f5ae 13098 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13099 gen_store_gpr(t1, rd);
13100 tcg_gen_movi_tl(t1, 8);
13101 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13102 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13103 gen_store_gpr(t1, rd+1);
3c824109
NF
13104 break;
13105 case SDP:
3c824109 13106 gen_load_gpr(t1, rd);
5f68f5ae 13107 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13108 tcg_gen_movi_tl(t1, 8);
13109 gen_op_addr_add(ctx, t0, t0, t1);
13110 gen_load_gpr(t1, rd+1);
5f68f5ae 13111 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13112 break;
13113#endif
6af0bf9c 13114 }
3c824109
NF
13115 tcg_temp_free(t0);
13116 tcg_temp_free(t1);
13117}
618b0fe9 13118
d208ac0c
LA
13119static void gen_sync(int stype)
13120{
13121 TCGBar tcg_mo = TCG_BAR_SC;
13122
13123 switch (stype) {
13124 case 0x4: /* SYNC_WMB */
13125 tcg_mo |= TCG_MO_ST_ST;
13126 break;
13127 case 0x10: /* SYNC_MB */
13128 tcg_mo |= TCG_MO_ALL;
13129 break;
13130 case 0x11: /* SYNC_ACQUIRE */
13131 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13132 break;
13133 case 0x12: /* SYNC_RELEASE */
13134 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13135 break;
13136 case 0x13: /* SYNC_RMB */
13137 tcg_mo |= TCG_MO_LD_LD;
13138 break;
13139 default:
13140 tcg_mo |= TCG_MO_ALL;
13141 break;
13142 }
13143
13144 tcg_gen_mb(tcg_mo);
13145}
13146
240ce26a 13147static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13148{
13149 int extension = (ctx->opcode >> 6) & 0x3f;
13150 int minor = (ctx->opcode >> 12) & 0xf;
13151 uint32_t mips32_op;
13152
13153 switch (extension) {
13154 case TEQ:
13155 mips32_op = OPC_TEQ;
13156 goto do_trap;
13157 case TGE:
13158 mips32_op = OPC_TGE;
13159 goto do_trap;
13160 case TGEU:
13161 mips32_op = OPC_TGEU;
13162 goto do_trap;
13163 case TLT:
13164 mips32_op = OPC_TLT;
13165 goto do_trap;
13166 case TLTU:
13167 mips32_op = OPC_TLTU;
13168 goto do_trap;
13169 case TNE:
13170 mips32_op = OPC_TNE;
13171 do_trap:
13172 gen_trap(ctx, mips32_op, rs, rt, -1);
13173 break;
13174#ifndef CONFIG_USER_ONLY
13175 case MFC0:
13176 case MFC0 + 32:
2e15497c 13177 check_cp0_enabled(ctx);
3c824109
NF
13178 if (rt == 0) {
13179 /* Treat as NOP. */
13180 break;
13181 }
d75c135e 13182 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13183 break;
13184 case MTC0:
13185 case MTC0 + 32:
2e15497c 13186 check_cp0_enabled(ctx);
3c824109
NF
13187 {
13188 TCGv t0 = tcg_temp_new();
618b0fe9 13189
3c824109 13190 gen_load_gpr(t0, rt);
d75c135e 13191 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13192 tcg_temp_free(t0);
13193 }
13194 break;
13195#endif
a1fc6246
LA
13196 case 0x2a:
13197 switch (minor & 3) {
13198 case MADD_ACC:
13199 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13200 break;
13201 case MADDU_ACC:
13202 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13203 break;
13204 case MSUB_ACC:
13205 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13206 break;
13207 case MSUBU_ACC:
13208 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13209 break;
13210 default:
13211 goto pool32axf_invalid;
13212 }
13213 break;
13214 case 0x32:
13215 switch (minor & 3) {
13216 case MULT_ACC:
13217 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13218 break;
13219 case MULTU_ACC:
13220 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13221 break;
13222 default:
13223 goto pool32axf_invalid;
13224 }
13225 break;
3c824109
NF
13226 case 0x2c:
13227 switch (minor) {
e0332095
YK
13228 case BITSWAP:
13229 check_insn(ctx, ISA_MIPS32R6);
13230 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13231 break;
3c824109
NF
13232 case SEB:
13233 gen_bshfl(ctx, OPC_SEB, rs, rt);
13234 break;
13235 case SEH:
13236 gen_bshfl(ctx, OPC_SEH, rs, rt);
13237 break;
13238 case CLO:
13239 mips32_op = OPC_CLO;
13240 goto do_cl;
13241 case CLZ:
13242 mips32_op = OPC_CLZ;
13243 do_cl:
d75c135e 13244 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13245 gen_cl(ctx, mips32_op, rt, rs);
13246 break;
13247 case RDHWR:
b00c7218
YK
13248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13249 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13250 break;
13251 case WSBH:
13252 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13253 break;
13254 case MULT:
9e8f441a 13255 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13256 mips32_op = OPC_MULT;
26135ead 13257 goto do_mul;
3c824109 13258 case MULTU:
9e8f441a 13259 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13260 mips32_op = OPC_MULTU;
26135ead 13261 goto do_mul;
3c824109 13262 case DIV:
9e8f441a 13263 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13264 mips32_op = OPC_DIV;
26135ead 13265 goto do_div;
3c824109 13266 case DIVU:
9e8f441a 13267 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13268 mips32_op = OPC_DIVU;
26135ead
RS
13269 goto do_div;
13270 do_div:
13271 check_insn(ctx, ISA_MIPS32);
13272 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13273 break;
3c824109 13274 case MADD:
9e8f441a 13275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13276 mips32_op = OPC_MADD;
26135ead 13277 goto do_mul;
3c824109 13278 case MADDU:
9e8f441a 13279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13280 mips32_op = OPC_MADDU;
26135ead 13281 goto do_mul;
3c824109 13282 case MSUB:
9e8f441a 13283 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13284 mips32_op = OPC_MSUB;
26135ead 13285 goto do_mul;
3c824109 13286 case MSUBU:
9e8f441a 13287 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13288 mips32_op = OPC_MSUBU;
26135ead 13289 do_mul:
d75c135e 13290 check_insn(ctx, ISA_MIPS32);
a1fc6246 13291 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13292 break;
13293 default:
13294 goto pool32axf_invalid;
13295 }
13296 break;
13297 case 0x34:
13298 switch (minor) {
13299 case MFC2:
13300 case MTC2:
13301 case MFHC2:
13302 case MTHC2:
13303 case CFC2:
13304 case CTC2:
13305 generate_exception_err(ctx, EXCP_CpU, 2);
13306 break;
13307 default:
13308 goto pool32axf_invalid;
13309 }
13310 break;
13311 case 0x3c:
13312 switch (minor) {
65935f07
YK
13313 case JALR: /* JALRC */
13314 case JALR_HB: /* JALRC_HB */
13315 if (ctx->insn_flags & ISA_MIPS32R6) {
13316 /* JALRC, JALRC_HB */
13317 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13318 } else {
13319 /* JALR, JALR_HB */
13320 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13321 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13322 }
3c824109
NF
13323 break;
13324 case JALRS:
13325 case JALRS_HB:
9e8f441a 13326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13327 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13328 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13329 break;
13330 default:
13331 goto pool32axf_invalid;
13332 }
13333 break;
13334 case 0x05:
13335 switch (minor) {
13336 case RDPGPR:
2e15497c 13337 check_cp0_enabled(ctx);
d75c135e 13338 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13339 gen_load_srsgpr(rs, rt);
3c824109
NF
13340 break;
13341 case WRPGPR:
2e15497c 13342 check_cp0_enabled(ctx);
d75c135e 13343 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13344 gen_store_srsgpr(rs, rt);
3c824109
NF
13345 break;
13346 default:
13347 goto pool32axf_invalid;
13348 }
13349 break;
13350#ifndef CONFIG_USER_ONLY
13351 case 0x0d:
13352 switch (minor) {
13353 case TLBP:
13354 mips32_op = OPC_TLBP;
13355 goto do_cp0;
13356 case TLBR:
13357 mips32_op = OPC_TLBR;
13358 goto do_cp0;
13359 case TLBWI:
13360 mips32_op = OPC_TLBWI;
13361 goto do_cp0;
13362 case TLBWR:
13363 mips32_op = OPC_TLBWR;
13364 goto do_cp0;
e60ec063
YK
13365 case TLBINV:
13366 mips32_op = OPC_TLBINV;
13367 goto do_cp0;
13368 case TLBINVF:
13369 mips32_op = OPC_TLBINVF;
13370 goto do_cp0;
3c824109
NF
13371 case WAIT:
13372 mips32_op = OPC_WAIT;
13373 goto do_cp0;
13374 case DERET:
13375 mips32_op = OPC_DERET;
13376 goto do_cp0;
13377 case ERET:
13378 mips32_op = OPC_ERET;
13379 do_cp0:
13380 gen_cp0(env, ctx, mips32_op, rt, rs);
13381 break;
13382 default:
13383 goto pool32axf_invalid;
13384 }
13385 break;
13386 case 0x1d:
13387 switch (minor) {
13388 case DI:
2e15497c 13389 check_cp0_enabled(ctx);
3c824109
NF
13390 {
13391 TCGv t0 = tcg_temp_new();
13392
13393 save_cpu_state(ctx, 1);
895c2d04 13394 gen_helper_di(t0, cpu_env);
3c824109
NF
13395 gen_store_gpr(t0, rs);
13396 /* Stop translation as we may have switched the execution mode */
13397 ctx->bstate = BS_STOP;
13398 tcg_temp_free(t0);
13399 }
13400 break;
13401 case EI:
2e15497c 13402 check_cp0_enabled(ctx);
3c824109
NF
13403 {
13404 TCGv t0 = tcg_temp_new();
13405
13406 save_cpu_state(ctx, 1);
895c2d04 13407 gen_helper_ei(t0, cpu_env);
3c824109
NF
13408 gen_store_gpr(t0, rs);
13409 /* Stop translation as we may have switched the execution mode */
13410 ctx->bstate = BS_STOP;
13411 tcg_temp_free(t0);
13412 }
13413 break;
13414 default:
13415 goto pool32axf_invalid;
13416 }
13417 break;
13418#endif
13419 case 0x2d:
13420 switch (minor) {
13421 case SYNC:
d208ac0c 13422 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13423 break;
13424 case SYSCALL:
9c708c7f 13425 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13426 break;
13427 case SDBBP:
3b3c1694
LA
13428 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13429 gen_helper_do_semihosting(cpu_env);
13430 } else {
13431 check_insn(ctx, ISA_MIPS32);
e0332095 13432 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13433 generate_exception_end(ctx, EXCP_RI);
e0332095 13434 } else {
9c708c7f 13435 generate_exception_end(ctx, EXCP_DBp);
e0332095 13436 }
3b3c1694 13437 }
3c824109
NF
13438 break;
13439 default:
13440 goto pool32axf_invalid;
13441 }
13442 break;
a1fc6246 13443 case 0x01:
26135ead 13444 switch (minor & 3) {
a1fc6246 13445 case MFHI_ACC:
26135ead 13446 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13447 break;
a1fc6246 13448 case MFLO_ACC:
26135ead 13449 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13450 break;
a1fc6246 13451 case MTHI_ACC:
26135ead 13452 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13453 break;
a1fc6246 13454 case MTLO_ACC:
26135ead 13455 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13456 break;
13457 default:
13458 goto pool32axf_invalid;
13459 }
13460 break;
a1fc6246 13461 case 0x35:
9e8f441a 13462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13463 switch (minor) {
13464 case MFHI32:
13465 gen_HILO(ctx, OPC_MFHI, 0, rs);
13466 break;
13467 case MFLO32:
13468 gen_HILO(ctx, OPC_MFLO, 0, rs);
13469 break;
13470 case MTHI32:
13471 gen_HILO(ctx, OPC_MTHI, 0, rs);
13472 break;
13473 case MTLO32:
13474 gen_HILO(ctx, OPC_MTLO, 0, rs);
13475 break;
13476 default:
13477 goto pool32axf_invalid;
13478 }
13479 break;
3c824109
NF
13480 default:
13481 pool32axf_invalid:
13482 MIPS_INVAL("pool32axf");
9c708c7f 13483 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13484 break;
13485 }
13486}
13487
13488/* Values for microMIPS fmt field. Variable-width, depending on which
13489 formats the instruction supports. */
13490
13491enum {
13492 FMT_SD_S = 0,
13493 FMT_SD_D = 1,
13494
13495 FMT_SDPS_S = 0,
13496 FMT_SDPS_D = 1,
13497 FMT_SDPS_PS = 2,
13498
13499 FMT_SWL_S = 0,
13500 FMT_SWL_W = 1,
13501 FMT_SWL_L = 2,
13502
13503 FMT_DWL_D = 0,
13504 FMT_DWL_W = 1,
13505 FMT_DWL_L = 2
13506};
13507
d75c135e 13508static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13509{
13510 int extension = (ctx->opcode >> 6) & 0x3ff;
13511 uint32_t mips32_op;
13512
13513#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13514#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13515#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13516
13517 switch (extension) {
13518 case FLOAT_1BIT_FMT(CFC1, 0):
13519 mips32_op = OPC_CFC1;
13520 goto do_cp1;
13521 case FLOAT_1BIT_FMT(CTC1, 0):
13522 mips32_op = OPC_CTC1;
13523 goto do_cp1;
13524 case FLOAT_1BIT_FMT(MFC1, 0):
13525 mips32_op = OPC_MFC1;
13526 goto do_cp1;
13527 case FLOAT_1BIT_FMT(MTC1, 0):
13528 mips32_op = OPC_MTC1;
13529 goto do_cp1;
13530 case FLOAT_1BIT_FMT(MFHC1, 0):
13531 mips32_op = OPC_MFHC1;
13532 goto do_cp1;
13533 case FLOAT_1BIT_FMT(MTHC1, 0):
13534 mips32_op = OPC_MTHC1;
13535 do_cp1:
13536 gen_cp1(ctx, mips32_op, rt, rs);
13537 break;
13538
13539 /* Reciprocal square root */
13540 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13541 mips32_op = OPC_RSQRT_S;
13542 goto do_unaryfp;
13543 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13544 mips32_op = OPC_RSQRT_D;
13545 goto do_unaryfp;
13546
13547 /* Square root */
13548 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13549 mips32_op = OPC_SQRT_S;
13550 goto do_unaryfp;
13551 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13552 mips32_op = OPC_SQRT_D;
13553 goto do_unaryfp;
13554
13555 /* Reciprocal */
13556 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13557 mips32_op = OPC_RECIP_S;
13558 goto do_unaryfp;
13559 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13560 mips32_op = OPC_RECIP_D;
13561 goto do_unaryfp;
13562
13563 /* Floor */
13564 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13565 mips32_op = OPC_FLOOR_L_S;
13566 goto do_unaryfp;
13567 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13568 mips32_op = OPC_FLOOR_L_D;
13569 goto do_unaryfp;
13570 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13571 mips32_op = OPC_FLOOR_W_S;
13572 goto do_unaryfp;
13573 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13574 mips32_op = OPC_FLOOR_W_D;
13575 goto do_unaryfp;
13576
13577 /* Ceiling */
13578 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13579 mips32_op = OPC_CEIL_L_S;
13580 goto do_unaryfp;
13581 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13582 mips32_op = OPC_CEIL_L_D;
13583 goto do_unaryfp;
13584 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13585 mips32_op = OPC_CEIL_W_S;
13586 goto do_unaryfp;
13587 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13588 mips32_op = OPC_CEIL_W_D;
13589 goto do_unaryfp;
13590
13591 /* Truncation */
13592 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13593 mips32_op = OPC_TRUNC_L_S;
13594 goto do_unaryfp;
13595 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13596 mips32_op = OPC_TRUNC_L_D;
13597 goto do_unaryfp;
13598 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13599 mips32_op = OPC_TRUNC_W_S;
13600 goto do_unaryfp;
13601 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13602 mips32_op = OPC_TRUNC_W_D;
13603 goto do_unaryfp;
13604
13605 /* Round */
13606 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13607 mips32_op = OPC_ROUND_L_S;
13608 goto do_unaryfp;
13609 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13610 mips32_op = OPC_ROUND_L_D;
13611 goto do_unaryfp;
13612 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13613 mips32_op = OPC_ROUND_W_S;
13614 goto do_unaryfp;
13615 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13616 mips32_op = OPC_ROUND_W_D;
13617 goto do_unaryfp;
13618
13619 /* Integer to floating-point conversion */
13620 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13621 mips32_op = OPC_CVT_L_S;
13622 goto do_unaryfp;
13623 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13624 mips32_op = OPC_CVT_L_D;
13625 goto do_unaryfp;
13626 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13627 mips32_op = OPC_CVT_W_S;
13628 goto do_unaryfp;
13629 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13630 mips32_op = OPC_CVT_W_D;
13631 goto do_unaryfp;
13632
13633 /* Paired-foo conversions */
13634 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13635 mips32_op = OPC_CVT_S_PL;
13636 goto do_unaryfp;
13637 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13638 mips32_op = OPC_CVT_S_PU;
13639 goto do_unaryfp;
13640 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13641 mips32_op = OPC_CVT_PW_PS;
13642 goto do_unaryfp;
13643 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13644 mips32_op = OPC_CVT_PS_PW;
13645 goto do_unaryfp;
13646
13647 /* Floating-point moves */
13648 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13649 mips32_op = OPC_MOV_S;
13650 goto do_unaryfp;
13651 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13652 mips32_op = OPC_MOV_D;
13653 goto do_unaryfp;
13654 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13655 mips32_op = OPC_MOV_PS;
13656 goto do_unaryfp;
13657
13658 /* Absolute value */
13659 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13660 mips32_op = OPC_ABS_S;
13661 goto do_unaryfp;
13662 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13663 mips32_op = OPC_ABS_D;
13664 goto do_unaryfp;
13665 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13666 mips32_op = OPC_ABS_PS;
13667 goto do_unaryfp;
13668
13669 /* Negation */
13670 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13671 mips32_op = OPC_NEG_S;
13672 goto do_unaryfp;
13673 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13674 mips32_op = OPC_NEG_D;
13675 goto do_unaryfp;
13676 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13677 mips32_op = OPC_NEG_PS;
13678 goto do_unaryfp;
13679
13680 /* Reciprocal square root step */
13681 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13682 mips32_op = OPC_RSQRT1_S;
13683 goto do_unaryfp;
13684 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13685 mips32_op = OPC_RSQRT1_D;
13686 goto do_unaryfp;
13687 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13688 mips32_op = OPC_RSQRT1_PS;
13689 goto do_unaryfp;
13690
13691 /* Reciprocal step */
13692 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13693 mips32_op = OPC_RECIP1_S;
13694 goto do_unaryfp;
13695 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13696 mips32_op = OPC_RECIP1_S;
13697 goto do_unaryfp;
13698 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13699 mips32_op = OPC_RECIP1_PS;
13700 goto do_unaryfp;
13701
13702 /* Conversions from double */
13703 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13704 mips32_op = OPC_CVT_D_S;
13705 goto do_unaryfp;
13706 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13707 mips32_op = OPC_CVT_D_W;
13708 goto do_unaryfp;
13709 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13710 mips32_op = OPC_CVT_D_L;
13711 goto do_unaryfp;
13712
13713 /* Conversions from single */
13714 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13715 mips32_op = OPC_CVT_S_D;
13716 goto do_unaryfp;
13717 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13718 mips32_op = OPC_CVT_S_W;
13719 goto do_unaryfp;
13720 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13721 mips32_op = OPC_CVT_S_L;
13722 do_unaryfp:
13723 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13724 break;
13725
13726 /* Conditional moves on floating-point codes */
13727 case COND_FLOAT_MOV(MOVT, 0):
13728 case COND_FLOAT_MOV(MOVT, 1):
13729 case COND_FLOAT_MOV(MOVT, 2):
13730 case COND_FLOAT_MOV(MOVT, 3):
13731 case COND_FLOAT_MOV(MOVT, 4):
13732 case COND_FLOAT_MOV(MOVT, 5):
13733 case COND_FLOAT_MOV(MOVT, 6):
13734 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13736 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13737 break;
13738 case COND_FLOAT_MOV(MOVF, 0):
13739 case COND_FLOAT_MOV(MOVF, 1):
13740 case COND_FLOAT_MOV(MOVF, 2):
13741 case COND_FLOAT_MOV(MOVF, 3):
13742 case COND_FLOAT_MOV(MOVF, 4):
13743 case COND_FLOAT_MOV(MOVF, 5):
13744 case COND_FLOAT_MOV(MOVF, 6):
13745 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13746 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13747 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13748 break;
13749 default:
13750 MIPS_INVAL("pool32fxf");
9c708c7f 13751 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13752 break;
13753 }
13754}
13755
f60eeb0c 13756static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13757{
13758 int32_t offset;
13759 uint16_t insn;
13760 int rt, rs, rd, rr;
13761 int16_t imm;
13762 uint32_t op, minor, mips32_op;
13763 uint32_t cond, fmt, cc;
13764
895c2d04 13765 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13766 ctx->opcode = (ctx->opcode << 16) | insn;
13767
13768 rt = (ctx->opcode >> 21) & 0x1f;
13769 rs = (ctx->opcode >> 16) & 0x1f;
13770 rd = (ctx->opcode >> 11) & 0x1f;
13771 rr = (ctx->opcode >> 6) & 0x1f;
13772 imm = (int16_t) ctx->opcode;
13773
13774 op = (ctx->opcode >> 26) & 0x3f;
13775 switch (op) {
13776 case POOL32A:
13777 minor = ctx->opcode & 0x3f;
13778 switch (minor) {
13779 case 0x00:
13780 minor = (ctx->opcode >> 6) & 0xf;
13781 switch (minor) {
13782 case SLL32:
13783 mips32_op = OPC_SLL;
13784 goto do_shifti;
13785 case SRA:
13786 mips32_op = OPC_SRA;
13787 goto do_shifti;
13788 case SRL32:
13789 mips32_op = OPC_SRL;
13790 goto do_shifti;
13791 case ROTR:
13792 mips32_op = OPC_ROTR;
13793 do_shifti:
d75c135e 13794 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13795 break;
e0332095
YK
13796 case SELEQZ:
13797 check_insn(ctx, ISA_MIPS32R6);
13798 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13799 break;
13800 case SELNEZ:
13801 check_insn(ctx, ISA_MIPS32R6);
13802 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13803 break;
b00c7218
YK
13804 case R6_RDHWR:
13805 check_insn(ctx, ISA_MIPS32R6);
13806 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13807 break;
3c824109
NF
13808 default:
13809 goto pool32a_invalid;
13810 }
13811 break;
13812 case 0x10:
13813 minor = (ctx->opcode >> 6) & 0xf;
13814 switch (minor) {
13815 /* Arithmetic */
13816 case ADD:
13817 mips32_op = OPC_ADD;
13818 goto do_arith;
13819 case ADDU32:
13820 mips32_op = OPC_ADDU;
13821 goto do_arith;
13822 case SUB:
13823 mips32_op = OPC_SUB;
13824 goto do_arith;
13825 case SUBU32:
13826 mips32_op = OPC_SUBU;
13827 goto do_arith;
13828 case MUL:
9e8f441a 13829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13830 mips32_op = OPC_MUL;
13831 do_arith:
d75c135e 13832 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13833 break;
13834 /* Shifts */
13835 case SLLV:
13836 mips32_op = OPC_SLLV;
13837 goto do_shift;
13838 case SRLV:
13839 mips32_op = OPC_SRLV;
13840 goto do_shift;
13841 case SRAV:
13842 mips32_op = OPC_SRAV;
13843 goto do_shift;
13844 case ROTRV:
13845 mips32_op = OPC_ROTRV;
13846 do_shift:
d75c135e 13847 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13848 break;
13849 /* Logical operations */
13850 case AND:
13851 mips32_op = OPC_AND;
13852 goto do_logic;
13853 case OR32:
13854 mips32_op = OPC_OR;
13855 goto do_logic;
13856 case NOR:
13857 mips32_op = OPC_NOR;
13858 goto do_logic;
13859 case XOR32:
13860 mips32_op = OPC_XOR;
13861 do_logic:
d75c135e 13862 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13863 break;
13864 /* Set less than */
13865 case SLT:
13866 mips32_op = OPC_SLT;
13867 goto do_slt;
13868 case SLTU:
13869 mips32_op = OPC_SLTU;
13870 do_slt:
d75c135e 13871 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13872 break;
13873 default:
13874 goto pool32a_invalid;
13875 }
13876 break;
13877 case 0x18:
13878 minor = (ctx->opcode >> 6) & 0xf;
13879 switch (minor) {
13880 /* Conditional moves */
e0332095
YK
13881 case MOVN: /* MUL */
13882 if (ctx->insn_flags & ISA_MIPS32R6) {
13883 /* MUL */
13884 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13885 } else {
13886 /* MOVN */
13887 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13888 }
13889 break;
13890 case MOVZ: /* MUH */
13891 if (ctx->insn_flags & ISA_MIPS32R6) {
13892 /* MUH */
13893 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13894 } else {
13895 /* MOVZ */
13896 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13897 }
13898 break;
13899 case MULU:
13900 check_insn(ctx, ISA_MIPS32R6);
13901 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13902 break;
13903 case MUHU:
13904 check_insn(ctx, ISA_MIPS32R6);
13905 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13906 break;
13907 case LWXS: /* DIV */
13908 if (ctx->insn_flags & ISA_MIPS32R6) {
13909 /* DIV */
13910 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13911 } else {
13912 /* LWXS */
13913 gen_ldxs(ctx, rs, rt, rd);
13914 }
13915 break;
13916 case MOD:
13917 check_insn(ctx, ISA_MIPS32R6);
13918 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13919 break;
13920 case R6_DIVU:
13921 check_insn(ctx, ISA_MIPS32R6);
13922 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13923 break;
e0332095
YK
13924 case MODU:
13925 check_insn(ctx, ISA_MIPS32R6);
13926 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13927 break;
13928 default:
13929 goto pool32a_invalid;
13930 }
13931 break;
13932 case INS:
13933 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13934 return;
e0332095
YK
13935 case LSA:
13936 check_insn(ctx, ISA_MIPS32R6);
13937 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13938 extract32(ctx->opcode, 9, 2));
13939 break;
13940 case ALIGN:
13941 check_insn(ctx, ISA_MIPS32R6);
13942 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13943 extract32(ctx->opcode, 9, 2));
13944 break;
3c824109
NF
13945 case EXT:
13946 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13947 return;
13948 case POOL32AXF:
240ce26a 13949 gen_pool32axf(env, ctx, rt, rs);
3c824109 13950 break;
dbd8af98 13951 case BREAK32:
9c708c7f 13952 generate_exception_end(ctx, EXCP_BREAK);
3c824109 13953 break;
bb238210
YK
13954 case SIGRIE:
13955 check_insn(ctx, ISA_MIPS32R6);
13956 generate_exception_end(ctx, EXCP_RI);
13957 break;
3c824109
NF
13958 default:
13959 pool32a_invalid:
13960 MIPS_INVAL("pool32a");
9c708c7f 13961 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13962 break;
13963 }
13964 break;
13965 case POOL32B:
13966 minor = (ctx->opcode >> 12) & 0xf;
13967 switch (minor) {
13968 case CACHE:
2e15497c 13969 check_cp0_enabled(ctx);
0d74a222
LA
13970 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13971 gen_cache_operation(ctx, rt, rs, imm);
13972 }
3c824109
NF
13973 break;
13974 case LWC2:
13975 case SWC2:
13976 /* COP2: Not implemented. */
13977 generate_exception_err(ctx, EXCP_CpU, 2);
13978 break;
3c824109
NF
13979#ifdef TARGET_MIPS64
13980 case LDP:
13981 case SDP:
d9224450
MR
13982 check_insn(ctx, ISA_MIPS3);
13983 check_mips_64(ctx);
13984 /* Fallthrough */
3c824109 13985#endif
d9224450
MR
13986 case LWP:
13987 case SWP:
3c824109
NF
13988 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13989 break;
3c824109
NF
13990#ifdef TARGET_MIPS64
13991 case LDM:
13992 case SDM:
d9224450
MR
13993 check_insn(ctx, ISA_MIPS3);
13994 check_mips_64(ctx);
13995 /* Fallthrough */
3c824109 13996#endif
d9224450
MR
13997 case LWM32:
13998 case SWM32:
3c824109
NF
13999 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14000 break;
14001 default:
14002 MIPS_INVAL("pool32b");
9c708c7f 14003 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14004 break;
14005 }
14006 break;
14007 case POOL32F:
5ab5c041 14008 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14009 minor = ctx->opcode & 0x3f;
14010 check_cp1_enabled(ctx);
14011 switch (minor) {
14012 case ALNV_PS:
9e8f441a 14013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14014 mips32_op = OPC_ALNV_PS;
14015 goto do_madd;
14016 case MADD_S:
9e8f441a 14017 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14018 mips32_op = OPC_MADD_S;
14019 goto do_madd;
14020 case MADD_D:
9e8f441a 14021 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14022 mips32_op = OPC_MADD_D;
14023 goto do_madd;
14024 case MADD_PS:
9e8f441a 14025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14026 mips32_op = OPC_MADD_PS;
14027 goto do_madd;
14028 case MSUB_S:
9e8f441a 14029 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14030 mips32_op = OPC_MSUB_S;
14031 goto do_madd;
14032 case MSUB_D:
9e8f441a 14033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14034 mips32_op = OPC_MSUB_D;
14035 goto do_madd;
14036 case MSUB_PS:
9e8f441a 14037 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14038 mips32_op = OPC_MSUB_PS;
14039 goto do_madd;
14040 case NMADD_S:
9e8f441a 14041 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14042 mips32_op = OPC_NMADD_S;
14043 goto do_madd;
14044 case NMADD_D:
9e8f441a 14045 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14046 mips32_op = OPC_NMADD_D;
14047 goto do_madd;
14048 case NMADD_PS:
9e8f441a 14049 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14050 mips32_op = OPC_NMADD_PS;
14051 goto do_madd;
14052 case NMSUB_S:
9e8f441a 14053 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14054 mips32_op = OPC_NMSUB_S;
14055 goto do_madd;
14056 case NMSUB_D:
9e8f441a 14057 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14058 mips32_op = OPC_NMSUB_D;
14059 goto do_madd;
14060 case NMSUB_PS:
9e8f441a 14061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14062 mips32_op = OPC_NMSUB_PS;
14063 do_madd:
14064 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14065 break;
14066 case CABS_COND_FMT:
9e8f441a 14067 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14068 cond = (ctx->opcode >> 6) & 0xf;
14069 cc = (ctx->opcode >> 13) & 0x7;
14070 fmt = (ctx->opcode >> 10) & 0x3;
14071 switch (fmt) {
14072 case 0x0:
14073 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14074 break;
14075 case 0x1:
14076 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14077 break;
14078 case 0x2:
14079 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14080 break;
14081 default:
14082 goto pool32f_invalid;
14083 }
14084 break;
14085 case C_COND_FMT:
9e8f441a 14086 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14087 cond = (ctx->opcode >> 6) & 0xf;
14088 cc = (ctx->opcode >> 13) & 0x7;
14089 fmt = (ctx->opcode >> 10) & 0x3;
14090 switch (fmt) {
14091 case 0x0:
14092 gen_cmp_s(ctx, cond, rt, rs, cc);
14093 break;
14094 case 0x1:
14095 gen_cmp_d(ctx, cond, rt, rs, cc);
14096 break;
14097 case 0x2:
14098 gen_cmp_ps(ctx, cond, rt, rs, cc);
14099 break;
14100 default:
14101 goto pool32f_invalid;
14102 }
14103 break;
2a24a7ba
YK
14104 case CMP_CONDN_S:
14105 check_insn(ctx, ISA_MIPS32R6);
14106 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14107 break;
14108 case CMP_CONDN_D:
14109 check_insn(ctx, ISA_MIPS32R6);
14110 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14111 break;
3c824109 14112 case POOL32FXF:
d75c135e 14113 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14114 break;
14115 case 0x00:
14116 /* PLL foo */
14117 switch ((ctx->opcode >> 6) & 0x7) {
14118 case PLL_PS:
14119 mips32_op = OPC_PLL_PS;
14120 goto do_ps;
14121 case PLU_PS:
14122 mips32_op = OPC_PLU_PS;
14123 goto do_ps;
14124 case PUL_PS:
14125 mips32_op = OPC_PUL_PS;
14126 goto do_ps;
14127 case PUU_PS:
14128 mips32_op = OPC_PUU_PS;
14129 goto do_ps;
14130 case CVT_PS_S:
9e8f441a 14131 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14132 mips32_op = OPC_CVT_PS_S;
14133 do_ps:
14134 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14135 break;
14136 default:
14137 goto pool32f_invalid;
14138 }
14139 break;
2a24a7ba
YK
14140 case MIN_FMT:
14141 check_insn(ctx, ISA_MIPS32R6);
14142 switch ((ctx->opcode >> 9) & 0x3) {
14143 case FMT_SDPS_S:
14144 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14145 break;
14146 case FMT_SDPS_D:
14147 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14148 break;
14149 default:
14150 goto pool32f_invalid;
14151 }
14152 break;
3c824109
NF
14153 case 0x08:
14154 /* [LS][WDU]XC1 */
14155 switch ((ctx->opcode >> 6) & 0x7) {
14156 case LWXC1:
9e8f441a 14157 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14158 mips32_op = OPC_LWXC1;
14159 goto do_ldst_cp1;
14160 case SWXC1:
9e8f441a 14161 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14162 mips32_op = OPC_SWXC1;
14163 goto do_ldst_cp1;
14164 case LDXC1:
9e8f441a 14165 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14166 mips32_op = OPC_LDXC1;
14167 goto do_ldst_cp1;
14168 case SDXC1:
9e8f441a 14169 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14170 mips32_op = OPC_SDXC1;
14171 goto do_ldst_cp1;
14172 case LUXC1:
9e8f441a 14173 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14174 mips32_op = OPC_LUXC1;
14175 goto do_ldst_cp1;
14176 case SUXC1:
9e8f441a 14177 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14178 mips32_op = OPC_SUXC1;
14179 do_ldst_cp1:
14180 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14181 break;
14182 default:
14183 goto pool32f_invalid;
14184 }
14185 break;
2a24a7ba
YK
14186 case MAX_FMT:
14187 check_insn(ctx, ISA_MIPS32R6);
14188 switch ((ctx->opcode >> 9) & 0x3) {
14189 case FMT_SDPS_S:
14190 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14191 break;
14192 case FMT_SDPS_D:
14193 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14194 break;
14195 default:
14196 goto pool32f_invalid;
14197 }
14198 break;
3c824109
NF
14199 case 0x18:
14200 /* 3D insns */
9e8f441a 14201 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14202 fmt = (ctx->opcode >> 9) & 0x3;
14203 switch ((ctx->opcode >> 6) & 0x7) {
14204 case RSQRT2_FMT:
14205 switch (fmt) {
14206 case FMT_SDPS_S:
14207 mips32_op = OPC_RSQRT2_S;
14208 goto do_3d;
14209 case FMT_SDPS_D:
14210 mips32_op = OPC_RSQRT2_D;
14211 goto do_3d;
14212 case FMT_SDPS_PS:
14213 mips32_op = OPC_RSQRT2_PS;
14214 goto do_3d;
14215 default:
14216 goto pool32f_invalid;
14217 }
14218 break;
14219 case RECIP2_FMT:
14220 switch (fmt) {
14221 case FMT_SDPS_S:
14222 mips32_op = OPC_RECIP2_S;
14223 goto do_3d;
14224 case FMT_SDPS_D:
14225 mips32_op = OPC_RECIP2_D;
14226 goto do_3d;
14227 case FMT_SDPS_PS:
14228 mips32_op = OPC_RECIP2_PS;
14229 goto do_3d;
14230 default:
14231 goto pool32f_invalid;
14232 }
14233 break;
14234 case ADDR_PS:
14235 mips32_op = OPC_ADDR_PS;
14236 goto do_3d;
14237 case MULR_PS:
14238 mips32_op = OPC_MULR_PS;
14239 do_3d:
14240 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14241 break;
14242 default:
14243 goto pool32f_invalid;
14244 }
14245 break;
14246 case 0x20:
2a24a7ba 14247 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14248 cc = (ctx->opcode >> 13) & 0x7;
14249 fmt = (ctx->opcode >> 9) & 0x3;
14250 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14251 case MOVF_FMT: /* RINT_FMT */
14252 if (ctx->insn_flags & ISA_MIPS32R6) {
14253 /* RINT_FMT */
14254 switch (fmt) {
14255 case FMT_SDPS_S:
14256 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14257 break;
14258 case FMT_SDPS_D:
14259 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14260 break;
14261 default:
14262 goto pool32f_invalid;
14263 }
14264 } else {
14265 /* MOVF_FMT */
14266 switch (fmt) {
14267 case FMT_SDPS_S:
14268 gen_movcf_s(ctx, rs, rt, cc, 0);
14269 break;
14270 case FMT_SDPS_D:
14271 gen_movcf_d(ctx, rs, rt, cc, 0);
14272 break;
14273 case FMT_SDPS_PS:
14274 check_ps(ctx);
14275 gen_movcf_ps(ctx, rs, rt, cc, 0);
14276 break;
14277 default:
14278 goto pool32f_invalid;
14279 }
3c824109
NF
14280 }
14281 break;
2a24a7ba
YK
14282 case MOVT_FMT: /* CLASS_FMT */
14283 if (ctx->insn_flags & ISA_MIPS32R6) {
14284 /* CLASS_FMT */
14285 switch (fmt) {
14286 case FMT_SDPS_S:
14287 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14288 break;
14289 case FMT_SDPS_D:
14290 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14291 break;
14292 default:
14293 goto pool32f_invalid;
14294 }
14295 } else {
14296 /* MOVT_FMT */
14297 switch (fmt) {
14298 case FMT_SDPS_S:
14299 gen_movcf_s(ctx, rs, rt, cc, 1);
14300 break;
14301 case FMT_SDPS_D:
14302 gen_movcf_d(ctx, rs, rt, cc, 1);
14303 break;
14304 case FMT_SDPS_PS:
14305 check_ps(ctx);
14306 gen_movcf_ps(ctx, rs, rt, cc, 1);
14307 break;
14308 default:
14309 goto pool32f_invalid;
14310 }
3c824109
NF
14311 }
14312 break;
14313 case PREFX:
9e8f441a 14314 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14315 break;
14316 default:
14317 goto pool32f_invalid;
14318 }
14319 break;
14320#define FINSN_3ARG_SDPS(prfx) \
14321 switch ((ctx->opcode >> 8) & 0x3) { \
14322 case FMT_SDPS_S: \
14323 mips32_op = OPC_##prfx##_S; \
14324 goto do_fpop; \
14325 case FMT_SDPS_D: \
14326 mips32_op = OPC_##prfx##_D; \
14327 goto do_fpop; \
14328 case FMT_SDPS_PS: \
e29c9628 14329 check_ps(ctx); \
3c824109
NF
14330 mips32_op = OPC_##prfx##_PS; \
14331 goto do_fpop; \
14332 default: \
14333 goto pool32f_invalid; \
14334 }
2a24a7ba
YK
14335 case MINA_FMT:
14336 check_insn(ctx, ISA_MIPS32R6);
14337 switch ((ctx->opcode >> 9) & 0x3) {
14338 case FMT_SDPS_S:
14339 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14340 break;
14341 case FMT_SDPS_D:
14342 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14343 break;
14344 default:
14345 goto pool32f_invalid;
14346 }
14347 break;
14348 case MAXA_FMT:
14349 check_insn(ctx, ISA_MIPS32R6);
14350 switch ((ctx->opcode >> 9) & 0x3) {
14351 case FMT_SDPS_S:
14352 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14353 break;
14354 case FMT_SDPS_D:
14355 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14356 break;
14357 default:
14358 goto pool32f_invalid;
14359 }
14360 break;
3c824109
NF
14361 case 0x30:
14362 /* regular FP ops */
14363 switch ((ctx->opcode >> 6) & 0x3) {
14364 case ADD_FMT:
14365 FINSN_3ARG_SDPS(ADD);
14366 break;
14367 case SUB_FMT:
14368 FINSN_3ARG_SDPS(SUB);
14369 break;
14370 case MUL_FMT:
14371 FINSN_3ARG_SDPS(MUL);
14372 break;
14373 case DIV_FMT:
14374 fmt = (ctx->opcode >> 8) & 0x3;
14375 if (fmt == 1) {
14376 mips32_op = OPC_DIV_D;
14377 } else if (fmt == 0) {
14378 mips32_op = OPC_DIV_S;
14379 } else {
14380 goto pool32f_invalid;
14381 }
14382 goto do_fpop;
14383 default:
14384 goto pool32f_invalid;
14385 }
14386 break;
14387 case 0x38:
14388 /* cmovs */
2a24a7ba
YK
14389 switch ((ctx->opcode >> 6) & 0x7) {
14390 case MOVN_FMT: /* SELNEZ_FMT */
14391 if (ctx->insn_flags & ISA_MIPS32R6) {
14392 /* SELNEZ_FMT */
14393 switch ((ctx->opcode >> 9) & 0x3) {
14394 case FMT_SDPS_S:
14395 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14396 break;
14397 case FMT_SDPS_D:
14398 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14399 break;
14400 default:
14401 goto pool32f_invalid;
14402 }
14403 } else {
14404 /* MOVN_FMT */
14405 FINSN_3ARG_SDPS(MOVN);
14406 }
14407 break;
14408 case MOVN_FMT_04:
14409 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14410 FINSN_3ARG_SDPS(MOVN);
14411 break;
2a24a7ba
YK
14412 case MOVZ_FMT: /* SELEQZ_FMT */
14413 if (ctx->insn_flags & ISA_MIPS32R6) {
14414 /* SELEQZ_FMT */
14415 switch ((ctx->opcode >> 9) & 0x3) {
14416 case FMT_SDPS_S:
14417 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14418 break;
14419 case FMT_SDPS_D:
14420 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14421 break;
14422 default:
14423 goto pool32f_invalid;
14424 }
14425 } else {
14426 /* MOVZ_FMT */
14427 FINSN_3ARG_SDPS(MOVZ);
14428 }
14429 break;
14430 case MOVZ_FMT_05:
14431 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14432 FINSN_3ARG_SDPS(MOVZ);
14433 break;
2a24a7ba
YK
14434 case SEL_FMT:
14435 check_insn(ctx, ISA_MIPS32R6);
14436 switch ((ctx->opcode >> 9) & 0x3) {
14437 case FMT_SDPS_S:
14438 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14439 break;
14440 case FMT_SDPS_D:
14441 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14442 break;
14443 default:
14444 goto pool32f_invalid;
14445 }
14446 break;
14447 case MADDF_FMT:
14448 check_insn(ctx, ISA_MIPS32R6);
14449 switch ((ctx->opcode >> 9) & 0x3) {
14450 case FMT_SDPS_S:
14451 mips32_op = OPC_MADDF_S;
14452 goto do_fpop;
14453 case FMT_SDPS_D:
14454 mips32_op = OPC_MADDF_D;
14455 goto do_fpop;
14456 default:
14457 goto pool32f_invalid;
14458 }
14459 break;
14460 case MSUBF_FMT:
14461 check_insn(ctx, ISA_MIPS32R6);
14462 switch ((ctx->opcode >> 9) & 0x3) {
14463 case FMT_SDPS_S:
14464 mips32_op = OPC_MSUBF_S;
14465 goto do_fpop;
14466 case FMT_SDPS_D:
14467 mips32_op = OPC_MSUBF_D;
14468 goto do_fpop;
14469 default:
14470 goto pool32f_invalid;
14471 }
14472 break;
3c824109
NF
14473 default:
14474 goto pool32f_invalid;
14475 }
14476 break;
14477 do_fpop:
14478 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14479 break;
14480 default:
14481 pool32f_invalid:
14482 MIPS_INVAL("pool32f");
9c708c7f 14483 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14484 break;
14485 }
14486 } else {
14487 generate_exception_err(ctx, EXCP_CpU, 1);
14488 }
14489 break;
14490 case POOL32I:
14491 minor = (ctx->opcode >> 21) & 0x1f;
14492 switch (minor) {
14493 case BLTZ:
9e8f441a 14494 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14495 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14496 break;
3c824109 14497 case BLTZAL:
9e8f441a 14498 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14499 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14500 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14501 break;
3c824109 14502 case BLTZALS:
9e8f441a 14503 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14504 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14505 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14506 break;
3c824109 14507 case BGEZ:
9e8f441a 14508 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14509 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14510 break;
3c824109 14511 case BGEZAL:
9e8f441a 14512 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14513 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14514 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14515 break;
3c824109 14516 case BGEZALS:
9e8f441a 14517 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14518 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14519 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14520 break;
3c824109 14521 case BLEZ:
9e8f441a 14522 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14523 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14524 break;
3c824109 14525 case BGTZ:
9e8f441a 14526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14527 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14528 break;
14529
14530 /* Traps */
65935f07
YK
14531 case TLTI: /* BC1EQZC */
14532 if (ctx->insn_flags & ISA_MIPS32R6) {
14533 /* BC1EQZC */
14534 check_cp1_enabled(ctx);
14535 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14536 } else {
14537 /* TLTI */
14538 mips32_op = OPC_TLTI;
14539 goto do_trapi;
14540 }
14541 break;
14542 case TGEI: /* BC1NEZC */
14543 if (ctx->insn_flags & ISA_MIPS32R6) {
14544 /* BC1NEZC */
14545 check_cp1_enabled(ctx);
14546 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14547 } else {
14548 /* TGEI */
14549 mips32_op = OPC_TGEI;
14550 goto do_trapi;
14551 }
14552 break;
3c824109 14553 case TLTIU:
9e8f441a 14554 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14555 mips32_op = OPC_TLTIU;
14556 goto do_trapi;
14557 case TGEIU:
9e8f441a 14558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14559 mips32_op = OPC_TGEIU;
14560 goto do_trapi;
3b4a5489
YK
14561 case TNEI: /* SYNCI */
14562 if (ctx->insn_flags & ISA_MIPS32R6) {
14563 /* SYNCI */
14564 /* Break the TB to be able to sync copied instructions
14565 immediately */
14566 ctx->bstate = BS_STOP;
14567 } else {
14568 /* TNEI */
14569 mips32_op = OPC_TNEI;
14570 goto do_trapi;
14571 }
14572 break;
3c824109 14573 case TEQI:
9e8f441a 14574 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14575 mips32_op = OPC_TEQI;
14576 do_trapi:
14577 gen_trap(ctx, mips32_op, rs, -1, imm);
14578 break;
14579
14580 case BNEZC:
14581 case BEQZC:
9e8f441a 14582 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14583 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14584 4, rs, 0, imm << 1, 0);
3c824109
NF
14585 /* Compact branches don't have a delay slot, so just let
14586 the normal delay slot handling take us to the branch
14587 target. */
14588 break;
14589 case LUI:
9e8f441a 14590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14591 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14592 break;
14593 case SYNCI:
9e8f441a 14594 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14595 /* Break the TB to be able to sync copied instructions
14596 immediately */
14597 ctx->bstate = BS_STOP;
3c824109
NF
14598 break;
14599 case BC2F:
14600 case BC2T:
9e8f441a 14601 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14602 /* COP2: Not implemented. */
14603 generate_exception_err(ctx, EXCP_CpU, 2);
14604 break;
14605 case BC1F:
9e8f441a 14606 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14607 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14608 goto do_cp1branch;
14609 case BC1T:
9e8f441a 14610 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14611 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14612 goto do_cp1branch;
14613 case BC1ANY4F:
9e8f441a 14614 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14615 mips32_op = OPC_BC1FANY4;
14616 goto do_cp1mips3d;
14617 case BC1ANY4T:
9e8f441a 14618 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14619 mips32_op = OPC_BC1TANY4;
14620 do_cp1mips3d:
14621 check_cop1x(ctx);
d75c135e 14622 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14623 /* Fall through */
14624 do_cp1branch:
272f458d
MR
14625 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14626 check_cp1_enabled(ctx);
14627 gen_compute_branch1(ctx, mips32_op,
14628 (ctx->opcode >> 18) & 0x7, imm << 1);
14629 } else {
14630 generate_exception_err(ctx, EXCP_CpU, 1);
14631 }
3c824109
NF
14632 break;
14633 case BPOSGE64:
14634 case BPOSGE32:
14635 /* MIPS DSP: not implemented */
14636 /* Fall through */
14637 default:
14638 MIPS_INVAL("pool32i");
9c708c7f 14639 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14640 break;
14641 }
14642 break;
14643 case POOL32C:
14644 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14645 offset = sextract32(ctx->opcode, 0,
14646 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14647 switch (minor) {
14648 case LWL:
9e8f441a 14649 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14650 mips32_op = OPC_LWL;
5c13fdfd 14651 goto do_ld_lr;
3c824109 14652 case SWL:
9e8f441a 14653 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14654 mips32_op = OPC_SWL;
5c13fdfd 14655 goto do_st_lr;
3c824109 14656 case LWR:
9e8f441a 14657 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14658 mips32_op = OPC_LWR;
5c13fdfd 14659 goto do_ld_lr;
3c824109 14660 case SWR:
9e8f441a 14661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14662 mips32_op = OPC_SWR;
5c13fdfd 14663 goto do_st_lr;
3c824109
NF
14664#if defined(TARGET_MIPS64)
14665 case LDL:
d9224450
MR
14666 check_insn(ctx, ISA_MIPS3);
14667 check_mips_64(ctx);
9e8f441a 14668 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14669 mips32_op = OPC_LDL;
5c13fdfd 14670 goto do_ld_lr;
3c824109 14671 case SDL:
d9224450
MR
14672 check_insn(ctx, ISA_MIPS3);
14673 check_mips_64(ctx);
9e8f441a 14674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14675 mips32_op = OPC_SDL;
5c13fdfd 14676 goto do_st_lr;
3c824109 14677 case LDR:
d9224450
MR
14678 check_insn(ctx, ISA_MIPS3);
14679 check_mips_64(ctx);
9e8f441a 14680 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14681 mips32_op = OPC_LDR;
5c13fdfd 14682 goto do_ld_lr;
3c824109 14683 case SDR:
d9224450
MR
14684 check_insn(ctx, ISA_MIPS3);
14685 check_mips_64(ctx);
9e8f441a 14686 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14687 mips32_op = OPC_SDR;
5c13fdfd 14688 goto do_st_lr;
3c824109 14689 case LWU:
d9224450
MR
14690 check_insn(ctx, ISA_MIPS3);
14691 check_mips_64(ctx);
3c824109 14692 mips32_op = OPC_LWU;
5c13fdfd 14693 goto do_ld_lr;
3c824109 14694 case LLD:
d9224450
MR
14695 check_insn(ctx, ISA_MIPS3);
14696 check_mips_64(ctx);
3c824109 14697 mips32_op = OPC_LLD;
5c13fdfd 14698 goto do_ld_lr;
3c824109
NF
14699#endif
14700 case LL:
14701 mips32_op = OPC_LL;
5c13fdfd
AJ
14702 goto do_ld_lr;
14703 do_ld_lr:
3b4a5489 14704 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14705 break;
14706 do_st_lr:
14707 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14708 break;
14709 case SC:
3b4a5489 14710 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14711 break;
14712#if defined(TARGET_MIPS64)
14713 case SCD:
d9224450
MR
14714 check_insn(ctx, ISA_MIPS3);
14715 check_mips_64(ctx);
3b4a5489 14716 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14717 break;
14718#endif
14719 case PREF:
14720 /* Treat as no-op */
3b4a5489
YK
14721 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14722 /* hint codes 24-31 are reserved and signal RI */
14723 generate_exception(ctx, EXCP_RI);
14724 }
3c824109
NF
14725 break;
14726 default:
14727 MIPS_INVAL("pool32c");
9c708c7f 14728 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14729 break;
14730 }
14731 break;
ab39ee45
YK
14732 case ADDI32: /* AUI, LUI */
14733 if (ctx->insn_flags & ISA_MIPS32R6) {
14734 /* AUI, LUI */
14735 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14736 } else {
14737 /* ADDI32 */
14738 mips32_op = OPC_ADDI;
14739 goto do_addi;
14740 }
14741 break;
3c824109
NF
14742 case ADDIU32:
14743 mips32_op = OPC_ADDIU;
14744 do_addi:
d75c135e 14745 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14746 break;
14747
14748 /* Logical operations */
14749 case ORI32:
14750 mips32_op = OPC_ORI;
14751 goto do_logici;
14752 case XORI32:
14753 mips32_op = OPC_XORI;
14754 goto do_logici;
14755 case ANDI32:
14756 mips32_op = OPC_ANDI;
14757 do_logici:
d75c135e 14758 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14759 break;
14760
14761 /* Set less than immediate */
14762 case SLTI32:
14763 mips32_op = OPC_SLTI;
14764 goto do_slti;
14765 case SLTIU32:
14766 mips32_op = OPC_SLTIU;
14767 do_slti:
d75c135e 14768 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14769 break;
14770 case JALX32:
9e8f441a 14771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14772 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14773 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14774 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14775 break;
65935f07
YK
14776 case JALS32: /* BOVC, BEQC, BEQZALC */
14777 if (ctx->insn_flags & ISA_MIPS32R6) {
14778 if (rs >= rt) {
14779 /* BOVC */
14780 mips32_op = OPC_BOVC;
14781 } else if (rs < rt && rs == 0) {
14782 /* BEQZALC */
14783 mips32_op = OPC_BEQZALC;
14784 } else {
14785 /* BEQC */
14786 mips32_op = OPC_BEQC;
14787 }
14788 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14789 } else {
14790 /* JALS32 */
14791 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14792 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14793 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14794 }
3c824109 14795 break;
65935f07
YK
14796 case BEQ32: /* BC */
14797 if (ctx->insn_flags & ISA_MIPS32R6) {
14798 /* BC */
14799 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14800 sextract32(ctx->opcode << 1, 0, 27));
14801 } else {
14802 /* BEQ32 */
14803 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14804 }
3c824109 14805 break;
65935f07
YK
14806 case BNE32: /* BALC */
14807 if (ctx->insn_flags & ISA_MIPS32R6) {
14808 /* BALC */
14809 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14810 sextract32(ctx->opcode << 1, 0, 27));
14811 } else {
14812 /* BNE32 */
14813 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14814 }
3c824109 14815 break;
65935f07
YK
14816 case J32: /* BGTZC, BLTZC, BLTC */
14817 if (ctx->insn_flags & ISA_MIPS32R6) {
14818 if (rs == 0 && rt != 0) {
14819 /* BGTZC */
14820 mips32_op = OPC_BGTZC;
14821 } else if (rs != 0 && rt != 0 && rs == rt) {
14822 /* BLTZC */
14823 mips32_op = OPC_BLTZC;
14824 } else {
14825 /* BLTC */
14826 mips32_op = OPC_BLTC;
14827 }
14828 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14829 } else {
14830 /* J32 */
14831 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14832 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14833 }
3c824109 14834 break;
65935f07
YK
14835 case JAL32: /* BLEZC, BGEZC, BGEC */
14836 if (ctx->insn_flags & ISA_MIPS32R6) {
14837 if (rs == 0 && rt != 0) {
14838 /* BLEZC */
14839 mips32_op = OPC_BLEZC;
14840 } else if (rs != 0 && rt != 0 && rs == rt) {
14841 /* BGEZC */
14842 mips32_op = OPC_BGEZC;
14843 } else {
14844 /* BGEC */
14845 mips32_op = OPC_BGEC;
14846 }
14847 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14848 } else {
14849 /* JAL32 */
14850 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14851 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14852 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14853 }
3c824109
NF
14854 break;
14855 /* Floating point (COP1) */
14856 case LWC132:
14857 mips32_op = OPC_LWC1;
14858 goto do_cop1;
14859 case LDC132:
14860 mips32_op = OPC_LDC1;
14861 goto do_cop1;
14862 case SWC132:
14863 mips32_op = OPC_SWC1;
14864 goto do_cop1;
14865 case SDC132:
14866 mips32_op = OPC_SDC1;
14867 do_cop1:
5ab5c041 14868 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14869 break;
ab39ee45
YK
14870 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14871 if (ctx->insn_flags & ISA_MIPS32R6) {
14872 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14873 switch ((ctx->opcode >> 16) & 0x1f) {
14874 case ADDIUPC_00 ... ADDIUPC_07:
14875 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14876 break;
14877 case AUIPC:
14878 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14879 break;
14880 case ALUIPC:
14881 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14882 break;
14883 case LWPC_08 ... LWPC_0F:
14884 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14885 break;
14886 default:
14887 generate_exception(ctx, EXCP_RI);
14888 break;
14889 }
14890 } else {
14891 /* ADDIUPC */
3c824109
NF
14892 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14893 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14894
14895 gen_addiupc(ctx, reg, offset, 0, 0);
14896 }
14897 break;
65935f07
YK
14898 case BNVC: /* BNEC, BNEZALC */
14899 check_insn(ctx, ISA_MIPS32R6);
14900 if (rs >= rt) {
14901 /* BNVC */
14902 mips32_op = OPC_BNVC;
14903 } else if (rs < rt && rs == 0) {
14904 /* BNEZALC */
14905 mips32_op = OPC_BNEZALC;
14906 } else {
14907 /* BNEC */
14908 mips32_op = OPC_BNEC;
14909 }
14910 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14911 break;
14912 case R6_BNEZC: /* JIALC */
14913 check_insn(ctx, ISA_MIPS32R6);
14914 if (rt != 0) {
14915 /* BNEZC */
14916 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14917 sextract32(ctx->opcode << 1, 0, 22));
14918 } else {
14919 /* JIALC */
14920 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14921 }
14922 break;
14923 case R6_BEQZC: /* JIC */
14924 check_insn(ctx, ISA_MIPS32R6);
14925 if (rt != 0) {
14926 /* BEQZC */
14927 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14928 sextract32(ctx->opcode << 1, 0, 22));
14929 } else {
14930 /* JIC */
14931 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14932 }
14933 break;
14934 case BLEZALC: /* BGEZALC, BGEUC */
14935 check_insn(ctx, ISA_MIPS32R6);
14936 if (rs == 0 && rt != 0) {
14937 /* BLEZALC */
14938 mips32_op = OPC_BLEZALC;
14939 } else if (rs != 0 && rt != 0 && rs == rt) {
14940 /* BGEZALC */
14941 mips32_op = OPC_BGEZALC;
14942 } else {
14943 /* BGEUC */
14944 mips32_op = OPC_BGEUC;
14945 }
14946 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14947 break;
14948 case BGTZALC: /* BLTZALC, BLTUC */
14949 check_insn(ctx, ISA_MIPS32R6);
14950 if (rs == 0 && rt != 0) {
14951 /* BGTZALC */
14952 mips32_op = OPC_BGTZALC;
14953 } else if (rs != 0 && rt != 0 && rs == rt) {
14954 /* BLTZALC */
14955 mips32_op = OPC_BLTZALC;
14956 } else {
14957 /* BLTUC */
14958 mips32_op = OPC_BLTUC;
14959 }
14960 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14961 break;
3c824109
NF
14962 /* Loads and stores */
14963 case LB32:
14964 mips32_op = OPC_LB;
5c13fdfd 14965 goto do_ld;
3c824109
NF
14966 case LBU32:
14967 mips32_op = OPC_LBU;
5c13fdfd 14968 goto do_ld;
3c824109
NF
14969 case LH32:
14970 mips32_op = OPC_LH;
5c13fdfd 14971 goto do_ld;
3c824109
NF
14972 case LHU32:
14973 mips32_op = OPC_LHU;
5c13fdfd 14974 goto do_ld;
3c824109
NF
14975 case LW32:
14976 mips32_op = OPC_LW;
5c13fdfd 14977 goto do_ld;
3c824109
NF
14978#ifdef TARGET_MIPS64
14979 case LD32:
d9224450
MR
14980 check_insn(ctx, ISA_MIPS3);
14981 check_mips_64(ctx);
3c824109 14982 mips32_op = OPC_LD;
5c13fdfd 14983 goto do_ld;
3c824109 14984 case SD32:
d9224450
MR
14985 check_insn(ctx, ISA_MIPS3);
14986 check_mips_64(ctx);
3c824109 14987 mips32_op = OPC_SD;
5c13fdfd 14988 goto do_st;
3c824109
NF
14989#endif
14990 case SB32:
14991 mips32_op = OPC_SB;
5c13fdfd 14992 goto do_st;
3c824109
NF
14993 case SH32:
14994 mips32_op = OPC_SH;
5c13fdfd 14995 goto do_st;
3c824109
NF
14996 case SW32:
14997 mips32_op = OPC_SW;
5c13fdfd
AJ
14998 goto do_st;
14999 do_ld:
d75c135e 15000 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15001 break;
15002 do_st:
15003 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15004 break;
15005 default:
9c708c7f 15006 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15007 break;
15008 }
15009}
15010
240ce26a 15011static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15012{
15013 uint32_t op;
15014
15015 /* make sure instructions are on a halfword boundary */
15016 if (ctx->pc & 0x1) {
15017 env->CP0_BadVAddr = ctx->pc;
9c708c7f 15018 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15019 return 2;
15020 }
15021
15022 op = (ctx->opcode >> 10) & 0x3f;
15023 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15024 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15025 switch (op & 0x7) { /* MSB-3..MSB-5 */
15026 case 0:
15027 /* POOL32A, POOL32B, POOL32I, POOL32C */
15028 case 4:
15029 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15030 case 5:
15031 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15032 case 6:
15033 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15034 case 7:
15035 /* LB32, LH32, LWC132, LDC132, LW32 */
15036 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15037 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15038 return 2;
15039 }
15040 break;
b231c103
YK
15041 case 1:
15042 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15043 case 2:
15044 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15045 case 3:
15046 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15047 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15048 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15049 return 2;
15050 }
15051 break;
3c824109
NF
15052 }
15053 }
b231c103 15054
3c824109
NF
15055 switch (op) {
15056 case POOL16A:
15057 {
15058 int rd = mmreg(uMIPS_RD(ctx->opcode));
15059 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15060 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15061 uint32_t opc = 0;
15062
15063 switch (ctx->opcode & 0x1) {
15064 case ADDU16:
15065 opc = OPC_ADDU;
15066 break;
15067 case SUBU16:
15068 opc = OPC_SUBU;
15069 break;
15070 }
ed7ce6c0
YK
15071 if (ctx->insn_flags & ISA_MIPS32R6) {
15072 /* In the Release 6 the register number location in
15073 * the instruction encoding has changed.
15074 */
15075 gen_arith(ctx, opc, rs1, rd, rs2);
15076 } else {
15077 gen_arith(ctx, opc, rd, rs1, rs2);
15078 }
3c824109
NF
15079 }
15080 break;
15081 case POOL16B:
15082 {
15083 int rd = mmreg(uMIPS_RD(ctx->opcode));
15084 int rs = mmreg(uMIPS_RS(ctx->opcode));
15085 int amount = (ctx->opcode >> 1) & 0x7;
15086 uint32_t opc = 0;
15087 amount = amount == 0 ? 8 : amount;
15088
15089 switch (ctx->opcode & 0x1) {
15090 case SLL16:
15091 opc = OPC_SLL;
15092 break;
15093 case SRL16:
15094 opc = OPC_SRL;
15095 break;
15096 }
15097
d75c135e 15098 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15099 }
15100 break;
15101 case POOL16C:
ed7ce6c0
YK
15102 if (ctx->insn_flags & ISA_MIPS32R6) {
15103 gen_pool16c_r6_insn(ctx);
15104 } else {
15105 gen_pool16c_insn(ctx);
15106 }
3c824109
NF
15107 break;
15108 case LWGP16:
15109 {
15110 int rd = mmreg(uMIPS_RD(ctx->opcode));
15111 int rb = 28; /* GP */
15112 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15113
d75c135e 15114 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15115 }
15116 break;
15117 case POOL16F:
9e8f441a 15118 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15119 if (ctx->opcode & 1) {
9c708c7f 15120 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15121 } else {
15122 /* MOVEP */
15123 int enc_dest = uMIPS_RD(ctx->opcode);
15124 int enc_rt = uMIPS_RS2(ctx->opcode);
15125 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15126 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15127 }
15128 break;
15129 case LBU16:
15130 {
15131 int rd = mmreg(uMIPS_RD(ctx->opcode));
15132 int rb = mmreg(uMIPS_RS(ctx->opcode));
15133 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15134 offset = (offset == 0xf ? -1 : offset);
15135
d75c135e 15136 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15137 }
15138 break;
15139 case LHU16:
15140 {
15141 int rd = mmreg(uMIPS_RD(ctx->opcode));
15142 int rb = mmreg(uMIPS_RS(ctx->opcode));
15143 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15144
d75c135e 15145 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15146 }
15147 break;
15148 case LWSP16:
15149 {
15150 int rd = (ctx->opcode >> 5) & 0x1f;
15151 int rb = 29; /* SP */
15152 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15153
d75c135e 15154 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15155 }
15156 break;
15157 case LW16:
15158 {
15159 int rd = mmreg(uMIPS_RD(ctx->opcode));
15160 int rb = mmreg(uMIPS_RS(ctx->opcode));
15161 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15162
d75c135e 15163 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15164 }
15165 break;
15166 case SB16:
15167 {
15168 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15169 int rb = mmreg(uMIPS_RS(ctx->opcode));
15170 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15171
5c13fdfd 15172 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15173 }
15174 break;
15175 case SH16:
15176 {
15177 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15178 int rb = mmreg(uMIPS_RS(ctx->opcode));
15179 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15180
5c13fdfd 15181 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15182 }
15183 break;
15184 case SWSP16:
15185 {
15186 int rd = (ctx->opcode >> 5) & 0x1f;
15187 int rb = 29; /* SP */
15188 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15189
5c13fdfd 15190 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15191 }
15192 break;
15193 case SW16:
15194 {
15195 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15196 int rb = mmreg(uMIPS_RS(ctx->opcode));
15197 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15198
5c13fdfd 15199 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15200 }
15201 break;
15202 case MOVE16:
15203 {
15204 int rd = uMIPS_RD5(ctx->opcode);
15205 int rs = uMIPS_RS5(ctx->opcode);
15206
7215d7e7 15207 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15208 }
15209 break;
15210 case ANDI16:
d75c135e 15211 gen_andi16(ctx);
3c824109
NF
15212 break;
15213 case POOL16D:
15214 switch (ctx->opcode & 0x1) {
15215 case ADDIUS5:
d75c135e 15216 gen_addius5(ctx);
3c824109
NF
15217 break;
15218 case ADDIUSP:
d75c135e 15219 gen_addiusp(ctx);
3c824109
NF
15220 break;
15221 }
15222 break;
15223 case POOL16E:
15224 switch (ctx->opcode & 0x1) {
15225 case ADDIUR2:
d75c135e 15226 gen_addiur2(ctx);
3c824109
NF
15227 break;
15228 case ADDIUR1SP:
d75c135e 15229 gen_addiur1sp(ctx);
3c824109
NF
15230 break;
15231 }
15232 break;
65935f07 15233 case B16: /* BC16 */
3c824109 15234 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15235 sextract32(ctx->opcode, 0, 10) << 1,
15236 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15237 break;
65935f07
YK
15238 case BNEZ16: /* BNEZC16 */
15239 case BEQZ16: /* BEQZC16 */
3c824109
NF
15240 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15241 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15242 0, sextract32(ctx->opcode, 0, 7) << 1,
15243 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15244
3c824109
NF
15245 break;
15246 case LI16:
15247 {
15248 int reg = mmreg(uMIPS_RD(ctx->opcode));
15249 int imm = ZIMM(ctx->opcode, 0, 7);
15250
15251 imm = (imm == 0x7f ? -1 : imm);
15252 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15253 }
15254 break;
3c824109 15255 case RES_29:
3c824109 15256 case RES_31:
3c824109 15257 case RES_39:
9c708c7f 15258 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15259 break;
15260 default:
f60eeb0c 15261 decode_micromips32_opc(env, ctx);
3c824109
NF
15262 return 4;
15263 }
15264
15265 return 2;
15266}
15267
15268/* SmartMIPS extension to MIPS32 */
15269
15270#if defined(TARGET_MIPS64)
15271
15272/* MDMX extension to MIPS64 */
15273
15274#endif
15275
9b1a1d68 15276/* MIPSDSP functions. */
d75c135e 15277static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15278 int rd, int base, int offset)
15279{
9b1a1d68
JL
15280 TCGv t0;
15281
9b1a1d68
JL
15282 check_dsp(ctx);
15283 t0 = tcg_temp_new();
15284
15285 if (base == 0) {
15286 gen_load_gpr(t0, offset);
15287 } else if (offset == 0) {
15288 gen_load_gpr(t0, base);
15289 } else {
15290 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15291 }
15292
9b1a1d68
JL
15293 switch (opc) {
15294 case OPC_LBUX:
5f68f5ae 15295 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15296 gen_store_gpr(t0, rd);
9b1a1d68
JL
15297 break;
15298 case OPC_LHX:
5f68f5ae 15299 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15300 gen_store_gpr(t0, rd);
9b1a1d68
JL
15301 break;
15302 case OPC_LWX:
5f68f5ae 15303 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15304 gen_store_gpr(t0, rd);
9b1a1d68
JL
15305 break;
15306#if defined(TARGET_MIPS64)
15307 case OPC_LDX:
5f68f5ae 15308 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15309 gen_store_gpr(t0, rd);
9b1a1d68
JL
15310 break;
15311#endif
15312 }
9b1a1d68
JL
15313 tcg_temp_free(t0);
15314}
15315
461c08df
JL
15316static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15317 int ret, int v1, int v2)
15318{
461c08df
JL
15319 TCGv v1_t;
15320 TCGv v2_t;
15321
15322 if (ret == 0) {
15323 /* Treat as NOP. */
461c08df
JL
15324 return;
15325 }
15326
15327 v1_t = tcg_temp_new();
15328 v2_t = tcg_temp_new();
15329
15330 gen_load_gpr(v1_t, v1);
15331 gen_load_gpr(v2_t, v2);
15332
15333 switch (op1) {
15334 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15335 case OPC_MULT_G_2E:
15336 check_dspr2(ctx);
15337 switch (op2) {
15338 case OPC_ADDUH_QB:
15339 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15340 break;
15341 case OPC_ADDUH_R_QB:
15342 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15343 break;
15344 case OPC_ADDQH_PH:
15345 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15346 break;
15347 case OPC_ADDQH_R_PH:
15348 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15349 break;
15350 case OPC_ADDQH_W:
15351 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15352 break;
15353 case OPC_ADDQH_R_W:
15354 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15355 break;
15356 case OPC_SUBUH_QB:
15357 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15358 break;
15359 case OPC_SUBUH_R_QB:
15360 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15361 break;
15362 case OPC_SUBQH_PH:
15363 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15364 break;
15365 case OPC_SUBQH_R_PH:
15366 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15367 break;
15368 case OPC_SUBQH_W:
15369 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15370 break;
15371 case OPC_SUBQH_R_W:
15372 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15373 break;
15374 }
15375 break;
15376 case OPC_ABSQ_S_PH_DSP:
15377 switch (op2) {
15378 case OPC_ABSQ_S_QB:
15379 check_dspr2(ctx);
15380 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15381 break;
15382 case OPC_ABSQ_S_PH:
15383 check_dsp(ctx);
15384 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15385 break;
15386 case OPC_ABSQ_S_W:
15387 check_dsp(ctx);
15388 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15389 break;
15390 case OPC_PRECEQ_W_PHL:
15391 check_dsp(ctx);
15392 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15393 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15394 break;
15395 case OPC_PRECEQ_W_PHR:
15396 check_dsp(ctx);
15397 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15398 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15399 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15400 break;
15401 case OPC_PRECEQU_PH_QBL:
15402 check_dsp(ctx);
15403 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15404 break;
15405 case OPC_PRECEQU_PH_QBR:
15406 check_dsp(ctx);
15407 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15408 break;
15409 case OPC_PRECEQU_PH_QBLA:
15410 check_dsp(ctx);
15411 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15412 break;
15413 case OPC_PRECEQU_PH_QBRA:
15414 check_dsp(ctx);
15415 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15416 break;
15417 case OPC_PRECEU_PH_QBL:
15418 check_dsp(ctx);
15419 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15420 break;
15421 case OPC_PRECEU_PH_QBR:
15422 check_dsp(ctx);
15423 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15424 break;
15425 case OPC_PRECEU_PH_QBLA:
15426 check_dsp(ctx);
15427 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15428 break;
15429 case OPC_PRECEU_PH_QBRA:
15430 check_dsp(ctx);
15431 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15432 break;
15433 }
15434 break;
15435 case OPC_ADDU_QB_DSP:
15436 switch (op2) {
15437 case OPC_ADDQ_PH:
15438 check_dsp(ctx);
15439 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15440 break;
15441 case OPC_ADDQ_S_PH:
15442 check_dsp(ctx);
15443 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15444 break;
15445 case OPC_ADDQ_S_W:
15446 check_dsp(ctx);
15447 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15448 break;
15449 case OPC_ADDU_QB:
15450 check_dsp(ctx);
15451 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15452 break;
15453 case OPC_ADDU_S_QB:
15454 check_dsp(ctx);
15455 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15456 break;
15457 case OPC_ADDU_PH:
15458 check_dspr2(ctx);
15459 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15460 break;
15461 case OPC_ADDU_S_PH:
15462 check_dspr2(ctx);
15463 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15464 break;
15465 case OPC_SUBQ_PH:
15466 check_dsp(ctx);
15467 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15468 break;
15469 case OPC_SUBQ_S_PH:
15470 check_dsp(ctx);
15471 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15472 break;
15473 case OPC_SUBQ_S_W:
15474 check_dsp(ctx);
15475 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15476 break;
15477 case OPC_SUBU_QB:
15478 check_dsp(ctx);
15479 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15480 break;
15481 case OPC_SUBU_S_QB:
15482 check_dsp(ctx);
15483 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15484 break;
15485 case OPC_SUBU_PH:
15486 check_dspr2(ctx);
15487 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15488 break;
15489 case OPC_SUBU_S_PH:
15490 check_dspr2(ctx);
15491 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15492 break;
15493 case OPC_ADDSC:
15494 check_dsp(ctx);
15495 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15496 break;
15497 case OPC_ADDWC:
15498 check_dsp(ctx);
15499 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15500 break;
15501 case OPC_MODSUB:
15502 check_dsp(ctx);
15503 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15504 break;
15505 case OPC_RADDU_W_QB:
15506 check_dsp(ctx);
15507 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15508 break;
15509 }
15510 break;
15511 case OPC_CMPU_EQ_QB_DSP:
15512 switch (op2) {
15513 case OPC_PRECR_QB_PH:
15514 check_dspr2(ctx);
15515 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15516 break;
15517 case OPC_PRECRQ_QB_PH:
15518 check_dsp(ctx);
15519 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15520 break;
15521 case OPC_PRECR_SRA_PH_W:
15522 check_dspr2(ctx);
15523 {
15524 TCGv_i32 sa_t = tcg_const_i32(v2);
15525 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15526 cpu_gpr[ret]);
15527 tcg_temp_free_i32(sa_t);
15528 break;
15529 }
15530 case OPC_PRECR_SRA_R_PH_W:
15531 check_dspr2(ctx);
15532 {
15533 TCGv_i32 sa_t = tcg_const_i32(v2);
15534 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15535 cpu_gpr[ret]);
15536 tcg_temp_free_i32(sa_t);
15537 break;
15538 }
15539 case OPC_PRECRQ_PH_W:
15540 check_dsp(ctx);
15541 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15542 break;
15543 case OPC_PRECRQ_RS_PH_W:
15544 check_dsp(ctx);
15545 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15546 break;
15547 case OPC_PRECRQU_S_QB_PH:
15548 check_dsp(ctx);
15549 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15550 break;
15551 }
15552 break;
15553#ifdef TARGET_MIPS64
15554 case OPC_ABSQ_S_QH_DSP:
15555 switch (op2) {
15556 case OPC_PRECEQ_L_PWL:
15557 check_dsp(ctx);
15558 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15559 break;
15560 case OPC_PRECEQ_L_PWR:
15561 check_dsp(ctx);
15562 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15563 break;
15564 case OPC_PRECEQ_PW_QHL:
15565 check_dsp(ctx);
15566 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15567 break;
15568 case OPC_PRECEQ_PW_QHR:
15569 check_dsp(ctx);
15570 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15571 break;
15572 case OPC_PRECEQ_PW_QHLA:
15573 check_dsp(ctx);
15574 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15575 break;
15576 case OPC_PRECEQ_PW_QHRA:
15577 check_dsp(ctx);
15578 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15579 break;
15580 case OPC_PRECEQU_QH_OBL:
15581 check_dsp(ctx);
15582 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15583 break;
15584 case OPC_PRECEQU_QH_OBR:
15585 check_dsp(ctx);
15586 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15587 break;
15588 case OPC_PRECEQU_QH_OBLA:
15589 check_dsp(ctx);
15590 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15591 break;
15592 case OPC_PRECEQU_QH_OBRA:
15593 check_dsp(ctx);
15594 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15595 break;
15596 case OPC_PRECEU_QH_OBL:
15597 check_dsp(ctx);
15598 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15599 break;
15600 case OPC_PRECEU_QH_OBR:
15601 check_dsp(ctx);
15602 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15603 break;
15604 case OPC_PRECEU_QH_OBLA:
15605 check_dsp(ctx);
15606 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15607 break;
15608 case OPC_PRECEU_QH_OBRA:
15609 check_dsp(ctx);
15610 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15611 break;
15612 case OPC_ABSQ_S_OB:
15613 check_dspr2(ctx);
15614 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15615 break;
15616 case OPC_ABSQ_S_PW:
15617 check_dsp(ctx);
15618 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15619 break;
15620 case OPC_ABSQ_S_QH:
15621 check_dsp(ctx);
15622 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15623 break;
15624 }
15625 break;
15626 case OPC_ADDU_OB_DSP:
15627 switch (op2) {
15628 case OPC_RADDU_L_OB:
15629 check_dsp(ctx);
15630 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15631 break;
15632 case OPC_SUBQ_PW:
15633 check_dsp(ctx);
15634 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15635 break;
15636 case OPC_SUBQ_S_PW:
15637 check_dsp(ctx);
15638 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15639 break;
15640 case OPC_SUBQ_QH:
15641 check_dsp(ctx);
15642 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15643 break;
15644 case OPC_SUBQ_S_QH:
15645 check_dsp(ctx);
15646 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15647 break;
15648 case OPC_SUBU_OB:
15649 check_dsp(ctx);
15650 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15651 break;
15652 case OPC_SUBU_S_OB:
15653 check_dsp(ctx);
15654 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15655 break;
15656 case OPC_SUBU_QH:
15657 check_dspr2(ctx);
15658 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15659 break;
15660 case OPC_SUBU_S_QH:
15661 check_dspr2(ctx);
15662 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15663 break;
15664 case OPC_SUBUH_OB:
15665 check_dspr2(ctx);
15666 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15667 break;
15668 case OPC_SUBUH_R_OB:
15669 check_dspr2(ctx);
15670 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15671 break;
15672 case OPC_ADDQ_PW:
15673 check_dsp(ctx);
15674 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15675 break;
15676 case OPC_ADDQ_S_PW:
15677 check_dsp(ctx);
15678 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15679 break;
15680 case OPC_ADDQ_QH:
15681 check_dsp(ctx);
15682 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15683 break;
15684 case OPC_ADDQ_S_QH:
15685 check_dsp(ctx);
15686 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15687 break;
15688 case OPC_ADDU_OB:
15689 check_dsp(ctx);
15690 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15691 break;
15692 case OPC_ADDU_S_OB:
15693 check_dsp(ctx);
15694 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15695 break;
15696 case OPC_ADDU_QH:
15697 check_dspr2(ctx);
15698 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15699 break;
15700 case OPC_ADDU_S_QH:
15701 check_dspr2(ctx);
15702 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15703 break;
15704 case OPC_ADDUH_OB:
15705 check_dspr2(ctx);
15706 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15707 break;
15708 case OPC_ADDUH_R_OB:
15709 check_dspr2(ctx);
15710 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15711 break;
15712 }
15713 break;
15714 case OPC_CMPU_EQ_OB_DSP:
15715 switch (op2) {
15716 case OPC_PRECR_OB_QH:
15717 check_dspr2(ctx);
15718 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15719 break;
15720 case OPC_PRECR_SRA_QH_PW:
15721 check_dspr2(ctx);
15722 {
15723 TCGv_i32 ret_t = tcg_const_i32(ret);
15724 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15725 tcg_temp_free_i32(ret_t);
15726 break;
15727 }
15728 case OPC_PRECR_SRA_R_QH_PW:
15729 check_dspr2(ctx);
15730 {
15731 TCGv_i32 sa_v = tcg_const_i32(ret);
15732 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15733 tcg_temp_free_i32(sa_v);
15734 break;
15735 }
15736 case OPC_PRECRQ_OB_QH:
15737 check_dsp(ctx);
15738 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15739 break;
15740 case OPC_PRECRQ_PW_L:
15741 check_dsp(ctx);
15742 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15743 break;
15744 case OPC_PRECRQ_QH_PW:
15745 check_dsp(ctx);
15746 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15747 break;
15748 case OPC_PRECRQ_RS_QH_PW:
15749 check_dsp(ctx);
15750 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15751 break;
15752 case OPC_PRECRQU_S_OB_QH:
15753 check_dsp(ctx);
15754 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15755 break;
15756 }
15757 break;
15758#endif
15759 }
15760
15761 tcg_temp_free(v1_t);
15762 tcg_temp_free(v2_t);
461c08df 15763}
9b1a1d68 15764
77c5fa8b
JL
15765static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15766 int ret, int v1, int v2)
15767{
15768 uint32_t op2;
77c5fa8b
JL
15769 TCGv t0;
15770 TCGv v1_t;
15771 TCGv v2_t;
15772
15773 if (ret == 0) {
15774 /* Treat as NOP. */
77c5fa8b
JL
15775 return;
15776 }
15777
15778 t0 = tcg_temp_new();
15779 v1_t = tcg_temp_new();
15780 v2_t = tcg_temp_new();
15781
15782 tcg_gen_movi_tl(t0, v1);
15783 gen_load_gpr(v1_t, v1);
15784 gen_load_gpr(v2_t, v2);
15785
15786 switch (opc) {
15787 case OPC_SHLL_QB_DSP:
15788 {
15789 op2 = MASK_SHLL_QB(ctx->opcode);
15790 switch (op2) {
15791 case OPC_SHLL_QB:
15792 check_dsp(ctx);
15793 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15794 break;
15795 case OPC_SHLLV_QB:
15796 check_dsp(ctx);
15797 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15798 break;
15799 case OPC_SHLL_PH:
15800 check_dsp(ctx);
15801 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15802 break;
15803 case OPC_SHLLV_PH:
15804 check_dsp(ctx);
15805 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15806 break;
15807 case OPC_SHLL_S_PH:
15808 check_dsp(ctx);
15809 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15810 break;
15811 case OPC_SHLLV_S_PH:
15812 check_dsp(ctx);
15813 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15814 break;
15815 case OPC_SHLL_S_W:
15816 check_dsp(ctx);
15817 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15818 break;
15819 case OPC_SHLLV_S_W:
15820 check_dsp(ctx);
15821 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15822 break;
15823 case OPC_SHRL_QB:
15824 check_dsp(ctx);
15825 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15826 break;
15827 case OPC_SHRLV_QB:
15828 check_dsp(ctx);
15829 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15830 break;
15831 case OPC_SHRL_PH:
15832 check_dspr2(ctx);
15833 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15834 break;
15835 case OPC_SHRLV_PH:
15836 check_dspr2(ctx);
15837 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15838 break;
15839 case OPC_SHRA_QB:
15840 check_dspr2(ctx);
15841 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15842 break;
15843 case OPC_SHRA_R_QB:
15844 check_dspr2(ctx);
15845 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15846 break;
15847 case OPC_SHRAV_QB:
15848 check_dspr2(ctx);
15849 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15850 break;
15851 case OPC_SHRAV_R_QB:
15852 check_dspr2(ctx);
15853 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15854 break;
15855 case OPC_SHRA_PH:
15856 check_dsp(ctx);
15857 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15858 break;
15859 case OPC_SHRA_R_PH:
15860 check_dsp(ctx);
15861 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15862 break;
15863 case OPC_SHRAV_PH:
15864 check_dsp(ctx);
15865 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15866 break;
15867 case OPC_SHRAV_R_PH:
15868 check_dsp(ctx);
15869 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15870 break;
15871 case OPC_SHRA_R_W:
15872 check_dsp(ctx);
15873 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15874 break;
15875 case OPC_SHRAV_R_W:
15876 check_dsp(ctx);
15877 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15878 break;
15879 default: /* Invalid */
15880 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 15881 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15882 break;
15883 }
15884 break;
15885 }
15886#ifdef TARGET_MIPS64
15887 case OPC_SHLL_OB_DSP:
15888 op2 = MASK_SHLL_OB(ctx->opcode);
15889 switch (op2) {
15890 case OPC_SHLL_PW:
15891 check_dsp(ctx);
15892 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15893 break;
15894 case OPC_SHLLV_PW:
15895 check_dsp(ctx);
15896 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15897 break;
15898 case OPC_SHLL_S_PW:
15899 check_dsp(ctx);
15900 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15901 break;
15902 case OPC_SHLLV_S_PW:
15903 check_dsp(ctx);
15904 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15905 break;
15906 case OPC_SHLL_OB:
15907 check_dsp(ctx);
15908 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15909 break;
15910 case OPC_SHLLV_OB:
15911 check_dsp(ctx);
15912 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15913 break;
15914 case OPC_SHLL_QH:
15915 check_dsp(ctx);
15916 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15917 break;
15918 case OPC_SHLLV_QH:
15919 check_dsp(ctx);
15920 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15921 break;
15922 case OPC_SHLL_S_QH:
15923 check_dsp(ctx);
15924 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15925 break;
15926 case OPC_SHLLV_S_QH:
15927 check_dsp(ctx);
15928 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15929 break;
15930 case OPC_SHRA_OB:
15931 check_dspr2(ctx);
15932 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15933 break;
15934 case OPC_SHRAV_OB:
15935 check_dspr2(ctx);
15936 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15937 break;
15938 case OPC_SHRA_R_OB:
15939 check_dspr2(ctx);
15940 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15941 break;
15942 case OPC_SHRAV_R_OB:
15943 check_dspr2(ctx);
15944 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15945 break;
15946 case OPC_SHRA_PW:
15947 check_dsp(ctx);
15948 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15949 break;
15950 case OPC_SHRAV_PW:
15951 check_dsp(ctx);
15952 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15953 break;
15954 case OPC_SHRA_R_PW:
15955 check_dsp(ctx);
15956 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15957 break;
15958 case OPC_SHRAV_R_PW:
15959 check_dsp(ctx);
15960 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15961 break;
15962 case OPC_SHRA_QH:
15963 check_dsp(ctx);
15964 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15965 break;
15966 case OPC_SHRAV_QH:
15967 check_dsp(ctx);
15968 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15969 break;
15970 case OPC_SHRA_R_QH:
15971 check_dsp(ctx);
15972 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15973 break;
15974 case OPC_SHRAV_R_QH:
15975 check_dsp(ctx);
15976 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15977 break;
15978 case OPC_SHRL_OB:
15979 check_dsp(ctx);
15980 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15981 break;
15982 case OPC_SHRLV_OB:
15983 check_dsp(ctx);
15984 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15985 break;
15986 case OPC_SHRL_QH:
15987 check_dspr2(ctx);
15988 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15989 break;
15990 case OPC_SHRLV_QH:
15991 check_dspr2(ctx);
15992 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15993 break;
15994 default: /* Invalid */
15995 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 15996 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15997 break;
15998 }
15999 break;
16000#endif
16001 }
16002
16003 tcg_temp_free(t0);
16004 tcg_temp_free(v1_t);
16005 tcg_temp_free(v2_t);
77c5fa8b
JL
16006}
16007
a22260ae
JL
16008static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16009 int ret, int v1, int v2, int check_ret)
16010{
a22260ae
JL
16011 TCGv_i32 t0;
16012 TCGv v1_t;
16013 TCGv v2_t;
16014
16015 if ((ret == 0) && (check_ret == 1)) {
16016 /* Treat as NOP. */
a22260ae
JL
16017 return;
16018 }
16019
16020 t0 = tcg_temp_new_i32();
16021 v1_t = tcg_temp_new();
16022 v2_t = tcg_temp_new();
16023
16024 tcg_gen_movi_i32(t0, ret);
16025 gen_load_gpr(v1_t, v1);
16026 gen_load_gpr(v2_t, v2);
16027
16028 switch (op1) {
16029 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16030 * the same mask and op1. */
16031 case OPC_MULT_G_2E:
639eadb9 16032 check_dspr2(ctx);
a22260ae
JL
16033 switch (op2) {
16034 case OPC_MUL_PH:
16035 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16036 break;
16037 case OPC_MUL_S_PH:
16038 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16039 break;
16040 case OPC_MULQ_S_W:
16041 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16042 break;
16043 case OPC_MULQ_RS_W:
16044 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16045 break;
16046 }
16047 break;
16048 case OPC_DPA_W_PH_DSP:
16049 switch (op2) {
16050 case OPC_DPAU_H_QBL:
16051 check_dsp(ctx);
16052 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16053 break;
16054 case OPC_DPAU_H_QBR:
16055 check_dsp(ctx);
16056 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16057 break;
16058 case OPC_DPSU_H_QBL:
16059 check_dsp(ctx);
16060 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16061 break;
16062 case OPC_DPSU_H_QBR:
16063 check_dsp(ctx);
16064 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16065 break;
16066 case OPC_DPA_W_PH:
16067 check_dspr2(ctx);
16068 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16069 break;
16070 case OPC_DPAX_W_PH:
16071 check_dspr2(ctx);
16072 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16073 break;
16074 case OPC_DPAQ_S_W_PH:
16075 check_dsp(ctx);
16076 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16077 break;
16078 case OPC_DPAQX_S_W_PH:
16079 check_dspr2(ctx);
16080 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16081 break;
16082 case OPC_DPAQX_SA_W_PH:
16083 check_dspr2(ctx);
16084 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16085 break;
16086 case OPC_DPS_W_PH:
16087 check_dspr2(ctx);
16088 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16089 break;
16090 case OPC_DPSX_W_PH:
16091 check_dspr2(ctx);
16092 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16093 break;
16094 case OPC_DPSQ_S_W_PH:
16095 check_dsp(ctx);
16096 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16097 break;
16098 case OPC_DPSQX_S_W_PH:
16099 check_dspr2(ctx);
16100 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16101 break;
16102 case OPC_DPSQX_SA_W_PH:
16103 check_dspr2(ctx);
16104 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16105 break;
16106 case OPC_MULSAQ_S_W_PH:
16107 check_dsp(ctx);
16108 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16109 break;
16110 case OPC_DPAQ_SA_L_W:
16111 check_dsp(ctx);
16112 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16113 break;
16114 case OPC_DPSQ_SA_L_W:
16115 check_dsp(ctx);
16116 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16117 break;
16118 case OPC_MAQ_S_W_PHL:
16119 check_dsp(ctx);
16120 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16121 break;
16122 case OPC_MAQ_S_W_PHR:
16123 check_dsp(ctx);
16124 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16125 break;
16126 case OPC_MAQ_SA_W_PHL:
16127 check_dsp(ctx);
16128 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16129 break;
16130 case OPC_MAQ_SA_W_PHR:
16131 check_dsp(ctx);
16132 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16133 break;
16134 case OPC_MULSA_W_PH:
16135 check_dspr2(ctx);
16136 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16137 break;
16138 }
16139 break;
16140#ifdef TARGET_MIPS64
16141 case OPC_DPAQ_W_QH_DSP:
16142 {
16143 int ac = ret & 0x03;
16144 tcg_gen_movi_i32(t0, ac);
16145
16146 switch (op2) {
16147 case OPC_DMADD:
16148 check_dsp(ctx);
16149 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16150 break;
16151 case OPC_DMADDU:
16152 check_dsp(ctx);
16153 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16154 break;
16155 case OPC_DMSUB:
16156 check_dsp(ctx);
16157 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16158 break;
16159 case OPC_DMSUBU:
16160 check_dsp(ctx);
16161 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16162 break;
16163 case OPC_DPA_W_QH:
16164 check_dspr2(ctx);
16165 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16166 break;
16167 case OPC_DPAQ_S_W_QH:
16168 check_dsp(ctx);
16169 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16170 break;
16171 case OPC_DPAQ_SA_L_PW:
16172 check_dsp(ctx);
16173 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16174 break;
16175 case OPC_DPAU_H_OBL:
16176 check_dsp(ctx);
16177 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16178 break;
16179 case OPC_DPAU_H_OBR:
16180 check_dsp(ctx);
16181 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16182 break;
16183 case OPC_DPS_W_QH:
16184 check_dspr2(ctx);
16185 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16186 break;
16187 case OPC_DPSQ_S_W_QH:
16188 check_dsp(ctx);
16189 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16190 break;
16191 case OPC_DPSQ_SA_L_PW:
16192 check_dsp(ctx);
16193 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16194 break;
16195 case OPC_DPSU_H_OBL:
16196 check_dsp(ctx);
16197 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16198 break;
16199 case OPC_DPSU_H_OBR:
16200 check_dsp(ctx);
16201 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16202 break;
16203 case OPC_MAQ_S_L_PWL:
16204 check_dsp(ctx);
16205 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16206 break;
16207 case OPC_MAQ_S_L_PWR:
16208 check_dsp(ctx);
16209 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16210 break;
16211 case OPC_MAQ_S_W_QHLL:
16212 check_dsp(ctx);
16213 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16214 break;
16215 case OPC_MAQ_SA_W_QHLL:
16216 check_dsp(ctx);
16217 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16218 break;
16219 case OPC_MAQ_S_W_QHLR:
16220 check_dsp(ctx);
16221 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16222 break;
16223 case OPC_MAQ_SA_W_QHLR:
16224 check_dsp(ctx);
16225 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16226 break;
16227 case OPC_MAQ_S_W_QHRL:
16228 check_dsp(ctx);
16229 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16230 break;
16231 case OPC_MAQ_SA_W_QHRL:
16232 check_dsp(ctx);
16233 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16234 break;
16235 case OPC_MAQ_S_W_QHRR:
16236 check_dsp(ctx);
16237 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16238 break;
16239 case OPC_MAQ_SA_W_QHRR:
16240 check_dsp(ctx);
16241 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16242 break;
16243 case OPC_MULSAQ_S_L_PW:
16244 check_dsp(ctx);
16245 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16246 break;
16247 case OPC_MULSAQ_S_W_QH:
16248 check_dsp(ctx);
16249 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16250 break;
16251 }
16252 }
16253 break;
16254#endif
16255 case OPC_ADDU_QB_DSP:
16256 switch (op2) {
16257 case OPC_MULEU_S_PH_QBL:
16258 check_dsp(ctx);
16259 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16260 break;
16261 case OPC_MULEU_S_PH_QBR:
16262 check_dsp(ctx);
16263 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16264 break;
16265 case OPC_MULQ_RS_PH:
16266 check_dsp(ctx);
16267 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16268 break;
16269 case OPC_MULEQ_S_W_PHL:
16270 check_dsp(ctx);
16271 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16272 break;
16273 case OPC_MULEQ_S_W_PHR:
16274 check_dsp(ctx);
16275 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16276 break;
16277 case OPC_MULQ_S_PH:
16278 check_dspr2(ctx);
16279 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16280 break;
16281 }
16282 break;
16283#ifdef TARGET_MIPS64
16284 case OPC_ADDU_OB_DSP:
16285 switch (op2) {
16286 case OPC_MULEQ_S_PW_QHL:
16287 check_dsp(ctx);
16288 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16289 break;
16290 case OPC_MULEQ_S_PW_QHR:
16291 check_dsp(ctx);
16292 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16293 break;
16294 case OPC_MULEU_S_QH_OBL:
16295 check_dsp(ctx);
16296 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16297 break;
16298 case OPC_MULEU_S_QH_OBR:
16299 check_dsp(ctx);
16300 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16301 break;
16302 case OPC_MULQ_RS_QH:
16303 check_dsp(ctx);
16304 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16305 break;
16306 }
16307 break;
16308#endif
16309 }
16310
16311 tcg_temp_free_i32(t0);
16312 tcg_temp_free(v1_t);
16313 tcg_temp_free(v2_t);
a22260ae
JL
16314}
16315
d75c135e 16316static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16317 int ret, int val)
16318{
1cb6686c
JL
16319 int16_t imm;
16320 TCGv t0;
16321 TCGv val_t;
16322
16323 if (ret == 0) {
16324 /* Treat as NOP. */
1cb6686c
JL
16325 return;
16326 }
16327
16328 t0 = tcg_temp_new();
16329 val_t = tcg_temp_new();
16330 gen_load_gpr(val_t, val);
16331
16332 switch (op1) {
16333 case OPC_ABSQ_S_PH_DSP:
16334 switch (op2) {
16335 case OPC_BITREV:
16336 check_dsp(ctx);
16337 gen_helper_bitrev(cpu_gpr[ret], val_t);
16338 break;
16339 case OPC_REPL_QB:
16340 check_dsp(ctx);
16341 {
16342 target_long result;
16343 imm = (ctx->opcode >> 16) & 0xFF;
16344 result = (uint32_t)imm << 24 |
16345 (uint32_t)imm << 16 |
16346 (uint32_t)imm << 8 |
16347 (uint32_t)imm;
16348 result = (int32_t)result;
16349 tcg_gen_movi_tl(cpu_gpr[ret], result);
16350 }
16351 break;
16352 case OPC_REPLV_QB:
16353 check_dsp(ctx);
16354 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16355 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16356 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16357 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16358 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16359 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16360 break;
16361 case OPC_REPL_PH:
16362 check_dsp(ctx);
16363 {
16364 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16365 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16366 tcg_gen_movi_tl(cpu_gpr[ret], \
16367 (target_long)((int32_t)imm << 16 | \
c4aaba92 16368 (uint16_t)imm));
1cb6686c
JL
16369 }
16370 break;
16371 case OPC_REPLV_PH:
16372 check_dsp(ctx);
16373 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16374 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16375 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16376 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16377 break;
16378 }
16379 break;
16380#ifdef TARGET_MIPS64
16381 case OPC_ABSQ_S_QH_DSP:
16382 switch (op2) {
16383 case OPC_REPL_OB:
16384 check_dsp(ctx);
16385 {
16386 target_long temp;
16387
16388 imm = (ctx->opcode >> 16) & 0xFF;
16389 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16390 temp = (temp << 16) | temp;
16391 temp = (temp << 32) | temp;
16392 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16393 break;
16394 }
16395 case OPC_REPL_PW:
16396 check_dsp(ctx);
16397 {
16398 target_long temp;
16399
16400 imm = (ctx->opcode >> 16) & 0x03FF;
16401 imm = (int16_t)(imm << 6) >> 6;
16402 temp = ((target_long)imm << 32) \
16403 | ((target_long)imm & 0xFFFFFFFF);
16404 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16405 break;
16406 }
16407 case OPC_REPL_QH:
16408 check_dsp(ctx);
16409 {
16410 target_long temp;
16411
16412 imm = (ctx->opcode >> 16) & 0x03FF;
16413 imm = (int16_t)(imm << 6) >> 6;
16414
16415 temp = ((uint64_t)(uint16_t)imm << 48) |
16416 ((uint64_t)(uint16_t)imm << 32) |
16417 ((uint64_t)(uint16_t)imm << 16) |
16418 (uint64_t)(uint16_t)imm;
16419 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16420 break;
16421 }
16422 case OPC_REPLV_OB:
16423 check_dsp(ctx);
16424 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16425 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16426 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16427 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16428 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16429 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16430 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16431 break;
16432 case OPC_REPLV_PW:
16433 check_dsp(ctx);
16434 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16435 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16436 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16437 break;
16438 case OPC_REPLV_QH:
16439 check_dsp(ctx);
16440 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16441 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16442 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16443 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16444 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16445 break;
16446 }
16447 break;
16448#endif
16449 }
16450 tcg_temp_free(t0);
16451 tcg_temp_free(val_t);
1cb6686c
JL
16452}
16453
26690560
JL
16454static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16455 uint32_t op1, uint32_t op2,
16456 int ret, int v1, int v2, int check_ret)
16457{
26690560
JL
16458 TCGv t1;
16459 TCGv v1_t;
16460 TCGv v2_t;
16461
16462 if ((ret == 0) && (check_ret == 1)) {
16463 /* Treat as NOP. */
26690560
JL
16464 return;
16465 }
16466
26690560
JL
16467 t1 = tcg_temp_new();
16468 v1_t = tcg_temp_new();
16469 v2_t = tcg_temp_new();
16470
16471 gen_load_gpr(v1_t, v1);
16472 gen_load_gpr(v2_t, v2);
16473
16474 switch (op1) {
26690560
JL
16475 case OPC_CMPU_EQ_QB_DSP:
16476 switch (op2) {
16477 case OPC_CMPU_EQ_QB:
16478 check_dsp(ctx);
16479 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16480 break;
16481 case OPC_CMPU_LT_QB:
16482 check_dsp(ctx);
16483 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16484 break;
16485 case OPC_CMPU_LE_QB:
16486 check_dsp(ctx);
16487 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16488 break;
16489 case OPC_CMPGU_EQ_QB:
16490 check_dsp(ctx);
16491 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16492 break;
16493 case OPC_CMPGU_LT_QB:
16494 check_dsp(ctx);
16495 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16496 break;
16497 case OPC_CMPGU_LE_QB:
16498 check_dsp(ctx);
16499 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16500 break;
16501 case OPC_CMPGDU_EQ_QB:
16502 check_dspr2(ctx);
16503 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16504 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16505 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16506 tcg_gen_shli_tl(t1, t1, 24);
16507 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16508 break;
16509 case OPC_CMPGDU_LT_QB:
16510 check_dspr2(ctx);
16511 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16512 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16513 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16514 tcg_gen_shli_tl(t1, t1, 24);
16515 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16516 break;
16517 case OPC_CMPGDU_LE_QB:
16518 check_dspr2(ctx);
16519 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16520 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16521 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16522 tcg_gen_shli_tl(t1, t1, 24);
16523 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16524 break;
16525 case OPC_CMP_EQ_PH:
16526 check_dsp(ctx);
16527 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16528 break;
16529 case OPC_CMP_LT_PH:
16530 check_dsp(ctx);
16531 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16532 break;
16533 case OPC_CMP_LE_PH:
16534 check_dsp(ctx);
16535 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16536 break;
16537 case OPC_PICK_QB:
16538 check_dsp(ctx);
16539 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16540 break;
16541 case OPC_PICK_PH:
16542 check_dsp(ctx);
16543 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16544 break;
16545 case OPC_PACKRL_PH:
16546 check_dsp(ctx);
16547 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16548 break;
16549 }
16550 break;
16551#ifdef TARGET_MIPS64
16552 case OPC_CMPU_EQ_OB_DSP:
16553 switch (op2) {
16554 case OPC_CMP_EQ_PW:
16555 check_dsp(ctx);
16556 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16557 break;
16558 case OPC_CMP_LT_PW:
16559 check_dsp(ctx);
16560 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16561 break;
16562 case OPC_CMP_LE_PW:
16563 check_dsp(ctx);
16564 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16565 break;
16566 case OPC_CMP_EQ_QH:
16567 check_dsp(ctx);
16568 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16569 break;
16570 case OPC_CMP_LT_QH:
16571 check_dsp(ctx);
16572 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16573 break;
16574 case OPC_CMP_LE_QH:
16575 check_dsp(ctx);
16576 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16577 break;
16578 case OPC_CMPGDU_EQ_OB:
16579 check_dspr2(ctx);
16580 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16581 break;
16582 case OPC_CMPGDU_LT_OB:
16583 check_dspr2(ctx);
16584 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16585 break;
16586 case OPC_CMPGDU_LE_OB:
16587 check_dspr2(ctx);
16588 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16589 break;
16590 case OPC_CMPGU_EQ_OB:
16591 check_dsp(ctx);
16592 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16593 break;
16594 case OPC_CMPGU_LT_OB:
16595 check_dsp(ctx);
16596 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16597 break;
16598 case OPC_CMPGU_LE_OB:
16599 check_dsp(ctx);
16600 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16601 break;
16602 case OPC_CMPU_EQ_OB:
16603 check_dsp(ctx);
16604 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16605 break;
16606 case OPC_CMPU_LT_OB:
16607 check_dsp(ctx);
16608 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16609 break;
16610 case OPC_CMPU_LE_OB:
16611 check_dsp(ctx);
16612 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16613 break;
16614 case OPC_PACKRL_PW:
16615 check_dsp(ctx);
16616 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16617 break;
16618 case OPC_PICK_OB:
16619 check_dsp(ctx);
16620 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16621 break;
16622 case OPC_PICK_PW:
16623 check_dsp(ctx);
16624 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16625 break;
16626 case OPC_PICK_QH:
16627 check_dsp(ctx);
16628 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16629 break;
16630 }
16631 break;
df6126a7
AJ
16632#endif
16633 }
16634
16635 tcg_temp_free(t1);
16636 tcg_temp_free(v1_t);
16637 tcg_temp_free(v2_t);
df6126a7
AJ
16638}
16639
16640static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16641 uint32_t op1, int rt, int rs, int sa)
16642{
df6126a7
AJ
16643 TCGv t0;
16644
16645 check_dspr2(ctx);
16646
16647 if (rt == 0) {
16648 /* Treat as NOP. */
df6126a7
AJ
16649 return;
16650 }
16651
16652 t0 = tcg_temp_new();
16653 gen_load_gpr(t0, rs);
16654
16655 switch (op1) {
16656 case OPC_APPEND_DSP:
16657 switch (MASK_APPEND(ctx->opcode)) {
16658 case OPC_APPEND:
16659 if (sa != 0) {
16660 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16661 }
16662 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16663 break;
16664 case OPC_PREPEND:
16665 if (sa != 0) {
16666 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16667 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16668 tcg_gen_shli_tl(t0, t0, 32 - sa);
16669 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16670 }
16671 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16672 break;
16673 case OPC_BALIGN:
16674 sa &= 3;
16675 if (sa != 0 && sa != 2) {
16676 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16677 tcg_gen_ext32u_tl(t0, t0);
16678 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16679 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16680 }
16681 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16682 break;
16683 default: /* Invalid */
16684 MIPS_INVAL("MASK APPEND");
9c708c7f 16685 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16686 break;
16687 }
16688 break;
16689#ifdef TARGET_MIPS64
26690560 16690 case OPC_DAPPEND_DSP:
df6126a7 16691 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16692 case OPC_DAPPEND:
df6126a7
AJ
16693 if (sa != 0) {
16694 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16695 }
26690560
JL
16696 break;
16697 case OPC_PREPENDD:
df6126a7
AJ
16698 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16699 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16700 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16701 break;
16702 case OPC_PREPENDW:
df6126a7
AJ
16703 if (sa != 0) {
16704 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16705 tcg_gen_shli_tl(t0, t0, 64 - sa);
16706 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16707 }
26690560
JL
16708 break;
16709 case OPC_DBALIGN:
df6126a7
AJ
16710 sa &= 7;
16711 if (sa != 0 && sa != 2 && sa != 4) {
16712 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16713 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16714 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16715 }
26690560
JL
16716 break;
16717 default: /* Invalid */
16718 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16719 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16720 break;
16721 }
16722 break;
16723#endif
16724 }
df6126a7 16725 tcg_temp_free(t0);
26690560
JL
16726}
16727
b53371ed
JL
16728static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16729 int ret, int v1, int v2, int check_ret)
16730
16731{
b53371ed
JL
16732 TCGv t0;
16733 TCGv t1;
16734 TCGv v1_t;
16735 TCGv v2_t;
16736 int16_t imm;
16737
16738 if ((ret == 0) && (check_ret == 1)) {
16739 /* Treat as NOP. */
b53371ed
JL
16740 return;
16741 }
16742
16743 t0 = tcg_temp_new();
16744 t1 = tcg_temp_new();
16745 v1_t = tcg_temp_new();
16746 v2_t = tcg_temp_new();
16747
16748 gen_load_gpr(v1_t, v1);
16749 gen_load_gpr(v2_t, v2);
16750
16751 switch (op1) {
16752 case OPC_EXTR_W_DSP:
16753 check_dsp(ctx);
16754 switch (op2) {
16755 case OPC_EXTR_W:
16756 tcg_gen_movi_tl(t0, v2);
16757 tcg_gen_movi_tl(t1, v1);
16758 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16759 break;
16760 case OPC_EXTR_R_W:
16761 tcg_gen_movi_tl(t0, v2);
16762 tcg_gen_movi_tl(t1, v1);
16763 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16764 break;
16765 case OPC_EXTR_RS_W:
16766 tcg_gen_movi_tl(t0, v2);
16767 tcg_gen_movi_tl(t1, v1);
16768 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16769 break;
16770 case OPC_EXTR_S_H:
16771 tcg_gen_movi_tl(t0, v2);
16772 tcg_gen_movi_tl(t1, v1);
16773 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16774 break;
16775 case OPC_EXTRV_S_H:
16776 tcg_gen_movi_tl(t0, v2);
16777 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16778 break;
16779 case OPC_EXTRV_W:
16780 tcg_gen_movi_tl(t0, v2);
16781 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16782 break;
16783 case OPC_EXTRV_R_W:
16784 tcg_gen_movi_tl(t0, v2);
16785 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16786 break;
16787 case OPC_EXTRV_RS_W:
16788 tcg_gen_movi_tl(t0, v2);
16789 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16790 break;
16791 case OPC_EXTP:
16792 tcg_gen_movi_tl(t0, v2);
16793 tcg_gen_movi_tl(t1, v1);
16794 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16795 break;
16796 case OPC_EXTPV:
16797 tcg_gen_movi_tl(t0, v2);
16798 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16799 break;
16800 case OPC_EXTPDP:
16801 tcg_gen_movi_tl(t0, v2);
16802 tcg_gen_movi_tl(t1, v1);
16803 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16804 break;
16805 case OPC_EXTPDPV:
16806 tcg_gen_movi_tl(t0, v2);
16807 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16808 break;
16809 case OPC_SHILO:
16810 imm = (ctx->opcode >> 20) & 0x3F;
16811 tcg_gen_movi_tl(t0, ret);
16812 tcg_gen_movi_tl(t1, imm);
16813 gen_helper_shilo(t0, t1, cpu_env);
16814 break;
16815 case OPC_SHILOV:
16816 tcg_gen_movi_tl(t0, ret);
16817 gen_helper_shilo(t0, v1_t, cpu_env);
16818 break;
16819 case OPC_MTHLIP:
16820 tcg_gen_movi_tl(t0, ret);
16821 gen_helper_mthlip(t0, v1_t, cpu_env);
16822 break;
16823 case OPC_WRDSP:
16824 imm = (ctx->opcode >> 11) & 0x3FF;
16825 tcg_gen_movi_tl(t0, imm);
16826 gen_helper_wrdsp(v1_t, t0, cpu_env);
16827 break;
16828 case OPC_RDDSP:
16829 imm = (ctx->opcode >> 16) & 0x03FF;
16830 tcg_gen_movi_tl(t0, imm);
16831 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16832 break;
16833 }
16834 break;
16835#ifdef TARGET_MIPS64
16836 case OPC_DEXTR_W_DSP:
16837 check_dsp(ctx);
16838 switch (op2) {
16839 case OPC_DMTHLIP:
16840 tcg_gen_movi_tl(t0, ret);
16841 gen_helper_dmthlip(v1_t, t0, cpu_env);
16842 break;
16843 case OPC_DSHILO:
16844 {
16845 int shift = (ctx->opcode >> 19) & 0x7F;
16846 int ac = (ctx->opcode >> 11) & 0x03;
16847 tcg_gen_movi_tl(t0, shift);
16848 tcg_gen_movi_tl(t1, ac);
16849 gen_helper_dshilo(t0, t1, cpu_env);
16850 break;
16851 }
16852 case OPC_DSHILOV:
16853 {
16854 int ac = (ctx->opcode >> 11) & 0x03;
16855 tcg_gen_movi_tl(t0, ac);
16856 gen_helper_dshilo(v1_t, t0, cpu_env);
16857 break;
16858 }
16859 case OPC_DEXTP:
16860 tcg_gen_movi_tl(t0, v2);
16861 tcg_gen_movi_tl(t1, v1);
16862
16863 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16864 break;
16865 case OPC_DEXTPV:
16866 tcg_gen_movi_tl(t0, v2);
16867 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16868 break;
16869 case OPC_DEXTPDP:
16870 tcg_gen_movi_tl(t0, v2);
16871 tcg_gen_movi_tl(t1, v1);
16872 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16873 break;
16874 case OPC_DEXTPDPV:
16875 tcg_gen_movi_tl(t0, v2);
16876 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16877 break;
16878 case OPC_DEXTR_L:
16879 tcg_gen_movi_tl(t0, v2);
16880 tcg_gen_movi_tl(t1, v1);
16881 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16882 break;
16883 case OPC_DEXTR_R_L:
16884 tcg_gen_movi_tl(t0, v2);
16885 tcg_gen_movi_tl(t1, v1);
16886 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16887 break;
16888 case OPC_DEXTR_RS_L:
16889 tcg_gen_movi_tl(t0, v2);
16890 tcg_gen_movi_tl(t1, v1);
16891 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16892 break;
16893 case OPC_DEXTR_W:
16894 tcg_gen_movi_tl(t0, v2);
16895 tcg_gen_movi_tl(t1, v1);
16896 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16897 break;
16898 case OPC_DEXTR_R_W:
16899 tcg_gen_movi_tl(t0, v2);
16900 tcg_gen_movi_tl(t1, v1);
16901 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16902 break;
16903 case OPC_DEXTR_RS_W:
16904 tcg_gen_movi_tl(t0, v2);
16905 tcg_gen_movi_tl(t1, v1);
16906 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16907 break;
16908 case OPC_DEXTR_S_H:
16909 tcg_gen_movi_tl(t0, v2);
16910 tcg_gen_movi_tl(t1, v1);
16911 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16912 break;
16913 case OPC_DEXTRV_S_H:
16914 tcg_gen_movi_tl(t0, v2);
16915 tcg_gen_movi_tl(t1, v1);
16916 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16917 break;
16918 case OPC_DEXTRV_L:
16919 tcg_gen_movi_tl(t0, v2);
16920 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16921 break;
16922 case OPC_DEXTRV_R_L:
16923 tcg_gen_movi_tl(t0, v2);
16924 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16925 break;
16926 case OPC_DEXTRV_RS_L:
16927 tcg_gen_movi_tl(t0, v2);
16928 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16929 break;
16930 case OPC_DEXTRV_W:
16931 tcg_gen_movi_tl(t0, v2);
16932 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16933 break;
16934 case OPC_DEXTRV_R_W:
16935 tcg_gen_movi_tl(t0, v2);
16936 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16937 break;
16938 case OPC_DEXTRV_RS_W:
16939 tcg_gen_movi_tl(t0, v2);
16940 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16941 break;
16942 }
16943 break;
16944#endif
16945 }
16946
16947 tcg_temp_free(t0);
16948 tcg_temp_free(t1);
16949 tcg_temp_free(v1_t);
16950 tcg_temp_free(v2_t);
b53371ed
JL
16951}
16952
9b1a1d68
JL
16953/* End MIPSDSP functions. */
16954
10dc65db
LA
16955static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16956{
4267d3e6 16957 int rs, rt, rd, sa;
b42ee5e1 16958 uint32_t op1, op2;
10dc65db
LA
16959
16960 rs = (ctx->opcode >> 21) & 0x1f;
16961 rt = (ctx->opcode >> 16) & 0x1f;
16962 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16963 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16964
16965 op1 = MASK_SPECIAL(ctx->opcode);
16966 switch (op1) {
d4ea6acd 16967 case OPC_LSA:
1f1b4c00 16968 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16969 break;
b42ee5e1
LA
16970 case OPC_MULT ... OPC_DIVU:
16971 op2 = MASK_R6_MULDIV(ctx->opcode);
16972 switch (op2) {
16973 case R6_OPC_MUL:
16974 case R6_OPC_MUH:
16975 case R6_OPC_MULU:
16976 case R6_OPC_MUHU:
16977 case R6_OPC_DIV:
16978 case R6_OPC_MOD:
16979 case R6_OPC_DIVU:
16980 case R6_OPC_MODU:
16981 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16982 break;
16983 default:
16984 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16985 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16986 break;
16987 }
16988 break;
10dc65db
LA
16989 case OPC_SELEQZ:
16990 case OPC_SELNEZ:
16991 gen_cond_move(ctx, op1, rd, rs, rt);
16992 break;
4267d3e6
LA
16993 case R6_OPC_CLO:
16994 case R6_OPC_CLZ:
16995 if (rt == 0 && sa == 1) {
16996 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16997 We need additionally to check other fields */
16998 gen_cl(ctx, op1, rd, rs);
16999 } else {
9c708c7f 17000 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17001 }
17002 break;
17003 case R6_OPC_SDBBP:
3b3c1694
LA
17004 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17005 gen_helper_do_semihosting(cpu_env);
faf1f68b 17006 } else {
3b3c1694 17007 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17008 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17009 } else {
9c708c7f 17010 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17011 }
faf1f68b 17012 }
4267d3e6 17013 break;
b42ee5e1 17014#if defined(TARGET_MIPS64)
d4ea6acd
LA
17015 case OPC_DLSA:
17016 check_mips_64(ctx);
1f1b4c00 17017 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17018 break;
4267d3e6
LA
17019 case R6_OPC_DCLO:
17020 case R6_OPC_DCLZ:
17021 if (rt == 0 && sa == 1) {
17022 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17023 We need additionally to check other fields */
17024 check_mips_64(ctx);
17025 gen_cl(ctx, op1, rd, rs);
17026 } else {
9c708c7f 17027 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17028 }
17029 break;
b42ee5e1
LA
17030 case OPC_DMULT ... OPC_DDIVU:
17031 op2 = MASK_R6_MULDIV(ctx->opcode);
17032 switch (op2) {
17033 case R6_OPC_DMUL:
17034 case R6_OPC_DMUH:
17035 case R6_OPC_DMULU:
17036 case R6_OPC_DMUHU:
17037 case R6_OPC_DDIV:
17038 case R6_OPC_DMOD:
17039 case R6_OPC_DDIVU:
17040 case R6_OPC_DMODU:
17041 check_mips_64(ctx);
17042 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17043 break;
17044 default:
17045 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17046 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17047 break;
17048 }
17049 break;
17050#endif
10dc65db
LA
17051 default: /* Invalid */
17052 MIPS_INVAL("special_r6");
9c708c7f 17053 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17054 break;
17055 }
17056}
17057
17058static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17059{
b42ee5e1 17060 int rs, rt, rd, sa;
10dc65db
LA
17061 uint32_t op1;
17062
17063 rs = (ctx->opcode >> 21) & 0x1f;
17064 rt = (ctx->opcode >> 16) & 0x1f;
17065 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17066 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17067
17068 op1 = MASK_SPECIAL(ctx->opcode);
17069 switch (op1) {
17070 case OPC_MOVN: /* Conditional move */
17071 case OPC_MOVZ:
17072 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17073 INSN_LOONGSON2E | INSN_LOONGSON2F);
17074 gen_cond_move(ctx, op1, rd, rs, rt);
17075 break;
17076 case OPC_MFHI: /* Move from HI/LO */
17077 case OPC_MFLO:
17078 gen_HILO(ctx, op1, rs & 3, rd);
17079 break;
17080 case OPC_MTHI:
17081 case OPC_MTLO: /* Move to HI/LO */
17082 gen_HILO(ctx, op1, rd & 3, rs);
17083 break;
17084 case OPC_MOVCI:
17085 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17086 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17087 check_cp1_enabled(ctx);
17088 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17089 (ctx->opcode >> 16) & 1);
17090 } else {
17091 generate_exception_err(ctx, EXCP_CpU, 1);
17092 }
17093 break;
b42ee5e1
LA
17094 case OPC_MULT:
17095 case OPC_MULTU:
17096 if (sa) {
17097 check_insn(ctx, INSN_VR54XX);
17098 op1 = MASK_MUL_VR54XX(ctx->opcode);
17099 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17100 } else {
17101 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17102 }
17103 break;
17104 case OPC_DIV:
17105 case OPC_DIVU:
17106 gen_muldiv(ctx, op1, 0, rs, rt);
17107 break;
17108#if defined(TARGET_MIPS64)
17109 case OPC_DMULT ... OPC_DDIVU:
17110 check_insn(ctx, ISA_MIPS3);
17111 check_mips_64(ctx);
17112 gen_muldiv(ctx, op1, 0, rs, rt);
17113 break;
17114#endif
0aefa333 17115 case OPC_JR:
b231c103 17116 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17117 break;
4267d3e6
LA
17118 case OPC_SPIM:
17119#ifdef MIPS_STRICT_STANDARD
17120 MIPS_INVAL("SPIM");
9c708c7f 17121 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17122#else
17123 /* Implemented as RI exception for now. */
17124 MIPS_INVAL("spim (unofficial)");
9c708c7f 17125 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17126#endif
17127 break;
10dc65db
LA
17128 default: /* Invalid */
17129 MIPS_INVAL("special_legacy");
9c708c7f 17130 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17131 break;
17132 }
17133}
17134
099e5b4d 17135static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17136{
3c824109 17137 int rs, rt, rd, sa;
099e5b4d 17138 uint32_t op1;
3c824109 17139
3c824109
NF
17140 rs = (ctx->opcode >> 21) & 0x1f;
17141 rt = (ctx->opcode >> 16) & 0x1f;
17142 rd = (ctx->opcode >> 11) & 0x1f;
17143 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17144
17145 op1 = MASK_SPECIAL(ctx->opcode);
17146 switch (op1) {
17147 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17148 if (sa == 5 && rd == 0 &&
17149 rs == 0 && rt == 0) { /* PAUSE */
17150 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17151 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17152 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17153 break;
17154 }
17155 }
17156 /* Fallthrough */
099e5b4d
LA
17157 case OPC_SRA:
17158 gen_shift_imm(ctx, op1, rd, rt, sa);
17159 break;
17160 case OPC_SRL:
17161 switch ((ctx->opcode >> 21) & 0x1f) {
17162 case 1:
17163 /* rotr is decoded as srl on non-R2 CPUs */
17164 if (ctx->insn_flags & ISA_MIPS32R2) {
17165 op1 = OPC_ROTR;
ea63e2c3 17166 }
099e5b4d
LA
17167 /* Fallthrough */
17168 case 0:
17169 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17170 break;
099e5b4d 17171 default:
9c708c7f 17172 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17173 break;
099e5b4d
LA
17174 }
17175 break;
099e5b4d
LA
17176 case OPC_ADD ... OPC_SUBU:
17177 gen_arith(ctx, op1, rd, rs, rt);
17178 break;
17179 case OPC_SLLV: /* Shifts */
17180 case OPC_SRAV:
17181 gen_shift(ctx, op1, rd, rs, rt);
17182 break;
17183 case OPC_SRLV:
17184 switch ((ctx->opcode >> 6) & 0x1f) {
17185 case 1:
17186 /* rotrv is decoded as srlv on non-R2 CPUs */
17187 if (ctx->insn_flags & ISA_MIPS32R2) {
17188 op1 = OPC_ROTRV;
26135ead 17189 }
099e5b4d
LA
17190 /* Fallthrough */
17191 case 0:
17192 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17193 break;
099e5b4d 17194 default:
9c708c7f 17195 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17196 break;
099e5b4d
LA
17197 }
17198 break;
17199 case OPC_SLT: /* Set on less than */
17200 case OPC_SLTU:
17201 gen_slt(ctx, op1, rd, rs, rt);
17202 break;
17203 case OPC_AND: /* Logic*/
17204 case OPC_OR:
17205 case OPC_NOR:
17206 case OPC_XOR:
17207 gen_logic(ctx, op1, rd, rs, rt);
17208 break;
0aefa333 17209 case OPC_JALR:
b231c103 17210 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
17211 break;
17212 case OPC_TGE ... OPC_TEQ: /* Traps */
17213 case OPC_TNE:
d9224450 17214 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17215 gen_trap(ctx, op1, rs, rt, -1);
17216 break;
d4ea6acd 17217 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17218 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17219 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17220 decode_opc_special_r6(env, ctx);
17221 } else {
17222 /* Pmon entry point, also R4010 selsl */
b48cfdff 17223#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17224 MIPS_INVAL("PMON / selsl");
9c708c7f 17225 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17226#else
d4ea6acd 17227 gen_helper_0e0i(pmon, sa);
b48cfdff 17228#endif
d4ea6acd 17229 }
099e5b4d
LA
17230 break;
17231 case OPC_SYSCALL:
9c708c7f 17232 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17233 break;
17234 case OPC_BREAK:
9c708c7f 17235 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17236 break;
099e5b4d 17237 case OPC_SYNC:
d9224450 17238 check_insn(ctx, ISA_MIPS2);
d208ac0c 17239 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17240 break;
4ad40f36 17241
d26bc211 17242#if defined(TARGET_MIPS64)
099e5b4d
LA
17243 /* MIPS64 specific opcodes */
17244 case OPC_DSLL:
17245 case OPC_DSRA:
17246 case OPC_DSLL32:
17247 case OPC_DSRA32:
17248 check_insn(ctx, ISA_MIPS3);
17249 check_mips_64(ctx);
17250 gen_shift_imm(ctx, op1, rd, rt, sa);
17251 break;
17252 case OPC_DSRL:
17253 switch ((ctx->opcode >> 21) & 0x1f) {
17254 case 1:
17255 /* drotr is decoded as dsrl on non-R2 CPUs */
17256 if (ctx->insn_flags & ISA_MIPS32R2) {
17257 op1 = OPC_DROTR;
ea63e2c3 17258 }
099e5b4d
LA
17259 /* Fallthrough */
17260 case 0:
d75c135e 17261 check_insn(ctx, ISA_MIPS3);
e189e748 17262 check_mips_64(ctx);
099e5b4d 17263 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17264 break;
099e5b4d 17265 default:
9c708c7f 17266 generate_exception_end(ctx, EXCP_RI);
460f00c4 17267 break;
099e5b4d
LA
17268 }
17269 break;
17270 case OPC_DSRL32:
17271 switch ((ctx->opcode >> 21) & 0x1f) {
17272 case 1:
17273 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17274 if (ctx->insn_flags & ISA_MIPS32R2) {
17275 op1 = OPC_DROTR32;
ea63e2c3 17276 }
099e5b4d
LA
17277 /* Fallthrough */
17278 case 0:
d75c135e 17279 check_insn(ctx, ISA_MIPS3);
e189e748 17280 check_mips_64(ctx);
099e5b4d 17281 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17282 break;
099e5b4d 17283 default:
9c708c7f 17284 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17285 break;
17286 }
17287 break;
099e5b4d
LA
17288 case OPC_DADD ... OPC_DSUBU:
17289 check_insn(ctx, ISA_MIPS3);
17290 check_mips_64(ctx);
17291 gen_arith(ctx, op1, rd, rs, rt);
17292 break;
17293 case OPC_DSLLV:
17294 case OPC_DSRAV:
17295 check_insn(ctx, ISA_MIPS3);
17296 check_mips_64(ctx);
17297 gen_shift(ctx, op1, rd, rs, rt);
17298 break;
17299 case OPC_DSRLV:
17300 switch ((ctx->opcode >> 6) & 0x1f) {
17301 case 1:
17302 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17303 if (ctx->insn_flags & ISA_MIPS32R2) {
17304 op1 = OPC_DROTRV;
6af0bf9c 17305 }
099e5b4d
LA
17306 /* Fallthrough */
17307 case 0:
17308 check_insn(ctx, ISA_MIPS3);
e189e748 17309 check_mips_64(ctx);
099e5b4d 17310 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17311 break;
099e5b4d 17312 default:
9c708c7f 17313 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17314 break;
17315 }
17316 break;
f7685877
YK
17317 case OPC_DLSA:
17318 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17319 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17320 decode_opc_special_r6(env, ctx);
17321 }
17322 break;
099e5b4d 17323#endif
10dc65db
LA
17324 default:
17325 if (ctx->insn_flags & ISA_MIPS32R6) {
17326 decode_opc_special_r6(env, ctx);
17327 } else {
17328 decode_opc_special_legacy(env, ctx);
17329 }
17330 }
17331}
17332
10dc65db 17333static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17334{
17335 int rs, rt, rd;
17336 uint32_t op1;
6c5c1e20 17337
4267d3e6
LA
17338 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17339
099e5b4d
LA
17340 rs = (ctx->opcode >> 21) & 0x1f;
17341 rt = (ctx->opcode >> 16) & 0x1f;
17342 rd = (ctx->opcode >> 11) & 0x1f;
17343
17344 op1 = MASK_SPECIAL2(ctx->opcode);
17345 switch (op1) {
17346 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17347 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17348 check_insn(ctx, ISA_MIPS32);
17349 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17350 break;
17351 case OPC_MUL:
099e5b4d
LA
17352 gen_arith(ctx, op1, rd, rs, rt);
17353 break;
fac5a073
LA
17354 case OPC_DIV_G_2F:
17355 case OPC_DIVU_G_2F:
17356 case OPC_MULT_G_2F:
17357 case OPC_MULTU_G_2F:
17358 case OPC_MOD_G_2F:
17359 case OPC_MODU_G_2F:
17360 check_insn(ctx, INSN_LOONGSON2F);
17361 gen_loongson_integer(ctx, op1, rd, rs, rt);
17362 break;
099e5b4d
LA
17363 case OPC_CLO:
17364 case OPC_CLZ:
17365 check_insn(ctx, ISA_MIPS32);
17366 gen_cl(ctx, op1, rd, rs);
17367 break;
17368 case OPC_SDBBP:
3b3c1694
LA
17369 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17370 gen_helper_do_semihosting(cpu_env);
17371 } else {
17372 /* XXX: not clear which exception should be raised
17373 * when in debug mode...
17374 */
17375 check_insn(ctx, ISA_MIPS32);
9c708c7f 17376 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17377 }
099e5b4d 17378 break;
9b1a1d68 17379#if defined(TARGET_MIPS64)
099e5b4d
LA
17380 case OPC_DCLO:
17381 case OPC_DCLZ:
17382 check_insn(ctx, ISA_MIPS64);
17383 check_mips_64(ctx);
17384 gen_cl(ctx, op1, rd, rs);
17385 break;
4267d3e6
LA
17386 case OPC_DMULT_G_2F:
17387 case OPC_DMULTU_G_2F:
17388 case OPC_DDIV_G_2F:
17389 case OPC_DDIVU_G_2F:
17390 case OPC_DMOD_G_2F:
17391 case OPC_DMODU_G_2F:
17392 check_insn(ctx, INSN_LOONGSON2F);
17393 gen_loongson_integer(ctx, op1, rd, rs, rt);
17394 break;
10dc65db 17395#endif
4267d3e6
LA
17396 default: /* Invalid */
17397 MIPS_INVAL("special2_legacy");
9c708c7f 17398 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17399 break;
10dc65db
LA
17400 }
17401}
17402
17403static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17404{
15eacb9b
YK
17405 int rs, rt, rd, sa;
17406 uint32_t op1, op2;
10dc65db
LA
17407 int16_t imm;
17408
17409 rs = (ctx->opcode >> 21) & 0x1f;
17410 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17411 rd = (ctx->opcode >> 11) & 0x1f;
17412 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17413 imm = (int16_t)ctx->opcode >> 7;
17414
17415 op1 = MASK_SPECIAL3(ctx->opcode);
17416 switch (op1) {
bf7910c6
LA
17417 case R6_OPC_PREF:
17418 if (rt >= 24) {
17419 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17420 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17421 }
17422 /* Treat as NOP. */
17423 break;
17424 case R6_OPC_CACHE:
40d48212 17425 check_cp0_enabled(ctx);
0d74a222
LA
17426 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17427 gen_cache_operation(ctx, rt, rs, imm);
17428 }
bf7910c6 17429 break;
10dc65db
LA
17430 case R6_OPC_SC:
17431 gen_st_cond(ctx, op1, rt, rs, imm);
17432 break;
17433 case R6_OPC_LL:
17434 gen_ld(ctx, op1, rt, rs, imm);
17435 break;
15eacb9b
YK
17436 case OPC_BSHFL:
17437 {
17438 if (rd == 0) {
17439 /* Treat as NOP. */
17440 break;
17441 }
15eacb9b
YK
17442 op2 = MASK_BSHFL(ctx->opcode);
17443 switch (op2) {
17444 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17445 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17446 break;
17447 case OPC_BITSWAP:
1f1b4c00 17448 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17449 break;
17450 }
15eacb9b
YK
17451 }
17452 break;
bf7910c6
LA
17453#if defined(TARGET_MIPS64)
17454 case R6_OPC_SCD:
17455 gen_st_cond(ctx, op1, rt, rs, imm);
17456 break;
17457 case R6_OPC_LLD:
17458 gen_ld(ctx, op1, rt, rs, imm);
17459 break;
15eacb9b
YK
17460 case OPC_DBSHFL:
17461 check_mips_64(ctx);
17462 {
17463 if (rd == 0) {
17464 /* Treat as NOP. */
17465 break;
17466 }
15eacb9b
YK
17467 op2 = MASK_DBSHFL(ctx->opcode);
17468 switch (op2) {
17469 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17470 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17471 break;
17472 case OPC_DBITSWAP:
1f1b4c00 17473 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17474 break;
17475 }
1f1b4c00 17476
15eacb9b
YK
17477 }
17478 break;
bf7910c6 17479#endif
10dc65db
LA
17480 default: /* Invalid */
17481 MIPS_INVAL("special3_r6");
9c708c7f 17482 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17483 break;
17484 }
17485}
17486
17487static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17488{
fac5a073 17489 int rs, rt, rd;
099e5b4d 17490 uint32_t op1, op2;
099e5b4d
LA
17491
17492 rs = (ctx->opcode >> 21) & 0x1f;
17493 rt = (ctx->opcode >> 16) & 0x1f;
17494 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17495
17496 op1 = MASK_SPECIAL3(ctx->opcode);
17497 switch (op1) {
099e5b4d
LA
17498 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17499 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17500 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17501 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17502 * the same mask and op1. */
17503 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17504 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17505 switch (op2) {
099e5b4d
LA
17506 case OPC_ADDUH_QB:
17507 case OPC_ADDUH_R_QB:
17508 case OPC_ADDQH_PH:
17509 case OPC_ADDQH_R_PH:
17510 case OPC_ADDQH_W:
17511 case OPC_ADDQH_R_W:
17512 case OPC_SUBUH_QB:
17513 case OPC_SUBUH_R_QB:
17514 case OPC_SUBQH_PH:
17515 case OPC_SUBQH_R_PH:
17516 case OPC_SUBQH_W:
17517 case OPC_SUBQH_R_W:
461c08df
JL
17518 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17519 break;
099e5b4d
LA
17520 case OPC_MUL_PH:
17521 case OPC_MUL_S_PH:
17522 case OPC_MULQ_S_W:
17523 case OPC_MULQ_RS_W:
17524 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17525 break;
461c08df 17526 default:
099e5b4d 17527 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17528 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17529 break;
17530 }
099e5b4d
LA
17531 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17532 gen_loongson_integer(ctx, op1, rd, rs, rt);
17533 } else {
9c708c7f 17534 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17535 }
17536 break;
17537 case OPC_LX_DSP:
17538 op2 = MASK_LX(ctx->opcode);
17539 switch (op2) {
17540#if defined(TARGET_MIPS64)
17541 case OPC_LDX:
17542#endif
17543 case OPC_LBUX:
17544 case OPC_LHX:
17545 case OPC_LWX:
17546 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17547 break;
17548 default: /* Invalid */
17549 MIPS_INVAL("MASK LX");
9c708c7f 17550 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17551 break;
17552 }
17553 break;
17554 case OPC_ABSQ_S_PH_DSP:
17555 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17556 switch (op2) {
17557 case OPC_ABSQ_S_QB:
17558 case OPC_ABSQ_S_PH:
17559 case OPC_ABSQ_S_W:
17560 case OPC_PRECEQ_W_PHL:
17561 case OPC_PRECEQ_W_PHR:
17562 case OPC_PRECEQU_PH_QBL:
17563 case OPC_PRECEQU_PH_QBR:
17564 case OPC_PRECEQU_PH_QBLA:
17565 case OPC_PRECEQU_PH_QBRA:
17566 case OPC_PRECEU_PH_QBL:
17567 case OPC_PRECEU_PH_QBR:
17568 case OPC_PRECEU_PH_QBLA:
17569 case OPC_PRECEU_PH_QBRA:
17570 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17571 break;
17572 case OPC_BITREV:
17573 case OPC_REPL_QB:
17574 case OPC_REPLV_QB:
17575 case OPC_REPL_PH:
17576 case OPC_REPLV_PH:
17577 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17578 break;
17579 default:
17580 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17581 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17582 break;
17583 }
17584 break;
17585 case OPC_ADDU_QB_DSP:
17586 op2 = MASK_ADDU_QB(ctx->opcode);
17587 switch (op2) {
17588 case OPC_ADDQ_PH:
17589 case OPC_ADDQ_S_PH:
17590 case OPC_ADDQ_S_W:
17591 case OPC_ADDU_QB:
17592 case OPC_ADDU_S_QB:
17593 case OPC_ADDU_PH:
17594 case OPC_ADDU_S_PH:
17595 case OPC_SUBQ_PH:
17596 case OPC_SUBQ_S_PH:
17597 case OPC_SUBQ_S_W:
17598 case OPC_SUBU_QB:
17599 case OPC_SUBU_S_QB:
17600 case OPC_SUBU_PH:
17601 case OPC_SUBU_S_PH:
17602 case OPC_ADDSC:
17603 case OPC_ADDWC:
17604 case OPC_MODSUB:
17605 case OPC_RADDU_W_QB:
17606 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17607 break;
17608 case OPC_MULEU_S_PH_QBL:
17609 case OPC_MULEU_S_PH_QBR:
17610 case OPC_MULQ_RS_PH:
17611 case OPC_MULEQ_S_W_PHL:
17612 case OPC_MULEQ_S_W_PHR:
17613 case OPC_MULQ_S_PH:
17614 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17615 break;
17616 default: /* Invalid */
17617 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17618 generate_exception_end(ctx, EXCP_RI);
461c08df 17619 break;
461c08df 17620
099e5b4d
LA
17621 }
17622 break;
17623 case OPC_CMPU_EQ_QB_DSP:
17624 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17625 switch (op2) {
17626 case OPC_PRECR_SRA_PH_W:
17627 case OPC_PRECR_SRA_R_PH_W:
17628 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17629 break;
099e5b4d
LA
17630 case OPC_PRECR_QB_PH:
17631 case OPC_PRECRQ_QB_PH:
17632 case OPC_PRECRQ_PH_W:
17633 case OPC_PRECRQ_RS_PH_W:
17634 case OPC_PRECRQU_S_QB_PH:
17635 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17636 break;
099e5b4d
LA
17637 case OPC_CMPU_EQ_QB:
17638 case OPC_CMPU_LT_QB:
17639 case OPC_CMPU_LE_QB:
17640 case OPC_CMP_EQ_PH:
17641 case OPC_CMP_LT_PH:
17642 case OPC_CMP_LE_PH:
17643 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17644 break;
099e5b4d
LA
17645 case OPC_CMPGU_EQ_QB:
17646 case OPC_CMPGU_LT_QB:
17647 case OPC_CMPGU_LE_QB:
17648 case OPC_CMPGDU_EQ_QB:
17649 case OPC_CMPGDU_LT_QB:
17650 case OPC_CMPGDU_LE_QB:
17651 case OPC_PICK_QB:
17652 case OPC_PICK_PH:
17653 case OPC_PACKRL_PH:
17654 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17655 break;
17656 default: /* Invalid */
17657 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17658 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17659 break;
17660 }
17661 break;
17662 case OPC_SHLL_QB_DSP:
17663 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17664 break;
17665 case OPC_DPA_W_PH_DSP:
17666 op2 = MASK_DPA_W_PH(ctx->opcode);
17667 switch (op2) {
17668 case OPC_DPAU_H_QBL:
17669 case OPC_DPAU_H_QBR:
17670 case OPC_DPSU_H_QBL:
17671 case OPC_DPSU_H_QBR:
17672 case OPC_DPA_W_PH:
17673 case OPC_DPAX_W_PH:
17674 case OPC_DPAQ_S_W_PH:
17675 case OPC_DPAQX_S_W_PH:
17676 case OPC_DPAQX_SA_W_PH:
17677 case OPC_DPS_W_PH:
17678 case OPC_DPSX_W_PH:
17679 case OPC_DPSQ_S_W_PH:
17680 case OPC_DPSQX_S_W_PH:
17681 case OPC_DPSQX_SA_W_PH:
17682 case OPC_MULSAQ_S_W_PH:
17683 case OPC_DPAQ_SA_L_W:
17684 case OPC_DPSQ_SA_L_W:
17685 case OPC_MAQ_S_W_PHL:
17686 case OPC_MAQ_S_W_PHR:
17687 case OPC_MAQ_SA_W_PHL:
17688 case OPC_MAQ_SA_W_PHR:
17689 case OPC_MULSA_W_PH:
17690 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17691 break;
17692 default: /* Invalid */
17693 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17694 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17695 break;
17696 }
17697 break;
17698 case OPC_INSV_DSP:
17699 op2 = MASK_INSV(ctx->opcode);
17700 switch (op2) {
17701 case OPC_INSV:
17702 check_dsp(ctx);
17703 {
17704 TCGv t0, t1;
17705
17706 if (rt == 0) {
099e5b4d
LA
17707 break;
17708 }
17709
17710 t0 = tcg_temp_new();
17711 t1 = tcg_temp_new();
17712
17713 gen_load_gpr(t0, rt);
17714 gen_load_gpr(t1, rs);
17715
17716 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17717
17718 tcg_temp_free(t0);
17719 tcg_temp_free(t1);
a22260ae
JL
17720 break;
17721 }
099e5b4d
LA
17722 default: /* Invalid */
17723 MIPS_INVAL("MASK INSV");
9c708c7f 17724 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17725 break;
17726 }
17727 break;
17728 case OPC_APPEND_DSP:
17729 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17730 break;
17731 case OPC_EXTR_W_DSP:
17732 op2 = MASK_EXTR_W(ctx->opcode);
17733 switch (op2) {
17734 case OPC_EXTR_W:
17735 case OPC_EXTR_R_W:
17736 case OPC_EXTR_RS_W:
17737 case OPC_EXTR_S_H:
17738 case OPC_EXTRV_S_H:
17739 case OPC_EXTRV_W:
17740 case OPC_EXTRV_R_W:
17741 case OPC_EXTRV_RS_W:
17742 case OPC_EXTP:
17743 case OPC_EXTPV:
17744 case OPC_EXTPDP:
17745 case OPC_EXTPDPV:
17746 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17747 break;
17748 case OPC_RDDSP:
17749 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17750 break;
17751 case OPC_SHILO:
17752 case OPC_SHILOV:
17753 case OPC_MTHLIP:
17754 case OPC_WRDSP:
17755 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17756 break;
17757 default: /* Invalid */
17758 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17759 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17760 break;
17761 }
17762 break;
099e5b4d 17763#if defined(TARGET_MIPS64)
fac5a073
LA
17764 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17765 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17766 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17767 check_insn(ctx, INSN_LOONGSON2E);
17768 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17769 break;
099e5b4d
LA
17770 case OPC_ABSQ_S_QH_DSP:
17771 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17772 switch (op2) {
17773 case OPC_PRECEQ_L_PWL:
17774 case OPC_PRECEQ_L_PWR:
17775 case OPC_PRECEQ_PW_QHL:
17776 case OPC_PRECEQ_PW_QHR:
17777 case OPC_PRECEQ_PW_QHLA:
17778 case OPC_PRECEQ_PW_QHRA:
17779 case OPC_PRECEQU_QH_OBL:
17780 case OPC_PRECEQU_QH_OBR:
17781 case OPC_PRECEQU_QH_OBLA:
17782 case OPC_PRECEQU_QH_OBRA:
17783 case OPC_PRECEU_QH_OBL:
17784 case OPC_PRECEU_QH_OBR:
17785 case OPC_PRECEU_QH_OBLA:
17786 case OPC_PRECEU_QH_OBRA:
17787 case OPC_ABSQ_S_OB:
17788 case OPC_ABSQ_S_PW:
17789 case OPC_ABSQ_S_QH:
17790 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17791 break;
17792 case OPC_REPL_OB:
17793 case OPC_REPL_PW:
17794 case OPC_REPL_QH:
17795 case OPC_REPLV_OB:
17796 case OPC_REPLV_PW:
17797 case OPC_REPLV_QH:
17798 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17799 break;
17800 default: /* Invalid */
17801 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 17802 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17803 break;
17804 }
17805 break;
17806 case OPC_ADDU_OB_DSP:
17807 op2 = MASK_ADDU_OB(ctx->opcode);
17808 switch (op2) {
17809 case OPC_RADDU_L_OB:
17810 case OPC_SUBQ_PW:
17811 case OPC_SUBQ_S_PW:
17812 case OPC_SUBQ_QH:
17813 case OPC_SUBQ_S_QH:
17814 case OPC_SUBU_OB:
17815 case OPC_SUBU_S_OB:
17816 case OPC_SUBU_QH:
17817 case OPC_SUBU_S_QH:
17818 case OPC_SUBUH_OB:
17819 case OPC_SUBUH_R_OB:
17820 case OPC_ADDQ_PW:
17821 case OPC_ADDQ_S_PW:
17822 case OPC_ADDQ_QH:
17823 case OPC_ADDQ_S_QH:
17824 case OPC_ADDU_OB:
17825 case OPC_ADDU_S_OB:
17826 case OPC_ADDU_QH:
17827 case OPC_ADDU_S_QH:
17828 case OPC_ADDUH_OB:
17829 case OPC_ADDUH_R_OB:
17830 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17831 break;
099e5b4d
LA
17832 case OPC_MULEQ_S_PW_QHL:
17833 case OPC_MULEQ_S_PW_QHR:
17834 case OPC_MULEU_S_QH_OBL:
17835 case OPC_MULEU_S_QH_OBR:
17836 case OPC_MULQ_RS_QH:
17837 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17838 break;
099e5b4d
LA
17839 default: /* Invalid */
17840 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 17841 generate_exception_end(ctx, EXCP_RI);
26690560 17842 break;
099e5b4d
LA
17843 }
17844 break;
17845 case OPC_CMPU_EQ_OB_DSP:
17846 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17847 switch (op2) {
17848 case OPC_PRECR_SRA_QH_PW:
17849 case OPC_PRECR_SRA_R_QH_PW:
17850 /* Return value is rt. */
17851 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17852 break;
099e5b4d
LA
17853 case OPC_PRECR_OB_QH:
17854 case OPC_PRECRQ_OB_QH:
17855 case OPC_PRECRQ_PW_L:
17856 case OPC_PRECRQ_QH_PW:
17857 case OPC_PRECRQ_RS_QH_PW:
17858 case OPC_PRECRQU_S_OB_QH:
17859 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17860 break;
099e5b4d
LA
17861 case OPC_CMPU_EQ_OB:
17862 case OPC_CMPU_LT_OB:
17863 case OPC_CMPU_LE_OB:
17864 case OPC_CMP_EQ_QH:
17865 case OPC_CMP_LT_QH:
17866 case OPC_CMP_LE_QH:
17867 case OPC_CMP_EQ_PW:
17868 case OPC_CMP_LT_PW:
17869 case OPC_CMP_LE_PW:
17870 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17871 break;
099e5b4d
LA
17872 case OPC_CMPGDU_EQ_OB:
17873 case OPC_CMPGDU_LT_OB:
17874 case OPC_CMPGDU_LE_OB:
17875 case OPC_CMPGU_EQ_OB:
17876 case OPC_CMPGU_LT_OB:
17877 case OPC_CMPGU_LE_OB:
17878 case OPC_PACKRL_PW:
17879 case OPC_PICK_OB:
17880 case OPC_PICK_PW:
17881 case OPC_PICK_QH:
17882 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17883 break;
099e5b4d
LA
17884 default: /* Invalid */
17885 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 17886 generate_exception_end(ctx, EXCP_RI);
161f85e6 17887 break;
099e5b4d
LA
17888 }
17889 break;
17890 case OPC_DAPPEND_DSP:
17891 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17892 break;
17893 case OPC_DEXTR_W_DSP:
17894 op2 = MASK_DEXTR_W(ctx->opcode);
17895 switch (op2) {
17896 case OPC_DEXTP:
17897 case OPC_DEXTPDP:
17898 case OPC_DEXTPDPV:
17899 case OPC_DEXTPV:
17900 case OPC_DEXTR_L:
17901 case OPC_DEXTR_R_L:
17902 case OPC_DEXTR_RS_L:
17903 case OPC_DEXTR_W:
17904 case OPC_DEXTR_R_W:
17905 case OPC_DEXTR_RS_W:
17906 case OPC_DEXTR_S_H:
17907 case OPC_DEXTRV_L:
17908 case OPC_DEXTRV_R_L:
17909 case OPC_DEXTRV_RS_L:
17910 case OPC_DEXTRV_S_H:
17911 case OPC_DEXTRV_W:
17912 case OPC_DEXTRV_R_W:
17913 case OPC_DEXTRV_RS_W:
17914 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17915 break;
099e5b4d
LA
17916 case OPC_DMTHLIP:
17917 case OPC_DSHILO:
17918 case OPC_DSHILOV:
17919 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17920 break;
099e5b4d
LA
17921 default: /* Invalid */
17922 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17923 generate_exception_end(ctx, EXCP_RI);
461c08df 17924 break;
099e5b4d
LA
17925 }
17926 break;
17927 case OPC_DPAQ_W_QH_DSP:
17928 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17929 switch (op2) {
17930 case OPC_DPAU_H_OBL:
17931 case OPC_DPAU_H_OBR:
17932 case OPC_DPSU_H_OBL:
17933 case OPC_DPSU_H_OBR:
17934 case OPC_DPA_W_QH:
17935 case OPC_DPAQ_S_W_QH:
17936 case OPC_DPS_W_QH:
17937 case OPC_DPSQ_S_W_QH:
17938 case OPC_MULSAQ_S_W_QH:
17939 case OPC_DPAQ_SA_L_PW:
17940 case OPC_DPSQ_SA_L_PW:
17941 case OPC_MULSAQ_S_L_PW:
17942 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17943 break;
17944 case OPC_MAQ_S_W_QHLL:
17945 case OPC_MAQ_S_W_QHLR:
17946 case OPC_MAQ_S_W_QHRL:
17947 case OPC_MAQ_S_W_QHRR:
17948 case OPC_MAQ_SA_W_QHLL:
17949 case OPC_MAQ_SA_W_QHLR:
17950 case OPC_MAQ_SA_W_QHRL:
17951 case OPC_MAQ_SA_W_QHRR:
17952 case OPC_MAQ_S_L_PWL:
17953 case OPC_MAQ_S_L_PWR:
17954 case OPC_DMADD:
17955 case OPC_DMADDU:
17956 case OPC_DMSUB:
17957 case OPC_DMSUBU:
17958 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17959 break;
099e5b4d
LA
17960 default: /* Invalid */
17961 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 17962 generate_exception_end(ctx, EXCP_RI);
b53371ed 17963 break;
099e5b4d
LA
17964 }
17965 break;
17966 case OPC_DINSV_DSP:
17967 op2 = MASK_INSV(ctx->opcode);
17968 switch (op2) {
17969 case OPC_DINSV:
17970 {
17971 TCGv t0, t1;
17972
17973 if (rt == 0) {
a22260ae
JL
17974 break;
17975 }
099e5b4d 17976 check_dsp(ctx);
1cb6686c 17977
099e5b4d
LA
17978 t0 = tcg_temp_new();
17979 t1 = tcg_temp_new();
1cb6686c 17980
099e5b4d
LA
17981 gen_load_gpr(t0, rt);
17982 gen_load_gpr(t1, rs);
1cb6686c 17983
099e5b4d 17984 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17985
099e5b4d
LA
17986 tcg_temp_free(t0);
17987 tcg_temp_free(t1);
77c5fa8b 17988 break;
099e5b4d 17989 }
7a387fff 17990 default: /* Invalid */
099e5b4d 17991 MIPS_INVAL("MASK DINSV");
9c708c7f 17992 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
17993 break;
17994 }
17995 break;
099e5b4d
LA
17996 case OPC_SHLL_OB_DSP:
17997 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17998 break;
17999#endif
fac5a073
LA
18000 default: /* Invalid */
18001 MIPS_INVAL("special3_legacy");
9c708c7f 18002 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18003 break;
18004 }
18005}
18006
18007static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18008{
18009 int rs, rt, rd, sa;
18010 uint32_t op1, op2;
18011
18012 rs = (ctx->opcode >> 21) & 0x1f;
18013 rt = (ctx->opcode >> 16) & 0x1f;
18014 rd = (ctx->opcode >> 11) & 0x1f;
18015 sa = (ctx->opcode >> 6) & 0x1f;
18016
18017 op1 = MASK_SPECIAL3(ctx->opcode);
18018 switch (op1) {
18019 case OPC_EXT:
18020 case OPC_INS:
18021 check_insn(ctx, ISA_MIPS32R2);
18022 gen_bitops(ctx, op1, rt, rs, sa, rd);
18023 break;
18024 case OPC_BSHFL:
fac5a073 18025 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
18026 switch (op2) {
18027 case OPC_ALIGN ... OPC_ALIGN_END:
18028 case OPC_BITSWAP:
18029 check_insn(ctx, ISA_MIPS32R6);
18030 decode_opc_special3_r6(env, ctx);
18031 break;
18032 default:
18033 check_insn(ctx, ISA_MIPS32R2);
18034 gen_bshfl(ctx, op2, rt, rd);
18035 break;
18036 }
fac5a073
LA
18037 break;
18038#if defined(TARGET_MIPS64)
18039 case OPC_DEXTM ... OPC_DEXT:
18040 case OPC_DINSM ... OPC_DINS:
18041 check_insn(ctx, ISA_MIPS64R2);
18042 check_mips_64(ctx);
18043 gen_bitops(ctx, op1, rt, rs, sa, rd);
18044 break;
18045 case OPC_DBSHFL:
fac5a073 18046 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
18047 switch (op2) {
18048 case OPC_DALIGN ... OPC_DALIGN_END:
18049 case OPC_DBITSWAP:
18050 check_insn(ctx, ISA_MIPS32R6);
18051 decode_opc_special3_r6(env, ctx);
18052 break;
18053 default:
18054 check_insn(ctx, ISA_MIPS64R2);
18055 check_mips_64(ctx);
18056 op2 = MASK_DBSHFL(ctx->opcode);
18057 gen_bshfl(ctx, op2, rt, rd);
18058 break;
18059 }
fac5a073
LA
18060 break;
18061#endif
18062 case OPC_RDHWR:
b00c7218 18063 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18064 break;
18065 case OPC_FORK:
18066 check_insn(ctx, ASE_MT);
18067 {
18068 TCGv t0 = tcg_temp_new();
18069 TCGv t1 = tcg_temp_new();
18070
18071 gen_load_gpr(t0, rt);
18072 gen_load_gpr(t1, rs);
18073 gen_helper_fork(t0, t1);
18074 tcg_temp_free(t0);
18075 tcg_temp_free(t1);
18076 }
18077 break;
18078 case OPC_YIELD:
18079 check_insn(ctx, ASE_MT);
18080 {
18081 TCGv t0 = tcg_temp_new();
18082
fac5a073
LA
18083 gen_load_gpr(t0, rs);
18084 gen_helper_yield(t0, cpu_env, t0);
18085 gen_store_gpr(t0, rd);
18086 tcg_temp_free(t0);
18087 }
18088 break;
10dc65db
LA
18089 default:
18090 if (ctx->insn_flags & ISA_MIPS32R6) {
18091 decode_opc_special3_r6(env, ctx);
18092 } else {
18093 decode_opc_special3_legacy(env, ctx);
18094 }
099e5b4d
LA
18095 }
18096}
18097
863f264d
YK
18098/* MIPS SIMD Architecture (MSA) */
18099static inline int check_msa_access(DisasContext *ctx)
18100{
18101 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18102 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18103 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18104 return 0;
18105 }
18106
18107 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18108 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18109 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18110 return 0;
18111 } else {
9c708c7f 18112 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18113 return 0;
18114 }
18115 }
18116 return 1;
18117}
18118
5692c6e1
YK
18119static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18120{
18121 /* generates tcg ops to check if any element is 0 */
18122 /* Note this function only works with MSA_WRLEN = 128 */
18123 uint64_t eval_zero_or_big = 0;
18124 uint64_t eval_big = 0;
18125 TCGv_i64 t0 = tcg_temp_new_i64();
18126 TCGv_i64 t1 = tcg_temp_new_i64();
18127 switch (df) {
18128 case DF_BYTE:
18129 eval_zero_or_big = 0x0101010101010101ULL;
18130 eval_big = 0x8080808080808080ULL;
18131 break;
18132 case DF_HALF:
18133 eval_zero_or_big = 0x0001000100010001ULL;
18134 eval_big = 0x8000800080008000ULL;
18135 break;
18136 case DF_WORD:
18137 eval_zero_or_big = 0x0000000100000001ULL;
18138 eval_big = 0x8000000080000000ULL;
18139 break;
18140 case DF_DOUBLE:
18141 eval_zero_or_big = 0x0000000000000001ULL;
18142 eval_big = 0x8000000000000000ULL;
18143 break;
18144 }
18145 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18146 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18147 tcg_gen_andi_i64(t0, t0, eval_big);
18148 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18149 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18150 tcg_gen_andi_i64(t1, t1, eval_big);
18151 tcg_gen_or_i64(t0, t0, t1);
18152 /* if all bits are zero then all elements are not zero */
18153 /* if some bit is non-zero then some element is zero */
18154 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18155 tcg_gen_trunc_i64_tl(tresult, t0);
18156 tcg_temp_free_i64(t0);
18157 tcg_temp_free_i64(t1);
18158}
18159
18160static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18161{
18162 uint8_t df = (ctx->opcode >> 21) & 0x3;
18163 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18164 int64_t s16 = (int16_t)ctx->opcode;
18165
18166 check_msa_access(ctx);
18167
18168 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18169 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18170 return;
18171 }
18172 switch (op1) {
18173 case OPC_BZ_V:
18174 case OPC_BNZ_V:
18175 {
18176 TCGv_i64 t0 = tcg_temp_new_i64();
18177 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18178 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18179 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18180 tcg_gen_trunc_i64_tl(bcond, t0);
18181 tcg_temp_free_i64(t0);
18182 }
18183 break;
18184 case OPC_BZ_B:
18185 case OPC_BZ_H:
18186 case OPC_BZ_W:
18187 case OPC_BZ_D:
18188 gen_check_zero_element(bcond, df, wt);
18189 break;
18190 case OPC_BNZ_B:
18191 case OPC_BNZ_H:
18192 case OPC_BNZ_W:
18193 case OPC_BNZ_D:
18194 gen_check_zero_element(bcond, df, wt);
18195 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18196 break;
18197 }
18198
18199 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18200
18201 ctx->hflags |= MIPS_HFLAG_BC;
18202 ctx->hflags |= MIPS_HFLAG_BDS32;
18203}
18204
4c789546
YK
18205static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18206{
18207#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18208 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18209 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18210 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18211
18212 TCGv_i32 twd = tcg_const_i32(wd);
18213 TCGv_i32 tws = tcg_const_i32(ws);
18214 TCGv_i32 ti8 = tcg_const_i32(i8);
18215
18216 switch (MASK_MSA_I8(ctx->opcode)) {
18217 case OPC_ANDI_B:
18218 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18219 break;
18220 case OPC_ORI_B:
18221 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18222 break;
18223 case OPC_NORI_B:
18224 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18225 break;
18226 case OPC_XORI_B:
18227 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18228 break;
18229 case OPC_BMNZI_B:
18230 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18231 break;
18232 case OPC_BMZI_B:
18233 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18234 break;
18235 case OPC_BSELI_B:
18236 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18237 break;
18238 case OPC_SHF_B:
18239 case OPC_SHF_H:
18240 case OPC_SHF_W:
18241 {
18242 uint8_t df = (ctx->opcode >> 24) & 0x3;
18243 if (df == DF_DOUBLE) {
9c708c7f 18244 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18245 } else {
18246 TCGv_i32 tdf = tcg_const_i32(df);
18247 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18248 tcg_temp_free_i32(tdf);
18249 }
18250 }
18251 break;
18252 default:
18253 MIPS_INVAL("MSA instruction");
9c708c7f 18254 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18255 break;
18256 }
18257
18258 tcg_temp_free_i32(twd);
18259 tcg_temp_free_i32(tws);
18260 tcg_temp_free_i32(ti8);
18261}
18262
80e71591
YK
18263static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18264{
18265#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18266 uint8_t df = (ctx->opcode >> 21) & 0x3;
18267 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18268 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18269 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18270 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18271
18272 TCGv_i32 tdf = tcg_const_i32(df);
18273 TCGv_i32 twd = tcg_const_i32(wd);
18274 TCGv_i32 tws = tcg_const_i32(ws);
18275 TCGv_i32 timm = tcg_temp_new_i32();
18276 tcg_gen_movi_i32(timm, u5);
18277
18278 switch (MASK_MSA_I5(ctx->opcode)) {
18279 case OPC_ADDVI_df:
18280 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18281 break;
18282 case OPC_SUBVI_df:
18283 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18284 break;
18285 case OPC_MAXI_S_df:
18286 tcg_gen_movi_i32(timm, s5);
18287 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18288 break;
18289 case OPC_MAXI_U_df:
18290 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18291 break;
18292 case OPC_MINI_S_df:
18293 tcg_gen_movi_i32(timm, s5);
18294 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18295 break;
18296 case OPC_MINI_U_df:
18297 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18298 break;
18299 case OPC_CEQI_df:
18300 tcg_gen_movi_i32(timm, s5);
18301 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18302 break;
18303 case OPC_CLTI_S_df:
18304 tcg_gen_movi_i32(timm, s5);
18305 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18306 break;
18307 case OPC_CLTI_U_df:
18308 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18309 break;
18310 case OPC_CLEI_S_df:
18311 tcg_gen_movi_i32(timm, s5);
18312 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18313 break;
18314 case OPC_CLEI_U_df:
18315 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18316 break;
18317 case OPC_LDI_df:
18318 {
18319 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18320 tcg_gen_movi_i32(timm, s10);
18321 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18322 }
18323 break;
18324 default:
18325 MIPS_INVAL("MSA instruction");
9c708c7f 18326 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18327 break;
18328 }
18329
18330 tcg_temp_free_i32(tdf);
18331 tcg_temp_free_i32(twd);
18332 tcg_temp_free_i32(tws);
18333 tcg_temp_free_i32(timm);
18334}
18335
d4cf28de
YK
18336static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18337{
18338#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18339 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18340 uint32_t df = 0, m = 0;
18341 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18342 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18343
18344 TCGv_i32 tdf;
18345 TCGv_i32 tm;
18346 TCGv_i32 twd;
18347 TCGv_i32 tws;
18348
18349 if ((dfm & 0x40) == 0x00) {
18350 m = dfm & 0x3f;
18351 df = DF_DOUBLE;
18352 } else if ((dfm & 0x60) == 0x40) {
18353 m = dfm & 0x1f;
18354 df = DF_WORD;
18355 } else if ((dfm & 0x70) == 0x60) {
18356 m = dfm & 0x0f;
18357 df = DF_HALF;
18358 } else if ((dfm & 0x78) == 0x70) {
18359 m = dfm & 0x7;
18360 df = DF_BYTE;
18361 } else {
9c708c7f 18362 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18363 return;
18364 }
18365
18366 tdf = tcg_const_i32(df);
18367 tm = tcg_const_i32(m);
18368 twd = tcg_const_i32(wd);
18369 tws = tcg_const_i32(ws);
18370
18371 switch (MASK_MSA_BIT(ctx->opcode)) {
18372 case OPC_SLLI_df:
18373 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18374 break;
18375 case OPC_SRAI_df:
18376 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18377 break;
18378 case OPC_SRLI_df:
18379 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18380 break;
18381 case OPC_BCLRI_df:
18382 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18383 break;
18384 case OPC_BSETI_df:
18385 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18386 break;
18387 case OPC_BNEGI_df:
18388 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18389 break;
18390 case OPC_BINSLI_df:
18391 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18392 break;
18393 case OPC_BINSRI_df:
18394 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18395 break;
18396 case OPC_SAT_S_df:
18397 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18398 break;
18399 case OPC_SAT_U_df:
18400 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18401 break;
18402 case OPC_SRARI_df:
18403 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18404 break;
18405 case OPC_SRLRI_df:
18406 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18407 break;
18408 default:
18409 MIPS_INVAL("MSA instruction");
9c708c7f 18410 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18411 break;
18412 }
18413
18414 tcg_temp_free_i32(tdf);
18415 tcg_temp_free_i32(tm);
18416 tcg_temp_free_i32(twd);
18417 tcg_temp_free_i32(tws);
18418}
18419
28f99f08
YK
18420static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18421{
18422#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18423 uint8_t df = (ctx->opcode >> 21) & 0x3;
18424 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18425 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18426 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18427
18428 TCGv_i32 tdf = tcg_const_i32(df);
18429 TCGv_i32 twd = tcg_const_i32(wd);
18430 TCGv_i32 tws = tcg_const_i32(ws);
18431 TCGv_i32 twt = tcg_const_i32(wt);
18432
18433 switch (MASK_MSA_3R(ctx->opcode)) {
18434 case OPC_SLL_df:
18435 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18436 break;
18437 case OPC_ADDV_df:
18438 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18439 break;
18440 case OPC_CEQ_df:
18441 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18442 break;
18443 case OPC_ADD_A_df:
18444 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18445 break;
18446 case OPC_SUBS_S_df:
18447 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18448 break;
18449 case OPC_MULV_df:
18450 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18451 break;
18452 case OPC_SLD_df:
18453 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18454 break;
18455 case OPC_VSHF_df:
18456 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18457 break;
18458 case OPC_SRA_df:
18459 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18460 break;
18461 case OPC_SUBV_df:
18462 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18463 break;
18464 case OPC_ADDS_A_df:
18465 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18466 break;
18467 case OPC_SUBS_U_df:
18468 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18469 break;
18470 case OPC_MADDV_df:
18471 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18472 break;
18473 case OPC_SPLAT_df:
18474 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18475 break;
18476 case OPC_SRAR_df:
18477 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18478 break;
18479 case OPC_SRL_df:
18480 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18481 break;
18482 case OPC_MAX_S_df:
18483 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18484 break;
18485 case OPC_CLT_S_df:
18486 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18487 break;
18488 case OPC_ADDS_S_df:
18489 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18490 break;
18491 case OPC_SUBSUS_U_df:
18492 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18493 break;
18494 case OPC_MSUBV_df:
18495 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18496 break;
18497 case OPC_PCKEV_df:
18498 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18499 break;
18500 case OPC_SRLR_df:
18501 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18502 break;
18503 case OPC_BCLR_df:
18504 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18505 break;
18506 case OPC_MAX_U_df:
18507 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18508 break;
18509 case OPC_CLT_U_df:
18510 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18511 break;
18512 case OPC_ADDS_U_df:
18513 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18514 break;
18515 case OPC_SUBSUU_S_df:
18516 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18517 break;
18518 case OPC_PCKOD_df:
18519 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18520 break;
18521 case OPC_BSET_df:
18522 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18523 break;
18524 case OPC_MIN_S_df:
18525 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18526 break;
18527 case OPC_CLE_S_df:
18528 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18529 break;
18530 case OPC_AVE_S_df:
18531 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18532 break;
18533 case OPC_ASUB_S_df:
18534 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18535 break;
18536 case OPC_DIV_S_df:
18537 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18538 break;
18539 case OPC_ILVL_df:
18540 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18541 break;
18542 case OPC_BNEG_df:
18543 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18544 break;
18545 case OPC_MIN_U_df:
18546 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18547 break;
18548 case OPC_CLE_U_df:
18549 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18550 break;
18551 case OPC_AVE_U_df:
18552 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18553 break;
18554 case OPC_ASUB_U_df:
18555 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18556 break;
18557 case OPC_DIV_U_df:
18558 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18559 break;
18560 case OPC_ILVR_df:
18561 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18562 break;
18563 case OPC_BINSL_df:
18564 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18565 break;
18566 case OPC_MAX_A_df:
18567 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_AVER_S_df:
18570 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_MOD_S_df:
18573 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_ILVEV_df:
18576 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_BINSR_df:
18579 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18580 break;
18581 case OPC_MIN_A_df:
18582 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18583 break;
18584 case OPC_AVER_U_df:
18585 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18586 break;
18587 case OPC_MOD_U_df:
18588 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18589 break;
18590 case OPC_ILVOD_df:
18591 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18592 break;
18593
18594 case OPC_DOTP_S_df:
18595 case OPC_DOTP_U_df:
18596 case OPC_DPADD_S_df:
18597 case OPC_DPADD_U_df:
18598 case OPC_DPSUB_S_df:
18599 case OPC_HADD_S_df:
18600 case OPC_DPSUB_U_df:
18601 case OPC_HADD_U_df:
18602 case OPC_HSUB_S_df:
18603 case OPC_HSUB_U_df:
18604 if (df == DF_BYTE) {
9c708c7f
PD
18605 generate_exception_end(ctx, EXCP_RI);
18606 break;
28f99f08
YK
18607 }
18608 switch (MASK_MSA_3R(ctx->opcode)) {
18609 case OPC_DOTP_S_df:
18610 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18611 break;
18612 case OPC_DOTP_U_df:
18613 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18614 break;
18615 case OPC_DPADD_S_df:
18616 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18617 break;
18618 case OPC_DPADD_U_df:
18619 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18620 break;
18621 case OPC_DPSUB_S_df:
18622 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18623 break;
18624 case OPC_HADD_S_df:
18625 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18626 break;
18627 case OPC_DPSUB_U_df:
18628 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18629 break;
18630 case OPC_HADD_U_df:
18631 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18632 break;
18633 case OPC_HSUB_S_df:
18634 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18635 break;
18636 case OPC_HSUB_U_df:
18637 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18638 break;
18639 }
18640 break;
18641 default:
18642 MIPS_INVAL("MSA instruction");
9c708c7f 18643 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18644 break;
18645 }
18646 tcg_temp_free_i32(twd);
18647 tcg_temp_free_i32(tws);
18648 tcg_temp_free_i32(twt);
18649 tcg_temp_free_i32(tdf);
18650}
18651
1e608ec1
YK
18652static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18653{
18654#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18655 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18656 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18657 TCGv telm = tcg_temp_new();
18658 TCGv_i32 tsr = tcg_const_i32(source);
18659 TCGv_i32 tdt = tcg_const_i32(dest);
18660
18661 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18662 case OPC_CTCMSA:
18663 gen_load_gpr(telm, source);
18664 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18665 break;
18666 case OPC_CFCMSA:
18667 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18668 gen_store_gpr(telm, dest);
18669 break;
18670 case OPC_MOVE_V:
18671 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18672 break;
18673 default:
18674 MIPS_INVAL("MSA instruction");
9c708c7f 18675 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18676 break;
18677 }
18678
18679 tcg_temp_free(telm);
18680 tcg_temp_free_i32(tdt);
18681 tcg_temp_free_i32(tsr);
18682}
18683
18684static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18685 uint32_t n)
18686{
18687#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18688 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18689 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18690
18691 TCGv_i32 tws = tcg_const_i32(ws);
18692 TCGv_i32 twd = tcg_const_i32(wd);
18693 TCGv_i32 tn = tcg_const_i32(n);
18694 TCGv_i32 tdf = tcg_const_i32(df);
18695
18696 switch (MASK_MSA_ELM(ctx->opcode)) {
18697 case OPC_SLDI_df:
18698 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18699 break;
18700 case OPC_SPLATI_df:
18701 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18702 break;
18703 case OPC_INSVE_df:
18704 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18705 break;
18706 case OPC_COPY_S_df:
18707 case OPC_COPY_U_df:
18708 case OPC_INSERT_df:
18709#if !defined(TARGET_MIPS64)
18710 /* Double format valid only for MIPS64 */
18711 if (df == DF_DOUBLE) {
9c708c7f 18712 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18713 break;
18714 }
18715#endif
18716 switch (MASK_MSA_ELM(ctx->opcode)) {
18717 case OPC_COPY_S_df:
18718 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18719 break;
18720 case OPC_COPY_U_df:
18721 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18722 break;
18723 case OPC_INSERT_df:
18724 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18725 break;
18726 }
18727 break;
18728 default:
18729 MIPS_INVAL("MSA instruction");
9c708c7f 18730 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18731 }
18732 tcg_temp_free_i32(twd);
18733 tcg_temp_free_i32(tws);
18734 tcg_temp_free_i32(tn);
18735 tcg_temp_free_i32(tdf);
18736}
18737
18738static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18739{
18740 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18741 uint32_t df = 0, n = 0;
18742
18743 if ((dfn & 0x30) == 0x00) {
18744 n = dfn & 0x0f;
18745 df = DF_BYTE;
18746 } else if ((dfn & 0x38) == 0x20) {
18747 n = dfn & 0x07;
18748 df = DF_HALF;
18749 } else if ((dfn & 0x3c) == 0x30) {
18750 n = dfn & 0x03;
18751 df = DF_WORD;
18752 } else if ((dfn & 0x3e) == 0x38) {
18753 n = dfn & 0x01;
18754 df = DF_DOUBLE;
18755 } else if (dfn == 0x3E) {
18756 /* CTCMSA, CFCMSA, MOVE.V */
18757 gen_msa_elm_3e(env, ctx);
18758 return;
18759 } else {
9c708c7f 18760 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18761 return;
18762 }
18763
18764 gen_msa_elm_df(env, ctx, df, n);
18765}
18766
7d05b9c8
YK
18767static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18768{
18769#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18770 uint8_t df = (ctx->opcode >> 21) & 0x1;
18771 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18772 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18773 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18774
18775 TCGv_i32 twd = tcg_const_i32(wd);
18776 TCGv_i32 tws = tcg_const_i32(ws);
18777 TCGv_i32 twt = tcg_const_i32(wt);
18778 TCGv_i32 tdf = tcg_temp_new_i32();
18779
18780 /* adjust df value for floating-point instruction */
18781 tcg_gen_movi_i32(tdf, df + 2);
18782
18783 switch (MASK_MSA_3RF(ctx->opcode)) {
18784 case OPC_FCAF_df:
18785 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18786 break;
18787 case OPC_FADD_df:
18788 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18789 break;
18790 case OPC_FCUN_df:
18791 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18792 break;
18793 case OPC_FSUB_df:
18794 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18795 break;
18796 case OPC_FCOR_df:
18797 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18798 break;
18799 case OPC_FCEQ_df:
18800 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18801 break;
18802 case OPC_FMUL_df:
18803 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18804 break;
18805 case OPC_FCUNE_df:
18806 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18807 break;
18808 case OPC_FCUEQ_df:
18809 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18810 break;
18811 case OPC_FDIV_df:
18812 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18813 break;
18814 case OPC_FCNE_df:
18815 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18816 break;
18817 case OPC_FCLT_df:
18818 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18819 break;
18820 case OPC_FMADD_df:
18821 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18822 break;
18823 case OPC_MUL_Q_df:
18824 tcg_gen_movi_i32(tdf, df + 1);
18825 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18826 break;
18827 case OPC_FCULT_df:
18828 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18829 break;
18830 case OPC_FMSUB_df:
18831 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18832 break;
18833 case OPC_MADD_Q_df:
18834 tcg_gen_movi_i32(tdf, df + 1);
18835 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18836 break;
18837 case OPC_FCLE_df:
18838 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18839 break;
18840 case OPC_MSUB_Q_df:
18841 tcg_gen_movi_i32(tdf, df + 1);
18842 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18843 break;
18844 case OPC_FCULE_df:
18845 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18846 break;
18847 case OPC_FEXP2_df:
18848 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18849 break;
18850 case OPC_FSAF_df:
18851 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18852 break;
18853 case OPC_FEXDO_df:
18854 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18855 break;
18856 case OPC_FSUN_df:
18857 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18858 break;
18859 case OPC_FSOR_df:
18860 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18861 break;
18862 case OPC_FSEQ_df:
18863 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18864 break;
18865 case OPC_FTQ_df:
18866 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18867 break;
18868 case OPC_FSUNE_df:
18869 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18870 break;
18871 case OPC_FSUEQ_df:
18872 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18873 break;
18874 case OPC_FSNE_df:
18875 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18876 break;
18877 case OPC_FSLT_df:
18878 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18879 break;
18880 case OPC_FMIN_df:
18881 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18882 break;
18883 case OPC_MULR_Q_df:
18884 tcg_gen_movi_i32(tdf, df + 1);
18885 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18886 break;
18887 case OPC_FSULT_df:
18888 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18889 break;
18890 case OPC_FMIN_A_df:
18891 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18892 break;
18893 case OPC_MADDR_Q_df:
18894 tcg_gen_movi_i32(tdf, df + 1);
18895 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18896 break;
18897 case OPC_FSLE_df:
18898 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18899 break;
18900 case OPC_FMAX_df:
18901 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18902 break;
18903 case OPC_MSUBR_Q_df:
18904 tcg_gen_movi_i32(tdf, df + 1);
18905 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18906 break;
18907 case OPC_FSULE_df:
18908 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18909 break;
18910 case OPC_FMAX_A_df:
18911 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18912 break;
18913 default:
18914 MIPS_INVAL("MSA instruction");
9c708c7f 18915 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
18916 break;
18917 }
18918
18919 tcg_temp_free_i32(twd);
18920 tcg_temp_free_i32(tws);
18921 tcg_temp_free_i32(twt);
18922 tcg_temp_free_i32(tdf);
18923}
18924
cbe50b9a
YK
18925static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18926{
18927#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18928 (op & (0x7 << 18)))
18929 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18930 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18931 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18932 uint8_t df = (ctx->opcode >> 16) & 0x3;
18933 TCGv_i32 twd = tcg_const_i32(wd);
18934 TCGv_i32 tws = tcg_const_i32(ws);
18935 TCGv_i32 twt = tcg_const_i32(wt);
18936 TCGv_i32 tdf = tcg_const_i32(df);
18937
18938 switch (MASK_MSA_2R(ctx->opcode)) {
18939 case OPC_FILL_df:
18940#if !defined(TARGET_MIPS64)
18941 /* Double format valid only for MIPS64 */
18942 if (df == DF_DOUBLE) {
9c708c7f 18943 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18944 break;
18945 }
18946#endif
18947 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18948 break;
18949 case OPC_PCNT_df:
18950 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18951 break;
18952 case OPC_NLOC_df:
18953 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18954 break;
18955 case OPC_NLZC_df:
18956 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18957 break;
18958 default:
18959 MIPS_INVAL("MSA instruction");
9c708c7f 18960 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18961 break;
18962 }
18963
18964 tcg_temp_free_i32(twd);
18965 tcg_temp_free_i32(tws);
18966 tcg_temp_free_i32(twt);
18967 tcg_temp_free_i32(tdf);
18968}
18969
3bdeb688
YK
18970static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18971{
18972#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18973 (op & (0xf << 17)))
18974 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18975 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18976 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18977 uint8_t df = (ctx->opcode >> 16) & 0x1;
18978 TCGv_i32 twd = tcg_const_i32(wd);
18979 TCGv_i32 tws = tcg_const_i32(ws);
18980 TCGv_i32 twt = tcg_const_i32(wt);
18981 /* adjust df value for floating-point instruction */
18982 TCGv_i32 tdf = tcg_const_i32(df + 2);
18983
18984 switch (MASK_MSA_2RF(ctx->opcode)) {
18985 case OPC_FCLASS_df:
18986 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18987 break;
18988 case OPC_FTRUNC_S_df:
18989 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18990 break;
18991 case OPC_FTRUNC_U_df:
18992 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18993 break;
18994 case OPC_FSQRT_df:
18995 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18996 break;
18997 case OPC_FRSQRT_df:
18998 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18999 break;
19000 case OPC_FRCP_df:
19001 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19002 break;
19003 case OPC_FRINT_df:
19004 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19005 break;
19006 case OPC_FLOG2_df:
19007 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19008 break;
19009 case OPC_FEXUPL_df:
19010 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19011 break;
19012 case OPC_FEXUPR_df:
19013 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19014 break;
19015 case OPC_FFQL_df:
19016 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19017 break;
19018 case OPC_FFQR_df:
19019 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19020 break;
19021 case OPC_FTINT_S_df:
19022 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19023 break;
19024 case OPC_FTINT_U_df:
19025 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19026 break;
19027 case OPC_FFINT_S_df:
19028 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19029 break;
19030 case OPC_FFINT_U_df:
19031 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19032 break;
19033 }
19034
19035 tcg_temp_free_i32(twd);
19036 tcg_temp_free_i32(tws);
19037 tcg_temp_free_i32(twt);
19038 tcg_temp_free_i32(tdf);
19039}
19040
cbe50b9a
YK
19041static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19042{
19043#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19044 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19045 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19046 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19047 TCGv_i32 twd = tcg_const_i32(wd);
19048 TCGv_i32 tws = tcg_const_i32(ws);
19049 TCGv_i32 twt = tcg_const_i32(wt);
19050
19051 switch (MASK_MSA_VEC(ctx->opcode)) {
19052 case OPC_AND_V:
19053 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19054 break;
19055 case OPC_OR_V:
19056 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19057 break;
19058 case OPC_NOR_V:
19059 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19060 break;
19061 case OPC_XOR_V:
19062 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19063 break;
19064 case OPC_BMNZ_V:
19065 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19066 break;
19067 case OPC_BMZ_V:
19068 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19069 break;
19070 case OPC_BSEL_V:
19071 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19072 break;
19073 default:
19074 MIPS_INVAL("MSA instruction");
9c708c7f 19075 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19076 break;
19077 }
19078
19079 tcg_temp_free_i32(twd);
19080 tcg_temp_free_i32(tws);
19081 tcg_temp_free_i32(twt);
19082}
19083
19084static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19085{
19086 switch (MASK_MSA_VEC(ctx->opcode)) {
19087 case OPC_AND_V:
19088 case OPC_OR_V:
19089 case OPC_NOR_V:
19090 case OPC_XOR_V:
19091 case OPC_BMNZ_V:
19092 case OPC_BMZ_V:
19093 case OPC_BSEL_V:
19094 gen_msa_vec_v(env, ctx);
19095 break;
19096 case OPC_MSA_2R:
19097 gen_msa_2r(env, ctx);
19098 break;
3bdeb688
YK
19099 case OPC_MSA_2RF:
19100 gen_msa_2rf(env, ctx);
19101 break;
cbe50b9a
YK
19102 default:
19103 MIPS_INVAL("MSA instruction");
9c708c7f 19104 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19105 break;
19106 }
19107}
19108
4c789546
YK
19109static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19110{
19111 uint32_t opcode = ctx->opcode;
19112 check_insn(ctx, ASE_MSA);
19113 check_msa_access(ctx);
19114
19115 switch (MASK_MSA_MINOR(opcode)) {
19116 case OPC_MSA_I8_00:
19117 case OPC_MSA_I8_01:
19118 case OPC_MSA_I8_02:
19119 gen_msa_i8(env, ctx);
19120 break;
80e71591
YK
19121 case OPC_MSA_I5_06:
19122 case OPC_MSA_I5_07:
19123 gen_msa_i5(env, ctx);
19124 break;
d4cf28de
YK
19125 case OPC_MSA_BIT_09:
19126 case OPC_MSA_BIT_0A:
19127 gen_msa_bit(env, ctx);
19128 break;
28f99f08
YK
19129 case OPC_MSA_3R_0D:
19130 case OPC_MSA_3R_0E:
19131 case OPC_MSA_3R_0F:
19132 case OPC_MSA_3R_10:
19133 case OPC_MSA_3R_11:
19134 case OPC_MSA_3R_12:
19135 case OPC_MSA_3R_13:
19136 case OPC_MSA_3R_14:
19137 case OPC_MSA_3R_15:
19138 gen_msa_3r(env, ctx);
19139 break;
1e608ec1
YK
19140 case OPC_MSA_ELM:
19141 gen_msa_elm(env, ctx);
19142 break;
7d05b9c8
YK
19143 case OPC_MSA_3RF_1A:
19144 case OPC_MSA_3RF_1B:
19145 case OPC_MSA_3RF_1C:
19146 gen_msa_3rf(env, ctx);
19147 break;
cbe50b9a
YK
19148 case OPC_MSA_VEC:
19149 gen_msa_vec(env, ctx);
19150 break;
f7685877
YK
19151 case OPC_LD_B:
19152 case OPC_LD_H:
19153 case OPC_LD_W:
19154 case OPC_LD_D:
19155 case OPC_ST_B:
19156 case OPC_ST_H:
19157 case OPC_ST_W:
19158 case OPC_ST_D:
19159 {
19160 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19161 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19162 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19163 uint8_t df = (ctx->opcode >> 0) & 0x3;
19164
f7685877 19165 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19166 TCGv taddr = tcg_temp_new();
19167 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19168
19169 switch (MASK_MSA_MINOR(opcode)) {
19170 case OPC_LD_B:
adc370a4
YK
19171 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19172 break;
f7685877 19173 case OPC_LD_H:
adc370a4
YK
19174 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19175 break;
f7685877 19176 case OPC_LD_W:
adc370a4
YK
19177 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19178 break;
f7685877 19179 case OPC_LD_D:
adc370a4 19180 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19181 break;
19182 case OPC_ST_B:
adc370a4
YK
19183 gen_helper_msa_st_b(cpu_env, twd, taddr);
19184 break;
f7685877 19185 case OPC_ST_H:
adc370a4
YK
19186 gen_helper_msa_st_h(cpu_env, twd, taddr);
19187 break;
f7685877 19188 case OPC_ST_W:
adc370a4
YK
19189 gen_helper_msa_st_w(cpu_env, twd, taddr);
19190 break;
f7685877 19191 case OPC_ST_D:
adc370a4 19192 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19193 break;
19194 }
19195
19196 tcg_temp_free_i32(twd);
adc370a4 19197 tcg_temp_free(taddr);
f7685877
YK
19198 }
19199 break;
4c789546
YK
19200 default:
19201 MIPS_INVAL("MSA instruction");
9c708c7f 19202 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19203 break;
19204 }
19205
19206}
19207
d2bfa6e6 19208static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19209{
19210 int32_t offset;
19211 int rs, rt, rd, sa;
19212 uint32_t op, op1;
19213 int16_t imm;
19214
19215 /* make sure instructions are on a word boundary */
19216 if (ctx->pc & 0x3) {
19217 env->CP0_BadVAddr = ctx->pc;
aea14095 19218 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19219 return;
19220 }
19221
19222 /* Handle blikely not taken case */
19223 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19224 TCGLabel *l1 = gen_new_label();
099e5b4d 19225
099e5b4d
LA
19226 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19227 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19228 gen_goto_tb(ctx, 1, ctx->pc + 4);
19229 gen_set_label(l1);
19230 }
19231
099e5b4d
LA
19232 op = MASK_OP_MAJOR(ctx->opcode);
19233 rs = (ctx->opcode >> 21) & 0x1f;
19234 rt = (ctx->opcode >> 16) & 0x1f;
19235 rd = (ctx->opcode >> 11) & 0x1f;
19236 sa = (ctx->opcode >> 6) & 0x1f;
19237 imm = (int16_t)ctx->opcode;
19238 switch (op) {
19239 case OPC_SPECIAL:
19240 decode_opc_special(env, ctx);
19241 break;
19242 case OPC_SPECIAL2:
4267d3e6 19243 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19244 break;
19245 case OPC_SPECIAL3:
19246 decode_opc_special3(env, ctx);
19247 break;
7a387fff
TS
19248 case OPC_REGIMM:
19249 op1 = MASK_REGIMM(ctx->opcode);
19250 switch (op1) {
fecd2646
LA
19251 case OPC_BLTZL: /* REGIMM branches */
19252 case OPC_BGEZL:
19253 case OPC_BLTZALL:
19254 case OPC_BGEZALL:
d9224450 19255 check_insn(ctx, ISA_MIPS2);
fecd2646 19256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19257 /* Fallthrough */
fecd2646
LA
19258 case OPC_BLTZ:
19259 case OPC_BGEZ:
b231c103 19260 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19261 break;
fecd2646
LA
19262 case OPC_BLTZAL:
19263 case OPC_BGEZAL:
0aefa333
YK
19264 if (ctx->insn_flags & ISA_MIPS32R6) {
19265 if (rs == 0) {
19266 /* OPC_NAL, OPC_BAL */
b231c103 19267 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19268 } else {
9c708c7f 19269 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19270 }
19271 } else {
b231c103 19272 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19273 }
c9602061 19274 break;
7a387fff
TS
19275 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19276 case OPC_TNEI:
d9224450 19277 check_insn(ctx, ISA_MIPS2);
fecd2646 19278 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19279 gen_trap(ctx, op1, rs, -1, imm);
19280 break;
bb238210
YK
19281 case OPC_SIGRIE:
19282 check_insn(ctx, ISA_MIPS32R6);
19283 generate_exception_end(ctx, EXCP_RI);
19284 break;
7a387fff 19285 case OPC_SYNCI:
d75c135e 19286 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19287 /* Break the TB to be able to sync copied instructions
19288 immediately */
19289 ctx->bstate = BS_STOP;
6af0bf9c 19290 break;
e45a93e2
JL
19291 case OPC_BPOSGE32: /* MIPS DSP branch */
19292#if defined(TARGET_MIPS64)
19293 case OPC_BPOSGE64:
19294#endif
19295 check_dsp(ctx);
b231c103 19296 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19297 break;
d4ea6acd
LA
19298#if defined(TARGET_MIPS64)
19299 case OPC_DAHI:
19300 check_insn(ctx, ISA_MIPS32R6);
19301 check_mips_64(ctx);
19302 if (rs != 0) {
19303 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19304 }
d4ea6acd
LA
19305 break;
19306 case OPC_DATI:
19307 check_insn(ctx, ISA_MIPS32R6);
19308 check_mips_64(ctx);
19309 if (rs != 0) {
19310 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19311 }
d4ea6acd
LA
19312 break;
19313#endif
6af0bf9c 19314 default: /* Invalid */
923617a3 19315 MIPS_INVAL("regimm");
9c708c7f 19316 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19317 break;
19318 }
19319 break;
7a387fff 19320 case OPC_CP0:
387a8fe5 19321 check_cp0_enabled(ctx);
7a387fff 19322 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19323 switch (op1) {
7a387fff
TS
19324 case OPC_MFC0:
19325 case OPC_MTC0:
ead9360e
TS
19326 case OPC_MFTR:
19327 case OPC_MTTR:
5204ea79
LA
19328 case OPC_MFHC0:
19329 case OPC_MTHC0:
d26bc211 19330#if defined(TARGET_MIPS64)
7a387fff
TS
19331 case OPC_DMFC0:
19332 case OPC_DMTC0:
19333#endif
f1aa6320 19334#ifndef CONFIG_USER_ONLY
932e71cd 19335 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19336#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19337 break;
19338 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19339#ifndef CONFIG_USER_ONLY
932e71cd 19340 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19341#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19342 break;
19343 case OPC_MFMC0:
8706c382 19344#ifndef CONFIG_USER_ONLY
932e71cd 19345 {
099e5b4d 19346 uint32_t op2;
35fbce2c 19347 TCGv t0 = tcg_temp_new();
6c5c1e20 19348
0eaef5aa 19349 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19350 switch (op2) {
19351 case OPC_DMT:
d75c135e 19352 check_insn(ctx, ASE_MT);
9ed5726c 19353 gen_helper_dmt(t0);
35fbce2c 19354 gen_store_gpr(t0, rt);
6c5c1e20
TS
19355 break;
19356 case OPC_EMT:
d75c135e 19357 check_insn(ctx, ASE_MT);
9ed5726c 19358 gen_helper_emt(t0);
35fbce2c 19359 gen_store_gpr(t0, rt);
da80682b 19360 break;
6c5c1e20 19361 case OPC_DVPE:
d75c135e 19362 check_insn(ctx, ASE_MT);
895c2d04 19363 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19364 gen_store_gpr(t0, rt);
6c5c1e20
TS
19365 break;
19366 case OPC_EVPE:
d75c135e 19367 check_insn(ctx, ASE_MT);
895c2d04 19368 gen_helper_evpe(t0, cpu_env);
35fbce2c 19369 gen_store_gpr(t0, rt);
6c5c1e20 19370 break;
01bc435b
YK
19371 case OPC_DVP:
19372 check_insn(ctx, ISA_MIPS32R6);
19373 if (ctx->vp) {
19374 gen_helper_dvp(t0, cpu_env);
19375 gen_store_gpr(t0, rt);
19376 }
19377 break;
19378 case OPC_EVP:
19379 check_insn(ctx, ISA_MIPS32R6);
19380 if (ctx->vp) {
19381 gen_helper_evp(t0, cpu_env);
19382 gen_store_gpr(t0, rt);
19383 }
19384 break;
6c5c1e20 19385 case OPC_DI:
d75c135e 19386 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19387 save_cpu_state(ctx, 1);
895c2d04 19388 gen_helper_di(t0, cpu_env);
35fbce2c 19389 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19390 /* Stop translation as we may have switched
19391 the execution mode. */
6c5c1e20
TS
19392 ctx->bstate = BS_STOP;
19393 break;
19394 case OPC_EI:
d75c135e 19395 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19396 save_cpu_state(ctx, 1);
895c2d04 19397 gen_helper_ei(t0, cpu_env);
35fbce2c 19398 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19399 /* Stop translation as we may have switched
19400 the execution mode. */
6c5c1e20
TS
19401 ctx->bstate = BS_STOP;
19402 break;
19403 default: /* Invalid */
19404 MIPS_INVAL("mfmc0");
9c708c7f 19405 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19406 break;
19407 }
6c5c1e20 19408 tcg_temp_free(t0);
7a387fff 19409 }
0eaef5aa 19410#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19411 break;
7a387fff 19412 case OPC_RDPGPR:
d75c135e 19413 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19414 gen_load_srsgpr(rt, rd);
ead9360e 19415 break;
7a387fff 19416 case OPC_WRPGPR:
d75c135e 19417 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19418 gen_store_srsgpr(rt, rd);
38121543 19419 break;
6af0bf9c 19420 default:
923617a3 19421 MIPS_INVAL("cp0");
9c708c7f 19422 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19423 break;
19424 }
19425 break;
31837be3
YK
19426 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19427 if (ctx->insn_flags & ISA_MIPS32R6) {
19428 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19429 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19430 } else {
19431 /* OPC_ADDI */
19432 /* Arithmetic with immediate opcode */
19433 gen_arith_imm(ctx, op, rt, rs, imm);
19434 }
19435 break;
324d9e32 19436 case OPC_ADDIU:
d75c135e 19437 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19438 break;
324d9e32
AJ
19439 case OPC_SLTI: /* Set on less than with immediate opcode */
19440 case OPC_SLTIU:
d75c135e 19441 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19442 break;
19443 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19444 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19445 case OPC_ORI:
19446 case OPC_XORI:
d75c135e 19447 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19448 break;
7a387fff
TS
19449 case OPC_J ... OPC_JAL: /* Jump */
19450 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19451 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19452 break;
31837be3
YK
19453 /* Branch */
19454 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19455 if (ctx->insn_flags & ISA_MIPS32R6) {
19456 if (rt == 0) {
9c708c7f 19457 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19458 break;
19459 }
19460 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19461 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19462 } else {
19463 /* OPC_BLEZL */
b231c103 19464 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19465 }
19466 break;
19467 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19468 if (ctx->insn_flags & ISA_MIPS32R6) {
19469 if (rt == 0) {
9c708c7f 19470 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19471 break;
19472 }
19473 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19474 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19475 } else {
19476 /* OPC_BGTZL */
b231c103 19477 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19478 }
19479 break;
19480 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19481 if (rt == 0) {
19482 /* OPC_BLEZ */
b231c103 19483 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19484 } else {
19485 check_insn(ctx, ISA_MIPS32R6);
19486 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19487 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19488 }
19489 break;
19490 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19491 if (rt == 0) {
19492 /* OPC_BGTZ */
b231c103 19493 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19494 } else {
19495 check_insn(ctx, ISA_MIPS32R6);
19496 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19497 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19498 }
19499 break;
19500 case OPC_BEQL:
19501 case OPC_BNEL:
d9224450 19502 check_insn(ctx, ISA_MIPS2);
fecd2646 19503 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19504 /* Fallthrough */
31837be3
YK
19505 case OPC_BEQ:
19506 case OPC_BNE:
b231c103 19507 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19508 break;
d9224450
MR
19509 case OPC_LL: /* Load and stores */
19510 check_insn(ctx, ISA_MIPS2);
19511 /* Fallthrough */
19512 case OPC_LWL:
fecd2646
LA
19513 case OPC_LWR:
19514 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19515 /* Fallthrough */
fecd2646
LA
19516 case OPC_LB ... OPC_LH:
19517 case OPC_LW ... OPC_LHU:
d75c135e 19518 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19519 break;
fecd2646 19520 case OPC_SWL:
7a387fff 19521 case OPC_SWR:
fecd2646 19522 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19523 /* fall through */
fecd2646
LA
19524 case OPC_SB ... OPC_SH:
19525 case OPC_SW:
5c13fdfd 19526 gen_st(ctx, op, rt, rs, imm);
7a387fff 19527 break;
d66c7132 19528 case OPC_SC:
d9224450 19529 check_insn(ctx, ISA_MIPS2);
4368b29a 19530 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19531 gen_st_cond(ctx, op, rt, rs, imm);
19532 break;
7a387fff 19533 case OPC_CACHE:
bf7910c6 19534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19535 check_cp0_enabled(ctx);
d75c135e 19536 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
19537 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19538 gen_cache_operation(ctx, rt, rs, imm);
19539 }
ead9360e 19540 /* Treat as NOP. */
34ae7b51 19541 break;
7a387fff 19542 case OPC_PREF:
bf7910c6 19543 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19544 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19545 /* Treat as NOP. */
6af0bf9c 19546 break;
4ad40f36 19547
923617a3 19548 /* Floating point (COP1). */
7a387fff
TS
19549 case OPC_LWC1:
19550 case OPC_LDC1:
19551 case OPC_SWC1:
19552 case OPC_SDC1:
5ab5c041 19553 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19554 break;
19555
7a387fff 19556 case OPC_CP1:
5692c6e1
YK
19557 op1 = MASK_CP1(ctx->opcode);
19558
19559 switch (op1) {
19560 case OPC_MFHC1:
19561 case OPC_MTHC1:
5e755519 19562 check_cp1_enabled(ctx);
5692c6e1
YK
19563 check_insn(ctx, ISA_MIPS32R2);
19564 case OPC_MFC1:
19565 case OPC_CFC1:
19566 case OPC_MTC1:
19567 case OPC_CTC1:
19568 check_cp1_enabled(ctx);
19569 gen_cp1(ctx, op1, rt, rd);
19570 break;
d26bc211 19571#if defined(TARGET_MIPS64)
5692c6e1
YK
19572 case OPC_DMFC1:
19573 case OPC_DMTC1:
19574 check_cp1_enabled(ctx);
19575 check_insn(ctx, ISA_MIPS3);
d9224450 19576 check_mips_64(ctx);
5692c6e1
YK
19577 gen_cp1(ctx, op1, rt, rd);
19578 break;
e189e748 19579#endif
5692c6e1
YK
19580 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19581 check_cp1_enabled(ctx);
19582 if (ctx->insn_flags & ISA_MIPS32R6) {
19583 /* OPC_BC1EQZ */
31837be3 19584 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19585 rt, imm << 2, 4);
5692c6e1
YK
19586 } else {
19587 /* OPC_BC1ANY2 */
b8aa4598 19588 check_cop1x(ctx);
d75c135e 19589 check_insn(ctx, ASE_MIPS3D);
d75c135e 19590 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19591 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19592 }
19593 break;
19594 case OPC_BC1NEZ:
19595 check_cp1_enabled(ctx);
19596 check_insn(ctx, ISA_MIPS32R6);
19597 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19598 rt, imm << 2, 4);
5692c6e1
YK
19599 break;
19600 case OPC_BC1ANY4:
19601 check_cp1_enabled(ctx);
19602 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19603 check_cop1x(ctx);
19604 check_insn(ctx, ASE_MIPS3D);
19605 /* fall through */
19606 case OPC_BC1:
19607 check_cp1_enabled(ctx);
19608 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19609 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19610 (rt >> 2) & 0x7, imm << 2);
19611 break;
19612 case OPC_PS_FMT:
e29c9628 19613 check_ps(ctx);
b6f3b233 19614 /* fall through */
5692c6e1
YK
19615 case OPC_S_FMT:
19616 case OPC_D_FMT:
19617 check_cp1_enabled(ctx);
19618 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19619 (imm >> 8) & 0x7);
19620 break;
19621 case OPC_W_FMT:
19622 case OPC_L_FMT:
19623 {
19624 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19625 check_cp1_enabled(ctx);
19626 if (ctx->insn_flags & ISA_MIPS32R6) {
19627 switch (r6_op) {
19628 case R6_OPC_CMP_AF_S:
19629 case R6_OPC_CMP_UN_S:
19630 case R6_OPC_CMP_EQ_S:
19631 case R6_OPC_CMP_UEQ_S:
19632 case R6_OPC_CMP_LT_S:
19633 case R6_OPC_CMP_ULT_S:
19634 case R6_OPC_CMP_LE_S:
19635 case R6_OPC_CMP_ULE_S:
19636 case R6_OPC_CMP_SAF_S:
19637 case R6_OPC_CMP_SUN_S:
19638 case R6_OPC_CMP_SEQ_S:
19639 case R6_OPC_CMP_SEUQ_S:
19640 case R6_OPC_CMP_SLT_S:
19641 case R6_OPC_CMP_SULT_S:
19642 case R6_OPC_CMP_SLE_S:
19643 case R6_OPC_CMP_SULE_S:
19644 case R6_OPC_CMP_OR_S:
19645 case R6_OPC_CMP_UNE_S:
19646 case R6_OPC_CMP_NE_S:
19647 case R6_OPC_CMP_SOR_S:
19648 case R6_OPC_CMP_SUNE_S:
19649 case R6_OPC_CMP_SNE_S:
19650 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19651 break;
19652 case R6_OPC_CMP_AF_D:
19653 case R6_OPC_CMP_UN_D:
19654 case R6_OPC_CMP_EQ_D:
19655 case R6_OPC_CMP_UEQ_D:
19656 case R6_OPC_CMP_LT_D:
19657 case R6_OPC_CMP_ULT_D:
19658 case R6_OPC_CMP_LE_D:
19659 case R6_OPC_CMP_ULE_D:
19660 case R6_OPC_CMP_SAF_D:
19661 case R6_OPC_CMP_SUN_D:
19662 case R6_OPC_CMP_SEQ_D:
19663 case R6_OPC_CMP_SEUQ_D:
19664 case R6_OPC_CMP_SLT_D:
19665 case R6_OPC_CMP_SULT_D:
19666 case R6_OPC_CMP_SLE_D:
19667 case R6_OPC_CMP_SULE_D:
19668 case R6_OPC_CMP_OR_D:
19669 case R6_OPC_CMP_UNE_D:
19670 case R6_OPC_CMP_NE_D:
19671 case R6_OPC_CMP_SOR_D:
19672 case R6_OPC_CMP_SUNE_D:
19673 case R6_OPC_CMP_SNE_D:
19674 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19675 break;
19676 default:
d2bfa6e6
MR
19677 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19678 rt, rd, sa, (imm >> 8) & 0x7);
19679
5692c6e1 19680 break;
3f493883 19681 }
5692c6e1
YK
19682 } else {
19683 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19684 (imm >> 8) & 0x7);
36d23958 19685 }
5692c6e1
YK
19686 break;
19687 }
19688 case OPC_BZ_V:
19689 case OPC_BNZ_V:
19690 case OPC_BZ_B:
19691 case OPC_BZ_H:
19692 case OPC_BZ_W:
19693 case OPC_BZ_D:
19694 case OPC_BNZ_B:
19695 case OPC_BNZ_H:
19696 case OPC_BNZ_W:
19697 case OPC_BNZ_D:
19698 check_insn(ctx, ASE_MSA);
19699 gen_msa_branch(env, ctx, op1);
19700 break;
19701 default:
19702 MIPS_INVAL("cp1");
9c708c7f 19703 generate_exception_end(ctx, EXCP_RI);
5692c6e1 19704 break;
6ea83fed 19705 }
4ad40f36
FB
19706 break;
19707
31837be3
YK
19708 /* Compact branches [R6] and COP2 [non-R6] */
19709 case OPC_BC: /* OPC_LWC2 */
19710 case OPC_BALC: /* OPC_SWC2 */
19711 if (ctx->insn_flags & ISA_MIPS32R6) {
19712 /* OPC_BC, OPC_BALC */
19713 gen_compute_compact_branch(ctx, op, 0, 0,
19714 sextract32(ctx->opcode << 2, 0, 28));
19715 } else {
19716 /* OPC_LWC2, OPC_SWC2 */
19717 /* COP2: Not implemented. */
19718 generate_exception_err(ctx, EXCP_CpU, 2);
19719 }
19720 break;
19721 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19722 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19723 if (ctx->insn_flags & ISA_MIPS32R6) {
19724 if (rs != 0) {
19725 /* OPC_BEQZC, OPC_BNEZC */
19726 gen_compute_compact_branch(ctx, op, rs, 0,
19727 sextract32(ctx->opcode << 2, 0, 23));
19728 } else {
19729 /* OPC_JIC, OPC_JIALC */
19730 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19731 }
19732 } else {
19733 /* OPC_LWC2, OPC_SWC2 */
19734 /* COP2: Not implemented. */
19735 generate_exception_err(ctx, EXCP_CpU, 2);
19736 }
4ad40f36 19737 break;
bd277fa1 19738 case OPC_CP2:
d75c135e 19739 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19740 /* Note that these instructions use different fields. */
19741 gen_loongson_multimedia(ctx, sa, rd, rt);
19742 break;
4ad40f36 19743
7a387fff 19744 case OPC_CP3:
fecd2646 19745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19746 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19747 check_cp1_enabled(ctx);
36d23958
TS
19748 op1 = MASK_CP3(ctx->opcode);
19749 switch (op1) {
d9224450
MR
19750 case OPC_LUXC1:
19751 case OPC_SUXC1:
19752 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19753 /* Fallthrough */
5a5012ec
TS
19754 case OPC_LWXC1:
19755 case OPC_LDXC1:
5a5012ec
TS
19756 case OPC_SWXC1:
19757 case OPC_SDXC1:
d9224450 19758 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19759 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19760 break;
e0c84da7 19761 case OPC_PREFX:
d9224450 19762 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19763 /* Treat as NOP. */
e0c84da7 19764 break;
5a5012ec 19765 case OPC_ALNV_PS:
d9224450
MR
19766 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19767 /* Fallthrough */
5a5012ec
TS
19768 case OPC_MADD_S:
19769 case OPC_MADD_D:
19770 case OPC_MADD_PS:
19771 case OPC_MSUB_S:
19772 case OPC_MSUB_D:
19773 case OPC_MSUB_PS:
19774 case OPC_NMADD_S:
19775 case OPC_NMADD_D:
19776 case OPC_NMADD_PS:
19777 case OPC_NMSUB_S:
19778 case OPC_NMSUB_D:
19779 case OPC_NMSUB_PS:
d9224450 19780 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19781 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19782 break;
36d23958 19783 default:
923617a3 19784 MIPS_INVAL("cp3");
9c708c7f 19785 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
19786 break;
19787 }
19788 } else {
e397ee33 19789 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19790 }
4ad40f36
FB
19791 break;
19792
d26bc211 19793#if defined(TARGET_MIPS64)
7a387fff 19794 /* MIPS64 opcodes */
7a387fff 19795 case OPC_LDL ... OPC_LDR:
bf7910c6 19796 case OPC_LLD:
fecd2646 19797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19798 /* fall through */
fecd2646 19799 case OPC_LWU:
7a387fff 19800 case OPC_LD:
d75c135e 19801 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19802 check_mips_64(ctx);
d75c135e 19803 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19804 break;
19805 case OPC_SDL ... OPC_SDR:
fecd2646 19806 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19807 /* fall through */
7a387fff 19808 case OPC_SD:
d75c135e 19809 check_insn(ctx, ISA_MIPS3);
e189e748 19810 check_mips_64(ctx);
5c13fdfd 19811 gen_st(ctx, op, rt, rs, imm);
7a387fff 19812 break;
d66c7132 19813 case OPC_SCD:
bf7910c6 19814 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19815 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19816 check_mips_64(ctx);
19817 gen_st_cond(ctx, op, rt, rs, imm);
19818 break;
31837be3
YK
19819 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19820 if (ctx->insn_flags & ISA_MIPS32R6) {
19821 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19822 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19823 } else {
19824 /* OPC_DADDI */
19825 check_insn(ctx, ISA_MIPS3);
19826 check_mips_64(ctx);
19827 gen_arith_imm(ctx, op, rt, rs, imm);
19828 }
19829 break;
324d9e32 19830 case OPC_DADDIU:
d75c135e 19831 check_insn(ctx, ISA_MIPS3);
e189e748 19832 check_mips_64(ctx);
d75c135e 19833 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19834 break;
31837be3
YK
19835#else
19836 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19837 if (ctx->insn_flags & ISA_MIPS32R6) {
19838 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19839 } else {
19840 MIPS_INVAL("major opcode");
9c708c7f 19841 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19842 }
19843 break;
6af0bf9c 19844#endif
d4ea6acd
LA
19845 case OPC_DAUI: /* OPC_JALX */
19846 if (ctx->insn_flags & ISA_MIPS32R6) {
19847#if defined(TARGET_MIPS64)
19848 /* OPC_DAUI */
19849 check_mips_64(ctx);
db77d852
LA
19850 if (rs == 0) {
19851 generate_exception(ctx, EXCP_RI);
19852 } else if (rt != 0) {
d4ea6acd
LA
19853 TCGv t0 = tcg_temp_new();
19854 gen_load_gpr(t0, rs);
19855 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19856 tcg_temp_free(t0);
19857 }
d4ea6acd 19858#else
9c708c7f 19859 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
19860 MIPS_INVAL("major opcode");
19861#endif
19862 } else {
19863 /* OPC_JALX */
19864 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19865 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19866 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19867 }
364d4831 19868 break;
4c789546 19869 case OPC_MSA: /* OPC_MDMX */
7a387fff 19870 /* MDMX: Not implemented. */
4c789546 19871 gen_msa(env, ctx);
d4ea6acd
LA
19872 break;
19873 case OPC_PCREL:
19874 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19875 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19876 break;
6af0bf9c 19877 default: /* Invalid */
923617a3 19878 MIPS_INVAL("major opcode");
9c708c7f 19879 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19880 break;
19881 }
6af0bf9c
FB
19882}
19883
4e5e1215 19884void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19885{
4e5e1215 19886 MIPSCPU *cpu = mips_env_get_cpu(env);
ed2803da 19887 CPUState *cs = CPU(cpu);
278d0702 19888 DisasContext ctx;
6af0bf9c 19889 target_ulong pc_start;
fe237291 19890 target_ulong next_page_start;
2e70f6ef
PB
19891 int num_insns;
19892 int max_insns;
c9602061 19893 int insn_bytes;
339cd2a8 19894 int is_slot;
6af0bf9c
FB
19895
19896 pc_start = tb->pc;
fe237291 19897 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19898 ctx.pc = pc_start;
4ad40f36 19899 ctx.saved_pc = -1;
ed2803da 19900 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19901 ctx.insn_flags = env->insn_flags;
5ab5c041 19902 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19903 ctx.tb = tb;
19904 ctx.bstate = BS_NONE;
c20d594e 19905 ctx.btarget = 0;
e98c0d17 19906 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19907 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19908 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19909 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19910 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19911 ctx.PAMask = env->PAMask;
19912 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19913 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
c870e3f5 19914 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 19915 /* Restore delay slot state from the tb context. */
c068688b 19916 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19917 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19918 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19919 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 19920 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
f6d4dd81 19921 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
87552089 19922 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
6be77480 19923 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
fd4a04eb 19924 restore_cpu_state(env, &ctx);
932e71cd 19925#ifdef CONFIG_USER_ONLY
0eaef5aa 19926 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19927#else
0eaef5aa 19928 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19929#endif
be3a8c53
YK
19930 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19931 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19932 num_insns = 0;
19933 max_insns = tb->cflags & CF_COUNT_MASK;
190ce7fb 19934 if (max_insns == 0) {
2e70f6ef 19935 max_insns = CF_COUNT_MASK;
190ce7fb
RH
19936 }
19937 if (max_insns > TCG_MAX_INSNS) {
19938 max_insns = TCG_MAX_INSNS;
19939 }
19940
d12d51d5 19941 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19942 gen_tb_start(tb);
faf7aaa9 19943 while (ctx.bstate == BS_NONE) {
c20d594e 19944 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
959082fc 19945 num_insns++;
667b8e29 19946
b933066a
RH
19947 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19948 save_cpu_state(&ctx, 1);
19949 ctx.bstate = BS_BRANCH;
19950 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
19951 /* The address covered by the breakpoint must be included in
19952 [tb->pc, tb->pc + tb->size) in order to for it to be
19953 properly cleared -- thus we increment the PC here so that
19954 the logic setting tb->size below does the right thing. */
b933066a
RH
19955 ctx.pc += 4;
19956 goto done_generating;
19957 }
19958
959082fc 19959 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 19960 gen_io_start();
667b8e29 19961 }
c9602061 19962
339cd2a8 19963 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19964 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19965 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19966 insn_bytes = 4;
240ce26a 19967 decode_opc(env, &ctx);
d75c135e 19968 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19969 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19970 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19971 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19972 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19973 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 19974 } else {
9c708c7f 19975 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
19976 break;
19977 }
31837be3 19978
b231c103 19979 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19980 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19981 MIPS_HFLAG_FBNSLOT))) {
19982 /* force to generate branch as there is neither delay nor
19983 forbidden slot */
19984 is_slot = 1;
b231c103 19985 }
65935f07
YK
19986 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19987 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19988 /* Force to generate branch as microMIPS R6 doesn't restrict
19989 branches in the forbidden slot. */
19990 is_slot = 1;
19991 }
b231c103 19992 }
339cd2a8 19993 if (is_slot) {
31837be3 19994 gen_branch(&ctx, insn_bytes);
c9602061
NF
19995 }
19996 ctx.pc += insn_bytes;
19997
7b270ef2
NF
19998 /* Execute a branch and its delay slot as a single instruction.
19999 This is what GDB expects and is consistent with what the
20000 hardware does (e.g. if a delay slot instruction faults, the
20001 reported PC is the PC of the branch). */
ed2803da 20002 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 20003 break;
ed2803da 20004 }
4ad40f36 20005
fe237291 20006 if (ctx.pc >= next_page_start) {
6af0bf9c 20007 break;
fe237291 20008 }
4ad40f36 20009
fe700adb 20010 if (tcg_op_buf_full()) {
faf7aaa9 20011 break;
efd7f486 20012 }
faf7aaa9 20013
2e70f6ef
PB
20014 if (num_insns >= max_insns)
20015 break;
1b530a6d
AJ
20016
20017 if (singlestep)
20018 break;
6af0bf9c 20019 }
ed2803da 20020 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 20021 gen_io_end();
ed2803da
AF
20022 }
20023 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 20024 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 20025 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20026 } else {
6958549d 20027 switch (ctx.bstate) {
16c00cb2 20028 case BS_STOP:
df1561e2
TS
20029 gen_goto_tb(&ctx, 0, ctx.pc);
20030 break;
16c00cb2 20031 case BS_NONE:
278d0702 20032 save_cpu_state(&ctx, 0);
16c00cb2
TS
20033 gen_goto_tb(&ctx, 0, ctx.pc);
20034 break;
5a5012ec 20035 case BS_EXCP:
57fec1fe 20036 tcg_gen_exit_tb(0);
16c00cb2 20037 break;
5a5012ec
TS
20038 case BS_BRANCH:
20039 default:
20040 break;
6958549d 20041 }
6af0bf9c 20042 }
4ad40f36 20043done_generating:
806f352d 20044 gen_tb_end(tb, num_insns);
0a7df5da 20045
4e5e1215
RH
20046 tb->size = ctx.pc - pc_start;
20047 tb->icount = num_insns;
20048
6af0bf9c 20049#ifdef DEBUG_DISAS
d12d51d5 20050 LOG_DISAS("\n");
4910e6e4
RH
20051 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20052 && qemu_log_in_addr_range(pc_start)) {
1ee73216 20053 qemu_log_lock();
93fcfe39 20054 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 20055 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 20056 qemu_log("\n");
1ee73216 20057 qemu_log_unlock();
6af0bf9c
FB
20058 }
20059#endif
6af0bf9c
FB
20060}
20061
7db13fae 20062static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20063 int flags)
6ea83fed
FB
20064{
20065 int i;
5e755519 20066 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20067
2a5612e6
SW
20068#define printfpr(fp) \
20069 do { \
20070 if (is_fpu64) \
20071 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20072 " fd:%13g fs:%13g psu: %13g\n", \
20073 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20074 (double)(fp)->fd, \
20075 (double)(fp)->fs[FP_ENDIAN_IDX], \
20076 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20077 else { \
20078 fpr_t tmp; \
20079 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20080 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20081 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20082 " fd:%13g fs:%13g psu:%13g\n", \
20083 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20084 (double)tmp.fd, \
20085 (double)tmp.fs[FP_ENDIAN_IDX], \
20086 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20087 } \
6ea83fed
FB
20088 } while(0)
20089
5a5012ec 20090
9a78eead
SW
20091 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20092 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20093 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20094 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20095 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20096 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20097 }
20098
20099#undef printfpr
20100}
20101
878096ee
AF
20102void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20103 int flags)
6af0bf9c 20104{
878096ee
AF
20105 MIPSCPU *cpu = MIPS_CPU(cs);
20106 CPUMIPSState *env = &cpu->env;
6af0bf9c 20107 int i;
3b46e624 20108
a7200c9f
SW
20109 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20110 " LO=0x" TARGET_FMT_lx " ds %04x "
20111 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20112 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20113 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20114 for (i = 0; i < 32; i++) {
20115 if ((i & 3) == 0)
20116 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20117 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20118 if ((i & 3) == 3)
20119 cpu_fprintf(f, "\n");
20120 }
568b600d 20121
3594c774 20122 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20123 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20124 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20125 PRIx64 "\n",
5499b6ff 20126 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20127 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20128 env->CP0_Config2, env->CP0_Config3);
20129 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20130 env->CP0_Config4, env->CP0_Config5);
5e755519 20131 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 20132 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
20133}
20134
78ce64f4 20135void mips_tcg_init(void)
39454628 20136{
f01be154 20137 int i;
39454628
TS
20138 static int inited;
20139
20140 /* Initialize various static tables. */
20141 if (inited)
6958549d 20142 return;
39454628 20143
a7812ae4 20144 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7c255043 20145 tcg_ctx.tcg_env = cpu_env;
e1ccc054 20146
f2c94b92 20147 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 20148 for (i = 1; i < 32; i++)
e1ccc054 20149 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20150 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20151 regnames[i]);
d73ee8a2 20152
863f264d
YK
20153 for (i = 0; i < 32; i++) {
20154 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20155 msa_wr_d[i * 2] =
e1ccc054 20156 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20157 /* The scalar floating-point unit (FPU) registers are mapped on
20158 * the MSA vector registers. */
20159 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20160 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20161 msa_wr_d[i * 2 + 1] =
e1ccc054 20162 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20163 }
20164
e1ccc054 20165 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20166 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20167 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20168 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20169 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20170 regnames_HI[i]);
e1ccc054 20171 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20172 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20173 regnames_LO[i]);
4b2eb8d2 20174 }
e1ccc054 20175 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20176 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20177 "DSPControl");
e1ccc054 20178 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20179 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20180 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20181 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20182 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20183 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20184
e1ccc054 20185 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20186 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20187 "fcr0");
e1ccc054 20188 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20189 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20190 "fcr31");
39454628
TS
20191
20192 inited = 1;
20193}
20194
aaed909a
FB
20195#include "translate_init.c"
20196
30bf942d 20197MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 20198{
0f71a709 20199 MIPSCPU *cpu;
6af0bf9c 20200 CPUMIPSState *env;
c227f099 20201 const mips_def_t *def;
6af0bf9c 20202
aaed909a
FB
20203 def = cpu_mips_find_by_name(cpu_model);
20204 if (!def)
20205 return NULL;
0f71a709
AF
20206 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20207 env = &cpu->env;
aaed909a 20208 env->cpu_model = def;
89777fd1 20209 env->exception_base = (int32_t)0xBFC00000;
aaed909a 20210
51cc2e78
BS
20211#ifndef CONFIG_USER_ONLY
20212 mmu_init(env, def);
20213#endif
20214 fpu_init(env, def);
20215 mvp_init(env, def);
c1caf1d9
AF
20216
20217 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20218
30bf942d 20219 return cpu;
6ae81775
TS
20220}
20221
bff384a4
LA
20222bool cpu_supports_cps_smp(const char *cpu_model)
20223{
20224 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20225 if (!def) {
20226 return false;
20227 }
20228
20229 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20230}
20231
bed9e5ce
PB
20232bool cpu_supports_isa(const char *cpu_model, unsigned int isa)
20233{
20234 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20235 if (!def) {
20236 return false;
20237 }
20238
20239 return (def->insn_flags & isa) != 0;
20240}
20241
89777fd1
LA
20242void cpu_set_exception_base(int vp_index, target_ulong address)
20243{
20244 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20245 vp->env.exception_base = address;
20246}
20247
1bba0dc9 20248void cpu_state_reset(CPUMIPSState *env)
6ae81775 20249{
55e5c285
AF
20250 MIPSCPU *cpu = mips_env_get_cpu(env);
20251 CPUState *cs = CPU(cpu);
6ae81775 20252
51cc2e78
BS
20253 /* Reset registers to their default values */
20254 env->CP0_PRid = env->cpu_model->CP0_PRid;
20255 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20256#ifdef TARGET_WORDS_BIGENDIAN
20257 env->CP0_Config0 |= (1 << CP0C0_BE);
20258#endif
20259 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20260 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20261 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20262 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20263 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20264 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20265 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20266 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20267 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20268 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20269 << env->cpu_model->CP0_LLAddr_shift;
20270 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20271 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20272 env->CCRes = env->cpu_model->CCRes;
20273 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20274 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20275 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20276 env->current_tc = 0;
20277 env->SEGBITS = env->cpu_model->SEGBITS;
20278 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20279#if defined(TARGET_MIPS64)
20280 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20281 env->SEGMask |= 3ULL << 62;
20282 }
20283#endif
20284 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20285 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20286 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20287 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20288 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20289 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20290 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20291 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20292 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20293 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20294 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20295 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20296 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 20297 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20298 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20299 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20300 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20301 env->insn_flags = env->cpu_model->insn_flags;
20302
0eaef5aa 20303#if defined(CONFIG_USER_ONLY)
03e6e501 20304 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20305# ifdef TARGET_MIPS64
20306 /* Enable 64-bit register mode. */
20307 env->CP0_Status |= (1 << CP0St_PX);
20308# endif
20309# ifdef TARGET_ABI_MIPSN64
20310 /* Enable 64-bit address mode. */
20311 env->CP0_Status |= (1 << CP0St_UX);
20312# endif
94159135
MI
20313 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20314 hardware registers. */
20315 env->CP0_HWREna |= 0x0000000F;
91a75935 20316 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20317 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20318 }
6f0af304
PJ
20319 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20320 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20321 }
4d66261f
PJ
20322# if defined(TARGET_MIPS64)
20323 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20324 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20325 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20326 env->CP0_Status |= (1 << CP0St_FR);
20327 }
4d66261f 20328# endif
932e71cd
AJ
20329#else
20330 if (env->hflags & MIPS_HFLAG_BMASK) {
20331 /* If the exception was raised from a delay slot,
20332 come back to the jump. */
c3577479
MR
20333 env->CP0_ErrorEPC = (env->active_tc.PC
20334 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20335 } else {
932e71cd
AJ
20336 env->CP0_ErrorEPC = env->active_tc.PC;
20337 }
89777fd1 20338 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20339 env->CP0_Random = env->tlb->nb_tlb - 1;
20340 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20341 env->CP0_Wired = 0;
01bc435b 20342 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7
JH
20343 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20344 if (kvm_enabled()) {
20345 env->CP0_EBase |= 0x40000000;
20346 } else {
20347 env->CP0_EBase |= 0x80000000;
20348 }
c870e3f5
YK
20349 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20350 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20351 }
a0c80608
PB
20352 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20353 0x3ff : 0xff;
932e71cd
AJ
20354 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20355 /* vectored interrupts not implemented, timer on int 7,
20356 no performance counters. */
20357 env->CP0_IntCtl = 0xe0000000;
20358 {
20359 int i;
20360
20361 for (i = 0; i < 7; i++) {
20362 env->CP0_WatchLo[i] = 0;
20363 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20364 }
932e71cd
AJ
20365 env->CP0_WatchLo[7] = 0;
20366 env->CP0_WatchHi[7] = 0;
fd88b6ab 20367 }
932e71cd
AJ
20368 /* Count register increments in debug mode, EJTAG version 1 */
20369 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20370
4b69c7e2
JH
20371 cpu_mips_store_count(env, 1);
20372
9e56e756
EI
20373 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20374 int i;
20375
20376 /* Only TC0 on VPE 0 starts as active. */
20377 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20378 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20379 env->tcs[i].CP0_TCHalt = 1;
20380 }
20381 env->active_tc.CP0_TCHalt = 1;
259186a7 20382 cs->halted = 1;
9e56e756 20383
55e5c285 20384 if (cs->cpu_index == 0) {
9e56e756
EI
20385 /* VPE0 starts up enabled. */
20386 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20387 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20388
20389 /* TC0 starts up unhalted. */
259186a7 20390 cs->halted = 0;
9e56e756
EI
20391 env->active_tc.CP0_TCHalt = 0;
20392 env->tcs[0].CP0_TCHalt = 0;
20393 /* With thread 0 active. */
20394 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20395 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20396 }
20397 }
51cc2e78 20398#endif
ddc584bd
LA
20399 if ((env->insn_flags & ISA_MIPS32R6) &&
20400 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20401 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20402 env->CP0_Status |= (1 << CP0St_FR);
20403 }
20404
863f264d
YK
20405 /* MSA */
20406 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20407 msa_reset(env);
20408 }
20409
03e6e501 20410 compute_hflags(env);
599bc5e8 20411 restore_fp_status(env);
e117f526 20412 restore_pamask(env);
27103424 20413 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20414
20415 if (semihosting_get_argc()) {
20416 /* UHI interface can be used to obtain argc and argv */
20417 env->active_tc.gpr[4] = -1;
20418 }
6af0bf9c 20419}
d2856f1a 20420
bad729e2
RH
20421void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20422 target_ulong *data)
d2856f1a 20423{
bad729e2 20424 env->active_tc.PC = data[0];
d2856f1a 20425 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20426 env->hflags |= data[1];
4636401d
AJ
20427 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20428 case MIPS_HFLAG_BR:
20429 break;
20430 case MIPS_HFLAG_BC:
20431 case MIPS_HFLAG_BL:
20432 case MIPS_HFLAG_B:
bad729e2 20433 env->btarget = data[2];
4636401d
AJ
20434 break;
20435 }
d2856f1a 20436}
This page took 4.704839 seconds and 4 git commands to generate.