]> Git Repo - qemu.git/blame - target-mips/translate.c
QJSON: Use OBJECT_CHECK
[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
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
a7812ae4 32
a7e30d84
LV
33#include "trace-tcg.h"
34
35
fb7729e2 36#define MIPS_DEBUG_DISAS 0
c570fd16 37//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 38
7a387fff
TS
39/* MIPS major opcodes */
40#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
41
42enum {
43 /* indirect opcode tables */
7a387fff
TS
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 52 /* arithmetic with immediate */
7a387fff
TS
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
324d9e32 57 /* logic with immediate */
7a387fff
TS
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
324d9e32 62 /* arithmetic with immediate */
7a387fff
TS
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
e37e863f 65 /* Jump and branches */
7a387fff
TS
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
68 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL = (0x14 << 26),
70 OPC_BNE = (0x05 << 26),
71 OPC_BNEL = (0x15 << 26),
72 OPC_BLEZ = (0x06 << 26),
73 OPC_BLEZL = (0x16 << 26),
74 OPC_BGTZ = (0x07 << 26),
75 OPC_BGTZL = (0x17 << 26),
b231c103 76 OPC_JALX = (0x1D << 26),
d4ea6acd 77 OPC_DAUI = (0x1D << 26),
e37e863f 78 /* Load and stores */
7a387fff
TS
79 OPC_LDL = (0x1A << 26),
80 OPC_LDR = (0x1B << 26),
81 OPC_LB = (0x20 << 26),
82 OPC_LH = (0x21 << 26),
83 OPC_LWL = (0x22 << 26),
84 OPC_LW = (0x23 << 26),
364d4831 85 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
86 OPC_LBU = (0x24 << 26),
87 OPC_LHU = (0x25 << 26),
88 OPC_LWR = (0x26 << 26),
89 OPC_LWU = (0x27 << 26),
90 OPC_SB = (0x28 << 26),
91 OPC_SH = (0x29 << 26),
92 OPC_SWL = (0x2A << 26),
93 OPC_SW = (0x2B << 26),
94 OPC_SDL = (0x2C << 26),
95 OPC_SDR = (0x2D << 26),
96 OPC_SWR = (0x2E << 26),
97 OPC_LL = (0x30 << 26),
98 OPC_LLD = (0x34 << 26),
99 OPC_LD = (0x37 << 26),
364d4831 100 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
101 OPC_SC = (0x38 << 26),
102 OPC_SCD = (0x3C << 26),
103 OPC_SD = (0x3F << 26),
e37e863f 104 /* Floating point load/store */
7a387fff
TS
105 OPC_LWC1 = (0x31 << 26),
106 OPC_LWC2 = (0x32 << 26),
107 OPC_LDC1 = (0x35 << 26),
108 OPC_LDC2 = (0x36 << 26),
109 OPC_SWC1 = (0x39 << 26),
110 OPC_SWC2 = (0x3A << 26),
111 OPC_SDC1 = (0x3D << 26),
112 OPC_SDC2 = (0x3E << 26),
31837be3
YK
113 /* Compact Branches */
114 OPC_BLEZALC = (0x06 << 26),
115 OPC_BGEZALC = (0x06 << 26),
116 OPC_BGEUC = (0x06 << 26),
117 OPC_BGTZALC = (0x07 << 26),
118 OPC_BLTZALC = (0x07 << 26),
119 OPC_BLTUC = (0x07 << 26),
120 OPC_BOVC = (0x08 << 26),
121 OPC_BEQZALC = (0x08 << 26),
122 OPC_BEQC = (0x08 << 26),
123 OPC_BLEZC = (0x16 << 26),
124 OPC_BGEZC = (0x16 << 26),
125 OPC_BGEC = (0x16 << 26),
126 OPC_BGTZC = (0x17 << 26),
127 OPC_BLTZC = (0x17 << 26),
128 OPC_BLTC = (0x17 << 26),
129 OPC_BNVC = (0x18 << 26),
130 OPC_BNEZALC = (0x18 << 26),
131 OPC_BNEC = (0x18 << 26),
132 OPC_BC = (0x32 << 26),
133 OPC_BEQZC = (0x36 << 26),
134 OPC_JIC = (0x36 << 26),
135 OPC_BALC = (0x3A << 26),
136 OPC_BNEZC = (0x3E << 26),
137 OPC_JIALC = (0x3E << 26),
7a387fff
TS
138 /* MDMX ASE specific */
139 OPC_MDMX = (0x1E << 26),
239dfebe
YK
140 /* MSA ASE, same as MDMX */
141 OPC_MSA = OPC_MDMX,
e37e863f 142 /* Cache and prefetch */
7a387fff
TS
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
147};
148
149/* PC-relative address computation / loads */
150#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152enum {
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
157
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
161
162 /* Other */
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
164};
165
166/* MIPS special opcodes */
7a387fff
TS
167#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
168
e37e863f
FB
169enum {
170 /* Shifts */
7a387fff 171 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 176 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 180 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 188 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 194 /* Multiplication / division */
7a387fff
TS
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 203
e37e863f 204 /* 2 registers arithmetic / logic */
7a387fff
TS
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 219 /* Jumps */
7a387fff
TS
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 222 /* Traps */
7a387fff
TS
223 OPC_TGE = 0x30 | OPC_SPECIAL,
224 OPC_TGEU = 0x31 | OPC_SPECIAL,
225 OPC_TLT = 0x32 | OPC_SPECIAL,
226 OPC_TLTU = 0x33 | OPC_SPECIAL,
227 OPC_TEQ = 0x34 | OPC_SPECIAL,
228 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 229 /* HI / LO registers load & stores */
7a387fff
TS
230 OPC_MFHI = 0x10 | OPC_SPECIAL,
231 OPC_MTHI = 0x11 | OPC_SPECIAL,
232 OPC_MFLO = 0x12 | OPC_SPECIAL,
233 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 234 /* Conditional moves */
7a387fff
TS
235 OPC_MOVZ = 0x0A | OPC_SPECIAL,
236 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 237
b691d9d2
LA
238 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
239 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
240
7a387fff 241 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
242
243 /* Special */
a0d700e4 244 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
245 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
246 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 247 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
248 OPC_SYNC = 0x0F | OPC_SPECIAL,
249
7a387fff
TS
250 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
251 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
252 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
253 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
254};
255
b42ee5e1
LA
256/* R6 Multiply and Divide instructions have the same Opcode
257 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
258#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
259
260enum {
261 R6_OPC_MUL = OPC_MULT | (2 << 6),
262 R6_OPC_MUH = OPC_MULT | (3 << 6),
263 R6_OPC_MULU = OPC_MULTU | (2 << 6),
264 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
265 R6_OPC_DIV = OPC_DIV | (2 << 6),
266 R6_OPC_MOD = OPC_DIV | (3 << 6),
267 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
268 R6_OPC_MODU = OPC_DIVU | (3 << 6),
269
270 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
271 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
272 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
273 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
274 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
275 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
276 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
277 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
278
279 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
280 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
281 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
282 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
283 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
284
285 OPC_LSA = 0x05 | OPC_SPECIAL,
286 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
287};
288
e9c71dd1
TS
289/* Multiplication variants of the vr54xx. */
290#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
291
292enum {
293 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
294 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
295 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
296 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
297 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
298 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
299 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
300 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
302 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
303 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
304 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
305 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
306 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
307};
308
7a387fff
TS
309/* REGIMM (rt field) opcodes */
310#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
311
312enum {
313 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
314 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
315 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
316 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
317 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
318 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
319 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
320 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
321 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
322 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
323 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
324 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
325 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
326 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
327 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
328
329 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
330 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
331};
332
7a387fff
TS
333/* Special2 opcodes */
334#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
335
e37e863f 336enum {
7a387fff
TS
337 /* Multiply & xxx operations */
338 OPC_MADD = 0x00 | OPC_SPECIAL2,
339 OPC_MADDU = 0x01 | OPC_SPECIAL2,
340 OPC_MUL = 0x02 | OPC_SPECIAL2,
341 OPC_MSUB = 0x04 | OPC_SPECIAL2,
342 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
343 /* Loongson 2F */
344 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
345 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
346 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
347 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
348 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
349 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
350 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
351 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
352 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
353 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
354 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
355 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 356 /* Misc */
7a387fff
TS
357 OPC_CLZ = 0x20 | OPC_SPECIAL2,
358 OPC_CLO = 0x21 | OPC_SPECIAL2,
359 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
360 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 361 /* Special */
7a387fff
TS
362 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
363};
364
365/* Special3 opcodes */
366#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
367
368enum {
369 OPC_EXT = 0x00 | OPC_SPECIAL3,
370 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
371 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
372 OPC_DEXT = 0x03 | OPC_SPECIAL3,
373 OPC_INS = 0x04 | OPC_SPECIAL3,
374 OPC_DINSM = 0x05 | OPC_SPECIAL3,
375 OPC_DINSU = 0x06 | OPC_SPECIAL3,
376 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
377 OPC_FORK = 0x08 | OPC_SPECIAL3,
378 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
379 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
380 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
381 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
382
383 /* Loongson 2E */
384 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
385 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
386 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
387 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
388 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
389 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
390 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
391 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
392 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
393 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
394 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
395 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
396
397 /* MIPS DSP Load */
398 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
399 /* MIPS DSP Arithmetic */
400 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 401 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 402 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 403 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
404 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
405 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
406 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 407 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
408 /* MIPS DSP GPR-Based Shift Sub-class */
409 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 410 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
411 /* MIPS DSP Multiply Sub-class insns */
412 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
413 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
414 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 415 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
416 /* DSP Bit/Manipulation Sub-class */
417 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 418 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 419 /* MIPS DSP Append Sub-class */
26690560 420 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 421 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
422 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
423 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 424 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
425
426 /* R6 */
bf7910c6
LA
427 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
428 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
429 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
430 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
431 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
432 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
433};
434
7a387fff
TS
435/* BSHFL opcodes */
436#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
437
e37e863f 438enum {
15eacb9b
YK
439 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
440 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
441 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
442 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
443 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
444 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
445};
446
7a387fff
TS
447/* DBSHFL opcodes */
448#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
449
e37e863f 450enum {
15eacb9b
YK
451 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
452 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
453 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
454 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
455 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
456};
457
e45a93e2
JL
458/* MIPS DSP REGIMM opcodes */
459enum {
460 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 461 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
462};
463
9b1a1d68
JL
464#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
465/* MIPS DSP Load */
466enum {
467 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
468 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
469 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 470 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
471};
472
461c08df
JL
473#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
474enum {
475 /* MIPS DSP Arithmetic Sub-class */
476 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
491 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
492 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
493 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
494 /* MIPS DSP Multiply Sub-class insns */
495 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
501};
502
503#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
504#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505enum {
506 /* MIPS DSP Arithmetic Sub-class */
507 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
519 /* MIPS DSP Multiply Sub-class insns */
520 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
524};
525
526#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527enum {
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
542 /* DSP Bit/Manipulation Sub-class */
543 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
548};
549
550#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
560 /* DSP Compare-Pick Sub-class */
561 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 576};
a22260ae 577
77c5fa8b
JL
578#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
579enum {
580 /* MIPS DSP GPR-Based Shift Sub-class */
581 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
603};
461c08df 604
a22260ae
JL
605#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606enum {
607 /* MIPS DSP Multiply Sub-class insns */
608 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
622 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
630};
631
1cb6686c
JL
632#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633enum {
634 /* DSP Bit/Manipulation Sub-class */
635 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
636};
637
26690560
JL
638#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639enum {
df6126a7 640 /* MIPS DSP Append Sub-class */
26690560
JL
641 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
642 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
643 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
644};
645
b53371ed
JL
646#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
647enum {
648 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
649 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
662 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
663 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
664 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
665 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
666};
667
461c08df
JL
668#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
670 /* MIPS DSP Arithmetic Sub-class */
671 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
688 /* DSP Bit/Manipulation Sub-class */
689 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 695};
461c08df 696
461c08df
JL
697#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
698enum {
a22260ae
JL
699 /* MIPS DSP Multiply Sub-class insns */
700 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
727};
461c08df 728
461c08df
JL
729#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730enum {
26690560
JL
731 /* DSP Compare-Pick Sub-class */
732 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
751 /* MIPS DSP Arithmetic Sub-class */
752 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
760};
461c08df 761
26690560
JL
762#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763enum {
df6126a7 764 /* DSP Append Sub-class */
26690560
JL
765 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
767 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
768 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
769};
26690560 770
b53371ed
JL
771#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
772enum {
773 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
774 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
775 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
795};
796
1cb6686c
JL
797#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798enum {
799 /* DSP Bit/Manipulation Sub-class */
800 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
801};
1cb6686c 802
a22260ae
JL
803#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804enum {
805 /* MIPS DSP Multiply Sub-class insns */
806 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
832};
a22260ae 833
77c5fa8b
JL
834#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835enum {
836 /* MIPS DSP GPR-Based Shift Sub-class */
837 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
863};
77c5fa8b 864
7a387fff
TS
865/* Coprocessor 0 (rs field) */
866#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
867
6ea83fed 868enum {
7a387fff
TS
869 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
870 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 873 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
874 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
875 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 876 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
877 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
878 OPC_C0 = (0x10 << 21) | OPC_CP0,
879 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
880 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 881};
7a387fff
TS
882
883/* MFMC0 opcodes */
b48cfdff 884#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
885
886enum {
ead9360e
TS
887 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
888 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
890 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
891 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
892 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
893};
894
895/* Coprocessor 0 (with rs == C0) */
896#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
897
898enum {
899 OPC_TLBR = 0x01 | OPC_C0,
900 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
901 OPC_TLBINV = 0x03 | OPC_C0,
902 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
903 OPC_TLBWR = 0x06 | OPC_C0,
904 OPC_TLBP = 0x08 | OPC_C0,
905 OPC_RFE = 0x10 | OPC_C0,
906 OPC_ERET = 0x18 | OPC_C0,
907 OPC_DERET = 0x1F | OPC_C0,
908 OPC_WAIT = 0x20 | OPC_C0,
909};
910
911/* Coprocessor 1 (rs field) */
912#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
913
bf4120ad
NF
914/* Values for the fmt field in FP instructions */
915enum {
916 /* 0 - 15 are reserved */
e459440a
AJ
917 FMT_S = 16, /* single fp */
918 FMT_D = 17, /* double fp */
919 FMT_E = 18, /* extended fp */
920 FMT_Q = 19, /* quad fp */
921 FMT_W = 20, /* 32-bit fixed */
922 FMT_L = 21, /* 64-bit fixed */
923 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
924 /* 23 - 31 are reserved */
925};
926
7a387fff
TS
927enum {
928 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
929 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
930 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 931 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
932 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
933 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
934 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 935 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 936 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
937 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
938 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
939 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
940 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
950 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
951 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
952 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
953 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
954 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
955 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
956 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
957 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
958};
959
5a5012ec
TS
960#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
961#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
962
7a387fff
TS
963enum {
964 OPC_BC1F = (0x00 << 16) | OPC_BC1,
965 OPC_BC1T = (0x01 << 16) | OPC_BC1,
966 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
967 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
968};
969
5a5012ec
TS
970enum {
971 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
972 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
973};
974
975enum {
976 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
977 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
978};
7a387fff
TS
979
980#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
981
982enum {
983 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
984 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
985 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
986 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
987 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
988 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
989 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
990 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
991 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
992 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
993 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
994};
995
bd277fa1
RH
996#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
997
998enum {
999 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1000 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1007
1008 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1009 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1016
1017 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1018 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1021 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1022 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1023 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1024 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1025
1026 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1027 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1030 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1034
1035 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1036 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1037 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1041
1042 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1043 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1048
1049 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1050 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1055
1056 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1057 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1062
1063 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1064 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1065 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1066 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1067 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1069
1070 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1071 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1072 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1073 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1074 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1076
1077 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1078 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1079 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1081 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1083
1084 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1085 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1086 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1087 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1088 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1089 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1090};
1091
1092
e0c84da7
TS
1093#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1094
1095enum {
1096 OPC_LWXC1 = 0x00 | OPC_CP3,
1097 OPC_LDXC1 = 0x01 | OPC_CP3,
1098 OPC_LUXC1 = 0x05 | OPC_CP3,
1099 OPC_SWXC1 = 0x08 | OPC_CP3,
1100 OPC_SDXC1 = 0x09 | OPC_CP3,
1101 OPC_SUXC1 = 0x0D | OPC_CP3,
1102 OPC_PREFX = 0x0F | OPC_CP3,
1103 OPC_ALNV_PS = 0x1E | OPC_CP3,
1104 OPC_MADD_S = 0x20 | OPC_CP3,
1105 OPC_MADD_D = 0x21 | OPC_CP3,
1106 OPC_MADD_PS = 0x26 | OPC_CP3,
1107 OPC_MSUB_S = 0x28 | OPC_CP3,
1108 OPC_MSUB_D = 0x29 | OPC_CP3,
1109 OPC_MSUB_PS = 0x2E | OPC_CP3,
1110 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1111 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1112 OPC_NMADD_PS= 0x36 | OPC_CP3,
1113 OPC_NMSUB_S = 0x38 | OPC_CP3,
1114 OPC_NMSUB_D = 0x39 | OPC_CP3,
1115 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1116};
1117
239dfebe
YK
1118/* MSA Opcodes */
1119#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1120enum {
1121 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1122 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1123 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1124 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1125 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1126 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1127 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1128 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1129 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1130 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1131 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1132 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1133 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1134 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1135 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1136 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1137 OPC_MSA_ELM = 0x19 | OPC_MSA,
1138 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1139 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1140 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1141 OPC_MSA_VEC = 0x1E | OPC_MSA,
1142
1143 /* MI10 instruction */
1144 OPC_LD_B = (0x20) | OPC_MSA,
1145 OPC_LD_H = (0x21) | OPC_MSA,
1146 OPC_LD_W = (0x22) | OPC_MSA,
1147 OPC_LD_D = (0x23) | OPC_MSA,
1148 OPC_ST_B = (0x24) | OPC_MSA,
1149 OPC_ST_H = (0x25) | OPC_MSA,
1150 OPC_ST_W = (0x26) | OPC_MSA,
1151 OPC_ST_D = (0x27) | OPC_MSA,
1152};
1153
1154enum {
1155 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1156 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1157 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1158 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1159 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1160 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1161 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1162 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1163 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1164 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1165 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1166 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1167 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1168
1169 /* I8 instruction */
1170 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1171 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1172 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1173 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1174 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1175 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1176 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1177 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1179 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1180
1181 /* VEC/2R/2RF instruction */
1182 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1183 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1184 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1185 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1186 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1187 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1188 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1189
1190 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1191 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1192
1193 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1194 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1195 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1196 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1197 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1198
1199 /* 2RF instruction df(bit 16) = _w, _d */
1200 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1201 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1203 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1204 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1205 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1206 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1207 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1208 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1210 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1211 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1212 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1214 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1216
1217 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1218 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1219 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1220 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1221 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1222 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1223 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1224 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1225 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1226 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1227 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1228 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1229 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1230 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1231 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1232 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1233 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1234 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1235 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1236 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1237 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1238 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1239 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1240 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1241 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1242 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1243 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1244 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1245 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1246 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1249 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1250 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1251 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1252 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1254 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1255 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1256 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1257 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1258 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1259 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1260 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1261 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1262 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1263 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1264 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1265 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1266 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1267 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1268 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1269 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1270 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1271 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1272 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1273 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1274 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1276 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1281
1282 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1283 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1284 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1285 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1286 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1287 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1288 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1289 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292
1293 /* 3RF instruction _df(bit 21) = _w, _d */
1294 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1295 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1296 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1297 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1298 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1299 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1300 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1301 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1302 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1307 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1310 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1312 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1313 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1314 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1315 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1317 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1318 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1320 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1322 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1324 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1325 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1326 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1329 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1332 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1335
1336 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1337 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1338 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1339 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1340 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1341 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1342 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1343 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1344 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1345 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1346 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1347 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1349};
1350
39454628 1351/* global register indices */
a7812ae4
PB
1352static TCGv_ptr cpu_env;
1353static TCGv cpu_gpr[32], cpu_PC;
340fff72 1354static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1355static TCGv cpu_dspctrl, btarget, bcond;
1356static TCGv_i32 hflags;
a7812ae4 1357static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1358static TCGv_i64 fpu_f64[32];
863f264d 1359static TCGv_i64 msa_wr_d[64];
aa0bf00b 1360
1a7ff922 1361static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1362static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1363
022c62cb 1364#include "exec/gen-icount.h"
2e70f6ef 1365
895c2d04 1366#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1368 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1369 tcg_temp_free_i32(helper_tmp); \
1370 } while(0)
be24bb4f 1371
895c2d04 1372#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1375 tcg_temp_free_i32(helper_tmp); \
1376 } while(0)
be24bb4f 1377
895c2d04
BS
1378#define gen_helper_1e0i(name, ret, arg1) do { \
1379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1380 gen_helper_##name(ret, cpu_env, helper_tmp); \
1381 tcg_temp_free_i32(helper_tmp); \
1382 } while(0)
1383
1384#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1387 tcg_temp_free_i32(helper_tmp); \
1388 } while(0)
1389
1390#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1393 tcg_temp_free_i32(helper_tmp); \
1394 } while(0)
1395
1396#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1399 tcg_temp_free_i32(helper_tmp); \
1400 } while(0)
be24bb4f 1401
895c2d04 1402#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1405 tcg_temp_free_i32(helper_tmp); \
1406 } while(0)
c239529e 1407
8e9ade68
TS
1408typedef struct DisasContext {
1409 struct TranslationBlock *tb;
1410 target_ulong pc, saved_pc;
1411 uint32_t opcode;
7b270ef2 1412 int singlestep_enabled;
d75c135e 1413 int insn_flags;
5ab5c041 1414 int32_t CP0_Config1;
8e9ade68
TS
1415 /* Routine used to access memory */
1416 int mem_idx;
1417 uint32_t hflags, saved_hflags;
1418 int bstate;
1419 target_ulong btarget;
d279279e 1420 bool ulri;
e98c0d17 1421 int kscrexist;
7207c7f9 1422 bool rxi;
9456c2fb 1423 int ie;
aea14095
LA
1424 bool bi;
1425 bool bp;
8e9ade68
TS
1426} DisasContext;
1427
1428enum {
1429 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1430 * exception condition */
8e9ade68
TS
1431 BS_STOP = 1, /* We want to stop translation for any reason */
1432 BS_BRANCH = 2, /* We reached a branch condition */
1433 BS_EXCP = 3, /* We reached an exception condition */
1434};
1435
d73ee8a2
RH
1436static const char * const regnames[] = {
1437 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1438 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1439 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1440 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1441};
6af0bf9c 1442
d73ee8a2
RH
1443static const char * const regnames_HI[] = {
1444 "HI0", "HI1", "HI2", "HI3",
1445};
4b2eb8d2 1446
d73ee8a2
RH
1447static const char * const regnames_LO[] = {
1448 "LO0", "LO1", "LO2", "LO3",
1449};
4b2eb8d2 1450
d73ee8a2
RH
1451static const char * const fregnames[] = {
1452 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1453 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1454 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1455 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1456};
958fb4a9 1457
863f264d
YK
1458static const char * const msaregnames[] = {
1459 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1460 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1461 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1462 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1463 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1464 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1465 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1466 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1467 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1468 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1469 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1470 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1471 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1472 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1473 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1474 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1475};
1476
fb7729e2
RH
1477#define MIPS_DEBUG(fmt, ...) \
1478 do { \
1479 if (MIPS_DEBUG_DISAS) { \
1480 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1481 TARGET_FMT_lx ": %08x " fmt "\n", \
1482 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1483 } \
1484 } while (0)
1485
1486#define LOG_DISAS(...) \
1487 do { \
1488 if (MIPS_DEBUG_DISAS) { \
1489 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1490 } \
1491 } while (0)
958fb4a9 1492
8e9ade68 1493#define MIPS_INVAL(op) \
8e9ade68 1494 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1495 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1496
8e9ade68
TS
1497/* General purpose registers moves. */
1498static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1499{
8e9ade68
TS
1500 if (reg == 0)
1501 tcg_gen_movi_tl(t, 0);
1502 else
4b2eb8d2 1503 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1504}
1505
8e9ade68 1506static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1507{
8e9ade68 1508 if (reg != 0)
4b2eb8d2 1509 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1510}
1511
8e9ade68 1512/* Moves to/from shadow registers. */
be24bb4f 1513static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1514{
d9bea114 1515 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1516
1517 if (from == 0)
d9bea114 1518 tcg_gen_movi_tl(t0, 0);
8e9ade68 1519 else {
d9bea114 1520 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1521 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1522
7db13fae 1523 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1524 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1525 tcg_gen_andi_i32(t2, t2, 0xf);
1526 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1527 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1528 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1529
d9bea114 1530 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1531 tcg_temp_free_ptr(addr);
d9bea114 1532 tcg_temp_free_i32(t2);
8e9ade68 1533 }
d9bea114
AJ
1534 gen_store_gpr(t0, to);
1535 tcg_temp_free(t0);
aaa9128a
TS
1536}
1537
be24bb4f 1538static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1539{
be24bb4f 1540 if (to != 0) {
d9bea114
AJ
1541 TCGv t0 = tcg_temp_new();
1542 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1543 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1544
d9bea114 1545 gen_load_gpr(t0, from);
7db13fae 1546 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1547 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1548 tcg_gen_andi_i32(t2, t2, 0xf);
1549 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1550 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1551 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1552
d9bea114 1553 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1554 tcg_temp_free_ptr(addr);
d9bea114
AJ
1555 tcg_temp_free_i32(t2);
1556 tcg_temp_free(t0);
8e9ade68 1557 }
aaa9128a
TS
1558}
1559
aaa9128a 1560/* Floating point register moves. */
d73ee8a2 1561static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1562{
d73ee8a2 1563 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1564}
1565
d73ee8a2 1566static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1567{
d73ee8a2
RH
1568 TCGv_i64 t64 = tcg_temp_new_i64();
1569 tcg_gen_extu_i32_i64(t64, t);
1570 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1571 tcg_temp_free_i64(t64);
6d066274
AJ
1572}
1573
7f6613ce 1574static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1575{
7f6613ce
PJ
1576 if (ctx->hflags & MIPS_HFLAG_F64) {
1577 TCGv_i64 t64 = tcg_temp_new_i64();
1578 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1579 tcg_gen_trunc_i64_i32(t, t64);
1580 tcg_temp_free_i64(t64);
1581 } else {
1582 gen_load_fpr32(t, reg | 1);
1583 }
6d066274
AJ
1584}
1585
7f6613ce 1586static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1587{
7f6613ce
PJ
1588 if (ctx->hflags & MIPS_HFLAG_F64) {
1589 TCGv_i64 t64 = tcg_temp_new_i64();
1590 tcg_gen_extu_i32_i64(t64, t);
1591 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1592 tcg_temp_free_i64(t64);
1593 } else {
1594 gen_store_fpr32(t, reg | 1);
1595 }
aa0bf00b 1596}
6ea83fed 1597
d73ee8a2 1598static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1599{
f364515c 1600 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1601 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1602 } else {
d73ee8a2 1603 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1604 }
1605}
6ea83fed 1606
d73ee8a2 1607static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1608{
f364515c 1609 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1610 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1611 } else {
d73ee8a2
RH
1612 TCGv_i64 t0;
1613 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1614 t0 = tcg_temp_new_i64();
6d066274 1615 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1616 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1617 tcg_temp_free_i64(t0);
aa0bf00b
TS
1618 }
1619}
6ea83fed 1620
d94536f4 1621static inline int get_fp_bit (int cc)
a16336e4 1622{
d94536f4
AJ
1623 if (cc)
1624 return 24 + cc;
1625 else
1626 return 23;
a16336e4
TS
1627}
1628
30898801 1629/* Tests */
8e9ade68
TS
1630static inline void gen_save_pc(target_ulong pc)
1631{
1eb75d4a 1632 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1633}
30898801 1634
356265ae 1635static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1636{
d12d51d5 1637 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1638 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1639 gen_save_pc(ctx->pc);
6af0bf9c
FB
1640 ctx->saved_pc = ctx->pc;
1641 }
1642 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1643 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1644 ctx->saved_hflags = ctx->hflags;
364d4831 1645 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1646 case MIPS_HFLAG_BR:
5a5012ec
TS
1647 break;
1648 case MIPS_HFLAG_BC:
5a5012ec 1649 case MIPS_HFLAG_BL:
5a5012ec 1650 case MIPS_HFLAG_B:
d077b6f7 1651 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1652 break;
6af0bf9c
FB
1653 }
1654 }
1655}
1656
7db13fae 1657static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1658{
fd4a04eb 1659 ctx->saved_hflags = ctx->hflags;
364d4831 1660 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1661 case MIPS_HFLAG_BR:
fd4a04eb
TS
1662 break;
1663 case MIPS_HFLAG_BC:
1664 case MIPS_HFLAG_BL:
39454628 1665 case MIPS_HFLAG_B:
fd4a04eb 1666 ctx->btarget = env->btarget;
fd4a04eb 1667 break;
5a5012ec
TS
1668 }
1669}
1670
356265ae 1671static inline void
48d38ca5 1672generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1673{
a7812ae4
PB
1674 TCGv_i32 texcp = tcg_const_i32(excp);
1675 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1676 save_cpu_state(ctx, 1);
895c2d04 1677 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1678 tcg_temp_free_i32(terr);
1679 tcg_temp_free_i32(texcp);
aaa9128a
TS
1680}
1681
356265ae 1682static inline void
48d38ca5 1683generate_exception (DisasContext *ctx, int excp)
aaa9128a 1684{
6af0bf9c 1685 save_cpu_state(ctx, 1);
895c2d04 1686 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1687}
1688
48d38ca5 1689/* Addresses computation */
941694d0 1690static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1691{
941694d0 1692 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1693
1694#if defined(TARGET_MIPS64)
01f72885 1695 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1696 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1697 }
1698#endif
4ad40f36
FB
1699}
1700
31837be3
YK
1701/* Addresses computation (translation time) */
1702static target_long addr_add(DisasContext *ctx, target_long base,
1703 target_long offset)
1704{
1705 target_long sum = base + offset;
1706
1707#if defined(TARGET_MIPS64)
1708 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1709 sum = (int32_t)sum;
1710 }
1711#endif
1712 return sum;
1713}
1714
356265ae 1715static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1716{
fe253235 1717 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1718 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1719}
1720
356265ae 1721static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1722{
fe253235 1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1724 generate_exception_err(ctx, EXCP_CpU, 1);
1725}
1726
b8aa4598
TS
1727/* Verify that the processor is running with COP1X instructions enabled.
1728 This is associated with the nabla symbol in the MIPS32 and MIPS64
1729 opcode tables. */
1730
356265ae 1731static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1732{
1733 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1734 generate_exception(ctx, EXCP_RI);
1735}
1736
1737/* Verify that the processor is running with 64-bit floating-point
1738 operations enabled. */
1739
356265ae 1740static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1741{
b8aa4598 1742 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1743 generate_exception(ctx, EXCP_RI);
1744}
1745
1746/*
1747 * Verify if floating point register is valid; an operation is not defined
1748 * if bit 0 of any register specification is set and the FR bit in the
1749 * Status register equals zero, since the register numbers specify an
1750 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1751 * in the Status register equals one, both even and odd register numbers
1752 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1753 *
1754 * Multiple 64 bit wide registers can be checked by calling
1755 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1756 */
356265ae 1757static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1758{
fe253235 1759 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1760 generate_exception(ctx, EXCP_RI);
1761}
1762
853c3240
JL
1763/* Verify that the processor is running with DSP instructions enabled.
1764 This is enabled by CP0 Status register MX(24) bit.
1765 */
1766
1767static inline void check_dsp(DisasContext *ctx)
1768{
1769 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1770 if (ctx->insn_flags & ASE_DSP) {
1771 generate_exception(ctx, EXCP_DSPDIS);
1772 } else {
1773 generate_exception(ctx, EXCP_RI);
1774 }
853c3240
JL
1775 }
1776}
1777
1778static inline void check_dspr2(DisasContext *ctx)
1779{
1780 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1781 if (ctx->insn_flags & ASE_DSP) {
1782 generate_exception(ctx, EXCP_DSPDIS);
1783 } else {
1784 generate_exception(ctx, EXCP_RI);
1785 }
853c3240
JL
1786 }
1787}
1788
3a95e3a7 1789/* This code generates a "reserved instruction" exception if the
e189e748 1790 CPU does not support the instruction set corresponding to flags. */
d75c135e 1791static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1792{
d75c135e 1793 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1794 generate_exception(ctx, EXCP_RI);
d75c135e 1795 }
3a95e3a7
TS
1796}
1797
fecd2646
LA
1798/* This code generates a "reserved instruction" exception if the
1799 CPU has corresponding flag set which indicates that the instruction
1800 has been removed. */
1801static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1802{
1803 if (unlikely(ctx->insn_flags & flags)) {
1804 generate_exception(ctx, EXCP_RI);
1805 }
1806}
1807
c7986fd6 1808#ifdef TARGET_MIPS64
e189e748
TS
1809/* This code generates a "reserved instruction" exception if 64-bit
1810 instructions are not enabled. */
356265ae 1811static inline void check_mips_64(DisasContext *ctx)
e189e748 1812{
fe253235 1813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1814 generate_exception(ctx, EXCP_RI);
1815}
c7986fd6 1816#endif
e189e748 1817
8153667c
NF
1818/* Define small wrappers for gen_load_fpr* so that we have a uniform
1819 calling interface for 32 and 64-bit FPRs. No sense in changing
1820 all callers for gen_load_fpr32 when we need the CTX parameter for
1821 this one use. */
1822#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1823#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1824#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1825static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1826 int ft, int fs, int cc) \
1827{ \
1828 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1829 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1830 switch (ifmt) { \
1831 case FMT_PS: \
1832 check_cp1_64bitmode(ctx); \
1833 break; \
1834 case FMT_D: \
1835 if (abs) { \
1836 check_cop1x(ctx); \
1837 } \
1838 check_cp1_registers(ctx, fs | ft); \
1839 break; \
1840 case FMT_S: \
1841 if (abs) { \
1842 check_cop1x(ctx); \
1843 } \
1844 break; \
1845 } \
1846 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1847 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1848 switch (n) { \
895c2d04
BS
1849 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1850 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1851 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1852 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1853 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1854 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1855 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1856 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1857 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1858 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1859 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1860 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1861 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1862 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1863 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1864 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1865 default: abort(); \
1866 } \
1867 tcg_temp_free_i##bits (fp0); \
1868 tcg_temp_free_i##bits (fp1); \
1869}
1870
1871FOP_CONDS(, 0, d, FMT_D, 64)
1872FOP_CONDS(abs, 1, d, FMT_D, 64)
1873FOP_CONDS(, 0, s, FMT_S, 32)
1874FOP_CONDS(abs, 1, s, FMT_S, 32)
1875FOP_CONDS(, 0, ps, FMT_PS, 64)
1876FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1877#undef FOP_CONDS
3f493883
YK
1878
1879#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1880static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1881 int ft, int fs, int fd) \
1882{ \
1883 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1884 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1885 if (ifmt == FMT_D) { \
3f493883 1886 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1887 } \
1888 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1889 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1890 switch (n) { \
1891 case 0: \
1892 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1893 break; \
1894 case 1: \
1895 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1896 break; \
1897 case 2: \
1898 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 3: \
1901 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 4: \
1904 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 5: \
1907 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 6: \
1910 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 7: \
1913 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 8: \
1916 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 9: \
1919 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 10: \
1922 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 11: \
1925 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 12: \
1928 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 13: \
1931 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 14: \
1934 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 15: \
1937 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 case 17: \
1940 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1941 break; \
1942 case 18: \
1943 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1944 break; \
1945 case 19: \
1946 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 25: \
1949 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 26: \
1952 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 27: \
1955 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 default: \
1958 abort(); \
1959 } \
1960 STORE; \
1961 tcg_temp_free_i ## bits (fp0); \
1962 tcg_temp_free_i ## bits (fp1); \
1963}
1964
1965FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1966FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1967#undef FOP_CONDNS
8153667c
NF
1968#undef gen_ldcmp_fpr32
1969#undef gen_ldcmp_fpr64
1970
958fb4a9 1971/* load/store instructions. */
e7139c44 1972#ifdef CONFIG_USER_ONLY
d9bea114 1973#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1974static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1975{ \
1976 TCGv t0 = tcg_temp_new(); \
1977 tcg_gen_mov_tl(t0, arg1); \
1978 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1979 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1980 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1981 tcg_temp_free(t0); \
aaa9128a 1982}
e7139c44
AJ
1983#else
1984#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1985static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1986{ \
895c2d04 1987 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1988}
1989#endif
aaa9128a
TS
1990OP_LD_ATOMIC(ll,ld32s);
1991#if defined(TARGET_MIPS64)
1992OP_LD_ATOMIC(lld,ld64);
1993#endif
1994#undef OP_LD_ATOMIC
1995
590bc601
PB
1996#ifdef CONFIG_USER_ONLY
1997#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1998static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1999{ \
2000 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2001 TCGLabel *l1 = gen_new_label(); \
2002 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2003 \
2004 tcg_gen_andi_tl(t0, arg2, almask); \
2005 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2006 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2007 generate_exception(ctx, EXCP_AdES); \
2008 gen_set_label(l1); \
7db13fae 2009 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2010 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2011 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2012 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2013 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2014 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2015 gen_set_label(l2); \
2016 tcg_gen_movi_tl(t0, 0); \
2017 gen_store_gpr(t0, rt); \
2018 tcg_temp_free(t0); \
2019}
2020#else
2021#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2022static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2023{ \
2024 TCGv t0 = tcg_temp_new(); \
895c2d04 2025 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2026 gen_store_gpr(t0, rt); \
590bc601
PB
2027 tcg_temp_free(t0); \
2028}
2029#endif
590bc601 2030OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2031#if defined(TARGET_MIPS64)
590bc601 2032OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2033#endif
2034#undef OP_ST_ATOMIC
2035
662d7485
NF
2036static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2037 int base, int16_t offset)
2038{
2039 if (base == 0) {
2040 tcg_gen_movi_tl(addr, offset);
2041 } else if (offset == 0) {
2042 gen_load_gpr(addr, base);
2043 } else {
2044 tcg_gen_movi_tl(addr, offset);
2045 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2046 }
2047}
2048
364d4831
NF
2049static target_ulong pc_relative_pc (DisasContext *ctx)
2050{
2051 target_ulong pc = ctx->pc;
2052
2053 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2054 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2055
2056 pc -= branch_bytes;
2057 }
2058
2059 pc &= ~(target_ulong)3;
2060 return pc;
2061}
2062
5c13fdfd 2063/* Load */
d75c135e
AJ
2064static void gen_ld(DisasContext *ctx, uint32_t opc,
2065 int rt, int base, int16_t offset)
6af0bf9c 2066{
5c13fdfd 2067 const char *opn = "ld";
fc40787a 2068 TCGv t0, t1, t2;
afa88c3a 2069
d75c135e 2070 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2071 /* Loongson CPU uses a load to zero register for prefetch.
2072 We emulate it as a NOP. On other CPU we must perform the
2073 actual memory access. */
2074 MIPS_DEBUG("NOP");
2075 return;
2076 }
6af0bf9c 2077
afa88c3a 2078 t0 = tcg_temp_new();
662d7485 2079 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2080
6af0bf9c 2081 switch (opc) {
d26bc211 2082#if defined(TARGET_MIPS64)
6e473128 2083 case OPC_LWU:
5f68f5ae 2084 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 2085 gen_store_gpr(t0, rt);
6e473128
TS
2086 opn = "lwu";
2087 break;
6af0bf9c 2088 case OPC_LD:
5f68f5ae 2089 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 2090 gen_store_gpr(t0, rt);
6af0bf9c
FB
2091 opn = "ld";
2092 break;
7a387fff 2093 case OPC_LLD:
bf7910c6 2094 case R6_OPC_LLD:
b835e919 2095 save_cpu_state(ctx, 1);
5c13fdfd 2096 op_ld_lld(t0, t0, ctx);
78723684 2097 gen_store_gpr(t0, rt);
7a387fff
TS
2098 opn = "lld";
2099 break;
6af0bf9c 2100 case OPC_LDL:
3cee3050 2101 t1 = tcg_temp_new();
fc40787a
AJ
2102 tcg_gen_andi_tl(t1, t0, 7);
2103#ifndef TARGET_WORDS_BIGENDIAN
2104 tcg_gen_xori_tl(t1, t1, 7);
2105#endif
2106 tcg_gen_shli_tl(t1, t1, 3);
2107 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2108 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2109 tcg_gen_shl_tl(t0, t0, t1);
2110 tcg_gen_xori_tl(t1, t1, 63);
2111 t2 = tcg_const_tl(0x7fffffffffffffffull);
2112 tcg_gen_shr_tl(t2, t2, t1);
78723684 2113 gen_load_gpr(t1, rt);
fc40787a
AJ
2114 tcg_gen_and_tl(t1, t1, t2);
2115 tcg_temp_free(t2);
2116 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2117 tcg_temp_free(t1);
fc40787a 2118 gen_store_gpr(t0, rt);
6af0bf9c
FB
2119 opn = "ldl";
2120 break;
6af0bf9c 2121 case OPC_LDR:
3cee3050 2122 t1 = tcg_temp_new();
fc40787a
AJ
2123 tcg_gen_andi_tl(t1, t0, 7);
2124#ifdef TARGET_WORDS_BIGENDIAN
2125 tcg_gen_xori_tl(t1, t1, 7);
2126#endif
2127 tcg_gen_shli_tl(t1, t1, 3);
2128 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2129 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2130 tcg_gen_shr_tl(t0, t0, t1);
2131 tcg_gen_xori_tl(t1, t1, 63);
2132 t2 = tcg_const_tl(0xfffffffffffffffeull);
2133 tcg_gen_shl_tl(t2, t2, t1);
78723684 2134 gen_load_gpr(t1, rt);
fc40787a
AJ
2135 tcg_gen_and_tl(t1, t1, t2);
2136 tcg_temp_free(t2);
2137 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2138 tcg_temp_free(t1);
fc40787a 2139 gen_store_gpr(t0, rt);
6af0bf9c
FB
2140 opn = "ldr";
2141 break;
364d4831 2142 case OPC_LDPC:
3cee3050 2143 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2144 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2145 tcg_temp_free(t1);
5f68f5ae 2146 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2147 gen_store_gpr(t0, rt);
5c13fdfd 2148 opn = "ldpc";
364d4831 2149 break;
6af0bf9c 2150#endif
364d4831 2151 case OPC_LWPC:
3cee3050 2152 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2153 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2154 tcg_temp_free(t1);
5f68f5ae 2155 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2156 gen_store_gpr(t0, rt);
5c13fdfd 2157 opn = "lwpc";
364d4831 2158 break;
6af0bf9c 2159 case OPC_LW:
5f68f5ae 2160 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 2161 gen_store_gpr(t0, rt);
6af0bf9c
FB
2162 opn = "lw";
2163 break;
6af0bf9c 2164 case OPC_LH:
5f68f5ae 2165 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 2166 gen_store_gpr(t0, rt);
6af0bf9c
FB
2167 opn = "lh";
2168 break;
6af0bf9c 2169 case OPC_LHU:
5f68f5ae 2170 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 2171 gen_store_gpr(t0, rt);
6af0bf9c
FB
2172 opn = "lhu";
2173 break;
2174 case OPC_LB:
5f68f5ae 2175 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2176 gen_store_gpr(t0, rt);
6af0bf9c
FB
2177 opn = "lb";
2178 break;
6af0bf9c 2179 case OPC_LBU:
5f68f5ae 2180 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2181 gen_store_gpr(t0, rt);
6af0bf9c
FB
2182 opn = "lbu";
2183 break;
2184 case OPC_LWL:
3cee3050 2185 t1 = tcg_temp_new();
fc40787a
AJ
2186 tcg_gen_andi_tl(t1, t0, 3);
2187#ifndef TARGET_WORDS_BIGENDIAN
2188 tcg_gen_xori_tl(t1, t1, 3);
2189#endif
2190 tcg_gen_shli_tl(t1, t1, 3);
2191 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2192 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2193 tcg_gen_shl_tl(t0, t0, t1);
2194 tcg_gen_xori_tl(t1, t1, 31);
2195 t2 = tcg_const_tl(0x7fffffffull);
2196 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2197 gen_load_gpr(t1, rt);
fc40787a
AJ
2198 tcg_gen_and_tl(t1, t1, t2);
2199 tcg_temp_free(t2);
2200 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2201 tcg_temp_free(t1);
fc40787a
AJ
2202 tcg_gen_ext32s_tl(t0, t0);
2203 gen_store_gpr(t0, rt);
6af0bf9c
FB
2204 opn = "lwl";
2205 break;
6af0bf9c 2206 case OPC_LWR:
3cee3050 2207 t1 = tcg_temp_new();
fc40787a
AJ
2208 tcg_gen_andi_tl(t1, t0, 3);
2209#ifdef TARGET_WORDS_BIGENDIAN
2210 tcg_gen_xori_tl(t1, t1, 3);
2211#endif
2212 tcg_gen_shli_tl(t1, t1, 3);
2213 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2214 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2215 tcg_gen_shr_tl(t0, t0, t1);
2216 tcg_gen_xori_tl(t1, t1, 31);
2217 t2 = tcg_const_tl(0xfffffffeull);
2218 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2219 gen_load_gpr(t1, rt);
fc40787a
AJ
2220 tcg_gen_and_tl(t1, t1, t2);
2221 tcg_temp_free(t2);
2222 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2223 tcg_temp_free(t1);
c728154b 2224 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2225 gen_store_gpr(t0, rt);
6af0bf9c
FB
2226 opn = "lwr";
2227 break;
6af0bf9c 2228 case OPC_LL:
4368b29a 2229 case R6_OPC_LL:
e7139c44 2230 save_cpu_state(ctx, 1);
5c13fdfd 2231 op_ld_ll(t0, t0, ctx);
78723684 2232 gen_store_gpr(t0, rt);
6af0bf9c
FB
2233 opn = "ll";
2234 break;
d66c7132 2235 }
2abf314d 2236 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2237 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2238 tcg_temp_free(t0);
d66c7132
AJ
2239}
2240
5c13fdfd
AJ
2241/* Store */
2242static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2243 int base, int16_t offset)
2244{
2245 const char *opn = "st";
2246 TCGv t0 = tcg_temp_new();
2247 TCGv t1 = tcg_temp_new();
2248
2249 gen_base_offset_addr(ctx, t0, base, offset);
2250 gen_load_gpr(t1, rt);
2251 switch (opc) {
2252#if defined(TARGET_MIPS64)
2253 case OPC_SD:
5f68f5ae 2254 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
2255 opn = "sd";
2256 break;
2257 case OPC_SDL:
2258 save_cpu_state(ctx, 1);
895c2d04 2259 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2260 opn = "sdl";
2261 break;
2262 case OPC_SDR:
2263 save_cpu_state(ctx, 1);
895c2d04 2264 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2265 opn = "sdr";
2266 break;
2267#endif
2268 case OPC_SW:
5f68f5ae 2269 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2270 opn = "sw";
2271 break;
2272 case OPC_SH:
5f68f5ae 2273 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2274 opn = "sh";
2275 break;
2276 case OPC_SB:
5f68f5ae 2277 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2278 opn = "sb";
2279 break;
2280 case OPC_SWL:
2281 save_cpu_state(ctx, 1);
895c2d04 2282 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2283 opn = "swl";
2284 break;
2285 case OPC_SWR:
2286 save_cpu_state(ctx, 1);
895c2d04 2287 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2288 opn = "swr";
2289 break;
2290 }
2abf314d 2291 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2292 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2293 tcg_temp_free(t0);
2294 tcg_temp_free(t1);
2295}
2296
2297
d66c7132
AJ
2298/* Store conditional */
2299static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2300 int base, int16_t offset)
2301{
2302 const char *opn = "st_cond";
2303 TCGv t0, t1;
2304
2d2826b9 2305#ifdef CONFIG_USER_ONLY
d66c7132 2306 t0 = tcg_temp_local_new();
d66c7132 2307 t1 = tcg_temp_local_new();
2d2826b9
AJ
2308#else
2309 t0 = tcg_temp_new();
2310 t1 = tcg_temp_new();
2311#endif
2312 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2313 gen_load_gpr(t1, rt);
2314 switch (opc) {
2315#if defined(TARGET_MIPS64)
2316 case OPC_SCD:
bf7910c6 2317 case R6_OPC_SCD:
b835e919 2318 save_cpu_state(ctx, 1);
5c13fdfd 2319 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2320 opn = "scd";
2321 break;
2322#endif
6af0bf9c 2323 case OPC_SC:
4368b29a 2324 case R6_OPC_SC:
e7139c44 2325 save_cpu_state(ctx, 1);
5c13fdfd 2326 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2327 opn = "sc";
2328 break;
6af0bf9c 2329 }
2abf314d 2330 (void)opn; /* avoid a compiler warning */
6af0bf9c 2331 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2332 tcg_temp_free(t1);
d66c7132 2333 tcg_temp_free(t0);
6af0bf9c
FB
2334}
2335
6ea83fed 2336/* Load and store */
7a387fff 2337static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2338 int base, int16_t offset)
6ea83fed 2339{
923617a3 2340 const char *opn = "flt_ldst";
4e2474d6 2341 TCGv t0 = tcg_temp_new();
6ea83fed 2342
662d7485 2343 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2344 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2345 memory access. */
6ea83fed
FB
2346 switch (opc) {
2347 case OPC_LWC1:
b6d96bed 2348 {
a7812ae4 2349 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2350 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2351 gen_store_fpr32(fp0, ft);
a7812ae4 2352 tcg_temp_free_i32(fp0);
b6d96bed 2353 }
6ea83fed
FB
2354 opn = "lwc1";
2355 break;
2356 case OPC_SWC1:
b6d96bed 2357 {
a7812ae4 2358 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2359 gen_load_fpr32(fp0, ft);
5f68f5ae 2360 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2361 tcg_temp_free_i32(fp0);
b6d96bed 2362 }
6ea83fed
FB
2363 opn = "swc1";
2364 break;
2365 case OPC_LDC1:
b6d96bed 2366 {
a7812ae4 2367 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2368 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2369 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2370 tcg_temp_free_i64(fp0);
b6d96bed 2371 }
6ea83fed
FB
2372 opn = "ldc1";
2373 break;
2374 case OPC_SDC1:
b6d96bed 2375 {
a7812ae4 2376 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2377 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2378 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2379 tcg_temp_free_i64(fp0);
b6d96bed 2380 }
6ea83fed
FB
2381 opn = "sdc1";
2382 break;
2383 default:
923617a3 2384 MIPS_INVAL(opn);
e397ee33 2385 generate_exception(ctx, EXCP_RI);
78723684 2386 goto out;
6ea83fed 2387 }
2abf314d 2388 (void)opn; /* avoid a compiler warning */
6ea83fed 2389 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2390 out:
2391 tcg_temp_free(t0);
6ea83fed 2392}
6ea83fed 2393
5ab5c041
AJ
2394static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2395 int rs, int16_t imm)
26ebe468 2396{
5ab5c041 2397 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2398 check_cp1_enabled(ctx);
d9224450
MR
2399 switch (op) {
2400 case OPC_LDC1:
2401 case OPC_SDC1:
2402 check_insn(ctx, ISA_MIPS2);
2403 /* Fallthrough */
2404 default:
2405 gen_flt_ldst(ctx, op, rt, rs, imm);
2406 }
26ebe468
NF
2407 } else {
2408 generate_exception_err(ctx, EXCP_CpU, 1);
2409 }
2410}
2411
6af0bf9c 2412/* Arithmetic with immediate operand */
d75c135e
AJ
2413static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2414 int rt, int rs, int16_t imm)
6af0bf9c 2415{
324d9e32 2416 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2417 const char *opn = "imm arith";
6af0bf9c 2418
7a387fff 2419 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2420 /* If no destination, treat it as a NOP.
2421 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2422 MIPS_DEBUG("NOP");
324d9e32 2423 return;
6af0bf9c
FB
2424 }
2425 switch (opc) {
2426 case OPC_ADDI:
48d38ca5 2427 {
324d9e32
AJ
2428 TCGv t0 = tcg_temp_local_new();
2429 TCGv t1 = tcg_temp_new();
2430 TCGv t2 = tcg_temp_new();
42a268c2 2431 TCGLabel *l1 = gen_new_label();
48d38ca5 2432
324d9e32
AJ
2433 gen_load_gpr(t1, rs);
2434 tcg_gen_addi_tl(t0, t1, uimm);
2435 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2436
324d9e32
AJ
2437 tcg_gen_xori_tl(t1, t1, ~uimm);
2438 tcg_gen_xori_tl(t2, t0, uimm);
2439 tcg_gen_and_tl(t1, t1, t2);
2440 tcg_temp_free(t2);
2441 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2442 tcg_temp_free(t1);
48d38ca5
TS
2443 /* operands of same sign, result different sign */
2444 generate_exception(ctx, EXCP_OVERFLOW);
2445 gen_set_label(l1);
78723684 2446 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2447 gen_store_gpr(t0, rt);
2448 tcg_temp_free(t0);
48d38ca5 2449 }
6af0bf9c
FB
2450 opn = "addi";
2451 break;
2452 case OPC_ADDIU:
324d9e32
AJ
2453 if (rs != 0) {
2454 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2455 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2456 } else {
2457 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2458 }
6af0bf9c
FB
2459 opn = "addiu";
2460 break;
d26bc211 2461#if defined(TARGET_MIPS64)
7a387fff 2462 case OPC_DADDI:
48d38ca5 2463 {
324d9e32
AJ
2464 TCGv t0 = tcg_temp_local_new();
2465 TCGv t1 = tcg_temp_new();
2466 TCGv t2 = tcg_temp_new();
42a268c2 2467 TCGLabel *l1 = gen_new_label();
48d38ca5 2468
324d9e32
AJ
2469 gen_load_gpr(t1, rs);
2470 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2471
324d9e32
AJ
2472 tcg_gen_xori_tl(t1, t1, ~uimm);
2473 tcg_gen_xori_tl(t2, t0, uimm);
2474 tcg_gen_and_tl(t1, t1, t2);
2475 tcg_temp_free(t2);
2476 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2477 tcg_temp_free(t1);
48d38ca5
TS
2478 /* operands of same sign, result different sign */
2479 generate_exception(ctx, EXCP_OVERFLOW);
2480 gen_set_label(l1);
324d9e32
AJ
2481 gen_store_gpr(t0, rt);
2482 tcg_temp_free(t0);
48d38ca5 2483 }
7a387fff
TS
2484 opn = "daddi";
2485 break;
2486 case OPC_DADDIU:
324d9e32
AJ
2487 if (rs != 0) {
2488 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2489 } else {
2490 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2491 }
7a387fff
TS
2492 opn = "daddiu";
2493 break;
2494#endif
324d9e32 2495 }
2abf314d 2496 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2497 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2498}
2499
2500/* Logic with immediate operand */
d75c135e 2501static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2502 int rt, int rs, int16_t imm)
324d9e32
AJ
2503{
2504 target_ulong uimm;
324d9e32
AJ
2505
2506 if (rt == 0) {
2507 /* If no destination, treat it as a NOP. */
2508 MIPS_DEBUG("NOP");
2509 return;
2510 }
2511 uimm = (uint16_t)imm;
2512 switch (opc) {
6af0bf9c 2513 case OPC_ANDI:
324d9e32
AJ
2514 if (likely(rs != 0))
2515 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2516 else
2517 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2518 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2519 regnames[rs], uimm);
6af0bf9c
FB
2520 break;
2521 case OPC_ORI:
324d9e32
AJ
2522 if (rs != 0)
2523 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2524 else
2525 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2526 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2527 regnames[rs], uimm);
6af0bf9c
FB
2528 break;
2529 case OPC_XORI:
324d9e32
AJ
2530 if (likely(rs != 0))
2531 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2532 else
2533 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2534 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2535 regnames[rs], uimm);
6af0bf9c
FB
2536 break;
2537 case OPC_LUI:
d4ea6acd
LA
2538 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2539 /* OPC_AUI */
2540 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2541 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2542 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2543 } else {
2544 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2545 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2546 }
7c2c3ea3
EJ
2547 break;
2548
2549 default:
2550 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2551 break;
324d9e32 2552 }
324d9e32
AJ
2553}
2554
2555/* Set on less than with immediate operand */
d75c135e 2556static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2557 int rt, int rs, int16_t imm)
324d9e32
AJ
2558{
2559 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2560 const char *opn = "imm arith";
2561 TCGv t0;
2562
2563 if (rt == 0) {
2564 /* If no destination, treat it as a NOP. */
2565 MIPS_DEBUG("NOP");
2566 return;
2567 }
2568 t0 = tcg_temp_new();
2569 gen_load_gpr(t0, rs);
2570 switch (opc) {
2571 case OPC_SLTI:
e68dd28f 2572 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2573 opn = "slti";
2574 break;
2575 case OPC_SLTIU:
e68dd28f 2576 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2577 opn = "sltiu";
2578 break;
2579 }
2abf314d 2580 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2581 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2582 tcg_temp_free(t0);
2583}
2584
2585/* Shifts with immediate operand */
d75c135e 2586static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2587 int rt, int rs, int16_t imm)
2588{
2589 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2590 const char *opn = "imm shift";
2591 TCGv t0;
2592
2593 if (rt == 0) {
2594 /* If no destination, treat it as a NOP. */
2595 MIPS_DEBUG("NOP");
2596 return;
2597 }
2598
2599 t0 = tcg_temp_new();
2600 gen_load_gpr(t0, rs);
2601 switch (opc) {
6af0bf9c 2602 case OPC_SLL:
78723684 2603 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2604 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2605 opn = "sll";
2606 break;
2607 case OPC_SRA:
324d9e32 2608 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2609 opn = "sra";
2610 break;
2611 case OPC_SRL:
ea63e2c3
NF
2612 if (uimm != 0) {
2613 tcg_gen_ext32u_tl(t0, t0);
2614 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2615 } else {
2616 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2617 }
ea63e2c3
NF
2618 opn = "srl";
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
NF
2630 }
2631 opn = "rotr";
7a387fff 2632 break;
d26bc211 2633#if defined(TARGET_MIPS64)
7a387fff 2634 case OPC_DSLL:
324d9e32 2635 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2636 opn = "dsll";
2637 break;
2638 case OPC_DSRA:
324d9e32 2639 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2640 opn = "dsra";
2641 break;
2642 case OPC_DSRL:
ea63e2c3
NF
2643 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2644 opn = "dsrl";
2645 break;
2646 case OPC_DROTR:
2647 if (uimm != 0) {
2648 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2649 } else {
2650 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2651 }
ea63e2c3 2652 opn = "drotr";
7a387fff
TS
2653 break;
2654 case OPC_DSLL32:
324d9e32 2655 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2656 opn = "dsll32";
2657 break;
2658 case OPC_DSRA32:
324d9e32 2659 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2660 opn = "dsra32";
2661 break;
2662 case OPC_DSRL32:
ea63e2c3
NF
2663 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2664 opn = "dsrl32";
2665 break;
2666 case OPC_DROTR32:
2667 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2668 opn = "drotr32";
6af0bf9c 2669 break;
7a387fff 2670#endif
6af0bf9c 2671 }
2abf314d 2672 (void)opn; /* avoid a compiler warning */
93b12ccc 2673 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2674 tcg_temp_free(t0);
6af0bf9c
FB
2675}
2676
2677/* Arithmetic */
d75c135e
AJ
2678static void gen_arith(DisasContext *ctx, uint32_t opc,
2679 int rd, int rs, int rt)
6af0bf9c 2680{
923617a3 2681 const char *opn = "arith";
6af0bf9c 2682
7a387fff
TS
2683 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2684 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2685 /* If no destination, treat it as a NOP.
2686 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2687 MIPS_DEBUG("NOP");
460f00c4 2688 return;
185f0762 2689 }
460f00c4 2690
6af0bf9c
FB
2691 switch (opc) {
2692 case OPC_ADD:
48d38ca5 2693 {
460f00c4
AJ
2694 TCGv t0 = tcg_temp_local_new();
2695 TCGv t1 = tcg_temp_new();
2696 TCGv t2 = tcg_temp_new();
42a268c2 2697 TCGLabel *l1 = gen_new_label();
48d38ca5 2698
460f00c4
AJ
2699 gen_load_gpr(t1, rs);
2700 gen_load_gpr(t2, rt);
2701 tcg_gen_add_tl(t0, t1, t2);
2702 tcg_gen_ext32s_tl(t0, t0);
2703 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2704 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2705 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2706 tcg_temp_free(t2);
2707 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2708 tcg_temp_free(t1);
48d38ca5
TS
2709 /* operands of same sign, result different sign */
2710 generate_exception(ctx, EXCP_OVERFLOW);
2711 gen_set_label(l1);
460f00c4
AJ
2712 gen_store_gpr(t0, rd);
2713 tcg_temp_free(t0);
48d38ca5 2714 }
6af0bf9c
FB
2715 opn = "add";
2716 break;
2717 case OPC_ADDU:
460f00c4
AJ
2718 if (rs != 0 && rt != 0) {
2719 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2720 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2721 } else if (rs == 0 && rt != 0) {
2722 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2723 } else if (rs != 0 && rt == 0) {
2724 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2725 } else {
2726 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2727 }
6af0bf9c
FB
2728 opn = "addu";
2729 break;
2730 case OPC_SUB:
48d38ca5 2731 {
460f00c4
AJ
2732 TCGv t0 = tcg_temp_local_new();
2733 TCGv t1 = tcg_temp_new();
2734 TCGv t2 = tcg_temp_new();
42a268c2 2735 TCGLabel *l1 = gen_new_label();
48d38ca5 2736
460f00c4
AJ
2737 gen_load_gpr(t1, rs);
2738 gen_load_gpr(t2, rt);
2739 tcg_gen_sub_tl(t0, t1, t2);
2740 tcg_gen_ext32s_tl(t0, t0);
2741 tcg_gen_xor_tl(t2, t1, t2);
2742 tcg_gen_xor_tl(t1, t0, t1);
2743 tcg_gen_and_tl(t1, t1, t2);
2744 tcg_temp_free(t2);
2745 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2746 tcg_temp_free(t1);
31e3104f 2747 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2748 generate_exception(ctx, EXCP_OVERFLOW);
2749 gen_set_label(l1);
460f00c4
AJ
2750 gen_store_gpr(t0, rd);
2751 tcg_temp_free(t0);
48d38ca5 2752 }
6af0bf9c
FB
2753 opn = "sub";
2754 break;
2755 case OPC_SUBU:
460f00c4
AJ
2756 if (rs != 0 && rt != 0) {
2757 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2758 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2759 } else if (rs == 0 && rt != 0) {
2760 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2761 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2762 } else if (rs != 0 && rt == 0) {
2763 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2764 } else {
2765 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2766 }
6af0bf9c
FB
2767 opn = "subu";
2768 break;
d26bc211 2769#if defined(TARGET_MIPS64)
7a387fff 2770 case OPC_DADD:
48d38ca5 2771 {
460f00c4
AJ
2772 TCGv t0 = tcg_temp_local_new();
2773 TCGv t1 = tcg_temp_new();
2774 TCGv t2 = tcg_temp_new();
42a268c2 2775 TCGLabel *l1 = gen_new_label();
48d38ca5 2776
460f00c4
AJ
2777 gen_load_gpr(t1, rs);
2778 gen_load_gpr(t2, rt);
2779 tcg_gen_add_tl(t0, t1, t2);
2780 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2781 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2782 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2783 tcg_temp_free(t2);
2784 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2785 tcg_temp_free(t1);
48d38ca5
TS
2786 /* operands of same sign, result different sign */
2787 generate_exception(ctx, EXCP_OVERFLOW);
2788 gen_set_label(l1);
460f00c4
AJ
2789 gen_store_gpr(t0, rd);
2790 tcg_temp_free(t0);
48d38ca5 2791 }
7a387fff
TS
2792 opn = "dadd";
2793 break;
2794 case OPC_DADDU:
460f00c4
AJ
2795 if (rs != 0 && rt != 0) {
2796 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2797 } else if (rs == 0 && rt != 0) {
2798 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2799 } else if (rs != 0 && rt == 0) {
2800 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2801 } else {
2802 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2803 }
7a387fff
TS
2804 opn = "daddu";
2805 break;
2806 case OPC_DSUB:
48d38ca5 2807 {
460f00c4
AJ
2808 TCGv t0 = tcg_temp_local_new();
2809 TCGv t1 = tcg_temp_new();
2810 TCGv t2 = tcg_temp_new();
42a268c2 2811 TCGLabel *l1 = gen_new_label();
48d38ca5 2812
460f00c4
AJ
2813 gen_load_gpr(t1, rs);
2814 gen_load_gpr(t2, rt);
2815 tcg_gen_sub_tl(t0, t1, t2);
2816 tcg_gen_xor_tl(t2, t1, t2);
2817 tcg_gen_xor_tl(t1, t0, t1);
2818 tcg_gen_and_tl(t1, t1, t2);
2819 tcg_temp_free(t2);
2820 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2821 tcg_temp_free(t1);
31e3104f 2822 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2823 generate_exception(ctx, EXCP_OVERFLOW);
2824 gen_set_label(l1);
460f00c4
AJ
2825 gen_store_gpr(t0, rd);
2826 tcg_temp_free(t0);
48d38ca5 2827 }
7a387fff
TS
2828 opn = "dsub";
2829 break;
2830 case OPC_DSUBU:
460f00c4
AJ
2831 if (rs != 0 && rt != 0) {
2832 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2833 } else if (rs == 0 && rt != 0) {
2834 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2835 } else if (rs != 0 && rt == 0) {
2836 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2837 } else {
2838 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2839 }
7a387fff
TS
2840 opn = "dsubu";
2841 break;
2842#endif
460f00c4
AJ
2843 case OPC_MUL:
2844 if (likely(rs != 0 && rt != 0)) {
2845 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2846 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2847 } else {
2848 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2849 }
2850 opn = "mul";
6af0bf9c 2851 break;
460f00c4 2852 }
2abf314d 2853 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2854 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2855}
2856
2857/* Conditional move */
d75c135e 2858static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2859 int rd, int rs, int rt)
460f00c4
AJ
2860{
2861 const char *opn = "cond move";
acf12465 2862 TCGv t0, t1, t2;
460f00c4
AJ
2863
2864 if (rd == 0) {
acf12465 2865 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2866 MIPS_DEBUG("NOP");
2867 return;
2868 }
2869
acf12465
AJ
2870 t0 = tcg_temp_new();
2871 gen_load_gpr(t0, rt);
2872 t1 = tcg_const_tl(0);
2873 t2 = tcg_temp_new();
2874 gen_load_gpr(t2, rs);
460f00c4
AJ
2875 switch (opc) {
2876 case OPC_MOVN:
acf12465 2877 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2878 opn = "movn";
6af0bf9c 2879 break;
460f00c4 2880 case OPC_MOVZ:
acf12465 2881 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2882 opn = "movz";
2883 break;
b691d9d2
LA
2884 case OPC_SELNEZ:
2885 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2886 opn = "selnez";
2887 break;
2888 case OPC_SELEQZ:
2889 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2890 opn = "seleqz";
2891 break;
460f00c4 2892 }
acf12465
AJ
2893 tcg_temp_free(t2);
2894 tcg_temp_free(t1);
2895 tcg_temp_free(t0);
460f00c4 2896
2abf314d 2897 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2898 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2899}
2900
2901/* Logic */
d75c135e 2902static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2903 int rd, int rs, int rt)
460f00c4
AJ
2904{
2905 const char *opn = "logic";
2906
2907 if (rd == 0) {
2908 /* If no destination, treat it as a NOP. */
2909 MIPS_DEBUG("NOP");
2910 return;
2911 }
2912
2913 switch (opc) {
6af0bf9c 2914 case OPC_AND:
460f00c4
AJ
2915 if (likely(rs != 0 && rt != 0)) {
2916 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2917 } else {
2918 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2919 }
6af0bf9c
FB
2920 opn = "and";
2921 break;
2922 case OPC_NOR:
460f00c4
AJ
2923 if (rs != 0 && rt != 0) {
2924 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2925 } else if (rs == 0 && rt != 0) {
2926 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2927 } else if (rs != 0 && rt == 0) {
2928 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2929 } else {
2930 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2931 }
6af0bf9c
FB
2932 opn = "nor";
2933 break;
2934 case OPC_OR:
460f00c4
AJ
2935 if (likely(rs != 0 && rt != 0)) {
2936 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2937 } else if (rs == 0 && rt != 0) {
2938 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2939 } else if (rs != 0 && rt == 0) {
2940 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2941 } else {
2942 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2943 }
6af0bf9c
FB
2944 opn = "or";
2945 break;
2946 case OPC_XOR:
460f00c4
AJ
2947 if (likely(rs != 0 && rt != 0)) {
2948 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2949 } else if (rs == 0 && rt != 0) {
2950 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2951 } else if (rs != 0 && rt == 0) {
2952 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2953 } else {
2954 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2955 }
6af0bf9c
FB
2956 opn = "xor";
2957 break;
460f00c4 2958 }
2abf314d 2959 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2960 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2961}
2962
2963/* Set on lower than */
d75c135e 2964static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2965 int rd, int rs, int rt)
460f00c4
AJ
2966{
2967 const char *opn = "slt";
2968 TCGv t0, t1;
2969
2970 if (rd == 0) {
2971 /* If no destination, treat it as a NOP. */
2972 MIPS_DEBUG("NOP");
2973 return;
2974 }
2975
2976 t0 = tcg_temp_new();
2977 t1 = tcg_temp_new();
2978 gen_load_gpr(t0, rs);
2979 gen_load_gpr(t1, rt);
2980 switch (opc) {
2981 case OPC_SLT:
e68dd28f 2982 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2983 opn = "slt";
6af0bf9c 2984 break;
460f00c4 2985 case OPC_SLTU:
e68dd28f 2986 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2987 opn = "sltu";
2988 break;
2989 }
2abf314d 2990 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2991 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2992 tcg_temp_free(t0);
2993 tcg_temp_free(t1);
2994}
20c4c97c 2995
460f00c4 2996/* Shifts */
d75c135e
AJ
2997static void gen_shift(DisasContext *ctx, uint32_t opc,
2998 int rd, int rs, int rt)
460f00c4
AJ
2999{
3000 const char *opn = "shifts";
3001 TCGv t0, t1;
20c4c97c 3002
460f00c4
AJ
3003 if (rd == 0) {
3004 /* If no destination, treat it as a NOP.
3005 For add & sub, we must generate the overflow exception when needed. */
3006 MIPS_DEBUG("NOP");
3007 return;
3008 }
3009
3010 t0 = tcg_temp_new();
3011 t1 = tcg_temp_new();
3012 gen_load_gpr(t0, rs);
3013 gen_load_gpr(t1, rt);
3014 switch (opc) {
6af0bf9c 3015 case OPC_SLLV:
78723684
TS
3016 tcg_gen_andi_tl(t0, t0, 0x1f);
3017 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3018 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3019 opn = "sllv";
3020 break;
3021 case OPC_SRAV:
78723684 3022 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3023 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3024 opn = "srav";
3025 break;
3026 case OPC_SRLV:
ea63e2c3
NF
3027 tcg_gen_ext32u_tl(t1, t1);
3028 tcg_gen_andi_tl(t0, t0, 0x1f);
3029 tcg_gen_shr_tl(t0, t1, t0);
3030 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3031 opn = "srlv";
3032 break;
3033 case OPC_ROTRV:
3034 {
3035 TCGv_i32 t2 = tcg_temp_new_i32();
3036 TCGv_i32 t3 = tcg_temp_new_i32();
3037
3038 tcg_gen_trunc_tl_i32(t2, t0);
3039 tcg_gen_trunc_tl_i32(t3, t1);
3040 tcg_gen_andi_i32(t2, t2, 0x1f);
3041 tcg_gen_rotr_i32(t2, t3, t2);
3042 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3043 tcg_temp_free_i32(t2);
3044 tcg_temp_free_i32(t3);
3045 opn = "rotrv";
5a63bcb2 3046 }
7a387fff 3047 break;
d26bc211 3048#if defined(TARGET_MIPS64)
7a387fff 3049 case OPC_DSLLV:
78723684 3050 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3051 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3052 opn = "dsllv";
3053 break;
3054 case OPC_DSRAV:
78723684 3055 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3056 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3057 opn = "dsrav";
3058 break;
3059 case OPC_DSRLV:
ea63e2c3
NF
3060 tcg_gen_andi_tl(t0, t0, 0x3f);
3061 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3062 opn = "dsrlv";
3063 break;
3064 case OPC_DROTRV:
3065 tcg_gen_andi_tl(t0, t0, 0x3f);
3066 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3067 opn = "drotrv";
6af0bf9c 3068 break;
7a387fff 3069#endif
6af0bf9c 3070 }
2abf314d 3071 (void)opn; /* avoid a compiler warning */
6af0bf9c 3072 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3073 tcg_temp_free(t0);
3074 tcg_temp_free(t1);
6af0bf9c
FB
3075}
3076
3077/* Arithmetic on HI/LO registers */
26135ead 3078static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3079{
923617a3 3080 const char *opn = "hilo";
6af0bf9c
FB
3081
3082 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3083 /* Treat as NOP. */
6af0bf9c 3084 MIPS_DEBUG("NOP");
a1f6684d 3085 return;
6af0bf9c 3086 }
4133498f 3087
4133498f
JL
3088 if (acc != 0) {
3089 check_dsp(ctx);
3090 }
3091
6af0bf9c
FB
3092 switch (opc) {
3093 case OPC_MFHI:
4133498f
JL
3094#if defined(TARGET_MIPS64)
3095 if (acc != 0) {
3096 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3097 } else
3098#endif
3099 {
3100 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3101 }
6af0bf9c
FB
3102 opn = "mfhi";
3103 break;
3104 case OPC_MFLO:
4133498f
JL
3105#if defined(TARGET_MIPS64)
3106 if (acc != 0) {
3107 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3108 } else
3109#endif
3110 {
3111 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3112 }
6af0bf9c
FB
3113 opn = "mflo";
3114 break;
3115 case OPC_MTHI:
4133498f
JL
3116 if (reg != 0) {
3117#if defined(TARGET_MIPS64)
3118 if (acc != 0) {
3119 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3120 } else
3121#endif
3122 {
3123 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3124 }
3125 } else {
3126 tcg_gen_movi_tl(cpu_HI[acc], 0);
3127 }
6af0bf9c
FB
3128 opn = "mthi";
3129 break;
3130 case OPC_MTLO:
4133498f
JL
3131 if (reg != 0) {
3132#if defined(TARGET_MIPS64)
3133 if (acc != 0) {
3134 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3135 } else
3136#endif
3137 {
3138 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3139 }
3140 } else {
3141 tcg_gen_movi_tl(cpu_LO[acc], 0);
3142 }
6af0bf9c
FB
3143 opn = "mtlo";
3144 break;
6af0bf9c 3145 }
2abf314d 3146 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3147 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3148}
3149
d4ea6acd
LA
3150static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3151 TCGMemOp memop)
3152{
3153 TCGv t0 = tcg_const_tl(addr);
3154 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3155 gen_store_gpr(t0, reg);
3156 tcg_temp_free(t0);
3157}
3158
3159static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3160{
3161 target_long offset;
3162 target_long addr;
3163
3164 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3165 case OPC_ADDIUPC:
3166 if (rs != 0) {
3167 offset = sextract32(ctx->opcode << 2, 0, 21);
3168 addr = addr_add(ctx, ctx->pc, offset);
3169 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3170 }
3171 break;
3172 case R6_OPC_LWPC:
3173 offset = sextract32(ctx->opcode << 2, 0, 21);
3174 addr = addr_add(ctx, ctx->pc, offset);
3175 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3176 break;
3177#if defined(TARGET_MIPS64)
3178 case OPC_LWUPC:
3179 check_mips_64(ctx);
3180 offset = sextract32(ctx->opcode << 2, 0, 21);
3181 addr = addr_add(ctx, ctx->pc, offset);
3182 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3183 break;
3184#endif
3185 default:
3186 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3187 case OPC_AUIPC:
3188 if (rs != 0) {
3189 offset = imm << 16;
3190 addr = addr_add(ctx, ctx->pc, offset);
3191 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3192 }
3193 break;
3194 case OPC_ALUIPC:
3195 if (rs != 0) {
3196 offset = imm << 16;
3197 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3198 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3199 }
3200 break;
3201#if defined(TARGET_MIPS64)
3202 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3203 case R6_OPC_LDPC + (1 << 16):
3204 case R6_OPC_LDPC + (2 << 16):
3205 case R6_OPC_LDPC + (3 << 16):
3206 check_mips_64(ctx);
3207 offset = sextract32(ctx->opcode << 3, 0, 21);
3208 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3209 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3210 break;
3211#endif
3212 default:
3213 MIPS_INVAL("OPC_PCREL");
3214 generate_exception(ctx, EXCP_RI);
3215 break;
3216 }
3217 break;
3218 }
3219}
3220
b42ee5e1
LA
3221static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3222{
3223 const char *opn = "r6 mul/div";
3224 TCGv t0, t1;
3225
3226 if (rd == 0) {
3227 /* Treat as NOP. */
3228 MIPS_DEBUG("NOP");
3229 return;
3230 }
3231
3232 t0 = tcg_temp_new();
3233 t1 = tcg_temp_new();
3234
3235 gen_load_gpr(t0, rs);
3236 gen_load_gpr(t1, rt);
3237
3238 switch (opc) {
3239 case R6_OPC_DIV:
3240 {
3241 TCGv t2 = tcg_temp_new();
3242 TCGv t3 = tcg_temp_new();
3243 tcg_gen_ext32s_tl(t0, t0);
3244 tcg_gen_ext32s_tl(t1, t1);
3245 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3246 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3247 tcg_gen_and_tl(t2, t2, t3);
3248 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3249 tcg_gen_or_tl(t2, t2, t3);
3250 tcg_gen_movi_tl(t3, 0);
3251 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3252 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3253 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3254 tcg_temp_free(t3);
3255 tcg_temp_free(t2);
3256 }
3257 opn = "div";
3258 break;
3259 case R6_OPC_MOD:
3260 {
3261 TCGv t2 = tcg_temp_new();
3262 TCGv t3 = tcg_temp_new();
3263 tcg_gen_ext32s_tl(t0, t0);
3264 tcg_gen_ext32s_tl(t1, t1);
3265 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3267 tcg_gen_and_tl(t2, t2, t3);
3268 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3269 tcg_gen_or_tl(t2, t2, t3);
3270 tcg_gen_movi_tl(t3, 0);
3271 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3272 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3273 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3274 tcg_temp_free(t3);
3275 tcg_temp_free(t2);
3276 }
3277 opn = "mod";
3278 break;
3279 case R6_OPC_DIVU:
3280 {
3281 TCGv t2 = tcg_const_tl(0);
3282 TCGv t3 = tcg_const_tl(1);
3283 tcg_gen_ext32u_tl(t0, t0);
3284 tcg_gen_ext32u_tl(t1, t1);
3285 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3286 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3287 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3288 tcg_temp_free(t3);
3289 tcg_temp_free(t2);
3290 }
3291 opn = "divu";
3292 break;
3293 case R6_OPC_MODU:
3294 {
3295 TCGv t2 = tcg_const_tl(0);
3296 TCGv t3 = tcg_const_tl(1);
3297 tcg_gen_ext32u_tl(t0, t0);
3298 tcg_gen_ext32u_tl(t1, t1);
3299 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3300 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3301 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3302 tcg_temp_free(t3);
3303 tcg_temp_free(t2);
3304 }
3305 opn = "modu";
3306 break;
3307 case R6_OPC_MUL:
3308 {
3309 TCGv_i32 t2 = tcg_temp_new_i32();
3310 TCGv_i32 t3 = tcg_temp_new_i32();
3311 tcg_gen_trunc_tl_i32(t2, t0);
3312 tcg_gen_trunc_tl_i32(t3, t1);
3313 tcg_gen_mul_i32(t2, t2, t3);
3314 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3315 tcg_temp_free_i32(t2);
3316 tcg_temp_free_i32(t3);
3317 }
3318 opn = "mul";
3319 break;
3320 case R6_OPC_MUH:
3321 {
3322 TCGv_i32 t2 = tcg_temp_new_i32();
3323 TCGv_i32 t3 = tcg_temp_new_i32();
3324 tcg_gen_trunc_tl_i32(t2, t0);
3325 tcg_gen_trunc_tl_i32(t3, t1);
3326 tcg_gen_muls2_i32(t2, t3, t2, t3);
3327 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3328 tcg_temp_free_i32(t2);
3329 tcg_temp_free_i32(t3);
3330 }
3331 opn = "muh";
3332 break;
3333 case R6_OPC_MULU:
3334 {
3335 TCGv_i32 t2 = tcg_temp_new_i32();
3336 TCGv_i32 t3 = tcg_temp_new_i32();
3337 tcg_gen_trunc_tl_i32(t2, t0);
3338 tcg_gen_trunc_tl_i32(t3, t1);
3339 tcg_gen_mul_i32(t2, t2, t3);
3340 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3341 tcg_temp_free_i32(t2);
3342 tcg_temp_free_i32(t3);
3343 }
3344 opn = "mulu";
3345 break;
3346 case R6_OPC_MUHU:
3347 {
3348 TCGv_i32 t2 = tcg_temp_new_i32();
3349 TCGv_i32 t3 = tcg_temp_new_i32();
3350 tcg_gen_trunc_tl_i32(t2, t0);
3351 tcg_gen_trunc_tl_i32(t3, t1);
3352 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3353 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3354 tcg_temp_free_i32(t2);
3355 tcg_temp_free_i32(t3);
3356 }
3357 opn = "muhu";
3358 break;
3359#if defined(TARGET_MIPS64)
3360 case R6_OPC_DDIV:
3361 {
3362 TCGv t2 = tcg_temp_new();
3363 TCGv t3 = tcg_temp_new();
3364 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3365 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3366 tcg_gen_and_tl(t2, t2, t3);
3367 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3368 tcg_gen_or_tl(t2, t2, t3);
3369 tcg_gen_movi_tl(t3, 0);
3370 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3371 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3372 tcg_temp_free(t3);
3373 tcg_temp_free(t2);
3374 }
3375 opn = "ddiv";
3376 break;
3377 case R6_OPC_DMOD:
3378 {
3379 TCGv t2 = tcg_temp_new();
3380 TCGv t3 = tcg_temp_new();
3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3383 tcg_gen_and_tl(t2, t2, t3);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3385 tcg_gen_or_tl(t2, t2, t3);
3386 tcg_gen_movi_tl(t3, 0);
3387 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3388 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3389 tcg_temp_free(t3);
3390 tcg_temp_free(t2);
3391 }
3392 opn = "dmod";
3393 break;
3394 case R6_OPC_DDIVU:
3395 {
3396 TCGv t2 = tcg_const_tl(0);
3397 TCGv t3 = tcg_const_tl(1);
3398 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3399 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3400 tcg_temp_free(t3);
3401 tcg_temp_free(t2);
3402 }
3403 opn = "ddivu";
3404 break;
3405 case R6_OPC_DMODU:
3406 {
3407 TCGv t2 = tcg_const_tl(0);
3408 TCGv t3 = tcg_const_tl(1);
3409 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3410 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3411 tcg_temp_free(t3);
3412 tcg_temp_free(t2);
3413 }
3414 opn = "dmodu";
3415 break;
3416 case R6_OPC_DMUL:
3417 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3418 opn = "dmul";
3419 break;
3420 case R6_OPC_DMUH:
3421 {
3422 TCGv t2 = tcg_temp_new();
3423 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3424 tcg_temp_free(t2);
3425 }
3426 opn = "dmuh";
3427 break;
3428 case R6_OPC_DMULU:
3429 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3430 opn = "dmulu";
3431 break;
3432 case R6_OPC_DMUHU:
3433 {
3434 TCGv t2 = tcg_temp_new();
3435 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3436 tcg_temp_free(t2);
3437 }
3438 opn = "dmuhu";
3439 break;
3440#endif
3441 default:
3442 MIPS_INVAL(opn);
3443 generate_exception(ctx, EXCP_RI);
3444 goto out;
3445 }
3446 (void)opn; /* avoid a compiler warning */
3447 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3448 out:
3449 tcg_temp_free(t0);
3450 tcg_temp_free(t1);
3451}
3452
26135ead
RS
3453static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3454 int acc, int rs, int rt)
6af0bf9c 3455{
923617a3 3456 const char *opn = "mul/div";
d45f89f4
AJ
3457 TCGv t0, t1;
3458
51127181
AJ
3459 t0 = tcg_temp_new();
3460 t1 = tcg_temp_new();
6af0bf9c 3461
78723684
TS
3462 gen_load_gpr(t0, rs);
3463 gen_load_gpr(t1, rt);
51127181 3464
26135ead
RS
3465 if (acc != 0) {
3466 check_dsp(ctx);
3467 }
3468
6af0bf9c
FB
3469 switch (opc) {
3470 case OPC_DIV:
48d38ca5 3471 {
51127181
AJ
3472 TCGv t2 = tcg_temp_new();
3473 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3474 tcg_gen_ext32s_tl(t0, t0);
3475 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3476 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3477 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3478 tcg_gen_and_tl(t2, t2, t3);
3479 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3480 tcg_gen_or_tl(t2, t2, t3);
3481 tcg_gen_movi_tl(t3, 0);
3482 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3483 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3484 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3485 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3486 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3487 tcg_temp_free(t3);
3488 tcg_temp_free(t2);
48d38ca5 3489 }
6af0bf9c
FB
3490 opn = "div";
3491 break;
3492 case OPC_DIVU:
48d38ca5 3493 {
51127181
AJ
3494 TCGv t2 = tcg_const_tl(0);
3495 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3496 tcg_gen_ext32u_tl(t0, t0);
3497 tcg_gen_ext32u_tl(t1, t1);
51127181 3498 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3499 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3500 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3501 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3502 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3503 tcg_temp_free(t3);
3504 tcg_temp_free(t2);
48d38ca5 3505 }
6af0bf9c
FB
3506 opn = "divu";
3507 break;
3508 case OPC_MULT:
214c465f 3509 {
ce1dd5d1
RH
3510 TCGv_i32 t2 = tcg_temp_new_i32();
3511 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3512 tcg_gen_trunc_tl_i32(t2, t0);
3513 tcg_gen_trunc_tl_i32(t3, t1);
3514 tcg_gen_muls2_i32(t2, t3, t2, t3);
3515 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3516 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3517 tcg_temp_free_i32(t2);
3518 tcg_temp_free_i32(t3);
214c465f 3519 }
6af0bf9c
FB
3520 opn = "mult";
3521 break;
3522 case OPC_MULTU:
214c465f 3523 {
ce1dd5d1
RH
3524 TCGv_i32 t2 = tcg_temp_new_i32();
3525 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3526 tcg_gen_trunc_tl_i32(t2, t0);
3527 tcg_gen_trunc_tl_i32(t3, t1);
3528 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3529 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3530 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3531 tcg_temp_free_i32(t2);
3532 tcg_temp_free_i32(t3);
214c465f 3533 }
6af0bf9c
FB
3534 opn = "multu";
3535 break;
d26bc211 3536#if defined(TARGET_MIPS64)
7a387fff 3537 case OPC_DDIV:
48d38ca5 3538 {
51127181
AJ
3539 TCGv t2 = tcg_temp_new();
3540 TCGv t3 = tcg_temp_new();
3541 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3542 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3543 tcg_gen_and_tl(t2, t2, t3);
3544 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3545 tcg_gen_or_tl(t2, t2, t3);
3546 tcg_gen_movi_tl(t3, 0);
3547 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3548 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3549 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3550 tcg_temp_free(t3);
3551 tcg_temp_free(t2);
48d38ca5 3552 }
7a387fff
TS
3553 opn = "ddiv";
3554 break;
3555 case OPC_DDIVU:
48d38ca5 3556 {
51127181
AJ
3557 TCGv t2 = tcg_const_tl(0);
3558 TCGv t3 = tcg_const_tl(1);
3559 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3560 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3561 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3562 tcg_temp_free(t3);
3563 tcg_temp_free(t2);
48d38ca5 3564 }
7a387fff
TS
3565 opn = "ddivu";
3566 break;
3567 case OPC_DMULT:
26135ead 3568 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3569 opn = "dmult";
3570 break;
3571 case OPC_DMULTU:
26135ead 3572 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3573 opn = "dmultu";
3574 break;
3575#endif
6af0bf9c 3576 case OPC_MADD:
214c465f 3577 {
d45f89f4
AJ
3578 TCGv_i64 t2 = tcg_temp_new_i64();
3579 TCGv_i64 t3 = tcg_temp_new_i64();
3580
3581 tcg_gen_ext_tl_i64(t2, t0);
3582 tcg_gen_ext_tl_i64(t3, t1);
3583 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3584 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3585 tcg_gen_add_i64(t2, t2, t3);
3586 tcg_temp_free_i64(t3);
3587 tcg_gen_trunc_i64_tl(t0, t2);
3588 tcg_gen_shri_i64(t2, t2, 32);
3589 tcg_gen_trunc_i64_tl(t1, t2);
3590 tcg_temp_free_i64(t2);
4133498f
JL
3591 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3592 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3593 }
6af0bf9c
FB
3594 opn = "madd";
3595 break;
3596 case OPC_MADDU:
4133498f 3597 {
d45f89f4
AJ
3598 TCGv_i64 t2 = tcg_temp_new_i64();
3599 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3600
78723684
TS
3601 tcg_gen_ext32u_tl(t0, t0);
3602 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3603 tcg_gen_extu_tl_i64(t2, t0);
3604 tcg_gen_extu_tl_i64(t3, t1);
3605 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3606 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3607 tcg_gen_add_i64(t2, t2, t3);
3608 tcg_temp_free_i64(t3);
3609 tcg_gen_trunc_i64_tl(t0, t2);
3610 tcg_gen_shri_i64(t2, t2, 32);
3611 tcg_gen_trunc_i64_tl(t1, t2);
3612 tcg_temp_free_i64(t2);
4133498f
JL
3613 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3614 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3615 }
6af0bf9c
FB
3616 opn = "maddu";
3617 break;
3618 case OPC_MSUB:
214c465f 3619 {
d45f89f4
AJ
3620 TCGv_i64 t2 = tcg_temp_new_i64();
3621 TCGv_i64 t3 = tcg_temp_new_i64();
3622
3623 tcg_gen_ext_tl_i64(t2, t0);
3624 tcg_gen_ext_tl_i64(t3, t1);
3625 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3626 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3627 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3628 tcg_temp_free_i64(t3);
3629 tcg_gen_trunc_i64_tl(t0, t2);
3630 tcg_gen_shri_i64(t2, t2, 32);
3631 tcg_gen_trunc_i64_tl(t1, t2);
3632 tcg_temp_free_i64(t2);
4133498f
JL
3633 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3634 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3635 }
6af0bf9c
FB
3636 opn = "msub";
3637 break;
3638 case OPC_MSUBU:
214c465f 3639 {
d45f89f4
AJ
3640 TCGv_i64 t2 = tcg_temp_new_i64();
3641 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3642
78723684
TS
3643 tcg_gen_ext32u_tl(t0, t0);
3644 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3645 tcg_gen_extu_tl_i64(t2, t0);
3646 tcg_gen_extu_tl_i64(t3, t1);
3647 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3648 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3649 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3650 tcg_temp_free_i64(t3);
3651 tcg_gen_trunc_i64_tl(t0, t2);
3652 tcg_gen_shri_i64(t2, t2, 32);
3653 tcg_gen_trunc_i64_tl(t1, t2);
3654 tcg_temp_free_i64(t2);
4133498f
JL
3655 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3656 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3657 }
6af0bf9c
FB
3658 opn = "msubu";
3659 break;
3660 default:
923617a3 3661 MIPS_INVAL(opn);
6af0bf9c 3662 generate_exception(ctx, EXCP_RI);
78723684 3663 goto out;
6af0bf9c 3664 }
2abf314d 3665 (void)opn; /* avoid a compiler warning */
6af0bf9c 3666 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3667 out:
3668 tcg_temp_free(t0);
3669 tcg_temp_free(t1);
6af0bf9c
FB
3670}
3671
e9c71dd1
TS
3672static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3673 int rd, int rs, int rt)
3674{
3675 const char *opn = "mul vr54xx";
f157bfe1
AJ
3676 TCGv t0 = tcg_temp_new();
3677 TCGv t1 = tcg_temp_new();
e9c71dd1 3678
6c5c1e20
TS
3679 gen_load_gpr(t0, rs);
3680 gen_load_gpr(t1, rt);
e9c71dd1
TS
3681
3682 switch (opc) {
3683 case OPC_VR54XX_MULS:
895c2d04 3684 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3685 opn = "muls";
6958549d 3686 break;
e9c71dd1 3687 case OPC_VR54XX_MULSU:
895c2d04 3688 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3689 opn = "mulsu";
6958549d 3690 break;
e9c71dd1 3691 case OPC_VR54XX_MACC:
895c2d04 3692 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3693 opn = "macc";
6958549d 3694 break;
e9c71dd1 3695 case OPC_VR54XX_MACCU:
895c2d04 3696 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3697 opn = "maccu";
6958549d 3698 break;
e9c71dd1 3699 case OPC_VR54XX_MSAC:
895c2d04 3700 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3701 opn = "msac";
6958549d 3702 break;
e9c71dd1 3703 case OPC_VR54XX_MSACU:
895c2d04 3704 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3705 opn = "msacu";
6958549d 3706 break;
e9c71dd1 3707 case OPC_VR54XX_MULHI:
895c2d04 3708 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3709 opn = "mulhi";
6958549d 3710 break;
e9c71dd1 3711 case OPC_VR54XX_MULHIU:
895c2d04 3712 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3713 opn = "mulhiu";
6958549d 3714 break;
e9c71dd1 3715 case OPC_VR54XX_MULSHI:
895c2d04 3716 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3717 opn = "mulshi";
6958549d 3718 break;
e9c71dd1 3719 case OPC_VR54XX_MULSHIU:
895c2d04 3720 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3721 opn = "mulshiu";
6958549d 3722 break;
e9c71dd1 3723 case OPC_VR54XX_MACCHI:
895c2d04 3724 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3725 opn = "macchi";
6958549d 3726 break;
e9c71dd1 3727 case OPC_VR54XX_MACCHIU:
895c2d04 3728 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3729 opn = "macchiu";
6958549d 3730 break;
e9c71dd1 3731 case OPC_VR54XX_MSACHI:
895c2d04 3732 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3733 opn = "msachi";
6958549d 3734 break;
e9c71dd1 3735 case OPC_VR54XX_MSACHIU:
895c2d04 3736 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3737 opn = "msachiu";
6958549d 3738 break;
e9c71dd1
TS
3739 default:
3740 MIPS_INVAL("mul vr54xx");
3741 generate_exception(ctx, EXCP_RI);
6c5c1e20 3742 goto out;
e9c71dd1 3743 }
6c5c1e20 3744 gen_store_gpr(t0, rd);
2abf314d 3745 (void)opn; /* avoid a compiler warning */
e9c71dd1 3746 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3747
3748 out:
3749 tcg_temp_free(t0);
3750 tcg_temp_free(t1);
e9c71dd1
TS
3751}
3752
7a387fff 3753static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3754 int rd, int rs)
3755{
923617a3 3756 const char *opn = "CLx";
20e1fb52 3757 TCGv t0;
6c5c1e20 3758
6af0bf9c 3759 if (rd == 0) {
ead9360e 3760 /* Treat as NOP. */
6af0bf9c 3761 MIPS_DEBUG("NOP");
20e1fb52 3762 return;
6af0bf9c 3763 }
20e1fb52 3764 t0 = tcg_temp_new();
6c5c1e20 3765 gen_load_gpr(t0, rs);
6af0bf9c
FB
3766 switch (opc) {
3767 case OPC_CLO:
4267d3e6 3768 case R6_OPC_CLO:
20e1fb52 3769 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3770 opn = "clo";
3771 break;
3772 case OPC_CLZ:
4267d3e6 3773 case R6_OPC_CLZ:
20e1fb52 3774 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3775 opn = "clz";
3776 break;
d26bc211 3777#if defined(TARGET_MIPS64)
7a387fff 3778 case OPC_DCLO:
4267d3e6 3779 case R6_OPC_DCLO:
20e1fb52 3780 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3781 opn = "dclo";
3782 break;
3783 case OPC_DCLZ:
4267d3e6 3784 case R6_OPC_DCLZ:
20e1fb52 3785 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3786 opn = "dclz";
3787 break;
3788#endif
6af0bf9c 3789 }
2abf314d 3790 (void)opn; /* avoid a compiler warning */
6af0bf9c 3791 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3792 tcg_temp_free(t0);
6af0bf9c
FB
3793}
3794
161f85e6 3795/* Godson integer instructions */
bd277fa1
RH
3796static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3797 int rd, int rs, int rt)
161f85e6
AJ
3798{
3799 const char *opn = "loongson";
3800 TCGv t0, t1;
3801
3802 if (rd == 0) {
3803 /* Treat as NOP. */
3804 MIPS_DEBUG("NOP");
3805 return;
3806 }
3807
3808 switch (opc) {
3809 case OPC_MULT_G_2E:
3810 case OPC_MULT_G_2F:
3811 case OPC_MULTU_G_2E:
3812 case OPC_MULTU_G_2F:
3813#if defined(TARGET_MIPS64)
3814 case OPC_DMULT_G_2E:
3815 case OPC_DMULT_G_2F:
3816 case OPC_DMULTU_G_2E:
3817 case OPC_DMULTU_G_2F:
3818#endif
3819 t0 = tcg_temp_new();
3820 t1 = tcg_temp_new();
3821 break;
3822 default:
3823 t0 = tcg_temp_local_new();
3824 t1 = tcg_temp_local_new();
3825 break;
3826 }
3827
3828 gen_load_gpr(t0, rs);
3829 gen_load_gpr(t1, rt);
3830
3831 switch (opc) {
3832 case OPC_MULT_G_2E:
3833 case OPC_MULT_G_2F:
3834 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3835 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3836 opn = "mult.g";
3837 break;
3838 case OPC_MULTU_G_2E:
3839 case OPC_MULTU_G_2F:
3840 tcg_gen_ext32u_tl(t0, t0);
3841 tcg_gen_ext32u_tl(t1, t1);
3842 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3843 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3844 opn = "multu.g";
3845 break;
3846 case OPC_DIV_G_2E:
3847 case OPC_DIV_G_2F:
3848 {
42a268c2
RH
3849 TCGLabel *l1 = gen_new_label();
3850 TCGLabel *l2 = gen_new_label();
3851 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3852 tcg_gen_ext32s_tl(t0, t0);
3853 tcg_gen_ext32s_tl(t1, t1);
3854 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3855 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3856 tcg_gen_br(l3);
3857 gen_set_label(l1);
3858 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3859 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3860 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3861 tcg_gen_br(l3);
3862 gen_set_label(l2);
3863 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3864 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3865 gen_set_label(l3);
3866 }
3867 opn = "div.g";
3868 break;
3869 case OPC_DIVU_G_2E:
3870 case OPC_DIVU_G_2F:
3871 {
42a268c2
RH
3872 TCGLabel *l1 = gen_new_label();
3873 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3874 tcg_gen_ext32u_tl(t0, t0);
3875 tcg_gen_ext32u_tl(t1, t1);
3876 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3877 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3878 tcg_gen_br(l2);
3879 gen_set_label(l1);
3880 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3881 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3882 gen_set_label(l2);
3883 }
3884 opn = "divu.g";
3885 break;
3886 case OPC_MOD_G_2E:
3887 case OPC_MOD_G_2F:
3888 {
42a268c2
RH
3889 TCGLabel *l1 = gen_new_label();
3890 TCGLabel *l2 = gen_new_label();
3891 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3892 tcg_gen_ext32u_tl(t0, t0);
3893 tcg_gen_ext32u_tl(t1, t1);
3894 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3895 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3896 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3897 gen_set_label(l1);
3898 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3899 tcg_gen_br(l3);
3900 gen_set_label(l2);
3901 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3902 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3903 gen_set_label(l3);
3904 }
3905 opn = "mod.g";
3906 break;
3907 case OPC_MODU_G_2E:
3908 case OPC_MODU_G_2F:
3909 {
42a268c2
RH
3910 TCGLabel *l1 = gen_new_label();
3911 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3912 tcg_gen_ext32u_tl(t0, t0);
3913 tcg_gen_ext32u_tl(t1, t1);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3915 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3916 tcg_gen_br(l2);
3917 gen_set_label(l1);
3918 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3919 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3920 gen_set_label(l2);
3921 }
3922 opn = "modu.g";
3923 break;
3924#if defined(TARGET_MIPS64)
3925 case OPC_DMULT_G_2E:
3926 case OPC_DMULT_G_2F:
3927 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3928 opn = "dmult.g";
3929 break;
3930 case OPC_DMULTU_G_2E:
3931 case OPC_DMULTU_G_2F:
3932 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3933 opn = "dmultu.g";
3934 break;
3935 case OPC_DDIV_G_2E:
3936 case OPC_DDIV_G_2F:
3937 {
42a268c2
RH
3938 TCGLabel *l1 = gen_new_label();
3939 TCGLabel *l2 = gen_new_label();
3940 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3941 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3942 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3943 tcg_gen_br(l3);
3944 gen_set_label(l1);
3945 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3946 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3947 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3948 tcg_gen_br(l3);
3949 gen_set_label(l2);
3950 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3951 gen_set_label(l3);
3952 }
3953 opn = "ddiv.g";
3954 break;
3955 case OPC_DDIVU_G_2E:
3956 case OPC_DDIVU_G_2F:
3957 {
42a268c2
RH
3958 TCGLabel *l1 = gen_new_label();
3959 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3960 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3961 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3962 tcg_gen_br(l2);
3963 gen_set_label(l1);
3964 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3965 gen_set_label(l2);
3966 }
3967 opn = "ddivu.g";
3968 break;
3969 case OPC_DMOD_G_2E:
3970 case OPC_DMOD_G_2F:
3971 {
42a268c2
RH
3972 TCGLabel *l1 = gen_new_label();
3973 TCGLabel *l2 = gen_new_label();
3974 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3975 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3976 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3977 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3978 gen_set_label(l1);
3979 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3980 tcg_gen_br(l3);
3981 gen_set_label(l2);
3982 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3983 gen_set_label(l3);
3984 }
3985 opn = "dmod.g";
3986 break;
3987 case OPC_DMODU_G_2E:
3988 case OPC_DMODU_G_2F:
3989 {
42a268c2
RH
3990 TCGLabel *l1 = gen_new_label();
3991 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3992 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3993 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3994 tcg_gen_br(l2);
3995 gen_set_label(l1);
3996 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3997 gen_set_label(l2);
3998 }
3999 opn = "dmodu.g";
4000 break;
4001#endif
4002 }
4003
2abf314d 4004 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4005 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4006 tcg_temp_free(t0);
4007 tcg_temp_free(t1);
4008}
4009
bd277fa1
RH
4010/* Loongson multimedia instructions */
4011static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4012{
4013 const char *opn = "loongson_cp2";
4014 uint32_t opc, shift_max;
4015 TCGv_i64 t0, t1;
4016
4017 opc = MASK_LMI(ctx->opcode);
4018 switch (opc) {
4019 case OPC_ADD_CP2:
4020 case OPC_SUB_CP2:
4021 case OPC_DADD_CP2:
4022 case OPC_DSUB_CP2:
4023 t0 = tcg_temp_local_new_i64();
4024 t1 = tcg_temp_local_new_i64();
4025 break;
4026 default:
4027 t0 = tcg_temp_new_i64();
4028 t1 = tcg_temp_new_i64();
4029 break;
4030 }
4031
4032 gen_load_fpr64(ctx, t0, rs);
4033 gen_load_fpr64(ctx, t1, rt);
4034
4035#define LMI_HELPER(UP, LO) \
4036 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4037#define LMI_HELPER_1(UP, LO) \
4038 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4039#define LMI_DIRECT(UP, LO, OP) \
4040 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4041
4042 switch (opc) {
4043 LMI_HELPER(PADDSH, paddsh);
4044 LMI_HELPER(PADDUSH, paddush);
4045 LMI_HELPER(PADDH, paddh);
4046 LMI_HELPER(PADDW, paddw);
4047 LMI_HELPER(PADDSB, paddsb);
4048 LMI_HELPER(PADDUSB, paddusb);
4049 LMI_HELPER(PADDB, paddb);
4050
4051 LMI_HELPER(PSUBSH, psubsh);
4052 LMI_HELPER(PSUBUSH, psubush);
4053 LMI_HELPER(PSUBH, psubh);
4054 LMI_HELPER(PSUBW, psubw);
4055 LMI_HELPER(PSUBSB, psubsb);
4056 LMI_HELPER(PSUBUSB, psubusb);
4057 LMI_HELPER(PSUBB, psubb);
4058
4059 LMI_HELPER(PSHUFH, pshufh);
4060 LMI_HELPER(PACKSSWH, packsswh);
4061 LMI_HELPER(PACKSSHB, packsshb);
4062 LMI_HELPER(PACKUSHB, packushb);
4063
4064 LMI_HELPER(PUNPCKLHW, punpcklhw);
4065 LMI_HELPER(PUNPCKHHW, punpckhhw);
4066 LMI_HELPER(PUNPCKLBH, punpcklbh);
4067 LMI_HELPER(PUNPCKHBH, punpckhbh);
4068 LMI_HELPER(PUNPCKLWD, punpcklwd);
4069 LMI_HELPER(PUNPCKHWD, punpckhwd);
4070
4071 LMI_HELPER(PAVGH, pavgh);
4072 LMI_HELPER(PAVGB, pavgb);
4073 LMI_HELPER(PMAXSH, pmaxsh);
4074 LMI_HELPER(PMINSH, pminsh);
4075 LMI_HELPER(PMAXUB, pmaxub);
4076 LMI_HELPER(PMINUB, pminub);
4077
4078 LMI_HELPER(PCMPEQW, pcmpeqw);
4079 LMI_HELPER(PCMPGTW, pcmpgtw);
4080 LMI_HELPER(PCMPEQH, pcmpeqh);
4081 LMI_HELPER(PCMPGTH, pcmpgth);
4082 LMI_HELPER(PCMPEQB, pcmpeqb);
4083 LMI_HELPER(PCMPGTB, pcmpgtb);
4084
4085 LMI_HELPER(PSLLW, psllw);
4086 LMI_HELPER(PSLLH, psllh);
4087 LMI_HELPER(PSRLW, psrlw);
4088 LMI_HELPER(PSRLH, psrlh);
4089 LMI_HELPER(PSRAW, psraw);
4090 LMI_HELPER(PSRAH, psrah);
4091
4092 LMI_HELPER(PMULLH, pmullh);
4093 LMI_HELPER(PMULHH, pmulhh);
4094 LMI_HELPER(PMULHUH, pmulhuh);
4095 LMI_HELPER(PMADDHW, pmaddhw);
4096
4097 LMI_HELPER(PASUBUB, pasubub);
4098 LMI_HELPER_1(BIADD, biadd);
4099 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4100
4101 LMI_DIRECT(PADDD, paddd, add);
4102 LMI_DIRECT(PSUBD, psubd, sub);
4103 LMI_DIRECT(XOR_CP2, xor, xor);
4104 LMI_DIRECT(NOR_CP2, nor, nor);
4105 LMI_DIRECT(AND_CP2, and, and);
4106 LMI_DIRECT(PANDN, pandn, andc);
4107 LMI_DIRECT(OR, or, or);
4108
4109 case OPC_PINSRH_0:
4110 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4111 opn = "pinsrh_0";
4112 break;
4113 case OPC_PINSRH_1:
4114 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4115 opn = "pinsrh_1";
4116 break;
4117 case OPC_PINSRH_2:
4118 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4119 opn = "pinsrh_2";
4120 break;
4121 case OPC_PINSRH_3:
4122 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4123 opn = "pinsrh_3";
4124 break;
4125
4126 case OPC_PEXTRH:
4127 tcg_gen_andi_i64(t1, t1, 3);
4128 tcg_gen_shli_i64(t1, t1, 4);
4129 tcg_gen_shr_i64(t0, t0, t1);
4130 tcg_gen_ext16u_i64(t0, t0);
4131 opn = "pextrh";
4132 break;
4133
4134 case OPC_ADDU_CP2:
4135 tcg_gen_add_i64(t0, t0, t1);
4136 tcg_gen_ext32s_i64(t0, t0);
4137 opn = "addu";
4138 break;
4139 case OPC_SUBU_CP2:
4140 tcg_gen_sub_i64(t0, t0, t1);
4141 tcg_gen_ext32s_i64(t0, t0);
4142 opn = "addu";
4143 break;
4144
4145 case OPC_SLL_CP2:
4146 opn = "sll";
4147 shift_max = 32;
4148 goto do_shift;
4149 case OPC_SRL_CP2:
4150 opn = "srl";
4151 shift_max = 32;
4152 goto do_shift;
4153 case OPC_SRA_CP2:
4154 opn = "sra";
4155 shift_max = 32;
4156 goto do_shift;
4157 case OPC_DSLL_CP2:
4158 opn = "dsll";
4159 shift_max = 64;
4160 goto do_shift;
4161 case OPC_DSRL_CP2:
4162 opn = "dsrl";
4163 shift_max = 64;
4164 goto do_shift;
4165 case OPC_DSRA_CP2:
4166 opn = "dsra";
4167 shift_max = 64;
4168 goto do_shift;
4169 do_shift:
4170 /* Make sure shift count isn't TCG undefined behaviour. */
4171 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4172
4173 switch (opc) {
4174 case OPC_SLL_CP2:
4175 case OPC_DSLL_CP2:
4176 tcg_gen_shl_i64(t0, t0, t1);
4177 break;
4178 case OPC_SRA_CP2:
4179 case OPC_DSRA_CP2:
4180 /* Since SRA is UndefinedResult without sign-extended inputs,
4181 we can treat SRA and DSRA the same. */
4182 tcg_gen_sar_i64(t0, t0, t1);
4183 break;
4184 case OPC_SRL_CP2:
4185 /* We want to shift in zeros for SRL; zero-extend first. */
4186 tcg_gen_ext32u_i64(t0, t0);
4187 /* FALLTHRU */
4188 case OPC_DSRL_CP2:
4189 tcg_gen_shr_i64(t0, t0, t1);
4190 break;
4191 }
4192
4193 if (shift_max == 32) {
4194 tcg_gen_ext32s_i64(t0, t0);
4195 }
4196
4197 /* Shifts larger than MAX produce zero. */
4198 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4199 tcg_gen_neg_i64(t1, t1);
4200 tcg_gen_and_i64(t0, t0, t1);
4201 break;
4202
4203 case OPC_ADD_CP2:
4204 case OPC_DADD_CP2:
4205 {
4206 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4207 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4208
4209 tcg_gen_mov_i64(t2, t0);
4210 tcg_gen_add_i64(t0, t1, t2);
4211 if (opc == OPC_ADD_CP2) {
4212 tcg_gen_ext32s_i64(t0, t0);
4213 }
4214 tcg_gen_xor_i64(t1, t1, t2);
4215 tcg_gen_xor_i64(t2, t2, t0);
4216 tcg_gen_andc_i64(t1, t2, t1);
4217 tcg_temp_free_i64(t2);
4218 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4219 generate_exception(ctx, EXCP_OVERFLOW);
4220 gen_set_label(lab);
4221
4222 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4223 break;
4224 }
4225
4226 case OPC_SUB_CP2:
4227 case OPC_DSUB_CP2:
4228 {
4229 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4230 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4231
4232 tcg_gen_mov_i64(t2, t0);
4233 tcg_gen_sub_i64(t0, t1, t2);
4234 if (opc == OPC_SUB_CP2) {
4235 tcg_gen_ext32s_i64(t0, t0);
4236 }
4237 tcg_gen_xor_i64(t1, t1, t2);
4238 tcg_gen_xor_i64(t2, t2, t0);
4239 tcg_gen_and_i64(t1, t1, t2);
4240 tcg_temp_free_i64(t2);
4241 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4242 generate_exception(ctx, EXCP_OVERFLOW);
4243 gen_set_label(lab);
4244
4245 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4246 break;
4247 }
4248
4249 case OPC_PMULUW:
4250 tcg_gen_ext32u_i64(t0, t0);
4251 tcg_gen_ext32u_i64(t1, t1);
4252 tcg_gen_mul_i64(t0, t0, t1);
4253 opn = "pmuluw";
4254 break;
4255
4256 case OPC_SEQU_CP2:
4257 case OPC_SEQ_CP2:
4258 case OPC_SLTU_CP2:
4259 case OPC_SLT_CP2:
4260 case OPC_SLEU_CP2:
4261 case OPC_SLE_CP2:
4262 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4263 FD field is the CC field? */
4264 default:
4265 MIPS_INVAL(opn);
4266 generate_exception(ctx, EXCP_RI);
4267 return;
4268 }
4269
4270#undef LMI_HELPER
4271#undef LMI_DIRECT
4272
4273 gen_store_fpr64(ctx, t0, rd);
4274
4275 (void)opn; /* avoid a compiler warning */
4276 MIPS_DEBUG("%s %s, %s, %s", opn,
4277 fregnames[rd], fregnames[rs], fregnames[rt]);
4278 tcg_temp_free_i64(t0);
4279 tcg_temp_free_i64(t1);
4280}
4281
6af0bf9c 4282/* Traps */
7a387fff 4283static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4284 int rs, int rt, int16_t imm)
4285{
4286 int cond;
cdc0faa6 4287 TCGv t0 = tcg_temp_new();
1ba74fb8 4288 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4289
4290 cond = 0;
4291 /* Load needed operands */
4292 switch (opc) {
4293 case OPC_TEQ:
4294 case OPC_TGE:
4295 case OPC_TGEU:
4296 case OPC_TLT:
4297 case OPC_TLTU:
4298 case OPC_TNE:
4299 /* Compare two registers */
4300 if (rs != rt) {
be24bb4f
TS
4301 gen_load_gpr(t0, rs);
4302 gen_load_gpr(t1, rt);
6af0bf9c
FB
4303 cond = 1;
4304 }
179e32bb 4305 break;
6af0bf9c
FB
4306 case OPC_TEQI:
4307 case OPC_TGEI:
4308 case OPC_TGEIU:
4309 case OPC_TLTI:
4310 case OPC_TLTIU:
4311 case OPC_TNEI:
4312 /* Compare register to immediate */
4313 if (rs != 0 || imm != 0) {
be24bb4f
TS
4314 gen_load_gpr(t0, rs);
4315 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4316 cond = 1;
4317 }
4318 break;
4319 }
4320 if (cond == 0) {
4321 switch (opc) {
4322 case OPC_TEQ: /* rs == rs */
4323 case OPC_TEQI: /* r0 == 0 */
4324 case OPC_TGE: /* rs >= rs */
4325 case OPC_TGEI: /* r0 >= 0 */
4326 case OPC_TGEU: /* rs >= rs unsigned */
4327 case OPC_TGEIU: /* r0 >= 0 unsigned */
4328 /* Always trap */
cdc0faa6 4329 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4330 break;
4331 case OPC_TLT: /* rs < rs */
4332 case OPC_TLTI: /* r0 < 0 */
4333 case OPC_TLTU: /* rs < rs unsigned */
4334 case OPC_TLTIU: /* r0 < 0 unsigned */
4335 case OPC_TNE: /* rs != rs */
4336 case OPC_TNEI: /* r0 != 0 */
ead9360e 4337 /* Never trap: treat as NOP. */
cdc0faa6 4338 break;
6af0bf9c
FB
4339 }
4340 } else {
42a268c2 4341 TCGLabel *l1 = gen_new_label();
cdc0faa6 4342
6af0bf9c
FB
4343 switch (opc) {
4344 case OPC_TEQ:
4345 case OPC_TEQI:
cdc0faa6 4346 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4347 break;
4348 case OPC_TGE:
4349 case OPC_TGEI:
cdc0faa6 4350 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4351 break;
4352 case OPC_TGEU:
4353 case OPC_TGEIU:
cdc0faa6 4354 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4355 break;
4356 case OPC_TLT:
4357 case OPC_TLTI:
cdc0faa6 4358 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4359 break;
4360 case OPC_TLTU:
4361 case OPC_TLTIU:
cdc0faa6 4362 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4363 break;
4364 case OPC_TNE:
4365 case OPC_TNEI:
cdc0faa6 4366 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4367 break;
6af0bf9c 4368 }
cdc0faa6 4369 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4370 gen_set_label(l1);
4371 }
be24bb4f
TS
4372 tcg_temp_free(t0);
4373 tcg_temp_free(t1);
6af0bf9c
FB
4374}
4375
356265ae 4376static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4377{
6e256c93
FB
4378 TranslationBlock *tb;
4379 tb = ctx->tb;
7b270ef2
NF
4380 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4381 likely(!ctx->singlestep_enabled)) {
57fec1fe 4382 tcg_gen_goto_tb(n);
9b9e4393 4383 gen_save_pc(dest);
8cfd0495 4384 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4385 } else {
9b9e4393 4386 gen_save_pc(dest);
7b270ef2
NF
4387 if (ctx->singlestep_enabled) {
4388 save_cpu_state(ctx, 0);
895c2d04 4389 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4390 }
57fec1fe 4391 tcg_gen_exit_tb(0);
6e256c93 4392 }
c53be334
FB
4393}
4394
6af0bf9c 4395/* Branches (before delay slot) */
7a387fff 4396static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4397 int insn_bytes,
b231c103
YK
4398 int rs, int rt, int32_t offset,
4399 int delayslot_size)
6af0bf9c 4400{
d077b6f7 4401 target_ulong btgt = -1;
3ad4bb2d 4402 int blink = 0;
2fdbad25 4403 int bcond_compute = 0;
1ba74fb8
AJ
4404 TCGv t0 = tcg_temp_new();
4405 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4406
4407 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4408#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4409 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4410 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4411#endif
3ad4bb2d 4412 generate_exception(ctx, EXCP_RI);
6c5c1e20 4413 goto out;
3ad4bb2d 4414 }
6af0bf9c 4415
6af0bf9c
FB
4416 /* Load needed operands */
4417 switch (opc) {
4418 case OPC_BEQ:
4419 case OPC_BEQL:
4420 case OPC_BNE:
4421 case OPC_BNEL:
4422 /* Compare two registers */
4423 if (rs != rt) {
6c5c1e20
TS
4424 gen_load_gpr(t0, rs);
4425 gen_load_gpr(t1, rt);
2fdbad25 4426 bcond_compute = 1;
6af0bf9c 4427 }
7dca4ad0 4428 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4429 break;
4430 case OPC_BGEZ:
4431 case OPC_BGEZAL:
4432 case OPC_BGEZALL:
4433 case OPC_BGEZL:
4434 case OPC_BGTZ:
4435 case OPC_BGTZL:
4436 case OPC_BLEZ:
4437 case OPC_BLEZL:
4438 case OPC_BLTZ:
4439 case OPC_BLTZAL:
4440 case OPC_BLTZALL:
4441 case OPC_BLTZL:
4442 /* Compare to zero */
4443 if (rs != 0) {
6c5c1e20 4444 gen_load_gpr(t0, rs);
2fdbad25 4445 bcond_compute = 1;
6af0bf9c 4446 }
7dca4ad0 4447 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4448 break;
e45a93e2
JL
4449 case OPC_BPOSGE32:
4450#if defined(TARGET_MIPS64)
4451 case OPC_BPOSGE64:
4452 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4453#else
4454 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4455#endif
4456 bcond_compute = 1;
4457 btgt = ctx->pc + insn_bytes + offset;
4458 break;
6af0bf9c
FB
4459 case OPC_J:
4460 case OPC_JAL:
364d4831 4461 case OPC_JALX:
6af0bf9c 4462 /* Jump to immediate */
7dca4ad0 4463 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4464 break;
4465 case OPC_JR:
4466 case OPC_JALR:
4467 /* Jump to register */
7a387fff
TS
4468 if (offset != 0 && offset != 16) {
4469 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4470 others are reserved. */
923617a3 4471 MIPS_INVAL("jump hint");
6af0bf9c 4472 generate_exception(ctx, EXCP_RI);
6c5c1e20 4473 goto out;
6af0bf9c 4474 }
d077b6f7 4475 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4476 break;
4477 default:
4478 MIPS_INVAL("branch/jump");
4479 generate_exception(ctx, EXCP_RI);
6c5c1e20 4480 goto out;
6af0bf9c 4481 }
2fdbad25 4482 if (bcond_compute == 0) {
6af0bf9c
FB
4483 /* No condition to be computed */
4484 switch (opc) {
4485 case OPC_BEQ: /* rx == rx */
4486 case OPC_BEQL: /* rx == rx likely */
4487 case OPC_BGEZ: /* 0 >= 0 */
4488 case OPC_BGEZL: /* 0 >= 0 likely */
4489 case OPC_BLEZ: /* 0 <= 0 */
4490 case OPC_BLEZL: /* 0 <= 0 likely */
4491 /* Always take */
4ad40f36 4492 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4493 MIPS_DEBUG("balways");
4494 break;
4495 case OPC_BGEZAL: /* 0 >= 0 */
4496 case OPC_BGEZALL: /* 0 >= 0 likely */
4497 /* Always take and link */
4498 blink = 31;
4ad40f36 4499 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4500 MIPS_DEBUG("balways and link");
4501 break;
4502 case OPC_BNE: /* rx != rx */
4503 case OPC_BGTZ: /* 0 > 0 */
4504 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4505 /* Treat as NOP. */
6af0bf9c 4506 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4507 goto out;
eeef26cd 4508 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4509 /* Handle as an unconditional branch to get correct delay
4510 slot checking. */
4511 blink = 31;
b231c103 4512 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4513 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4514 MIPS_DEBUG("bnever and link");
3c824109 4515 break;
eeef26cd 4516 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4517 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4518 /* Skip the instruction in the delay slot */
4519 MIPS_DEBUG("bnever, link and skip");
4520 ctx->pc += 4;
6c5c1e20 4521 goto out;
6af0bf9c
FB
4522 case OPC_BNEL: /* rx != rx likely */
4523 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4524 case OPC_BLTZL: /* 0 < 0 likely */
4525 /* Skip the instruction in the delay slot */
4526 MIPS_DEBUG("bnever and skip");
9898128f 4527 ctx->pc += 4;
6c5c1e20 4528 goto out;
6af0bf9c 4529 case OPC_J:
4ad40f36 4530 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4531 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4532 break;
364d4831
NF
4533 case OPC_JALX:
4534 ctx->hflags |= MIPS_HFLAG_BX;
4535 /* Fallthrough */
6af0bf9c
FB
4536 case OPC_JAL:
4537 blink = 31;
4ad40f36 4538 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4539 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4540 break;
4541 case OPC_JR:
4ad40f36 4542 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4543 MIPS_DEBUG("jr %s", regnames[rs]);
4544 break;
4545 case OPC_JALR:
4546 blink = rt;
4ad40f36 4547 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4548 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4549 break;
4550 default:
4551 MIPS_INVAL("branch/jump");
4552 generate_exception(ctx, EXCP_RI);
6c5c1e20 4553 goto out;
6af0bf9c
FB
4554 }
4555 } else {
4556 switch (opc) {
4557 case OPC_BEQ:
e68dd28f 4558 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4559 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4560 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4561 goto not_likely;
4562 case OPC_BEQL:
e68dd28f 4563 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4564 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4565 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4566 goto likely;
4567 case OPC_BNE:
e68dd28f 4568 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4569 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4570 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4571 goto not_likely;
4572 case OPC_BNEL:
e68dd28f 4573 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4574 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4575 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4576 goto likely;
4577 case OPC_BGEZ:
e68dd28f 4578 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4579 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4580 goto not_likely;
4581 case OPC_BGEZL:
e68dd28f 4582 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4583 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4584 goto likely;
4585 case OPC_BGEZAL:
e68dd28f 4586 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4587 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4588 blink = 31;
4589 goto not_likely;
4590 case OPC_BGEZALL:
e68dd28f 4591 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4592 blink = 31;
d077b6f7 4593 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4594 goto likely;
4595 case OPC_BGTZ:
e68dd28f 4596 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4597 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4598 goto not_likely;
4599 case OPC_BGTZL:
e68dd28f 4600 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4601 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4602 goto likely;
4603 case OPC_BLEZ:
e68dd28f 4604 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4605 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4606 goto not_likely;
4607 case OPC_BLEZL:
e68dd28f 4608 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4609 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4610 goto likely;
4611 case OPC_BLTZ:
e68dd28f 4612 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4613 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4614 goto not_likely;
4615 case OPC_BLTZL:
e68dd28f 4616 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4617 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4618 goto likely;
e45a93e2
JL
4619 case OPC_BPOSGE32:
4620 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4621 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4622 goto not_likely;
4623#if defined(TARGET_MIPS64)
4624 case OPC_BPOSGE64:
4625 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4626 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4627 goto not_likely;
4628#endif
6af0bf9c 4629 case OPC_BLTZAL:
e68dd28f 4630 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4631 blink = 31;
d077b6f7 4632 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4633 not_likely:
4ad40f36 4634 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4635 break;
4636 case OPC_BLTZALL:
e68dd28f 4637 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4638 blink = 31;
d077b6f7 4639 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4640 likely:
4ad40f36 4641 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4642 break;
c53f4a62
TS
4643 default:
4644 MIPS_INVAL("conditional branch/jump");
4645 generate_exception(ctx, EXCP_RI);
6c5c1e20 4646 goto out;
6af0bf9c 4647 }
6af0bf9c 4648 }
923617a3 4649 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4650 blink, ctx->hflags, btgt);
9b9e4393 4651
d077b6f7 4652 ctx->btarget = btgt;
b231c103
YK
4653
4654 switch (delayslot_size) {
4655 case 2:
4656 ctx->hflags |= MIPS_HFLAG_BDS16;
4657 break;
4658 case 4:
4659 ctx->hflags |= MIPS_HFLAG_BDS32;
4660 break;
4661 }
4662
6af0bf9c 4663 if (blink > 0) {
b231c103 4664 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4665 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4666
364d4831 4667 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4668 }
6c5c1e20
TS
4669
4670 out:
364d4831
NF
4671 if (insn_bytes == 2)
4672 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4673 tcg_temp_free(t0);
4674 tcg_temp_free(t1);
6af0bf9c
FB
4675}
4676
7a387fff
TS
4677/* special3 bitfield operations */
4678static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4679 int rs, int lsb, int msb)
7a387fff 4680{
a7812ae4
PB
4681 TCGv t0 = tcg_temp_new();
4682 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4683
4684 gen_load_gpr(t1, rs);
7a387fff
TS
4685 switch (opc) {
4686 case OPC_EXT:
4687 if (lsb + msb > 31)
4688 goto fail;
505ad7c2
AJ
4689 tcg_gen_shri_tl(t0, t1, lsb);
4690 if (msb != 31) {
4691 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4692 } else {
4693 tcg_gen_ext32s_tl(t0, t0);
4694 }
7a387fff 4695 break;
c6d6dd7c 4696#if defined(TARGET_MIPS64)
7a387fff 4697 case OPC_DEXTM:
505ad7c2
AJ
4698 tcg_gen_shri_tl(t0, t1, lsb);
4699 if (msb != 31) {
4700 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4701 }
7a387fff
TS
4702 break;
4703 case OPC_DEXTU:
505ad7c2
AJ
4704 tcg_gen_shri_tl(t0, t1, lsb + 32);
4705 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4706 break;
4707 case OPC_DEXT:
505ad7c2
AJ
4708 tcg_gen_shri_tl(t0, t1, lsb);
4709 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4710 break;
c6d6dd7c 4711#endif
7a387fff
TS
4712 case OPC_INS:
4713 if (lsb > msb)
4714 goto fail;
6c5c1e20 4715 gen_load_gpr(t0, rt);
e0d002f1 4716 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4717 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4718 break;
c6d6dd7c 4719#if defined(TARGET_MIPS64)
7a387fff 4720 case OPC_DINSM:
6c5c1e20 4721 gen_load_gpr(t0, rt);
e0d002f1 4722 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4723 break;
4724 case OPC_DINSU:
6c5c1e20 4725 gen_load_gpr(t0, rt);
e0d002f1 4726 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4727 break;
4728 case OPC_DINS:
6c5c1e20 4729 gen_load_gpr(t0, rt);
e0d002f1 4730 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4731 break;
c6d6dd7c 4732#endif
7a387fff
TS
4733 default:
4734fail:
4735 MIPS_INVAL("bitops");
4736 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4737 tcg_temp_free(t0);
4738 tcg_temp_free(t1);
7a387fff
TS
4739 return;
4740 }
6c5c1e20
TS
4741 gen_store_gpr(t0, rt);
4742 tcg_temp_free(t0);
4743 tcg_temp_free(t1);
7a387fff
TS
4744}
4745
49bcf33c
AJ
4746static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4747{
3a55fa47 4748 TCGv t0;
49bcf33c 4749
3a55fa47
AJ
4750 if (rd == 0) {
4751 /* If no destination, treat it as a NOP. */
4752 MIPS_DEBUG("NOP");
4753 return;
4754 }
4755
4756 t0 = tcg_temp_new();
4757 gen_load_gpr(t0, rt);
49bcf33c
AJ
4758 switch (op2) {
4759 case OPC_WSBH:
3a55fa47
AJ
4760 {
4761 TCGv t1 = tcg_temp_new();
4762
4763 tcg_gen_shri_tl(t1, t0, 8);
4764 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4765 tcg_gen_shli_tl(t0, t0, 8);
4766 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4767 tcg_gen_or_tl(t0, t0, t1);
4768 tcg_temp_free(t1);
4769 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4770 }
49bcf33c
AJ
4771 break;
4772 case OPC_SEB:
3a55fa47 4773 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4774 break;
4775 case OPC_SEH:
3a55fa47 4776 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4777 break;
4778#if defined(TARGET_MIPS64)
4779 case OPC_DSBH:
3a55fa47
AJ
4780 {
4781 TCGv t1 = tcg_temp_new();
4782
4783 tcg_gen_shri_tl(t1, t0, 8);
4784 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4785 tcg_gen_shli_tl(t0, t0, 8);
4786 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4787 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4788 tcg_temp_free(t1);
4789 }
49bcf33c
AJ
4790 break;
4791 case OPC_DSHD:
3a55fa47
AJ
4792 {
4793 TCGv t1 = tcg_temp_new();
4794
4795 tcg_gen_shri_tl(t1, t0, 16);
4796 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4797 tcg_gen_shli_tl(t0, t0, 16);
4798 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4799 tcg_gen_or_tl(t0, t0, t1);
4800 tcg_gen_shri_tl(t1, t0, 32);
4801 tcg_gen_shli_tl(t0, t0, 32);
4802 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4803 tcg_temp_free(t1);
4804 }
49bcf33c
AJ
4805 break;
4806#endif
4807 default:
4808 MIPS_INVAL("bsfhl");
4809 generate_exception(ctx, EXCP_RI);
4810 tcg_temp_free(t0);
49bcf33c
AJ
4811 return;
4812 }
49bcf33c 4813 tcg_temp_free(t0);
49bcf33c
AJ
4814}
4815
f1aa6320 4816#ifndef CONFIG_USER_ONLY
0eaef5aa 4817/* CP0 (MMU and control) */
d9bea114 4818static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4819{
d9bea114 4820 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4821
d9bea114
AJ
4822 tcg_gen_ld_i32(t0, cpu_env, off);
4823 tcg_gen_ext_i32_tl(arg, t0);
4824 tcg_temp_free_i32(t0);
4f57689a
TS
4825}
4826
d9bea114 4827static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4828{
d9bea114
AJ
4829 tcg_gen_ld_tl(arg, cpu_env, off);
4830 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4831}
4832
d9bea114 4833static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4834{
d9bea114 4835 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4836
d9bea114
AJ
4837 tcg_gen_trunc_tl_i32(t0, arg);
4838 tcg_gen_st_i32(t0, cpu_env, off);
4839 tcg_temp_free_i32(t0);
f1aa6320
TS
4840}
4841
d9bea114 4842static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4843{
d9bea114
AJ
4844 tcg_gen_ext32s_tl(arg, arg);
4845 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4846}
4847
e98c0d17
LA
4848static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4849{
4850 if (ctx->insn_flags & ISA_MIPS32R6) {
4851 tcg_gen_movi_tl(arg, 0);
4852 } else {
4853 tcg_gen_movi_tl(arg, ~0);
4854 }
4855}
4856
f31b035a
LA
4857#define CP0_CHECK(c) \
4858 do { \
4859 if (!(c)) { \
4860 goto cp0_unimplemented; \
4861 } \
4862 } while (0)
4863
d75c135e 4864static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4865{
7a387fff 4866 const char *rn = "invalid";
873eb012 4867
e189e748 4868 if (sel != 0)
d75c135e 4869 check_insn(ctx, ISA_MIPS32);
e189e748 4870
873eb012
TS
4871 switch (reg) {
4872 case 0:
7a387fff
TS
4873 switch (sel) {
4874 case 0:
7db13fae 4875 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4876 rn = "Index";
4877 break;
4878 case 1:
f31b035a 4879 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4880 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4881 rn = "MVPControl";
ead9360e 4882 break;
7a387fff 4883 case 2:
f31b035a 4884 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4885 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4886 rn = "MVPConf0";
ead9360e 4887 break;
7a387fff 4888 case 3:
f31b035a 4889 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4890 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4891 rn = "MVPConf1";
ead9360e 4892 break;
7a387fff 4893 default:
f31b035a 4894 goto cp0_unimplemented;
7a387fff 4895 }
873eb012
TS
4896 break;
4897 case 1:
7a387fff
TS
4898 switch (sel) {
4899 case 0:
f31b035a 4900 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4901 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4902 rn = "Random";
2423f660 4903 break;
7a387fff 4904 case 1:
f31b035a 4905 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4907 rn = "VPEControl";
ead9360e 4908 break;
7a387fff 4909 case 2:
f31b035a 4910 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4912 rn = "VPEConf0";
ead9360e 4913 break;
7a387fff 4914 case 3:
f31b035a 4915 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4916 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4917 rn = "VPEConf1";
ead9360e 4918 break;
7a387fff 4919 case 4:
f31b035a 4920 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4921 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4922 rn = "YQMask";
ead9360e 4923 break;
7a387fff 4924 case 5:
f31b035a 4925 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4926 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4927 rn = "VPESchedule";
ead9360e 4928 break;
7a387fff 4929 case 6:
f31b035a 4930 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4931 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4932 rn = "VPEScheFBack";
ead9360e 4933 break;
7a387fff 4934 case 7:
f31b035a 4935 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4937 rn = "VPEOpt";
ead9360e 4938 break;
7a387fff 4939 default:
f31b035a 4940 goto cp0_unimplemented;
7a387fff 4941 }
873eb012
TS
4942 break;
4943 case 2:
7a387fff
TS
4944 switch (sel) {
4945 case 0:
7db13fae 4946 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4947#if defined(TARGET_MIPS64)
4948 if (ctx->rxi) {
4949 TCGv tmp = tcg_temp_new();
d3b1979d 4950 tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
7207c7f9
LA
4951 tcg_gen_shri_tl(tmp, tmp, 32);
4952 tcg_gen_or_tl(arg, arg, tmp);
4953 tcg_temp_free(tmp);
4954 }
4955#endif
d9bea114 4956 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4957 rn = "EntryLo0";
4958 break;
7a387fff 4959 case 1:
f31b035a 4960 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4961 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4962 rn = "TCStatus";
ead9360e 4963 break;
7a387fff 4964 case 2:
f31b035a 4965 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4966 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4967 rn = "TCBind";
ead9360e 4968 break;
7a387fff 4969 case 3:
f31b035a 4970 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4971 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4972 rn = "TCRestart";
ead9360e 4973 break;
7a387fff 4974 case 4:
f31b035a 4975 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4976 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4977 rn = "TCHalt";
ead9360e 4978 break;
7a387fff 4979 case 5:
f31b035a 4980 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4981 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4982 rn = "TCContext";
ead9360e 4983 break;
7a387fff 4984 case 6:
f31b035a 4985 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4986 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4987 rn = "TCSchedule";
ead9360e 4988 break;
7a387fff 4989 case 7:
f31b035a 4990 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4991 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4992 rn = "TCScheFBack";
ead9360e 4993 break;
7a387fff 4994 default:
f31b035a 4995 goto cp0_unimplemented;
7a387fff 4996 }
873eb012
TS
4997 break;
4998 case 3:
7a387fff
TS
4999 switch (sel) {
5000 case 0:
7db13fae 5001 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
5002#if defined(TARGET_MIPS64)
5003 if (ctx->rxi) {
5004 TCGv tmp = tcg_temp_new();
d3b1979d 5005 tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
7207c7f9
LA
5006 tcg_gen_shri_tl(tmp, tmp, 32);
5007 tcg_gen_or_tl(arg, arg, tmp);
5008 tcg_temp_free(tmp);
5009 }
5010#endif
d9bea114 5011 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5012 rn = "EntryLo1";
5013 break;
7a387fff 5014 default:
f31b035a 5015 goto cp0_unimplemented;
1579a72e 5016 }
873eb012
TS
5017 break;
5018 case 4:
7a387fff
TS
5019 switch (sel) {
5020 case 0:
7db13fae 5021 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5022 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5023 rn = "Context";
5024 break;
7a387fff 5025 case 1:
d9bea114 5026// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5027 rn = "ContextConfig";
f31b035a 5028 goto cp0_unimplemented;
2423f660 5029// break;
d279279e 5030 case 2:
f31b035a
LA
5031 CP0_CHECK(ctx->ulri);
5032 tcg_gen_ld32s_tl(arg, cpu_env,
5033 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5034 rn = "UserLocal";
d279279e 5035 break;
7a387fff 5036 default:
f31b035a 5037 goto cp0_unimplemented;
1579a72e 5038 }
873eb012
TS
5039 break;
5040 case 5:
7a387fff
TS
5041 switch (sel) {
5042 case 0:
7db13fae 5043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5044 rn = "PageMask";
5045 break;
7a387fff 5046 case 1:
d75c135e 5047 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5048 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5049 rn = "PageGrain";
5050 break;
7a387fff 5051 default:
f31b035a 5052 goto cp0_unimplemented;
1579a72e 5053 }
873eb012
TS
5054 break;
5055 case 6:
7a387fff
TS
5056 switch (sel) {
5057 case 0:
7db13fae 5058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5059 rn = "Wired";
5060 break;
7a387fff 5061 case 1:
d75c135e 5062 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5064 rn = "SRSConf0";
ead9360e 5065 break;
7a387fff 5066 case 2:
d75c135e 5067 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5069 rn = "SRSConf1";
ead9360e 5070 break;
7a387fff 5071 case 3:
d75c135e 5072 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5074 rn = "SRSConf2";
ead9360e 5075 break;
7a387fff 5076 case 4:
d75c135e 5077 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5078 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5079 rn = "SRSConf3";
ead9360e 5080 break;
7a387fff 5081 case 5:
d75c135e 5082 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5084 rn = "SRSConf4";
ead9360e 5085 break;
7a387fff 5086 default:
f31b035a 5087 goto cp0_unimplemented;
1579a72e 5088 }
873eb012 5089 break;
8c0fdd85 5090 case 7:
7a387fff
TS
5091 switch (sel) {
5092 case 0:
d75c135e 5093 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5095 rn = "HWREna";
5096 break;
7a387fff 5097 default:
f31b035a 5098 goto cp0_unimplemented;
1579a72e 5099 }
8c0fdd85 5100 break;
873eb012 5101 case 8:
7a387fff
TS
5102 switch (sel) {
5103 case 0:
7db13fae 5104 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5105 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5106 rn = "BadVAddr";
2423f660 5107 break;
aea14095 5108 case 1:
f31b035a
LA
5109 CP0_CHECK(ctx->bi);
5110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5111 rn = "BadInstr";
aea14095
LA
5112 break;
5113 case 2:
f31b035a
LA
5114 CP0_CHECK(ctx->bp);
5115 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5116 rn = "BadInstrP";
aea14095 5117 break;
7a387fff 5118 default:
f31b035a 5119 goto cp0_unimplemented;
aea14095 5120 }
873eb012
TS
5121 break;
5122 case 9:
7a387fff
TS
5123 switch (sel) {
5124 case 0:
2e70f6ef 5125 /* Mark as an IO operation because we read the time. */
bd79255d 5126 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5127 gen_io_start();
bd79255d 5128 }
895c2d04 5129 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5130 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5131 gen_io_end();
2e70f6ef 5132 }
55807224
EI
5133 /* Break the TB to be able to take timer interrupts immediately
5134 after reading count. */
5135 ctx->bstate = BS_STOP;
2423f660
TS
5136 rn = "Count";
5137 break;
5138 /* 6,7 are implementation dependent */
7a387fff 5139 default:
f31b035a 5140 goto cp0_unimplemented;
2423f660 5141 }
873eb012
TS
5142 break;
5143 case 10:
7a387fff
TS
5144 switch (sel) {
5145 case 0:
7db13fae 5146 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5147 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5148 rn = "EntryHi";
5149 break;
7a387fff 5150 default:
f31b035a 5151 goto cp0_unimplemented;
1579a72e 5152 }
873eb012
TS
5153 break;
5154 case 11:
7a387fff
TS
5155 switch (sel) {
5156 case 0:
7db13fae 5157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5158 rn = "Compare";
5159 break;
5160 /* 6,7 are implementation dependent */
7a387fff 5161 default:
f31b035a 5162 goto cp0_unimplemented;
2423f660 5163 }
873eb012
TS
5164 break;
5165 case 12:
7a387fff
TS
5166 switch (sel) {
5167 case 0:
7db13fae 5168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5169 rn = "Status";
5170 break;
7a387fff 5171 case 1:
d75c135e 5172 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5174 rn = "IntCtl";
5175 break;
7a387fff 5176 case 2:
d75c135e 5177 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5179 rn = "SRSCtl";
5180 break;
7a387fff 5181 case 3:
d75c135e 5182 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5184 rn = "SRSMap";
fd88b6ab 5185 break;
7a387fff 5186 default:
f31b035a 5187 goto cp0_unimplemented;
7a387fff 5188 }
873eb012
TS
5189 break;
5190 case 13:
7a387fff
TS
5191 switch (sel) {
5192 case 0:
7db13fae 5193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5194 rn = "Cause";
5195 break;
7a387fff 5196 default:
f31b035a 5197 goto cp0_unimplemented;
7a387fff 5198 }
873eb012
TS
5199 break;
5200 case 14:
7a387fff
TS
5201 switch (sel) {
5202 case 0:
7db13fae 5203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5204 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5205 rn = "EPC";
5206 break;
7a387fff 5207 default:
f31b035a 5208 goto cp0_unimplemented;
1579a72e 5209 }
873eb012
TS
5210 break;
5211 case 15:
7a387fff
TS
5212 switch (sel) {
5213 case 0:
7db13fae 5214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5215 rn = "PRid";
5216 break;
7a387fff 5217 case 1:
d75c135e 5218 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5220 rn = "EBase";
5221 break;
7a387fff 5222 default:
f31b035a 5223 goto cp0_unimplemented;
7a387fff 5224 }
873eb012
TS
5225 break;
5226 case 16:
5227 switch (sel) {
5228 case 0:
7db13fae 5229 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5230 rn = "Config";
5231 break;
5232 case 1:
7db13fae 5233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5234 rn = "Config1";
5235 break;
7a387fff 5236 case 2:
7db13fae 5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5238 rn = "Config2";
5239 break;
5240 case 3:
7db13fae 5241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5242 rn = "Config3";
5243 break;
b4160af1
PJ
5244 case 4:
5245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5246 rn = "Config4";
5247 break;
b4dd99a3
PJ
5248 case 5:
5249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5250 rn = "Config5";
5251 break;
e397ee33
TS
5252 /* 6,7 are implementation dependent */
5253 case 6:
7db13fae 5254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5255 rn = "Config6";
5256 break;
5257 case 7:
7db13fae 5258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5259 rn = "Config7";
5260 break;
873eb012 5261 default:
f31b035a 5262 goto cp0_unimplemented;
873eb012
TS
5263 }
5264 break;
5265 case 17:
7a387fff
TS
5266 switch (sel) {
5267 case 0:
895c2d04 5268 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5269 rn = "LLAddr";
5270 break;
7a387fff 5271 default:
f31b035a 5272 goto cp0_unimplemented;
7a387fff 5273 }
873eb012
TS
5274 break;
5275 case 18:
7a387fff 5276 switch (sel) {
fd88b6ab 5277 case 0 ... 7:
895c2d04 5278 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5279 rn = "WatchLo";
5280 break;
7a387fff 5281 default:
f31b035a 5282 goto cp0_unimplemented;
7a387fff 5283 }
873eb012
TS
5284 break;
5285 case 19:
7a387fff 5286 switch (sel) {
fd88b6ab 5287 case 0 ...7:
895c2d04 5288 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5289 rn = "WatchHi";
5290 break;
7a387fff 5291 default:
f31b035a 5292 goto cp0_unimplemented;
7a387fff 5293 }
873eb012 5294 break;
8c0fdd85 5295 case 20:
7a387fff
TS
5296 switch (sel) {
5297 case 0:
d26bc211 5298#if defined(TARGET_MIPS64)
d75c135e 5299 check_insn(ctx, ISA_MIPS3);
7db13fae 5300 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5301 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5302 rn = "XContext";
5303 break;
703eaf37 5304#endif
7a387fff 5305 default:
f31b035a 5306 goto cp0_unimplemented;
7a387fff 5307 }
8c0fdd85
TS
5308 break;
5309 case 21:
7a387fff 5310 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5311 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5312 switch (sel) {
5313 case 0:
7db13fae 5314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5315 rn = "Framemask";
5316 break;
7a387fff 5317 default:
f31b035a 5318 goto cp0_unimplemented;
7a387fff 5319 }
8c0fdd85
TS
5320 break;
5321 case 22:
d9bea114 5322 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5323 rn = "'Diagnostic"; /* implementation dependent */
5324 break;
873eb012 5325 case 23:
7a387fff
TS
5326 switch (sel) {
5327 case 0:
895c2d04 5328 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5329 rn = "Debug";
5330 break;
7a387fff 5331 case 1:
d9bea114 5332// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5333 rn = "TraceControl";
5334// break;
7a387fff 5335 case 2:
d9bea114 5336// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5337 rn = "TraceControl2";
5338// break;
7a387fff 5339 case 3:
d9bea114 5340// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5341 rn = "UserTraceData";
5342// break;
7a387fff 5343 case 4:
d9bea114 5344// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5345 rn = "TraceBPC";
5346// break;
7a387fff 5347 default:
f31b035a 5348 goto cp0_unimplemented;
7a387fff 5349 }
873eb012
TS
5350 break;
5351 case 24:
7a387fff
TS
5352 switch (sel) {
5353 case 0:
f0b3f3ae 5354 /* EJTAG support */
7db13fae 5355 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5356 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5357 rn = "DEPC";
5358 break;
7a387fff 5359 default:
f31b035a 5360 goto cp0_unimplemented;
7a387fff 5361 }
873eb012 5362 break;
8c0fdd85 5363 case 25:
7a387fff
TS
5364 switch (sel) {
5365 case 0:
7db13fae 5366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5367 rn = "Performance0";
7a387fff
TS
5368 break;
5369 case 1:
d9bea114 5370// gen_helper_mfc0_performance1(arg);
2423f660
TS
5371 rn = "Performance1";
5372// break;
7a387fff 5373 case 2:
d9bea114 5374// gen_helper_mfc0_performance2(arg);
2423f660
TS
5375 rn = "Performance2";
5376// break;
7a387fff 5377 case 3:
d9bea114 5378// gen_helper_mfc0_performance3(arg);
2423f660
TS
5379 rn = "Performance3";
5380// break;
7a387fff 5381 case 4:
d9bea114 5382// gen_helper_mfc0_performance4(arg);
2423f660
TS
5383 rn = "Performance4";
5384// break;
7a387fff 5385 case 5:
d9bea114 5386// gen_helper_mfc0_performance5(arg);
2423f660
TS
5387 rn = "Performance5";
5388// break;
7a387fff 5389 case 6:
d9bea114 5390// gen_helper_mfc0_performance6(arg);
2423f660
TS
5391 rn = "Performance6";
5392// break;
7a387fff 5393 case 7:
d9bea114 5394// gen_helper_mfc0_performance7(arg);
2423f660
TS
5395 rn = "Performance7";
5396// break;
7a387fff 5397 default:
f31b035a 5398 goto cp0_unimplemented;
7a387fff 5399 }
8c0fdd85
TS
5400 break;
5401 case 26:
d9bea114 5402 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5403 rn = "ECC";
5404 break;
8c0fdd85 5405 case 27:
7a387fff 5406 switch (sel) {
7a387fff 5407 case 0 ... 3:
d9bea114 5408 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5409 rn = "CacheErr";
5410 break;
7a387fff 5411 default:
f31b035a 5412 goto cp0_unimplemented;
7a387fff 5413 }
8c0fdd85 5414 break;
873eb012
TS
5415 case 28:
5416 switch (sel) {
5417 case 0:
7a387fff
TS
5418 case 2:
5419 case 4:
5420 case 6:
7db13fae 5421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5422 rn = "TagLo";
5423 break;
5424 case 1:
7a387fff
TS
5425 case 3:
5426 case 5:
5427 case 7:
7db13fae 5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5429 rn = "DataLo";
5430 break;
5431 default:
f31b035a 5432 goto cp0_unimplemented;
873eb012
TS
5433 }
5434 break;
8c0fdd85 5435 case 29:
7a387fff
TS
5436 switch (sel) {
5437 case 0:
5438 case 2:
5439 case 4:
5440 case 6:
7db13fae 5441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5442 rn = "TagHi";
5443 break;
5444 case 1:
5445 case 3:
5446 case 5:
5447 case 7:
7db13fae 5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5449 rn = "DataHi";
5450 break;
5451 default:
f31b035a 5452 goto cp0_unimplemented;
7a387fff 5453 }
8c0fdd85 5454 break;
873eb012 5455 case 30:
7a387fff
TS
5456 switch (sel) {
5457 case 0:
7db13fae 5458 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5459 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5460 rn = "ErrorEPC";
5461 break;
7a387fff 5462 default:
f31b035a 5463 goto cp0_unimplemented;
7a387fff 5464 }
873eb012
TS
5465 break;
5466 case 31:
7a387fff
TS
5467 switch (sel) {
5468 case 0:
f0b3f3ae 5469 /* EJTAG support */
7db13fae 5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5471 rn = "DESAVE";
5472 break;
e98c0d17 5473 case 2 ... 7:
f31b035a
LA
5474 CP0_CHECK(ctx->kscrexist & (1 << sel));
5475 tcg_gen_ld_tl(arg, cpu_env,
5476 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5477 tcg_gen_ext32s_tl(arg, arg);
5478 rn = "KScratch";
e98c0d17 5479 break;
7a387fff 5480 default:
f31b035a 5481 goto cp0_unimplemented;
7a387fff 5482 }
873eb012
TS
5483 break;
5484 default:
f31b035a 5485 goto cp0_unimplemented;
873eb012 5486 }
2abf314d 5487 (void)rn; /* avoid a compiler warning */
d12d51d5 5488 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5489 return;
5490
f31b035a 5491cp0_unimplemented:
d12d51d5 5492 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5493 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5494}
5495
d75c135e 5496static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5497{
7a387fff
TS
5498 const char *rn = "invalid";
5499
e189e748 5500 if (sel != 0)
d75c135e 5501 check_insn(ctx, ISA_MIPS32);
e189e748 5502
bd79255d 5503 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5504 gen_io_start();
bd79255d 5505 }
2e70f6ef 5506
8c0fdd85
TS
5507 switch (reg) {
5508 case 0:
7a387fff
TS
5509 switch (sel) {
5510 case 0:
895c2d04 5511 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5512 rn = "Index";
5513 break;
5514 case 1:
f31b035a 5515 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5516 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5517 rn = "MVPControl";
ead9360e 5518 break;
7a387fff 5519 case 2:
f31b035a 5520 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5521 /* ignored */
7a387fff 5522 rn = "MVPConf0";
ead9360e 5523 break;
7a387fff 5524 case 3:
f31b035a 5525 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5526 /* ignored */
7a387fff 5527 rn = "MVPConf1";
ead9360e 5528 break;
7a387fff 5529 default:
f31b035a 5530 goto cp0_unimplemented;
7a387fff 5531 }
8c0fdd85
TS
5532 break;
5533 case 1:
7a387fff
TS
5534 switch (sel) {
5535 case 0:
2423f660 5536 /* ignored */
7a387fff 5537 rn = "Random";
2423f660 5538 break;
7a387fff 5539 case 1:
f31b035a 5540 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5541 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5542 rn = "VPEControl";
ead9360e 5543 break;
7a387fff 5544 case 2:
f31b035a 5545 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5546 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5547 rn = "VPEConf0";
ead9360e 5548 break;
7a387fff 5549 case 3:
f31b035a 5550 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5551 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5552 rn = "VPEConf1";
ead9360e 5553 break;
7a387fff 5554 case 4:
f31b035a 5555 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5556 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5557 rn = "YQMask";
ead9360e 5558 break;
7a387fff 5559 case 5:
f31b035a 5560 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5561 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5562 rn = "VPESchedule";
ead9360e 5563 break;
7a387fff 5564 case 6:
f31b035a 5565 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5566 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5567 rn = "VPEScheFBack";
ead9360e 5568 break;
7a387fff 5569 case 7:
f31b035a 5570 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5571 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5572 rn = "VPEOpt";
ead9360e 5573 break;
7a387fff 5574 default:
f31b035a 5575 goto cp0_unimplemented;
7a387fff 5576 }
8c0fdd85
TS
5577 break;
5578 case 2:
7a387fff
TS
5579 switch (sel) {
5580 case 0:
895c2d04 5581 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5582 rn = "EntryLo0";
5583 break;
7a387fff 5584 case 1:
f31b035a 5585 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5586 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5587 rn = "TCStatus";
ead9360e 5588 break;
7a387fff 5589 case 2:
f31b035a 5590 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5591 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5592 rn = "TCBind";
ead9360e 5593 break;
7a387fff 5594 case 3:
f31b035a 5595 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5596 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5597 rn = "TCRestart";
ead9360e 5598 break;
7a387fff 5599 case 4:
f31b035a 5600 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5601 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5602 rn = "TCHalt";
ead9360e 5603 break;
7a387fff 5604 case 5:
f31b035a 5605 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5606 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5607 rn = "TCContext";
ead9360e 5608 break;
7a387fff 5609 case 6:
f31b035a 5610 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5611 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5612 rn = "TCSchedule";
ead9360e 5613 break;
7a387fff 5614 case 7:
f31b035a 5615 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5616 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5617 rn = "TCScheFBack";
ead9360e 5618 break;
7a387fff 5619 default:
f31b035a 5620 goto cp0_unimplemented;
7a387fff 5621 }
8c0fdd85
TS
5622 break;
5623 case 3:
7a387fff
TS
5624 switch (sel) {
5625 case 0:
895c2d04 5626 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5627 rn = "EntryLo1";
5628 break;
7a387fff 5629 default:
f31b035a 5630 goto cp0_unimplemented;
876d4b07 5631 }
8c0fdd85
TS
5632 break;
5633 case 4:
7a387fff
TS
5634 switch (sel) {
5635 case 0:
895c2d04 5636 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5637 rn = "Context";
5638 break;
7a387fff 5639 case 1:
895c2d04 5640// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5641 rn = "ContextConfig";
f31b035a 5642 goto cp0_unimplemented;
2423f660 5643// break;
d279279e 5644 case 2:
f31b035a
LA
5645 CP0_CHECK(ctx->ulri);
5646 tcg_gen_st_tl(arg, cpu_env,
5647 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5648 rn = "UserLocal";
d279279e 5649 break;
7a387fff 5650 default:
f31b035a 5651 goto cp0_unimplemented;
876d4b07 5652 }
8c0fdd85
TS
5653 break;
5654 case 5:
7a387fff
TS
5655 switch (sel) {
5656 case 0:
895c2d04 5657 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5658 rn = "PageMask";
5659 break;
7a387fff 5660 case 1:
d75c135e 5661 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5662 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5663 rn = "PageGrain";
5664 break;
7a387fff 5665 default:
f31b035a 5666 goto cp0_unimplemented;
876d4b07 5667 }
8c0fdd85
TS
5668 break;
5669 case 6:
7a387fff
TS
5670 switch (sel) {
5671 case 0:
895c2d04 5672 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5673 rn = "Wired";
5674 break;
7a387fff 5675 case 1:
d75c135e 5676 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5677 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5678 rn = "SRSConf0";
ead9360e 5679 break;
7a387fff 5680 case 2:
d75c135e 5681 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5682 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5683 rn = "SRSConf1";
ead9360e 5684 break;
7a387fff 5685 case 3:
d75c135e 5686 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5687 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5688 rn = "SRSConf2";
ead9360e 5689 break;
7a387fff 5690 case 4:
d75c135e 5691 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5692 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5693 rn = "SRSConf3";
ead9360e 5694 break;
7a387fff 5695 case 5:
d75c135e 5696 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5697 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5698 rn = "SRSConf4";
ead9360e 5699 break;
7a387fff 5700 default:
f31b035a 5701 goto cp0_unimplemented;
876d4b07 5702 }
8c0fdd85
TS
5703 break;
5704 case 7:
7a387fff
TS
5705 switch (sel) {
5706 case 0:
d75c135e 5707 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5708 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5709 ctx->bstate = BS_STOP;
2423f660
TS
5710 rn = "HWREna";
5711 break;
7a387fff 5712 default:
f31b035a 5713 goto cp0_unimplemented;
876d4b07 5714 }
8c0fdd85
TS
5715 break;
5716 case 8:
aea14095
LA
5717 switch (sel) {
5718 case 0:
5719 /* ignored */
5720 rn = "BadVAddr";
5721 break;
5722 case 1:
5723 /* ignored */
5724 rn = "BadInstr";
5725 break;
5726 case 2:
5727 /* ignored */
5728 rn = "BadInstrP";
5729 break;
5730 default:
f31b035a 5731 goto cp0_unimplemented;
aea14095 5732 }
8c0fdd85
TS
5733 break;
5734 case 9:
7a387fff
TS
5735 switch (sel) {
5736 case 0:
895c2d04 5737 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5738 rn = "Count";
5739 break;
876d4b07 5740 /* 6,7 are implementation dependent */
7a387fff 5741 default:
f31b035a 5742 goto cp0_unimplemented;
876d4b07 5743 }
8c0fdd85
TS
5744 break;
5745 case 10:
7a387fff
TS
5746 switch (sel) {
5747 case 0:
895c2d04 5748 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5749 rn = "EntryHi";
5750 break;
7a387fff 5751 default:
f31b035a 5752 goto cp0_unimplemented;
876d4b07 5753 }
8c0fdd85
TS
5754 break;
5755 case 11:
7a387fff
TS
5756 switch (sel) {
5757 case 0:
895c2d04 5758 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5759 rn = "Compare";
5760 break;
5761 /* 6,7 are implementation dependent */
7a387fff 5762 default:
f31b035a 5763 goto cp0_unimplemented;
876d4b07 5764 }
8c0fdd85
TS
5765 break;
5766 case 12:
7a387fff
TS
5767 switch (sel) {
5768 case 0:
867abc7e 5769 save_cpu_state(ctx, 1);
895c2d04 5770 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5771 /* BS_STOP isn't good enough here, hflags may have changed. */
5772 gen_save_pc(ctx->pc + 4);
5773 ctx->bstate = BS_EXCP;
2423f660
TS
5774 rn = "Status";
5775 break;
7a387fff 5776 case 1:
d75c135e 5777 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5778 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5779 /* Stop translation as we may have switched the execution mode */
5780 ctx->bstate = BS_STOP;
2423f660
TS
5781 rn = "IntCtl";
5782 break;
7a387fff 5783 case 2:
d75c135e 5784 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5785 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5786 /* Stop translation as we may have switched the execution mode */
5787 ctx->bstate = BS_STOP;
2423f660
TS
5788 rn = "SRSCtl";
5789 break;
7a387fff 5790 case 3:
d75c135e 5791 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5792 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5793 /* Stop translation as we may have switched the execution mode */
5794 ctx->bstate = BS_STOP;
2423f660 5795 rn = "SRSMap";
fd88b6ab 5796 break;
7a387fff 5797 default:
f31b035a 5798 goto cp0_unimplemented;
876d4b07 5799 }
8c0fdd85
TS
5800 break;
5801 case 13:
7a387fff
TS
5802 switch (sel) {
5803 case 0:
867abc7e 5804 save_cpu_state(ctx, 1);
895c2d04 5805 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5806 rn = "Cause";
5807 break;
7a387fff 5808 default:
f31b035a 5809 goto cp0_unimplemented;
876d4b07 5810 }
8c0fdd85
TS
5811 break;
5812 case 14:
7a387fff
TS
5813 switch (sel) {
5814 case 0:
7db13fae 5815 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5816 rn = "EPC";
5817 break;
7a387fff 5818 default:
f31b035a 5819 goto cp0_unimplemented;
876d4b07 5820 }
8c0fdd85
TS
5821 break;
5822 case 15:
7a387fff
TS
5823 switch (sel) {
5824 case 0:
2423f660
TS
5825 /* ignored */
5826 rn = "PRid";
5827 break;
7a387fff 5828 case 1:
d75c135e 5829 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5830 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5831 rn = "EBase";
5832 break;
7a387fff 5833 default:
f31b035a 5834 goto cp0_unimplemented;
1579a72e 5835 }
8c0fdd85
TS
5836 break;
5837 case 16:
5838 switch (sel) {
5839 case 0:
895c2d04 5840 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5841 rn = "Config";
2423f660
TS
5842 /* Stop translation as we may have switched the execution mode */
5843 ctx->bstate = BS_STOP;
7a387fff
TS
5844 break;
5845 case 1:
e397ee33 5846 /* ignored, read only */
7a387fff
TS
5847 rn = "Config1";
5848 break;
5849 case 2:
895c2d04 5850 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5851 rn = "Config2";
2423f660
TS
5852 /* Stop translation as we may have switched the execution mode */
5853 ctx->bstate = BS_STOP;
8c0fdd85 5854 break;
7a387fff 5855 case 3:
90f12d73 5856 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5857 rn = "Config3";
90f12d73
MR
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx->bstate = BS_STOP;
7a387fff 5860 break;
b4160af1
PJ
5861 case 4:
5862 gen_helper_mtc0_config4(cpu_env, arg);
5863 rn = "Config4";
5864 ctx->bstate = BS_STOP;
5865 break;
b4dd99a3
PJ
5866 case 5:
5867 gen_helper_mtc0_config5(cpu_env, arg);
5868 rn = "Config5";
5869 /* Stop translation as we may have switched the execution mode */
5870 ctx->bstate = BS_STOP;
5871 break;
e397ee33
TS
5872 /* 6,7 are implementation dependent */
5873 case 6:
5874 /* ignored */
5875 rn = "Config6";
5876 break;
5877 case 7:
5878 /* ignored */
5879 rn = "Config7";
5880 break;
8c0fdd85
TS
5881 default:
5882 rn = "Invalid config selector";
f31b035a 5883 goto cp0_unimplemented;
8c0fdd85
TS
5884 }
5885 break;
5886 case 17:
7a387fff
TS
5887 switch (sel) {
5888 case 0:
895c2d04 5889 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5890 rn = "LLAddr";
5891 break;
7a387fff 5892 default:
f31b035a 5893 goto cp0_unimplemented;
7a387fff 5894 }
8c0fdd85
TS
5895 break;
5896 case 18:
7a387fff 5897 switch (sel) {
fd88b6ab 5898 case 0 ... 7:
895c2d04 5899 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5900 rn = "WatchLo";
5901 break;
7a387fff 5902 default:
f31b035a 5903 goto cp0_unimplemented;
7a387fff 5904 }
8c0fdd85
TS
5905 break;
5906 case 19:
7a387fff 5907 switch (sel) {
fd88b6ab 5908 case 0 ... 7:
895c2d04 5909 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5910 rn = "WatchHi";
5911 break;
7a387fff 5912 default:
f31b035a 5913 goto cp0_unimplemented;
7a387fff 5914 }
8c0fdd85
TS
5915 break;
5916 case 20:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
d26bc211 5919#if defined(TARGET_MIPS64)
d75c135e 5920 check_insn(ctx, ISA_MIPS3);
895c2d04 5921 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5922 rn = "XContext";
5923 break;
703eaf37 5924#endif
7a387fff 5925 default:
f31b035a 5926 goto cp0_unimplemented;
7a387fff 5927 }
8c0fdd85
TS
5928 break;
5929 case 21:
7a387fff 5930 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5931 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5932 switch (sel) {
5933 case 0:
895c2d04 5934 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5935 rn = "Framemask";
5936 break;
7a387fff 5937 default:
f31b035a 5938 goto cp0_unimplemented;
7a387fff
TS
5939 }
5940 break;
8c0fdd85 5941 case 22:
7a387fff
TS
5942 /* ignored */
5943 rn = "Diagnostic"; /* implementation dependent */
2423f660 5944 break;
8c0fdd85 5945 case 23:
7a387fff
TS
5946 switch (sel) {
5947 case 0:
895c2d04 5948 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5949 /* BS_STOP isn't good enough here, hflags may have changed. */
5950 gen_save_pc(ctx->pc + 4);
5951 ctx->bstate = BS_EXCP;
2423f660
TS
5952 rn = "Debug";
5953 break;
7a387fff 5954 case 1:
895c2d04 5955// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5956 rn = "TraceControl";
8487327a
TS
5957 /* Stop translation as we may have switched the execution mode */
5958 ctx->bstate = BS_STOP;
2423f660 5959// break;
7a387fff 5960 case 2:
895c2d04 5961// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5962 rn = "TraceControl2";
8487327a
TS
5963 /* Stop translation as we may have switched the execution mode */
5964 ctx->bstate = BS_STOP;
2423f660 5965// break;
7a387fff 5966 case 3:
8487327a
TS
5967 /* Stop translation as we may have switched the execution mode */
5968 ctx->bstate = BS_STOP;
895c2d04 5969// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5970 rn = "UserTraceData";
8487327a
TS
5971 /* Stop translation as we may have switched the execution mode */
5972 ctx->bstate = BS_STOP;
2423f660 5973// break;
7a387fff 5974 case 4:
895c2d04 5975// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5976 /* Stop translation as we may have switched the execution mode */
5977 ctx->bstate = BS_STOP;
2423f660
TS
5978 rn = "TraceBPC";
5979// break;
7a387fff 5980 default:
f31b035a 5981 goto cp0_unimplemented;
7a387fff 5982 }
8c0fdd85
TS
5983 break;
5984 case 24:
7a387fff
TS
5985 switch (sel) {
5986 case 0:
f1aa6320 5987 /* EJTAG support */
7db13fae 5988 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5989 rn = "DEPC";
5990 break;
7a387fff 5991 default:
f31b035a 5992 goto cp0_unimplemented;
7a387fff 5993 }
8c0fdd85
TS
5994 break;
5995 case 25:
7a387fff
TS
5996 switch (sel) {
5997 case 0:
895c2d04 5998 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5999 rn = "Performance0";
6000 break;
7a387fff 6001 case 1:
d9bea114 6002// gen_helper_mtc0_performance1(arg);
2423f660
TS
6003 rn = "Performance1";
6004// break;
7a387fff 6005 case 2:
d9bea114 6006// gen_helper_mtc0_performance2(arg);
2423f660
TS
6007 rn = "Performance2";
6008// break;
7a387fff 6009 case 3:
d9bea114 6010// gen_helper_mtc0_performance3(arg);
2423f660
TS
6011 rn = "Performance3";
6012// break;
7a387fff 6013 case 4:
d9bea114 6014// gen_helper_mtc0_performance4(arg);
2423f660
TS
6015 rn = "Performance4";
6016// break;
7a387fff 6017 case 5:
d9bea114 6018// gen_helper_mtc0_performance5(arg);
2423f660
TS
6019 rn = "Performance5";
6020// break;
7a387fff 6021 case 6:
d9bea114 6022// gen_helper_mtc0_performance6(arg);
2423f660
TS
6023 rn = "Performance6";
6024// break;
7a387fff 6025 case 7:
d9bea114 6026// gen_helper_mtc0_performance7(arg);
2423f660
TS
6027 rn = "Performance7";
6028// break;
7a387fff 6029 default:
f31b035a 6030 goto cp0_unimplemented;
7a387fff 6031 }
8c0fdd85
TS
6032 break;
6033 case 26:
2423f660 6034 /* ignored */
8c0fdd85 6035 rn = "ECC";
2423f660 6036 break;
8c0fdd85 6037 case 27:
7a387fff
TS
6038 switch (sel) {
6039 case 0 ... 3:
2423f660
TS
6040 /* ignored */
6041 rn = "CacheErr";
6042 break;
7a387fff 6043 default:
f31b035a 6044 goto cp0_unimplemented;
7a387fff 6045 }
8c0fdd85
TS
6046 break;
6047 case 28:
6048 switch (sel) {
6049 case 0:
7a387fff
TS
6050 case 2:
6051 case 4:
6052 case 6:
895c2d04 6053 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6054 rn = "TagLo";
6055 break;
7a387fff
TS
6056 case 1:
6057 case 3:
6058 case 5:
6059 case 7:
895c2d04 6060 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6061 rn = "DataLo";
6062 break;
8c0fdd85 6063 default:
f31b035a 6064 goto cp0_unimplemented;
8c0fdd85
TS
6065 }
6066 break;
6067 case 29:
7a387fff
TS
6068 switch (sel) {
6069 case 0:
6070 case 2:
6071 case 4:
6072 case 6:
895c2d04 6073 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6074 rn = "TagHi";
6075 break;
6076 case 1:
6077 case 3:
6078 case 5:
6079 case 7:
895c2d04 6080 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6081 rn = "DataHi";
6082 break;
6083 default:
6084 rn = "invalid sel";
f31b035a 6085 goto cp0_unimplemented;
7a387fff 6086 }
8c0fdd85
TS
6087 break;
6088 case 30:
7a387fff
TS
6089 switch (sel) {
6090 case 0:
7db13fae 6091 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6092 rn = "ErrorEPC";
6093 break;
7a387fff 6094 default:
f31b035a 6095 goto cp0_unimplemented;
7a387fff 6096 }
8c0fdd85
TS
6097 break;
6098 case 31:
7a387fff
TS
6099 switch (sel) {
6100 case 0:
f1aa6320 6101 /* EJTAG support */
7db13fae 6102 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6103 rn = "DESAVE";
6104 break;
e98c0d17 6105 case 2 ... 7:
f31b035a
LA
6106 CP0_CHECK(ctx->kscrexist & (1 << sel));
6107 tcg_gen_st_tl(arg, cpu_env,
6108 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6109 rn = "KScratch";
e98c0d17 6110 break;
7a387fff 6111 default:
f31b035a 6112 goto cp0_unimplemented;
7a387fff 6113 }
2423f660
TS
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx->bstate = BS_STOP;
8c0fdd85
TS
6116 break;
6117 default:
f31b035a 6118 goto cp0_unimplemented;
8c0fdd85 6119 }
2abf314d 6120 (void)rn; /* avoid a compiler warning */
d12d51d5 6121 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6122 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6123 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6124 gen_io_end();
6125 ctx->bstate = BS_STOP;
6126 }
8c0fdd85
TS
6127 return;
6128
f31b035a 6129cp0_unimplemented:
d12d51d5 6130 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6131}
6132
d26bc211 6133#if defined(TARGET_MIPS64)
d75c135e 6134static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6135{
6136 const char *rn = "invalid";
6137
e189e748 6138 if (sel != 0)
d75c135e 6139 check_insn(ctx, ISA_MIPS64);
e189e748 6140
9c2149c8
TS
6141 switch (reg) {
6142 case 0:
6143 switch (sel) {
6144 case 0:
7db13fae 6145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6146 rn = "Index";
6147 break;
6148 case 1:
f31b035a 6149 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6150 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6151 rn = "MVPControl";
ead9360e 6152 break;
9c2149c8 6153 case 2:
f31b035a 6154 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6155 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6156 rn = "MVPConf0";
ead9360e 6157 break;
9c2149c8 6158 case 3:
f31b035a 6159 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6160 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6161 rn = "MVPConf1";
ead9360e 6162 break;
9c2149c8 6163 default:
f31b035a 6164 goto cp0_unimplemented;
9c2149c8
TS
6165 }
6166 break;
6167 case 1:
6168 switch (sel) {
6169 case 0:
f31b035a 6170 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6171 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6172 rn = "Random";
2423f660 6173 break;
9c2149c8 6174 case 1:
f31b035a 6175 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6177 rn = "VPEControl";
ead9360e 6178 break;
9c2149c8 6179 case 2:
f31b035a 6180 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6182 rn = "VPEConf0";
ead9360e 6183 break;
9c2149c8 6184 case 3:
f31b035a 6185 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6187 rn = "VPEConf1";
ead9360e 6188 break;
9c2149c8 6189 case 4:
f31b035a 6190 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6191 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6192 rn = "YQMask";
ead9360e 6193 break;
9c2149c8 6194 case 5:
f31b035a 6195 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6196 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6197 rn = "VPESchedule";
ead9360e 6198 break;
9c2149c8 6199 case 6:
f31b035a 6200 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6202 rn = "VPEScheFBack";
ead9360e 6203 break;
9c2149c8 6204 case 7:
f31b035a 6205 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6207 rn = "VPEOpt";
ead9360e 6208 break;
9c2149c8 6209 default:
f31b035a 6210 goto cp0_unimplemented;
9c2149c8
TS
6211 }
6212 break;
6213 case 2:
6214 switch (sel) {
6215 case 0:
7db13fae 6216 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6217 rn = "EntryLo0";
6218 break;
9c2149c8 6219 case 1:
f31b035a 6220 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6221 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6222 rn = "TCStatus";
ead9360e 6223 break;
9c2149c8 6224 case 2:
f31b035a 6225 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6226 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6227 rn = "TCBind";
ead9360e 6228 break;
9c2149c8 6229 case 3:
f31b035a 6230 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6231 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6232 rn = "TCRestart";
ead9360e 6233 break;
9c2149c8 6234 case 4:
f31b035a 6235 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6236 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6237 rn = "TCHalt";
ead9360e 6238 break;
9c2149c8 6239 case 5:
f31b035a 6240 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6241 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6242 rn = "TCContext";
ead9360e 6243 break;
9c2149c8 6244 case 6:
f31b035a 6245 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6246 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6247 rn = "TCSchedule";
ead9360e 6248 break;
9c2149c8 6249 case 7:
f31b035a 6250 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6251 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6252 rn = "TCScheFBack";
ead9360e 6253 break;
9c2149c8 6254 default:
f31b035a 6255 goto cp0_unimplemented;
9c2149c8
TS
6256 }
6257 break;
6258 case 3:
6259 switch (sel) {
6260 case 0:
7db13fae 6261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6262 rn = "EntryLo1";
6263 break;
9c2149c8 6264 default:
f31b035a 6265 goto cp0_unimplemented;
1579a72e 6266 }
9c2149c8
TS
6267 break;
6268 case 4:
6269 switch (sel) {
6270 case 0:
7db13fae 6271 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6272 rn = "Context";
6273 break;
9c2149c8 6274 case 1:
d9bea114 6275// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6276 rn = "ContextConfig";
f31b035a 6277 goto cp0_unimplemented;
2423f660 6278// break;
d279279e 6279 case 2:
f31b035a
LA
6280 CP0_CHECK(ctx->ulri);
6281 tcg_gen_ld_tl(arg, cpu_env,
6282 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6283 rn = "UserLocal";
d279279e 6284 break;
9c2149c8 6285 default:
f31b035a 6286 goto cp0_unimplemented;
876d4b07 6287 }
9c2149c8
TS
6288 break;
6289 case 5:
6290 switch (sel) {
6291 case 0:
7db13fae 6292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6293 rn = "PageMask";
6294 break;
9c2149c8 6295 case 1:
d75c135e 6296 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6298 rn = "PageGrain";
6299 break;
9c2149c8 6300 default:
f31b035a 6301 goto cp0_unimplemented;
876d4b07 6302 }
9c2149c8
TS
6303 break;
6304 case 6:
6305 switch (sel) {
6306 case 0:
7db13fae 6307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6308 rn = "Wired";
6309 break;
9c2149c8 6310 case 1:
d75c135e 6311 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6313 rn = "SRSConf0";
ead9360e 6314 break;
9c2149c8 6315 case 2:
d75c135e 6316 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6318 rn = "SRSConf1";
ead9360e 6319 break;
9c2149c8 6320 case 3:
d75c135e 6321 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6323 rn = "SRSConf2";
ead9360e 6324 break;
9c2149c8 6325 case 4:
d75c135e 6326 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6328 rn = "SRSConf3";
ead9360e 6329 break;
9c2149c8 6330 case 5:
d75c135e 6331 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6333 rn = "SRSConf4";
ead9360e 6334 break;
9c2149c8 6335 default:
f31b035a 6336 goto cp0_unimplemented;
876d4b07 6337 }
9c2149c8
TS
6338 break;
6339 case 7:
6340 switch (sel) {
6341 case 0:
d75c135e 6342 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6344 rn = "HWREna";
6345 break;
9c2149c8 6346 default:
f31b035a 6347 goto cp0_unimplemented;
876d4b07 6348 }
9c2149c8
TS
6349 break;
6350 case 8:
6351 switch (sel) {
6352 case 0:
7db13fae 6353 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6354 rn = "BadVAddr";
2423f660 6355 break;
aea14095 6356 case 1:
f31b035a
LA
6357 CP0_CHECK(ctx->bi);
6358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6359 rn = "BadInstr";
aea14095
LA
6360 break;
6361 case 2:
f31b035a
LA
6362 CP0_CHECK(ctx->bp);
6363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6364 rn = "BadInstrP";
aea14095 6365 break;
9c2149c8 6366 default:
f31b035a 6367 goto cp0_unimplemented;
876d4b07 6368 }
9c2149c8
TS
6369 break;
6370 case 9:
6371 switch (sel) {
6372 case 0:
2e70f6ef 6373 /* Mark as an IO operation because we read the time. */
bd79255d 6374 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6375 gen_io_start();
bd79255d 6376 }
895c2d04 6377 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6378 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6379 gen_io_end();
2e70f6ef 6380 }
55807224
EI
6381 /* Break the TB to be able to take timer interrupts immediately
6382 after reading count. */
6383 ctx->bstate = BS_STOP;
2423f660
TS
6384 rn = "Count";
6385 break;
6386 /* 6,7 are implementation dependent */
9c2149c8 6387 default:
f31b035a 6388 goto cp0_unimplemented;
876d4b07 6389 }
9c2149c8
TS
6390 break;
6391 case 10:
6392 switch (sel) {
6393 case 0:
7db13fae 6394 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6395 rn = "EntryHi";
6396 break;
9c2149c8 6397 default:
f31b035a 6398 goto cp0_unimplemented;
876d4b07 6399 }
9c2149c8
TS
6400 break;
6401 case 11:
6402 switch (sel) {
6403 case 0:
7db13fae 6404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6405 rn = "Compare";
6406 break;
876d4b07 6407 /* 6,7 are implementation dependent */
9c2149c8 6408 default:
f31b035a 6409 goto cp0_unimplemented;
876d4b07 6410 }
9c2149c8
TS
6411 break;
6412 case 12:
6413 switch (sel) {
6414 case 0:
7db13fae 6415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6416 rn = "Status";
6417 break;
9c2149c8 6418 case 1:
d75c135e 6419 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6421 rn = "IntCtl";
6422 break;
9c2149c8 6423 case 2:
d75c135e 6424 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6426 rn = "SRSCtl";
6427 break;
9c2149c8 6428 case 3:
d75c135e 6429 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6431 rn = "SRSMap";
6432 break;
9c2149c8 6433 default:
f31b035a 6434 goto cp0_unimplemented;
876d4b07 6435 }
9c2149c8
TS
6436 break;
6437 case 13:
6438 switch (sel) {
6439 case 0:
7db13fae 6440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6441 rn = "Cause";
6442 break;
9c2149c8 6443 default:
f31b035a 6444 goto cp0_unimplemented;
876d4b07 6445 }
9c2149c8
TS
6446 break;
6447 case 14:
6448 switch (sel) {
6449 case 0:
7db13fae 6450 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6451 rn = "EPC";
6452 break;
9c2149c8 6453 default:
f31b035a 6454 goto cp0_unimplemented;
876d4b07 6455 }
9c2149c8
TS
6456 break;
6457 case 15:
6458 switch (sel) {
6459 case 0:
7db13fae 6460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6461 rn = "PRid";
6462 break;
9c2149c8 6463 case 1:
d75c135e 6464 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6466 rn = "EBase";
6467 break;
9c2149c8 6468 default:
f31b035a 6469 goto cp0_unimplemented;
876d4b07 6470 }
9c2149c8
TS
6471 break;
6472 case 16:
6473 switch (sel) {
6474 case 0:
7db13fae 6475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6476 rn = "Config";
6477 break;
6478 case 1:
7db13fae 6479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6480 rn = "Config1";
6481 break;
6482 case 2:
7db13fae 6483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6484 rn = "Config2";
6485 break;
6486 case 3:
7db13fae 6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6488 rn = "Config3";
6489 break;
faf1f68b
LA
6490 case 4:
6491 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6492 rn = "Config4";
6493 break;
6494 case 5:
6495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6496 rn = "Config5";
6497 break;
9c2149c8 6498 /* 6,7 are implementation dependent */
f0b3f3ae 6499 case 6:
7db13fae 6500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6501 rn = "Config6";
6502 break;
6503 case 7:
7db13fae 6504 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6505 rn = "Config7";
6506 break;
9c2149c8 6507 default:
f31b035a 6508 goto cp0_unimplemented;
9c2149c8
TS
6509 }
6510 break;
6511 case 17:
6512 switch (sel) {
6513 case 0:
895c2d04 6514 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6515 rn = "LLAddr";
6516 break;
9c2149c8 6517 default:
f31b035a 6518 goto cp0_unimplemented;
9c2149c8
TS
6519 }
6520 break;
6521 case 18:
6522 switch (sel) {
fd88b6ab 6523 case 0 ... 7:
895c2d04 6524 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6525 rn = "WatchLo";
6526 break;
9c2149c8 6527 default:
f31b035a 6528 goto cp0_unimplemented;
9c2149c8
TS
6529 }
6530 break;
6531 case 19:
6532 switch (sel) {
fd88b6ab 6533 case 0 ... 7:
895c2d04 6534 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6535 rn = "WatchHi";
6536 break;
9c2149c8 6537 default:
f31b035a 6538 goto cp0_unimplemented;
9c2149c8
TS
6539 }
6540 break;
6541 case 20:
6542 switch (sel) {
6543 case 0:
d75c135e 6544 check_insn(ctx, ISA_MIPS3);
7db13fae 6545 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6546 rn = "XContext";
6547 break;
9c2149c8 6548 default:
f31b035a 6549 goto cp0_unimplemented;
9c2149c8
TS
6550 }
6551 break;
6552 case 21:
6553 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6554 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6555 switch (sel) {
6556 case 0:
7db13fae 6557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6558 rn = "Framemask";
6559 break;
9c2149c8 6560 default:
f31b035a 6561 goto cp0_unimplemented;
9c2149c8
TS
6562 }
6563 break;
6564 case 22:
d9bea114 6565 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6566 rn = "'Diagnostic"; /* implementation dependent */
6567 break;
9c2149c8
TS
6568 case 23:
6569 switch (sel) {
6570 case 0:
895c2d04 6571 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6572 rn = "Debug";
6573 break;
9c2149c8 6574 case 1:
895c2d04 6575// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6576 rn = "TraceControl";
6577// break;
9c2149c8 6578 case 2:
895c2d04 6579// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6580 rn = "TraceControl2";
6581// break;
9c2149c8 6582 case 3:
895c2d04 6583// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6584 rn = "UserTraceData";
6585// break;
9c2149c8 6586 case 4:
895c2d04 6587// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6588 rn = "TraceBPC";
6589// break;
9c2149c8 6590 default:
f31b035a 6591 goto cp0_unimplemented;
9c2149c8
TS
6592 }
6593 break;
6594 case 24:
6595 switch (sel) {
6596 case 0:
f0b3f3ae 6597 /* EJTAG support */
7db13fae 6598 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6599 rn = "DEPC";
6600 break;
9c2149c8 6601 default:
f31b035a 6602 goto cp0_unimplemented;
9c2149c8
TS
6603 }
6604 break;
6605 case 25:
6606 switch (sel) {
6607 case 0:
7db13fae 6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6609 rn = "Performance0";
9c2149c8
TS
6610 break;
6611 case 1:
d9bea114 6612// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6613 rn = "Performance1";
6614// break;
9c2149c8 6615 case 2:
d9bea114 6616// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6617 rn = "Performance2";
6618// break;
9c2149c8 6619 case 3:
d9bea114 6620// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6621 rn = "Performance3";
6622// break;
9c2149c8 6623 case 4:
d9bea114 6624// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6625 rn = "Performance4";
6626// break;
9c2149c8 6627 case 5:
d9bea114 6628// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6629 rn = "Performance5";
6630// break;
9c2149c8 6631 case 6:
d9bea114 6632// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6633 rn = "Performance6";
6634// break;
9c2149c8 6635 case 7:
d9bea114 6636// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6637 rn = "Performance7";
6638// break;
9c2149c8 6639 default:
f31b035a 6640 goto cp0_unimplemented;
9c2149c8
TS
6641 }
6642 break;
6643 case 26:
d9bea114 6644 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6645 rn = "ECC";
6646 break;
9c2149c8
TS
6647 case 27:
6648 switch (sel) {
6649 /* ignored */
6650 case 0 ... 3:
d9bea114 6651 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6652 rn = "CacheErr";
6653 break;
9c2149c8 6654 default:
f31b035a 6655 goto cp0_unimplemented;
9c2149c8
TS
6656 }
6657 break;
6658 case 28:
6659 switch (sel) {
6660 case 0:
6661 case 2:
6662 case 4:
6663 case 6:
7db13fae 6664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6665 rn = "TagLo";
6666 break;
6667 case 1:
6668 case 3:
6669 case 5:
6670 case 7:
7db13fae 6671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6672 rn = "DataLo";
6673 break;
6674 default:
f31b035a 6675 goto cp0_unimplemented;
9c2149c8
TS
6676 }
6677 break;
6678 case 29:
6679 switch (sel) {
6680 case 0:
6681 case 2:
6682 case 4:
6683 case 6:
7db13fae 6684 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6685 rn = "TagHi";
6686 break;
6687 case 1:
6688 case 3:
6689 case 5:
6690 case 7:
7db13fae 6691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6692 rn = "DataHi";
6693 break;
6694 default:
f31b035a 6695 goto cp0_unimplemented;
9c2149c8
TS
6696 }
6697 break;
6698 case 30:
6699 switch (sel) {
6700 case 0:
7db13fae 6701 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6702 rn = "ErrorEPC";
6703 break;
9c2149c8 6704 default:
f31b035a 6705 goto cp0_unimplemented;
9c2149c8
TS
6706 }
6707 break;
6708 case 31:
6709 switch (sel) {
6710 case 0:
f0b3f3ae 6711 /* EJTAG support */
7db13fae 6712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6713 rn = "DESAVE";
6714 break;
e98c0d17 6715 case 2 ... 7:
f31b035a
LA
6716 CP0_CHECK(ctx->kscrexist & (1 << sel));
6717 tcg_gen_ld_tl(arg, cpu_env,
6718 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6719 rn = "KScratch";
e98c0d17 6720 break;
9c2149c8 6721 default:
f31b035a 6722 goto cp0_unimplemented;
9c2149c8
TS
6723 }
6724 break;
6725 default:
f31b035a 6726 goto cp0_unimplemented;
9c2149c8 6727 }
2abf314d 6728 (void)rn; /* avoid a compiler warning */
d12d51d5 6729 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6730 return;
6731
f31b035a 6732cp0_unimplemented:
d12d51d5 6733 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6734 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6735}
6736
d75c135e 6737static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6738{
6739 const char *rn = "invalid";
6740
e189e748 6741 if (sel != 0)
d75c135e 6742 check_insn(ctx, ISA_MIPS64);
e189e748 6743
bd79255d 6744 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6745 gen_io_start();
bd79255d 6746 }
2e70f6ef 6747
9c2149c8
TS
6748 switch (reg) {
6749 case 0:
6750 switch (sel) {
6751 case 0:
895c2d04 6752 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6753 rn = "Index";
6754 break;
6755 case 1:
f31b035a 6756 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6757 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6758 rn = "MVPControl";
ead9360e 6759 break;
9c2149c8 6760 case 2:
f31b035a 6761 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6762 /* ignored */
9c2149c8 6763 rn = "MVPConf0";
ead9360e 6764 break;
9c2149c8 6765 case 3:
f31b035a 6766 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6767 /* ignored */
9c2149c8 6768 rn = "MVPConf1";
ead9360e 6769 break;
9c2149c8 6770 default:
f31b035a 6771 goto cp0_unimplemented;
9c2149c8
TS
6772 }
6773 break;
6774 case 1:
6775 switch (sel) {
6776 case 0:
2423f660 6777 /* ignored */
9c2149c8 6778 rn = "Random";
2423f660 6779 break;
9c2149c8 6780 case 1:
f31b035a 6781 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6782 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6783 rn = "VPEControl";
ead9360e 6784 break;
9c2149c8 6785 case 2:
f31b035a 6786 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6787 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6788 rn = "VPEConf0";
ead9360e 6789 break;
9c2149c8 6790 case 3:
f31b035a 6791 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6792 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6793 rn = "VPEConf1";
ead9360e 6794 break;
9c2149c8 6795 case 4:
f31b035a 6796 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6797 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6798 rn = "YQMask";
ead9360e 6799 break;
9c2149c8 6800 case 5:
f31b035a 6801 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6802 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6803 rn = "VPESchedule";
ead9360e 6804 break;
9c2149c8 6805 case 6:
f31b035a 6806 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6807 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6808 rn = "VPEScheFBack";
ead9360e 6809 break;
9c2149c8 6810 case 7:
f31b035a 6811 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6812 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6813 rn = "VPEOpt";
ead9360e 6814 break;
9c2149c8 6815 default:
f31b035a 6816 goto cp0_unimplemented;
9c2149c8
TS
6817 }
6818 break;
6819 case 2:
6820 switch (sel) {
6821 case 0:
7207c7f9 6822 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6823 rn = "EntryLo0";
6824 break;
9c2149c8 6825 case 1:
f31b035a 6826 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6827 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6828 rn = "TCStatus";
ead9360e 6829 break;
9c2149c8 6830 case 2:
f31b035a 6831 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6832 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6833 rn = "TCBind";
ead9360e 6834 break;
9c2149c8 6835 case 3:
f31b035a 6836 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6837 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6838 rn = "TCRestart";
ead9360e 6839 break;
9c2149c8 6840 case 4:
f31b035a 6841 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6842 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6843 rn = "TCHalt";
ead9360e 6844 break;
9c2149c8 6845 case 5:
f31b035a 6846 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6847 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6848 rn = "TCContext";
ead9360e 6849 break;
9c2149c8 6850 case 6:
f31b035a 6851 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6852 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6853 rn = "TCSchedule";
ead9360e 6854 break;
9c2149c8 6855 case 7:
f31b035a 6856 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6857 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6858 rn = "TCScheFBack";
ead9360e 6859 break;
9c2149c8 6860 default:
f31b035a 6861 goto cp0_unimplemented;
9c2149c8
TS
6862 }
6863 break;
6864 case 3:
6865 switch (sel) {
6866 case 0:
7207c7f9 6867 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6868 rn = "EntryLo1";
6869 break;
9c2149c8 6870 default:
f31b035a 6871 goto cp0_unimplemented;
876d4b07 6872 }
9c2149c8
TS
6873 break;
6874 case 4:
6875 switch (sel) {
6876 case 0:
895c2d04 6877 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6878 rn = "Context";
6879 break;
9c2149c8 6880 case 1:
895c2d04 6881// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6882 rn = "ContextConfig";
f31b035a 6883 goto cp0_unimplemented;
2423f660 6884// break;
d279279e 6885 case 2:
f31b035a
LA
6886 CP0_CHECK(ctx->ulri);
6887 tcg_gen_st_tl(arg, cpu_env,
6888 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6889 rn = "UserLocal";
d279279e 6890 break;
9c2149c8 6891 default:
f31b035a 6892 goto cp0_unimplemented;
876d4b07 6893 }
9c2149c8
TS
6894 break;
6895 case 5:
6896 switch (sel) {
6897 case 0:
895c2d04 6898 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6899 rn = "PageMask";
6900 break;
9c2149c8 6901 case 1:
d75c135e 6902 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6903 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6904 rn = "PageGrain";
6905 break;
9c2149c8 6906 default:
f31b035a 6907 goto cp0_unimplemented;
876d4b07 6908 }
9c2149c8
TS
6909 break;
6910 case 6:
6911 switch (sel) {
6912 case 0:
895c2d04 6913 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6914 rn = "Wired";
6915 break;
9c2149c8 6916 case 1:
d75c135e 6917 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6918 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6919 rn = "SRSConf0";
ead9360e 6920 break;
9c2149c8 6921 case 2:
d75c135e 6922 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6923 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6924 rn = "SRSConf1";
ead9360e 6925 break;
9c2149c8 6926 case 3:
d75c135e 6927 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6928 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6929 rn = "SRSConf2";
ead9360e 6930 break;
9c2149c8 6931 case 4:
d75c135e 6932 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6933 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6934 rn = "SRSConf3";
ead9360e 6935 break;
9c2149c8 6936 case 5:
d75c135e 6937 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6938 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6939 rn = "SRSConf4";
ead9360e 6940 break;
9c2149c8 6941 default:
f31b035a 6942 goto cp0_unimplemented;
876d4b07 6943 }
9c2149c8
TS
6944 break;
6945 case 7:
6946 switch (sel) {
6947 case 0:
d75c135e 6948 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6949 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6950 ctx->bstate = BS_STOP;
2423f660
TS
6951 rn = "HWREna";
6952 break;
9c2149c8 6953 default:
f31b035a 6954 goto cp0_unimplemented;
876d4b07 6955 }
9c2149c8
TS
6956 break;
6957 case 8:
aea14095
LA
6958 switch (sel) {
6959 case 0:
6960 /* ignored */
6961 rn = "BadVAddr";
6962 break;
6963 case 1:
6964 /* ignored */
6965 rn = "BadInstr";
6966 break;
6967 case 2:
6968 /* ignored */
6969 rn = "BadInstrP";
6970 break;
6971 default:
f31b035a 6972 goto cp0_unimplemented;
aea14095 6973 }
9c2149c8
TS
6974 break;
6975 case 9:
6976 switch (sel) {
6977 case 0:
895c2d04 6978 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6979 rn = "Count";
6980 break;
876d4b07 6981 /* 6,7 are implementation dependent */
9c2149c8 6982 default:
f31b035a 6983 goto cp0_unimplemented;
876d4b07
TS
6984 }
6985 /* Stop translation as we may have switched the execution mode */
6986 ctx->bstate = BS_STOP;
9c2149c8
TS
6987 break;
6988 case 10:
6989 switch (sel) {
6990 case 0:
895c2d04 6991 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6992 rn = "EntryHi";
6993 break;
9c2149c8 6994 default:
f31b035a 6995 goto cp0_unimplemented;
876d4b07 6996 }
9c2149c8
TS
6997 break;
6998 case 11:
6999 switch (sel) {
7000 case 0:
895c2d04 7001 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7002 rn = "Compare";
7003 break;
876d4b07 7004 /* 6,7 are implementation dependent */
9c2149c8 7005 default:
f31b035a 7006 goto cp0_unimplemented;
876d4b07 7007 }
de9a95f0
AJ
7008 /* Stop translation as we may have switched the execution mode */
7009 ctx->bstate = BS_STOP;
9c2149c8
TS
7010 break;
7011 case 12:
7012 switch (sel) {
7013 case 0:
867abc7e 7014 save_cpu_state(ctx, 1);
895c2d04 7015 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7016 /* BS_STOP isn't good enough here, hflags may have changed. */
7017 gen_save_pc(ctx->pc + 4);
7018 ctx->bstate = BS_EXCP;
2423f660
TS
7019 rn = "Status";
7020 break;
9c2149c8 7021 case 1:
d75c135e 7022 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7023 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7024 /* Stop translation as we may have switched the execution mode */
7025 ctx->bstate = BS_STOP;
2423f660
TS
7026 rn = "IntCtl";
7027 break;
9c2149c8 7028 case 2:
d75c135e 7029 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7030 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7031 /* Stop translation as we may have switched the execution mode */
7032 ctx->bstate = BS_STOP;
2423f660
TS
7033 rn = "SRSCtl";
7034 break;
9c2149c8 7035 case 3:
d75c135e 7036 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7037 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7038 /* Stop translation as we may have switched the execution mode */
7039 ctx->bstate = BS_STOP;
2423f660
TS
7040 rn = "SRSMap";
7041 break;
7042 default:
f31b035a 7043 goto cp0_unimplemented;
876d4b07 7044 }
9c2149c8
TS
7045 break;
7046 case 13:
7047 switch (sel) {
7048 case 0:
867abc7e 7049 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7050 /* Mark as an IO operation because we may trigger a software
7051 interrupt. */
bd79255d 7052 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7053 gen_io_start();
7054 }
895c2d04 7055 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7056 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7057 gen_io_end();
7058 }
7059 /* Stop translation as we may have triggered an intetrupt */
7060 ctx->bstate = BS_STOP;
2423f660
TS
7061 rn = "Cause";
7062 break;
9c2149c8 7063 default:
f31b035a 7064 goto cp0_unimplemented;
876d4b07 7065 }
9c2149c8
TS
7066 break;
7067 case 14:
7068 switch (sel) {
7069 case 0:
7db13fae 7070 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7071 rn = "EPC";
7072 break;
9c2149c8 7073 default:
f31b035a 7074 goto cp0_unimplemented;
876d4b07 7075 }
9c2149c8
TS
7076 break;
7077 case 15:
7078 switch (sel) {
7079 case 0:
2423f660
TS
7080 /* ignored */
7081 rn = "PRid";
7082 break;
9c2149c8 7083 case 1:
d75c135e 7084 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7085 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7086 rn = "EBase";
7087 break;
9c2149c8 7088 default:
f31b035a 7089 goto cp0_unimplemented;
876d4b07 7090 }
9c2149c8
TS
7091 break;
7092 case 16:
7093 switch (sel) {
7094 case 0:
895c2d04 7095 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7096 rn = "Config";
2423f660
TS
7097 /* Stop translation as we may have switched the execution mode */
7098 ctx->bstate = BS_STOP;
9c2149c8
TS
7099 break;
7100 case 1:
1fc7bf6e 7101 /* ignored, read only */
9c2149c8
TS
7102 rn = "Config1";
7103 break;
7104 case 2:
895c2d04 7105 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7106 rn = "Config2";
2423f660
TS
7107 /* Stop translation as we may have switched the execution mode */
7108 ctx->bstate = BS_STOP;
9c2149c8
TS
7109 break;
7110 case 3:
90f12d73 7111 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7112 rn = "Config3";
90f12d73
MR
7113 /* Stop translation as we may have switched the execution mode */
7114 ctx->bstate = BS_STOP;
9c2149c8 7115 break;
faf1f68b
LA
7116 case 4:
7117 /* currently ignored */
7118 rn = "Config4";
7119 break;
7120 case 5:
7121 gen_helper_mtc0_config5(cpu_env, arg);
7122 rn = "Config5";
7123 /* Stop translation as we may have switched the execution mode */
7124 ctx->bstate = BS_STOP;
7125 break;
9c2149c8
TS
7126 /* 6,7 are implementation dependent */
7127 default:
7128 rn = "Invalid config selector";
f31b035a 7129 goto cp0_unimplemented;
9c2149c8 7130 }
9c2149c8
TS
7131 break;
7132 case 17:
7133 switch (sel) {
7134 case 0:
895c2d04 7135 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7136 rn = "LLAddr";
7137 break;
9c2149c8 7138 default:
f31b035a 7139 goto cp0_unimplemented;
9c2149c8
TS
7140 }
7141 break;
7142 case 18:
7143 switch (sel) {
fd88b6ab 7144 case 0 ... 7:
895c2d04 7145 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7146 rn = "WatchLo";
7147 break;
9c2149c8 7148 default:
f31b035a 7149 goto cp0_unimplemented;
9c2149c8
TS
7150 }
7151 break;
7152 case 19:
7153 switch (sel) {
fd88b6ab 7154 case 0 ... 7:
895c2d04 7155 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7156 rn = "WatchHi";
7157 break;
9c2149c8 7158 default:
f31b035a 7159 goto cp0_unimplemented;
9c2149c8
TS
7160 }
7161 break;
7162 case 20:
7163 switch (sel) {
7164 case 0:
d75c135e 7165 check_insn(ctx, ISA_MIPS3);
895c2d04 7166 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7167 rn = "XContext";
7168 break;
9c2149c8 7169 default:
f31b035a 7170 goto cp0_unimplemented;
9c2149c8
TS
7171 }
7172 break;
7173 case 21:
7174 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7175 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7176 switch (sel) {
7177 case 0:
895c2d04 7178 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7179 rn = "Framemask";
7180 break;
9c2149c8 7181 default:
f31b035a 7182 goto cp0_unimplemented;
9c2149c8
TS
7183 }
7184 break;
7185 case 22:
7186 /* ignored */
7187 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7188 break;
9c2149c8
TS
7189 case 23:
7190 switch (sel) {
7191 case 0:
895c2d04 7192 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7193 /* BS_STOP isn't good enough here, hflags may have changed. */
7194 gen_save_pc(ctx->pc + 4);
7195 ctx->bstate = BS_EXCP;
2423f660
TS
7196 rn = "Debug";
7197 break;
9c2149c8 7198 case 1:
895c2d04 7199// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7200 /* Stop translation as we may have switched the execution mode */
7201 ctx->bstate = BS_STOP;
2423f660
TS
7202 rn = "TraceControl";
7203// break;
9c2149c8 7204 case 2:
895c2d04 7205// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7206 /* Stop translation as we may have switched the execution mode */
7207 ctx->bstate = BS_STOP;
2423f660
TS
7208 rn = "TraceControl2";
7209// break;
9c2149c8 7210 case 3:
895c2d04 7211// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7212 /* Stop translation as we may have switched the execution mode */
7213 ctx->bstate = BS_STOP;
2423f660
TS
7214 rn = "UserTraceData";
7215// break;
9c2149c8 7216 case 4:
895c2d04 7217// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7218 /* Stop translation as we may have switched the execution mode */
7219 ctx->bstate = BS_STOP;
2423f660
TS
7220 rn = "TraceBPC";
7221// break;
9c2149c8 7222 default:
f31b035a 7223 goto cp0_unimplemented;
9c2149c8 7224 }
9c2149c8
TS
7225 break;
7226 case 24:
7227 switch (sel) {
7228 case 0:
f1aa6320 7229 /* EJTAG support */
7db13fae 7230 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7231 rn = "DEPC";
7232 break;
9c2149c8 7233 default:
f31b035a 7234 goto cp0_unimplemented;
9c2149c8
TS
7235 }
7236 break;
7237 case 25:
7238 switch (sel) {
7239 case 0:
895c2d04 7240 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7241 rn = "Performance0";
7242 break;
9c2149c8 7243 case 1:
895c2d04 7244// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7245 rn = "Performance1";
7246// break;
9c2149c8 7247 case 2:
895c2d04 7248// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7249 rn = "Performance2";
7250// break;
9c2149c8 7251 case 3:
895c2d04 7252// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7253 rn = "Performance3";
7254// break;
9c2149c8 7255 case 4:
895c2d04 7256// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7257 rn = "Performance4";
7258// break;
9c2149c8 7259 case 5:
895c2d04 7260// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7261 rn = "Performance5";
7262// break;
9c2149c8 7263 case 6:
895c2d04 7264// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7265 rn = "Performance6";
7266// break;
9c2149c8 7267 case 7:
895c2d04 7268// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7269 rn = "Performance7";
7270// break;
9c2149c8 7271 default:
f31b035a 7272 goto cp0_unimplemented;
9c2149c8 7273 }
876d4b07 7274 break;
9c2149c8 7275 case 26:
876d4b07 7276 /* ignored */
9c2149c8 7277 rn = "ECC";
876d4b07 7278 break;
9c2149c8
TS
7279 case 27:
7280 switch (sel) {
7281 case 0 ... 3:
2423f660
TS
7282 /* ignored */
7283 rn = "CacheErr";
7284 break;
9c2149c8 7285 default:
f31b035a 7286 goto cp0_unimplemented;
9c2149c8 7287 }
876d4b07 7288 break;
9c2149c8
TS
7289 case 28:
7290 switch (sel) {
7291 case 0:
7292 case 2:
7293 case 4:
7294 case 6:
895c2d04 7295 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7296 rn = "TagLo";
7297 break;
7298 case 1:
7299 case 3:
7300 case 5:
7301 case 7:
895c2d04 7302 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7303 rn = "DataLo";
7304 break;
7305 default:
f31b035a 7306 goto cp0_unimplemented;
9c2149c8
TS
7307 }
7308 break;
7309 case 29:
7310 switch (sel) {
7311 case 0:
7312 case 2:
7313 case 4:
7314 case 6:
895c2d04 7315 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7316 rn = "TagHi";
7317 break;
7318 case 1:
7319 case 3:
7320 case 5:
7321 case 7:
895c2d04 7322 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7323 rn = "DataHi";
7324 break;
7325 default:
7326 rn = "invalid sel";
f31b035a 7327 goto cp0_unimplemented;
9c2149c8 7328 }
876d4b07 7329 break;
9c2149c8
TS
7330 case 30:
7331 switch (sel) {
7332 case 0:
7db13fae 7333 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7334 rn = "ErrorEPC";
7335 break;
9c2149c8 7336 default:
f31b035a 7337 goto cp0_unimplemented;
9c2149c8
TS
7338 }
7339 break;
7340 case 31:
7341 switch (sel) {
7342 case 0:
f1aa6320 7343 /* EJTAG support */
7db13fae 7344 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7345 rn = "DESAVE";
7346 break;
e98c0d17 7347 case 2 ... 7:
f31b035a
LA
7348 CP0_CHECK(ctx->kscrexist & (1 << sel));
7349 tcg_gen_st_tl(arg, cpu_env,
7350 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7351 rn = "KScratch";
e98c0d17 7352 break;
9c2149c8 7353 default:
f31b035a 7354 goto cp0_unimplemented;
9c2149c8 7355 }
876d4b07
TS
7356 /* Stop translation as we may have switched the execution mode */
7357 ctx->bstate = BS_STOP;
9c2149c8
TS
7358 break;
7359 default:
f31b035a 7360 goto cp0_unimplemented;
9c2149c8 7361 }
2abf314d 7362 (void)rn; /* avoid a compiler warning */
d12d51d5 7363 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7364 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7365 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7366 gen_io_end();
7367 ctx->bstate = BS_STOP;
7368 }
9c2149c8
TS
7369 return;
7370
f31b035a 7371cp0_unimplemented:
d12d51d5 7372 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7373}
d26bc211 7374#endif /* TARGET_MIPS64 */
9c2149c8 7375
7db13fae 7376static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7377 int u, int sel, int h)
7378{
7379 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7380 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7381
7382 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7383 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7384 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7385 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7386 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7387 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7388 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7389 else if (u == 0) {
7390 switch (rt) {
5a25ce94
EI
7391 case 1:
7392 switch (sel) {
7393 case 1:
895c2d04 7394 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7395 break;
7396 case 2:
895c2d04 7397 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7398 break;
7399 default:
7400 goto die;
7401 break;
7402 }
7403 break;
ead9360e
TS
7404 case 2:
7405 switch (sel) {
7406 case 1:
895c2d04 7407 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7408 break;
7409 case 2:
895c2d04 7410 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7411 break;
7412 case 3:
895c2d04 7413 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7414 break;
7415 case 4:
895c2d04 7416 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7417 break;
7418 case 5:
895c2d04 7419 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7420 break;
7421 case 6:
895c2d04 7422 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7423 break;
7424 case 7:
895c2d04 7425 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7426 break;
7427 default:
d75c135e 7428 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7429 break;
7430 }
7431 break;
7432 case 10:
7433 switch (sel) {
7434 case 0:
895c2d04 7435 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7436 break;
7437 default:
d75c135e 7438 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7439 break;
7440 }
7441 case 12:
7442 switch (sel) {
7443 case 0:
895c2d04 7444 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7445 break;
7446 default:
d75c135e 7447 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7448 break;
7449 }
5a25ce94
EI
7450 case 13:
7451 switch (sel) {
7452 case 0:
895c2d04 7453 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7454 break;
7455 default:
7456 goto die;
7457 break;
7458 }
7459 break;
7460 case 14:
7461 switch (sel) {
7462 case 0:
895c2d04 7463 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7464 break;
7465 default:
7466 goto die;
7467 break;
7468 }
7469 break;
7470 case 15:
7471 switch (sel) {
7472 case 1:
895c2d04 7473 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7474 break;
7475 default:
7476 goto die;
7477 break;
7478 }
7479 break;
7480 case 16:
7481 switch (sel) {
7482 case 0 ... 7:
895c2d04 7483 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7484 break;
7485 default:
7486 goto die;
7487 break;
7488 }
7489 break;
ead9360e
TS
7490 case 23:
7491 switch (sel) {
7492 case 0:
895c2d04 7493 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7494 break;
7495 default:
d75c135e 7496 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7497 break;
7498 }
7499 break;
7500 default:
d75c135e 7501 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7502 }
7503 } else switch (sel) {
7504 /* GPR registers. */
7505 case 0:
895c2d04 7506 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7507 break;
7508 /* Auxiliary CPU registers */
7509 case 1:
7510 switch (rt) {
7511 case 0:
895c2d04 7512 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7513 break;
7514 case 1:
895c2d04 7515 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7516 break;
7517 case 2:
895c2d04 7518 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7519 break;
7520 case 4:
895c2d04 7521 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7522 break;
7523 case 5:
895c2d04 7524 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7525 break;
7526 case 6:
895c2d04 7527 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7528 break;
7529 case 8:
895c2d04 7530 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7531 break;
7532 case 9:
895c2d04 7533 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7534 break;
7535 case 10:
895c2d04 7536 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7537 break;
7538 case 12:
895c2d04 7539 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7540 break;
7541 case 13:
895c2d04 7542 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7543 break;
7544 case 14:
895c2d04 7545 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7546 break;
7547 case 16:
895c2d04 7548 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7549 break;
7550 default:
7551 goto die;
7552 }
7553 break;
7554 /* Floating point (COP1). */
7555 case 2:
7556 /* XXX: For now we support only a single FPU context. */
7557 if (h == 0) {
a7812ae4 7558 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7559
7560 gen_load_fpr32(fp0, rt);
7561 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7562 tcg_temp_free_i32(fp0);
ead9360e 7563 } else {
a7812ae4 7564 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7565
7f6613ce 7566 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7567 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7568 tcg_temp_free_i32(fp0);
ead9360e
TS
7569 }
7570 break;
7571 case 3:
7572 /* XXX: For now we support only a single FPU context. */
895c2d04 7573 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7574 break;
7575 /* COP2: Not implemented. */
7576 case 4:
7577 case 5:
7578 /* fall through */
7579 default:
7580 goto die;
7581 }
d12d51d5 7582 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7583 gen_store_gpr(t0, rd);
7584 tcg_temp_free(t0);
ead9360e
TS
7585 return;
7586
7587die:
1a3fd9c3 7588 tcg_temp_free(t0);
d12d51d5 7589 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7590 generate_exception(ctx, EXCP_RI);
7591}
7592
7db13fae 7593static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7594 int u, int sel, int h)
7595{
7596 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7597 TCGv t0 = tcg_temp_local_new();
ead9360e 7598
1a3fd9c3 7599 gen_load_gpr(t0, rt);
ead9360e 7600 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7601 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7602 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7603 /* NOP */ ;
7604 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7605 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7606 /* NOP */ ;
7607 else if (u == 0) {
7608 switch (rd) {
5a25ce94
EI
7609 case 1:
7610 switch (sel) {
7611 case 1:
895c2d04 7612 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7613 break;
7614 case 2:
895c2d04 7615 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7616 break;
7617 default:
7618 goto die;
7619 break;
7620 }
7621 break;
ead9360e
TS
7622 case 2:
7623 switch (sel) {
7624 case 1:
895c2d04 7625 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7626 break;
7627 case 2:
895c2d04 7628 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7629 break;
7630 case 3:
895c2d04 7631 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7632 break;
7633 case 4:
895c2d04 7634 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7635 break;
7636 case 5:
895c2d04 7637 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7638 break;
7639 case 6:
895c2d04 7640 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7641 break;
7642 case 7:
895c2d04 7643 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7644 break;
7645 default:
d75c135e 7646 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7647 break;
7648 }
7649 break;
7650 case 10:
7651 switch (sel) {
7652 case 0:
895c2d04 7653 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7654 break;
7655 default:
d75c135e 7656 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7657 break;
7658 }
7659 case 12:
7660 switch (sel) {
7661 case 0:
895c2d04 7662 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7663 break;
7664 default:
d75c135e 7665 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7666 break;
7667 }
5a25ce94
EI
7668 case 13:
7669 switch (sel) {
7670 case 0:
895c2d04 7671 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7672 break;
7673 default:
7674 goto die;
7675 break;
7676 }
7677 break;
7678 case 15:
7679 switch (sel) {
7680 case 1:
895c2d04 7681 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7682 break;
7683 default:
7684 goto die;
7685 break;
7686 }
7687 break;
ead9360e
TS
7688 case 23:
7689 switch (sel) {
7690 case 0:
895c2d04 7691 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7692 break;
7693 default:
d75c135e 7694 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7695 break;
7696 }
7697 break;
7698 default:
d75c135e 7699 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7700 }
7701 } else switch (sel) {
7702 /* GPR registers. */
7703 case 0:
895c2d04 7704 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7705 break;
7706 /* Auxiliary CPU registers */
7707 case 1:
7708 switch (rd) {
7709 case 0:
895c2d04 7710 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7711 break;
7712 case 1:
895c2d04 7713 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7714 break;
7715 case 2:
895c2d04 7716 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7717 break;
7718 case 4:
895c2d04 7719 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7720 break;
7721 case 5:
895c2d04 7722 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7723 break;
7724 case 6:
895c2d04 7725 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7726 break;
7727 case 8:
895c2d04 7728 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7729 break;
7730 case 9:
895c2d04 7731 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7732 break;
7733 case 10:
895c2d04 7734 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7735 break;
7736 case 12:
895c2d04 7737 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7738 break;
7739 case 13:
895c2d04 7740 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7741 break;
7742 case 14:
895c2d04 7743 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7744 break;
7745 case 16:
895c2d04 7746 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7747 break;
7748 default:
7749 goto die;
7750 }
7751 break;
7752 /* Floating point (COP1). */
7753 case 2:
7754 /* XXX: For now we support only a single FPU context. */
7755 if (h == 0) {
a7812ae4 7756 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7757
7758 tcg_gen_trunc_tl_i32(fp0, t0);
7759 gen_store_fpr32(fp0, rd);
a7812ae4 7760 tcg_temp_free_i32(fp0);
ead9360e 7761 } else {
a7812ae4 7762 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7763
7764 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7765 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7766 tcg_temp_free_i32(fp0);
ead9360e
TS
7767 }
7768 break;
7769 case 3:
7770 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7771 save_cpu_state(ctx, 1);
736d120a
PJ
7772 {
7773 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7774
7775 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7776 tcg_temp_free_i32(fs_tmp);
7777 }
4cf8a45f
YK
7778 /* Stop translation as we may have changed hflags */
7779 ctx->bstate = BS_STOP;
ead9360e
TS
7780 break;
7781 /* COP2: Not implemented. */
7782 case 4:
7783 case 5:
7784 /* fall through */
7785 default:
7786 goto die;
7787 }
d12d51d5 7788 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7789 tcg_temp_free(t0);
ead9360e
TS
7790 return;
7791
7792die:
1a3fd9c3 7793 tcg_temp_free(t0);
d12d51d5 7794 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7795 generate_exception(ctx, EXCP_RI);
7796}
7797
7db13fae 7798static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7799{
287c4b84 7800 const char *opn = "ldst";
6af0bf9c 7801
2e15497c 7802 check_cp0_enabled(ctx);
6af0bf9c
FB
7803 switch (opc) {
7804 case OPC_MFC0:
7805 if (rt == 0) {
ead9360e 7806 /* Treat as NOP. */
6af0bf9c
FB
7807 return;
7808 }
d75c135e 7809 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7810 opn = "mfc0";
7811 break;
7812 case OPC_MTC0:
1a3fd9c3 7813 {
1fc7bf6e 7814 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7815
7816 gen_load_gpr(t0, rt);
d75c135e 7817 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7818 tcg_temp_free(t0);
7819 }
6af0bf9c
FB
7820 opn = "mtc0";
7821 break;
d26bc211 7822#if defined(TARGET_MIPS64)
9c2149c8 7823 case OPC_DMFC0:
d75c135e 7824 check_insn(ctx, ISA_MIPS3);
9c2149c8 7825 if (rt == 0) {
ead9360e 7826 /* Treat as NOP. */
9c2149c8
TS
7827 return;
7828 }
d75c135e 7829 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7830 opn = "dmfc0";
7831 break;
7832 case OPC_DMTC0:
d75c135e 7833 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7834 {
1fc7bf6e 7835 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7836
7837 gen_load_gpr(t0, rt);
d75c135e 7838 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7839 tcg_temp_free(t0);
7840 }
9c2149c8
TS
7841 opn = "dmtc0";
7842 break;
534ce69f 7843#endif
ead9360e 7844 case OPC_MFTR:
d75c135e 7845 check_insn(ctx, ASE_MT);
ead9360e
TS
7846 if (rd == 0) {
7847 /* Treat as NOP. */
7848 return;
7849 }
6c5c1e20 7850 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7851 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7852 opn = "mftr";
7853 break;
7854 case OPC_MTTR:
d75c135e 7855 check_insn(ctx, ASE_MT);
6c5c1e20 7856 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7857 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7858 opn = "mttr";
7859 break;
6af0bf9c 7860 case OPC_TLBWI:
6af0bf9c 7861 opn = "tlbwi";
c01fccd2 7862 if (!env->tlb->helper_tlbwi)
29929e34 7863 goto die;
895c2d04 7864 gen_helper_tlbwi(cpu_env);
6af0bf9c 7865 break;
9456c2fb
LA
7866 case OPC_TLBINV:
7867 opn = "tlbinv";
7868 if (ctx->ie >= 2) {
7869 if (!env->tlb->helper_tlbinv) {
7870 goto die;
7871 }
7872 gen_helper_tlbinv(cpu_env);
7873 } /* treat as nop if TLBINV not supported */
7874 break;
7875 case OPC_TLBINVF:
7876 opn = "tlbinvf";
7877 if (ctx->ie >= 2) {
7878 if (!env->tlb->helper_tlbinvf) {
7879 goto die;
7880 }
7881 gen_helper_tlbinvf(cpu_env);
7882 } /* treat as nop if TLBINV not supported */
7883 break;
6af0bf9c 7884 case OPC_TLBWR:
6af0bf9c 7885 opn = "tlbwr";
c01fccd2 7886 if (!env->tlb->helper_tlbwr)
29929e34 7887 goto die;
895c2d04 7888 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7889 break;
7890 case OPC_TLBP:
6af0bf9c 7891 opn = "tlbp";
c01fccd2 7892 if (!env->tlb->helper_tlbp)
29929e34 7893 goto die;
895c2d04 7894 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7895 break;
7896 case OPC_TLBR:
6af0bf9c 7897 opn = "tlbr";
c01fccd2 7898 if (!env->tlb->helper_tlbr)
29929e34 7899 goto die;
895c2d04 7900 gen_helper_tlbr(cpu_env);
6af0bf9c 7901 break;
6af0bf9c
FB
7902 case OPC_ERET:
7903 opn = "eret";
d75c135e 7904 check_insn(ctx, ISA_MIPS2);
339cd2a8
LA
7905 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7906 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7907 MIPS_DEBUG("CTI in delay / forbidden slot");
7908 goto die;
7909 }
895c2d04 7910 gen_helper_eret(cpu_env);
6af0bf9c
FB
7911 ctx->bstate = BS_EXCP;
7912 break;
7913 case OPC_DERET:
7914 opn = "deret";
d75c135e 7915 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7916 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7917 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7918 MIPS_DEBUG("CTI in delay / forbidden slot");
7919 goto die;
7920 }
6af0bf9c 7921 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7922 MIPS_INVAL(opn);
6af0bf9c
FB
7923 generate_exception(ctx, EXCP_RI);
7924 } else {
895c2d04 7925 gen_helper_deret(cpu_env);
6af0bf9c
FB
7926 ctx->bstate = BS_EXCP;
7927 }
7928 break;
4ad40f36
FB
7929 case OPC_WAIT:
7930 opn = "wait";
d75c135e 7931 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7932 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7933 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7934 MIPS_DEBUG("CTI in delay / forbidden slot");
7935 goto die;
7936 }
4ad40f36
FB
7937 /* If we get an exception, we want to restart at next instruction */
7938 ctx->pc += 4;
7939 save_cpu_state(ctx, 1);
7940 ctx->pc -= 4;
895c2d04 7941 gen_helper_wait(cpu_env);
4ad40f36
FB
7942 ctx->bstate = BS_EXCP;
7943 break;
6af0bf9c 7944 default:
29929e34 7945 die:
923617a3 7946 MIPS_INVAL(opn);
6af0bf9c
FB
7947 generate_exception(ctx, EXCP_RI);
7948 return;
7949 }
2abf314d 7950 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7951 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7952}
f1aa6320 7953#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7954
6ea83fed 7955/* CP1 Branches (before delay slot) */
d75c135e
AJ
7956static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7957 int32_t cc, int32_t offset)
6ea83fed
FB
7958{
7959 target_ulong btarget;
923617a3 7960 const char *opn = "cp1 cond branch";
a7812ae4 7961 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7962
339cd2a8
LA
7963 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7964 MIPS_DEBUG("CTI in delay / forbidden slot");
7965 generate_exception(ctx, EXCP_RI);
7966 goto out;
7967 }
7968
e189e748 7969 if (cc != 0)
d75c135e 7970 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7971
6ea83fed
FB
7972 btarget = ctx->pc + 4 + offset;
7973
7a387fff
TS
7974 switch (op) {
7975 case OPC_BC1F:
d94536f4
AJ
7976 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7977 tcg_gen_not_i32(t0, t0);
7978 tcg_gen_andi_i32(t0, t0, 1);
7979 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7980 opn = "bc1f";
6ea83fed 7981 goto not_likely;
7a387fff 7982 case OPC_BC1FL:
d94536f4
AJ
7983 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7984 tcg_gen_not_i32(t0, t0);
7985 tcg_gen_andi_i32(t0, t0, 1);
7986 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7987 opn = "bc1fl";
6ea83fed 7988 goto likely;
7a387fff 7989 case OPC_BC1T:
d94536f4
AJ
7990 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7991 tcg_gen_andi_i32(t0, t0, 1);
7992 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7993 opn = "bc1t";
5a5012ec 7994 goto not_likely;
7a387fff 7995 case OPC_BC1TL:
d94536f4
AJ
7996 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7997 tcg_gen_andi_i32(t0, t0, 1);
7998 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7999 opn = "bc1tl";
6ea83fed
FB
8000 likely:
8001 ctx->hflags |= MIPS_HFLAG_BL;
8002 break;
5a5012ec 8003 case OPC_BC1FANY2:
a16336e4 8004 {
d94536f4
AJ
8005 TCGv_i32 t1 = tcg_temp_new_i32();
8006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8007 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8008 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8009 tcg_temp_free_i32(t1);
d94536f4
AJ
8010 tcg_gen_andi_i32(t0, t0, 1);
8011 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8012 }
fd4a04eb 8013 opn = "bc1any2f";
5a5012ec
TS
8014 goto not_likely;
8015 case OPC_BC1TANY2:
a16336e4 8016 {
d94536f4
AJ
8017 TCGv_i32 t1 = tcg_temp_new_i32();
8018 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8019 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8020 tcg_gen_or_i32(t0, t0, t1);
8021 tcg_temp_free_i32(t1);
8022 tcg_gen_andi_i32(t0, t0, 1);
8023 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8024 }
fd4a04eb 8025 opn = "bc1any2t";
5a5012ec
TS
8026 goto not_likely;
8027 case OPC_BC1FANY4:
a16336e4 8028 {
d94536f4
AJ
8029 TCGv_i32 t1 = tcg_temp_new_i32();
8030 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8032 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8034 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8036 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8037 tcg_temp_free_i32(t1);
d94536f4
AJ
8038 tcg_gen_andi_i32(t0, t0, 1);
8039 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8040 }
fd4a04eb 8041 opn = "bc1any4f";
5a5012ec
TS
8042 goto not_likely;
8043 case OPC_BC1TANY4:
a16336e4 8044 {
d94536f4
AJ
8045 TCGv_i32 t1 = tcg_temp_new_i32();
8046 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8047 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8048 tcg_gen_or_i32(t0, t0, t1);
8049 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8050 tcg_gen_or_i32(t0, t0, t1);
8051 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8052 tcg_gen_or_i32(t0, t0, t1);
8053 tcg_temp_free_i32(t1);
8054 tcg_gen_andi_i32(t0, t0, 1);
8055 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8056 }
fd4a04eb 8057 opn = "bc1any4t";
5a5012ec
TS
8058 not_likely:
8059 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8060 break;
8061 default:
923617a3 8062 MIPS_INVAL(opn);
e397ee33 8063 generate_exception (ctx, EXCP_RI);
6c5c1e20 8064 goto out;
6ea83fed 8065 }
2abf314d 8066 (void)opn; /* avoid a compiler warning */
923617a3 8067 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8068 ctx->hflags, btarget);
8069 ctx->btarget = btarget;
b231c103 8070 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8071 out:
a7812ae4 8072 tcg_temp_free_i32(t0);
6ea83fed
FB
8073}
8074
31837be3
YK
8075/* R6 CP1 Branches */
8076static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8077 int32_t ft, int32_t offset)
8078{
8079 target_ulong btarget;
8080 const char *opn = "cp1 cond branch";
8081 TCGv_i64 t0 = tcg_temp_new_i64();
8082
8083 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8084#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8085 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8086 "\n", ctx->pc);
31837be3
YK
8087#endif
8088 generate_exception(ctx, EXCP_RI);
8089 goto out;
8090 }
8091
8092 gen_load_fpr64(ctx, t0, ft);
8093 tcg_gen_andi_i64(t0, t0, 1);
8094
8095 btarget = addr_add(ctx, ctx->pc + 4, offset);
8096
8097 switch (op) {
8098 case OPC_BC1EQZ:
8099 tcg_gen_xori_i64(t0, t0, 1);
8100 opn = "bc1eqz";
8101 ctx->hflags |= MIPS_HFLAG_BC;
8102 break;
8103 case OPC_BC1NEZ:
8104 /* t0 already set */
8105 opn = "bc1nez";
8106 ctx->hflags |= MIPS_HFLAG_BC;
8107 break;
8108 default:
8109 MIPS_INVAL(opn);
8110 generate_exception(ctx, EXCP_RI);
8111 goto out;
8112 }
8113
8114 tcg_gen_trunc_i64_tl(bcond, t0);
8115
8116 (void)opn; /* avoid a compiler warning */
8117 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8118 ctx->hflags, btarget);
8119 ctx->btarget = btarget;
85479575 8120 ctx->hflags |= MIPS_HFLAG_BDS32;
31837be3
YK
8121
8122out:
8123 tcg_temp_free_i64(t0);
8124}
8125
6af0bf9c 8126/* Coprocessor 1 (FPU) */
5a5012ec 8127
5a5012ec
TS
8128#define FOP(func, fmt) (((fmt) << 21) | (func))
8129
bf4120ad
NF
8130enum fopcode {
8131 OPC_ADD_S = FOP(0, FMT_S),
8132 OPC_SUB_S = FOP(1, FMT_S),
8133 OPC_MUL_S = FOP(2, FMT_S),
8134 OPC_DIV_S = FOP(3, FMT_S),
8135 OPC_SQRT_S = FOP(4, FMT_S),
8136 OPC_ABS_S = FOP(5, FMT_S),
8137 OPC_MOV_S = FOP(6, FMT_S),
8138 OPC_NEG_S = FOP(7, FMT_S),
8139 OPC_ROUND_L_S = FOP(8, FMT_S),
8140 OPC_TRUNC_L_S = FOP(9, FMT_S),
8141 OPC_CEIL_L_S = FOP(10, FMT_S),
8142 OPC_FLOOR_L_S = FOP(11, FMT_S),
8143 OPC_ROUND_W_S = FOP(12, FMT_S),
8144 OPC_TRUNC_W_S = FOP(13, FMT_S),
8145 OPC_CEIL_W_S = FOP(14, FMT_S),
8146 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8147 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8148 OPC_MOVCF_S = FOP(17, FMT_S),
8149 OPC_MOVZ_S = FOP(18, FMT_S),
8150 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8151 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8152 OPC_RECIP_S = FOP(21, FMT_S),
8153 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8154 OPC_SELNEZ_S = FOP(23, FMT_S),
8155 OPC_MADDF_S = FOP(24, FMT_S),
8156 OPC_MSUBF_S = FOP(25, FMT_S),
8157 OPC_RINT_S = FOP(26, FMT_S),
8158 OPC_CLASS_S = FOP(27, FMT_S),
8159 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8160 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8161 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8162 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8163 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8164 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8165 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8166 OPC_RSQRT2_S = FOP(31, FMT_S),
8167 OPC_CVT_D_S = FOP(33, FMT_S),
8168 OPC_CVT_W_S = FOP(36, FMT_S),
8169 OPC_CVT_L_S = FOP(37, FMT_S),
8170 OPC_CVT_PS_S = FOP(38, FMT_S),
8171 OPC_CMP_F_S = FOP (48, FMT_S),
8172 OPC_CMP_UN_S = FOP (49, FMT_S),
8173 OPC_CMP_EQ_S = FOP (50, FMT_S),
8174 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8175 OPC_CMP_OLT_S = FOP (52, FMT_S),
8176 OPC_CMP_ULT_S = FOP (53, FMT_S),
8177 OPC_CMP_OLE_S = FOP (54, FMT_S),
8178 OPC_CMP_ULE_S = FOP (55, FMT_S),
8179 OPC_CMP_SF_S = FOP (56, FMT_S),
8180 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8181 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8182 OPC_CMP_NGL_S = FOP (59, FMT_S),
8183 OPC_CMP_LT_S = FOP (60, FMT_S),
8184 OPC_CMP_NGE_S = FOP (61, FMT_S),
8185 OPC_CMP_LE_S = FOP (62, FMT_S),
8186 OPC_CMP_NGT_S = FOP (63, FMT_S),
8187
8188 OPC_ADD_D = FOP(0, FMT_D),
8189 OPC_SUB_D = FOP(1, FMT_D),
8190 OPC_MUL_D = FOP(2, FMT_D),
8191 OPC_DIV_D = FOP(3, FMT_D),
8192 OPC_SQRT_D = FOP(4, FMT_D),
8193 OPC_ABS_D = FOP(5, FMT_D),
8194 OPC_MOV_D = FOP(6, FMT_D),
8195 OPC_NEG_D = FOP(7, FMT_D),
8196 OPC_ROUND_L_D = FOP(8, FMT_D),
8197 OPC_TRUNC_L_D = FOP(9, FMT_D),
8198 OPC_CEIL_L_D = FOP(10, FMT_D),
8199 OPC_FLOOR_L_D = FOP(11, FMT_D),
8200 OPC_ROUND_W_D = FOP(12, FMT_D),
8201 OPC_TRUNC_W_D = FOP(13, FMT_D),
8202 OPC_CEIL_W_D = FOP(14, FMT_D),
8203 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8204 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8205 OPC_MOVCF_D = FOP(17, FMT_D),
8206 OPC_MOVZ_D = FOP(18, FMT_D),
8207 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8208 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8209 OPC_RECIP_D = FOP(21, FMT_D),
8210 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8211 OPC_SELNEZ_D = FOP(23, FMT_D),
8212 OPC_MADDF_D = FOP(24, FMT_D),
8213 OPC_MSUBF_D = FOP(25, FMT_D),
8214 OPC_RINT_D = FOP(26, FMT_D),
8215 OPC_CLASS_D = FOP(27, FMT_D),
8216 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8217 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8218 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8219 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8220 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8221 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8222 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8223 OPC_RSQRT2_D = FOP(31, FMT_D),
8224 OPC_CVT_S_D = FOP(32, FMT_D),
8225 OPC_CVT_W_D = FOP(36, FMT_D),
8226 OPC_CVT_L_D = FOP(37, FMT_D),
8227 OPC_CMP_F_D = FOP (48, FMT_D),
8228 OPC_CMP_UN_D = FOP (49, FMT_D),
8229 OPC_CMP_EQ_D = FOP (50, FMT_D),
8230 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8231 OPC_CMP_OLT_D = FOP (52, FMT_D),
8232 OPC_CMP_ULT_D = FOP (53, FMT_D),
8233 OPC_CMP_OLE_D = FOP (54, FMT_D),
8234 OPC_CMP_ULE_D = FOP (55, FMT_D),
8235 OPC_CMP_SF_D = FOP (56, FMT_D),
8236 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8237 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8238 OPC_CMP_NGL_D = FOP (59, FMT_D),
8239 OPC_CMP_LT_D = FOP (60, FMT_D),
8240 OPC_CMP_NGE_D = FOP (61, FMT_D),
8241 OPC_CMP_LE_D = FOP (62, FMT_D),
8242 OPC_CMP_NGT_D = FOP (63, FMT_D),
8243
8244 OPC_CVT_S_W = FOP(32, FMT_W),
8245 OPC_CVT_D_W = FOP(33, FMT_W),
8246 OPC_CVT_S_L = FOP(32, FMT_L),
8247 OPC_CVT_D_L = FOP(33, FMT_L),
8248 OPC_CVT_PS_PW = FOP(38, FMT_W),
8249
8250 OPC_ADD_PS = FOP(0, FMT_PS),
8251 OPC_SUB_PS = FOP(1, FMT_PS),
8252 OPC_MUL_PS = FOP(2, FMT_PS),
8253 OPC_DIV_PS = FOP(3, FMT_PS),
8254 OPC_ABS_PS = FOP(5, FMT_PS),
8255 OPC_MOV_PS = FOP(6, FMT_PS),
8256 OPC_NEG_PS = FOP(7, FMT_PS),
8257 OPC_MOVCF_PS = FOP(17, FMT_PS),
8258 OPC_MOVZ_PS = FOP(18, FMT_PS),
8259 OPC_MOVN_PS = FOP(19, FMT_PS),
8260 OPC_ADDR_PS = FOP(24, FMT_PS),
8261 OPC_MULR_PS = FOP(26, FMT_PS),
8262 OPC_RECIP2_PS = FOP(28, FMT_PS),
8263 OPC_RECIP1_PS = FOP(29, FMT_PS),
8264 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8265 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8266
8267 OPC_CVT_S_PU = FOP(32, FMT_PS),
8268 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8269 OPC_CVT_S_PL = FOP(40, FMT_PS),
8270 OPC_PLL_PS = FOP(44, FMT_PS),
8271 OPC_PLU_PS = FOP(45, FMT_PS),
8272 OPC_PUL_PS = FOP(46, FMT_PS),
8273 OPC_PUU_PS = FOP(47, FMT_PS),
8274 OPC_CMP_F_PS = FOP (48, FMT_PS),
8275 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8276 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8277 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8278 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8279 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8280 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8281 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8282 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8283 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8284 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8285 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8286 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8287 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8288 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8289 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8290};
8291
3f493883
YK
8292enum r6_f_cmp_op {
8293 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8294 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8295 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8296 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8297 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8298 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8299 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8300 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8301 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8302 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8303 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8304 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8305 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8306 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8307 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8308 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8309 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8310 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8311 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8312 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8313 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8314 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8315
8316 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8317 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8318 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8319 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8320 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8321 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8322 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8323 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8324 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8325 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8326 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8327 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8328 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8329 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8330 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8331 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8332 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8333 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8334 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8335 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8336 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8337 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8338};
7a387fff 8339static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8340{
923617a3 8341 const char *opn = "cp1 move";
72c3a3ee 8342 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8343
8344 switch (opc) {
8345 case OPC_MFC1:
b6d96bed 8346 {
a7812ae4 8347 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8348
8349 gen_load_fpr32(fp0, fs);
8350 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8351 tcg_temp_free_i32(fp0);
6958549d 8352 }
6c5c1e20 8353 gen_store_gpr(t0, rt);
6ea83fed
FB
8354 opn = "mfc1";
8355 break;
8356 case OPC_MTC1:
6c5c1e20 8357 gen_load_gpr(t0, rt);
b6d96bed 8358 {
a7812ae4 8359 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8360
8361 tcg_gen_trunc_tl_i32(fp0, t0);
8362 gen_store_fpr32(fp0, fs);
a7812ae4 8363 tcg_temp_free_i32(fp0);
6958549d 8364 }
6ea83fed
FB
8365 opn = "mtc1";
8366 break;
8367 case OPC_CFC1:
895c2d04 8368 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8369 gen_store_gpr(t0, rt);
6ea83fed
FB
8370 opn = "cfc1";
8371 break;
8372 case OPC_CTC1:
6c5c1e20 8373 gen_load_gpr(t0, rt);
4cf8a45f 8374 save_cpu_state(ctx, 1);
736d120a
PJ
8375 {
8376 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8377
8378 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8379 tcg_temp_free_i32(fs_tmp);
8380 }
4cf8a45f
YK
8381 /* Stop translation as we may have changed hflags */
8382 ctx->bstate = BS_STOP;
6ea83fed
FB
8383 opn = "ctc1";
8384 break;
72c3a3ee 8385#if defined(TARGET_MIPS64)
9c2149c8 8386 case OPC_DMFC1:
72c3a3ee 8387 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8388 gen_store_gpr(t0, rt);
5a5012ec
TS
8389 opn = "dmfc1";
8390 break;
9c2149c8 8391 case OPC_DMTC1:
6c5c1e20 8392 gen_load_gpr(t0, rt);
72c3a3ee 8393 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8394 opn = "dmtc1";
8395 break;
72c3a3ee 8396#endif
5a5012ec 8397 case OPC_MFHC1:
b6d96bed 8398 {
a7812ae4 8399 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8400
7f6613ce 8401 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8402 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8403 tcg_temp_free_i32(fp0);
6958549d 8404 }
6c5c1e20 8405 gen_store_gpr(t0, rt);
5a5012ec
TS
8406 opn = "mfhc1";
8407 break;
8408 case OPC_MTHC1:
6c5c1e20 8409 gen_load_gpr(t0, rt);
b6d96bed 8410 {
a7812ae4 8411 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8412
8413 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8414 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8415 tcg_temp_free_i32(fp0);
6958549d 8416 }
5a5012ec
TS
8417 opn = "mthc1";
8418 break;
6ea83fed 8419 default:
923617a3 8420 MIPS_INVAL(opn);
e397ee33 8421 generate_exception (ctx, EXCP_RI);
6c5c1e20 8422 goto out;
6ea83fed 8423 }
2abf314d 8424 (void)opn; /* avoid a compiler warning */
6ea83fed 8425 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8426
8427 out:
8428 tcg_temp_free(t0);
6ea83fed
FB
8429}
8430
5a5012ec
TS
8431static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8432{
42a268c2 8433 TCGLabel *l1;
e214b9bb 8434 TCGCond cond;
af58f9ca
AJ
8435 TCGv_i32 t0;
8436
8437 if (rd == 0) {
8438 /* Treat as NOP. */
8439 return;
8440 }
6ea83fed 8441
e214b9bb 8442 if (tf)
e214b9bb 8443 cond = TCG_COND_EQ;
27848470
TS
8444 else
8445 cond = TCG_COND_NE;
8446
af58f9ca
AJ
8447 l1 = gen_new_label();
8448 t0 = tcg_temp_new_i32();
fa31af0e 8449 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8450 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8451 tcg_temp_free_i32(t0);
af58f9ca
AJ
8452 if (rs == 0) {
8453 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8454 } else {
8455 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8456 }
e214b9bb 8457 gen_set_label(l1);
5a5012ec
TS
8458}
8459
b6d96bed 8460static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8461{
a16336e4 8462 int cond;
cbc37b28 8463 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8464 TCGLabel *l1 = gen_new_label();
a16336e4 8465
a16336e4
TS
8466 if (tf)
8467 cond = TCG_COND_EQ;
8468 else
8469 cond = TCG_COND_NE;
8470
fa31af0e 8471 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8472 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8473 gen_load_fpr32(t0, fs);
8474 gen_store_fpr32(t0, fd);
a16336e4 8475 gen_set_label(l1);
cbc37b28 8476 tcg_temp_free_i32(t0);
5a5012ec 8477}
a16336e4 8478
b6d96bed 8479static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8480{
a16336e4 8481 int cond;
cbc37b28
AJ
8482 TCGv_i32 t0 = tcg_temp_new_i32();
8483 TCGv_i64 fp0;
42a268c2 8484 TCGLabel *l1 = gen_new_label();
a16336e4 8485
a16336e4
TS
8486 if (tf)
8487 cond = TCG_COND_EQ;
8488 else
8489 cond = TCG_COND_NE;
8490
fa31af0e 8491 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8492 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8493 tcg_temp_free_i32(t0);
11f94258 8494 fp0 = tcg_temp_new_i64();
9bf3eb2c 8495 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8496 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8497 tcg_temp_free_i64(fp0);
cbc37b28 8498 gen_set_label(l1);
a16336e4
TS
8499}
8500
7f6613ce
PJ
8501static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8502 int cc, int tf)
a16336e4
TS
8503{
8504 int cond;
cbc37b28 8505 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8506 TCGLabel *l1 = gen_new_label();
8507 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8508
8509 if (tf)
8510 cond = TCG_COND_EQ;
8511 else
8512 cond = TCG_COND_NE;
8513
fa31af0e 8514 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8515 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8516 gen_load_fpr32(t0, fs);
8517 gen_store_fpr32(t0, fd);
a16336e4 8518 gen_set_label(l1);
9bf3eb2c 8519
fa31af0e 8520 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8521 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8522 gen_load_fpr32h(ctx, t0, fs);
8523 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8524 tcg_temp_free_i32(t0);
a16336e4 8525 gen_set_label(l2);
a16336e4
TS
8526}
8527
e7f16abb
LA
8528static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8529 int fs)
8530{
8531 TCGv_i32 t1 = tcg_const_i32(0);
8532 TCGv_i32 fp0 = tcg_temp_new_i32();
8533 TCGv_i32 fp1 = tcg_temp_new_i32();
8534 TCGv_i32 fp2 = tcg_temp_new_i32();
8535 gen_load_fpr32(fp0, fd);
8536 gen_load_fpr32(fp1, ft);
8537 gen_load_fpr32(fp2, fs);
8538
8539 switch (op1) {
8540 case OPC_SEL_S:
8541 tcg_gen_andi_i32(fp0, fp0, 1);
8542 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8543 break;
8544 case OPC_SELEQZ_S:
8545 tcg_gen_andi_i32(fp1, fp1, 1);
8546 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8547 break;
8548 case OPC_SELNEZ_S:
8549 tcg_gen_andi_i32(fp1, fp1, 1);
8550 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8551 break;
8552 default:
8553 MIPS_INVAL("gen_sel_s");
8554 generate_exception (ctx, EXCP_RI);
8555 break;
8556 }
8557
8558 gen_store_fpr32(fp0, fd);
8559 tcg_temp_free_i32(fp2);
8560 tcg_temp_free_i32(fp1);
8561 tcg_temp_free_i32(fp0);
8562 tcg_temp_free_i32(t1);
8563}
8564
8565static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8566 int fs)
8567{
8568 TCGv_i64 t1 = tcg_const_i64(0);
8569 TCGv_i64 fp0 = tcg_temp_new_i64();
8570 TCGv_i64 fp1 = tcg_temp_new_i64();
8571 TCGv_i64 fp2 = tcg_temp_new_i64();
8572 gen_load_fpr64(ctx, fp0, fd);
8573 gen_load_fpr64(ctx, fp1, ft);
8574 gen_load_fpr64(ctx, fp2, fs);
8575
8576 switch (op1) {
8577 case OPC_SEL_D:
8578 tcg_gen_andi_i64(fp0, fp0, 1);
8579 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8580 break;
8581 case OPC_SELEQZ_D:
8582 tcg_gen_andi_i64(fp1, fp1, 1);
8583 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8584 break;
8585 case OPC_SELNEZ_D:
8586 tcg_gen_andi_i64(fp1, fp1, 1);
8587 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8588 break;
8589 default:
8590 MIPS_INVAL("gen_sel_d");
8591 generate_exception (ctx, EXCP_RI);
8592 break;
8593 }
8594
8595 gen_store_fpr64(ctx, fp0, fd);
8596 tcg_temp_free_i64(fp2);
8597 tcg_temp_free_i64(fp1);
8598 tcg_temp_free_i64(fp0);
8599 tcg_temp_free_i64(t1);
8600}
6ea83fed 8601
bf4120ad 8602static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8603 int ft, int fs, int fd, int cc)
6ea83fed 8604{
923617a3 8605 const char *opn = "farith";
6ea83fed
FB
8606 const char *condnames[] = {
8607 "c.f",
8608 "c.un",
8609 "c.eq",
8610 "c.ueq",
8611 "c.olt",
8612 "c.ult",
8613 "c.ole",
8614 "c.ule",
8615 "c.sf",
8616 "c.ngle",
8617 "c.seq",
8618 "c.ngl",
8619 "c.lt",
8620 "c.nge",
8621 "c.le",
8622 "c.ngt",
8623 };
5a1e8ffb
TS
8624 const char *condnames_abs[] = {
8625 "cabs.f",
8626 "cabs.un",
8627 "cabs.eq",
8628 "cabs.ueq",
8629 "cabs.olt",
8630 "cabs.ult",
8631 "cabs.ole",
8632 "cabs.ule",
8633 "cabs.sf",
8634 "cabs.ngle",
8635 "cabs.seq",
8636 "cabs.ngl",
8637 "cabs.lt",
8638 "cabs.nge",
8639 "cabs.le",
8640 "cabs.ngt",
8641 };
8642 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8643 uint32_t func = ctx->opcode & 0x3f;
8644
bf4120ad
NF
8645 switch (op1) {
8646 case OPC_ADD_S:
b6d96bed 8647 {
a7812ae4
PB
8648 TCGv_i32 fp0 = tcg_temp_new_i32();
8649 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8650
8651 gen_load_fpr32(fp0, fs);
8652 gen_load_fpr32(fp1, ft);
895c2d04 8653 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8654 tcg_temp_free_i32(fp1);
b6d96bed 8655 gen_store_fpr32(fp0, fd);
a7812ae4 8656 tcg_temp_free_i32(fp0);
b6d96bed 8657 }
5a5012ec 8658 opn = "add.s";
5a1e8ffb 8659 optype = BINOP;
5a5012ec 8660 break;
bf4120ad 8661 case OPC_SUB_S:
b6d96bed 8662 {
a7812ae4
PB
8663 TCGv_i32 fp0 = tcg_temp_new_i32();
8664 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8665
8666 gen_load_fpr32(fp0, fs);
8667 gen_load_fpr32(fp1, ft);
895c2d04 8668 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8669 tcg_temp_free_i32(fp1);
b6d96bed 8670 gen_store_fpr32(fp0, fd);
a7812ae4 8671 tcg_temp_free_i32(fp0);
b6d96bed 8672 }
5a5012ec 8673 opn = "sub.s";
5a1e8ffb 8674 optype = BINOP;
5a5012ec 8675 break;
bf4120ad 8676 case OPC_MUL_S:
b6d96bed 8677 {
a7812ae4
PB
8678 TCGv_i32 fp0 = tcg_temp_new_i32();
8679 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8680
8681 gen_load_fpr32(fp0, fs);
8682 gen_load_fpr32(fp1, ft);
895c2d04 8683 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8684 tcg_temp_free_i32(fp1);
b6d96bed 8685 gen_store_fpr32(fp0, fd);
a7812ae4 8686 tcg_temp_free_i32(fp0);
b6d96bed 8687 }
5a5012ec 8688 opn = "mul.s";
5a1e8ffb 8689 optype = BINOP;
5a5012ec 8690 break;
bf4120ad 8691 case OPC_DIV_S:
b6d96bed 8692 {
a7812ae4
PB
8693 TCGv_i32 fp0 = tcg_temp_new_i32();
8694 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8695
8696 gen_load_fpr32(fp0, fs);
8697 gen_load_fpr32(fp1, ft);
895c2d04 8698 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8699 tcg_temp_free_i32(fp1);
b6d96bed 8700 gen_store_fpr32(fp0, fd);
a7812ae4 8701 tcg_temp_free_i32(fp0);
b6d96bed 8702 }
5a5012ec 8703 opn = "div.s";
5a1e8ffb 8704 optype = BINOP;
5a5012ec 8705 break;
bf4120ad 8706 case OPC_SQRT_S:
b6d96bed 8707 {
a7812ae4 8708 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8709
8710 gen_load_fpr32(fp0, fs);
895c2d04 8711 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8712 gen_store_fpr32(fp0, fd);
a7812ae4 8713 tcg_temp_free_i32(fp0);
b6d96bed 8714 }
5a5012ec
TS
8715 opn = "sqrt.s";
8716 break;
bf4120ad 8717 case OPC_ABS_S:
b6d96bed 8718 {
a7812ae4 8719 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8720
8721 gen_load_fpr32(fp0, fs);
a7812ae4 8722 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8723 gen_store_fpr32(fp0, fd);
a7812ae4 8724 tcg_temp_free_i32(fp0);
b6d96bed 8725 }
5a5012ec
TS
8726 opn = "abs.s";
8727 break;
bf4120ad 8728 case OPC_MOV_S:
b6d96bed 8729 {
a7812ae4 8730 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8731
8732 gen_load_fpr32(fp0, fs);
8733 gen_store_fpr32(fp0, fd);
a7812ae4 8734 tcg_temp_free_i32(fp0);
b6d96bed 8735 }
5a5012ec
TS
8736 opn = "mov.s";
8737 break;
bf4120ad 8738 case OPC_NEG_S:
b6d96bed 8739 {
a7812ae4 8740 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8741
8742 gen_load_fpr32(fp0, fs);
a7812ae4 8743 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8744 gen_store_fpr32(fp0, fd);
a7812ae4 8745 tcg_temp_free_i32(fp0);
b6d96bed 8746 }
5a5012ec
TS
8747 opn = "neg.s";
8748 break;
bf4120ad 8749 case OPC_ROUND_L_S:
5e755519 8750 check_cp1_64bitmode(ctx);
b6d96bed 8751 {
a7812ae4
PB
8752 TCGv_i32 fp32 = tcg_temp_new_i32();
8753 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8754
8755 gen_load_fpr32(fp32, fs);
895c2d04 8756 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8757 tcg_temp_free_i32(fp32);
b6d96bed 8758 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8759 tcg_temp_free_i64(fp64);
b6d96bed 8760 }
5a5012ec
TS
8761 opn = "round.l.s";
8762 break;
bf4120ad 8763 case OPC_TRUNC_L_S:
5e755519 8764 check_cp1_64bitmode(ctx);
b6d96bed 8765 {
a7812ae4
PB
8766 TCGv_i32 fp32 = tcg_temp_new_i32();
8767 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8768
8769 gen_load_fpr32(fp32, fs);
895c2d04 8770 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8771 tcg_temp_free_i32(fp32);
b6d96bed 8772 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8773 tcg_temp_free_i64(fp64);
b6d96bed 8774 }
5a5012ec
TS
8775 opn = "trunc.l.s";
8776 break;
bf4120ad 8777 case OPC_CEIL_L_S:
5e755519 8778 check_cp1_64bitmode(ctx);
b6d96bed 8779 {
a7812ae4
PB
8780 TCGv_i32 fp32 = tcg_temp_new_i32();
8781 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8782
8783 gen_load_fpr32(fp32, fs);
895c2d04 8784 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8785 tcg_temp_free_i32(fp32);
b6d96bed 8786 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8787 tcg_temp_free_i64(fp64);
b6d96bed 8788 }
5a5012ec
TS
8789 opn = "ceil.l.s";
8790 break;
bf4120ad 8791 case OPC_FLOOR_L_S:
5e755519 8792 check_cp1_64bitmode(ctx);
b6d96bed 8793 {
a7812ae4
PB
8794 TCGv_i32 fp32 = tcg_temp_new_i32();
8795 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8796
8797 gen_load_fpr32(fp32, fs);
895c2d04 8798 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8799 tcg_temp_free_i32(fp32);
b6d96bed 8800 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8801 tcg_temp_free_i64(fp64);
b6d96bed 8802 }
5a5012ec
TS
8803 opn = "floor.l.s";
8804 break;
bf4120ad 8805 case OPC_ROUND_W_S:
b6d96bed 8806 {
a7812ae4 8807 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8808
8809 gen_load_fpr32(fp0, fs);
895c2d04 8810 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8811 gen_store_fpr32(fp0, fd);
a7812ae4 8812 tcg_temp_free_i32(fp0);
b6d96bed 8813 }
5a5012ec
TS
8814 opn = "round.w.s";
8815 break;
bf4120ad 8816 case OPC_TRUNC_W_S:
b6d96bed 8817 {
a7812ae4 8818 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8819
8820 gen_load_fpr32(fp0, fs);
895c2d04 8821 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8822 gen_store_fpr32(fp0, fd);
a7812ae4 8823 tcg_temp_free_i32(fp0);
b6d96bed 8824 }
5a5012ec
TS
8825 opn = "trunc.w.s";
8826 break;
bf4120ad 8827 case OPC_CEIL_W_S:
b6d96bed 8828 {
a7812ae4 8829 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8830
8831 gen_load_fpr32(fp0, fs);
895c2d04 8832 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8833 gen_store_fpr32(fp0, fd);
a7812ae4 8834 tcg_temp_free_i32(fp0);
b6d96bed 8835 }
5a5012ec
TS
8836 opn = "ceil.w.s";
8837 break;
bf4120ad 8838 case OPC_FLOOR_W_S:
b6d96bed 8839 {
a7812ae4 8840 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8841
8842 gen_load_fpr32(fp0, fs);
895c2d04 8843 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8844 gen_store_fpr32(fp0, fd);
a7812ae4 8845 tcg_temp_free_i32(fp0);
b6d96bed 8846 }
5a5012ec
TS
8847 opn = "floor.w.s";
8848 break;
e7f16abb
LA
8849 case OPC_SEL_S:
8850 check_insn(ctx, ISA_MIPS32R6);
8851 gen_sel_s(ctx, op1, fd, ft, fs);
8852 opn = "sel.s";
8853 break;
8854 case OPC_SELEQZ_S:
8855 check_insn(ctx, ISA_MIPS32R6);
8856 gen_sel_s(ctx, op1, fd, ft, fs);
8857 opn = "seleqz.s";
8858 break;
8859 case OPC_SELNEZ_S:
8860 check_insn(ctx, ISA_MIPS32R6);
8861 gen_sel_s(ctx, op1, fd, ft, fs);
8862 opn = "selnez.s";
8863 break;
bf4120ad 8864 case OPC_MOVCF_S:
fecd2646 8865 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8866 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8867 opn = "movcf.s";
8868 break;
bf4120ad 8869 case OPC_MOVZ_S:
fecd2646 8870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8871 {
42a268c2 8872 TCGLabel *l1 = gen_new_label();
c9297f4d 8873 TCGv_i32 fp0;
a16336e4 8874
c9297f4d
AJ
8875 if (ft != 0) {
8876 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8877 }
8878 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8879 gen_load_fpr32(fp0, fs);
8880 gen_store_fpr32(fp0, fd);
a7812ae4 8881 tcg_temp_free_i32(fp0);
a16336e4
TS
8882 gen_set_label(l1);
8883 }
5a5012ec
TS
8884 opn = "movz.s";
8885 break;
bf4120ad 8886 case OPC_MOVN_S:
fecd2646 8887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8888 {
42a268c2 8889 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8890 TCGv_i32 fp0;
8891
8892 if (ft != 0) {
8893 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8894 fp0 = tcg_temp_new_i32();
8895 gen_load_fpr32(fp0, fs);
8896 gen_store_fpr32(fp0, fd);
8897 tcg_temp_free_i32(fp0);
8898 gen_set_label(l1);
8899 }
a16336e4 8900 }
5a5012ec
TS
8901 opn = "movn.s";
8902 break;
bf4120ad 8903 case OPC_RECIP_S:
b8aa4598 8904 check_cop1x(ctx);
b6d96bed 8905 {
a7812ae4 8906 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8907
8908 gen_load_fpr32(fp0, fs);
895c2d04 8909 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8910 gen_store_fpr32(fp0, fd);
a7812ae4 8911 tcg_temp_free_i32(fp0);
b6d96bed 8912 }
57fa1fb3
TS
8913 opn = "recip.s";
8914 break;
bf4120ad 8915 case OPC_RSQRT_S:
b8aa4598 8916 check_cop1x(ctx);
b6d96bed 8917 {
a7812ae4 8918 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8919
8920 gen_load_fpr32(fp0, fs);
895c2d04 8921 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8922 gen_store_fpr32(fp0, fd);
a7812ae4 8923 tcg_temp_free_i32(fp0);
b6d96bed 8924 }
57fa1fb3
TS
8925 opn = "rsqrt.s";
8926 break;
e7f16abb
LA
8927 case OPC_MADDF_S:
8928 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8929 {
a7812ae4
PB
8930 TCGv_i32 fp0 = tcg_temp_new_i32();
8931 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8932 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8933 gen_load_fpr32(fp0, fs);
d22d7289 8934 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8935 gen_load_fpr32(fp2, fd);
8936 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8937 gen_store_fpr32(fp2, fd);
8938 tcg_temp_free_i32(fp2);
a7812ae4 8939 tcg_temp_free_i32(fp1);
a7812ae4 8940 tcg_temp_free_i32(fp0);
e7f16abb 8941 opn = "maddf.s";
b6d96bed 8942 }
57fa1fb3 8943 break;
e7f16abb
LA
8944 case OPC_MSUBF_S:
8945 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8946 {
a7812ae4 8947 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8948 TCGv_i32 fp1 = tcg_temp_new_i32();
8949 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8950 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8951 gen_load_fpr32(fp1, ft);
8952 gen_load_fpr32(fp2, fd);
8953 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8954 gen_store_fpr32(fp2, fd);
8955 tcg_temp_free_i32(fp2);
8956 tcg_temp_free_i32(fp1);
a7812ae4 8957 tcg_temp_free_i32(fp0);
e7f16abb 8958 opn = "msubf.s";
b6d96bed 8959 }
57fa1fb3 8960 break;
e7f16abb
LA
8961 case OPC_RINT_S:
8962 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8963 {
a7812ae4 8964 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8965 gen_load_fpr32(fp0, fs);
e7f16abb 8966 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8967 gen_store_fpr32(fp0, fd);
a7812ae4 8968 tcg_temp_free_i32(fp0);
e7f16abb 8969 opn = "rint.s";
b6d96bed 8970 }
57fa1fb3 8971 break;
e7f16abb
LA
8972 case OPC_CLASS_S:
8973 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8974 {
e7f16abb
LA
8975 TCGv_i32 fp0 = tcg_temp_new_i32();
8976 gen_load_fpr32(fp0, fs);
8977 gen_helper_float_class_s(fp0, fp0);
8978 gen_store_fpr32(fp0, fd);
8979 tcg_temp_free_i32(fp0);
8980 opn = "class.s";
8981 }
8982 break;
8983 case OPC_MIN_S: /* OPC_RECIP2_S */
8984 if (ctx->insn_flags & ISA_MIPS32R6) {
8985 /* OPC_MIN_S */
a7812ae4
PB
8986 TCGv_i32 fp0 = tcg_temp_new_i32();
8987 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8988 TCGv_i32 fp2 = tcg_temp_new_i32();
8989 gen_load_fpr32(fp0, fs);
8990 gen_load_fpr32(fp1, ft);
8991 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8992 gen_store_fpr32(fp2, fd);
8993 tcg_temp_free_i32(fp2);
8994 tcg_temp_free_i32(fp1);
8995 tcg_temp_free_i32(fp0);
8996 opn = "min.s";
8997 } else {
8998 /* OPC_RECIP2_S */
8999 check_cp1_64bitmode(ctx);
9000 {
9001 TCGv_i32 fp0 = tcg_temp_new_i32();
9002 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9003
e7f16abb
LA
9004 gen_load_fpr32(fp0, fs);
9005 gen_load_fpr32(fp1, ft);
9006 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9007 tcg_temp_free_i32(fp1);
9008 gen_store_fpr32(fp0, fd);
9009 tcg_temp_free_i32(fp0);
9010 }
9011 opn = "recip2.s";
9012 }
9013 break;
9014 case OPC_MINA_S: /* OPC_RECIP1_S */
9015 if (ctx->insn_flags & ISA_MIPS32R6) {
9016 /* OPC_MINA_S */
9017 TCGv_i32 fp0 = tcg_temp_new_i32();
9018 TCGv_i32 fp1 = tcg_temp_new_i32();
9019 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9020 gen_load_fpr32(fp0, fs);
9021 gen_load_fpr32(fp1, ft);
e7f16abb
LA
9022 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9023 gen_store_fpr32(fp2, fd);
9024 tcg_temp_free_i32(fp2);
9025 tcg_temp_free_i32(fp1);
9026 tcg_temp_free_i32(fp0);
9027 opn = "mina.s";
9028 } else {
9029 /* OPC_RECIP1_S */
9030 check_cp1_64bitmode(ctx);
9031 {
9032 TCGv_i32 fp0 = tcg_temp_new_i32();
9033
9034 gen_load_fpr32(fp0, fs);
9035 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9036 gen_store_fpr32(fp0, fd);
9037 tcg_temp_free_i32(fp0);
9038 }
9039 opn = "recip1.s";
9040 }
9041 break;
9042 case OPC_MAX_S: /* OPC_RSQRT1_S */
9043 if (ctx->insn_flags & ISA_MIPS32R6) {
9044 /* OPC_MAX_S */
9045 TCGv_i32 fp0 = tcg_temp_new_i32();
9046 TCGv_i32 fp1 = tcg_temp_new_i32();
9047 gen_load_fpr32(fp0, fs);
9048 gen_load_fpr32(fp1, ft);
9049 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9050 gen_store_fpr32(fp1, fd);
9051 tcg_temp_free_i32(fp1);
9052 tcg_temp_free_i32(fp0);
9053 opn = "max.s";
9054 } else {
9055 /* OPC_RSQRT1_S */
9056 check_cp1_64bitmode(ctx);
9057 {
9058 TCGv_i32 fp0 = tcg_temp_new_i32();
9059
9060 gen_load_fpr32(fp0, fs);
9061 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9062 gen_store_fpr32(fp0, fd);
9063 tcg_temp_free_i32(fp0);
9064 }
9065 opn = "rsqrt1.s";
9066 }
9067 break;
9068 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9069 if (ctx->insn_flags & ISA_MIPS32R6) {
9070 /* OPC_MAXA_S */
9071 TCGv_i32 fp0 = tcg_temp_new_i32();
9072 TCGv_i32 fp1 = tcg_temp_new_i32();
9073 gen_load_fpr32(fp0, fs);
9074 gen_load_fpr32(fp1, ft);
9075 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9076 gen_store_fpr32(fp1, fd);
a7812ae4 9077 tcg_temp_free_i32(fp1);
a7812ae4 9078 tcg_temp_free_i32(fp0);
e7f16abb
LA
9079 opn = "maxa.s";
9080 } else {
9081 /* OPC_RSQRT2_S */
9082 check_cp1_64bitmode(ctx);
9083 {
9084 TCGv_i32 fp0 = tcg_temp_new_i32();
9085 TCGv_i32 fp1 = tcg_temp_new_i32();
9086
9087 gen_load_fpr32(fp0, fs);
9088 gen_load_fpr32(fp1, ft);
9089 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9090 tcg_temp_free_i32(fp1);
9091 gen_store_fpr32(fp0, fd);
9092 tcg_temp_free_i32(fp0);
9093 }
9094 opn = "rsqrt2.s";
b6d96bed 9095 }
57fa1fb3 9096 break;
bf4120ad 9097 case OPC_CVT_D_S:
5e755519 9098 check_cp1_registers(ctx, fd);
b6d96bed 9099 {
a7812ae4
PB
9100 TCGv_i32 fp32 = tcg_temp_new_i32();
9101 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9102
9103 gen_load_fpr32(fp32, fs);
895c2d04 9104 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9105 tcg_temp_free_i32(fp32);
b6d96bed 9106 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9107 tcg_temp_free_i64(fp64);
b6d96bed 9108 }
5a5012ec
TS
9109 opn = "cvt.d.s";
9110 break;
bf4120ad 9111 case OPC_CVT_W_S:
b6d96bed 9112 {
a7812ae4 9113 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9114
9115 gen_load_fpr32(fp0, fs);
895c2d04 9116 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 9117 gen_store_fpr32(fp0, fd);
a7812ae4 9118 tcg_temp_free_i32(fp0);
b6d96bed 9119 }
5a5012ec
TS
9120 opn = "cvt.w.s";
9121 break;
bf4120ad 9122 case OPC_CVT_L_S:
5e755519 9123 check_cp1_64bitmode(ctx);
b6d96bed 9124 {
a7812ae4
PB
9125 TCGv_i32 fp32 = tcg_temp_new_i32();
9126 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9127
9128 gen_load_fpr32(fp32, fs);
895c2d04 9129 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9130 tcg_temp_free_i32(fp32);
b6d96bed 9131 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9132 tcg_temp_free_i64(fp64);
b6d96bed 9133 }
5a5012ec
TS
9134 opn = "cvt.l.s";
9135 break;
bf4120ad 9136 case OPC_CVT_PS_S:
fecd2646 9137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9138 check_cp1_64bitmode(ctx);
b6d96bed 9139 {
a7812ae4
PB
9140 TCGv_i64 fp64 = tcg_temp_new_i64();
9141 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9142 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
9143
9144 gen_load_fpr32(fp32_0, fs);
9145 gen_load_fpr32(fp32_1, ft);
13d24f49 9146 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9147 tcg_temp_free_i32(fp32_1);
9148 tcg_temp_free_i32(fp32_0);
36aa55dc 9149 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9150 tcg_temp_free_i64(fp64);
b6d96bed 9151 }
5a5012ec
TS
9152 opn = "cvt.ps.s";
9153 break;
bf4120ad
NF
9154 case OPC_CMP_F_S:
9155 case OPC_CMP_UN_S:
9156 case OPC_CMP_EQ_S:
9157 case OPC_CMP_UEQ_S:
9158 case OPC_CMP_OLT_S:
9159 case OPC_CMP_ULT_S:
9160 case OPC_CMP_OLE_S:
9161 case OPC_CMP_ULE_S:
9162 case OPC_CMP_SF_S:
9163 case OPC_CMP_NGLE_S:
9164 case OPC_CMP_SEQ_S:
9165 case OPC_CMP_NGL_S:
9166 case OPC_CMP_LT_S:
9167 case OPC_CMP_NGE_S:
9168 case OPC_CMP_LE_S:
9169 case OPC_CMP_NGT_S:
fecd2646 9170 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9171 if (ctx->opcode & (1 << 6)) {
9172 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9173 opn = condnames_abs[func-48];
9174 } else {
9175 gen_cmp_s(ctx, func-48, ft, fs, cc);
9176 opn = condnames[func-48];
5a1e8ffb 9177 }
5a5012ec 9178 break;
bf4120ad 9179 case OPC_ADD_D:
5e755519 9180 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9181 {
a7812ae4
PB
9182 TCGv_i64 fp0 = tcg_temp_new_i64();
9183 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9184
9185 gen_load_fpr64(ctx, fp0, fs);
9186 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9187 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9188 tcg_temp_free_i64(fp1);
b6d96bed 9189 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9190 tcg_temp_free_i64(fp0);
b6d96bed 9191 }
6ea83fed 9192 opn = "add.d";
5a1e8ffb 9193 optype = BINOP;
6ea83fed 9194 break;
bf4120ad 9195 case OPC_SUB_D:
5e755519 9196 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9197 {
a7812ae4
PB
9198 TCGv_i64 fp0 = tcg_temp_new_i64();
9199 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9200
9201 gen_load_fpr64(ctx, fp0, fs);
9202 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9203 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9204 tcg_temp_free_i64(fp1);
b6d96bed 9205 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9206 tcg_temp_free_i64(fp0);
b6d96bed 9207 }
6ea83fed 9208 opn = "sub.d";
5a1e8ffb 9209 optype = BINOP;
6ea83fed 9210 break;
bf4120ad 9211 case OPC_MUL_D:
5e755519 9212 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9213 {
a7812ae4
PB
9214 TCGv_i64 fp0 = tcg_temp_new_i64();
9215 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9216
9217 gen_load_fpr64(ctx, fp0, fs);
9218 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9219 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9220 tcg_temp_free_i64(fp1);
b6d96bed 9221 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9222 tcg_temp_free_i64(fp0);
b6d96bed 9223 }
6ea83fed 9224 opn = "mul.d";
5a1e8ffb 9225 optype = BINOP;
6ea83fed 9226 break;
bf4120ad 9227 case OPC_DIV_D:
5e755519 9228 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9229 {
a7812ae4
PB
9230 TCGv_i64 fp0 = tcg_temp_new_i64();
9231 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9232
9233 gen_load_fpr64(ctx, fp0, fs);
9234 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9235 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9236 tcg_temp_free_i64(fp1);
b6d96bed 9237 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9238 tcg_temp_free_i64(fp0);
b6d96bed 9239 }
6ea83fed 9240 opn = "div.d";
5a1e8ffb 9241 optype = BINOP;
6ea83fed 9242 break;
bf4120ad 9243 case OPC_SQRT_D:
5e755519 9244 check_cp1_registers(ctx, fs | fd);
b6d96bed 9245 {
a7812ae4 9246 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9247
9248 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9249 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9251 tcg_temp_free_i64(fp0);
b6d96bed 9252 }
6ea83fed
FB
9253 opn = "sqrt.d";
9254 break;
bf4120ad 9255 case OPC_ABS_D:
5e755519 9256 check_cp1_registers(ctx, fs | fd);
b6d96bed 9257 {
a7812ae4 9258 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9259
9260 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9261 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9262 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9263 tcg_temp_free_i64(fp0);
b6d96bed 9264 }
6ea83fed
FB
9265 opn = "abs.d";
9266 break;
bf4120ad 9267 case OPC_MOV_D:
5e755519 9268 check_cp1_registers(ctx, fs | fd);
b6d96bed 9269 {
a7812ae4 9270 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9271
9272 gen_load_fpr64(ctx, fp0, fs);
9273 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9274 tcg_temp_free_i64(fp0);
b6d96bed 9275 }
6ea83fed
FB
9276 opn = "mov.d";
9277 break;
bf4120ad 9278 case OPC_NEG_D:
5e755519 9279 check_cp1_registers(ctx, fs | fd);
b6d96bed 9280 {
a7812ae4 9281 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9282
9283 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9284 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9285 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9286 tcg_temp_free_i64(fp0);
b6d96bed 9287 }
6ea83fed
FB
9288 opn = "neg.d";
9289 break;
bf4120ad 9290 case OPC_ROUND_L_D:
5e755519 9291 check_cp1_64bitmode(ctx);
b6d96bed 9292 {
a7812ae4 9293 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9294
9295 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9296 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9297 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9298 tcg_temp_free_i64(fp0);
b6d96bed 9299 }
5a5012ec
TS
9300 opn = "round.l.d";
9301 break;
bf4120ad 9302 case OPC_TRUNC_L_D:
5e755519 9303 check_cp1_64bitmode(ctx);
b6d96bed 9304 {
a7812ae4 9305 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9306
9307 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9308 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9309 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9310 tcg_temp_free_i64(fp0);
b6d96bed 9311 }
5a5012ec
TS
9312 opn = "trunc.l.d";
9313 break;
bf4120ad 9314 case OPC_CEIL_L_D:
5e755519 9315 check_cp1_64bitmode(ctx);
b6d96bed 9316 {
a7812ae4 9317 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9318
9319 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9320 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9321 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9322 tcg_temp_free_i64(fp0);
b6d96bed 9323 }
5a5012ec
TS
9324 opn = "ceil.l.d";
9325 break;
bf4120ad 9326 case OPC_FLOOR_L_D:
5e755519 9327 check_cp1_64bitmode(ctx);
b6d96bed 9328 {
a7812ae4 9329 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9330
9331 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9332 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9333 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9334 tcg_temp_free_i64(fp0);
b6d96bed 9335 }
5a5012ec
TS
9336 opn = "floor.l.d";
9337 break;
bf4120ad 9338 case OPC_ROUND_W_D:
5e755519 9339 check_cp1_registers(ctx, fs);
b6d96bed 9340 {
a7812ae4
PB
9341 TCGv_i32 fp32 = tcg_temp_new_i32();
9342 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9343
9344 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9345 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9346 tcg_temp_free_i64(fp64);
b6d96bed 9347 gen_store_fpr32(fp32, fd);
a7812ae4 9348 tcg_temp_free_i32(fp32);
b6d96bed 9349 }
6ea83fed
FB
9350 opn = "round.w.d";
9351 break;
bf4120ad 9352 case OPC_TRUNC_W_D:
5e755519 9353 check_cp1_registers(ctx, fs);
b6d96bed 9354 {
a7812ae4
PB
9355 TCGv_i32 fp32 = tcg_temp_new_i32();
9356 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9357
9358 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9359 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9360 tcg_temp_free_i64(fp64);
b6d96bed 9361 gen_store_fpr32(fp32, fd);
a7812ae4 9362 tcg_temp_free_i32(fp32);
b6d96bed 9363 }
6ea83fed
FB
9364 opn = "trunc.w.d";
9365 break;
bf4120ad 9366 case OPC_CEIL_W_D:
5e755519 9367 check_cp1_registers(ctx, fs);
b6d96bed 9368 {
a7812ae4
PB
9369 TCGv_i32 fp32 = tcg_temp_new_i32();
9370 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9371
9372 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9373 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9374 tcg_temp_free_i64(fp64);
b6d96bed 9375 gen_store_fpr32(fp32, fd);
a7812ae4 9376 tcg_temp_free_i32(fp32);
b6d96bed 9377 }
6ea83fed
FB
9378 opn = "ceil.w.d";
9379 break;
bf4120ad 9380 case OPC_FLOOR_W_D:
5e755519 9381 check_cp1_registers(ctx, fs);
b6d96bed 9382 {
a7812ae4
PB
9383 TCGv_i32 fp32 = tcg_temp_new_i32();
9384 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9385
9386 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9387 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9388 tcg_temp_free_i64(fp64);
b6d96bed 9389 gen_store_fpr32(fp32, fd);
a7812ae4 9390 tcg_temp_free_i32(fp32);
b6d96bed 9391 }
7a387fff 9392 opn = "floor.w.d";
6ea83fed 9393 break;
e7f16abb
LA
9394 case OPC_SEL_D:
9395 check_insn(ctx, ISA_MIPS32R6);
9396 gen_sel_d(ctx, op1, fd, ft, fs);
9397 opn = "sel.d";
9398 break;
9399 case OPC_SELEQZ_D:
9400 check_insn(ctx, ISA_MIPS32R6);
9401 gen_sel_d(ctx, op1, fd, ft, fs);
9402 opn = "seleqz.d";
9403 break;
9404 case OPC_SELNEZ_D:
9405 check_insn(ctx, ISA_MIPS32R6);
9406 gen_sel_d(ctx, op1, fd, ft, fs);
9407 opn = "selnez.d";
9408 break;
bf4120ad 9409 case OPC_MOVCF_D:
fecd2646 9410 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9411 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9412 opn = "movcf.d";
dd016883 9413 break;
bf4120ad 9414 case OPC_MOVZ_D:
fecd2646 9415 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9416 {
42a268c2 9417 TCGLabel *l1 = gen_new_label();
c9297f4d 9418 TCGv_i64 fp0;
a16336e4 9419
c9297f4d
AJ
9420 if (ft != 0) {
9421 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9422 }
9423 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9424 gen_load_fpr64(ctx, fp0, fs);
9425 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9426 tcg_temp_free_i64(fp0);
a16336e4
TS
9427 gen_set_label(l1);
9428 }
5a5012ec
TS
9429 opn = "movz.d";
9430 break;
bf4120ad 9431 case OPC_MOVN_D:
fecd2646 9432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9433 {
42a268c2 9434 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9435 TCGv_i64 fp0;
9436
9437 if (ft != 0) {
9438 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9439 fp0 = tcg_temp_new_i64();
9440 gen_load_fpr64(ctx, fp0, fs);
9441 gen_store_fpr64(ctx, fp0, fd);
9442 tcg_temp_free_i64(fp0);
9443 gen_set_label(l1);
9444 }
a16336e4 9445 }
5a5012ec 9446 opn = "movn.d";
6ea83fed 9447 break;
bf4120ad 9448 case OPC_RECIP_D:
b8aa4598 9449 check_cp1_64bitmode(ctx);
b6d96bed 9450 {
a7812ae4 9451 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9452
9453 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9454 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9455 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9456 tcg_temp_free_i64(fp0);
b6d96bed 9457 }
57fa1fb3
TS
9458 opn = "recip.d";
9459 break;
bf4120ad 9460 case OPC_RSQRT_D:
b8aa4598 9461 check_cp1_64bitmode(ctx);
b6d96bed 9462 {
a7812ae4 9463 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9464
9465 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9466 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9467 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9468 tcg_temp_free_i64(fp0);
b6d96bed 9469 }
57fa1fb3
TS
9470 opn = "rsqrt.d";
9471 break;
e7f16abb
LA
9472 case OPC_MADDF_D:
9473 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9474 {
a7812ae4
PB
9475 TCGv_i64 fp0 = tcg_temp_new_i64();
9476 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9477 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9478 gen_load_fpr64(ctx, fp0, fs);
9479 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9480 gen_load_fpr64(ctx, fp2, fd);
9481 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9482 gen_store_fpr64(ctx, fp2, fd);
9483 tcg_temp_free_i64(fp2);
a7812ae4 9484 tcg_temp_free_i64(fp1);
a7812ae4 9485 tcg_temp_free_i64(fp0);
e7f16abb 9486 opn = "maddf.d";
b6d96bed 9487 }
57fa1fb3 9488 break;
e7f16abb
LA
9489 case OPC_MSUBF_D:
9490 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9491 {
a7812ae4 9492 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9493 TCGv_i64 fp1 = tcg_temp_new_i64();
9494 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9495 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9496 gen_load_fpr64(ctx, fp1, ft);
9497 gen_load_fpr64(ctx, fp2, fd);
9498 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9499 gen_store_fpr64(ctx, fp2, fd);
9500 tcg_temp_free_i64(fp2);
9501 tcg_temp_free_i64(fp1);
a7812ae4 9502 tcg_temp_free_i64(fp0);
e7f16abb 9503 opn = "msubf.d";
b6d96bed 9504 }
57fa1fb3 9505 break;
e7f16abb
LA
9506 case OPC_RINT_D:
9507 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9508 {
a7812ae4 9509 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9510 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9511 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9512 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9513 tcg_temp_free_i64(fp0);
e7f16abb 9514 opn = "rint.d";
b6d96bed 9515 }
57fa1fb3 9516 break;
e7f16abb
LA
9517 case OPC_CLASS_D:
9518 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9519 {
e7f16abb
LA
9520 TCGv_i64 fp0 = tcg_temp_new_i64();
9521 gen_load_fpr64(ctx, fp0, fs);
9522 gen_helper_float_class_d(fp0, fp0);
9523 gen_store_fpr64(ctx, fp0, fd);
9524 tcg_temp_free_i64(fp0);
9525 opn = "class.d";
9526 }
9527 break;
9528 case OPC_MIN_D: /* OPC_RECIP2_D */
9529 if (ctx->insn_flags & ISA_MIPS32R6) {
9530 /* OPC_MIN_D */
a7812ae4
PB
9531 TCGv_i64 fp0 = tcg_temp_new_i64();
9532 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9533 gen_load_fpr64(ctx, fp0, fs);
9534 gen_load_fpr64(ctx, fp1, ft);
9535 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9536 gen_store_fpr64(ctx, fp1, fd);
9537 tcg_temp_free_i64(fp1);
9538 tcg_temp_free_i64(fp0);
9539 opn = "min.d";
9540 } else {
9541 /* OPC_RECIP2_D */
9542 check_cp1_64bitmode(ctx);
9543 {
9544 TCGv_i64 fp0 = tcg_temp_new_i64();
9545 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9546
e7f16abb
LA
9547 gen_load_fpr64(ctx, fp0, fs);
9548 gen_load_fpr64(ctx, fp1, ft);
9549 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9550 tcg_temp_free_i64(fp1);
9551 gen_store_fpr64(ctx, fp0, fd);
9552 tcg_temp_free_i64(fp0);
9553 }
9554 opn = "recip2.d";
9555 }
9556 break;
9557 case OPC_MINA_D: /* OPC_RECIP1_D */
9558 if (ctx->insn_flags & ISA_MIPS32R6) {
9559 /* OPC_MINA_D */
9560 TCGv_i64 fp0 = tcg_temp_new_i64();
9561 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9562 gen_load_fpr64(ctx, fp0, fs);
9563 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9564 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9565 gen_store_fpr64(ctx, fp1, fd);
9566 tcg_temp_free_i64(fp1);
9567 tcg_temp_free_i64(fp0);
9568 opn = "mina.d";
9569 } else {
9570 /* OPC_RECIP1_D */
9571 check_cp1_64bitmode(ctx);
9572 {
9573 TCGv_i64 fp0 = tcg_temp_new_i64();
9574
9575 gen_load_fpr64(ctx, fp0, fs);
9576 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9577 gen_store_fpr64(ctx, fp0, fd);
9578 tcg_temp_free_i64(fp0);
9579 }
9580 opn = "recip1.d";
9581 }
9582 break;
9583 case OPC_MAX_D: /* OPC_RSQRT1_D */
9584 if (ctx->insn_flags & ISA_MIPS32R6) {
9585 /* OPC_MAX_D */
9586 TCGv_i64 fp0 = tcg_temp_new_i64();
9587 TCGv_i64 fp1 = tcg_temp_new_i64();
9588 gen_load_fpr64(ctx, fp0, fs);
9589 gen_load_fpr64(ctx, fp1, ft);
9590 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9591 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9592 tcg_temp_free_i64(fp1);
a7812ae4 9593 tcg_temp_free_i64(fp0);
e7f16abb
LA
9594 opn = "max.d";
9595 } else {
9596 /* OPC_RSQRT1_D */
9597 check_cp1_64bitmode(ctx);
9598 {
9599 TCGv_i64 fp0 = tcg_temp_new_i64();
9600
9601 gen_load_fpr64(ctx, fp0, fs);
9602 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9603 gen_store_fpr64(ctx, fp0, fd);
9604 tcg_temp_free_i64(fp0);
9605 }
9606 opn = "rsqrt1.d";
9607 }
9608 break;
9609 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9610 if (ctx->insn_flags & ISA_MIPS32R6) {
9611 /* OPC_MAXA_D */
9612 TCGv_i64 fp0 = tcg_temp_new_i64();
9613 TCGv_i64 fp1 = tcg_temp_new_i64();
9614 gen_load_fpr64(ctx, fp0, fs);
9615 gen_load_fpr64(ctx, fp1, ft);
9616 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9617 gen_store_fpr64(ctx, fp1, fd);
9618 tcg_temp_free_i64(fp1);
9619 tcg_temp_free_i64(fp0);
9620 opn = "maxa.d";
9621 } else {
9622 /* OPC_RSQRT2_D */
9623 check_cp1_64bitmode(ctx);
9624 {
9625 TCGv_i64 fp0 = tcg_temp_new_i64();
9626 TCGv_i64 fp1 = tcg_temp_new_i64();
9627
9628 gen_load_fpr64(ctx, fp0, fs);
9629 gen_load_fpr64(ctx, fp1, ft);
9630 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9631 tcg_temp_free_i64(fp1);
9632 gen_store_fpr64(ctx, fp0, fd);
9633 tcg_temp_free_i64(fp0);
9634 }
9635 opn = "rsqrt2.d";
b6d96bed 9636 }
57fa1fb3 9637 break;
bf4120ad
NF
9638 case OPC_CMP_F_D:
9639 case OPC_CMP_UN_D:
9640 case OPC_CMP_EQ_D:
9641 case OPC_CMP_UEQ_D:
9642 case OPC_CMP_OLT_D:
9643 case OPC_CMP_ULT_D:
9644 case OPC_CMP_OLE_D:
9645 case OPC_CMP_ULE_D:
9646 case OPC_CMP_SF_D:
9647 case OPC_CMP_NGLE_D:
9648 case OPC_CMP_SEQ_D:
9649 case OPC_CMP_NGL_D:
9650 case OPC_CMP_LT_D:
9651 case OPC_CMP_NGE_D:
9652 case OPC_CMP_LE_D:
9653 case OPC_CMP_NGT_D:
fecd2646 9654 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9655 if (ctx->opcode & (1 << 6)) {
9656 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9657 opn = condnames_abs[func-48];
9658 } else {
9659 gen_cmp_d(ctx, func-48, ft, fs, cc);
9660 opn = condnames[func-48];
5a1e8ffb 9661 }
6ea83fed 9662 break;
bf4120ad 9663 case OPC_CVT_S_D:
5e755519 9664 check_cp1_registers(ctx, fs);
b6d96bed 9665 {
a7812ae4
PB
9666 TCGv_i32 fp32 = tcg_temp_new_i32();
9667 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9668
9669 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9670 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9671 tcg_temp_free_i64(fp64);
b6d96bed 9672 gen_store_fpr32(fp32, fd);
a7812ae4 9673 tcg_temp_free_i32(fp32);
b6d96bed 9674 }
5a5012ec
TS
9675 opn = "cvt.s.d";
9676 break;
bf4120ad 9677 case OPC_CVT_W_D:
5e755519 9678 check_cp1_registers(ctx, fs);
b6d96bed 9679 {
a7812ae4
PB
9680 TCGv_i32 fp32 = tcg_temp_new_i32();
9681 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9682
9683 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9684 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9685 tcg_temp_free_i64(fp64);
b6d96bed 9686 gen_store_fpr32(fp32, fd);
a7812ae4 9687 tcg_temp_free_i32(fp32);
b6d96bed 9688 }
5a5012ec
TS
9689 opn = "cvt.w.d";
9690 break;
bf4120ad 9691 case OPC_CVT_L_D:
5e755519 9692 check_cp1_64bitmode(ctx);
b6d96bed 9693 {
a7812ae4 9694 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9695
9696 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9697 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9698 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9699 tcg_temp_free_i64(fp0);
b6d96bed 9700 }
5a5012ec
TS
9701 opn = "cvt.l.d";
9702 break;
bf4120ad 9703 case OPC_CVT_S_W:
b6d96bed 9704 {
a7812ae4 9705 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9706
9707 gen_load_fpr32(fp0, fs);
895c2d04 9708 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9709 gen_store_fpr32(fp0, fd);
a7812ae4 9710 tcg_temp_free_i32(fp0);
b6d96bed 9711 }
5a5012ec 9712 opn = "cvt.s.w";
6ea83fed 9713 break;
bf4120ad 9714 case OPC_CVT_D_W:
5e755519 9715 check_cp1_registers(ctx, fd);
b6d96bed 9716 {
a7812ae4
PB
9717 TCGv_i32 fp32 = tcg_temp_new_i32();
9718 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9719
9720 gen_load_fpr32(fp32, fs);
895c2d04 9721 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9722 tcg_temp_free_i32(fp32);
b6d96bed 9723 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9724 tcg_temp_free_i64(fp64);
b6d96bed 9725 }
5a5012ec
TS
9726 opn = "cvt.d.w";
9727 break;
bf4120ad 9728 case OPC_CVT_S_L:
5e755519 9729 check_cp1_64bitmode(ctx);
b6d96bed 9730 {
a7812ae4
PB
9731 TCGv_i32 fp32 = tcg_temp_new_i32();
9732 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9733
9734 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9735 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9736 tcg_temp_free_i64(fp64);
b6d96bed 9737 gen_store_fpr32(fp32, fd);
a7812ae4 9738 tcg_temp_free_i32(fp32);
b6d96bed 9739 }
5a5012ec
TS
9740 opn = "cvt.s.l";
9741 break;
bf4120ad 9742 case OPC_CVT_D_L:
5e755519 9743 check_cp1_64bitmode(ctx);
b6d96bed 9744 {
a7812ae4 9745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9746
9747 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9748 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9749 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9750 tcg_temp_free_i64(fp0);
b6d96bed 9751 }
5a5012ec
TS
9752 opn = "cvt.d.l";
9753 break;
bf4120ad 9754 case OPC_CVT_PS_PW:
fecd2646 9755 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9756 check_cp1_64bitmode(ctx);
b6d96bed 9757 {
a7812ae4 9758 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9759
9760 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9761 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9762 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9763 tcg_temp_free_i64(fp0);
b6d96bed 9764 }
5a5012ec
TS
9765 opn = "cvt.ps.pw";
9766 break;
bf4120ad 9767 case OPC_ADD_PS:
5e755519 9768 check_cp1_64bitmode(ctx);
b6d96bed 9769 {
a7812ae4
PB
9770 TCGv_i64 fp0 = tcg_temp_new_i64();
9771 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9772
9773 gen_load_fpr64(ctx, fp0, fs);
9774 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9775 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9776 tcg_temp_free_i64(fp1);
b6d96bed 9777 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9778 tcg_temp_free_i64(fp0);
b6d96bed 9779 }
5a5012ec 9780 opn = "add.ps";
6ea83fed 9781 break;
bf4120ad 9782 case OPC_SUB_PS:
5e755519 9783 check_cp1_64bitmode(ctx);
b6d96bed 9784 {
a7812ae4
PB
9785 TCGv_i64 fp0 = tcg_temp_new_i64();
9786 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9787
9788 gen_load_fpr64(ctx, fp0, fs);
9789 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9790 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9791 tcg_temp_free_i64(fp1);
b6d96bed 9792 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9793 tcg_temp_free_i64(fp0);
b6d96bed 9794 }
5a5012ec 9795 opn = "sub.ps";
6ea83fed 9796 break;
bf4120ad 9797 case OPC_MUL_PS:
5e755519 9798 check_cp1_64bitmode(ctx);
b6d96bed 9799 {
a7812ae4
PB
9800 TCGv_i64 fp0 = tcg_temp_new_i64();
9801 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9802
9803 gen_load_fpr64(ctx, fp0, fs);
9804 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9805 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9806 tcg_temp_free_i64(fp1);
b6d96bed 9807 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9808 tcg_temp_free_i64(fp0);
b6d96bed 9809 }
5a5012ec 9810 opn = "mul.ps";
6ea83fed 9811 break;
bf4120ad 9812 case OPC_ABS_PS:
5e755519 9813 check_cp1_64bitmode(ctx);
b6d96bed 9814 {
a7812ae4 9815 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9816
9817 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9818 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9819 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9820 tcg_temp_free_i64(fp0);
b6d96bed 9821 }
5a5012ec 9822 opn = "abs.ps";
6ea83fed 9823 break;
bf4120ad 9824 case OPC_MOV_PS:
5e755519 9825 check_cp1_64bitmode(ctx);
b6d96bed 9826 {
a7812ae4 9827 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9828
9829 gen_load_fpr64(ctx, fp0, fs);
9830 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9831 tcg_temp_free_i64(fp0);
b6d96bed 9832 }
5a5012ec 9833 opn = "mov.ps";
6ea83fed 9834 break;
bf4120ad 9835 case OPC_NEG_PS:
5e755519 9836 check_cp1_64bitmode(ctx);
b6d96bed 9837 {
a7812ae4 9838 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9839
9840 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9841 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9842 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9843 tcg_temp_free_i64(fp0);
b6d96bed 9844 }
5a5012ec 9845 opn = "neg.ps";
6ea83fed 9846 break;
bf4120ad 9847 case OPC_MOVCF_PS:
5e755519 9848 check_cp1_64bitmode(ctx);
7f6613ce 9849 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9850 opn = "movcf.ps";
6ea83fed 9851 break;
bf4120ad 9852 case OPC_MOVZ_PS:
5e755519 9853 check_cp1_64bitmode(ctx);
a16336e4 9854 {
42a268c2 9855 TCGLabel *l1 = gen_new_label();
30a3848b 9856 TCGv_i64 fp0;
a16336e4 9857
c9297f4d
AJ
9858 if (ft != 0)
9859 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9860 fp0 = tcg_temp_new_i64();
9861 gen_load_fpr64(ctx, fp0, fs);
9862 gen_store_fpr64(ctx, fp0, fd);
9863 tcg_temp_free_i64(fp0);
a16336e4
TS
9864 gen_set_label(l1);
9865 }
5a5012ec 9866 opn = "movz.ps";
6ea83fed 9867 break;
bf4120ad 9868 case OPC_MOVN_PS:
5e755519 9869 check_cp1_64bitmode(ctx);
a16336e4 9870 {
42a268c2 9871 TCGLabel *l1 = gen_new_label();
30a3848b 9872 TCGv_i64 fp0;
c9297f4d
AJ
9873
9874 if (ft != 0) {
9875 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9876 fp0 = tcg_temp_new_i64();
9877 gen_load_fpr64(ctx, fp0, fs);
9878 gen_store_fpr64(ctx, fp0, fd);
9879 tcg_temp_free_i64(fp0);
9880 gen_set_label(l1);
9881 }
a16336e4 9882 }
5a5012ec 9883 opn = "movn.ps";
6ea83fed 9884 break;
bf4120ad 9885 case OPC_ADDR_PS:
5e755519 9886 check_cp1_64bitmode(ctx);
b6d96bed 9887 {
a7812ae4
PB
9888 TCGv_i64 fp0 = tcg_temp_new_i64();
9889 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9890
9891 gen_load_fpr64(ctx, fp0, ft);
9892 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9893 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9894 tcg_temp_free_i64(fp1);
b6d96bed 9895 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9896 tcg_temp_free_i64(fp0);
b6d96bed 9897 }
fbcc6828
TS
9898 opn = "addr.ps";
9899 break;
bf4120ad 9900 case OPC_MULR_PS:
5e755519 9901 check_cp1_64bitmode(ctx);
b6d96bed 9902 {
a7812ae4
PB
9903 TCGv_i64 fp0 = tcg_temp_new_i64();
9904 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9905
9906 gen_load_fpr64(ctx, fp0, ft);
9907 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9908 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9909 tcg_temp_free_i64(fp1);
b6d96bed 9910 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9911 tcg_temp_free_i64(fp0);
b6d96bed 9912 }
57fa1fb3
TS
9913 opn = "mulr.ps";
9914 break;
bf4120ad 9915 case OPC_RECIP2_PS:
5e755519 9916 check_cp1_64bitmode(ctx);
b6d96bed 9917 {
a7812ae4
PB
9918 TCGv_i64 fp0 = tcg_temp_new_i64();
9919 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9920
9921 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9922 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9923 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9924 tcg_temp_free_i64(fp1);
b6d96bed 9925 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9926 tcg_temp_free_i64(fp0);
b6d96bed 9927 }
57fa1fb3
TS
9928 opn = "recip2.ps";
9929 break;
bf4120ad 9930 case OPC_RECIP1_PS:
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_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9937 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9938 tcg_temp_free_i64(fp0);
b6d96bed 9939 }
57fa1fb3
TS
9940 opn = "recip1.ps";
9941 break;
bf4120ad 9942 case OPC_RSQRT1_PS:
5e755519 9943 check_cp1_64bitmode(ctx);
b6d96bed 9944 {
a7812ae4 9945 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9946
9947 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9948 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9949 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9950 tcg_temp_free_i64(fp0);
b6d96bed 9951 }
57fa1fb3
TS
9952 opn = "rsqrt1.ps";
9953 break;
bf4120ad 9954 case OPC_RSQRT2_PS:
5e755519 9955 check_cp1_64bitmode(ctx);
b6d96bed 9956 {
a7812ae4
PB
9957 TCGv_i64 fp0 = tcg_temp_new_i64();
9958 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9959
9960 gen_load_fpr64(ctx, fp0, fs);
9961 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9962 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9963 tcg_temp_free_i64(fp1);
b6d96bed 9964 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9965 tcg_temp_free_i64(fp0);
b6d96bed 9966 }
57fa1fb3
TS
9967 opn = "rsqrt2.ps";
9968 break;
bf4120ad 9969 case OPC_CVT_S_PU:
5e755519 9970 check_cp1_64bitmode(ctx);
b6d96bed 9971 {
a7812ae4 9972 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9973
7f6613ce 9974 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9975 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9976 gen_store_fpr32(fp0, fd);
a7812ae4 9977 tcg_temp_free_i32(fp0);
b6d96bed 9978 }
5a5012ec 9979 opn = "cvt.s.pu";
dd016883 9980 break;
bf4120ad 9981 case OPC_CVT_PW_PS:
5e755519 9982 check_cp1_64bitmode(ctx);
b6d96bed 9983 {
a7812ae4 9984 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9985
9986 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9987 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9988 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9989 tcg_temp_free_i64(fp0);
b6d96bed 9990 }
5a5012ec 9991 opn = "cvt.pw.ps";
6ea83fed 9992 break;
bf4120ad 9993 case OPC_CVT_S_PL:
5e755519 9994 check_cp1_64bitmode(ctx);
b6d96bed 9995 {
a7812ae4 9996 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9997
9998 gen_load_fpr32(fp0, fs);
895c2d04 9999 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 10000 gen_store_fpr32(fp0, fd);
a7812ae4 10001 tcg_temp_free_i32(fp0);
b6d96bed 10002 }
5a5012ec 10003 opn = "cvt.s.pl";
6ea83fed 10004 break;
bf4120ad 10005 case OPC_PLL_PS:
5e755519 10006 check_cp1_64bitmode(ctx);
b6d96bed 10007 {
a7812ae4
PB
10008 TCGv_i32 fp0 = tcg_temp_new_i32();
10009 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
10010
10011 gen_load_fpr32(fp0, fs);
10012 gen_load_fpr32(fp1, ft);
7f6613ce 10013 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 10014 gen_store_fpr32(fp1, fd);
a7812ae4
PB
10015 tcg_temp_free_i32(fp0);
10016 tcg_temp_free_i32(fp1);
b6d96bed 10017 }
5a5012ec 10018 opn = "pll.ps";
6ea83fed 10019 break;
bf4120ad 10020 case OPC_PLU_PS:
5e755519 10021 check_cp1_64bitmode(ctx);
b6d96bed 10022 {
a7812ae4
PB
10023 TCGv_i32 fp0 = tcg_temp_new_i32();
10024 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
10025
10026 gen_load_fpr32(fp0, fs);
7f6613ce 10027 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10028 gen_store_fpr32(fp1, fd);
7f6613ce 10029 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10030 tcg_temp_free_i32(fp0);
10031 tcg_temp_free_i32(fp1);
b6d96bed 10032 }
5a5012ec
TS
10033 opn = "plu.ps";
10034 break;
bf4120ad 10035 case OPC_PUL_PS:
5e755519 10036 check_cp1_64bitmode(ctx);
b6d96bed 10037 {
a7812ae4
PB
10038 TCGv_i32 fp0 = tcg_temp_new_i32();
10039 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10040
7f6613ce 10041 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
10042 gen_load_fpr32(fp1, ft);
10043 gen_store_fpr32(fp1, fd);
7f6613ce 10044 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10045 tcg_temp_free_i32(fp0);
10046 tcg_temp_free_i32(fp1);
b6d96bed 10047 }
5a5012ec
TS
10048 opn = "pul.ps";
10049 break;
bf4120ad 10050 case OPC_PUU_PS:
5e755519 10051 check_cp1_64bitmode(ctx);
b6d96bed 10052 {
a7812ae4
PB
10053 TCGv_i32 fp0 = tcg_temp_new_i32();
10054 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10055
7f6613ce
PJ
10056 gen_load_fpr32h(ctx, fp0, fs);
10057 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10058 gen_store_fpr32(fp1, fd);
7f6613ce 10059 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10060 tcg_temp_free_i32(fp0);
10061 tcg_temp_free_i32(fp1);
b6d96bed 10062 }
5a5012ec
TS
10063 opn = "puu.ps";
10064 break;
bf4120ad
NF
10065 case OPC_CMP_F_PS:
10066 case OPC_CMP_UN_PS:
10067 case OPC_CMP_EQ_PS:
10068 case OPC_CMP_UEQ_PS:
10069 case OPC_CMP_OLT_PS:
10070 case OPC_CMP_ULT_PS:
10071 case OPC_CMP_OLE_PS:
10072 case OPC_CMP_ULE_PS:
10073 case OPC_CMP_SF_PS:
10074 case OPC_CMP_NGLE_PS:
10075 case OPC_CMP_SEQ_PS:
10076 case OPC_CMP_NGL_PS:
10077 case OPC_CMP_LT_PS:
10078 case OPC_CMP_NGE_PS:
10079 case OPC_CMP_LE_PS:
10080 case OPC_CMP_NGT_PS:
8153667c
NF
10081 if (ctx->opcode & (1 << 6)) {
10082 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10083 opn = condnames_abs[func-48];
10084 } else {
10085 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10086 opn = condnames[func-48];
5a1e8ffb 10087 }
6ea83fed 10088 break;
5a5012ec 10089 default:
923617a3 10090 MIPS_INVAL(opn);
e397ee33 10091 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10092 return;
10093 }
2abf314d 10094 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10095 switch (optype) {
10096 case BINOP:
6ea83fed 10097 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10098 break;
10099 case CMPOP:
10100 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10101 break;
10102 default:
6ea83fed 10103 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10104 break;
10105 }
6ea83fed 10106}
6af0bf9c 10107
5a5012ec 10108/* Coprocessor 3 (FPU) */
5e755519
TS
10109static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10110 int fd, int fs, int base, int index)
7a387fff 10111{
923617a3 10112 const char *opn = "extended float load/store";
93b12ccc 10113 int store = 0;
4e2474d6 10114 TCGv t0 = tcg_temp_new();
7a387fff 10115
93b12ccc 10116 if (base == 0) {
6c5c1e20 10117 gen_load_gpr(t0, index);
93b12ccc 10118 } else if (index == 0) {
6c5c1e20 10119 gen_load_gpr(t0, base);
93b12ccc 10120 } else {
05168674 10121 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10122 }
5a5012ec 10123 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10124 memory access. */
5a5012ec
TS
10125 switch (opc) {
10126 case OPC_LWXC1:
8c0ab41f 10127 check_cop1x(ctx);
b6d96bed 10128 {
a7812ae4 10129 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10130
5f68f5ae 10131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10132 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 10133 gen_store_fpr32(fp0, fd);
a7812ae4 10134 tcg_temp_free_i32(fp0);
b6d96bed 10135 }
5a5012ec
TS
10136 opn = "lwxc1";
10137 break;
10138 case OPC_LDXC1:
8c0ab41f
AJ
10139 check_cop1x(ctx);
10140 check_cp1_registers(ctx, fd);
b6d96bed 10141 {
a7812ae4 10142 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10143 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10144 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10145 tcg_temp_free_i64(fp0);
b6d96bed 10146 }
5a5012ec
TS
10147 opn = "ldxc1";
10148 break;
10149 case OPC_LUXC1:
8c0ab41f 10150 check_cp1_64bitmode(ctx);
6c5c1e20 10151 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10152 {
a7812ae4 10153 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10154
5f68f5ae 10155 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10156 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10157 tcg_temp_free_i64(fp0);
b6d96bed 10158 }
5a5012ec
TS
10159 opn = "luxc1";
10160 break;
10161 case OPC_SWXC1:
8c0ab41f 10162 check_cop1x(ctx);
b6d96bed 10163 {
a7812ae4 10164 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10165 gen_load_fpr32(fp0, fs);
5f68f5ae 10166 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10167 tcg_temp_free_i32(fp0);
b6d96bed 10168 }
5a5012ec 10169 opn = "swxc1";
93b12ccc 10170 store = 1;
5a5012ec
TS
10171 break;
10172 case OPC_SDXC1:
8c0ab41f
AJ
10173 check_cop1x(ctx);
10174 check_cp1_registers(ctx, fs);
b6d96bed 10175 {
a7812ae4 10176 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10177 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10178 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10179 tcg_temp_free_i64(fp0);
b6d96bed 10180 }
5a5012ec 10181 opn = "sdxc1";
93b12ccc 10182 store = 1;
5a5012ec
TS
10183 break;
10184 case OPC_SUXC1:
8c0ab41f 10185 check_cp1_64bitmode(ctx);
6c5c1e20 10186 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10187 {
a7812ae4 10188 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10189 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10190 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10191 tcg_temp_free_i64(fp0);
b6d96bed 10192 }
5a5012ec 10193 opn = "suxc1";
93b12ccc 10194 store = 1;
5a5012ec 10195 break;
5a5012ec 10196 }
6c5c1e20 10197 tcg_temp_free(t0);
2abf314d 10198 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10199 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10200 regnames[index], regnames[base]);
5a5012ec
TS
10201}
10202
5e755519
TS
10203static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10204 int fd, int fr, int fs, int ft)
5a5012ec 10205{
923617a3 10206 const char *opn = "flt3_arith";
5a5012ec 10207
5a5012ec
TS
10208 switch (opc) {
10209 case OPC_ALNV_PS:
b8aa4598 10210 check_cp1_64bitmode(ctx);
a16336e4 10211 {
a7812ae4 10212 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10213 TCGv_i32 fp = tcg_temp_new_i32();
10214 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10215 TCGLabel *l1 = gen_new_label();
10216 TCGLabel *l2 = gen_new_label();
a16336e4 10217
6c5c1e20
TS
10218 gen_load_gpr(t0, fr);
10219 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10220
10221 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 10222 gen_load_fpr32(fp, fs);
7f6613ce 10223 gen_load_fpr32h(ctx, fph, fs);
c905fdac 10224 gen_store_fpr32(fp, fd);
7f6613ce 10225 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10226 tcg_gen_br(l2);
10227 gen_set_label(l1);
6c5c1e20
TS
10228 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10229 tcg_temp_free(t0);
a16336e4 10230#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 10231 gen_load_fpr32(fp, fs);
7f6613ce
PJ
10232 gen_load_fpr32h(ctx, fph, ft);
10233 gen_store_fpr32h(ctx, fp, fd);
c905fdac 10234 gen_store_fpr32(fph, fd);
a16336e4 10235#else
7f6613ce 10236 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
10237 gen_load_fpr32(fp, ft);
10238 gen_store_fpr32(fph, fd);
7f6613ce 10239 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10240#endif
10241 gen_set_label(l2);
c905fdac
AJ
10242 tcg_temp_free_i32(fp);
10243 tcg_temp_free_i32(fph);
a16336e4 10244 }
5a5012ec
TS
10245 opn = "alnv.ps";
10246 break;
10247 case OPC_MADD_S:
b8aa4598 10248 check_cop1x(ctx);
b6d96bed 10249 {
a7812ae4
PB
10250 TCGv_i32 fp0 = tcg_temp_new_i32();
10251 TCGv_i32 fp1 = tcg_temp_new_i32();
10252 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10253
10254 gen_load_fpr32(fp0, fs);
10255 gen_load_fpr32(fp1, ft);
10256 gen_load_fpr32(fp2, fr);
b3d6cd44 10257 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10258 tcg_temp_free_i32(fp0);
10259 tcg_temp_free_i32(fp1);
b6d96bed 10260 gen_store_fpr32(fp2, fd);
a7812ae4 10261 tcg_temp_free_i32(fp2);
b6d96bed 10262 }
5a5012ec
TS
10263 opn = "madd.s";
10264 break;
10265 case OPC_MADD_D:
b8aa4598
TS
10266 check_cop1x(ctx);
10267 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10268 {
a7812ae4
PB
10269 TCGv_i64 fp0 = tcg_temp_new_i64();
10270 TCGv_i64 fp1 = tcg_temp_new_i64();
10271 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10272
10273 gen_load_fpr64(ctx, fp0, fs);
10274 gen_load_fpr64(ctx, fp1, ft);
10275 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10276 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10277 tcg_temp_free_i64(fp0);
10278 tcg_temp_free_i64(fp1);
b6d96bed 10279 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10280 tcg_temp_free_i64(fp2);
b6d96bed 10281 }
5a5012ec
TS
10282 opn = "madd.d";
10283 break;
10284 case OPC_MADD_PS:
b8aa4598 10285 check_cp1_64bitmode(ctx);
b6d96bed 10286 {
a7812ae4
PB
10287 TCGv_i64 fp0 = tcg_temp_new_i64();
10288 TCGv_i64 fp1 = tcg_temp_new_i64();
10289 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10290
10291 gen_load_fpr64(ctx, fp0, fs);
10292 gen_load_fpr64(ctx, fp1, ft);
10293 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10294 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10295 tcg_temp_free_i64(fp0);
10296 tcg_temp_free_i64(fp1);
b6d96bed 10297 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10298 tcg_temp_free_i64(fp2);
b6d96bed 10299 }
5a5012ec
TS
10300 opn = "madd.ps";
10301 break;
10302 case OPC_MSUB_S:
b8aa4598 10303 check_cop1x(ctx);
b6d96bed 10304 {
a7812ae4
PB
10305 TCGv_i32 fp0 = tcg_temp_new_i32();
10306 TCGv_i32 fp1 = tcg_temp_new_i32();
10307 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10308
10309 gen_load_fpr32(fp0, fs);
10310 gen_load_fpr32(fp1, ft);
10311 gen_load_fpr32(fp2, fr);
b3d6cd44 10312 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10313 tcg_temp_free_i32(fp0);
10314 tcg_temp_free_i32(fp1);
b6d96bed 10315 gen_store_fpr32(fp2, fd);
a7812ae4 10316 tcg_temp_free_i32(fp2);
b6d96bed 10317 }
5a5012ec
TS
10318 opn = "msub.s";
10319 break;
10320 case OPC_MSUB_D:
b8aa4598
TS
10321 check_cop1x(ctx);
10322 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10323 {
a7812ae4
PB
10324 TCGv_i64 fp0 = tcg_temp_new_i64();
10325 TCGv_i64 fp1 = tcg_temp_new_i64();
10326 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10327
10328 gen_load_fpr64(ctx, fp0, fs);
10329 gen_load_fpr64(ctx, fp1, ft);
10330 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10331 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10332 tcg_temp_free_i64(fp0);
10333 tcg_temp_free_i64(fp1);
b6d96bed 10334 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10335 tcg_temp_free_i64(fp2);
b6d96bed 10336 }
5a5012ec
TS
10337 opn = "msub.d";
10338 break;
10339 case OPC_MSUB_PS:
b8aa4598 10340 check_cp1_64bitmode(ctx);
b6d96bed 10341 {
a7812ae4
PB
10342 TCGv_i64 fp0 = tcg_temp_new_i64();
10343 TCGv_i64 fp1 = tcg_temp_new_i64();
10344 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10345
10346 gen_load_fpr64(ctx, fp0, fs);
10347 gen_load_fpr64(ctx, fp1, ft);
10348 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10349 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10350 tcg_temp_free_i64(fp0);
10351 tcg_temp_free_i64(fp1);
b6d96bed 10352 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10353 tcg_temp_free_i64(fp2);
b6d96bed 10354 }
5a5012ec
TS
10355 opn = "msub.ps";
10356 break;
10357 case OPC_NMADD_S:
b8aa4598 10358 check_cop1x(ctx);
b6d96bed 10359 {
a7812ae4
PB
10360 TCGv_i32 fp0 = tcg_temp_new_i32();
10361 TCGv_i32 fp1 = tcg_temp_new_i32();
10362 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10363
10364 gen_load_fpr32(fp0, fs);
10365 gen_load_fpr32(fp1, ft);
10366 gen_load_fpr32(fp2, fr);
b3d6cd44 10367 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10368 tcg_temp_free_i32(fp0);
10369 tcg_temp_free_i32(fp1);
b6d96bed 10370 gen_store_fpr32(fp2, fd);
a7812ae4 10371 tcg_temp_free_i32(fp2);
b6d96bed 10372 }
5a5012ec
TS
10373 opn = "nmadd.s";
10374 break;
10375 case OPC_NMADD_D:
b8aa4598
TS
10376 check_cop1x(ctx);
10377 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10378 {
a7812ae4
PB
10379 TCGv_i64 fp0 = tcg_temp_new_i64();
10380 TCGv_i64 fp1 = tcg_temp_new_i64();
10381 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10382
10383 gen_load_fpr64(ctx, fp0, fs);
10384 gen_load_fpr64(ctx, fp1, ft);
10385 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10386 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10387 tcg_temp_free_i64(fp0);
10388 tcg_temp_free_i64(fp1);
b6d96bed 10389 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10390 tcg_temp_free_i64(fp2);
b6d96bed 10391 }
5a5012ec
TS
10392 opn = "nmadd.d";
10393 break;
10394 case OPC_NMADD_PS:
b8aa4598 10395 check_cp1_64bitmode(ctx);
b6d96bed 10396 {
a7812ae4
PB
10397 TCGv_i64 fp0 = tcg_temp_new_i64();
10398 TCGv_i64 fp1 = tcg_temp_new_i64();
10399 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10400
10401 gen_load_fpr64(ctx, fp0, fs);
10402 gen_load_fpr64(ctx, fp1, ft);
10403 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10404 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10405 tcg_temp_free_i64(fp0);
10406 tcg_temp_free_i64(fp1);
b6d96bed 10407 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10408 tcg_temp_free_i64(fp2);
b6d96bed 10409 }
5a5012ec
TS
10410 opn = "nmadd.ps";
10411 break;
10412 case OPC_NMSUB_S:
b8aa4598 10413 check_cop1x(ctx);
b6d96bed 10414 {
a7812ae4
PB
10415 TCGv_i32 fp0 = tcg_temp_new_i32();
10416 TCGv_i32 fp1 = tcg_temp_new_i32();
10417 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10418
10419 gen_load_fpr32(fp0, fs);
10420 gen_load_fpr32(fp1, ft);
10421 gen_load_fpr32(fp2, fr);
b3d6cd44 10422 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10423 tcg_temp_free_i32(fp0);
10424 tcg_temp_free_i32(fp1);
b6d96bed 10425 gen_store_fpr32(fp2, fd);
a7812ae4 10426 tcg_temp_free_i32(fp2);
b6d96bed 10427 }
5a5012ec
TS
10428 opn = "nmsub.s";
10429 break;
10430 case OPC_NMSUB_D:
b8aa4598
TS
10431 check_cop1x(ctx);
10432 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10433 {
a7812ae4
PB
10434 TCGv_i64 fp0 = tcg_temp_new_i64();
10435 TCGv_i64 fp1 = tcg_temp_new_i64();
10436 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10437
10438 gen_load_fpr64(ctx, fp0, fs);
10439 gen_load_fpr64(ctx, fp1, ft);
10440 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10441 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10442 tcg_temp_free_i64(fp0);
10443 tcg_temp_free_i64(fp1);
b6d96bed 10444 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10445 tcg_temp_free_i64(fp2);
b6d96bed 10446 }
5a5012ec
TS
10447 opn = "nmsub.d";
10448 break;
10449 case OPC_NMSUB_PS:
b8aa4598 10450 check_cp1_64bitmode(ctx);
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_nmsub_ps(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 opn = "nmsub.ps";
10466 break;
923617a3
TS
10467 default:
10468 MIPS_INVAL(opn);
5a5012ec
TS
10469 generate_exception (ctx, EXCP_RI);
10470 return;
10471 }
2abf314d 10472 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10473 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10474 fregnames[fs], fregnames[ft]);
7a387fff
TS
10475}
10476
d75c135e 10477static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10478{
10479 TCGv t0;
10480
b3167288
RH
10481#if !defined(CONFIG_USER_ONLY)
10482 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10483 Therefore only check the ISA in system mode. */
d75c135e 10484 check_insn(ctx, ISA_MIPS32R2);
b3167288 10485#endif
26ebe468
NF
10486 t0 = tcg_temp_new();
10487
10488 switch (rd) {
10489 case 0:
10490 save_cpu_state(ctx, 1);
895c2d04 10491 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10492 gen_store_gpr(t0, rt);
10493 break;
10494 case 1:
10495 save_cpu_state(ctx, 1);
895c2d04 10496 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10497 gen_store_gpr(t0, rt);
10498 break;
10499 case 2:
10500 save_cpu_state(ctx, 1);
895c2d04 10501 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10502 gen_store_gpr(t0, rt);
10503 break;
10504 case 3:
10505 save_cpu_state(ctx, 1);
895c2d04 10506 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10507 gen_store_gpr(t0, rt);
10508 break;
10509 case 29:
10510#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10511 tcg_gen_ld_tl(t0, cpu_env,
10512 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10513 gen_store_gpr(t0, rt);
10514 break;
10515#else
d279279e
PJ
10516 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10517 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10518 tcg_gen_ld_tl(t0, cpu_env,
10519 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10520 gen_store_gpr(t0, rt);
10521 } else {
10522 generate_exception(ctx, EXCP_RI);
10523 }
10524 break;
26ebe468
NF
10525#endif
10526 default: /* Invalid */
10527 MIPS_INVAL("rdhwr");
10528 generate_exception(ctx, EXCP_RI);
10529 break;
10530 }
10531 tcg_temp_free(t0);
10532}
10533
a5f53390
LA
10534static inline void clear_branch_hflags(DisasContext *ctx)
10535{
10536 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10537 if (ctx->bstate == BS_NONE) {
10538 save_cpu_state(ctx, 0);
10539 } else {
10540 /* it is not safe to save ctx->hflags as hflags may be changed
10541 in execution time by the instruction in delay / forbidden slot. */
10542 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10543 }
10544}
10545
31837be3 10546static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10547{
10548 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10549 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10550 /* Branches completion */
a5f53390 10551 clear_branch_hflags(ctx);
c9602061 10552 ctx->bstate = BS_BRANCH;
c9602061 10553 /* FIXME: Need to clear can_do_io. */
364d4831 10554 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10555 case MIPS_HFLAG_FBNSLOT:
10556 MIPS_DEBUG("forbidden slot");
10557 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10558 break;
c9602061
NF
10559 case MIPS_HFLAG_B:
10560 /* unconditional branch */
10561 MIPS_DEBUG("unconditional branch");
364d4831
NF
10562 if (proc_hflags & MIPS_HFLAG_BX) {
10563 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10564 }
c9602061
NF
10565 gen_goto_tb(ctx, 0, ctx->btarget);
10566 break;
10567 case MIPS_HFLAG_BL:
10568 /* blikely taken case */
10569 MIPS_DEBUG("blikely branch taken");
10570 gen_goto_tb(ctx, 0, ctx->btarget);
10571 break;
10572 case MIPS_HFLAG_BC:
10573 /* Conditional branch */
10574 MIPS_DEBUG("conditional branch");
10575 {
42a268c2 10576 TCGLabel *l1 = gen_new_label();
c9602061
NF
10577
10578 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10579 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10580 gen_set_label(l1);
10581 gen_goto_tb(ctx, 0, ctx->btarget);
10582 }
10583 break;
10584 case MIPS_HFLAG_BR:
10585 /* unconditional branch to register */
10586 MIPS_DEBUG("branch to register");
d75c135e 10587 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10588 TCGv t0 = tcg_temp_new();
10589 TCGv_i32 t1 = tcg_temp_new_i32();
10590
10591 tcg_gen_andi_tl(t0, btarget, 0x1);
10592 tcg_gen_trunc_tl_i32(t1, t0);
10593 tcg_temp_free(t0);
10594 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10595 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10596 tcg_gen_or_i32(hflags, hflags, t1);
10597 tcg_temp_free_i32(t1);
10598
10599 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10600 } else {
10601 tcg_gen_mov_tl(cpu_PC, btarget);
10602 }
c9602061
NF
10603 if (ctx->singlestep_enabled) {
10604 save_cpu_state(ctx, 0);
895c2d04 10605 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10606 }
10607 tcg_gen_exit_tb(0);
10608 break;
10609 default:
a5f53390
LA
10610 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10611 abort();
c9602061
NF
10612 }
10613 }
10614}
10615
7a387fff 10616/* ISA extensions (ASEs) */
6af0bf9c 10617/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10618
10619/* MIPS16 major opcodes */
10620enum {
10621 M16_OPC_ADDIUSP = 0x00,
10622 M16_OPC_ADDIUPC = 0x01,
10623 M16_OPC_B = 0x02,
10624 M16_OPC_JAL = 0x03,
10625 M16_OPC_BEQZ = 0x04,
10626 M16_OPC_BNEQZ = 0x05,
10627 M16_OPC_SHIFT = 0x06,
10628 M16_OPC_LD = 0x07,
10629 M16_OPC_RRIA = 0x08,
10630 M16_OPC_ADDIU8 = 0x09,
10631 M16_OPC_SLTI = 0x0a,
10632 M16_OPC_SLTIU = 0x0b,
10633 M16_OPC_I8 = 0x0c,
10634 M16_OPC_LI = 0x0d,
10635 M16_OPC_CMPI = 0x0e,
10636 M16_OPC_SD = 0x0f,
10637 M16_OPC_LB = 0x10,
10638 M16_OPC_LH = 0x11,
10639 M16_OPC_LWSP = 0x12,
10640 M16_OPC_LW = 0x13,
10641 M16_OPC_LBU = 0x14,
10642 M16_OPC_LHU = 0x15,
10643 M16_OPC_LWPC = 0x16,
10644 M16_OPC_LWU = 0x17,
10645 M16_OPC_SB = 0x18,
10646 M16_OPC_SH = 0x19,
10647 M16_OPC_SWSP = 0x1a,
10648 M16_OPC_SW = 0x1b,
10649 M16_OPC_RRR = 0x1c,
10650 M16_OPC_RR = 0x1d,
10651 M16_OPC_EXTEND = 0x1e,
10652 M16_OPC_I64 = 0x1f
10653};
10654
10655/* I8 funct field */
10656enum {
10657 I8_BTEQZ = 0x0,
10658 I8_BTNEZ = 0x1,
10659 I8_SWRASP = 0x2,
10660 I8_ADJSP = 0x3,
10661 I8_SVRS = 0x4,
10662 I8_MOV32R = 0x5,
10663 I8_MOVR32 = 0x7
10664};
10665
10666/* RRR f field */
10667enum {
10668 RRR_DADDU = 0x0,
10669 RRR_ADDU = 0x1,
10670 RRR_DSUBU = 0x2,
10671 RRR_SUBU = 0x3
10672};
10673
10674/* RR funct field */
10675enum {
10676 RR_JR = 0x00,
10677 RR_SDBBP = 0x01,
10678 RR_SLT = 0x02,
10679 RR_SLTU = 0x03,
10680 RR_SLLV = 0x04,
10681 RR_BREAK = 0x05,
10682 RR_SRLV = 0x06,
10683 RR_SRAV = 0x07,
10684 RR_DSRL = 0x08,
10685 RR_CMP = 0x0a,
10686 RR_NEG = 0x0b,
10687 RR_AND = 0x0c,
10688 RR_OR = 0x0d,
10689 RR_XOR = 0x0e,
10690 RR_NOT = 0x0f,
10691 RR_MFHI = 0x10,
10692 RR_CNVT = 0x11,
10693 RR_MFLO = 0x12,
10694 RR_DSRA = 0x13,
10695 RR_DSLLV = 0x14,
10696 RR_DSRLV = 0x16,
10697 RR_DSRAV = 0x17,
10698 RR_MULT = 0x18,
10699 RR_MULTU = 0x19,
10700 RR_DIV = 0x1a,
10701 RR_DIVU = 0x1b,
10702 RR_DMULT = 0x1c,
10703 RR_DMULTU = 0x1d,
10704 RR_DDIV = 0x1e,
10705 RR_DDIVU = 0x1f
10706};
10707
10708/* I64 funct field */
10709enum {
10710 I64_LDSP = 0x0,
10711 I64_SDSP = 0x1,
10712 I64_SDRASP = 0x2,
10713 I64_DADJSP = 0x3,
10714 I64_LDPC = 0x4,
364d4831 10715 I64_DADDIU5 = 0x5,
6ea219d0
NF
10716 I64_DADDIUPC = 0x6,
10717 I64_DADDIUSP = 0x7
10718};
10719
10720/* RR ry field for CNVT */
10721enum {
10722 RR_RY_CNVT_ZEB = 0x0,
10723 RR_RY_CNVT_ZEH = 0x1,
10724 RR_RY_CNVT_ZEW = 0x2,
10725 RR_RY_CNVT_SEB = 0x4,
10726 RR_RY_CNVT_SEH = 0x5,
10727 RR_RY_CNVT_SEW = 0x6,
10728};
10729
364d4831
NF
10730static int xlat (int r)
10731{
10732 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10733
10734 return map[r];
10735}
10736
10737static void gen_mips16_save (DisasContext *ctx,
10738 int xsregs, int aregs,
10739 int do_ra, int do_s0, int do_s1,
10740 int framesize)
10741{
10742 TCGv t0 = tcg_temp_new();
10743 TCGv t1 = tcg_temp_new();
c48245f0 10744 TCGv t2 = tcg_temp_new();
364d4831
NF
10745 int args, astatic;
10746
10747 switch (aregs) {
10748 case 0:
10749 case 1:
10750 case 2:
10751 case 3:
10752 case 11:
10753 args = 0;
10754 break;
10755 case 4:
10756 case 5:
10757 case 6:
10758 case 7:
10759 args = 1;
10760 break;
10761 case 8:
10762 case 9:
10763 case 10:
10764 args = 2;
10765 break;
10766 case 12:
10767 case 13:
10768 args = 3;
10769 break;
10770 case 14:
10771 args = 4;
10772 break;
10773 default:
10774 generate_exception(ctx, EXCP_RI);
10775 return;
10776 }
10777
10778 switch (args) {
10779 case 4:
10780 gen_base_offset_addr(ctx, t0, 29, 12);
10781 gen_load_gpr(t1, 7);
5f68f5ae 10782 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10783 /* Fall through */
10784 case 3:
10785 gen_base_offset_addr(ctx, t0, 29, 8);
10786 gen_load_gpr(t1, 6);
5f68f5ae 10787 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10788 /* Fall through */
10789 case 2:
10790 gen_base_offset_addr(ctx, t0, 29, 4);
10791 gen_load_gpr(t1, 5);
5f68f5ae 10792 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10793 /* Fall through */
10794 case 1:
10795 gen_base_offset_addr(ctx, t0, 29, 0);
10796 gen_load_gpr(t1, 4);
5f68f5ae 10797 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10798 }
10799
10800 gen_load_gpr(t0, 29);
10801
5f68f5ae 10802#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10803 tcg_gen_movi_tl(t2, -4); \
10804 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10805 gen_load_gpr(t1, reg); \
10806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10807 } while (0)
10808
10809 if (do_ra) {
10810 DECR_AND_STORE(31);
10811 }
10812
10813 switch (xsregs) {
10814 case 7:
10815 DECR_AND_STORE(30);
10816 /* Fall through */
10817 case 6:
10818 DECR_AND_STORE(23);
10819 /* Fall through */
10820 case 5:
10821 DECR_AND_STORE(22);
10822 /* Fall through */
10823 case 4:
10824 DECR_AND_STORE(21);
10825 /* Fall through */
10826 case 3:
10827 DECR_AND_STORE(20);
10828 /* Fall through */
10829 case 2:
10830 DECR_AND_STORE(19);
10831 /* Fall through */
10832 case 1:
10833 DECR_AND_STORE(18);
10834 }
10835
10836 if (do_s1) {
10837 DECR_AND_STORE(17);
10838 }
10839 if (do_s0) {
10840 DECR_AND_STORE(16);
10841 }
10842
10843 switch (aregs) {
10844 case 0:
10845 case 4:
10846 case 8:
10847 case 12:
10848 case 14:
10849 astatic = 0;
10850 break;
10851 case 1:
10852 case 5:
10853 case 9:
10854 case 13:
10855 astatic = 1;
10856 break;
10857 case 2:
10858 case 6:
10859 case 10:
10860 astatic = 2;
10861 break;
10862 case 3:
10863 case 7:
10864 astatic = 3;
10865 break;
10866 case 11:
10867 astatic = 4;
10868 break;
10869 default:
10870 generate_exception(ctx, EXCP_RI);
10871 return;
10872 }
10873
10874 if (astatic > 0) {
10875 DECR_AND_STORE(7);
10876 if (astatic > 1) {
10877 DECR_AND_STORE(6);
10878 if (astatic > 2) {
10879 DECR_AND_STORE(5);
10880 if (astatic > 3) {
10881 DECR_AND_STORE(4);
10882 }
10883 }
10884 }
10885 }
10886#undef DECR_AND_STORE
10887
c48245f0
MR
10888 tcg_gen_movi_tl(t2, -framesize);
10889 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10890 tcg_temp_free(t0);
10891 tcg_temp_free(t1);
c48245f0 10892 tcg_temp_free(t2);
364d4831
NF
10893}
10894
10895static void gen_mips16_restore (DisasContext *ctx,
10896 int xsregs, int aregs,
10897 int do_ra, int do_s0, int do_s1,
10898 int framesize)
10899{
10900 int astatic;
10901 TCGv t0 = tcg_temp_new();
10902 TCGv t1 = tcg_temp_new();
c48245f0 10903 TCGv t2 = tcg_temp_new();
364d4831 10904
c48245f0
MR
10905 tcg_gen_movi_tl(t2, framesize);
10906 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 10907
5f68f5ae 10908#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
10909 tcg_gen_movi_tl(t2, -4); \
10910 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10911 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10912 gen_store_gpr(t1, reg); \
364d4831
NF
10913 } while (0)
10914
10915 if (do_ra) {
10916 DECR_AND_LOAD(31);
10917 }
10918
10919 switch (xsregs) {
10920 case 7:
10921 DECR_AND_LOAD(30);
10922 /* Fall through */
10923 case 6:
10924 DECR_AND_LOAD(23);
10925 /* Fall through */
10926 case 5:
10927 DECR_AND_LOAD(22);
10928 /* Fall through */
10929 case 4:
10930 DECR_AND_LOAD(21);
10931 /* Fall through */
10932 case 3:
10933 DECR_AND_LOAD(20);
10934 /* Fall through */
10935 case 2:
10936 DECR_AND_LOAD(19);
10937 /* Fall through */
10938 case 1:
10939 DECR_AND_LOAD(18);
10940 }
10941
10942 if (do_s1) {
10943 DECR_AND_LOAD(17);
10944 }
10945 if (do_s0) {
10946 DECR_AND_LOAD(16);
10947 }
10948
10949 switch (aregs) {
10950 case 0:
10951 case 4:
10952 case 8:
10953 case 12:
10954 case 14:
10955 astatic = 0;
10956 break;
10957 case 1:
10958 case 5:
10959 case 9:
10960 case 13:
10961 astatic = 1;
10962 break;
10963 case 2:
10964 case 6:
10965 case 10:
10966 astatic = 2;
10967 break;
10968 case 3:
10969 case 7:
10970 astatic = 3;
10971 break;
10972 case 11:
10973 astatic = 4;
10974 break;
10975 default:
10976 generate_exception(ctx, EXCP_RI);
10977 return;
10978 }
10979
10980 if (astatic > 0) {
10981 DECR_AND_LOAD(7);
10982 if (astatic > 1) {
10983 DECR_AND_LOAD(6);
10984 if (astatic > 2) {
10985 DECR_AND_LOAD(5);
10986 if (astatic > 3) {
10987 DECR_AND_LOAD(4);
10988 }
10989 }
10990 }
10991 }
10992#undef DECR_AND_LOAD
10993
c48245f0
MR
10994 tcg_gen_movi_tl(t2, framesize);
10995 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10996 tcg_temp_free(t0);
10997 tcg_temp_free(t1);
c48245f0 10998 tcg_temp_free(t2);
364d4831
NF
10999}
11000
11001static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11002 int is_64_bit, int extended)
11003{
11004 TCGv t0;
11005
11006 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11007 generate_exception(ctx, EXCP_RI);
11008 return;
11009 }
11010
11011 t0 = tcg_temp_new();
11012
11013 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11014 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11015 if (!is_64_bit) {
11016 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11017 }
11018
11019 tcg_temp_free(t0);
11020}
11021
11022#if defined(TARGET_MIPS64)
d75c135e 11023static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11024 int ry, int funct, int16_t offset,
11025 int extended)
11026{
11027 switch (funct) {
11028 case I64_LDSP:
d9224450 11029 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11030 check_mips_64(ctx);
11031 offset = extended ? offset : offset << 3;
d75c135e 11032 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11033 break;
11034 case I64_SDSP:
d9224450 11035 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11036 check_mips_64(ctx);
11037 offset = extended ? offset : offset << 3;
5c13fdfd 11038 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11039 break;
11040 case I64_SDRASP:
d9224450 11041 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11042 check_mips_64(ctx);
11043 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11044 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11045 break;
11046 case I64_DADJSP:
d9224450 11047 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11048 check_mips_64(ctx);
11049 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11050 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11051 break;
11052 case I64_LDPC:
d9224450
MR
11053 check_insn(ctx, ISA_MIPS3);
11054 check_mips_64(ctx);
364d4831
NF
11055 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11056 generate_exception(ctx, EXCP_RI);
11057 } else {
11058 offset = extended ? offset : offset << 3;
d75c135e 11059 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11060 }
11061 break;
11062 case I64_DADDIU5:
d9224450 11063 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11064 check_mips_64(ctx);
11065 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11066 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11067 break;
11068 case I64_DADDIUPC:
d9224450 11069 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11070 check_mips_64(ctx);
11071 offset = extended ? offset : offset << 2;
11072 gen_addiupc(ctx, ry, offset, 1, extended);
11073 break;
11074 case I64_DADDIUSP:
d9224450 11075 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11076 check_mips_64(ctx);
11077 offset = extended ? offset : offset << 2;
d75c135e 11078 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11079 break;
11080 }
11081}
11082#endif
11083
240ce26a 11084static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11085{
895c2d04 11086 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11087 int op, rx, ry, funct, sa;
11088 int16_t imm, offset;
11089
11090 ctx->opcode = (ctx->opcode << 16) | extend;
11091 op = (ctx->opcode >> 11) & 0x1f;
11092 sa = (ctx->opcode >> 22) & 0x1f;
11093 funct = (ctx->opcode >> 8) & 0x7;
11094 rx = xlat((ctx->opcode >> 8) & 0x7);
11095 ry = xlat((ctx->opcode >> 5) & 0x7);
11096 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11097 | ((ctx->opcode >> 21) & 0x3f) << 5
11098 | (ctx->opcode & 0x1f));
11099
11100 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11101 counterparts. */
11102 switch (op) {
11103 case M16_OPC_ADDIUSP:
d75c135e 11104 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11105 break;
11106 case M16_OPC_ADDIUPC:
11107 gen_addiupc(ctx, rx, imm, 0, 1);
11108 break;
11109 case M16_OPC_B:
b231c103 11110 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11111 /* No delay slot, so just process as a normal instruction */
11112 break;
11113 case M16_OPC_BEQZ:
b231c103 11114 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11115 /* No delay slot, so just process as a normal instruction */
11116 break;
11117 case M16_OPC_BNEQZ:
b231c103 11118 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11119 /* No delay slot, so just process as a normal instruction */
11120 break;
11121 case M16_OPC_SHIFT:
11122 switch (ctx->opcode & 0x3) {
11123 case 0x0:
d75c135e 11124 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11125 break;
11126 case 0x1:
11127#if defined(TARGET_MIPS64)
11128 check_mips_64(ctx);
d75c135e 11129 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11130#else
11131 generate_exception(ctx, EXCP_RI);
11132#endif
11133 break;
11134 case 0x2:
d75c135e 11135 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11136 break;
11137 case 0x3:
d75c135e 11138 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11139 break;
11140 }
11141 break;
11142#if defined(TARGET_MIPS64)
11143 case M16_OPC_LD:
d9224450 11144 check_insn(ctx, ISA_MIPS3);
d75de749 11145 check_mips_64(ctx);
d75c135e 11146 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11147 break;
11148#endif
11149 case M16_OPC_RRIA:
11150 imm = ctx->opcode & 0xf;
11151 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11152 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11153 imm = (int16_t) (imm << 1) >> 1;
11154 if ((ctx->opcode >> 4) & 0x1) {
11155#if defined(TARGET_MIPS64)
11156 check_mips_64(ctx);
d75c135e 11157 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11158#else
11159 generate_exception(ctx, EXCP_RI);
11160#endif
11161 } else {
d75c135e 11162 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11163 }
11164 break;
11165 case M16_OPC_ADDIU8:
d75c135e 11166 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11167 break;
11168 case M16_OPC_SLTI:
d75c135e 11169 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11170 break;
11171 case M16_OPC_SLTIU:
d75c135e 11172 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11173 break;
11174 case M16_OPC_I8:
11175 switch (funct) {
11176 case I8_BTEQZ:
b231c103 11177 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11178 break;
11179 case I8_BTNEZ:
b231c103 11180 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11181 break;
11182 case I8_SWRASP:
5c13fdfd 11183 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11184 break;
11185 case I8_ADJSP:
d75c135e 11186 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11187 break;
11188 case I8_SVRS:
d9224450 11189 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11190 {
11191 int xsregs = (ctx->opcode >> 24) & 0x7;
11192 int aregs = (ctx->opcode >> 16) & 0xf;
11193 int do_ra = (ctx->opcode >> 6) & 0x1;
11194 int do_s0 = (ctx->opcode >> 5) & 0x1;
11195 int do_s1 = (ctx->opcode >> 4) & 0x1;
11196 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11197 | (ctx->opcode & 0xf)) << 3;
11198
11199 if (ctx->opcode & (1 << 7)) {
11200 gen_mips16_save(ctx, xsregs, aregs,
11201 do_ra, do_s0, do_s1,
11202 framesize);
11203 } else {
11204 gen_mips16_restore(ctx, xsregs, aregs,
11205 do_ra, do_s0, do_s1,
11206 framesize);
11207 }
11208 }
11209 break;
11210 default:
11211 generate_exception(ctx, EXCP_RI);
11212 break;
11213 }
11214 break;
11215 case M16_OPC_LI:
11216 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11217 break;
11218 case M16_OPC_CMPI:
11219 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11220 break;
11221#if defined(TARGET_MIPS64)
11222 case M16_OPC_SD:
d9224450
MR
11223 check_insn(ctx, ISA_MIPS3);
11224 check_mips_64(ctx);
5c13fdfd 11225 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11226 break;
11227#endif
11228 case M16_OPC_LB:
d75c135e 11229 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11230 break;
11231 case M16_OPC_LH:
d75c135e 11232 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11233 break;
11234 case M16_OPC_LWSP:
d75c135e 11235 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11236 break;
11237 case M16_OPC_LW:
d75c135e 11238 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11239 break;
11240 case M16_OPC_LBU:
d75c135e 11241 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11242 break;
11243 case M16_OPC_LHU:
d75c135e 11244 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11245 break;
11246 case M16_OPC_LWPC:
d75c135e 11247 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11248 break;
11249#if defined(TARGET_MIPS64)
11250 case M16_OPC_LWU:
d9224450
MR
11251 check_insn(ctx, ISA_MIPS3);
11252 check_mips_64(ctx);
d75c135e 11253 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11254 break;
11255#endif
11256 case M16_OPC_SB:
5c13fdfd 11257 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11258 break;
11259 case M16_OPC_SH:
5c13fdfd 11260 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11261 break;
11262 case M16_OPC_SWSP:
5c13fdfd 11263 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11264 break;
11265 case M16_OPC_SW:
5c13fdfd 11266 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11267 break;
11268#if defined(TARGET_MIPS64)
11269 case M16_OPC_I64:
d75c135e 11270 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11271 break;
11272#endif
11273 default:
11274 generate_exception(ctx, EXCP_RI);
11275 break;
11276 }
11277
11278 return 4;
11279}
11280
240ce26a 11281static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11282{
11283 int rx, ry;
11284 int sa;
11285 int op, cnvt_op, op1, offset;
11286 int funct;
11287 int n_bytes;
11288
11289 op = (ctx->opcode >> 11) & 0x1f;
11290 sa = (ctx->opcode >> 2) & 0x7;
11291 sa = sa == 0 ? 8 : sa;
11292 rx = xlat((ctx->opcode >> 8) & 0x7);
11293 cnvt_op = (ctx->opcode >> 5) & 0x7;
11294 ry = xlat((ctx->opcode >> 5) & 0x7);
11295 op1 = offset = ctx->opcode & 0x1f;
11296
11297 n_bytes = 2;
11298
11299 switch (op) {
11300 case M16_OPC_ADDIUSP:
11301 {
11302 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11303
d75c135e 11304 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11305 }
11306 break;
11307 case M16_OPC_ADDIUPC:
11308 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11309 break;
11310 case M16_OPC_B:
11311 offset = (ctx->opcode & 0x7ff) << 1;
11312 offset = (int16_t)(offset << 4) >> 4;
b231c103 11313 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11314 /* No delay slot, so just process as a normal instruction */
11315 break;
11316 case M16_OPC_JAL:
895c2d04 11317 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11318 offset = (((ctx->opcode & 0x1f) << 21)
11319 | ((ctx->opcode >> 5) & 0x1f) << 16
11320 | offset) << 2;
b231c103
YK
11321 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11322 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11323 n_bytes = 4;
364d4831
NF
11324 break;
11325 case M16_OPC_BEQZ:
b231c103
YK
11326 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11327 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11328 /* No delay slot, so just process as a normal instruction */
11329 break;
11330 case M16_OPC_BNEQZ:
b231c103
YK
11331 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11332 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11333 /* No delay slot, so just process as a normal instruction */
11334 break;
11335 case M16_OPC_SHIFT:
11336 switch (ctx->opcode & 0x3) {
11337 case 0x0:
d75c135e 11338 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11339 break;
11340 case 0x1:
11341#if defined(TARGET_MIPS64)
d9224450 11342 check_insn(ctx, ISA_MIPS3);
364d4831 11343 check_mips_64(ctx);
d75c135e 11344 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11345#else
11346 generate_exception(ctx, EXCP_RI);
11347#endif
11348 break;
11349 case 0x2:
d75c135e 11350 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11351 break;
11352 case 0x3:
d75c135e 11353 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11354 break;
11355 }
11356 break;
11357#if defined(TARGET_MIPS64)
11358 case M16_OPC_LD:
d9224450 11359 check_insn(ctx, ISA_MIPS3);
364d4831 11360 check_mips_64(ctx);
d75c135e 11361 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11362 break;
11363#endif
11364 case M16_OPC_RRIA:
11365 {
11366 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11367
11368 if ((ctx->opcode >> 4) & 1) {
11369#if defined(TARGET_MIPS64)
d9224450 11370 check_insn(ctx, ISA_MIPS3);
364d4831 11371 check_mips_64(ctx);
d75c135e 11372 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11373#else
11374 generate_exception(ctx, EXCP_RI);
11375#endif
11376 } else {
d75c135e 11377 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11378 }
11379 }
11380 break;
11381 case M16_OPC_ADDIU8:
11382 {
11383 int16_t imm = (int8_t) ctx->opcode;
11384
d75c135e 11385 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11386 }
11387 break;
11388 case M16_OPC_SLTI:
11389 {
11390 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11391 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11392 }
11393 break;
11394 case M16_OPC_SLTIU:
11395 {
11396 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11397 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11398 }
11399 break;
11400 case M16_OPC_I8:
11401 {
11402 int reg32;
11403
11404 funct = (ctx->opcode >> 8) & 0x7;
11405 switch (funct) {
11406 case I8_BTEQZ:
11407 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11408 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11409 break;
11410 case I8_BTNEZ:
11411 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11412 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11413 break;
11414 case I8_SWRASP:
5c13fdfd 11415 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11416 break;
11417 case I8_ADJSP:
d75c135e 11418 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11419 ((int8_t)ctx->opcode) << 3);
11420 break;
11421 case I8_SVRS:
d9224450 11422 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11423 {
11424 int do_ra = ctx->opcode & (1 << 6);
11425 int do_s0 = ctx->opcode & (1 << 5);
11426 int do_s1 = ctx->opcode & (1 << 4);
11427 int framesize = ctx->opcode & 0xf;
11428
11429 if (framesize == 0) {
11430 framesize = 128;
11431 } else {
11432 framesize = framesize << 3;
11433 }
11434
11435 if (ctx->opcode & (1 << 7)) {
11436 gen_mips16_save(ctx, 0, 0,
11437 do_ra, do_s0, do_s1, framesize);
11438 } else {
11439 gen_mips16_restore(ctx, 0, 0,
11440 do_ra, do_s0, do_s1, framesize);
11441 }
11442 }
11443 break;
11444 case I8_MOV32R:
11445 {
11446 int rz = xlat(ctx->opcode & 0x7);
11447
11448 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11449 ((ctx->opcode >> 5) & 0x7);
d75c135e 11450 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11451 }
11452 break;
11453 case I8_MOVR32:
11454 reg32 = ctx->opcode & 0x1f;
d75c135e 11455 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11456 break;
11457 default:
11458 generate_exception(ctx, EXCP_RI);
11459 break;
11460 }
11461 }
11462 break;
11463 case M16_OPC_LI:
11464 {
11465 int16_t imm = (uint8_t) ctx->opcode;
11466
d75c135e 11467 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11468 }
11469 break;
11470 case M16_OPC_CMPI:
11471 {
11472 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11473 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11474 }
11475 break;
11476#if defined(TARGET_MIPS64)
11477 case M16_OPC_SD:
d9224450 11478 check_insn(ctx, ISA_MIPS3);
364d4831 11479 check_mips_64(ctx);
5c13fdfd 11480 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11481 break;
11482#endif
11483 case M16_OPC_LB:
d75c135e 11484 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11485 break;
11486 case M16_OPC_LH:
d75c135e 11487 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11488 break;
11489 case M16_OPC_LWSP:
d75c135e 11490 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11491 break;
11492 case M16_OPC_LW:
d75c135e 11493 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11494 break;
11495 case M16_OPC_LBU:
d75c135e 11496 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11497 break;
11498 case M16_OPC_LHU:
d75c135e 11499 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11500 break;
11501 case M16_OPC_LWPC:
d75c135e 11502 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11503 break;
11504#if defined (TARGET_MIPS64)
11505 case M16_OPC_LWU:
d9224450 11506 check_insn(ctx, ISA_MIPS3);
364d4831 11507 check_mips_64(ctx);
d75c135e 11508 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11509 break;
11510#endif
11511 case M16_OPC_SB:
5c13fdfd 11512 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11513 break;
11514 case M16_OPC_SH:
5c13fdfd 11515 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11516 break;
11517 case M16_OPC_SWSP:
5c13fdfd 11518 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11519 break;
11520 case M16_OPC_SW:
5c13fdfd 11521 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11522 break;
11523 case M16_OPC_RRR:
11524 {
11525 int rz = xlat((ctx->opcode >> 2) & 0x7);
11526 int mips32_op;
11527
11528 switch (ctx->opcode & 0x3) {
11529 case RRR_ADDU:
11530 mips32_op = OPC_ADDU;
11531 break;
11532 case RRR_SUBU:
11533 mips32_op = OPC_SUBU;
11534 break;
11535#if defined(TARGET_MIPS64)
11536 case RRR_DADDU:
11537 mips32_op = OPC_DADDU;
d9224450 11538 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11539 check_mips_64(ctx);
11540 break;
11541 case RRR_DSUBU:
11542 mips32_op = OPC_DSUBU;
d9224450 11543 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11544 check_mips_64(ctx);
11545 break;
11546#endif
11547 default:
11548 generate_exception(ctx, EXCP_RI);
11549 goto done;
11550 }
11551
d75c135e 11552 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11553 done:
11554 ;
11555 }
11556 break;
11557 case M16_OPC_RR:
11558 switch (op1) {
11559 case RR_JR:
11560 {
11561 int nd = (ctx->opcode >> 7) & 0x1;
11562 int link = (ctx->opcode >> 6) & 0x1;
11563 int ra = (ctx->opcode >> 5) & 0x1;
11564
d9224450
MR
11565 if (nd) {
11566 check_insn(ctx, ISA_MIPS32);
11567 }
11568
364d4831 11569 if (link) {
b231c103 11570 op = OPC_JALR;
364d4831
NF
11571 } else {
11572 op = OPC_JR;
11573 }
11574
b231c103
YK
11575 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11576 (nd ? 0 : 2));
364d4831
NF
11577 }
11578 break;
11579 case RR_SDBBP:
11580 /* XXX: not clear which exception should be raised
11581 * when in debug mode...
11582 */
d75c135e 11583 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11584 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11585 generate_exception(ctx, EXCP_DBp);
11586 } else {
11587 generate_exception(ctx, EXCP_DBp);
11588 }
11589 break;
11590 case RR_SLT:
d75c135e 11591 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11592 break;
11593 case RR_SLTU:
d75c135e 11594 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11595 break;
11596 case RR_BREAK:
11597 generate_exception(ctx, EXCP_BREAK);
11598 break;
11599 case RR_SLLV:
d75c135e 11600 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11601 break;
11602 case RR_SRLV:
d75c135e 11603 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11604 break;
11605 case RR_SRAV:
d75c135e 11606 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11607 break;
11608#if defined (TARGET_MIPS64)
11609 case RR_DSRL:
d9224450 11610 check_insn(ctx, ISA_MIPS3);
364d4831 11611 check_mips_64(ctx);
d75c135e 11612 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11613 break;
11614#endif
11615 case RR_CMP:
d75c135e 11616 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11617 break;
11618 case RR_NEG:
d75c135e 11619 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11620 break;
11621 case RR_AND:
d75c135e 11622 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11623 break;
11624 case RR_OR:
d75c135e 11625 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11626 break;
11627 case RR_XOR:
d75c135e 11628 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11629 break;
11630 case RR_NOT:
d75c135e 11631 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11632 break;
11633 case RR_MFHI:
26135ead 11634 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11635 break;
11636 case RR_CNVT:
d9224450 11637 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11638 switch (cnvt_op) {
11639 case RR_RY_CNVT_ZEB:
11640 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11641 break;
11642 case RR_RY_CNVT_ZEH:
11643 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11644 break;
11645 case RR_RY_CNVT_SEB:
11646 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11647 break;
11648 case RR_RY_CNVT_SEH:
11649 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11650 break;
11651#if defined (TARGET_MIPS64)
11652 case RR_RY_CNVT_ZEW:
d9224450 11653 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11654 check_mips_64(ctx);
11655 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11656 break;
11657 case RR_RY_CNVT_SEW:
d9224450 11658 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11659 check_mips_64(ctx);
11660 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11661 break;
11662#endif
11663 default:
11664 generate_exception(ctx, EXCP_RI);
11665 break;
11666 }
11667 break;
11668 case RR_MFLO:
26135ead 11669 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11670 break;
11671#if defined (TARGET_MIPS64)
11672 case RR_DSRA:
d9224450 11673 check_insn(ctx, ISA_MIPS3);
364d4831 11674 check_mips_64(ctx);
d75c135e 11675 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11676 break;
11677 case RR_DSLLV:
d9224450 11678 check_insn(ctx, ISA_MIPS3);
364d4831 11679 check_mips_64(ctx);
d75c135e 11680 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11681 break;
11682 case RR_DSRLV:
d9224450 11683 check_insn(ctx, ISA_MIPS3);
364d4831 11684 check_mips_64(ctx);
d75c135e 11685 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11686 break;
11687 case RR_DSRAV:
d9224450 11688 check_insn(ctx, ISA_MIPS3);
364d4831 11689 check_mips_64(ctx);
d75c135e 11690 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11691 break;
11692#endif
11693 case RR_MULT:
26135ead 11694 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11695 break;
11696 case RR_MULTU:
26135ead 11697 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11698 break;
11699 case RR_DIV:
26135ead 11700 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11701 break;
11702 case RR_DIVU:
26135ead 11703 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11704 break;
11705#if defined (TARGET_MIPS64)
11706 case RR_DMULT:
d9224450 11707 check_insn(ctx, ISA_MIPS3);
364d4831 11708 check_mips_64(ctx);
26135ead 11709 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11710 break;
11711 case RR_DMULTU:
d9224450 11712 check_insn(ctx, ISA_MIPS3);
364d4831 11713 check_mips_64(ctx);
26135ead 11714 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11715 break;
11716 case RR_DDIV:
d9224450 11717 check_insn(ctx, ISA_MIPS3);
364d4831 11718 check_mips_64(ctx);
26135ead 11719 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11720 break;
11721 case RR_DDIVU:
d9224450 11722 check_insn(ctx, ISA_MIPS3);
364d4831 11723 check_mips_64(ctx);
26135ead 11724 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11725 break;
11726#endif
11727 default:
11728 generate_exception(ctx, EXCP_RI);
11729 break;
11730 }
11731 break;
11732 case M16_OPC_EXTEND:
240ce26a 11733 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11734 n_bytes = 4;
11735 break;
11736#if defined(TARGET_MIPS64)
11737 case M16_OPC_I64:
11738 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11739 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11740 break;
11741#endif
11742 default:
11743 generate_exception(ctx, EXCP_RI);
11744 break;
11745 }
11746
11747 return n_bytes;
11748}
11749
211da992 11750/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11751
211da992
CWR
11752/*
11753 * microMIPS32/microMIPS64 major opcodes
11754 *
11755 * 1. MIPS Architecture for Programmers Volume II-B:
11756 * The microMIPS32 Instruction Set (Revision 3.05)
11757 *
11758 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11759 *
11760 * 2. MIPS Architecture For Programmers Volume II-A:
11761 * The MIPS64 Instruction Set (Revision 3.51)
11762 */
6af0bf9c 11763
3c824109
NF
11764enum {
11765 POOL32A = 0x00,
11766 POOL16A = 0x01,
11767 LBU16 = 0x02,
11768 MOVE16 = 0x03,
11769 ADDI32 = 0x04,
11770 LBU32 = 0x05,
11771 SB32 = 0x06,
11772 LB32 = 0x07,
11773
11774 POOL32B = 0x08,
11775 POOL16B = 0x09,
11776 LHU16 = 0x0a,
11777 ANDI16 = 0x0b,
11778 ADDIU32 = 0x0c,
11779 LHU32 = 0x0d,
11780 SH32 = 0x0e,
11781 LH32 = 0x0f,
11782
11783 POOL32I = 0x10,
11784 POOL16C = 0x11,
11785 LWSP16 = 0x12,
11786 POOL16D = 0x13,
11787 ORI32 = 0x14,
11788 POOL32F = 0x15,
211da992
CWR
11789 POOL32S = 0x16, /* MIPS64 */
11790 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11791
211da992 11792 /* 0x1f is reserved */
3c824109
NF
11793 POOL32C = 0x18,
11794 LWGP16 = 0x19,
11795 LW16 = 0x1a,
11796 POOL16E = 0x1b,
11797 XORI32 = 0x1c,
11798 JALS32 = 0x1d,
11799 ADDIUPC = 0x1e,
3c824109
NF
11800
11801 /* 0x20 is reserved */
11802 RES_20 = 0x20,
11803 POOL16F = 0x21,
11804 SB16 = 0x22,
11805 BEQZ16 = 0x23,
11806 SLTI32 = 0x24,
11807 BEQ32 = 0x25,
11808 SWC132 = 0x26,
11809 LWC132 = 0x27,
11810
11811 /* 0x28 and 0x29 are reserved */
11812 RES_28 = 0x28,
11813 RES_29 = 0x29,
11814 SH16 = 0x2a,
11815 BNEZ16 = 0x2b,
11816 SLTIU32 = 0x2c,
11817 BNE32 = 0x2d,
11818 SDC132 = 0x2e,
11819 LDC132 = 0x2f,
11820
11821 /* 0x30 and 0x31 are reserved */
11822 RES_30 = 0x30,
11823 RES_31 = 0x31,
11824 SWSP16 = 0x32,
11825 B16 = 0x33,
11826 ANDI32 = 0x34,
11827 J32 = 0x35,
211da992
CWR
11828 SD32 = 0x36, /* MIPS64 */
11829 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11830
11831 /* 0x38 and 0x39 are reserved */
11832 RES_38 = 0x38,
11833 RES_39 = 0x39,
11834 SW16 = 0x3a,
11835 LI16 = 0x3b,
11836 JALX32 = 0x3c,
11837 JAL32 = 0x3d,
11838 SW32 = 0x3e,
11839 LW32 = 0x3f
11840};
11841
11842/* POOL32A encoding of minor opcode field */
11843
11844enum {
11845 /* These opcodes are distinguished only by bits 9..6; those bits are
11846 * what are recorded below. */
11847 SLL32 = 0x0,
11848 SRL32 = 0x1,
11849 SRA = 0x2,
11850 ROTR = 0x3,
11851
11852 SLLV = 0x0,
11853 SRLV = 0x1,
11854 SRAV = 0x2,
11855 ROTRV = 0x3,
11856 ADD = 0x4,
11857 ADDU32 = 0x5,
11858 SUB = 0x6,
11859 SUBU32 = 0x7,
11860 MUL = 0x8,
11861 AND = 0x9,
11862 OR32 = 0xa,
11863 NOR = 0xb,
11864 XOR32 = 0xc,
11865 SLT = 0xd,
11866 SLTU = 0xe,
11867
11868 MOVN = 0x0,
11869 MOVZ = 0x1,
11870 LWXS = 0x4,
11871
11872 /* The following can be distinguished by their lower 6 bits. */
11873 INS = 0x0c,
11874 EXT = 0x2c,
11875 POOL32AXF = 0x3c
11876};
11877
11878/* POOL32AXF encoding of minor opcode field extension */
11879
d132c79f
CWR
11880/*
11881 * 1. MIPS Architecture for Programmers Volume II-B:
11882 * The microMIPS32 Instruction Set (Revision 3.05)
11883 *
11884 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11885 *
11886 * 2. MIPS Architecture for Programmers VolumeIV-e:
11887 * The MIPS DSP Application-Specific Extension
11888 * to the microMIPS32 Architecture (Revision 2.34)
11889 *
11890 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11891 */
11892
3c824109
NF
11893enum {
11894 /* bits 11..6 */
11895 TEQ = 0x00,
11896 TGE = 0x08,
11897 TGEU = 0x10,
11898 TLT = 0x20,
11899 TLTU = 0x28,
11900 TNE = 0x30,
11901
11902 MFC0 = 0x03,
11903 MTC0 = 0x0b,
11904
d132c79f
CWR
11905 /* begin of microMIPS32 DSP */
11906
3c824109
NF
11907 /* bits 13..12 for 0x01 */
11908 MFHI_ACC = 0x0,
11909 MFLO_ACC = 0x1,
11910 MTHI_ACC = 0x2,
11911 MTLO_ACC = 0x3,
11912
11913 /* bits 13..12 for 0x2a */
11914 MADD_ACC = 0x0,
11915 MADDU_ACC = 0x1,
11916 MSUB_ACC = 0x2,
11917 MSUBU_ACC = 0x3,
11918
11919 /* bits 13..12 for 0x32 */
11920 MULT_ACC = 0x0,
6801038b 11921 MULTU_ACC = 0x1,
3c824109 11922
d132c79f
CWR
11923 /* end of microMIPS32 DSP */
11924
3c824109
NF
11925 /* bits 15..12 for 0x2c */
11926 SEB = 0x2,
11927 SEH = 0x3,
11928 CLO = 0x4,
11929 CLZ = 0x5,
11930 RDHWR = 0x6,
11931 WSBH = 0x7,
11932 MULT = 0x8,
11933 MULTU = 0x9,
11934 DIV = 0xa,
11935 DIVU = 0xb,
11936 MADD = 0xc,
11937 MADDU = 0xd,
11938 MSUB = 0xe,
11939 MSUBU = 0xf,
11940
11941 /* bits 15..12 for 0x34 */
11942 MFC2 = 0x4,
11943 MTC2 = 0x5,
11944 MFHC2 = 0x8,
11945 MTHC2 = 0x9,
11946 CFC2 = 0xc,
11947 CTC2 = 0xd,
11948
11949 /* bits 15..12 for 0x3c */
11950 JALR = 0x0,
11951 JR = 0x0, /* alias */
11952 JALR_HB = 0x1,
11953 JALRS = 0x4,
11954 JALRS_HB = 0x5,
11955
11956 /* bits 15..12 for 0x05 */
11957 RDPGPR = 0xe,
11958 WRPGPR = 0xf,
11959
11960 /* bits 15..12 for 0x0d */
11961 TLBP = 0x0,
11962 TLBR = 0x1,
11963 TLBWI = 0x2,
11964 TLBWR = 0x3,
11965 WAIT = 0x9,
11966 IRET = 0xd,
11967 DERET = 0xe,
11968 ERET = 0xf,
11969
11970 /* bits 15..12 for 0x15 */
11971 DMT = 0x0,
11972 DVPE = 0x1,
11973 EMT = 0x2,
11974 EVPE = 0x3,
11975
11976 /* bits 15..12 for 0x1d */
11977 DI = 0x4,
11978 EI = 0x5,
11979
11980 /* bits 15..12 for 0x2d */
11981 SYNC = 0x6,
11982 SYSCALL = 0x8,
11983 SDBBP = 0xd,
11984
11985 /* bits 15..12 for 0x35 */
11986 MFHI32 = 0x0,
11987 MFLO32 = 0x1,
11988 MTHI32 = 0x2,
11989 MTLO32 = 0x3,
11990};
11991
11992/* POOL32B encoding of minor opcode field (bits 15..12) */
11993
11994enum {
11995 LWC2 = 0x0,
11996 LWP = 0x1,
11997 LDP = 0x4,
11998 LWM32 = 0x5,
11999 CACHE = 0x6,
12000 LDM = 0x7,
12001 SWC2 = 0x8,
12002 SWP = 0x9,
12003 SDP = 0xc,
12004 SWM32 = 0xd,
12005 SDM = 0xf
12006};
12007
12008/* POOL32C encoding of minor opcode field (bits 15..12) */
12009
12010enum {
12011 LWL = 0x0,
12012 SWL = 0x8,
12013 LWR = 0x1,
12014 SWR = 0x9,
12015 PREF = 0x2,
12016 /* 0xa is reserved */
12017 LL = 0x3,
12018 SC = 0xb,
12019 LDL = 0x4,
12020 SDL = 0xc,
12021 LDR = 0x5,
12022 SDR = 0xd,
12023 /* 0x6 is reserved */
12024 LWU = 0xe,
12025 LLD = 0x7,
12026 SCD = 0xf
12027};
12028
12029/* POOL32F encoding of minor opcode field (bits 5..0) */
12030
12031enum {
12032 /* These are the bit 7..6 values */
12033 ADD_FMT = 0x0,
12034 MOVN_FMT = 0x0,
12035
12036 SUB_FMT = 0x1,
12037 MOVZ_FMT = 0x1,
12038
12039 MUL_FMT = 0x2,
12040
12041 DIV_FMT = 0x3,
12042
12043 /* These are the bit 8..6 values */
12044 RSQRT2_FMT = 0x0,
12045 MOVF_FMT = 0x0,
12046
12047 LWXC1 = 0x1,
12048 MOVT_FMT = 0x1,
12049
12050 PLL_PS = 0x2,
12051 SWXC1 = 0x2,
12052
12053 PLU_PS = 0x3,
12054 LDXC1 = 0x3,
12055
12056 PUL_PS = 0x4,
12057 SDXC1 = 0x4,
12058 RECIP2_FMT = 0x4,
12059
12060 PUU_PS = 0x5,
12061 LUXC1 = 0x5,
12062
12063 CVT_PS_S = 0x6,
12064 SUXC1 = 0x6,
12065 ADDR_PS = 0x6,
12066 PREFX = 0x6,
12067
12068 MULR_PS = 0x7,
12069
12070 MADD_S = 0x01,
12071 MADD_D = 0x09,
12072 MADD_PS = 0x11,
12073 ALNV_PS = 0x19,
12074 MSUB_S = 0x21,
12075 MSUB_D = 0x29,
12076 MSUB_PS = 0x31,
12077
12078 NMADD_S = 0x02,
12079 NMADD_D = 0x0a,
12080 NMADD_PS = 0x12,
12081 NMSUB_S = 0x22,
12082 NMSUB_D = 0x2a,
12083 NMSUB_PS = 0x32,
12084
12085 POOL32FXF = 0x3b,
12086
12087 CABS_COND_FMT = 0x1c, /* MIPS3D */
12088 C_COND_FMT = 0x3c
12089};
12090
12091/* POOL32Fxf encoding of minor opcode extension field */
12092
12093enum {
12094 CVT_L = 0x04,
12095 RSQRT_FMT = 0x08,
12096 FLOOR_L = 0x0c,
12097 CVT_PW_PS = 0x1c,
12098 CVT_W = 0x24,
12099 SQRT_FMT = 0x28,
12100 FLOOR_W = 0x2c,
12101 CVT_PS_PW = 0x3c,
12102 CFC1 = 0x40,
12103 RECIP_FMT = 0x48,
12104 CEIL_L = 0x4c,
12105 CTC1 = 0x60,
12106 CEIL_W = 0x6c,
12107 MFC1 = 0x80,
12108 CVT_S_PL = 0x84,
12109 TRUNC_L = 0x8c,
12110 MTC1 = 0xa0,
12111 CVT_S_PU = 0xa4,
12112 TRUNC_W = 0xac,
12113 MFHC1 = 0xc0,
12114 ROUND_L = 0xcc,
12115 MTHC1 = 0xe0,
12116 ROUND_W = 0xec,
12117
12118 MOV_FMT = 0x01,
12119 MOVF = 0x05,
12120 ABS_FMT = 0x0d,
12121 RSQRT1_FMT = 0x1d,
12122 MOVT = 0x25,
12123 NEG_FMT = 0x2d,
12124 CVT_D = 0x4d,
12125 RECIP1_FMT = 0x5d,
12126 CVT_S = 0x6d
12127};
12128
12129/* POOL32I encoding of minor opcode field (bits 25..21) */
12130
12131enum {
12132 BLTZ = 0x00,
12133 BLTZAL = 0x01,
12134 BGEZ = 0x02,
12135 BGEZAL = 0x03,
12136 BLEZ = 0x04,
12137 BNEZC = 0x05,
12138 BGTZ = 0x06,
12139 BEQZC = 0x07,
12140 TLTI = 0x08,
12141 TGEI = 0x09,
12142 TLTIU = 0x0a,
12143 TGEIU = 0x0b,
12144 TNEI = 0x0c,
12145 LUI = 0x0d,
12146 TEQI = 0x0e,
12147 SYNCI = 0x10,
12148 BLTZALS = 0x11,
12149 BGEZALS = 0x13,
12150 BC2F = 0x14,
12151 BC2T = 0x15,
12152 BPOSGE64 = 0x1a,
12153 BPOSGE32 = 0x1b,
12154 /* These overlap and are distinguished by bit16 of the instruction */
12155 BC1F = 0x1c,
12156 BC1T = 0x1d,
12157 BC1ANY2F = 0x1c,
12158 BC1ANY2T = 0x1d,
12159 BC1ANY4F = 0x1e,
12160 BC1ANY4T = 0x1f
12161};
12162
12163/* POOL16A encoding of minor opcode field */
12164
12165enum {
12166 ADDU16 = 0x0,
12167 SUBU16 = 0x1
12168};
12169
12170/* POOL16B encoding of minor opcode field */
12171
12172enum {
12173 SLL16 = 0x0,
12174 SRL16 = 0x1
12175};
12176
12177/* POOL16C encoding of minor opcode field */
12178
12179enum {
12180 NOT16 = 0x00,
12181 XOR16 = 0x04,
12182 AND16 = 0x08,
12183 OR16 = 0x0c,
12184 LWM16 = 0x10,
12185 SWM16 = 0x14,
12186 JR16 = 0x18,
12187 JRC16 = 0x1a,
12188 JALR16 = 0x1c,
12189 JALR16S = 0x1e,
12190 MFHI16 = 0x20,
12191 MFLO16 = 0x24,
12192 BREAK16 = 0x28,
12193 SDBBP16 = 0x2c,
12194 JRADDIUSP = 0x30
12195};
12196
12197/* POOL16D encoding of minor opcode field */
12198
12199enum {
12200 ADDIUS5 = 0x0,
12201 ADDIUSP = 0x1
12202};
12203
12204/* POOL16E encoding of minor opcode field */
12205
12206enum {
12207 ADDIUR2 = 0x0,
12208 ADDIUR1SP = 0x1
12209};
12210
12211static int mmreg (int r)
12212{
12213 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12214
12215 return map[r];
12216}
12217
12218/* Used for 16-bit store instructions. */
12219static int mmreg2 (int r)
12220{
12221 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12222
12223 return map[r];
12224}
12225
12226#define uMIPS_RD(op) ((op >> 7) & 0x7)
12227#define uMIPS_RS(op) ((op >> 4) & 0x7)
12228#define uMIPS_RS2(op) uMIPS_RS(op)
12229#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12230#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12231#define uMIPS_RS5(op) (op & 0x1f)
12232
12233/* Signed immediate */
12234#define SIMM(op, start, width) \
12235 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12236 << (32-width)) \
12237 >> (32-width))
12238/* Zero-extended immediate */
12239#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12240
d75c135e 12241static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12242{
12243 int rd = mmreg(uMIPS_RD(ctx->opcode));
12244
d75c135e 12245 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12246}
12247
d75c135e 12248static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12249{
12250 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12251 int rd = mmreg(uMIPS_RD(ctx->opcode));
12252 int rs = mmreg(uMIPS_RS(ctx->opcode));
12253
d75c135e 12254 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12255}
12256
d75c135e 12257static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12258{
12259 int encoded = ZIMM(ctx->opcode, 1, 9);
12260 int decoded;
12261
12262 if (encoded <= 1) {
12263 decoded = 256 + encoded;
12264 } else if (encoded <= 255) {
12265 decoded = encoded;
12266 } else if (encoded <= 509) {
12267 decoded = encoded - 512;
12268 } else {
12269 decoded = encoded - 768;
12270 }
12271
d75c135e 12272 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12273}
12274
d75c135e 12275static void gen_addius5(DisasContext *ctx)
3c824109
NF
12276{
12277 int imm = SIMM(ctx->opcode, 1, 4);
12278 int rd = (ctx->opcode >> 5) & 0x1f;
12279
d75c135e 12280 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12281}
12282
d75c135e 12283static void gen_andi16(DisasContext *ctx)
3c824109
NF
12284{
12285 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12286 31, 32, 63, 64, 255, 32768, 65535 };
12287 int rd = mmreg(uMIPS_RD(ctx->opcode));
12288 int rs = mmreg(uMIPS_RS(ctx->opcode));
12289 int encoded = ZIMM(ctx->opcode, 0, 4);
12290
d75c135e 12291 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12292}
12293
12294static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12295 int base, int16_t offset)
12296{
e1050a76 12297 const char *opn = "ldst_multiple";
3c824109
NF
12298 TCGv t0, t1;
12299 TCGv_i32 t2;
12300
12301 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12302 generate_exception(ctx, EXCP_RI);
12303 return;
12304 }
12305
12306 t0 = tcg_temp_new();
12307
12308 gen_base_offset_addr(ctx, t0, base, offset);
12309
12310 t1 = tcg_const_tl(reglist);
12311 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12312
3c824109
NF
12313 save_cpu_state(ctx, 1);
12314 switch (opc) {
12315 case LWM32:
895c2d04 12316 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12317 opn = "lwm";
3c824109
NF
12318 break;
12319 case SWM32:
895c2d04 12320 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12321 opn = "swm";
3c824109
NF
12322 break;
12323#ifdef TARGET_MIPS64
12324 case LDM:
895c2d04 12325 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12326 opn = "ldm";
3c824109
NF
12327 break;
12328 case SDM:
895c2d04 12329 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12330 opn = "sdm";
3c824109 12331 break;
6af0bf9c 12332#endif
3c824109 12333 }
e1050a76 12334 (void)opn;
3c824109
NF
12335 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12336 tcg_temp_free(t0);
33087598 12337 tcg_temp_free(t1);
3c824109
NF
12338 tcg_temp_free_i32(t2);
12339}
6af0bf9c 12340
3c824109 12341
240ce26a 12342static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12343{
3c824109
NF
12344 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12345 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12346
3c824109
NF
12347 switch (((ctx->opcode) >> 4) & 0x3f) {
12348 case NOT16 + 0:
12349 case NOT16 + 1:
12350 case NOT16 + 2:
12351 case NOT16 + 3:
d75c135e 12352 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12353 break;
12354 case XOR16 + 0:
12355 case XOR16 + 1:
12356 case XOR16 + 2:
12357 case XOR16 + 3:
d75c135e 12358 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12359 break;
12360 case AND16 + 0:
12361 case AND16 + 1:
12362 case AND16 + 2:
12363 case AND16 + 3:
d75c135e 12364 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12365 break;
12366 case OR16 + 0:
12367 case OR16 + 1:
12368 case OR16 + 2:
12369 case OR16 + 3:
d75c135e 12370 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12371 break;
12372 case LWM16 + 0:
12373 case LWM16 + 1:
12374 case LWM16 + 2:
12375 case LWM16 + 3:
12376 {
12377 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12378 int offset = ZIMM(ctx->opcode, 0, 4);
12379
12380 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12381 29, offset << 2);
12382 }
12383 break;
12384 case SWM16 + 0:
12385 case SWM16 + 1:
12386 case SWM16 + 2:
12387 case SWM16 + 3:
12388 {
12389 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12390 int offset = ZIMM(ctx->opcode, 0, 4);
12391
12392 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12393 29, offset << 2);
12394 }
12395 break;
12396 case JR16 + 0:
12397 case JR16 + 1:
12398 {
12399 int reg = ctx->opcode & 0x1f;
12400
b231c103 12401 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12402 }
3c824109
NF
12403 break;
12404 case JRC16 + 0:
12405 case JRC16 + 1:
12406 {
12407 int reg = ctx->opcode & 0x1f;
b231c103 12408 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12409 /* Let normal delay slot handling in our caller take us
12410 to the branch target. */
12411 }
12412 break;
12413 case JALR16 + 0:
12414 case JALR16 + 1:
b231c103
YK
12415 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12416 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12417 break;
3c824109
NF
12418 case JALR16S + 0:
12419 case JALR16S + 1:
b231c103
YK
12420 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12421 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12422 break;
12423 case MFHI16 + 0:
12424 case MFHI16 + 1:
26135ead 12425 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12426 break;
12427 case MFLO16 + 0:
12428 case MFLO16 + 1:
26135ead 12429 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12430 break;
12431 case BREAK16:
12432 generate_exception(ctx, EXCP_BREAK);
12433 break;
12434 case SDBBP16:
12435 /* XXX: not clear which exception should be raised
12436 * when in debug mode...
12437 */
d75c135e 12438 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12439 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12440 generate_exception(ctx, EXCP_DBp);
12441 } else {
12442 generate_exception(ctx, EXCP_DBp);
12443 }
12444 break;
12445 case JRADDIUSP + 0:
12446 case JRADDIUSP + 1:
12447 {
12448 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12449 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12450 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12451 /* Let normal delay slot handling in our caller take us
12452 to the branch target. */
12453 }
12454 break;
12455 default:
12456 generate_exception(ctx, EXCP_RI);
12457 break;
12458 }
12459}
12460
12461static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12462{
12463 TCGv t0 = tcg_temp_new();
12464 TCGv t1 = tcg_temp_new();
12465
12466 gen_load_gpr(t0, base);
12467
12468 if (index != 0) {
12469 gen_load_gpr(t1, index);
12470 tcg_gen_shli_tl(t1, t1, 2);
12471 gen_op_addr_add(ctx, t0, t1, t0);
12472 }
12473
5f68f5ae 12474 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12475 gen_store_gpr(t1, rd);
12476
12477 tcg_temp_free(t0);
12478 tcg_temp_free(t1);
12479}
12480
12481static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12482 int base, int16_t offset)
12483{
12484 const char *opn = "ldst_pair";
12485 TCGv t0, t1;
12486
36c6711b 12487 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12488 generate_exception(ctx, EXCP_RI);
d796321b
FB
12489 return;
12490 }
12491
3c824109
NF
12492 t0 = tcg_temp_new();
12493 t1 = tcg_temp_new();
8e9ade68 12494
3c824109
NF
12495 gen_base_offset_addr(ctx, t0, base, offset);
12496
12497 switch (opc) {
12498 case LWP:
36c6711b
EJ
12499 if (rd == base) {
12500 generate_exception(ctx, EXCP_RI);
12501 return;
12502 }
5f68f5ae 12503 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12504 gen_store_gpr(t1, rd);
12505 tcg_gen_movi_tl(t1, 4);
12506 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12507 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12508 gen_store_gpr(t1, rd+1);
12509 opn = "lwp";
12510 break;
12511 case SWP:
3c824109 12512 gen_load_gpr(t1, rd);
5f68f5ae 12513 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12514 tcg_gen_movi_tl(t1, 4);
12515 gen_op_addr_add(ctx, t0, t0, t1);
12516 gen_load_gpr(t1, rd+1);
5f68f5ae 12517 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12518 opn = "swp";
12519 break;
12520#ifdef TARGET_MIPS64
12521 case LDP:
36c6711b
EJ
12522 if (rd == base) {
12523 generate_exception(ctx, EXCP_RI);
12524 return;
12525 }
5f68f5ae 12526 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12527 gen_store_gpr(t1, rd);
12528 tcg_gen_movi_tl(t1, 8);
12529 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12530 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12531 gen_store_gpr(t1, rd+1);
12532 opn = "ldp";
12533 break;
12534 case SDP:
3c824109 12535 gen_load_gpr(t1, rd);
5f68f5ae 12536 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12537 tcg_gen_movi_tl(t1, 8);
12538 gen_op_addr_add(ctx, t0, t0, t1);
12539 gen_load_gpr(t1, rd+1);
5f68f5ae 12540 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12541 opn = "sdp";
12542 break;
12543#endif
6af0bf9c 12544 }
2abf314d 12545 (void)opn; /* avoid a compiler warning */
3c824109
NF
12546 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12547 tcg_temp_free(t0);
12548 tcg_temp_free(t1);
12549}
618b0fe9 12550
240ce26a 12551static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12552{
12553 int extension = (ctx->opcode >> 6) & 0x3f;
12554 int minor = (ctx->opcode >> 12) & 0xf;
12555 uint32_t mips32_op;
12556
12557 switch (extension) {
12558 case TEQ:
12559 mips32_op = OPC_TEQ;
12560 goto do_trap;
12561 case TGE:
12562 mips32_op = OPC_TGE;
12563 goto do_trap;
12564 case TGEU:
12565 mips32_op = OPC_TGEU;
12566 goto do_trap;
12567 case TLT:
12568 mips32_op = OPC_TLT;
12569 goto do_trap;
12570 case TLTU:
12571 mips32_op = OPC_TLTU;
12572 goto do_trap;
12573 case TNE:
12574 mips32_op = OPC_TNE;
12575 do_trap:
12576 gen_trap(ctx, mips32_op, rs, rt, -1);
12577 break;
12578#ifndef CONFIG_USER_ONLY
12579 case MFC0:
12580 case MFC0 + 32:
2e15497c 12581 check_cp0_enabled(ctx);
3c824109
NF
12582 if (rt == 0) {
12583 /* Treat as NOP. */
12584 break;
12585 }
d75c135e 12586 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12587 break;
12588 case MTC0:
12589 case MTC0 + 32:
2e15497c 12590 check_cp0_enabled(ctx);
3c824109
NF
12591 {
12592 TCGv t0 = tcg_temp_new();
618b0fe9 12593
3c824109 12594 gen_load_gpr(t0, rt);
d75c135e 12595 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12596 tcg_temp_free(t0);
12597 }
12598 break;
12599#endif
a1fc6246
LA
12600 case 0x2a:
12601 switch (minor & 3) {
12602 case MADD_ACC:
12603 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12604 break;
12605 case MADDU_ACC:
12606 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12607 break;
12608 case MSUB_ACC:
12609 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12610 break;
12611 case MSUBU_ACC:
12612 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12613 break;
12614 default:
12615 goto pool32axf_invalid;
12616 }
12617 break;
12618 case 0x32:
12619 switch (minor & 3) {
12620 case MULT_ACC:
12621 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12622 break;
12623 case MULTU_ACC:
12624 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12625 break;
12626 default:
12627 goto pool32axf_invalid;
12628 }
12629 break;
3c824109
NF
12630 case 0x2c:
12631 switch (minor) {
12632 case SEB:
12633 gen_bshfl(ctx, OPC_SEB, rs, rt);
12634 break;
12635 case SEH:
12636 gen_bshfl(ctx, OPC_SEH, rs, rt);
12637 break;
12638 case CLO:
12639 mips32_op = OPC_CLO;
12640 goto do_cl;
12641 case CLZ:
12642 mips32_op = OPC_CLZ;
12643 do_cl:
d75c135e 12644 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12645 gen_cl(ctx, mips32_op, rt, rs);
12646 break;
12647 case RDHWR:
d75c135e 12648 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12649 break;
12650 case WSBH:
12651 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12652 break;
12653 case MULT:
12654 mips32_op = OPC_MULT;
26135ead 12655 goto do_mul;
3c824109
NF
12656 case MULTU:
12657 mips32_op = OPC_MULTU;
26135ead 12658 goto do_mul;
3c824109
NF
12659 case DIV:
12660 mips32_op = OPC_DIV;
26135ead 12661 goto do_div;
3c824109
NF
12662 case DIVU:
12663 mips32_op = OPC_DIVU;
26135ead
RS
12664 goto do_div;
12665 do_div:
12666 check_insn(ctx, ISA_MIPS32);
12667 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12668 break;
3c824109
NF
12669 case MADD:
12670 mips32_op = OPC_MADD;
26135ead 12671 goto do_mul;
3c824109
NF
12672 case MADDU:
12673 mips32_op = OPC_MADDU;
26135ead 12674 goto do_mul;
3c824109
NF
12675 case MSUB:
12676 mips32_op = OPC_MSUB;
26135ead 12677 goto do_mul;
3c824109
NF
12678 case MSUBU:
12679 mips32_op = OPC_MSUBU;
26135ead 12680 do_mul:
d75c135e 12681 check_insn(ctx, ISA_MIPS32);
a1fc6246 12682 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12683 break;
12684 default:
12685 goto pool32axf_invalid;
12686 }
12687 break;
12688 case 0x34:
12689 switch (minor) {
12690 case MFC2:
12691 case MTC2:
12692 case MFHC2:
12693 case MTHC2:
12694 case CFC2:
12695 case CTC2:
12696 generate_exception_err(ctx, EXCP_CpU, 2);
12697 break;
12698 default:
12699 goto pool32axf_invalid;
12700 }
12701 break;
12702 case 0x3c:
12703 switch (minor) {
12704 case JALR:
12705 case JALR_HB:
b231c103
YK
12706 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12707 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12708 break;
12709 case JALRS:
12710 case JALRS_HB:
b231c103
YK
12711 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12712 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12713 break;
12714 default:
12715 goto pool32axf_invalid;
12716 }
12717 break;
12718 case 0x05:
12719 switch (minor) {
12720 case RDPGPR:
2e15497c 12721 check_cp0_enabled(ctx);
d75c135e 12722 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12723 gen_load_srsgpr(rt, rs);
12724 break;
12725 case WRPGPR:
2e15497c 12726 check_cp0_enabled(ctx);
d75c135e 12727 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12728 gen_store_srsgpr(rt, rs);
12729 break;
12730 default:
12731 goto pool32axf_invalid;
12732 }
12733 break;
12734#ifndef CONFIG_USER_ONLY
12735 case 0x0d:
12736 switch (minor) {
12737 case TLBP:
12738 mips32_op = OPC_TLBP;
12739 goto do_cp0;
12740 case TLBR:
12741 mips32_op = OPC_TLBR;
12742 goto do_cp0;
12743 case TLBWI:
12744 mips32_op = OPC_TLBWI;
12745 goto do_cp0;
12746 case TLBWR:
12747 mips32_op = OPC_TLBWR;
12748 goto do_cp0;
12749 case WAIT:
12750 mips32_op = OPC_WAIT;
12751 goto do_cp0;
12752 case DERET:
12753 mips32_op = OPC_DERET;
12754 goto do_cp0;
12755 case ERET:
12756 mips32_op = OPC_ERET;
12757 do_cp0:
12758 gen_cp0(env, ctx, mips32_op, rt, rs);
12759 break;
12760 default:
12761 goto pool32axf_invalid;
12762 }
12763 break;
12764 case 0x1d:
12765 switch (minor) {
12766 case DI:
2e15497c 12767 check_cp0_enabled(ctx);
3c824109
NF
12768 {
12769 TCGv t0 = tcg_temp_new();
12770
12771 save_cpu_state(ctx, 1);
895c2d04 12772 gen_helper_di(t0, cpu_env);
3c824109
NF
12773 gen_store_gpr(t0, rs);
12774 /* Stop translation as we may have switched the execution mode */
12775 ctx->bstate = BS_STOP;
12776 tcg_temp_free(t0);
12777 }
12778 break;
12779 case EI:
2e15497c 12780 check_cp0_enabled(ctx);
3c824109
NF
12781 {
12782 TCGv t0 = tcg_temp_new();
12783
12784 save_cpu_state(ctx, 1);
895c2d04 12785 gen_helper_ei(t0, cpu_env);
3c824109
NF
12786 gen_store_gpr(t0, rs);
12787 /* Stop translation as we may have switched the execution mode */
12788 ctx->bstate = BS_STOP;
12789 tcg_temp_free(t0);
12790 }
12791 break;
12792 default:
12793 goto pool32axf_invalid;
12794 }
12795 break;
12796#endif
12797 case 0x2d:
12798 switch (minor) {
12799 case SYNC:
12800 /* NOP */
12801 break;
12802 case SYSCALL:
12803 generate_exception(ctx, EXCP_SYSCALL);
12804 ctx->bstate = BS_STOP;
12805 break;
12806 case SDBBP:
d75c135e 12807 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12808 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12809 generate_exception(ctx, EXCP_DBp);
12810 } else {
12811 generate_exception(ctx, EXCP_DBp);
12812 }
12813 break;
12814 default:
12815 goto pool32axf_invalid;
12816 }
12817 break;
a1fc6246 12818 case 0x01:
26135ead 12819 switch (minor & 3) {
a1fc6246 12820 case MFHI_ACC:
26135ead 12821 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12822 break;
a1fc6246 12823 case MFLO_ACC:
26135ead 12824 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12825 break;
a1fc6246 12826 case MTHI_ACC:
26135ead 12827 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12828 break;
a1fc6246 12829 case MTLO_ACC:
26135ead 12830 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12831 break;
12832 default:
12833 goto pool32axf_invalid;
12834 }
12835 break;
a1fc6246
LA
12836 case 0x35:
12837 switch (minor) {
12838 case MFHI32:
12839 gen_HILO(ctx, OPC_MFHI, 0, rs);
12840 break;
12841 case MFLO32:
12842 gen_HILO(ctx, OPC_MFLO, 0, rs);
12843 break;
12844 case MTHI32:
12845 gen_HILO(ctx, OPC_MTHI, 0, rs);
12846 break;
12847 case MTLO32:
12848 gen_HILO(ctx, OPC_MTLO, 0, rs);
12849 break;
12850 default:
12851 goto pool32axf_invalid;
12852 }
12853 break;
3c824109
NF
12854 default:
12855 pool32axf_invalid:
12856 MIPS_INVAL("pool32axf");
12857 generate_exception(ctx, EXCP_RI);
12858 break;
12859 }
12860}
12861
12862/* Values for microMIPS fmt field. Variable-width, depending on which
12863 formats the instruction supports. */
12864
12865enum {
12866 FMT_SD_S = 0,
12867 FMT_SD_D = 1,
12868
12869 FMT_SDPS_S = 0,
12870 FMT_SDPS_D = 1,
12871 FMT_SDPS_PS = 2,
12872
12873 FMT_SWL_S = 0,
12874 FMT_SWL_W = 1,
12875 FMT_SWL_L = 2,
12876
12877 FMT_DWL_D = 0,
12878 FMT_DWL_W = 1,
12879 FMT_DWL_L = 2
12880};
12881
d75c135e 12882static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12883{
12884 int extension = (ctx->opcode >> 6) & 0x3ff;
12885 uint32_t mips32_op;
12886
12887#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12888#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12889#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12890
12891 switch (extension) {
12892 case FLOAT_1BIT_FMT(CFC1, 0):
12893 mips32_op = OPC_CFC1;
12894 goto do_cp1;
12895 case FLOAT_1BIT_FMT(CTC1, 0):
12896 mips32_op = OPC_CTC1;
12897 goto do_cp1;
12898 case FLOAT_1BIT_FMT(MFC1, 0):
12899 mips32_op = OPC_MFC1;
12900 goto do_cp1;
12901 case FLOAT_1BIT_FMT(MTC1, 0):
12902 mips32_op = OPC_MTC1;
12903 goto do_cp1;
12904 case FLOAT_1BIT_FMT(MFHC1, 0):
12905 mips32_op = OPC_MFHC1;
12906 goto do_cp1;
12907 case FLOAT_1BIT_FMT(MTHC1, 0):
12908 mips32_op = OPC_MTHC1;
12909 do_cp1:
12910 gen_cp1(ctx, mips32_op, rt, rs);
12911 break;
12912
12913 /* Reciprocal square root */
12914 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12915 mips32_op = OPC_RSQRT_S;
12916 goto do_unaryfp;
12917 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12918 mips32_op = OPC_RSQRT_D;
12919 goto do_unaryfp;
12920
12921 /* Square root */
12922 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12923 mips32_op = OPC_SQRT_S;
12924 goto do_unaryfp;
12925 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12926 mips32_op = OPC_SQRT_D;
12927 goto do_unaryfp;
12928
12929 /* Reciprocal */
12930 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12931 mips32_op = OPC_RECIP_S;
12932 goto do_unaryfp;
12933 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12934 mips32_op = OPC_RECIP_D;
12935 goto do_unaryfp;
12936
12937 /* Floor */
12938 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12939 mips32_op = OPC_FLOOR_L_S;
12940 goto do_unaryfp;
12941 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12942 mips32_op = OPC_FLOOR_L_D;
12943 goto do_unaryfp;
12944 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12945 mips32_op = OPC_FLOOR_W_S;
12946 goto do_unaryfp;
12947 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12948 mips32_op = OPC_FLOOR_W_D;
12949 goto do_unaryfp;
12950
12951 /* Ceiling */
12952 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12953 mips32_op = OPC_CEIL_L_S;
12954 goto do_unaryfp;
12955 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12956 mips32_op = OPC_CEIL_L_D;
12957 goto do_unaryfp;
12958 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12959 mips32_op = OPC_CEIL_W_S;
12960 goto do_unaryfp;
12961 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12962 mips32_op = OPC_CEIL_W_D;
12963 goto do_unaryfp;
12964
12965 /* Truncation */
12966 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12967 mips32_op = OPC_TRUNC_L_S;
12968 goto do_unaryfp;
12969 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12970 mips32_op = OPC_TRUNC_L_D;
12971 goto do_unaryfp;
12972 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12973 mips32_op = OPC_TRUNC_W_S;
12974 goto do_unaryfp;
12975 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12976 mips32_op = OPC_TRUNC_W_D;
12977 goto do_unaryfp;
12978
12979 /* Round */
12980 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12981 mips32_op = OPC_ROUND_L_S;
12982 goto do_unaryfp;
12983 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12984 mips32_op = OPC_ROUND_L_D;
12985 goto do_unaryfp;
12986 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12987 mips32_op = OPC_ROUND_W_S;
12988 goto do_unaryfp;
12989 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12990 mips32_op = OPC_ROUND_W_D;
12991 goto do_unaryfp;
12992
12993 /* Integer to floating-point conversion */
12994 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12995 mips32_op = OPC_CVT_L_S;
12996 goto do_unaryfp;
12997 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12998 mips32_op = OPC_CVT_L_D;
12999 goto do_unaryfp;
13000 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13001 mips32_op = OPC_CVT_W_S;
13002 goto do_unaryfp;
13003 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13004 mips32_op = OPC_CVT_W_D;
13005 goto do_unaryfp;
13006
13007 /* Paired-foo conversions */
13008 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13009 mips32_op = OPC_CVT_S_PL;
13010 goto do_unaryfp;
13011 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13012 mips32_op = OPC_CVT_S_PU;
13013 goto do_unaryfp;
13014 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13015 mips32_op = OPC_CVT_PW_PS;
13016 goto do_unaryfp;
13017 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13018 mips32_op = OPC_CVT_PS_PW;
13019 goto do_unaryfp;
13020
13021 /* Floating-point moves */
13022 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13023 mips32_op = OPC_MOV_S;
13024 goto do_unaryfp;
13025 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13026 mips32_op = OPC_MOV_D;
13027 goto do_unaryfp;
13028 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13029 mips32_op = OPC_MOV_PS;
13030 goto do_unaryfp;
13031
13032 /* Absolute value */
13033 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13034 mips32_op = OPC_ABS_S;
13035 goto do_unaryfp;
13036 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13037 mips32_op = OPC_ABS_D;
13038 goto do_unaryfp;
13039 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13040 mips32_op = OPC_ABS_PS;
13041 goto do_unaryfp;
13042
13043 /* Negation */
13044 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13045 mips32_op = OPC_NEG_S;
13046 goto do_unaryfp;
13047 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13048 mips32_op = OPC_NEG_D;
13049 goto do_unaryfp;
13050 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13051 mips32_op = OPC_NEG_PS;
13052 goto do_unaryfp;
13053
13054 /* Reciprocal square root step */
13055 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13056 mips32_op = OPC_RSQRT1_S;
13057 goto do_unaryfp;
13058 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13059 mips32_op = OPC_RSQRT1_D;
13060 goto do_unaryfp;
13061 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13062 mips32_op = OPC_RSQRT1_PS;
13063 goto do_unaryfp;
13064
13065 /* Reciprocal step */
13066 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13067 mips32_op = OPC_RECIP1_S;
13068 goto do_unaryfp;
13069 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13070 mips32_op = OPC_RECIP1_S;
13071 goto do_unaryfp;
13072 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13073 mips32_op = OPC_RECIP1_PS;
13074 goto do_unaryfp;
13075
13076 /* Conversions from double */
13077 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13078 mips32_op = OPC_CVT_D_S;
13079 goto do_unaryfp;
13080 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13081 mips32_op = OPC_CVT_D_W;
13082 goto do_unaryfp;
13083 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13084 mips32_op = OPC_CVT_D_L;
13085 goto do_unaryfp;
13086
13087 /* Conversions from single */
13088 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13089 mips32_op = OPC_CVT_S_D;
13090 goto do_unaryfp;
13091 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13092 mips32_op = OPC_CVT_S_W;
13093 goto do_unaryfp;
13094 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13095 mips32_op = OPC_CVT_S_L;
13096 do_unaryfp:
13097 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13098 break;
13099
13100 /* Conditional moves on floating-point codes */
13101 case COND_FLOAT_MOV(MOVT, 0):
13102 case COND_FLOAT_MOV(MOVT, 1):
13103 case COND_FLOAT_MOV(MOVT, 2):
13104 case COND_FLOAT_MOV(MOVT, 3):
13105 case COND_FLOAT_MOV(MOVT, 4):
13106 case COND_FLOAT_MOV(MOVT, 5):
13107 case COND_FLOAT_MOV(MOVT, 6):
13108 case COND_FLOAT_MOV(MOVT, 7):
13109 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13110 break;
13111 case COND_FLOAT_MOV(MOVF, 0):
13112 case COND_FLOAT_MOV(MOVF, 1):
13113 case COND_FLOAT_MOV(MOVF, 2):
13114 case COND_FLOAT_MOV(MOVF, 3):
13115 case COND_FLOAT_MOV(MOVF, 4):
13116 case COND_FLOAT_MOV(MOVF, 5):
13117 case COND_FLOAT_MOV(MOVF, 6):
13118 case COND_FLOAT_MOV(MOVF, 7):
13119 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13120 break;
13121 default:
13122 MIPS_INVAL("pool32fxf");
13123 generate_exception(ctx, EXCP_RI);
13124 break;
13125 }
13126}
13127
7db13fae 13128static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13129 uint16_t insn_hw1)
3c824109
NF
13130{
13131 int32_t offset;
13132 uint16_t insn;
13133 int rt, rs, rd, rr;
13134 int16_t imm;
13135 uint32_t op, minor, mips32_op;
13136 uint32_t cond, fmt, cc;
13137
895c2d04 13138 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13139 ctx->opcode = (ctx->opcode << 16) | insn;
13140
13141 rt = (ctx->opcode >> 21) & 0x1f;
13142 rs = (ctx->opcode >> 16) & 0x1f;
13143 rd = (ctx->opcode >> 11) & 0x1f;
13144 rr = (ctx->opcode >> 6) & 0x1f;
13145 imm = (int16_t) ctx->opcode;
13146
13147 op = (ctx->opcode >> 26) & 0x3f;
13148 switch (op) {
13149 case POOL32A:
13150 minor = ctx->opcode & 0x3f;
13151 switch (minor) {
13152 case 0x00:
13153 minor = (ctx->opcode >> 6) & 0xf;
13154 switch (minor) {
13155 case SLL32:
13156 mips32_op = OPC_SLL;
13157 goto do_shifti;
13158 case SRA:
13159 mips32_op = OPC_SRA;
13160 goto do_shifti;
13161 case SRL32:
13162 mips32_op = OPC_SRL;
13163 goto do_shifti;
13164 case ROTR:
13165 mips32_op = OPC_ROTR;
13166 do_shifti:
d75c135e 13167 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13168 break;
13169 default:
13170 goto pool32a_invalid;
13171 }
13172 break;
13173 case 0x10:
13174 minor = (ctx->opcode >> 6) & 0xf;
13175 switch (minor) {
13176 /* Arithmetic */
13177 case ADD:
13178 mips32_op = OPC_ADD;
13179 goto do_arith;
13180 case ADDU32:
13181 mips32_op = OPC_ADDU;
13182 goto do_arith;
13183 case SUB:
13184 mips32_op = OPC_SUB;
13185 goto do_arith;
13186 case SUBU32:
13187 mips32_op = OPC_SUBU;
13188 goto do_arith;
13189 case MUL:
13190 mips32_op = OPC_MUL;
13191 do_arith:
d75c135e 13192 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13193 break;
13194 /* Shifts */
13195 case SLLV:
13196 mips32_op = OPC_SLLV;
13197 goto do_shift;
13198 case SRLV:
13199 mips32_op = OPC_SRLV;
13200 goto do_shift;
13201 case SRAV:
13202 mips32_op = OPC_SRAV;
13203 goto do_shift;
13204 case ROTRV:
13205 mips32_op = OPC_ROTRV;
13206 do_shift:
d75c135e 13207 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13208 break;
13209 /* Logical operations */
13210 case AND:
13211 mips32_op = OPC_AND;
13212 goto do_logic;
13213 case OR32:
13214 mips32_op = OPC_OR;
13215 goto do_logic;
13216 case NOR:
13217 mips32_op = OPC_NOR;
13218 goto do_logic;
13219 case XOR32:
13220 mips32_op = OPC_XOR;
13221 do_logic:
d75c135e 13222 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13223 break;
13224 /* Set less than */
13225 case SLT:
13226 mips32_op = OPC_SLT;
13227 goto do_slt;
13228 case SLTU:
13229 mips32_op = OPC_SLTU;
13230 do_slt:
d75c135e 13231 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13232 break;
13233 default:
13234 goto pool32a_invalid;
13235 }
13236 break;
13237 case 0x18:
13238 minor = (ctx->opcode >> 6) & 0xf;
13239 switch (minor) {
13240 /* Conditional moves */
13241 case MOVN:
13242 mips32_op = OPC_MOVN;
13243 goto do_cmov;
13244 case MOVZ:
13245 mips32_op = OPC_MOVZ;
13246 do_cmov:
d75c135e 13247 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13248 break;
13249 case LWXS:
13250 gen_ldxs(ctx, rs, rt, rd);
13251 break;
13252 default:
13253 goto pool32a_invalid;
13254 }
13255 break;
13256 case INS:
13257 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13258 return;
13259 case EXT:
13260 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13261 return;
13262 case POOL32AXF:
240ce26a 13263 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13264 break;
13265 case 0x07:
13266 generate_exception(ctx, EXCP_BREAK);
13267 break;
13268 default:
13269 pool32a_invalid:
13270 MIPS_INVAL("pool32a");
13271 generate_exception(ctx, EXCP_RI);
13272 break;
13273 }
13274 break;
13275 case POOL32B:
13276 minor = (ctx->opcode >> 12) & 0xf;
13277 switch (minor) {
13278 case CACHE:
2e15497c 13279 check_cp0_enabled(ctx);
3c824109
NF
13280 /* Treat as no-op. */
13281 break;
13282 case LWC2:
13283 case SWC2:
13284 /* COP2: Not implemented. */
13285 generate_exception_err(ctx, EXCP_CpU, 2);
13286 break;
3c824109
NF
13287#ifdef TARGET_MIPS64
13288 case LDP:
13289 case SDP:
d9224450
MR
13290 check_insn(ctx, ISA_MIPS3);
13291 check_mips_64(ctx);
13292 /* Fallthrough */
3c824109 13293#endif
d9224450
MR
13294 case LWP:
13295 case SWP:
3c824109
NF
13296 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13297 break;
3c824109
NF
13298#ifdef TARGET_MIPS64
13299 case LDM:
13300 case SDM:
d9224450
MR
13301 check_insn(ctx, ISA_MIPS3);
13302 check_mips_64(ctx);
13303 /* Fallthrough */
3c824109 13304#endif
d9224450
MR
13305 case LWM32:
13306 case SWM32:
3c824109
NF
13307 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13308 break;
13309 default:
13310 MIPS_INVAL("pool32b");
13311 generate_exception(ctx, EXCP_RI);
13312 break;
13313 }
13314 break;
13315 case POOL32F:
5ab5c041 13316 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13317 minor = ctx->opcode & 0x3f;
13318 check_cp1_enabled(ctx);
13319 switch (minor) {
13320 case ALNV_PS:
13321 mips32_op = OPC_ALNV_PS;
13322 goto do_madd;
13323 case MADD_S:
13324 mips32_op = OPC_MADD_S;
13325 goto do_madd;
13326 case MADD_D:
13327 mips32_op = OPC_MADD_D;
13328 goto do_madd;
13329 case MADD_PS:
13330 mips32_op = OPC_MADD_PS;
13331 goto do_madd;
13332 case MSUB_S:
13333 mips32_op = OPC_MSUB_S;
13334 goto do_madd;
13335 case MSUB_D:
13336 mips32_op = OPC_MSUB_D;
13337 goto do_madd;
13338 case MSUB_PS:
13339 mips32_op = OPC_MSUB_PS;
13340 goto do_madd;
13341 case NMADD_S:
13342 mips32_op = OPC_NMADD_S;
13343 goto do_madd;
13344 case NMADD_D:
13345 mips32_op = OPC_NMADD_D;
13346 goto do_madd;
13347 case NMADD_PS:
13348 mips32_op = OPC_NMADD_PS;
13349 goto do_madd;
13350 case NMSUB_S:
13351 mips32_op = OPC_NMSUB_S;
13352 goto do_madd;
13353 case NMSUB_D:
13354 mips32_op = OPC_NMSUB_D;
13355 goto do_madd;
13356 case NMSUB_PS:
13357 mips32_op = OPC_NMSUB_PS;
13358 do_madd:
13359 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13360 break;
13361 case CABS_COND_FMT:
13362 cond = (ctx->opcode >> 6) & 0xf;
13363 cc = (ctx->opcode >> 13) & 0x7;
13364 fmt = (ctx->opcode >> 10) & 0x3;
13365 switch (fmt) {
13366 case 0x0:
13367 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13368 break;
13369 case 0x1:
13370 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13371 break;
13372 case 0x2:
13373 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13374 break;
13375 default:
13376 goto pool32f_invalid;
13377 }
13378 break;
13379 case C_COND_FMT:
13380 cond = (ctx->opcode >> 6) & 0xf;
13381 cc = (ctx->opcode >> 13) & 0x7;
13382 fmt = (ctx->opcode >> 10) & 0x3;
13383 switch (fmt) {
13384 case 0x0:
13385 gen_cmp_s(ctx, cond, rt, rs, cc);
13386 break;
13387 case 0x1:
13388 gen_cmp_d(ctx, cond, rt, rs, cc);
13389 break;
13390 case 0x2:
13391 gen_cmp_ps(ctx, cond, rt, rs, cc);
13392 break;
13393 default:
13394 goto pool32f_invalid;
13395 }
13396 break;
13397 case POOL32FXF:
d75c135e 13398 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13399 break;
13400 case 0x00:
13401 /* PLL foo */
13402 switch ((ctx->opcode >> 6) & 0x7) {
13403 case PLL_PS:
13404 mips32_op = OPC_PLL_PS;
13405 goto do_ps;
13406 case PLU_PS:
13407 mips32_op = OPC_PLU_PS;
13408 goto do_ps;
13409 case PUL_PS:
13410 mips32_op = OPC_PUL_PS;
13411 goto do_ps;
13412 case PUU_PS:
13413 mips32_op = OPC_PUU_PS;
13414 goto do_ps;
13415 case CVT_PS_S:
13416 mips32_op = OPC_CVT_PS_S;
13417 do_ps:
13418 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13419 break;
13420 default:
13421 goto pool32f_invalid;
13422 }
13423 break;
13424 case 0x08:
13425 /* [LS][WDU]XC1 */
13426 switch ((ctx->opcode >> 6) & 0x7) {
13427 case LWXC1:
13428 mips32_op = OPC_LWXC1;
13429 goto do_ldst_cp1;
13430 case SWXC1:
13431 mips32_op = OPC_SWXC1;
13432 goto do_ldst_cp1;
13433 case LDXC1:
13434 mips32_op = OPC_LDXC1;
13435 goto do_ldst_cp1;
13436 case SDXC1:
13437 mips32_op = OPC_SDXC1;
13438 goto do_ldst_cp1;
13439 case LUXC1:
13440 mips32_op = OPC_LUXC1;
13441 goto do_ldst_cp1;
13442 case SUXC1:
13443 mips32_op = OPC_SUXC1;
13444 do_ldst_cp1:
13445 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13446 break;
13447 default:
13448 goto pool32f_invalid;
13449 }
13450 break;
13451 case 0x18:
13452 /* 3D insns */
13453 fmt = (ctx->opcode >> 9) & 0x3;
13454 switch ((ctx->opcode >> 6) & 0x7) {
13455 case RSQRT2_FMT:
13456 switch (fmt) {
13457 case FMT_SDPS_S:
13458 mips32_op = OPC_RSQRT2_S;
13459 goto do_3d;
13460 case FMT_SDPS_D:
13461 mips32_op = OPC_RSQRT2_D;
13462 goto do_3d;
13463 case FMT_SDPS_PS:
13464 mips32_op = OPC_RSQRT2_PS;
13465 goto do_3d;
13466 default:
13467 goto pool32f_invalid;
13468 }
13469 break;
13470 case RECIP2_FMT:
13471 switch (fmt) {
13472 case FMT_SDPS_S:
13473 mips32_op = OPC_RECIP2_S;
13474 goto do_3d;
13475 case FMT_SDPS_D:
13476 mips32_op = OPC_RECIP2_D;
13477 goto do_3d;
13478 case FMT_SDPS_PS:
13479 mips32_op = OPC_RECIP2_PS;
13480 goto do_3d;
13481 default:
13482 goto pool32f_invalid;
13483 }
13484 break;
13485 case ADDR_PS:
13486 mips32_op = OPC_ADDR_PS;
13487 goto do_3d;
13488 case MULR_PS:
13489 mips32_op = OPC_MULR_PS;
13490 do_3d:
13491 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13492 break;
13493 default:
13494 goto pool32f_invalid;
13495 }
13496 break;
13497 case 0x20:
13498 /* MOV[FT].fmt and PREFX */
13499 cc = (ctx->opcode >> 13) & 0x7;
13500 fmt = (ctx->opcode >> 9) & 0x3;
13501 switch ((ctx->opcode >> 6) & 0x7) {
13502 case MOVF_FMT:
13503 switch (fmt) {
13504 case FMT_SDPS_S:
13505 gen_movcf_s(rs, rt, cc, 0);
13506 break;
13507 case FMT_SDPS_D:
13508 gen_movcf_d(ctx, rs, rt, cc, 0);
13509 break;
13510 case FMT_SDPS_PS:
7f6613ce 13511 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13512 break;
13513 default:
13514 goto pool32f_invalid;
13515 }
13516 break;
13517 case MOVT_FMT:
13518 switch (fmt) {
13519 case FMT_SDPS_S:
13520 gen_movcf_s(rs, rt, cc, 1);
13521 break;
13522 case FMT_SDPS_D:
13523 gen_movcf_d(ctx, rs, rt, cc, 1);
13524 break;
13525 case FMT_SDPS_PS:
7f6613ce 13526 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13527 break;
13528 default:
13529 goto pool32f_invalid;
13530 }
13531 break;
13532 case PREFX:
13533 break;
13534 default:
13535 goto pool32f_invalid;
13536 }
13537 break;
13538#define FINSN_3ARG_SDPS(prfx) \
13539 switch ((ctx->opcode >> 8) & 0x3) { \
13540 case FMT_SDPS_S: \
13541 mips32_op = OPC_##prfx##_S; \
13542 goto do_fpop; \
13543 case FMT_SDPS_D: \
13544 mips32_op = OPC_##prfx##_D; \
13545 goto do_fpop; \
13546 case FMT_SDPS_PS: \
13547 mips32_op = OPC_##prfx##_PS; \
13548 goto do_fpop; \
13549 default: \
13550 goto pool32f_invalid; \
13551 }
13552 case 0x30:
13553 /* regular FP ops */
13554 switch ((ctx->opcode >> 6) & 0x3) {
13555 case ADD_FMT:
13556 FINSN_3ARG_SDPS(ADD);
13557 break;
13558 case SUB_FMT:
13559 FINSN_3ARG_SDPS(SUB);
13560 break;
13561 case MUL_FMT:
13562 FINSN_3ARG_SDPS(MUL);
13563 break;
13564 case DIV_FMT:
13565 fmt = (ctx->opcode >> 8) & 0x3;
13566 if (fmt == 1) {
13567 mips32_op = OPC_DIV_D;
13568 } else if (fmt == 0) {
13569 mips32_op = OPC_DIV_S;
13570 } else {
13571 goto pool32f_invalid;
13572 }
13573 goto do_fpop;
13574 default:
13575 goto pool32f_invalid;
13576 }
13577 break;
13578 case 0x38:
13579 /* cmovs */
13580 switch ((ctx->opcode >> 6) & 0x3) {
13581 case MOVN_FMT:
13582 FINSN_3ARG_SDPS(MOVN);
13583 break;
13584 case MOVZ_FMT:
13585 FINSN_3ARG_SDPS(MOVZ);
13586 break;
13587 default:
13588 goto pool32f_invalid;
13589 }
13590 break;
13591 do_fpop:
13592 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13593 break;
13594 default:
13595 pool32f_invalid:
13596 MIPS_INVAL("pool32f");
13597 generate_exception(ctx, EXCP_RI);
13598 break;
13599 }
13600 } else {
13601 generate_exception_err(ctx, EXCP_CpU, 1);
13602 }
13603 break;
13604 case POOL32I:
13605 minor = (ctx->opcode >> 21) & 0x1f;
13606 switch (minor) {
13607 case BLTZ:
b231c103
YK
13608 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13609 break;
3c824109 13610 case BLTZAL:
b231c103
YK
13611 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13612 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13613 break;
3c824109 13614 case BLTZALS:
b231c103
YK
13615 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13616 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13617 break;
3c824109 13618 case BGEZ:
b231c103
YK
13619 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13620 break;
3c824109 13621 case BGEZAL:
b231c103
YK
13622 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13623 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13624 break;
3c824109 13625 case BGEZALS:
b231c103
YK
13626 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13627 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13628 break;
3c824109 13629 case BLEZ:
b231c103
YK
13630 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13631 break;
3c824109 13632 case BGTZ:
b231c103 13633 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13634 break;
13635
13636 /* Traps */
13637 case TLTI:
13638 mips32_op = OPC_TLTI;
13639 goto do_trapi;
13640 case TGEI:
13641 mips32_op = OPC_TGEI;
13642 goto do_trapi;
13643 case TLTIU:
13644 mips32_op = OPC_TLTIU;
13645 goto do_trapi;
13646 case TGEIU:
13647 mips32_op = OPC_TGEIU;
13648 goto do_trapi;
13649 case TNEI:
13650 mips32_op = OPC_TNEI;
13651 goto do_trapi;
13652 case TEQI:
13653 mips32_op = OPC_TEQI;
13654 do_trapi:
13655 gen_trap(ctx, mips32_op, rs, -1, imm);
13656 break;
13657
13658 case BNEZC:
13659 case BEQZC:
13660 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13661 4, rs, 0, imm << 1, 0);
3c824109
NF
13662 /* Compact branches don't have a delay slot, so just let
13663 the normal delay slot handling take us to the branch
13664 target. */
13665 break;
13666 case LUI:
5e88759a 13667 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
13668 break;
13669 case SYNCI:
a83bddd6
DZ
13670 /* Break the TB to be able to sync copied instructions
13671 immediately */
13672 ctx->bstate = BS_STOP;
3c824109
NF
13673 break;
13674 case BC2F:
13675 case BC2T:
13676 /* COP2: Not implemented. */
13677 generate_exception_err(ctx, EXCP_CpU, 2);
13678 break;
13679 case BC1F:
13680 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13681 goto do_cp1branch;
13682 case BC1T:
13683 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13684 goto do_cp1branch;
13685 case BC1ANY4F:
13686 mips32_op = OPC_BC1FANY4;
13687 goto do_cp1mips3d;
13688 case BC1ANY4T:
13689 mips32_op = OPC_BC1TANY4;
13690 do_cp1mips3d:
13691 check_cop1x(ctx);
d75c135e 13692 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13693 /* Fall through */
13694 do_cp1branch:
272f458d
MR
13695 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13696 check_cp1_enabled(ctx);
13697 gen_compute_branch1(ctx, mips32_op,
13698 (ctx->opcode >> 18) & 0x7, imm << 1);
13699 } else {
13700 generate_exception_err(ctx, EXCP_CpU, 1);
13701 }
3c824109
NF
13702 break;
13703 case BPOSGE64:
13704 case BPOSGE32:
13705 /* MIPS DSP: not implemented */
13706 /* Fall through */
13707 default:
13708 MIPS_INVAL("pool32i");
13709 generate_exception(ctx, EXCP_RI);
13710 break;
13711 }
13712 break;
13713 case POOL32C:
13714 minor = (ctx->opcode >> 12) & 0xf;
13715 switch (minor) {
13716 case LWL:
13717 mips32_op = OPC_LWL;
5c13fdfd 13718 goto do_ld_lr;
3c824109
NF
13719 case SWL:
13720 mips32_op = OPC_SWL;
5c13fdfd 13721 goto do_st_lr;
3c824109
NF
13722 case LWR:
13723 mips32_op = OPC_LWR;
5c13fdfd 13724 goto do_ld_lr;
3c824109
NF
13725 case SWR:
13726 mips32_op = OPC_SWR;
5c13fdfd 13727 goto do_st_lr;
3c824109
NF
13728#if defined(TARGET_MIPS64)
13729 case LDL:
d9224450
MR
13730 check_insn(ctx, ISA_MIPS3);
13731 check_mips_64(ctx);
3c824109 13732 mips32_op = OPC_LDL;
5c13fdfd 13733 goto do_ld_lr;
3c824109 13734 case SDL:
d9224450
MR
13735 check_insn(ctx, ISA_MIPS3);
13736 check_mips_64(ctx);
3c824109 13737 mips32_op = OPC_SDL;
5c13fdfd 13738 goto do_st_lr;
3c824109 13739 case LDR:
d9224450
MR
13740 check_insn(ctx, ISA_MIPS3);
13741 check_mips_64(ctx);
3c824109 13742 mips32_op = OPC_LDR;
5c13fdfd 13743 goto do_ld_lr;
3c824109 13744 case SDR:
d9224450
MR
13745 check_insn(ctx, ISA_MIPS3);
13746 check_mips_64(ctx);
3c824109 13747 mips32_op = OPC_SDR;
5c13fdfd 13748 goto do_st_lr;
3c824109 13749 case LWU:
d9224450
MR
13750 check_insn(ctx, ISA_MIPS3);
13751 check_mips_64(ctx);
3c824109 13752 mips32_op = OPC_LWU;
5c13fdfd 13753 goto do_ld_lr;
3c824109 13754 case LLD:
d9224450
MR
13755 check_insn(ctx, ISA_MIPS3);
13756 check_mips_64(ctx);
3c824109 13757 mips32_op = OPC_LLD;
5c13fdfd 13758 goto do_ld_lr;
3c824109
NF
13759#endif
13760 case LL:
13761 mips32_op = OPC_LL;
5c13fdfd
AJ
13762 goto do_ld_lr;
13763 do_ld_lr:
d75c135e 13764 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13765 break;
13766 do_st_lr:
13767 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13768 break;
13769 case SC:
13770 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13771 break;
13772#if defined(TARGET_MIPS64)
13773 case SCD:
d9224450
MR
13774 check_insn(ctx, ISA_MIPS3);
13775 check_mips_64(ctx);
3c824109
NF
13776 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13777 break;
13778#endif
13779 case PREF:
13780 /* Treat as no-op */
13781 break;
13782 default:
13783 MIPS_INVAL("pool32c");
13784 generate_exception(ctx, EXCP_RI);
13785 break;
13786 }
13787 break;
13788 case ADDI32:
13789 mips32_op = OPC_ADDI;
13790 goto do_addi;
13791 case ADDIU32:
13792 mips32_op = OPC_ADDIU;
13793 do_addi:
d75c135e 13794 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13795 break;
13796
13797 /* Logical operations */
13798 case ORI32:
13799 mips32_op = OPC_ORI;
13800 goto do_logici;
13801 case XORI32:
13802 mips32_op = OPC_XORI;
13803 goto do_logici;
13804 case ANDI32:
13805 mips32_op = OPC_ANDI;
13806 do_logici:
d75c135e 13807 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13808 break;
13809
13810 /* Set less than immediate */
13811 case SLTI32:
13812 mips32_op = OPC_SLTI;
13813 goto do_slti;
13814 case SLTIU32:
13815 mips32_op = OPC_SLTIU;
13816 do_slti:
d75c135e 13817 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13818 break;
13819 case JALX32:
13820 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13821 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13822 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13823 break;
13824 case JALS32:
13825 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13826 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13827 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13828 break;
13829 case BEQ32:
b231c103 13830 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13831 break;
13832 case BNE32:
b231c103 13833 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13834 break;
13835 case J32:
13836 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13837 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13838 break;
13839 case JAL32:
13840 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13841 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13842 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13843 break;
13844 /* Floating point (COP1) */
13845 case LWC132:
13846 mips32_op = OPC_LWC1;
13847 goto do_cop1;
13848 case LDC132:
13849 mips32_op = OPC_LDC1;
13850 goto do_cop1;
13851 case SWC132:
13852 mips32_op = OPC_SWC1;
13853 goto do_cop1;
13854 case SDC132:
13855 mips32_op = OPC_SDC1;
13856 do_cop1:
5ab5c041 13857 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13858 break;
13859 case ADDIUPC:
13860 {
13861 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13862 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13863
13864 gen_addiupc(ctx, reg, offset, 0, 0);
13865 }
13866 break;
13867 /* Loads and stores */
13868 case LB32:
13869 mips32_op = OPC_LB;
5c13fdfd 13870 goto do_ld;
3c824109
NF
13871 case LBU32:
13872 mips32_op = OPC_LBU;
5c13fdfd 13873 goto do_ld;
3c824109
NF
13874 case LH32:
13875 mips32_op = OPC_LH;
5c13fdfd 13876 goto do_ld;
3c824109
NF
13877 case LHU32:
13878 mips32_op = OPC_LHU;
5c13fdfd 13879 goto do_ld;
3c824109
NF
13880 case LW32:
13881 mips32_op = OPC_LW;
5c13fdfd 13882 goto do_ld;
3c824109
NF
13883#ifdef TARGET_MIPS64
13884 case LD32:
d9224450
MR
13885 check_insn(ctx, ISA_MIPS3);
13886 check_mips_64(ctx);
3c824109 13887 mips32_op = OPC_LD;
5c13fdfd 13888 goto do_ld;
3c824109 13889 case SD32:
d9224450
MR
13890 check_insn(ctx, ISA_MIPS3);
13891 check_mips_64(ctx);
3c824109 13892 mips32_op = OPC_SD;
5c13fdfd 13893 goto do_st;
3c824109
NF
13894#endif
13895 case SB32:
13896 mips32_op = OPC_SB;
5c13fdfd 13897 goto do_st;
3c824109
NF
13898 case SH32:
13899 mips32_op = OPC_SH;
5c13fdfd 13900 goto do_st;
3c824109
NF
13901 case SW32:
13902 mips32_op = OPC_SW;
5c13fdfd
AJ
13903 goto do_st;
13904 do_ld:
d75c135e 13905 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13906 break;
13907 do_st:
13908 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13909 break;
13910 default:
13911 generate_exception(ctx, EXCP_RI);
13912 break;
13913 }
13914}
13915
240ce26a 13916static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13917{
13918 uint32_t op;
13919
13920 /* make sure instructions are on a halfword boundary */
13921 if (ctx->pc & 0x1) {
13922 env->CP0_BadVAddr = ctx->pc;
13923 generate_exception(ctx, EXCP_AdEL);
13924 ctx->bstate = BS_STOP;
13925 return 2;
13926 }
13927
13928 op = (ctx->opcode >> 10) & 0x3f;
13929 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13930 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13931 switch (op & 0x7) { /* MSB-3..MSB-5 */
13932 case 0:
13933 /* POOL32A, POOL32B, POOL32I, POOL32C */
13934 case 4:
13935 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13936 case 5:
13937 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13938 case 6:
13939 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13940 case 7:
13941 /* LB32, LH32, LWC132, LDC132, LW32 */
13942 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13943 generate_exception(ctx, EXCP_RI);
13944 /* Just stop translation; the user is confused. */
13945 ctx->bstate = BS_STOP;
13946 return 2;
13947 }
13948 break;
b231c103
YK
13949 case 1:
13950 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13951 case 2:
13952 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13953 case 3:
13954 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13955 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13956 generate_exception(ctx, EXCP_RI);
13957 /* Just stop translation; the user is confused. */
13958 ctx->bstate = BS_STOP;
13959 return 2;
13960 }
13961 break;
3c824109
NF
13962 }
13963 }
b231c103 13964
3c824109
NF
13965 switch (op) {
13966 case POOL16A:
13967 {
13968 int rd = mmreg(uMIPS_RD(ctx->opcode));
13969 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13970 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13971 uint32_t opc = 0;
13972
13973 switch (ctx->opcode & 0x1) {
13974 case ADDU16:
13975 opc = OPC_ADDU;
13976 break;
13977 case SUBU16:
13978 opc = OPC_SUBU;
13979 break;
13980 }
13981
d75c135e 13982 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13983 }
13984 break;
13985 case POOL16B:
13986 {
13987 int rd = mmreg(uMIPS_RD(ctx->opcode));
13988 int rs = mmreg(uMIPS_RS(ctx->opcode));
13989 int amount = (ctx->opcode >> 1) & 0x7;
13990 uint32_t opc = 0;
13991 amount = amount == 0 ? 8 : amount;
13992
13993 switch (ctx->opcode & 0x1) {
13994 case SLL16:
13995 opc = OPC_SLL;
13996 break;
13997 case SRL16:
13998 opc = OPC_SRL;
13999 break;
14000 }
14001
d75c135e 14002 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14003 }
14004 break;
14005 case POOL16C:
240ce26a 14006 gen_pool16c_insn(ctx);
3c824109
NF
14007 break;
14008 case LWGP16:
14009 {
14010 int rd = mmreg(uMIPS_RD(ctx->opcode));
14011 int rb = 28; /* GP */
14012 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14013
d75c135e 14014 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14015 }
14016 break;
14017 case POOL16F:
14018 if (ctx->opcode & 1) {
14019 generate_exception(ctx, EXCP_RI);
14020 } else {
14021 /* MOVEP */
14022 int enc_dest = uMIPS_RD(ctx->opcode);
14023 int enc_rt = uMIPS_RS2(ctx->opcode);
14024 int enc_rs = uMIPS_RS1(ctx->opcode);
14025 int rd, rs, re, rt;
14026 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14027 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14028 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14029
14030 rd = rd_enc[enc_dest];
14031 re = re_enc[enc_dest];
14032 rs = rs_rt_enc[enc_rs];
14033 rt = rs_rt_enc[enc_rt];
14034
7215d7e7
MR
14035 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14036 gen_arith(ctx, OPC_ADDU, re, rt, 0);
3c824109
NF
14037 }
14038 break;
14039 case LBU16:
14040 {
14041 int rd = mmreg(uMIPS_RD(ctx->opcode));
14042 int rb = mmreg(uMIPS_RS(ctx->opcode));
14043 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14044 offset = (offset == 0xf ? -1 : offset);
14045
d75c135e 14046 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14047 }
14048 break;
14049 case LHU16:
14050 {
14051 int rd = mmreg(uMIPS_RD(ctx->opcode));
14052 int rb = mmreg(uMIPS_RS(ctx->opcode));
14053 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14054
d75c135e 14055 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14056 }
14057 break;
14058 case LWSP16:
14059 {
14060 int rd = (ctx->opcode >> 5) & 0x1f;
14061 int rb = 29; /* SP */
14062 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14063
d75c135e 14064 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14065 }
14066 break;
14067 case LW16:
14068 {
14069 int rd = mmreg(uMIPS_RD(ctx->opcode));
14070 int rb = mmreg(uMIPS_RS(ctx->opcode));
14071 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14072
d75c135e 14073 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14074 }
14075 break;
14076 case SB16:
14077 {
14078 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14079 int rb = mmreg(uMIPS_RS(ctx->opcode));
14080 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14081
5c13fdfd 14082 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14083 }
14084 break;
14085 case SH16:
14086 {
14087 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14088 int rb = mmreg(uMIPS_RS(ctx->opcode));
14089 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14090
5c13fdfd 14091 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14092 }
14093 break;
14094 case SWSP16:
14095 {
14096 int rd = (ctx->opcode >> 5) & 0x1f;
14097 int rb = 29; /* SP */
14098 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14099
5c13fdfd 14100 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14101 }
14102 break;
14103 case SW16:
14104 {
14105 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14106 int rb = mmreg(uMIPS_RS(ctx->opcode));
14107 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14108
5c13fdfd 14109 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14110 }
14111 break;
14112 case MOVE16:
14113 {
14114 int rd = uMIPS_RD5(ctx->opcode);
14115 int rs = uMIPS_RS5(ctx->opcode);
14116
7215d7e7 14117 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14118 }
14119 break;
14120 case ANDI16:
d75c135e 14121 gen_andi16(ctx);
3c824109
NF
14122 break;
14123 case POOL16D:
14124 switch (ctx->opcode & 0x1) {
14125 case ADDIUS5:
d75c135e 14126 gen_addius5(ctx);
3c824109
NF
14127 break;
14128 case ADDIUSP:
d75c135e 14129 gen_addiusp(ctx);
3c824109
NF
14130 break;
14131 }
14132 break;
14133 case POOL16E:
14134 switch (ctx->opcode & 0x1) {
14135 case ADDIUR2:
d75c135e 14136 gen_addiur2(ctx);
3c824109
NF
14137 break;
14138 case ADDIUR1SP:
d75c135e 14139 gen_addiur1sp(ctx);
3c824109
NF
14140 break;
14141 }
14142 break;
14143 case B16:
14144 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14145 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14146 break;
14147 case BNEZ16:
14148 case BEQZ16:
14149 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14150 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14151 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14152 break;
14153 case LI16:
14154 {
14155 int reg = mmreg(uMIPS_RD(ctx->opcode));
14156 int imm = ZIMM(ctx->opcode, 0, 7);
14157
14158 imm = (imm == 0x7f ? -1 : imm);
14159 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14160 }
14161 break;
14162 case RES_20:
14163 case RES_28:
14164 case RES_29:
14165 case RES_30:
14166 case RES_31:
14167 case RES_38:
14168 case RES_39:
14169 generate_exception(ctx, EXCP_RI);
14170 break;
14171 default:
240ce26a 14172 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14173 return 4;
14174 }
14175
14176 return 2;
14177}
14178
14179/* SmartMIPS extension to MIPS32 */
14180
14181#if defined(TARGET_MIPS64)
14182
14183/* MDMX extension to MIPS64 */
14184
14185#endif
14186
9b1a1d68 14187/* MIPSDSP functions. */
d75c135e 14188static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14189 int rd, int base, int offset)
14190{
14191 const char *opn = "ldx";
14192 TCGv t0;
14193
9b1a1d68
JL
14194 check_dsp(ctx);
14195 t0 = tcg_temp_new();
14196
14197 if (base == 0) {
14198 gen_load_gpr(t0, offset);
14199 } else if (offset == 0) {
14200 gen_load_gpr(t0, base);
14201 } else {
14202 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14203 }
14204
9b1a1d68
JL
14205 switch (opc) {
14206 case OPC_LBUX:
5f68f5ae 14207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14208 gen_store_gpr(t0, rd);
14209 opn = "lbux";
14210 break;
14211 case OPC_LHX:
5f68f5ae 14212 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14213 gen_store_gpr(t0, rd);
14214 opn = "lhx";
14215 break;
14216 case OPC_LWX:
5f68f5ae 14217 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14218 gen_store_gpr(t0, rd);
14219 opn = "lwx";
14220 break;
14221#if defined(TARGET_MIPS64)
14222 case OPC_LDX:
5f68f5ae 14223 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14224 gen_store_gpr(t0, rd);
14225 opn = "ldx";
14226 break;
14227#endif
14228 }
14229 (void)opn; /* avoid a compiler warning */
14230 MIPS_DEBUG("%s %s, %s(%s)", opn,
14231 regnames[rd], regnames[offset], regnames[base]);
14232 tcg_temp_free(t0);
14233}
14234
461c08df
JL
14235static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14236 int ret, int v1, int v2)
14237{
14238 const char *opn = "mipsdsp arith";
14239 TCGv v1_t;
14240 TCGv v2_t;
14241
14242 if (ret == 0) {
14243 /* Treat as NOP. */
14244 MIPS_DEBUG("NOP");
14245 return;
14246 }
14247
14248 v1_t = tcg_temp_new();
14249 v2_t = tcg_temp_new();
14250
14251 gen_load_gpr(v1_t, v1);
14252 gen_load_gpr(v2_t, v2);
14253
14254 switch (op1) {
14255 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14256 case OPC_MULT_G_2E:
14257 check_dspr2(ctx);
14258 switch (op2) {
14259 case OPC_ADDUH_QB:
14260 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14261 break;
14262 case OPC_ADDUH_R_QB:
14263 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14264 break;
14265 case OPC_ADDQH_PH:
14266 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14267 break;
14268 case OPC_ADDQH_R_PH:
14269 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14270 break;
14271 case OPC_ADDQH_W:
14272 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14273 break;
14274 case OPC_ADDQH_R_W:
14275 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14276 break;
14277 case OPC_SUBUH_QB:
14278 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14279 break;
14280 case OPC_SUBUH_R_QB:
14281 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14282 break;
14283 case OPC_SUBQH_PH:
14284 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14285 break;
14286 case OPC_SUBQH_R_PH:
14287 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14288 break;
14289 case OPC_SUBQH_W:
14290 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14291 break;
14292 case OPC_SUBQH_R_W:
14293 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14294 break;
14295 }
14296 break;
14297 case OPC_ABSQ_S_PH_DSP:
14298 switch (op2) {
14299 case OPC_ABSQ_S_QB:
14300 check_dspr2(ctx);
14301 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14302 break;
14303 case OPC_ABSQ_S_PH:
14304 check_dsp(ctx);
14305 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14306 break;
14307 case OPC_ABSQ_S_W:
14308 check_dsp(ctx);
14309 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14310 break;
14311 case OPC_PRECEQ_W_PHL:
14312 check_dsp(ctx);
14313 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14314 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14315 break;
14316 case OPC_PRECEQ_W_PHR:
14317 check_dsp(ctx);
14318 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14319 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14320 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14321 break;
14322 case OPC_PRECEQU_PH_QBL:
14323 check_dsp(ctx);
14324 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14325 break;
14326 case OPC_PRECEQU_PH_QBR:
14327 check_dsp(ctx);
14328 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14329 break;
14330 case OPC_PRECEQU_PH_QBLA:
14331 check_dsp(ctx);
14332 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14333 break;
14334 case OPC_PRECEQU_PH_QBRA:
14335 check_dsp(ctx);
14336 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14337 break;
14338 case OPC_PRECEU_PH_QBL:
14339 check_dsp(ctx);
14340 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14341 break;
14342 case OPC_PRECEU_PH_QBR:
14343 check_dsp(ctx);
14344 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14345 break;
14346 case OPC_PRECEU_PH_QBLA:
14347 check_dsp(ctx);
14348 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14349 break;
14350 case OPC_PRECEU_PH_QBRA:
14351 check_dsp(ctx);
14352 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14353 break;
14354 }
14355 break;
14356 case OPC_ADDU_QB_DSP:
14357 switch (op2) {
14358 case OPC_ADDQ_PH:
14359 check_dsp(ctx);
14360 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14361 break;
14362 case OPC_ADDQ_S_PH:
14363 check_dsp(ctx);
14364 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14365 break;
14366 case OPC_ADDQ_S_W:
14367 check_dsp(ctx);
14368 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14369 break;
14370 case OPC_ADDU_QB:
14371 check_dsp(ctx);
14372 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14373 break;
14374 case OPC_ADDU_S_QB:
14375 check_dsp(ctx);
14376 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14377 break;
14378 case OPC_ADDU_PH:
14379 check_dspr2(ctx);
14380 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14381 break;
14382 case OPC_ADDU_S_PH:
14383 check_dspr2(ctx);
14384 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14385 break;
14386 case OPC_SUBQ_PH:
14387 check_dsp(ctx);
14388 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14389 break;
14390 case OPC_SUBQ_S_PH:
14391 check_dsp(ctx);
14392 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14393 break;
14394 case OPC_SUBQ_S_W:
14395 check_dsp(ctx);
14396 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14397 break;
14398 case OPC_SUBU_QB:
14399 check_dsp(ctx);
14400 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14401 break;
14402 case OPC_SUBU_S_QB:
14403 check_dsp(ctx);
14404 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14405 break;
14406 case OPC_SUBU_PH:
14407 check_dspr2(ctx);
14408 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14409 break;
14410 case OPC_SUBU_S_PH:
14411 check_dspr2(ctx);
14412 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14413 break;
14414 case OPC_ADDSC:
14415 check_dsp(ctx);
14416 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14417 break;
14418 case OPC_ADDWC:
14419 check_dsp(ctx);
14420 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14421 break;
14422 case OPC_MODSUB:
14423 check_dsp(ctx);
14424 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14425 break;
14426 case OPC_RADDU_W_QB:
14427 check_dsp(ctx);
14428 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14429 break;
14430 }
14431 break;
14432 case OPC_CMPU_EQ_QB_DSP:
14433 switch (op2) {
14434 case OPC_PRECR_QB_PH:
14435 check_dspr2(ctx);
14436 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14437 break;
14438 case OPC_PRECRQ_QB_PH:
14439 check_dsp(ctx);
14440 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14441 break;
14442 case OPC_PRECR_SRA_PH_W:
14443 check_dspr2(ctx);
14444 {
14445 TCGv_i32 sa_t = tcg_const_i32(v2);
14446 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14447 cpu_gpr[ret]);
14448 tcg_temp_free_i32(sa_t);
14449 break;
14450 }
14451 case OPC_PRECR_SRA_R_PH_W:
14452 check_dspr2(ctx);
14453 {
14454 TCGv_i32 sa_t = tcg_const_i32(v2);
14455 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14456 cpu_gpr[ret]);
14457 tcg_temp_free_i32(sa_t);
14458 break;
14459 }
14460 case OPC_PRECRQ_PH_W:
14461 check_dsp(ctx);
14462 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14463 break;
14464 case OPC_PRECRQ_RS_PH_W:
14465 check_dsp(ctx);
14466 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14467 break;
14468 case OPC_PRECRQU_S_QB_PH:
14469 check_dsp(ctx);
14470 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14471 break;
14472 }
14473 break;
14474#ifdef TARGET_MIPS64
14475 case OPC_ABSQ_S_QH_DSP:
14476 switch (op2) {
14477 case OPC_PRECEQ_L_PWL:
14478 check_dsp(ctx);
14479 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14480 break;
14481 case OPC_PRECEQ_L_PWR:
14482 check_dsp(ctx);
14483 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14484 break;
14485 case OPC_PRECEQ_PW_QHL:
14486 check_dsp(ctx);
14487 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14488 break;
14489 case OPC_PRECEQ_PW_QHR:
14490 check_dsp(ctx);
14491 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14492 break;
14493 case OPC_PRECEQ_PW_QHLA:
14494 check_dsp(ctx);
14495 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14496 break;
14497 case OPC_PRECEQ_PW_QHRA:
14498 check_dsp(ctx);
14499 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14500 break;
14501 case OPC_PRECEQU_QH_OBL:
14502 check_dsp(ctx);
14503 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14504 break;
14505 case OPC_PRECEQU_QH_OBR:
14506 check_dsp(ctx);
14507 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14508 break;
14509 case OPC_PRECEQU_QH_OBLA:
14510 check_dsp(ctx);
14511 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14512 break;
14513 case OPC_PRECEQU_QH_OBRA:
14514 check_dsp(ctx);
14515 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14516 break;
14517 case OPC_PRECEU_QH_OBL:
14518 check_dsp(ctx);
14519 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14520 break;
14521 case OPC_PRECEU_QH_OBR:
14522 check_dsp(ctx);
14523 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14524 break;
14525 case OPC_PRECEU_QH_OBLA:
14526 check_dsp(ctx);
14527 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14528 break;
14529 case OPC_PRECEU_QH_OBRA:
14530 check_dsp(ctx);
14531 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14532 break;
14533 case OPC_ABSQ_S_OB:
14534 check_dspr2(ctx);
14535 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14536 break;
14537 case OPC_ABSQ_S_PW:
14538 check_dsp(ctx);
14539 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14540 break;
14541 case OPC_ABSQ_S_QH:
14542 check_dsp(ctx);
14543 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14544 break;
14545 }
14546 break;
14547 case OPC_ADDU_OB_DSP:
14548 switch (op2) {
14549 case OPC_RADDU_L_OB:
14550 check_dsp(ctx);
14551 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14552 break;
14553 case OPC_SUBQ_PW:
14554 check_dsp(ctx);
14555 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14556 break;
14557 case OPC_SUBQ_S_PW:
14558 check_dsp(ctx);
14559 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14560 break;
14561 case OPC_SUBQ_QH:
14562 check_dsp(ctx);
14563 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14564 break;
14565 case OPC_SUBQ_S_QH:
14566 check_dsp(ctx);
14567 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14568 break;
14569 case OPC_SUBU_OB:
14570 check_dsp(ctx);
14571 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14572 break;
14573 case OPC_SUBU_S_OB:
14574 check_dsp(ctx);
14575 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14576 break;
14577 case OPC_SUBU_QH:
14578 check_dspr2(ctx);
14579 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14580 break;
14581 case OPC_SUBU_S_QH:
14582 check_dspr2(ctx);
14583 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14584 break;
14585 case OPC_SUBUH_OB:
14586 check_dspr2(ctx);
14587 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14588 break;
14589 case OPC_SUBUH_R_OB:
14590 check_dspr2(ctx);
14591 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14592 break;
14593 case OPC_ADDQ_PW:
14594 check_dsp(ctx);
14595 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14596 break;
14597 case OPC_ADDQ_S_PW:
14598 check_dsp(ctx);
14599 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14600 break;
14601 case OPC_ADDQ_QH:
14602 check_dsp(ctx);
14603 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14604 break;
14605 case OPC_ADDQ_S_QH:
14606 check_dsp(ctx);
14607 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14608 break;
14609 case OPC_ADDU_OB:
14610 check_dsp(ctx);
14611 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14612 break;
14613 case OPC_ADDU_S_OB:
14614 check_dsp(ctx);
14615 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14616 break;
14617 case OPC_ADDU_QH:
14618 check_dspr2(ctx);
14619 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14620 break;
14621 case OPC_ADDU_S_QH:
14622 check_dspr2(ctx);
14623 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14624 break;
14625 case OPC_ADDUH_OB:
14626 check_dspr2(ctx);
14627 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14628 break;
14629 case OPC_ADDUH_R_OB:
14630 check_dspr2(ctx);
14631 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14632 break;
14633 }
14634 break;
14635 case OPC_CMPU_EQ_OB_DSP:
14636 switch (op2) {
14637 case OPC_PRECR_OB_QH:
14638 check_dspr2(ctx);
14639 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14640 break;
14641 case OPC_PRECR_SRA_QH_PW:
14642 check_dspr2(ctx);
14643 {
14644 TCGv_i32 ret_t = tcg_const_i32(ret);
14645 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14646 tcg_temp_free_i32(ret_t);
14647 break;
14648 }
14649 case OPC_PRECR_SRA_R_QH_PW:
14650 check_dspr2(ctx);
14651 {
14652 TCGv_i32 sa_v = tcg_const_i32(ret);
14653 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14654 tcg_temp_free_i32(sa_v);
14655 break;
14656 }
14657 case OPC_PRECRQ_OB_QH:
14658 check_dsp(ctx);
14659 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14660 break;
14661 case OPC_PRECRQ_PW_L:
14662 check_dsp(ctx);
14663 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14664 break;
14665 case OPC_PRECRQ_QH_PW:
14666 check_dsp(ctx);
14667 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14668 break;
14669 case OPC_PRECRQ_RS_QH_PW:
14670 check_dsp(ctx);
14671 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14672 break;
14673 case OPC_PRECRQU_S_OB_QH:
14674 check_dsp(ctx);
14675 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14676 break;
14677 }
14678 break;
14679#endif
14680 }
14681
14682 tcg_temp_free(v1_t);
14683 tcg_temp_free(v2_t);
14684
14685 (void)opn; /* avoid a compiler warning */
14686 MIPS_DEBUG("%s", opn);
14687}
9b1a1d68 14688
77c5fa8b
JL
14689static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14690 int ret, int v1, int v2)
14691{
14692 uint32_t op2;
14693 const char *opn = "mipsdsp shift";
14694 TCGv t0;
14695 TCGv v1_t;
14696 TCGv v2_t;
14697
14698 if (ret == 0) {
14699 /* Treat as NOP. */
14700 MIPS_DEBUG("NOP");
14701 return;
14702 }
14703
14704 t0 = tcg_temp_new();
14705 v1_t = tcg_temp_new();
14706 v2_t = tcg_temp_new();
14707
14708 tcg_gen_movi_tl(t0, v1);
14709 gen_load_gpr(v1_t, v1);
14710 gen_load_gpr(v2_t, v2);
14711
14712 switch (opc) {
14713 case OPC_SHLL_QB_DSP:
14714 {
14715 op2 = MASK_SHLL_QB(ctx->opcode);
14716 switch (op2) {
14717 case OPC_SHLL_QB:
14718 check_dsp(ctx);
14719 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14720 break;
14721 case OPC_SHLLV_QB:
14722 check_dsp(ctx);
14723 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14724 break;
14725 case OPC_SHLL_PH:
14726 check_dsp(ctx);
14727 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14728 break;
14729 case OPC_SHLLV_PH:
14730 check_dsp(ctx);
14731 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14732 break;
14733 case OPC_SHLL_S_PH:
14734 check_dsp(ctx);
14735 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14736 break;
14737 case OPC_SHLLV_S_PH:
14738 check_dsp(ctx);
14739 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14740 break;
14741 case OPC_SHLL_S_W:
14742 check_dsp(ctx);
14743 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14744 break;
14745 case OPC_SHLLV_S_W:
14746 check_dsp(ctx);
14747 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14748 break;
14749 case OPC_SHRL_QB:
14750 check_dsp(ctx);
14751 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14752 break;
14753 case OPC_SHRLV_QB:
14754 check_dsp(ctx);
14755 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14756 break;
14757 case OPC_SHRL_PH:
14758 check_dspr2(ctx);
14759 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14760 break;
14761 case OPC_SHRLV_PH:
14762 check_dspr2(ctx);
14763 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14764 break;
14765 case OPC_SHRA_QB:
14766 check_dspr2(ctx);
14767 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14768 break;
14769 case OPC_SHRA_R_QB:
14770 check_dspr2(ctx);
14771 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14772 break;
14773 case OPC_SHRAV_QB:
14774 check_dspr2(ctx);
14775 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14776 break;
14777 case OPC_SHRAV_R_QB:
14778 check_dspr2(ctx);
14779 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14780 break;
14781 case OPC_SHRA_PH:
14782 check_dsp(ctx);
14783 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14784 break;
14785 case OPC_SHRA_R_PH:
14786 check_dsp(ctx);
14787 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14788 break;
14789 case OPC_SHRAV_PH:
14790 check_dsp(ctx);
14791 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14792 break;
14793 case OPC_SHRAV_R_PH:
14794 check_dsp(ctx);
14795 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14796 break;
14797 case OPC_SHRA_R_W:
14798 check_dsp(ctx);
14799 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14800 break;
14801 case OPC_SHRAV_R_W:
14802 check_dsp(ctx);
14803 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14804 break;
14805 default: /* Invalid */
14806 MIPS_INVAL("MASK SHLL.QB");
14807 generate_exception(ctx, EXCP_RI);
14808 break;
14809 }
14810 break;
14811 }
14812#ifdef TARGET_MIPS64
14813 case OPC_SHLL_OB_DSP:
14814 op2 = MASK_SHLL_OB(ctx->opcode);
14815 switch (op2) {
14816 case OPC_SHLL_PW:
14817 check_dsp(ctx);
14818 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14819 break;
14820 case OPC_SHLLV_PW:
14821 check_dsp(ctx);
14822 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14823 break;
14824 case OPC_SHLL_S_PW:
14825 check_dsp(ctx);
14826 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14827 break;
14828 case OPC_SHLLV_S_PW:
14829 check_dsp(ctx);
14830 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14831 break;
14832 case OPC_SHLL_OB:
14833 check_dsp(ctx);
14834 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14835 break;
14836 case OPC_SHLLV_OB:
14837 check_dsp(ctx);
14838 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14839 break;
14840 case OPC_SHLL_QH:
14841 check_dsp(ctx);
14842 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14843 break;
14844 case OPC_SHLLV_QH:
14845 check_dsp(ctx);
14846 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14847 break;
14848 case OPC_SHLL_S_QH:
14849 check_dsp(ctx);
14850 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14851 break;
14852 case OPC_SHLLV_S_QH:
14853 check_dsp(ctx);
14854 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14855 break;
14856 case OPC_SHRA_OB:
14857 check_dspr2(ctx);
14858 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14859 break;
14860 case OPC_SHRAV_OB:
14861 check_dspr2(ctx);
14862 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14863 break;
14864 case OPC_SHRA_R_OB:
14865 check_dspr2(ctx);
14866 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14867 break;
14868 case OPC_SHRAV_R_OB:
14869 check_dspr2(ctx);
14870 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14871 break;
14872 case OPC_SHRA_PW:
14873 check_dsp(ctx);
14874 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14875 break;
14876 case OPC_SHRAV_PW:
14877 check_dsp(ctx);
14878 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14879 break;
14880 case OPC_SHRA_R_PW:
14881 check_dsp(ctx);
14882 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14883 break;
14884 case OPC_SHRAV_R_PW:
14885 check_dsp(ctx);
14886 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14887 break;
14888 case OPC_SHRA_QH:
14889 check_dsp(ctx);
14890 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14891 break;
14892 case OPC_SHRAV_QH:
14893 check_dsp(ctx);
14894 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14895 break;
14896 case OPC_SHRA_R_QH:
14897 check_dsp(ctx);
14898 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14899 break;
14900 case OPC_SHRAV_R_QH:
14901 check_dsp(ctx);
14902 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14903 break;
14904 case OPC_SHRL_OB:
14905 check_dsp(ctx);
14906 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14907 break;
14908 case OPC_SHRLV_OB:
14909 check_dsp(ctx);
14910 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14911 break;
14912 case OPC_SHRL_QH:
14913 check_dspr2(ctx);
14914 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14915 break;
14916 case OPC_SHRLV_QH:
14917 check_dspr2(ctx);
14918 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14919 break;
14920 default: /* Invalid */
14921 MIPS_INVAL("MASK SHLL.OB");
14922 generate_exception(ctx, EXCP_RI);
14923 break;
14924 }
14925 break;
14926#endif
14927 }
14928
14929 tcg_temp_free(t0);
14930 tcg_temp_free(v1_t);
14931 tcg_temp_free(v2_t);
14932 (void)opn; /* avoid a compiler warning */
14933 MIPS_DEBUG("%s", opn);
14934}
14935
a22260ae
JL
14936static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14937 int ret, int v1, int v2, int check_ret)
14938{
14939 const char *opn = "mipsdsp multiply";
14940 TCGv_i32 t0;
14941 TCGv v1_t;
14942 TCGv v2_t;
14943
14944 if ((ret == 0) && (check_ret == 1)) {
14945 /* Treat as NOP. */
14946 MIPS_DEBUG("NOP");
14947 return;
14948 }
14949
14950 t0 = tcg_temp_new_i32();
14951 v1_t = tcg_temp_new();
14952 v2_t = tcg_temp_new();
14953
14954 tcg_gen_movi_i32(t0, ret);
14955 gen_load_gpr(v1_t, v1);
14956 gen_load_gpr(v2_t, v2);
14957
14958 switch (op1) {
14959 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14960 * the same mask and op1. */
14961 case OPC_MULT_G_2E:
639eadb9 14962 check_dspr2(ctx);
a22260ae
JL
14963 switch (op2) {
14964 case OPC_MUL_PH:
14965 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14966 break;
14967 case OPC_MUL_S_PH:
14968 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14969 break;
14970 case OPC_MULQ_S_W:
14971 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14972 break;
14973 case OPC_MULQ_RS_W:
14974 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14975 break;
14976 }
14977 break;
14978 case OPC_DPA_W_PH_DSP:
14979 switch (op2) {
14980 case OPC_DPAU_H_QBL:
14981 check_dsp(ctx);
14982 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14983 break;
14984 case OPC_DPAU_H_QBR:
14985 check_dsp(ctx);
14986 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14987 break;
14988 case OPC_DPSU_H_QBL:
14989 check_dsp(ctx);
14990 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14991 break;
14992 case OPC_DPSU_H_QBR:
14993 check_dsp(ctx);
14994 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14995 break;
14996 case OPC_DPA_W_PH:
14997 check_dspr2(ctx);
14998 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14999 break;
15000 case OPC_DPAX_W_PH:
15001 check_dspr2(ctx);
15002 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15003 break;
15004 case OPC_DPAQ_S_W_PH:
15005 check_dsp(ctx);
15006 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15007 break;
15008 case OPC_DPAQX_S_W_PH:
15009 check_dspr2(ctx);
15010 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15011 break;
15012 case OPC_DPAQX_SA_W_PH:
15013 check_dspr2(ctx);
15014 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15015 break;
15016 case OPC_DPS_W_PH:
15017 check_dspr2(ctx);
15018 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15019 break;
15020 case OPC_DPSX_W_PH:
15021 check_dspr2(ctx);
15022 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15023 break;
15024 case OPC_DPSQ_S_W_PH:
15025 check_dsp(ctx);
15026 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15027 break;
15028 case OPC_DPSQX_S_W_PH:
15029 check_dspr2(ctx);
15030 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15031 break;
15032 case OPC_DPSQX_SA_W_PH:
15033 check_dspr2(ctx);
15034 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15035 break;
15036 case OPC_MULSAQ_S_W_PH:
15037 check_dsp(ctx);
15038 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15039 break;
15040 case OPC_DPAQ_SA_L_W:
15041 check_dsp(ctx);
15042 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15043 break;
15044 case OPC_DPSQ_SA_L_W:
15045 check_dsp(ctx);
15046 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15047 break;
15048 case OPC_MAQ_S_W_PHL:
15049 check_dsp(ctx);
15050 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15051 break;
15052 case OPC_MAQ_S_W_PHR:
15053 check_dsp(ctx);
15054 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15055 break;
15056 case OPC_MAQ_SA_W_PHL:
15057 check_dsp(ctx);
15058 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15059 break;
15060 case OPC_MAQ_SA_W_PHR:
15061 check_dsp(ctx);
15062 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15063 break;
15064 case OPC_MULSA_W_PH:
15065 check_dspr2(ctx);
15066 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15067 break;
15068 }
15069 break;
15070#ifdef TARGET_MIPS64
15071 case OPC_DPAQ_W_QH_DSP:
15072 {
15073 int ac = ret & 0x03;
15074 tcg_gen_movi_i32(t0, ac);
15075
15076 switch (op2) {
15077 case OPC_DMADD:
15078 check_dsp(ctx);
15079 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15080 break;
15081 case OPC_DMADDU:
15082 check_dsp(ctx);
15083 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15084 break;
15085 case OPC_DMSUB:
15086 check_dsp(ctx);
15087 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15088 break;
15089 case OPC_DMSUBU:
15090 check_dsp(ctx);
15091 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15092 break;
15093 case OPC_DPA_W_QH:
15094 check_dspr2(ctx);
15095 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15096 break;
15097 case OPC_DPAQ_S_W_QH:
15098 check_dsp(ctx);
15099 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15100 break;
15101 case OPC_DPAQ_SA_L_PW:
15102 check_dsp(ctx);
15103 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15104 break;
15105 case OPC_DPAU_H_OBL:
15106 check_dsp(ctx);
15107 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15108 break;
15109 case OPC_DPAU_H_OBR:
15110 check_dsp(ctx);
15111 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15112 break;
15113 case OPC_DPS_W_QH:
15114 check_dspr2(ctx);
15115 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15116 break;
15117 case OPC_DPSQ_S_W_QH:
15118 check_dsp(ctx);
15119 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15120 break;
15121 case OPC_DPSQ_SA_L_PW:
15122 check_dsp(ctx);
15123 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15124 break;
15125 case OPC_DPSU_H_OBL:
15126 check_dsp(ctx);
15127 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15128 break;
15129 case OPC_DPSU_H_OBR:
15130 check_dsp(ctx);
15131 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15132 break;
15133 case OPC_MAQ_S_L_PWL:
15134 check_dsp(ctx);
15135 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15136 break;
15137 case OPC_MAQ_S_L_PWR:
15138 check_dsp(ctx);
15139 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15140 break;
15141 case OPC_MAQ_S_W_QHLL:
15142 check_dsp(ctx);
15143 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15144 break;
15145 case OPC_MAQ_SA_W_QHLL:
15146 check_dsp(ctx);
15147 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15148 break;
15149 case OPC_MAQ_S_W_QHLR:
15150 check_dsp(ctx);
15151 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15152 break;
15153 case OPC_MAQ_SA_W_QHLR:
15154 check_dsp(ctx);
15155 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15156 break;
15157 case OPC_MAQ_S_W_QHRL:
15158 check_dsp(ctx);
15159 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15160 break;
15161 case OPC_MAQ_SA_W_QHRL:
15162 check_dsp(ctx);
15163 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15164 break;
15165 case OPC_MAQ_S_W_QHRR:
15166 check_dsp(ctx);
15167 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15168 break;
15169 case OPC_MAQ_SA_W_QHRR:
15170 check_dsp(ctx);
15171 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15172 break;
15173 case OPC_MULSAQ_S_L_PW:
15174 check_dsp(ctx);
15175 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15176 break;
15177 case OPC_MULSAQ_S_W_QH:
15178 check_dsp(ctx);
15179 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15180 break;
15181 }
15182 }
15183 break;
15184#endif
15185 case OPC_ADDU_QB_DSP:
15186 switch (op2) {
15187 case OPC_MULEU_S_PH_QBL:
15188 check_dsp(ctx);
15189 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15190 break;
15191 case OPC_MULEU_S_PH_QBR:
15192 check_dsp(ctx);
15193 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15194 break;
15195 case OPC_MULQ_RS_PH:
15196 check_dsp(ctx);
15197 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15198 break;
15199 case OPC_MULEQ_S_W_PHL:
15200 check_dsp(ctx);
15201 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15202 break;
15203 case OPC_MULEQ_S_W_PHR:
15204 check_dsp(ctx);
15205 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15206 break;
15207 case OPC_MULQ_S_PH:
15208 check_dspr2(ctx);
15209 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15210 break;
15211 }
15212 break;
15213#ifdef TARGET_MIPS64
15214 case OPC_ADDU_OB_DSP:
15215 switch (op2) {
15216 case OPC_MULEQ_S_PW_QHL:
15217 check_dsp(ctx);
15218 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15219 break;
15220 case OPC_MULEQ_S_PW_QHR:
15221 check_dsp(ctx);
15222 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15223 break;
15224 case OPC_MULEU_S_QH_OBL:
15225 check_dsp(ctx);
15226 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15227 break;
15228 case OPC_MULEU_S_QH_OBR:
15229 check_dsp(ctx);
15230 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15231 break;
15232 case OPC_MULQ_RS_QH:
15233 check_dsp(ctx);
15234 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15235 break;
15236 }
15237 break;
15238#endif
15239 }
15240
15241 tcg_temp_free_i32(t0);
15242 tcg_temp_free(v1_t);
15243 tcg_temp_free(v2_t);
15244
15245 (void)opn; /* avoid a compiler warning */
15246 MIPS_DEBUG("%s", opn);
15247
15248}
15249
d75c135e 15250static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15251 int ret, int val)
15252{
15253 const char *opn = "mipsdsp Bit/ Manipulation";
15254 int16_t imm;
15255 TCGv t0;
15256 TCGv val_t;
15257
15258 if (ret == 0) {
15259 /* Treat as NOP. */
15260 MIPS_DEBUG("NOP");
15261 return;
15262 }
15263
15264 t0 = tcg_temp_new();
15265 val_t = tcg_temp_new();
15266 gen_load_gpr(val_t, val);
15267
15268 switch (op1) {
15269 case OPC_ABSQ_S_PH_DSP:
15270 switch (op2) {
15271 case OPC_BITREV:
15272 check_dsp(ctx);
15273 gen_helper_bitrev(cpu_gpr[ret], val_t);
15274 break;
15275 case OPC_REPL_QB:
15276 check_dsp(ctx);
15277 {
15278 target_long result;
15279 imm = (ctx->opcode >> 16) & 0xFF;
15280 result = (uint32_t)imm << 24 |
15281 (uint32_t)imm << 16 |
15282 (uint32_t)imm << 8 |
15283 (uint32_t)imm;
15284 result = (int32_t)result;
15285 tcg_gen_movi_tl(cpu_gpr[ret], result);
15286 }
15287 break;
15288 case OPC_REPLV_QB:
15289 check_dsp(ctx);
15290 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15291 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15292 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15293 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15294 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15295 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15296 break;
15297 case OPC_REPL_PH:
15298 check_dsp(ctx);
15299 {
15300 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15301 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15302 tcg_gen_movi_tl(cpu_gpr[ret], \
15303 (target_long)((int32_t)imm << 16 | \
c4aaba92 15304 (uint16_t)imm));
1cb6686c
JL
15305 }
15306 break;
15307 case OPC_REPLV_PH:
15308 check_dsp(ctx);
15309 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15310 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15311 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15312 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15313 break;
15314 }
15315 break;
15316#ifdef TARGET_MIPS64
15317 case OPC_ABSQ_S_QH_DSP:
15318 switch (op2) {
15319 case OPC_REPL_OB:
15320 check_dsp(ctx);
15321 {
15322 target_long temp;
15323
15324 imm = (ctx->opcode >> 16) & 0xFF;
15325 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15326 temp = (temp << 16) | temp;
15327 temp = (temp << 32) | temp;
15328 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15329 break;
15330 }
15331 case OPC_REPL_PW:
15332 check_dsp(ctx);
15333 {
15334 target_long temp;
15335
15336 imm = (ctx->opcode >> 16) & 0x03FF;
15337 imm = (int16_t)(imm << 6) >> 6;
15338 temp = ((target_long)imm << 32) \
15339 | ((target_long)imm & 0xFFFFFFFF);
15340 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15341 break;
15342 }
15343 case OPC_REPL_QH:
15344 check_dsp(ctx);
15345 {
15346 target_long temp;
15347
15348 imm = (ctx->opcode >> 16) & 0x03FF;
15349 imm = (int16_t)(imm << 6) >> 6;
15350
15351 temp = ((uint64_t)(uint16_t)imm << 48) |
15352 ((uint64_t)(uint16_t)imm << 32) |
15353 ((uint64_t)(uint16_t)imm << 16) |
15354 (uint64_t)(uint16_t)imm;
15355 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15356 break;
15357 }
15358 case OPC_REPLV_OB:
15359 check_dsp(ctx);
15360 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15361 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15362 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15363 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15364 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15365 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15366 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15367 break;
15368 case OPC_REPLV_PW:
15369 check_dsp(ctx);
15370 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15371 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15372 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15373 break;
15374 case OPC_REPLV_QH:
15375 check_dsp(ctx);
15376 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15377 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15378 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15379 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15380 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15381 break;
15382 }
15383 break;
15384#endif
15385 }
15386 tcg_temp_free(t0);
15387 tcg_temp_free(val_t);
15388
15389 (void)opn; /* avoid a compiler warning */
15390 MIPS_DEBUG("%s", opn);
15391}
15392
26690560
JL
15393static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15394 uint32_t op1, uint32_t op2,
15395 int ret, int v1, int v2, int check_ret)
15396{
15397 const char *opn = "mipsdsp add compare pick";
26690560
JL
15398 TCGv t1;
15399 TCGv v1_t;
15400 TCGv v2_t;
15401
15402 if ((ret == 0) && (check_ret == 1)) {
15403 /* Treat as NOP. */
15404 MIPS_DEBUG("NOP");
15405 return;
15406 }
15407
26690560
JL
15408 t1 = tcg_temp_new();
15409 v1_t = tcg_temp_new();
15410 v2_t = tcg_temp_new();
15411
15412 gen_load_gpr(v1_t, v1);
15413 gen_load_gpr(v2_t, v2);
15414
15415 switch (op1) {
26690560
JL
15416 case OPC_CMPU_EQ_QB_DSP:
15417 switch (op2) {
15418 case OPC_CMPU_EQ_QB:
15419 check_dsp(ctx);
15420 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15421 break;
15422 case OPC_CMPU_LT_QB:
15423 check_dsp(ctx);
15424 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15425 break;
15426 case OPC_CMPU_LE_QB:
15427 check_dsp(ctx);
15428 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15429 break;
15430 case OPC_CMPGU_EQ_QB:
15431 check_dsp(ctx);
15432 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15433 break;
15434 case OPC_CMPGU_LT_QB:
15435 check_dsp(ctx);
15436 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15437 break;
15438 case OPC_CMPGU_LE_QB:
15439 check_dsp(ctx);
15440 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15441 break;
15442 case OPC_CMPGDU_EQ_QB:
15443 check_dspr2(ctx);
15444 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15445 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15446 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15447 tcg_gen_shli_tl(t1, t1, 24);
15448 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15449 break;
15450 case OPC_CMPGDU_LT_QB:
15451 check_dspr2(ctx);
15452 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15453 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15454 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15455 tcg_gen_shli_tl(t1, t1, 24);
15456 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15457 break;
15458 case OPC_CMPGDU_LE_QB:
15459 check_dspr2(ctx);
15460 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15461 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15462 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15463 tcg_gen_shli_tl(t1, t1, 24);
15464 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15465 break;
15466 case OPC_CMP_EQ_PH:
15467 check_dsp(ctx);
15468 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15469 break;
15470 case OPC_CMP_LT_PH:
15471 check_dsp(ctx);
15472 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15473 break;
15474 case OPC_CMP_LE_PH:
15475 check_dsp(ctx);
15476 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15477 break;
15478 case OPC_PICK_QB:
15479 check_dsp(ctx);
15480 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15481 break;
15482 case OPC_PICK_PH:
15483 check_dsp(ctx);
15484 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15485 break;
15486 case OPC_PACKRL_PH:
15487 check_dsp(ctx);
15488 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15489 break;
15490 }
15491 break;
15492#ifdef TARGET_MIPS64
15493 case OPC_CMPU_EQ_OB_DSP:
15494 switch (op2) {
15495 case OPC_CMP_EQ_PW:
15496 check_dsp(ctx);
15497 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15498 break;
15499 case OPC_CMP_LT_PW:
15500 check_dsp(ctx);
15501 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15502 break;
15503 case OPC_CMP_LE_PW:
15504 check_dsp(ctx);
15505 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15506 break;
15507 case OPC_CMP_EQ_QH:
15508 check_dsp(ctx);
15509 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15510 break;
15511 case OPC_CMP_LT_QH:
15512 check_dsp(ctx);
15513 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15514 break;
15515 case OPC_CMP_LE_QH:
15516 check_dsp(ctx);
15517 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15518 break;
15519 case OPC_CMPGDU_EQ_OB:
15520 check_dspr2(ctx);
15521 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15522 break;
15523 case OPC_CMPGDU_LT_OB:
15524 check_dspr2(ctx);
15525 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15526 break;
15527 case OPC_CMPGDU_LE_OB:
15528 check_dspr2(ctx);
15529 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15530 break;
15531 case OPC_CMPGU_EQ_OB:
15532 check_dsp(ctx);
15533 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15534 break;
15535 case OPC_CMPGU_LT_OB:
15536 check_dsp(ctx);
15537 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15538 break;
15539 case OPC_CMPGU_LE_OB:
15540 check_dsp(ctx);
15541 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15542 break;
15543 case OPC_CMPU_EQ_OB:
15544 check_dsp(ctx);
15545 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15546 break;
15547 case OPC_CMPU_LT_OB:
15548 check_dsp(ctx);
15549 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15550 break;
15551 case OPC_CMPU_LE_OB:
15552 check_dsp(ctx);
15553 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15554 break;
15555 case OPC_PACKRL_PW:
15556 check_dsp(ctx);
15557 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15558 break;
15559 case OPC_PICK_OB:
15560 check_dsp(ctx);
15561 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15562 break;
15563 case OPC_PICK_PW:
15564 check_dsp(ctx);
15565 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15566 break;
15567 case OPC_PICK_QH:
15568 check_dsp(ctx);
15569 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15570 break;
15571 }
15572 break;
df6126a7
AJ
15573#endif
15574 }
15575
15576 tcg_temp_free(t1);
15577 tcg_temp_free(v1_t);
15578 tcg_temp_free(v2_t);
15579
15580 (void)opn; /* avoid a compiler warning */
15581 MIPS_DEBUG("%s", opn);
15582}
15583
15584static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15585 uint32_t op1, int rt, int rs, int sa)
15586{
15587 const char *opn = "mipsdsp append/dappend";
15588 TCGv t0;
15589
15590 check_dspr2(ctx);
15591
15592 if (rt == 0) {
15593 /* Treat as NOP. */
15594 MIPS_DEBUG("NOP");
15595 return;
15596 }
15597
15598 t0 = tcg_temp_new();
15599 gen_load_gpr(t0, rs);
15600
15601 switch (op1) {
15602 case OPC_APPEND_DSP:
15603 switch (MASK_APPEND(ctx->opcode)) {
15604 case OPC_APPEND:
15605 if (sa != 0) {
15606 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15607 }
15608 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15609 break;
15610 case OPC_PREPEND:
15611 if (sa != 0) {
15612 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15613 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15614 tcg_gen_shli_tl(t0, t0, 32 - sa);
15615 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15616 }
15617 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15618 break;
15619 case OPC_BALIGN:
15620 sa &= 3;
15621 if (sa != 0 && sa != 2) {
15622 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15623 tcg_gen_ext32u_tl(t0, t0);
15624 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15625 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15626 }
15627 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15628 break;
15629 default: /* Invalid */
15630 MIPS_INVAL("MASK APPEND");
15631 generate_exception(ctx, EXCP_RI);
15632 break;
15633 }
15634 break;
15635#ifdef TARGET_MIPS64
26690560 15636 case OPC_DAPPEND_DSP:
df6126a7 15637 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15638 case OPC_DAPPEND:
df6126a7
AJ
15639 if (sa != 0) {
15640 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15641 }
26690560
JL
15642 break;
15643 case OPC_PREPENDD:
df6126a7
AJ
15644 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15645 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15646 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15647 break;
15648 case OPC_PREPENDW:
df6126a7
AJ
15649 if (sa != 0) {
15650 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15651 tcg_gen_shli_tl(t0, t0, 64 - sa);
15652 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15653 }
26690560
JL
15654 break;
15655 case OPC_DBALIGN:
df6126a7
AJ
15656 sa &= 7;
15657 if (sa != 0 && sa != 2 && sa != 4) {
15658 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15659 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15660 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15661 }
26690560
JL
15662 break;
15663 default: /* Invalid */
15664 MIPS_INVAL("MASK DAPPEND");
15665 generate_exception(ctx, EXCP_RI);
15666 break;
15667 }
15668 break;
15669#endif
15670 }
df6126a7 15671 tcg_temp_free(t0);
26690560
JL
15672 (void)opn; /* avoid a compiler warning */
15673 MIPS_DEBUG("%s", opn);
15674}
15675
b53371ed
JL
15676static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15677 int ret, int v1, int v2, int check_ret)
15678
15679{
15680 const char *opn = "mipsdsp accumulator";
15681 TCGv t0;
15682 TCGv t1;
15683 TCGv v1_t;
15684 TCGv v2_t;
15685 int16_t imm;
15686
15687 if ((ret == 0) && (check_ret == 1)) {
15688 /* Treat as NOP. */
15689 MIPS_DEBUG("NOP");
15690 return;
15691 }
15692
15693 t0 = tcg_temp_new();
15694 t1 = tcg_temp_new();
15695 v1_t = tcg_temp_new();
15696 v2_t = tcg_temp_new();
15697
15698 gen_load_gpr(v1_t, v1);
15699 gen_load_gpr(v2_t, v2);
15700
15701 switch (op1) {
15702 case OPC_EXTR_W_DSP:
15703 check_dsp(ctx);
15704 switch (op2) {
15705 case OPC_EXTR_W:
15706 tcg_gen_movi_tl(t0, v2);
15707 tcg_gen_movi_tl(t1, v1);
15708 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15709 break;
15710 case OPC_EXTR_R_W:
15711 tcg_gen_movi_tl(t0, v2);
15712 tcg_gen_movi_tl(t1, v1);
15713 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15714 break;
15715 case OPC_EXTR_RS_W:
15716 tcg_gen_movi_tl(t0, v2);
15717 tcg_gen_movi_tl(t1, v1);
15718 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15719 break;
15720 case OPC_EXTR_S_H:
15721 tcg_gen_movi_tl(t0, v2);
15722 tcg_gen_movi_tl(t1, v1);
15723 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15724 break;
15725 case OPC_EXTRV_S_H:
15726 tcg_gen_movi_tl(t0, v2);
15727 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15728 break;
15729 case OPC_EXTRV_W:
15730 tcg_gen_movi_tl(t0, v2);
15731 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15732 break;
15733 case OPC_EXTRV_R_W:
15734 tcg_gen_movi_tl(t0, v2);
15735 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15736 break;
15737 case OPC_EXTRV_RS_W:
15738 tcg_gen_movi_tl(t0, v2);
15739 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15740 break;
15741 case OPC_EXTP:
15742 tcg_gen_movi_tl(t0, v2);
15743 tcg_gen_movi_tl(t1, v1);
15744 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15745 break;
15746 case OPC_EXTPV:
15747 tcg_gen_movi_tl(t0, v2);
15748 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15749 break;
15750 case OPC_EXTPDP:
15751 tcg_gen_movi_tl(t0, v2);
15752 tcg_gen_movi_tl(t1, v1);
15753 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15754 break;
15755 case OPC_EXTPDPV:
15756 tcg_gen_movi_tl(t0, v2);
15757 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15758 break;
15759 case OPC_SHILO:
15760 imm = (ctx->opcode >> 20) & 0x3F;
15761 tcg_gen_movi_tl(t0, ret);
15762 tcg_gen_movi_tl(t1, imm);
15763 gen_helper_shilo(t0, t1, cpu_env);
15764 break;
15765 case OPC_SHILOV:
15766 tcg_gen_movi_tl(t0, ret);
15767 gen_helper_shilo(t0, v1_t, cpu_env);
15768 break;
15769 case OPC_MTHLIP:
15770 tcg_gen_movi_tl(t0, ret);
15771 gen_helper_mthlip(t0, v1_t, cpu_env);
15772 break;
15773 case OPC_WRDSP:
15774 imm = (ctx->opcode >> 11) & 0x3FF;
15775 tcg_gen_movi_tl(t0, imm);
15776 gen_helper_wrdsp(v1_t, t0, cpu_env);
15777 break;
15778 case OPC_RDDSP:
15779 imm = (ctx->opcode >> 16) & 0x03FF;
15780 tcg_gen_movi_tl(t0, imm);
15781 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15782 break;
15783 }
15784 break;
15785#ifdef TARGET_MIPS64
15786 case OPC_DEXTR_W_DSP:
15787 check_dsp(ctx);
15788 switch (op2) {
15789 case OPC_DMTHLIP:
15790 tcg_gen_movi_tl(t0, ret);
15791 gen_helper_dmthlip(v1_t, t0, cpu_env);
15792 break;
15793 case OPC_DSHILO:
15794 {
15795 int shift = (ctx->opcode >> 19) & 0x7F;
15796 int ac = (ctx->opcode >> 11) & 0x03;
15797 tcg_gen_movi_tl(t0, shift);
15798 tcg_gen_movi_tl(t1, ac);
15799 gen_helper_dshilo(t0, t1, cpu_env);
15800 break;
15801 }
15802 case OPC_DSHILOV:
15803 {
15804 int ac = (ctx->opcode >> 11) & 0x03;
15805 tcg_gen_movi_tl(t0, ac);
15806 gen_helper_dshilo(v1_t, t0, cpu_env);
15807 break;
15808 }
15809 case OPC_DEXTP:
15810 tcg_gen_movi_tl(t0, v2);
15811 tcg_gen_movi_tl(t1, v1);
15812
15813 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15814 break;
15815 case OPC_DEXTPV:
15816 tcg_gen_movi_tl(t0, v2);
15817 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15818 break;
15819 case OPC_DEXTPDP:
15820 tcg_gen_movi_tl(t0, v2);
15821 tcg_gen_movi_tl(t1, v1);
15822 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15823 break;
15824 case OPC_DEXTPDPV:
15825 tcg_gen_movi_tl(t0, v2);
15826 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15827 break;
15828 case OPC_DEXTR_L:
15829 tcg_gen_movi_tl(t0, v2);
15830 tcg_gen_movi_tl(t1, v1);
15831 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15832 break;
15833 case OPC_DEXTR_R_L:
15834 tcg_gen_movi_tl(t0, v2);
15835 tcg_gen_movi_tl(t1, v1);
15836 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15837 break;
15838 case OPC_DEXTR_RS_L:
15839 tcg_gen_movi_tl(t0, v2);
15840 tcg_gen_movi_tl(t1, v1);
15841 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15842 break;
15843 case OPC_DEXTR_W:
15844 tcg_gen_movi_tl(t0, v2);
15845 tcg_gen_movi_tl(t1, v1);
15846 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15847 break;
15848 case OPC_DEXTR_R_W:
15849 tcg_gen_movi_tl(t0, v2);
15850 tcg_gen_movi_tl(t1, v1);
15851 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15852 break;
15853 case OPC_DEXTR_RS_W:
15854 tcg_gen_movi_tl(t0, v2);
15855 tcg_gen_movi_tl(t1, v1);
15856 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15857 break;
15858 case OPC_DEXTR_S_H:
15859 tcg_gen_movi_tl(t0, v2);
15860 tcg_gen_movi_tl(t1, v1);
15861 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15862 break;
15863 case OPC_DEXTRV_S_H:
15864 tcg_gen_movi_tl(t0, v2);
15865 tcg_gen_movi_tl(t1, v1);
15866 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15867 break;
15868 case OPC_DEXTRV_L:
15869 tcg_gen_movi_tl(t0, v2);
15870 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15871 break;
15872 case OPC_DEXTRV_R_L:
15873 tcg_gen_movi_tl(t0, v2);
15874 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15875 break;
15876 case OPC_DEXTRV_RS_L:
15877 tcg_gen_movi_tl(t0, v2);
15878 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15879 break;
15880 case OPC_DEXTRV_W:
15881 tcg_gen_movi_tl(t0, v2);
15882 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15883 break;
15884 case OPC_DEXTRV_R_W:
15885 tcg_gen_movi_tl(t0, v2);
15886 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15887 break;
15888 case OPC_DEXTRV_RS_W:
15889 tcg_gen_movi_tl(t0, v2);
15890 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15891 break;
15892 }
15893 break;
15894#endif
15895 }
15896
15897 tcg_temp_free(t0);
15898 tcg_temp_free(t1);
15899 tcg_temp_free(v1_t);
15900 tcg_temp_free(v2_t);
15901
15902 (void)opn; /* avoid a compiler warning */
15903 MIPS_DEBUG("%s", opn);
15904}
15905
9b1a1d68
JL
15906/* End MIPSDSP functions. */
15907
31837be3
YK
15908/* Compact Branches */
15909static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15910 int rs, int rt, int32_t offset)
15911{
15912 int bcond_compute = 0;
15913 TCGv t0 = tcg_temp_new();
15914 TCGv t1 = tcg_temp_new();
15915
15916 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15917#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15918 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15919 "\n", ctx->pc);
31837be3
YK
15920#endif
15921 generate_exception(ctx, EXCP_RI);
15922 goto out;
15923 }
15924
15925 /* Load needed operands and calculate btarget */
15926 switch (opc) {
15927 /* compact branch */
15928 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15929 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15930 gen_load_gpr(t0, rs);
15931 gen_load_gpr(t1, rt);
15932 bcond_compute = 1;
15933 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15934 if (rs <= rt && rs == 0) {
15935 /* OPC_BEQZALC, OPC_BNEZALC */
15936 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15937 }
15938 break;
15939 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15940 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15941 gen_load_gpr(t0, rs);
15942 gen_load_gpr(t1, rt);
15943 bcond_compute = 1;
15944 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15945 break;
15946 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15947 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15948 if (rs == 0 || rs == rt) {
15949 /* OPC_BLEZALC, OPC_BGEZALC */
15950 /* OPC_BGTZALC, OPC_BLTZALC */
15951 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15952 }
15953 gen_load_gpr(t0, rs);
15954 gen_load_gpr(t1, rt);
15955 bcond_compute = 1;
15956 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15957 break;
15958 case OPC_BC:
15959 case OPC_BALC:
15960 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15961 break;
15962 case OPC_BEQZC:
15963 case OPC_BNEZC:
15964 if (rs != 0) {
15965 /* OPC_BEQZC, OPC_BNEZC */
15966 gen_load_gpr(t0, rs);
15967 bcond_compute = 1;
15968 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15969 } else {
15970 /* OPC_JIC, OPC_JIALC */
15971 TCGv tbase = tcg_temp_new();
15972 TCGv toffset = tcg_temp_new();
15973
15974 gen_load_gpr(tbase, rt);
15975 tcg_gen_movi_tl(toffset, offset);
15976 gen_op_addr_add(ctx, btarget, tbase, toffset);
15977 tcg_temp_free(tbase);
15978 tcg_temp_free(toffset);
15979 }
15980 break;
15981 default:
15982 MIPS_INVAL("Compact branch/jump");
15983 generate_exception(ctx, EXCP_RI);
15984 goto out;
15985 }
15986
15987 if (bcond_compute == 0) {
15988 /* Uncoditional compact branch */
15989 switch (opc) {
15990 case OPC_JIALC:
15991 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15992 /* Fallthrough */
15993 case OPC_JIC:
15994 ctx->hflags |= MIPS_HFLAG_BR;
15995 break;
15996 case OPC_BALC:
15997 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15998 /* Fallthrough */
15999 case OPC_BC:
16000 ctx->hflags |= MIPS_HFLAG_B;
16001 break;
16002 default:
16003 MIPS_INVAL("Compact branch/jump");
16004 generate_exception(ctx, EXCP_RI);
16005 goto out;
16006 }
16007
16008 /* Generating branch here as compact branches don't have delay slot */
16009 gen_branch(ctx, 4);
16010 } else {
16011 /* Conditional compact branch */
42a268c2 16012 TCGLabel *fs = gen_new_label();
31837be3
YK
16013 save_cpu_state(ctx, 0);
16014
16015 switch (opc) {
16016 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
16017 if (rs == 0 && rt != 0) {
16018 /* OPC_BLEZALC */
339cd2a8 16019 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16020 } else if (rs != 0 && rt != 0 && rs == rt) {
16021 /* OPC_BGEZALC */
339cd2a8 16022 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16023 } else {
16024 /* OPC_BGEUC */
339cd2a8 16025 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
16026 }
16027 break;
16028 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16029 if (rs == 0 && rt != 0) {
16030 /* OPC_BGTZALC */
339cd2a8 16031 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16032 } else if (rs != 0 && rt != 0 && rs == rt) {
16033 /* OPC_BLTZALC */
339cd2a8 16034 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16035 } else {
16036 /* OPC_BLTUC */
339cd2a8 16037 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
16038 }
16039 break;
16040 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16041 if (rs == 0 && rt != 0) {
16042 /* OPC_BLEZC */
339cd2a8 16043 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16044 } else if (rs != 0 && rt != 0 && rs == rt) {
16045 /* OPC_BGEZC */
339cd2a8 16046 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16047 } else {
16048 /* OPC_BGEC */
339cd2a8 16049 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
16050 }
16051 break;
16052 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16053 if (rs == 0 && rt != 0) {
16054 /* OPC_BGTZC */
339cd2a8 16055 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16056 } else if (rs != 0 && rt != 0 && rs == rt) {
16057 /* OPC_BLTZC */
339cd2a8 16058 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16059 } else {
16060 /* OPC_BLTC */
339cd2a8 16061 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
16062 }
16063 break;
16064 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16065 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16066 if (rs >= rt) {
16067 /* OPC_BOVC, OPC_BNVC */
16068 TCGv t2 = tcg_temp_new();
16069 TCGv t3 = tcg_temp_new();
16070 TCGv t4 = tcg_temp_new();
16071 TCGv input_overflow = tcg_temp_new();
16072
16073 gen_load_gpr(t0, rs);
16074 gen_load_gpr(t1, rt);
16075 tcg_gen_ext32s_tl(t2, t0);
16076 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
16077 tcg_gen_ext32s_tl(t3, t1);
16078 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
16079 tcg_gen_or_tl(input_overflow, input_overflow, t4);
16080
16081 tcg_gen_add_tl(t4, t2, t3);
16082 tcg_gen_ext32s_tl(t4, t4);
16083 tcg_gen_xor_tl(t2, t2, t3);
16084 tcg_gen_xor_tl(t3, t4, t3);
16085 tcg_gen_andc_tl(t2, t3, t2);
16086 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
16087 tcg_gen_or_tl(t4, t4, input_overflow);
16088 if (opc == OPC_BOVC) {
16089 /* OPC_BOVC */
339cd2a8 16090 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
16091 } else {
16092 /* OPC_BNVC */
339cd2a8 16093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
16094 }
16095 tcg_temp_free(input_overflow);
16096 tcg_temp_free(t4);
16097 tcg_temp_free(t3);
16098 tcg_temp_free(t2);
16099 } else if (rs < rt && rs == 0) {
16100 /* OPC_BEQZALC, OPC_BNEZALC */
16101 if (opc == OPC_BEQZALC) {
16102 /* OPC_BEQZALC */
339cd2a8 16103 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
16104 } else {
16105 /* OPC_BNEZALC */
339cd2a8 16106 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
16107 }
16108 } else {
16109 /* OPC_BEQC, OPC_BNEC */
16110 if (opc == OPC_BEQC) {
16111 /* OPC_BEQC */
339cd2a8 16112 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
16113 } else {
16114 /* OPC_BNEC */
339cd2a8 16115 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
16116 }
16117 }
16118 break;
16119 case OPC_BEQZC:
339cd2a8 16120 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
16121 break;
16122 case OPC_BNEZC:
339cd2a8 16123 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16124 break;
16125 default:
16126 MIPS_INVAL("Compact conditional branch/jump");
16127 generate_exception(ctx, EXCP_RI);
16128 goto out;
16129 }
16130
16131 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16132 gen_goto_tb(ctx, 1, ctx->btarget);
16133 gen_set_label(fs);
16134
16135 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16136 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16137 }
16138
16139out:
16140 tcg_temp_free(t0);
16141 tcg_temp_free(t1);
16142}
16143
10dc65db
LA
16144static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16145{
4267d3e6 16146 int rs, rt, rd, sa;
b42ee5e1 16147 uint32_t op1, op2;
10dc65db
LA
16148
16149 rs = (ctx->opcode >> 21) & 0x1f;
16150 rt = (ctx->opcode >> 16) & 0x1f;
16151 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16152 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16153
16154 op1 = MASK_SPECIAL(ctx->opcode);
16155 switch (op1) {
d4ea6acd
LA
16156 case OPC_LSA:
16157 if (rd != 0) {
16158 int imm2 = extract32(ctx->opcode, 6, 3);
16159 TCGv t0 = tcg_temp_new();
16160 TCGv t1 = tcg_temp_new();
16161 gen_load_gpr(t0, rs);
16162 gen_load_gpr(t1, rt);
16163 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16164 tcg_gen_add_tl(t0, t0, t1);
16165 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16166 tcg_temp_free(t1);
16167 tcg_temp_free(t0);
16168 }
16169 break;
b42ee5e1
LA
16170 case OPC_MULT ... OPC_DIVU:
16171 op2 = MASK_R6_MULDIV(ctx->opcode);
16172 switch (op2) {
16173 case R6_OPC_MUL:
16174 case R6_OPC_MUH:
16175 case R6_OPC_MULU:
16176 case R6_OPC_MUHU:
16177 case R6_OPC_DIV:
16178 case R6_OPC_MOD:
16179 case R6_OPC_DIVU:
16180 case R6_OPC_MODU:
16181 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16182 break;
16183 default:
16184 MIPS_INVAL("special_r6 muldiv");
16185 generate_exception(ctx, EXCP_RI);
16186 break;
16187 }
16188 break;
10dc65db
LA
16189 case OPC_SELEQZ:
16190 case OPC_SELNEZ:
16191 gen_cond_move(ctx, op1, rd, rs, rt);
16192 break;
4267d3e6
LA
16193 case R6_OPC_CLO:
16194 case R6_OPC_CLZ:
16195 if (rt == 0 && sa == 1) {
16196 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16197 We need additionally to check other fields */
16198 gen_cl(ctx, op1, rd, rs);
16199 } else {
16200 generate_exception(ctx, EXCP_RI);
16201 }
16202 break;
16203 case R6_OPC_SDBBP:
faf1f68b
LA
16204 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16205 generate_exception(ctx, EXCP_RI);
16206 } else {
16207 generate_exception(ctx, EXCP_DBp);
16208 }
4267d3e6 16209 break;
b42ee5e1 16210#if defined(TARGET_MIPS64)
d4ea6acd
LA
16211 case OPC_DLSA:
16212 check_mips_64(ctx);
16213 if (rd != 0) {
16214 int imm2 = extract32(ctx->opcode, 6, 3);
16215 TCGv t0 = tcg_temp_new();
16216 TCGv t1 = tcg_temp_new();
16217 gen_load_gpr(t0, rs);
16218 gen_load_gpr(t1, rt);
16219 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16220 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16221 tcg_temp_free(t1);
16222 tcg_temp_free(t0);
16223 }
16224 break;
4267d3e6
LA
16225 case R6_OPC_DCLO:
16226 case R6_OPC_DCLZ:
16227 if (rt == 0 && sa == 1) {
16228 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16229 We need additionally to check other fields */
16230 check_mips_64(ctx);
16231 gen_cl(ctx, op1, rd, rs);
16232 } else {
16233 generate_exception(ctx, EXCP_RI);
16234 }
16235 break;
b42ee5e1
LA
16236 case OPC_DMULT ... OPC_DDIVU:
16237 op2 = MASK_R6_MULDIV(ctx->opcode);
16238 switch (op2) {
16239 case R6_OPC_DMUL:
16240 case R6_OPC_DMUH:
16241 case R6_OPC_DMULU:
16242 case R6_OPC_DMUHU:
16243 case R6_OPC_DDIV:
16244 case R6_OPC_DMOD:
16245 case R6_OPC_DDIVU:
16246 case R6_OPC_DMODU:
16247 check_mips_64(ctx);
16248 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16249 break;
16250 default:
16251 MIPS_INVAL("special_r6 muldiv");
16252 generate_exception(ctx, EXCP_RI);
16253 break;
16254 }
16255 break;
16256#endif
10dc65db
LA
16257 default: /* Invalid */
16258 MIPS_INVAL("special_r6");
16259 generate_exception(ctx, EXCP_RI);
16260 break;
16261 }
16262}
16263
16264static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16265{
b42ee5e1 16266 int rs, rt, rd, sa;
10dc65db
LA
16267 uint32_t op1;
16268
16269 rs = (ctx->opcode >> 21) & 0x1f;
16270 rt = (ctx->opcode >> 16) & 0x1f;
16271 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16272 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16273
16274 op1 = MASK_SPECIAL(ctx->opcode);
16275 switch (op1) {
16276 case OPC_MOVN: /* Conditional move */
16277 case OPC_MOVZ:
16278 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16279 INSN_LOONGSON2E | INSN_LOONGSON2F);
16280 gen_cond_move(ctx, op1, rd, rs, rt);
16281 break;
16282 case OPC_MFHI: /* Move from HI/LO */
16283 case OPC_MFLO:
16284 gen_HILO(ctx, op1, rs & 3, rd);
16285 break;
16286 case OPC_MTHI:
16287 case OPC_MTLO: /* Move to HI/LO */
16288 gen_HILO(ctx, op1, rd & 3, rs);
16289 break;
16290 case OPC_MOVCI:
16291 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16292 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16293 check_cp1_enabled(ctx);
16294 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16295 (ctx->opcode >> 16) & 1);
16296 } else {
16297 generate_exception_err(ctx, EXCP_CpU, 1);
16298 }
16299 break;
b42ee5e1
LA
16300 case OPC_MULT:
16301 case OPC_MULTU:
16302 if (sa) {
16303 check_insn(ctx, INSN_VR54XX);
16304 op1 = MASK_MUL_VR54XX(ctx->opcode);
16305 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16306 } else {
16307 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16308 }
16309 break;
16310 case OPC_DIV:
16311 case OPC_DIVU:
16312 gen_muldiv(ctx, op1, 0, rs, rt);
16313 break;
16314#if defined(TARGET_MIPS64)
16315 case OPC_DMULT ... OPC_DDIVU:
16316 check_insn(ctx, ISA_MIPS3);
16317 check_mips_64(ctx);
16318 gen_muldiv(ctx, op1, 0, rs, rt);
16319 break;
16320#endif
0aefa333 16321 case OPC_JR:
b231c103 16322 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16323 break;
4267d3e6
LA
16324 case OPC_SPIM:
16325#ifdef MIPS_STRICT_STANDARD
16326 MIPS_INVAL("SPIM");
16327 generate_exception(ctx, EXCP_RI);
16328#else
16329 /* Implemented as RI exception for now. */
16330 MIPS_INVAL("spim (unofficial)");
16331 generate_exception(ctx, EXCP_RI);
16332#endif
16333 break;
10dc65db
LA
16334 default: /* Invalid */
16335 MIPS_INVAL("special_legacy");
16336 generate_exception(ctx, EXCP_RI);
16337 break;
16338 }
16339}
16340
099e5b4d 16341static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16342{
3c824109 16343 int rs, rt, rd, sa;
099e5b4d 16344 uint32_t op1;
3c824109 16345
3c824109
NF
16346 rs = (ctx->opcode >> 21) & 0x1f;
16347 rt = (ctx->opcode >> 16) & 0x1f;
16348 rd = (ctx->opcode >> 11) & 0x1f;
16349 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16350
16351 op1 = MASK_SPECIAL(ctx->opcode);
16352 switch (op1) {
16353 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16354 if (sa == 5 && rd == 0 &&
16355 rs == 0 && rt == 0) { /* PAUSE */
16356 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16357 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16358 MIPS_DEBUG("CTI in delay / forbidden slot");
16359 generate_exception(ctx, EXCP_RI);
16360 break;
16361 }
16362 }
16363 /* Fallthrough */
099e5b4d
LA
16364 case OPC_SRA:
16365 gen_shift_imm(ctx, op1, rd, rt, sa);
16366 break;
16367 case OPC_SRL:
16368 switch ((ctx->opcode >> 21) & 0x1f) {
16369 case 1:
16370 /* rotr is decoded as srl on non-R2 CPUs */
16371 if (ctx->insn_flags & ISA_MIPS32R2) {
16372 op1 = OPC_ROTR;
ea63e2c3 16373 }
099e5b4d
LA
16374 /* Fallthrough */
16375 case 0:
16376 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16377 break;
099e5b4d
LA
16378 default:
16379 generate_exception(ctx, EXCP_RI);
ea63e2c3 16380 break;
099e5b4d
LA
16381 }
16382 break;
099e5b4d
LA
16383 case OPC_ADD ... OPC_SUBU:
16384 gen_arith(ctx, op1, rd, rs, rt);
16385 break;
16386 case OPC_SLLV: /* Shifts */
16387 case OPC_SRAV:
16388 gen_shift(ctx, op1, rd, rs, rt);
16389 break;
16390 case OPC_SRLV:
16391 switch ((ctx->opcode >> 6) & 0x1f) {
16392 case 1:
16393 /* rotrv is decoded as srlv on non-R2 CPUs */
16394 if (ctx->insn_flags & ISA_MIPS32R2) {
16395 op1 = OPC_ROTRV;
26135ead 16396 }
099e5b4d
LA
16397 /* Fallthrough */
16398 case 0:
16399 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16400 break;
099e5b4d
LA
16401 default:
16402 generate_exception(ctx, EXCP_RI);
6af0bf9c 16403 break;
099e5b4d
LA
16404 }
16405 break;
16406 case OPC_SLT: /* Set on less than */
16407 case OPC_SLTU:
16408 gen_slt(ctx, op1, rd, rs, rt);
16409 break;
16410 case OPC_AND: /* Logic*/
16411 case OPC_OR:
16412 case OPC_NOR:
16413 case OPC_XOR:
16414 gen_logic(ctx, op1, rd, rs, rt);
16415 break;
0aefa333 16416 case OPC_JALR:
b231c103 16417 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16418 break;
16419 case OPC_TGE ... OPC_TEQ: /* Traps */
16420 case OPC_TNE:
d9224450 16421 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16422 gen_trap(ctx, op1, rs, rt, -1);
16423 break;
d4ea6acd 16424 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16425 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16426 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16427 decode_opc_special_r6(env, ctx);
16428 } else {
16429 /* Pmon entry point, also R4010 selsl */
b48cfdff 16430#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16431 MIPS_INVAL("PMON / selsl");
16432 generate_exception(ctx, EXCP_RI);
b48cfdff 16433#else
d4ea6acd 16434 gen_helper_0e0i(pmon, sa);
b48cfdff 16435#endif
d4ea6acd 16436 }
099e5b4d
LA
16437 break;
16438 case OPC_SYSCALL:
16439 generate_exception(ctx, EXCP_SYSCALL);
16440 ctx->bstate = BS_STOP;
16441 break;
16442 case OPC_BREAK:
16443 generate_exception(ctx, EXCP_BREAK);
16444 break;
099e5b4d 16445 case OPC_SYNC:
d9224450 16446 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16447 /* Treat as NOP. */
16448 break;
4ad40f36 16449
d26bc211 16450#if defined(TARGET_MIPS64)
099e5b4d
LA
16451 /* MIPS64 specific opcodes */
16452 case OPC_DSLL:
16453 case OPC_DSRA:
16454 case OPC_DSLL32:
16455 case OPC_DSRA32:
16456 check_insn(ctx, ISA_MIPS3);
16457 check_mips_64(ctx);
16458 gen_shift_imm(ctx, op1, rd, rt, sa);
16459 break;
16460 case OPC_DSRL:
16461 switch ((ctx->opcode >> 21) & 0x1f) {
16462 case 1:
16463 /* drotr is decoded as dsrl on non-R2 CPUs */
16464 if (ctx->insn_flags & ISA_MIPS32R2) {
16465 op1 = OPC_DROTR;
ea63e2c3 16466 }
099e5b4d
LA
16467 /* Fallthrough */
16468 case 0:
d75c135e 16469 check_insn(ctx, ISA_MIPS3);
e189e748 16470 check_mips_64(ctx);
099e5b4d 16471 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16472 break;
099e5b4d
LA
16473 default:
16474 generate_exception(ctx, EXCP_RI);
460f00c4 16475 break;
099e5b4d
LA
16476 }
16477 break;
16478 case OPC_DSRL32:
16479 switch ((ctx->opcode >> 21) & 0x1f) {
16480 case 1:
16481 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16482 if (ctx->insn_flags & ISA_MIPS32R2) {
16483 op1 = OPC_DROTR32;
ea63e2c3 16484 }
099e5b4d
LA
16485 /* Fallthrough */
16486 case 0:
d75c135e 16487 check_insn(ctx, ISA_MIPS3);
e189e748 16488 check_mips_64(ctx);
099e5b4d 16489 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16490 break;
099e5b4d 16491 default:
6af0bf9c
FB
16492 generate_exception(ctx, EXCP_RI);
16493 break;
16494 }
16495 break;
099e5b4d
LA
16496 case OPC_DADD ... OPC_DSUBU:
16497 check_insn(ctx, ISA_MIPS3);
16498 check_mips_64(ctx);
16499 gen_arith(ctx, op1, rd, rs, rt);
16500 break;
16501 case OPC_DSLLV:
16502 case OPC_DSRAV:
16503 check_insn(ctx, ISA_MIPS3);
16504 check_mips_64(ctx);
16505 gen_shift(ctx, op1, rd, rs, rt);
16506 break;
16507 case OPC_DSRLV:
16508 switch ((ctx->opcode >> 6) & 0x1f) {
16509 case 1:
16510 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16511 if (ctx->insn_flags & ISA_MIPS32R2) {
16512 op1 = OPC_DROTRV;
6af0bf9c 16513 }
099e5b4d
LA
16514 /* Fallthrough */
16515 case 0:
16516 check_insn(ctx, ISA_MIPS3);
e189e748 16517 check_mips_64(ctx);
099e5b4d 16518 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16519 break;
099e5b4d 16520 default:
6af0bf9c
FB
16521 generate_exception(ctx, EXCP_RI);
16522 break;
16523 }
16524 break;
f7685877
YK
16525 case OPC_DLSA:
16526 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16527 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16528 decode_opc_special_r6(env, ctx);
16529 }
16530 break;
099e5b4d 16531#endif
10dc65db
LA
16532 default:
16533 if (ctx->insn_flags & ISA_MIPS32R6) {
16534 decode_opc_special_r6(env, ctx);
16535 } else {
16536 decode_opc_special_legacy(env, ctx);
16537 }
16538 }
16539}
16540
10dc65db 16541static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16542{
16543 int rs, rt, rd;
16544 uint32_t op1;
6c5c1e20 16545
4267d3e6
LA
16546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16547
099e5b4d
LA
16548 rs = (ctx->opcode >> 21) & 0x1f;
16549 rt = (ctx->opcode >> 16) & 0x1f;
16550 rd = (ctx->opcode >> 11) & 0x1f;
16551
16552 op1 = MASK_SPECIAL2(ctx->opcode);
16553 switch (op1) {
16554 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16555 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16556 check_insn(ctx, ISA_MIPS32);
16557 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16558 break;
16559 case OPC_MUL:
099e5b4d
LA
16560 gen_arith(ctx, op1, rd, rs, rt);
16561 break;
fac5a073
LA
16562 case OPC_DIV_G_2F:
16563 case OPC_DIVU_G_2F:
16564 case OPC_MULT_G_2F:
16565 case OPC_MULTU_G_2F:
16566 case OPC_MOD_G_2F:
16567 case OPC_MODU_G_2F:
16568 check_insn(ctx, INSN_LOONGSON2F);
16569 gen_loongson_integer(ctx, op1, rd, rs, rt);
16570 break;
099e5b4d
LA
16571 case OPC_CLO:
16572 case OPC_CLZ:
16573 check_insn(ctx, ISA_MIPS32);
16574 gen_cl(ctx, op1, rd, rs);
16575 break;
16576 case OPC_SDBBP:
16577 /* XXX: not clear which exception should be raised
16578 * when in debug mode...
16579 */
16580 check_insn(ctx, ISA_MIPS32);
16581 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16582 generate_exception(ctx, EXCP_DBp);
16583 } else {
16584 generate_exception(ctx, EXCP_DBp);
16585 }
16586 /* Treat as NOP. */
16587 break;
9b1a1d68 16588#if defined(TARGET_MIPS64)
099e5b4d
LA
16589 case OPC_DCLO:
16590 case OPC_DCLZ:
16591 check_insn(ctx, ISA_MIPS64);
16592 check_mips_64(ctx);
16593 gen_cl(ctx, op1, rd, rs);
16594 break;
4267d3e6
LA
16595 case OPC_DMULT_G_2F:
16596 case OPC_DMULTU_G_2F:
16597 case OPC_DDIV_G_2F:
16598 case OPC_DDIVU_G_2F:
16599 case OPC_DMOD_G_2F:
16600 case OPC_DMODU_G_2F:
16601 check_insn(ctx, INSN_LOONGSON2F);
16602 gen_loongson_integer(ctx, op1, rd, rs, rt);
16603 break;
10dc65db 16604#endif
4267d3e6
LA
16605 default: /* Invalid */
16606 MIPS_INVAL("special2_legacy");
16607 generate_exception(ctx, EXCP_RI);
16608 break;
10dc65db
LA
16609 }
16610}
16611
16612static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16613{
15eacb9b
YK
16614 int rs, rt, rd, sa;
16615 uint32_t op1, op2;
10dc65db
LA
16616 int16_t imm;
16617
16618 rs = (ctx->opcode >> 21) & 0x1f;
16619 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16620 rd = (ctx->opcode >> 11) & 0x1f;
16621 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16622 imm = (int16_t)ctx->opcode >> 7;
16623
16624 op1 = MASK_SPECIAL3(ctx->opcode);
16625 switch (op1) {
bf7910c6
LA
16626 case R6_OPC_PREF:
16627 if (rt >= 24) {
16628 /* hint codes 24-31 are reserved and signal RI */
16629 generate_exception(ctx, EXCP_RI);
16630 }
16631 /* Treat as NOP. */
16632 break;
16633 case R6_OPC_CACHE:
16634 /* Treat as NOP. */
16635 break;
10dc65db
LA
16636 case R6_OPC_SC:
16637 gen_st_cond(ctx, op1, rt, rs, imm);
16638 break;
16639 case R6_OPC_LL:
16640 gen_ld(ctx, op1, rt, rs, imm);
16641 break;
15eacb9b
YK
16642 case OPC_BSHFL:
16643 {
16644 if (rd == 0) {
16645 /* Treat as NOP. */
16646 break;
16647 }
16648 TCGv t0 = tcg_temp_new();
16649 gen_load_gpr(t0, rt);
16650
16651 op2 = MASK_BSHFL(ctx->opcode);
16652 switch (op2) {
16653 case OPC_ALIGN ... OPC_ALIGN_END:
16654 sa &= 3;
16655 if (sa == 0) {
16656 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16657 } else {
16658 TCGv t1 = tcg_temp_new();
16659 TCGv_i64 t2 = tcg_temp_new_i64();
16660 gen_load_gpr(t1, rs);
16661 tcg_gen_concat_tl_i64(t2, t1, t0);
16662 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16663#if defined(TARGET_MIPS64)
16664 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16665#else
16666 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16667#endif
16668 tcg_temp_free_i64(t2);
16669 tcg_temp_free(t1);
16670 }
16671 break;
16672 case OPC_BITSWAP:
16673 gen_helper_bitswap(cpu_gpr[rd], t0);
16674 break;
16675 }
16676 tcg_temp_free(t0);
16677 }
16678 break;
bf7910c6
LA
16679#if defined(TARGET_MIPS64)
16680 case R6_OPC_SCD:
16681 gen_st_cond(ctx, op1, rt, rs, imm);
16682 break;
16683 case R6_OPC_LLD:
16684 gen_ld(ctx, op1, rt, rs, imm);
16685 break;
15eacb9b
YK
16686 case OPC_DBSHFL:
16687 check_mips_64(ctx);
16688 {
16689 if (rd == 0) {
16690 /* Treat as NOP. */
16691 break;
16692 }
16693 TCGv t0 = tcg_temp_new();
16694 gen_load_gpr(t0, rt);
16695
16696 op2 = MASK_DBSHFL(ctx->opcode);
16697 switch (op2) {
16698 case OPC_DALIGN ... OPC_DALIGN_END:
16699 sa &= 7;
16700 if (sa == 0) {
16701 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16702 } else {
16703 TCGv t1 = tcg_temp_new();
16704 gen_load_gpr(t1, rs);
16705 tcg_gen_shli_tl(t0, t0, 8 * sa);
16706 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16707 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16708 tcg_temp_free(t1);
16709 }
16710 break;
16711 case OPC_DBITSWAP:
16712 gen_helper_dbitswap(cpu_gpr[rd], t0);
16713 break;
16714 }
16715 tcg_temp_free(t0);
16716 }
16717 break;
bf7910c6 16718#endif
10dc65db
LA
16719 default: /* Invalid */
16720 MIPS_INVAL("special3_r6");
16721 generate_exception(ctx, EXCP_RI);
16722 break;
16723 }
16724}
16725
16726static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16727{
fac5a073 16728 int rs, rt, rd;
099e5b4d 16729 uint32_t op1, op2;
099e5b4d
LA
16730
16731 rs = (ctx->opcode >> 21) & 0x1f;
16732 rt = (ctx->opcode >> 16) & 0x1f;
16733 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16734
16735 op1 = MASK_SPECIAL3(ctx->opcode);
16736 switch (op1) {
099e5b4d
LA
16737 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16738 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16739 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16740 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16741 * the same mask and op1. */
16742 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16743 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16744 switch (op2) {
099e5b4d
LA
16745 case OPC_ADDUH_QB:
16746 case OPC_ADDUH_R_QB:
16747 case OPC_ADDQH_PH:
16748 case OPC_ADDQH_R_PH:
16749 case OPC_ADDQH_W:
16750 case OPC_ADDQH_R_W:
16751 case OPC_SUBUH_QB:
16752 case OPC_SUBUH_R_QB:
16753 case OPC_SUBQH_PH:
16754 case OPC_SUBQH_R_PH:
16755 case OPC_SUBQH_W:
16756 case OPC_SUBQH_R_W:
461c08df
JL
16757 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16758 break;
099e5b4d
LA
16759 case OPC_MUL_PH:
16760 case OPC_MUL_S_PH:
16761 case OPC_MULQ_S_W:
16762 case OPC_MULQ_RS_W:
16763 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16764 break;
461c08df 16765 default:
099e5b4d 16766 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16767 generate_exception(ctx, EXCP_RI);
16768 break;
16769 }
099e5b4d
LA
16770 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16771 gen_loongson_integer(ctx, op1, rd, rs, rt);
16772 } else {
16773 generate_exception(ctx, EXCP_RI);
16774 }
16775 break;
16776 case OPC_LX_DSP:
16777 op2 = MASK_LX(ctx->opcode);
16778 switch (op2) {
16779#if defined(TARGET_MIPS64)
16780 case OPC_LDX:
16781#endif
16782 case OPC_LBUX:
16783 case OPC_LHX:
16784 case OPC_LWX:
16785 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16786 break;
16787 default: /* Invalid */
16788 MIPS_INVAL("MASK LX");
16789 generate_exception(ctx, EXCP_RI);
16790 break;
16791 }
16792 break;
16793 case OPC_ABSQ_S_PH_DSP:
16794 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16795 switch (op2) {
16796 case OPC_ABSQ_S_QB:
16797 case OPC_ABSQ_S_PH:
16798 case OPC_ABSQ_S_W:
16799 case OPC_PRECEQ_W_PHL:
16800 case OPC_PRECEQ_W_PHR:
16801 case OPC_PRECEQU_PH_QBL:
16802 case OPC_PRECEQU_PH_QBR:
16803 case OPC_PRECEQU_PH_QBLA:
16804 case OPC_PRECEQU_PH_QBRA:
16805 case OPC_PRECEU_PH_QBL:
16806 case OPC_PRECEU_PH_QBR:
16807 case OPC_PRECEU_PH_QBLA:
16808 case OPC_PRECEU_PH_QBRA:
16809 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16810 break;
16811 case OPC_BITREV:
16812 case OPC_REPL_QB:
16813 case OPC_REPLV_QB:
16814 case OPC_REPL_PH:
16815 case OPC_REPLV_PH:
16816 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16817 break;
16818 default:
16819 MIPS_INVAL("MASK ABSQ_S.PH");
16820 generate_exception(ctx, EXCP_RI);
16821 break;
16822 }
16823 break;
16824 case OPC_ADDU_QB_DSP:
16825 op2 = MASK_ADDU_QB(ctx->opcode);
16826 switch (op2) {
16827 case OPC_ADDQ_PH:
16828 case OPC_ADDQ_S_PH:
16829 case OPC_ADDQ_S_W:
16830 case OPC_ADDU_QB:
16831 case OPC_ADDU_S_QB:
16832 case OPC_ADDU_PH:
16833 case OPC_ADDU_S_PH:
16834 case OPC_SUBQ_PH:
16835 case OPC_SUBQ_S_PH:
16836 case OPC_SUBQ_S_W:
16837 case OPC_SUBU_QB:
16838 case OPC_SUBU_S_QB:
16839 case OPC_SUBU_PH:
16840 case OPC_SUBU_S_PH:
16841 case OPC_ADDSC:
16842 case OPC_ADDWC:
16843 case OPC_MODSUB:
16844 case OPC_RADDU_W_QB:
16845 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16846 break;
16847 case OPC_MULEU_S_PH_QBL:
16848 case OPC_MULEU_S_PH_QBR:
16849 case OPC_MULQ_RS_PH:
16850 case OPC_MULEQ_S_W_PHL:
16851 case OPC_MULEQ_S_W_PHR:
16852 case OPC_MULQ_S_PH:
16853 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16854 break;
16855 default: /* Invalid */
16856 MIPS_INVAL("MASK ADDU.QB");
16857 generate_exception(ctx, EXCP_RI);
461c08df 16858 break;
461c08df 16859
099e5b4d
LA
16860 }
16861 break;
16862 case OPC_CMPU_EQ_QB_DSP:
16863 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16864 switch (op2) {
16865 case OPC_PRECR_SRA_PH_W:
16866 case OPC_PRECR_SRA_R_PH_W:
16867 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16868 break;
099e5b4d
LA
16869 case OPC_PRECR_QB_PH:
16870 case OPC_PRECRQ_QB_PH:
16871 case OPC_PRECRQ_PH_W:
16872 case OPC_PRECRQ_RS_PH_W:
16873 case OPC_PRECRQU_S_QB_PH:
16874 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16875 break;
099e5b4d
LA
16876 case OPC_CMPU_EQ_QB:
16877 case OPC_CMPU_LT_QB:
16878 case OPC_CMPU_LE_QB:
16879 case OPC_CMP_EQ_PH:
16880 case OPC_CMP_LT_PH:
16881 case OPC_CMP_LE_PH:
16882 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16883 break;
099e5b4d
LA
16884 case OPC_CMPGU_EQ_QB:
16885 case OPC_CMPGU_LT_QB:
16886 case OPC_CMPGU_LE_QB:
16887 case OPC_CMPGDU_EQ_QB:
16888 case OPC_CMPGDU_LT_QB:
16889 case OPC_CMPGDU_LE_QB:
16890 case OPC_PICK_QB:
16891 case OPC_PICK_PH:
16892 case OPC_PACKRL_PH:
16893 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16894 break;
16895 default: /* Invalid */
16896 MIPS_INVAL("MASK CMPU.EQ.QB");
16897 generate_exception(ctx, EXCP_RI);
16898 break;
16899 }
16900 break;
16901 case OPC_SHLL_QB_DSP:
16902 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16903 break;
16904 case OPC_DPA_W_PH_DSP:
16905 op2 = MASK_DPA_W_PH(ctx->opcode);
16906 switch (op2) {
16907 case OPC_DPAU_H_QBL:
16908 case OPC_DPAU_H_QBR:
16909 case OPC_DPSU_H_QBL:
16910 case OPC_DPSU_H_QBR:
16911 case OPC_DPA_W_PH:
16912 case OPC_DPAX_W_PH:
16913 case OPC_DPAQ_S_W_PH:
16914 case OPC_DPAQX_S_W_PH:
16915 case OPC_DPAQX_SA_W_PH:
16916 case OPC_DPS_W_PH:
16917 case OPC_DPSX_W_PH:
16918 case OPC_DPSQ_S_W_PH:
16919 case OPC_DPSQX_S_W_PH:
16920 case OPC_DPSQX_SA_W_PH:
16921 case OPC_MULSAQ_S_W_PH:
16922 case OPC_DPAQ_SA_L_W:
16923 case OPC_DPSQ_SA_L_W:
16924 case OPC_MAQ_S_W_PHL:
16925 case OPC_MAQ_S_W_PHR:
16926 case OPC_MAQ_SA_W_PHL:
16927 case OPC_MAQ_SA_W_PHR:
16928 case OPC_MULSA_W_PH:
16929 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16930 break;
16931 default: /* Invalid */
16932 MIPS_INVAL("MASK DPAW.PH");
16933 generate_exception(ctx, EXCP_RI);
16934 break;
16935 }
16936 break;
16937 case OPC_INSV_DSP:
16938 op2 = MASK_INSV(ctx->opcode);
16939 switch (op2) {
16940 case OPC_INSV:
16941 check_dsp(ctx);
16942 {
16943 TCGv t0, t1;
16944
16945 if (rt == 0) {
16946 MIPS_DEBUG("NOP");
16947 break;
16948 }
16949
16950 t0 = tcg_temp_new();
16951 t1 = tcg_temp_new();
16952
16953 gen_load_gpr(t0, rt);
16954 gen_load_gpr(t1, rs);
16955
16956 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16957
16958 tcg_temp_free(t0);
16959 tcg_temp_free(t1);
a22260ae
JL
16960 break;
16961 }
099e5b4d
LA
16962 default: /* Invalid */
16963 MIPS_INVAL("MASK INSV");
16964 generate_exception(ctx, EXCP_RI);
16965 break;
16966 }
16967 break;
16968 case OPC_APPEND_DSP:
16969 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16970 break;
16971 case OPC_EXTR_W_DSP:
16972 op2 = MASK_EXTR_W(ctx->opcode);
16973 switch (op2) {
16974 case OPC_EXTR_W:
16975 case OPC_EXTR_R_W:
16976 case OPC_EXTR_RS_W:
16977 case OPC_EXTR_S_H:
16978 case OPC_EXTRV_S_H:
16979 case OPC_EXTRV_W:
16980 case OPC_EXTRV_R_W:
16981 case OPC_EXTRV_RS_W:
16982 case OPC_EXTP:
16983 case OPC_EXTPV:
16984 case OPC_EXTPDP:
16985 case OPC_EXTPDPV:
16986 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16987 break;
16988 case OPC_RDDSP:
16989 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16990 break;
16991 case OPC_SHILO:
16992 case OPC_SHILOV:
16993 case OPC_MTHLIP:
16994 case OPC_WRDSP:
16995 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16996 break;
16997 default: /* Invalid */
16998 MIPS_INVAL("MASK EXTR.W");
16999 generate_exception(ctx, EXCP_RI);
17000 break;
17001 }
17002 break;
099e5b4d 17003#if defined(TARGET_MIPS64)
fac5a073
LA
17004 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17005 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17006 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17007 check_insn(ctx, INSN_LOONGSON2E);
17008 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17009 break;
099e5b4d
LA
17010 case OPC_ABSQ_S_QH_DSP:
17011 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17012 switch (op2) {
17013 case OPC_PRECEQ_L_PWL:
17014 case OPC_PRECEQ_L_PWR:
17015 case OPC_PRECEQ_PW_QHL:
17016 case OPC_PRECEQ_PW_QHR:
17017 case OPC_PRECEQ_PW_QHLA:
17018 case OPC_PRECEQ_PW_QHRA:
17019 case OPC_PRECEQU_QH_OBL:
17020 case OPC_PRECEQU_QH_OBR:
17021 case OPC_PRECEQU_QH_OBLA:
17022 case OPC_PRECEQU_QH_OBRA:
17023 case OPC_PRECEU_QH_OBL:
17024 case OPC_PRECEU_QH_OBR:
17025 case OPC_PRECEU_QH_OBLA:
17026 case OPC_PRECEU_QH_OBRA:
17027 case OPC_ABSQ_S_OB:
17028 case OPC_ABSQ_S_PW:
17029 case OPC_ABSQ_S_QH:
17030 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17031 break;
17032 case OPC_REPL_OB:
17033 case OPC_REPL_PW:
17034 case OPC_REPL_QH:
17035 case OPC_REPLV_OB:
17036 case OPC_REPLV_PW:
17037 case OPC_REPLV_QH:
17038 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17039 break;
17040 default: /* Invalid */
17041 MIPS_INVAL("MASK ABSQ_S.QH");
17042 generate_exception(ctx, EXCP_RI);
17043 break;
17044 }
17045 break;
17046 case OPC_ADDU_OB_DSP:
17047 op2 = MASK_ADDU_OB(ctx->opcode);
17048 switch (op2) {
17049 case OPC_RADDU_L_OB:
17050 case OPC_SUBQ_PW:
17051 case OPC_SUBQ_S_PW:
17052 case OPC_SUBQ_QH:
17053 case OPC_SUBQ_S_QH:
17054 case OPC_SUBU_OB:
17055 case OPC_SUBU_S_OB:
17056 case OPC_SUBU_QH:
17057 case OPC_SUBU_S_QH:
17058 case OPC_SUBUH_OB:
17059 case OPC_SUBUH_R_OB:
17060 case OPC_ADDQ_PW:
17061 case OPC_ADDQ_S_PW:
17062 case OPC_ADDQ_QH:
17063 case OPC_ADDQ_S_QH:
17064 case OPC_ADDU_OB:
17065 case OPC_ADDU_S_OB:
17066 case OPC_ADDU_QH:
17067 case OPC_ADDU_S_QH:
17068 case OPC_ADDUH_OB:
17069 case OPC_ADDUH_R_OB:
17070 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17071 break;
099e5b4d
LA
17072 case OPC_MULEQ_S_PW_QHL:
17073 case OPC_MULEQ_S_PW_QHR:
17074 case OPC_MULEU_S_QH_OBL:
17075 case OPC_MULEU_S_QH_OBR:
17076 case OPC_MULQ_RS_QH:
17077 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17078 break;
099e5b4d
LA
17079 default: /* Invalid */
17080 MIPS_INVAL("MASK ADDU.OB");
17081 generate_exception(ctx, EXCP_RI);
26690560 17082 break;
099e5b4d
LA
17083 }
17084 break;
17085 case OPC_CMPU_EQ_OB_DSP:
17086 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17087 switch (op2) {
17088 case OPC_PRECR_SRA_QH_PW:
17089 case OPC_PRECR_SRA_R_QH_PW:
17090 /* Return value is rt. */
17091 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17092 break;
099e5b4d
LA
17093 case OPC_PRECR_OB_QH:
17094 case OPC_PRECRQ_OB_QH:
17095 case OPC_PRECRQ_PW_L:
17096 case OPC_PRECRQ_QH_PW:
17097 case OPC_PRECRQ_RS_QH_PW:
17098 case OPC_PRECRQU_S_OB_QH:
17099 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17100 break;
099e5b4d
LA
17101 case OPC_CMPU_EQ_OB:
17102 case OPC_CMPU_LT_OB:
17103 case OPC_CMPU_LE_OB:
17104 case OPC_CMP_EQ_QH:
17105 case OPC_CMP_LT_QH:
17106 case OPC_CMP_LE_QH:
17107 case OPC_CMP_EQ_PW:
17108 case OPC_CMP_LT_PW:
17109 case OPC_CMP_LE_PW:
17110 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17111 break;
099e5b4d
LA
17112 case OPC_CMPGDU_EQ_OB:
17113 case OPC_CMPGDU_LT_OB:
17114 case OPC_CMPGDU_LE_OB:
17115 case OPC_CMPGU_EQ_OB:
17116 case OPC_CMPGU_LT_OB:
17117 case OPC_CMPGU_LE_OB:
17118 case OPC_PACKRL_PW:
17119 case OPC_PICK_OB:
17120 case OPC_PICK_PW:
17121 case OPC_PICK_QH:
17122 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17123 break;
099e5b4d
LA
17124 default: /* Invalid */
17125 MIPS_INVAL("MASK CMPU_EQ.OB");
17126 generate_exception(ctx, EXCP_RI);
161f85e6 17127 break;
099e5b4d
LA
17128 }
17129 break;
17130 case OPC_DAPPEND_DSP:
17131 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17132 break;
17133 case OPC_DEXTR_W_DSP:
17134 op2 = MASK_DEXTR_W(ctx->opcode);
17135 switch (op2) {
17136 case OPC_DEXTP:
17137 case OPC_DEXTPDP:
17138 case OPC_DEXTPDPV:
17139 case OPC_DEXTPV:
17140 case OPC_DEXTR_L:
17141 case OPC_DEXTR_R_L:
17142 case OPC_DEXTR_RS_L:
17143 case OPC_DEXTR_W:
17144 case OPC_DEXTR_R_W:
17145 case OPC_DEXTR_RS_W:
17146 case OPC_DEXTR_S_H:
17147 case OPC_DEXTRV_L:
17148 case OPC_DEXTRV_R_L:
17149 case OPC_DEXTRV_RS_L:
17150 case OPC_DEXTRV_S_H:
17151 case OPC_DEXTRV_W:
17152 case OPC_DEXTRV_R_W:
17153 case OPC_DEXTRV_RS_W:
17154 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17155 break;
099e5b4d
LA
17156 case OPC_DMTHLIP:
17157 case OPC_DSHILO:
17158 case OPC_DSHILOV:
17159 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17160 break;
099e5b4d
LA
17161 default: /* Invalid */
17162 MIPS_INVAL("MASK EXTR.W");
17163 generate_exception(ctx, EXCP_RI);
461c08df 17164 break;
099e5b4d
LA
17165 }
17166 break;
17167 case OPC_DPAQ_W_QH_DSP:
17168 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17169 switch (op2) {
17170 case OPC_DPAU_H_OBL:
17171 case OPC_DPAU_H_OBR:
17172 case OPC_DPSU_H_OBL:
17173 case OPC_DPSU_H_OBR:
17174 case OPC_DPA_W_QH:
17175 case OPC_DPAQ_S_W_QH:
17176 case OPC_DPS_W_QH:
17177 case OPC_DPSQ_S_W_QH:
17178 case OPC_MULSAQ_S_W_QH:
17179 case OPC_DPAQ_SA_L_PW:
17180 case OPC_DPSQ_SA_L_PW:
17181 case OPC_MULSAQ_S_L_PW:
17182 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17183 break;
17184 case OPC_MAQ_S_W_QHLL:
17185 case OPC_MAQ_S_W_QHLR:
17186 case OPC_MAQ_S_W_QHRL:
17187 case OPC_MAQ_S_W_QHRR:
17188 case OPC_MAQ_SA_W_QHLL:
17189 case OPC_MAQ_SA_W_QHLR:
17190 case OPC_MAQ_SA_W_QHRL:
17191 case OPC_MAQ_SA_W_QHRR:
17192 case OPC_MAQ_S_L_PWL:
17193 case OPC_MAQ_S_L_PWR:
17194 case OPC_DMADD:
17195 case OPC_DMADDU:
17196 case OPC_DMSUB:
17197 case OPC_DMSUBU:
17198 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17199 break;
099e5b4d
LA
17200 default: /* Invalid */
17201 MIPS_INVAL("MASK DPAQ.W.QH");
17202 generate_exception(ctx, EXCP_RI);
b53371ed 17203 break;
099e5b4d
LA
17204 }
17205 break;
17206 case OPC_DINSV_DSP:
17207 op2 = MASK_INSV(ctx->opcode);
17208 switch (op2) {
17209 case OPC_DINSV:
17210 {
17211 TCGv t0, t1;
17212
17213 if (rt == 0) {
17214 MIPS_DEBUG("NOP");
a22260ae
JL
17215 break;
17216 }
099e5b4d 17217 check_dsp(ctx);
1cb6686c 17218
099e5b4d
LA
17219 t0 = tcg_temp_new();
17220 t1 = tcg_temp_new();
1cb6686c 17221
099e5b4d
LA
17222 gen_load_gpr(t0, rt);
17223 gen_load_gpr(t1, rs);
1cb6686c 17224
099e5b4d 17225 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17226
099e5b4d
LA
17227 tcg_temp_free(t0);
17228 tcg_temp_free(t1);
77c5fa8b 17229 break;
099e5b4d 17230 }
7a387fff 17231 default: /* Invalid */
099e5b4d 17232 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17233 generate_exception(ctx, EXCP_RI);
17234 break;
17235 }
17236 break;
099e5b4d
LA
17237 case OPC_SHLL_OB_DSP:
17238 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17239 break;
17240#endif
fac5a073
LA
17241 default: /* Invalid */
17242 MIPS_INVAL("special3_legacy");
17243 generate_exception(ctx, EXCP_RI);
17244 break;
17245 }
17246}
17247
17248static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17249{
17250 int rs, rt, rd, sa;
17251 uint32_t op1, op2;
17252
17253 rs = (ctx->opcode >> 21) & 0x1f;
17254 rt = (ctx->opcode >> 16) & 0x1f;
17255 rd = (ctx->opcode >> 11) & 0x1f;
17256 sa = (ctx->opcode >> 6) & 0x1f;
17257
17258 op1 = MASK_SPECIAL3(ctx->opcode);
17259 switch (op1) {
17260 case OPC_EXT:
17261 case OPC_INS:
17262 check_insn(ctx, ISA_MIPS32R2);
17263 gen_bitops(ctx, op1, rt, rs, sa, rd);
17264 break;
17265 case OPC_BSHFL:
fac5a073 17266 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17267 switch (op2) {
17268 case OPC_ALIGN ... OPC_ALIGN_END:
17269 case OPC_BITSWAP:
17270 check_insn(ctx, ISA_MIPS32R6);
17271 decode_opc_special3_r6(env, ctx);
17272 break;
17273 default:
17274 check_insn(ctx, ISA_MIPS32R2);
17275 gen_bshfl(ctx, op2, rt, rd);
17276 break;
17277 }
fac5a073
LA
17278 break;
17279#if defined(TARGET_MIPS64)
17280 case OPC_DEXTM ... OPC_DEXT:
17281 case OPC_DINSM ... OPC_DINS:
17282 check_insn(ctx, ISA_MIPS64R2);
17283 check_mips_64(ctx);
17284 gen_bitops(ctx, op1, rt, rs, sa, rd);
17285 break;
17286 case OPC_DBSHFL:
fac5a073 17287 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17288 switch (op2) {
17289 case OPC_DALIGN ... OPC_DALIGN_END:
17290 case OPC_DBITSWAP:
17291 check_insn(ctx, ISA_MIPS32R6);
17292 decode_opc_special3_r6(env, ctx);
17293 break;
17294 default:
17295 check_insn(ctx, ISA_MIPS64R2);
17296 check_mips_64(ctx);
17297 op2 = MASK_DBSHFL(ctx->opcode);
17298 gen_bshfl(ctx, op2, rt, rd);
17299 break;
17300 }
fac5a073
LA
17301 break;
17302#endif
17303 case OPC_RDHWR:
17304 gen_rdhwr(ctx, rt, rd);
17305 break;
17306 case OPC_FORK:
17307 check_insn(ctx, ASE_MT);
17308 {
17309 TCGv t0 = tcg_temp_new();
17310 TCGv t1 = tcg_temp_new();
17311
17312 gen_load_gpr(t0, rt);
17313 gen_load_gpr(t1, rs);
17314 gen_helper_fork(t0, t1);
17315 tcg_temp_free(t0);
17316 tcg_temp_free(t1);
17317 }
17318 break;
17319 case OPC_YIELD:
17320 check_insn(ctx, ASE_MT);
17321 {
17322 TCGv t0 = tcg_temp_new();
17323
17324 save_cpu_state(ctx, 1);
17325 gen_load_gpr(t0, rs);
17326 gen_helper_yield(t0, cpu_env, t0);
17327 gen_store_gpr(t0, rd);
17328 tcg_temp_free(t0);
17329 }
17330 break;
10dc65db
LA
17331 default:
17332 if (ctx->insn_flags & ISA_MIPS32R6) {
17333 decode_opc_special3_r6(env, ctx);
17334 } else {
17335 decode_opc_special3_legacy(env, ctx);
17336 }
099e5b4d
LA
17337 }
17338}
17339
863f264d
YK
17340/* MIPS SIMD Architecture (MSA) */
17341static inline int check_msa_access(DisasContext *ctx)
17342{
17343 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17344 !(ctx->hflags & MIPS_HFLAG_F64))) {
17345 generate_exception(ctx, EXCP_RI);
17346 return 0;
17347 }
17348
17349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17350 if (ctx->insn_flags & ASE_MSA) {
17351 generate_exception(ctx, EXCP_MSADIS);
17352 return 0;
17353 } else {
17354 generate_exception(ctx, EXCP_RI);
17355 return 0;
17356 }
17357 }
17358 return 1;
17359}
17360
5692c6e1
YK
17361static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17362{
17363 /* generates tcg ops to check if any element is 0 */
17364 /* Note this function only works with MSA_WRLEN = 128 */
17365 uint64_t eval_zero_or_big = 0;
17366 uint64_t eval_big = 0;
17367 TCGv_i64 t0 = tcg_temp_new_i64();
17368 TCGv_i64 t1 = tcg_temp_new_i64();
17369 switch (df) {
17370 case DF_BYTE:
17371 eval_zero_or_big = 0x0101010101010101ULL;
17372 eval_big = 0x8080808080808080ULL;
17373 break;
17374 case DF_HALF:
17375 eval_zero_or_big = 0x0001000100010001ULL;
17376 eval_big = 0x8000800080008000ULL;
17377 break;
17378 case DF_WORD:
17379 eval_zero_or_big = 0x0000000100000001ULL;
17380 eval_big = 0x8000000080000000ULL;
17381 break;
17382 case DF_DOUBLE:
17383 eval_zero_or_big = 0x0000000000000001ULL;
17384 eval_big = 0x8000000000000000ULL;
17385 break;
17386 }
17387 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17388 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17389 tcg_gen_andi_i64(t0, t0, eval_big);
17390 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17391 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17392 tcg_gen_andi_i64(t1, t1, eval_big);
17393 tcg_gen_or_i64(t0, t0, t1);
17394 /* if all bits are zero then all elements are not zero */
17395 /* if some bit is non-zero then some element is zero */
17396 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17397 tcg_gen_trunc_i64_tl(tresult, t0);
17398 tcg_temp_free_i64(t0);
17399 tcg_temp_free_i64(t1);
17400}
17401
17402static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17403{
17404 uint8_t df = (ctx->opcode >> 21) & 0x3;
17405 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17406 int64_t s16 = (int16_t)ctx->opcode;
17407
17408 check_msa_access(ctx);
17409
17410 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17411 MIPS_DEBUG("CTI in delay / forbidden slot");
17412 generate_exception(ctx, EXCP_RI);
17413 return;
17414 }
17415 switch (op1) {
17416 case OPC_BZ_V:
17417 case OPC_BNZ_V:
17418 {
17419 TCGv_i64 t0 = tcg_temp_new_i64();
17420 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17421 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17422 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17423 tcg_gen_trunc_i64_tl(bcond, t0);
17424 tcg_temp_free_i64(t0);
17425 }
17426 break;
17427 case OPC_BZ_B:
17428 case OPC_BZ_H:
17429 case OPC_BZ_W:
17430 case OPC_BZ_D:
17431 gen_check_zero_element(bcond, df, wt);
17432 break;
17433 case OPC_BNZ_B:
17434 case OPC_BNZ_H:
17435 case OPC_BNZ_W:
17436 case OPC_BNZ_D:
17437 gen_check_zero_element(bcond, df, wt);
17438 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17439 break;
17440 }
17441
17442 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17443
17444 ctx->hflags |= MIPS_HFLAG_BC;
17445 ctx->hflags |= MIPS_HFLAG_BDS32;
17446}
17447
4c789546
YK
17448static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17449{
17450#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17451 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17452 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17453 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17454
17455 TCGv_i32 twd = tcg_const_i32(wd);
17456 TCGv_i32 tws = tcg_const_i32(ws);
17457 TCGv_i32 ti8 = tcg_const_i32(i8);
17458
17459 switch (MASK_MSA_I8(ctx->opcode)) {
17460 case OPC_ANDI_B:
17461 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17462 break;
17463 case OPC_ORI_B:
17464 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17465 break;
17466 case OPC_NORI_B:
17467 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17468 break;
17469 case OPC_XORI_B:
17470 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17471 break;
17472 case OPC_BMNZI_B:
17473 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17474 break;
17475 case OPC_BMZI_B:
17476 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17477 break;
17478 case OPC_BSELI_B:
17479 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17480 break;
17481 case OPC_SHF_B:
17482 case OPC_SHF_H:
17483 case OPC_SHF_W:
17484 {
17485 uint8_t df = (ctx->opcode >> 24) & 0x3;
17486 if (df == DF_DOUBLE) {
17487 generate_exception(ctx, EXCP_RI);
17488 } else {
17489 TCGv_i32 tdf = tcg_const_i32(df);
17490 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17491 tcg_temp_free_i32(tdf);
17492 }
17493 }
17494 break;
17495 default:
17496 MIPS_INVAL("MSA instruction");
17497 generate_exception(ctx, EXCP_RI);
17498 break;
17499 }
17500
17501 tcg_temp_free_i32(twd);
17502 tcg_temp_free_i32(tws);
17503 tcg_temp_free_i32(ti8);
17504}
17505
80e71591
YK
17506static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17507{
17508#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17509 uint8_t df = (ctx->opcode >> 21) & 0x3;
17510 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17511 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17512 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17513 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17514
17515 TCGv_i32 tdf = tcg_const_i32(df);
17516 TCGv_i32 twd = tcg_const_i32(wd);
17517 TCGv_i32 tws = tcg_const_i32(ws);
17518 TCGv_i32 timm = tcg_temp_new_i32();
17519 tcg_gen_movi_i32(timm, u5);
17520
17521 switch (MASK_MSA_I5(ctx->opcode)) {
17522 case OPC_ADDVI_df:
17523 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17524 break;
17525 case OPC_SUBVI_df:
17526 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17527 break;
17528 case OPC_MAXI_S_df:
17529 tcg_gen_movi_i32(timm, s5);
17530 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17531 break;
17532 case OPC_MAXI_U_df:
17533 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17534 break;
17535 case OPC_MINI_S_df:
17536 tcg_gen_movi_i32(timm, s5);
17537 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17538 break;
17539 case OPC_MINI_U_df:
17540 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17541 break;
17542 case OPC_CEQI_df:
17543 tcg_gen_movi_i32(timm, s5);
17544 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17545 break;
17546 case OPC_CLTI_S_df:
17547 tcg_gen_movi_i32(timm, s5);
17548 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17549 break;
17550 case OPC_CLTI_U_df:
17551 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17552 break;
17553 case OPC_CLEI_S_df:
17554 tcg_gen_movi_i32(timm, s5);
17555 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17556 break;
17557 case OPC_CLEI_U_df:
17558 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17559 break;
17560 case OPC_LDI_df:
17561 {
17562 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17563 tcg_gen_movi_i32(timm, s10);
17564 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17565 }
17566 break;
17567 default:
17568 MIPS_INVAL("MSA instruction");
17569 generate_exception(ctx, EXCP_RI);
17570 break;
17571 }
17572
17573 tcg_temp_free_i32(tdf);
17574 tcg_temp_free_i32(twd);
17575 tcg_temp_free_i32(tws);
17576 tcg_temp_free_i32(timm);
17577}
17578
d4cf28de
YK
17579static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17580{
17581#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17582 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17583 uint32_t df = 0, m = 0;
17584 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17585 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17586
17587 TCGv_i32 tdf;
17588 TCGv_i32 tm;
17589 TCGv_i32 twd;
17590 TCGv_i32 tws;
17591
17592 if ((dfm & 0x40) == 0x00) {
17593 m = dfm & 0x3f;
17594 df = DF_DOUBLE;
17595 } else if ((dfm & 0x60) == 0x40) {
17596 m = dfm & 0x1f;
17597 df = DF_WORD;
17598 } else if ((dfm & 0x70) == 0x60) {
17599 m = dfm & 0x0f;
17600 df = DF_HALF;
17601 } else if ((dfm & 0x78) == 0x70) {
17602 m = dfm & 0x7;
17603 df = DF_BYTE;
17604 } else {
17605 generate_exception(ctx, EXCP_RI);
17606 return;
17607 }
17608
17609 tdf = tcg_const_i32(df);
17610 tm = tcg_const_i32(m);
17611 twd = tcg_const_i32(wd);
17612 tws = tcg_const_i32(ws);
17613
17614 switch (MASK_MSA_BIT(ctx->opcode)) {
17615 case OPC_SLLI_df:
17616 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17617 break;
17618 case OPC_SRAI_df:
17619 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17620 break;
17621 case OPC_SRLI_df:
17622 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17623 break;
17624 case OPC_BCLRI_df:
17625 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17626 break;
17627 case OPC_BSETI_df:
17628 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17629 break;
17630 case OPC_BNEGI_df:
17631 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17632 break;
17633 case OPC_BINSLI_df:
17634 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17635 break;
17636 case OPC_BINSRI_df:
17637 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17638 break;
17639 case OPC_SAT_S_df:
17640 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17641 break;
17642 case OPC_SAT_U_df:
17643 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17644 break;
17645 case OPC_SRARI_df:
17646 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17647 break;
17648 case OPC_SRLRI_df:
17649 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17650 break;
17651 default:
17652 MIPS_INVAL("MSA instruction");
17653 generate_exception(ctx, EXCP_RI);
17654 break;
17655 }
17656
17657 tcg_temp_free_i32(tdf);
17658 tcg_temp_free_i32(tm);
17659 tcg_temp_free_i32(twd);
17660 tcg_temp_free_i32(tws);
17661}
17662
28f99f08
YK
17663static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17664{
17665#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17666 uint8_t df = (ctx->opcode >> 21) & 0x3;
17667 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17668 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17669 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17670
17671 TCGv_i32 tdf = tcg_const_i32(df);
17672 TCGv_i32 twd = tcg_const_i32(wd);
17673 TCGv_i32 tws = tcg_const_i32(ws);
17674 TCGv_i32 twt = tcg_const_i32(wt);
17675
17676 switch (MASK_MSA_3R(ctx->opcode)) {
17677 case OPC_SLL_df:
17678 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17679 break;
17680 case OPC_ADDV_df:
17681 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17682 break;
17683 case OPC_CEQ_df:
17684 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17685 break;
17686 case OPC_ADD_A_df:
17687 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17688 break;
17689 case OPC_SUBS_S_df:
17690 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17691 break;
17692 case OPC_MULV_df:
17693 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17694 break;
17695 case OPC_SLD_df:
17696 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17697 break;
17698 case OPC_VSHF_df:
17699 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17700 break;
17701 case OPC_SRA_df:
17702 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17703 break;
17704 case OPC_SUBV_df:
17705 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17706 break;
17707 case OPC_ADDS_A_df:
17708 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17709 break;
17710 case OPC_SUBS_U_df:
17711 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17712 break;
17713 case OPC_MADDV_df:
17714 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17715 break;
17716 case OPC_SPLAT_df:
17717 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17718 break;
17719 case OPC_SRAR_df:
17720 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17721 break;
17722 case OPC_SRL_df:
17723 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17724 break;
17725 case OPC_MAX_S_df:
17726 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17727 break;
17728 case OPC_CLT_S_df:
17729 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17730 break;
17731 case OPC_ADDS_S_df:
17732 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17733 break;
17734 case OPC_SUBSUS_U_df:
17735 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17736 break;
17737 case OPC_MSUBV_df:
17738 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17739 break;
17740 case OPC_PCKEV_df:
17741 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17742 break;
17743 case OPC_SRLR_df:
17744 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17745 break;
17746 case OPC_BCLR_df:
17747 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17748 break;
17749 case OPC_MAX_U_df:
17750 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17751 break;
17752 case OPC_CLT_U_df:
17753 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17754 break;
17755 case OPC_ADDS_U_df:
17756 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17757 break;
17758 case OPC_SUBSUU_S_df:
17759 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17760 break;
17761 case OPC_PCKOD_df:
17762 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17763 break;
17764 case OPC_BSET_df:
17765 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17766 break;
17767 case OPC_MIN_S_df:
17768 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17769 break;
17770 case OPC_CLE_S_df:
17771 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17772 break;
17773 case OPC_AVE_S_df:
17774 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17775 break;
17776 case OPC_ASUB_S_df:
17777 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17778 break;
17779 case OPC_DIV_S_df:
17780 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17781 break;
17782 case OPC_ILVL_df:
17783 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17784 break;
17785 case OPC_BNEG_df:
17786 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17787 break;
17788 case OPC_MIN_U_df:
17789 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17790 break;
17791 case OPC_CLE_U_df:
17792 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17793 break;
17794 case OPC_AVE_U_df:
17795 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17796 break;
17797 case OPC_ASUB_U_df:
17798 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17799 break;
17800 case OPC_DIV_U_df:
17801 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17802 break;
17803 case OPC_ILVR_df:
17804 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17805 break;
17806 case OPC_BINSL_df:
17807 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17808 break;
17809 case OPC_MAX_A_df:
17810 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17811 break;
17812 case OPC_AVER_S_df:
17813 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17814 break;
17815 case OPC_MOD_S_df:
17816 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17817 break;
17818 case OPC_ILVEV_df:
17819 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17820 break;
17821 case OPC_BINSR_df:
17822 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17823 break;
17824 case OPC_MIN_A_df:
17825 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17826 break;
17827 case OPC_AVER_U_df:
17828 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17829 break;
17830 case OPC_MOD_U_df:
17831 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17832 break;
17833 case OPC_ILVOD_df:
17834 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17835 break;
17836
17837 case OPC_DOTP_S_df:
17838 case OPC_DOTP_U_df:
17839 case OPC_DPADD_S_df:
17840 case OPC_DPADD_U_df:
17841 case OPC_DPSUB_S_df:
17842 case OPC_HADD_S_df:
17843 case OPC_DPSUB_U_df:
17844 case OPC_HADD_U_df:
17845 case OPC_HSUB_S_df:
17846 case OPC_HSUB_U_df:
17847 if (df == DF_BYTE) {
17848 generate_exception(ctx, EXCP_RI);
17849 }
17850 switch (MASK_MSA_3R(ctx->opcode)) {
17851 case OPC_DOTP_S_df:
17852 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17853 break;
17854 case OPC_DOTP_U_df:
17855 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17856 break;
17857 case OPC_DPADD_S_df:
17858 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17859 break;
17860 case OPC_DPADD_U_df:
17861 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17862 break;
17863 case OPC_DPSUB_S_df:
17864 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17865 break;
17866 case OPC_HADD_S_df:
17867 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17868 break;
17869 case OPC_DPSUB_U_df:
17870 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17871 break;
17872 case OPC_HADD_U_df:
17873 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17874 break;
17875 case OPC_HSUB_S_df:
17876 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17877 break;
17878 case OPC_HSUB_U_df:
17879 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17880 break;
17881 }
17882 break;
17883 default:
17884 MIPS_INVAL("MSA instruction");
17885 generate_exception(ctx, EXCP_RI);
17886 break;
17887 }
17888 tcg_temp_free_i32(twd);
17889 tcg_temp_free_i32(tws);
17890 tcg_temp_free_i32(twt);
17891 tcg_temp_free_i32(tdf);
17892}
17893
1e608ec1
YK
17894static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17895{
17896#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17897 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17898 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17899 TCGv telm = tcg_temp_new();
17900 TCGv_i32 tsr = tcg_const_i32(source);
17901 TCGv_i32 tdt = tcg_const_i32(dest);
17902
17903 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17904 case OPC_CTCMSA:
17905 gen_load_gpr(telm, source);
17906 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17907 break;
17908 case OPC_CFCMSA:
17909 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17910 gen_store_gpr(telm, dest);
17911 break;
17912 case OPC_MOVE_V:
17913 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17914 break;
17915 default:
17916 MIPS_INVAL("MSA instruction");
17917 generate_exception(ctx, EXCP_RI);
17918 break;
17919 }
17920
17921 tcg_temp_free(telm);
17922 tcg_temp_free_i32(tdt);
17923 tcg_temp_free_i32(tsr);
17924}
17925
17926static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17927 uint32_t n)
17928{
17929#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17930 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17931 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17932
17933 TCGv_i32 tws = tcg_const_i32(ws);
17934 TCGv_i32 twd = tcg_const_i32(wd);
17935 TCGv_i32 tn = tcg_const_i32(n);
17936 TCGv_i32 tdf = tcg_const_i32(df);
17937
17938 switch (MASK_MSA_ELM(ctx->opcode)) {
17939 case OPC_SLDI_df:
17940 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17941 break;
17942 case OPC_SPLATI_df:
17943 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17944 break;
17945 case OPC_INSVE_df:
17946 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17947 break;
17948 case OPC_COPY_S_df:
17949 case OPC_COPY_U_df:
17950 case OPC_INSERT_df:
17951#if !defined(TARGET_MIPS64)
17952 /* Double format valid only for MIPS64 */
17953 if (df == DF_DOUBLE) {
17954 generate_exception(ctx, EXCP_RI);
17955 break;
17956 }
17957#endif
17958 switch (MASK_MSA_ELM(ctx->opcode)) {
17959 case OPC_COPY_S_df:
17960 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
17961 break;
17962 case OPC_COPY_U_df:
17963 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
17964 break;
17965 case OPC_INSERT_df:
17966 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
17967 break;
17968 }
17969 break;
17970 default:
17971 MIPS_INVAL("MSA instruction");
17972 generate_exception(ctx, EXCP_RI);
17973 }
17974 tcg_temp_free_i32(twd);
17975 tcg_temp_free_i32(tws);
17976 tcg_temp_free_i32(tn);
17977 tcg_temp_free_i32(tdf);
17978}
17979
17980static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
17981{
17982 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
17983 uint32_t df = 0, n = 0;
17984
17985 if ((dfn & 0x30) == 0x00) {
17986 n = dfn & 0x0f;
17987 df = DF_BYTE;
17988 } else if ((dfn & 0x38) == 0x20) {
17989 n = dfn & 0x07;
17990 df = DF_HALF;
17991 } else if ((dfn & 0x3c) == 0x30) {
17992 n = dfn & 0x03;
17993 df = DF_WORD;
17994 } else if ((dfn & 0x3e) == 0x38) {
17995 n = dfn & 0x01;
17996 df = DF_DOUBLE;
17997 } else if (dfn == 0x3E) {
17998 /* CTCMSA, CFCMSA, MOVE.V */
17999 gen_msa_elm_3e(env, ctx);
18000 return;
18001 } else {
18002 generate_exception(ctx, EXCP_RI);
18003 return;
18004 }
18005
18006 gen_msa_elm_df(env, ctx, df, n);
18007}
18008
7d05b9c8
YK
18009static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18010{
18011#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18012 uint8_t df = (ctx->opcode >> 21) & 0x1;
18013 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18014 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18015 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18016
18017 TCGv_i32 twd = tcg_const_i32(wd);
18018 TCGv_i32 tws = tcg_const_i32(ws);
18019 TCGv_i32 twt = tcg_const_i32(wt);
18020 TCGv_i32 tdf = tcg_temp_new_i32();
18021
18022 /* adjust df value for floating-point instruction */
18023 tcg_gen_movi_i32(tdf, df + 2);
18024
18025 switch (MASK_MSA_3RF(ctx->opcode)) {
18026 case OPC_FCAF_df:
18027 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18028 break;
18029 case OPC_FADD_df:
18030 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18031 break;
18032 case OPC_FCUN_df:
18033 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18034 break;
18035 case OPC_FSUB_df:
18036 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18037 break;
18038 case OPC_FCOR_df:
18039 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18040 break;
18041 case OPC_FCEQ_df:
18042 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18043 break;
18044 case OPC_FMUL_df:
18045 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18046 break;
18047 case OPC_FCUNE_df:
18048 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18049 break;
18050 case OPC_FCUEQ_df:
18051 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18052 break;
18053 case OPC_FDIV_df:
18054 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18055 break;
18056 case OPC_FCNE_df:
18057 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18058 break;
18059 case OPC_FCLT_df:
18060 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18061 break;
18062 case OPC_FMADD_df:
18063 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18064 break;
18065 case OPC_MUL_Q_df:
18066 tcg_gen_movi_i32(tdf, df + 1);
18067 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18068 break;
18069 case OPC_FCULT_df:
18070 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18071 break;
18072 case OPC_FMSUB_df:
18073 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18074 break;
18075 case OPC_MADD_Q_df:
18076 tcg_gen_movi_i32(tdf, df + 1);
18077 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18078 break;
18079 case OPC_FCLE_df:
18080 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18081 break;
18082 case OPC_MSUB_Q_df:
18083 tcg_gen_movi_i32(tdf, df + 1);
18084 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18085 break;
18086 case OPC_FCULE_df:
18087 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18088 break;
18089 case OPC_FEXP2_df:
18090 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18091 break;
18092 case OPC_FSAF_df:
18093 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18094 break;
18095 case OPC_FEXDO_df:
18096 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18097 break;
18098 case OPC_FSUN_df:
18099 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18100 break;
18101 case OPC_FSOR_df:
18102 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18103 break;
18104 case OPC_FSEQ_df:
18105 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18106 break;
18107 case OPC_FTQ_df:
18108 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18109 break;
18110 case OPC_FSUNE_df:
18111 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18112 break;
18113 case OPC_FSUEQ_df:
18114 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18115 break;
18116 case OPC_FSNE_df:
18117 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18118 break;
18119 case OPC_FSLT_df:
18120 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18121 break;
18122 case OPC_FMIN_df:
18123 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18124 break;
18125 case OPC_MULR_Q_df:
18126 tcg_gen_movi_i32(tdf, df + 1);
18127 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18128 break;
18129 case OPC_FSULT_df:
18130 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18131 break;
18132 case OPC_FMIN_A_df:
18133 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18134 break;
18135 case OPC_MADDR_Q_df:
18136 tcg_gen_movi_i32(tdf, df + 1);
18137 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18138 break;
18139 case OPC_FSLE_df:
18140 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18141 break;
18142 case OPC_FMAX_df:
18143 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18144 break;
18145 case OPC_MSUBR_Q_df:
18146 tcg_gen_movi_i32(tdf, df + 1);
18147 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18148 break;
18149 case OPC_FSULE_df:
18150 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18151 break;
18152 case OPC_FMAX_A_df:
18153 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18154 break;
18155 default:
18156 MIPS_INVAL("MSA instruction");
18157 generate_exception(ctx, EXCP_RI);
18158 break;
18159 }
18160
18161 tcg_temp_free_i32(twd);
18162 tcg_temp_free_i32(tws);
18163 tcg_temp_free_i32(twt);
18164 tcg_temp_free_i32(tdf);
18165}
18166
cbe50b9a
YK
18167static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18168{
18169#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18170 (op & (0x7 << 18)))
18171 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18172 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18173 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18174 uint8_t df = (ctx->opcode >> 16) & 0x3;
18175 TCGv_i32 twd = tcg_const_i32(wd);
18176 TCGv_i32 tws = tcg_const_i32(ws);
18177 TCGv_i32 twt = tcg_const_i32(wt);
18178 TCGv_i32 tdf = tcg_const_i32(df);
18179
18180 switch (MASK_MSA_2R(ctx->opcode)) {
18181 case OPC_FILL_df:
18182#if !defined(TARGET_MIPS64)
18183 /* Double format valid only for MIPS64 */
18184 if (df == DF_DOUBLE) {
18185 generate_exception(ctx, EXCP_RI);
18186 break;
18187 }
18188#endif
18189 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18190 break;
18191 case OPC_PCNT_df:
18192 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18193 break;
18194 case OPC_NLOC_df:
18195 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18196 break;
18197 case OPC_NLZC_df:
18198 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18199 break;
18200 default:
18201 MIPS_INVAL("MSA instruction");
18202 generate_exception(ctx, EXCP_RI);
18203 break;
18204 }
18205
18206 tcg_temp_free_i32(twd);
18207 tcg_temp_free_i32(tws);
18208 tcg_temp_free_i32(twt);
18209 tcg_temp_free_i32(tdf);
18210}
18211
3bdeb688
YK
18212static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18213{
18214#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18215 (op & (0xf << 17)))
18216 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18217 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18218 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18219 uint8_t df = (ctx->opcode >> 16) & 0x1;
18220 TCGv_i32 twd = tcg_const_i32(wd);
18221 TCGv_i32 tws = tcg_const_i32(ws);
18222 TCGv_i32 twt = tcg_const_i32(wt);
18223 /* adjust df value for floating-point instruction */
18224 TCGv_i32 tdf = tcg_const_i32(df + 2);
18225
18226 switch (MASK_MSA_2RF(ctx->opcode)) {
18227 case OPC_FCLASS_df:
18228 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18229 break;
18230 case OPC_FTRUNC_S_df:
18231 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18232 break;
18233 case OPC_FTRUNC_U_df:
18234 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18235 break;
18236 case OPC_FSQRT_df:
18237 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18238 break;
18239 case OPC_FRSQRT_df:
18240 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18241 break;
18242 case OPC_FRCP_df:
18243 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18244 break;
18245 case OPC_FRINT_df:
18246 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18247 break;
18248 case OPC_FLOG2_df:
18249 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18250 break;
18251 case OPC_FEXUPL_df:
18252 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18253 break;
18254 case OPC_FEXUPR_df:
18255 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18256 break;
18257 case OPC_FFQL_df:
18258 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18259 break;
18260 case OPC_FFQR_df:
18261 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18262 break;
18263 case OPC_FTINT_S_df:
18264 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18265 break;
18266 case OPC_FTINT_U_df:
18267 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18268 break;
18269 case OPC_FFINT_S_df:
18270 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18271 break;
18272 case OPC_FFINT_U_df:
18273 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18274 break;
18275 }
18276
18277 tcg_temp_free_i32(twd);
18278 tcg_temp_free_i32(tws);
18279 tcg_temp_free_i32(twt);
18280 tcg_temp_free_i32(tdf);
18281}
18282
cbe50b9a
YK
18283static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18284{
18285#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18286 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18287 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18288 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18289 TCGv_i32 twd = tcg_const_i32(wd);
18290 TCGv_i32 tws = tcg_const_i32(ws);
18291 TCGv_i32 twt = tcg_const_i32(wt);
18292
18293 switch (MASK_MSA_VEC(ctx->opcode)) {
18294 case OPC_AND_V:
18295 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18296 break;
18297 case OPC_OR_V:
18298 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18299 break;
18300 case OPC_NOR_V:
18301 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18302 break;
18303 case OPC_XOR_V:
18304 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18305 break;
18306 case OPC_BMNZ_V:
18307 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18308 break;
18309 case OPC_BMZ_V:
18310 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18311 break;
18312 case OPC_BSEL_V:
18313 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18314 break;
18315 default:
18316 MIPS_INVAL("MSA instruction");
18317 generate_exception(ctx, EXCP_RI);
18318 break;
18319 }
18320
18321 tcg_temp_free_i32(twd);
18322 tcg_temp_free_i32(tws);
18323 tcg_temp_free_i32(twt);
18324}
18325
18326static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18327{
18328 switch (MASK_MSA_VEC(ctx->opcode)) {
18329 case OPC_AND_V:
18330 case OPC_OR_V:
18331 case OPC_NOR_V:
18332 case OPC_XOR_V:
18333 case OPC_BMNZ_V:
18334 case OPC_BMZ_V:
18335 case OPC_BSEL_V:
18336 gen_msa_vec_v(env, ctx);
18337 break;
18338 case OPC_MSA_2R:
18339 gen_msa_2r(env, ctx);
18340 break;
3bdeb688
YK
18341 case OPC_MSA_2RF:
18342 gen_msa_2rf(env, ctx);
18343 break;
cbe50b9a
YK
18344 default:
18345 MIPS_INVAL("MSA instruction");
18346 generate_exception(ctx, EXCP_RI);
18347 break;
18348 }
18349}
18350
4c789546
YK
18351static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18352{
18353 uint32_t opcode = ctx->opcode;
18354 check_insn(ctx, ASE_MSA);
18355 check_msa_access(ctx);
18356
18357 switch (MASK_MSA_MINOR(opcode)) {
18358 case OPC_MSA_I8_00:
18359 case OPC_MSA_I8_01:
18360 case OPC_MSA_I8_02:
18361 gen_msa_i8(env, ctx);
18362 break;
80e71591
YK
18363 case OPC_MSA_I5_06:
18364 case OPC_MSA_I5_07:
18365 gen_msa_i5(env, ctx);
18366 break;
d4cf28de
YK
18367 case OPC_MSA_BIT_09:
18368 case OPC_MSA_BIT_0A:
18369 gen_msa_bit(env, ctx);
18370 break;
28f99f08
YK
18371 case OPC_MSA_3R_0D:
18372 case OPC_MSA_3R_0E:
18373 case OPC_MSA_3R_0F:
18374 case OPC_MSA_3R_10:
18375 case OPC_MSA_3R_11:
18376 case OPC_MSA_3R_12:
18377 case OPC_MSA_3R_13:
18378 case OPC_MSA_3R_14:
18379 case OPC_MSA_3R_15:
18380 gen_msa_3r(env, ctx);
18381 break;
1e608ec1
YK
18382 case OPC_MSA_ELM:
18383 gen_msa_elm(env, ctx);
18384 break;
7d05b9c8
YK
18385 case OPC_MSA_3RF_1A:
18386 case OPC_MSA_3RF_1B:
18387 case OPC_MSA_3RF_1C:
18388 gen_msa_3rf(env, ctx);
18389 break;
cbe50b9a
YK
18390 case OPC_MSA_VEC:
18391 gen_msa_vec(env, ctx);
18392 break;
f7685877
YK
18393 case OPC_LD_B:
18394 case OPC_LD_H:
18395 case OPC_LD_W:
18396 case OPC_LD_D:
18397 case OPC_ST_B:
18398 case OPC_ST_H:
18399 case OPC_ST_W:
18400 case OPC_ST_D:
18401 {
18402 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18403 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18404 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18405 uint8_t df = (ctx->opcode >> 0) & 0x3;
18406
18407 TCGv_i32 tdf = tcg_const_i32(df);
18408 TCGv_i32 twd = tcg_const_i32(wd);
18409 TCGv_i32 trs = tcg_const_i32(rs);
18410 TCGv_i32 ts10 = tcg_const_i32(s10);
18411
18412 switch (MASK_MSA_MINOR(opcode)) {
18413 case OPC_LD_B:
18414 case OPC_LD_H:
18415 case OPC_LD_W:
18416 case OPC_LD_D:
0af7a370 18417 save_cpu_state(ctx, 1);
f7685877
YK
18418 gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10);
18419 break;
18420 case OPC_ST_B:
18421 case OPC_ST_H:
18422 case OPC_ST_W:
18423 case OPC_ST_D:
0af7a370 18424 save_cpu_state(ctx, 1);
f7685877
YK
18425 gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10);
18426 break;
18427 }
18428
18429 tcg_temp_free_i32(twd);
18430 tcg_temp_free_i32(tdf);
18431 tcg_temp_free_i32(trs);
18432 tcg_temp_free_i32(ts10);
18433 }
18434 break;
4c789546
YK
18435 default:
18436 MIPS_INVAL("MSA instruction");
18437 generate_exception(ctx, EXCP_RI);
18438 break;
18439 }
18440
18441}
18442
d2bfa6e6 18443static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18444{
18445 int32_t offset;
18446 int rs, rt, rd, sa;
18447 uint32_t op, op1;
18448 int16_t imm;
18449
18450 /* make sure instructions are on a word boundary */
18451 if (ctx->pc & 0x3) {
18452 env->CP0_BadVAddr = ctx->pc;
aea14095 18453 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
62c68869 18454 ctx->bstate = BS_STOP;
099e5b4d
LA
18455 return;
18456 }
18457
18458 /* Handle blikely not taken case */
18459 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18460 TCGLabel *l1 = gen_new_label();
099e5b4d
LA
18461
18462 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18463 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18464 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18465 gen_goto_tb(ctx, 1, ctx->pc + 4);
18466 gen_set_label(l1);
18467 }
18468
18469 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18470 tcg_gen_debug_insn_start(ctx->pc);
18471 }
18472
18473 op = MASK_OP_MAJOR(ctx->opcode);
18474 rs = (ctx->opcode >> 21) & 0x1f;
18475 rt = (ctx->opcode >> 16) & 0x1f;
18476 rd = (ctx->opcode >> 11) & 0x1f;
18477 sa = (ctx->opcode >> 6) & 0x1f;
18478 imm = (int16_t)ctx->opcode;
18479 switch (op) {
18480 case OPC_SPECIAL:
18481 decode_opc_special(env, ctx);
18482 break;
18483 case OPC_SPECIAL2:
4267d3e6 18484 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18485 break;
18486 case OPC_SPECIAL3:
18487 decode_opc_special3(env, ctx);
18488 break;
7a387fff
TS
18489 case OPC_REGIMM:
18490 op1 = MASK_REGIMM(ctx->opcode);
18491 switch (op1) {
fecd2646
LA
18492 case OPC_BLTZL: /* REGIMM branches */
18493 case OPC_BGEZL:
18494 case OPC_BLTZALL:
18495 case OPC_BGEZALL:
d9224450 18496 check_insn(ctx, ISA_MIPS2);
fecd2646 18497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18498 /* Fallthrough */
fecd2646
LA
18499 case OPC_BLTZ:
18500 case OPC_BGEZ:
b231c103 18501 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18502 break;
fecd2646
LA
18503 case OPC_BLTZAL:
18504 case OPC_BGEZAL:
0aefa333
YK
18505 if (ctx->insn_flags & ISA_MIPS32R6) {
18506 if (rs == 0) {
18507 /* OPC_NAL, OPC_BAL */
b231c103 18508 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18509 } else {
18510 generate_exception(ctx, EXCP_RI);
18511 }
18512 } else {
b231c103 18513 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18514 }
c9602061 18515 break;
7a387fff
TS
18516 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18517 case OPC_TNEI:
d9224450 18518 check_insn(ctx, ISA_MIPS2);
fecd2646 18519 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18520 gen_trap(ctx, op1, rs, -1, imm);
18521 break;
18522 case OPC_SYNCI:
d75c135e 18523 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18524 /* Break the TB to be able to sync copied instructions
18525 immediately */
18526 ctx->bstate = BS_STOP;
6af0bf9c 18527 break;
e45a93e2
JL
18528 case OPC_BPOSGE32: /* MIPS DSP branch */
18529#if defined(TARGET_MIPS64)
18530 case OPC_BPOSGE64:
18531#endif
18532 check_dsp(ctx);
b231c103 18533 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18534 break;
d4ea6acd
LA
18535#if defined(TARGET_MIPS64)
18536 case OPC_DAHI:
18537 check_insn(ctx, ISA_MIPS32R6);
18538 check_mips_64(ctx);
18539 if (rs != 0) {
18540 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18541 }
18542 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18543 break;
18544 case OPC_DATI:
18545 check_insn(ctx, ISA_MIPS32R6);
18546 check_mips_64(ctx);
18547 if (rs != 0) {
18548 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18549 }
18550 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18551 break;
18552#endif
6af0bf9c 18553 default: /* Invalid */
923617a3 18554 MIPS_INVAL("regimm");
6af0bf9c
FB
18555 generate_exception(ctx, EXCP_RI);
18556 break;
18557 }
18558 break;
7a387fff 18559 case OPC_CP0:
387a8fe5 18560 check_cp0_enabled(ctx);
7a387fff 18561 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18562 switch (op1) {
7a387fff
TS
18563 case OPC_MFC0:
18564 case OPC_MTC0:
ead9360e
TS
18565 case OPC_MFTR:
18566 case OPC_MTTR:
d26bc211 18567#if defined(TARGET_MIPS64)
7a387fff
TS
18568 case OPC_DMFC0:
18569 case OPC_DMTC0:
18570#endif
f1aa6320 18571#ifndef CONFIG_USER_ONLY
932e71cd 18572 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 18573#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18574 break;
18575 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 18576#ifndef CONFIG_USER_ONLY
932e71cd 18577 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 18578#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18579 break;
18580 case OPC_MFMC0:
8706c382 18581#ifndef CONFIG_USER_ONLY
932e71cd 18582 {
099e5b4d 18583 uint32_t op2;
35fbce2c 18584 TCGv t0 = tcg_temp_new();
6c5c1e20 18585
0eaef5aa 18586 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
18587 switch (op2) {
18588 case OPC_DMT:
d75c135e 18589 check_insn(ctx, ASE_MT);
9ed5726c 18590 gen_helper_dmt(t0);
35fbce2c 18591 gen_store_gpr(t0, rt);
6c5c1e20
TS
18592 break;
18593 case OPC_EMT:
d75c135e 18594 check_insn(ctx, ASE_MT);
9ed5726c 18595 gen_helper_emt(t0);
35fbce2c 18596 gen_store_gpr(t0, rt);
da80682b 18597 break;
6c5c1e20 18598 case OPC_DVPE:
d75c135e 18599 check_insn(ctx, ASE_MT);
895c2d04 18600 gen_helper_dvpe(t0, cpu_env);
35fbce2c 18601 gen_store_gpr(t0, rt);
6c5c1e20
TS
18602 break;
18603 case OPC_EVPE:
d75c135e 18604 check_insn(ctx, ASE_MT);
895c2d04 18605 gen_helper_evpe(t0, cpu_env);
35fbce2c 18606 gen_store_gpr(t0, rt);
6c5c1e20
TS
18607 break;
18608 case OPC_DI:
d75c135e 18609 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18610 save_cpu_state(ctx, 1);
895c2d04 18611 gen_helper_di(t0, cpu_env);
35fbce2c 18612 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18613 /* Stop translation as we may have switched
18614 the execution mode. */
6c5c1e20
TS
18615 ctx->bstate = BS_STOP;
18616 break;
18617 case OPC_EI:
d75c135e 18618 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18619 save_cpu_state(ctx, 1);
895c2d04 18620 gen_helper_ei(t0, cpu_env);
35fbce2c 18621 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18622 /* Stop translation as we may have switched
18623 the execution mode. */
6c5c1e20
TS
18624 ctx->bstate = BS_STOP;
18625 break;
18626 default: /* Invalid */
18627 MIPS_INVAL("mfmc0");
18628 generate_exception(ctx, EXCP_RI);
18629 break;
18630 }
6c5c1e20 18631 tcg_temp_free(t0);
7a387fff 18632 }
0eaef5aa 18633#endif /* !CONFIG_USER_ONLY */
6af0bf9c 18634 break;
7a387fff 18635 case OPC_RDPGPR:
d75c135e 18636 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18637 gen_load_srsgpr(rt, rd);
ead9360e 18638 break;
7a387fff 18639 case OPC_WRPGPR:
d75c135e 18640 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18641 gen_store_srsgpr(rt, rd);
38121543 18642 break;
6af0bf9c 18643 default:
923617a3 18644 MIPS_INVAL("cp0");
7a387fff 18645 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
18646 break;
18647 }
18648 break;
31837be3
YK
18649 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18650 if (ctx->insn_flags & ISA_MIPS32R6) {
18651 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18652 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18653 } else {
18654 /* OPC_ADDI */
18655 /* Arithmetic with immediate opcode */
18656 gen_arith_imm(ctx, op, rt, rs, imm);
18657 }
18658 break;
324d9e32 18659 case OPC_ADDIU:
d75c135e 18660 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18661 break;
324d9e32
AJ
18662 case OPC_SLTI: /* Set on less than with immediate opcode */
18663 case OPC_SLTIU:
d75c135e 18664 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
18665 break;
18666 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 18667 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
18668 case OPC_ORI:
18669 case OPC_XORI:
d75c135e 18670 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 18671 break;
7a387fff
TS
18672 case OPC_J ... OPC_JAL: /* Jump */
18673 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18674 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 18675 break;
31837be3
YK
18676 /* Branch */
18677 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18678 if (ctx->insn_flags & ISA_MIPS32R6) {
18679 if (rt == 0) {
18680 generate_exception(ctx, EXCP_RI);
18681 break;
18682 }
18683 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18684 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18685 } else {
18686 /* OPC_BLEZL */
b231c103 18687 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18688 }
18689 break;
18690 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18691 if (ctx->insn_flags & ISA_MIPS32R6) {
18692 if (rt == 0) {
18693 generate_exception(ctx, EXCP_RI);
18694 break;
18695 }
18696 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18697 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18698 } else {
18699 /* OPC_BGTZL */
b231c103 18700 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18701 }
18702 break;
18703 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18704 if (rt == 0) {
18705 /* OPC_BLEZ */
b231c103 18706 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18707 } else {
18708 check_insn(ctx, ISA_MIPS32R6);
18709 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18710 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18711 }
18712 break;
18713 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18714 if (rt == 0) {
18715 /* OPC_BGTZ */
b231c103 18716 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18717 } else {
18718 check_insn(ctx, ISA_MIPS32R6);
18719 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18720 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18721 }
18722 break;
18723 case OPC_BEQL:
18724 case OPC_BNEL:
d9224450 18725 check_insn(ctx, ISA_MIPS2);
fecd2646 18726 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18727 /* Fallthrough */
31837be3
YK
18728 case OPC_BEQ:
18729 case OPC_BNE:
b231c103 18730 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 18731 break;
d9224450
MR
18732 case OPC_LL: /* Load and stores */
18733 check_insn(ctx, ISA_MIPS2);
18734 /* Fallthrough */
18735 case OPC_LWL:
fecd2646
LA
18736 case OPC_LWR:
18737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18738 /* Fallthrough */
fecd2646
LA
18739 case OPC_LB ... OPC_LH:
18740 case OPC_LW ... OPC_LHU:
d75c135e 18741 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 18742 break;
fecd2646 18743 case OPC_SWL:
7a387fff 18744 case OPC_SWR:
fecd2646 18745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18746 /* fall through */
fecd2646
LA
18747 case OPC_SB ... OPC_SH:
18748 case OPC_SW:
5c13fdfd 18749 gen_st(ctx, op, rt, rs, imm);
7a387fff 18750 break;
d66c7132 18751 case OPC_SC:
d9224450 18752 check_insn(ctx, ISA_MIPS2);
4368b29a 18753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
18754 gen_st_cond(ctx, op, rt, rs, imm);
18755 break;
7a387fff 18756 case OPC_CACHE:
bf7910c6 18757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 18758 check_cp0_enabled(ctx);
d75c135e 18759 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 18760 /* Treat as NOP. */
34ae7b51 18761 break;
7a387fff 18762 case OPC_PREF:
bf7910c6 18763 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18764 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 18765 /* Treat as NOP. */
6af0bf9c 18766 break;
4ad40f36 18767
923617a3 18768 /* Floating point (COP1). */
7a387fff
TS
18769 case OPC_LWC1:
18770 case OPC_LDC1:
18771 case OPC_SWC1:
18772 case OPC_SDC1:
5ab5c041 18773 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
18774 break;
18775
7a387fff 18776 case OPC_CP1:
5692c6e1
YK
18777 op1 = MASK_CP1(ctx->opcode);
18778
18779 switch (op1) {
18780 case OPC_MFHC1:
18781 case OPC_MTHC1:
5e755519 18782 check_cp1_enabled(ctx);
5692c6e1
YK
18783 check_insn(ctx, ISA_MIPS32R2);
18784 case OPC_MFC1:
18785 case OPC_CFC1:
18786 case OPC_MTC1:
18787 case OPC_CTC1:
18788 check_cp1_enabled(ctx);
18789 gen_cp1(ctx, op1, rt, rd);
18790 break;
d26bc211 18791#if defined(TARGET_MIPS64)
5692c6e1
YK
18792 case OPC_DMFC1:
18793 case OPC_DMTC1:
18794 check_cp1_enabled(ctx);
18795 check_insn(ctx, ISA_MIPS3);
d9224450 18796 check_mips_64(ctx);
5692c6e1
YK
18797 gen_cp1(ctx, op1, rt, rd);
18798 break;
e189e748 18799#endif
5692c6e1
YK
18800 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18801 check_cp1_enabled(ctx);
18802 if (ctx->insn_flags & ISA_MIPS32R6) {
18803 /* OPC_BC1EQZ */
31837be3
YK
18804 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18805 rt, imm << 2);
5692c6e1
YK
18806 } else {
18807 /* OPC_BC1ANY2 */
b8aa4598 18808 check_cop1x(ctx);
d75c135e 18809 check_insn(ctx, ASE_MIPS3D);
d75c135e 18810 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 18811 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
18812 }
18813 break;
18814 case OPC_BC1NEZ:
18815 check_cp1_enabled(ctx);
18816 check_insn(ctx, ISA_MIPS32R6);
18817 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18818 rt, imm << 2);
18819 break;
18820 case OPC_BC1ANY4:
18821 check_cp1_enabled(ctx);
18822 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18823 check_cop1x(ctx);
18824 check_insn(ctx, ASE_MIPS3D);
18825 /* fall through */
18826 case OPC_BC1:
18827 check_cp1_enabled(ctx);
18828 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18829 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18830 (rt >> 2) & 0x7, imm << 2);
18831 break;
18832 case OPC_PS_FMT:
18833 check_cp1_enabled(ctx);
18834 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18835 /* fall through */
5692c6e1
YK
18836 case OPC_S_FMT:
18837 case OPC_D_FMT:
18838 check_cp1_enabled(ctx);
18839 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18840 (imm >> 8) & 0x7);
18841 break;
18842 case OPC_W_FMT:
18843 case OPC_L_FMT:
18844 {
18845 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18846 check_cp1_enabled(ctx);
18847 if (ctx->insn_flags & ISA_MIPS32R6) {
18848 switch (r6_op) {
18849 case R6_OPC_CMP_AF_S:
18850 case R6_OPC_CMP_UN_S:
18851 case R6_OPC_CMP_EQ_S:
18852 case R6_OPC_CMP_UEQ_S:
18853 case R6_OPC_CMP_LT_S:
18854 case R6_OPC_CMP_ULT_S:
18855 case R6_OPC_CMP_LE_S:
18856 case R6_OPC_CMP_ULE_S:
18857 case R6_OPC_CMP_SAF_S:
18858 case R6_OPC_CMP_SUN_S:
18859 case R6_OPC_CMP_SEQ_S:
18860 case R6_OPC_CMP_SEUQ_S:
18861 case R6_OPC_CMP_SLT_S:
18862 case R6_OPC_CMP_SULT_S:
18863 case R6_OPC_CMP_SLE_S:
18864 case R6_OPC_CMP_SULE_S:
18865 case R6_OPC_CMP_OR_S:
18866 case R6_OPC_CMP_UNE_S:
18867 case R6_OPC_CMP_NE_S:
18868 case R6_OPC_CMP_SOR_S:
18869 case R6_OPC_CMP_SUNE_S:
18870 case R6_OPC_CMP_SNE_S:
18871 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18872 break;
18873 case R6_OPC_CMP_AF_D:
18874 case R6_OPC_CMP_UN_D:
18875 case R6_OPC_CMP_EQ_D:
18876 case R6_OPC_CMP_UEQ_D:
18877 case R6_OPC_CMP_LT_D:
18878 case R6_OPC_CMP_ULT_D:
18879 case R6_OPC_CMP_LE_D:
18880 case R6_OPC_CMP_ULE_D:
18881 case R6_OPC_CMP_SAF_D:
18882 case R6_OPC_CMP_SUN_D:
18883 case R6_OPC_CMP_SEQ_D:
18884 case R6_OPC_CMP_SEUQ_D:
18885 case R6_OPC_CMP_SLT_D:
18886 case R6_OPC_CMP_SULT_D:
18887 case R6_OPC_CMP_SLE_D:
18888 case R6_OPC_CMP_SULE_D:
18889 case R6_OPC_CMP_OR_D:
18890 case R6_OPC_CMP_UNE_D:
18891 case R6_OPC_CMP_NE_D:
18892 case R6_OPC_CMP_SOR_D:
18893 case R6_OPC_CMP_SUNE_D:
18894 case R6_OPC_CMP_SNE_D:
18895 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18896 break;
18897 default:
d2bfa6e6
MR
18898 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
18899 rt, rd, sa, (imm >> 8) & 0x7);
18900
5692c6e1 18901 break;
3f493883 18902 }
5692c6e1
YK
18903 } else {
18904 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18905 (imm >> 8) & 0x7);
36d23958 18906 }
5692c6e1
YK
18907 break;
18908 }
18909 case OPC_BZ_V:
18910 case OPC_BNZ_V:
18911 case OPC_BZ_B:
18912 case OPC_BZ_H:
18913 case OPC_BZ_W:
18914 case OPC_BZ_D:
18915 case OPC_BNZ_B:
18916 case OPC_BNZ_H:
18917 case OPC_BNZ_W:
18918 case OPC_BNZ_D:
18919 check_insn(ctx, ASE_MSA);
18920 gen_msa_branch(env, ctx, op1);
18921 break;
18922 default:
18923 MIPS_INVAL("cp1");
18924 generate_exception(ctx, EXCP_RI);
18925 break;
6ea83fed 18926 }
4ad40f36
FB
18927 break;
18928
31837be3
YK
18929 /* Compact branches [R6] and COP2 [non-R6] */
18930 case OPC_BC: /* OPC_LWC2 */
18931 case OPC_BALC: /* OPC_SWC2 */
18932 if (ctx->insn_flags & ISA_MIPS32R6) {
18933 /* OPC_BC, OPC_BALC */
18934 gen_compute_compact_branch(ctx, op, 0, 0,
18935 sextract32(ctx->opcode << 2, 0, 28));
18936 } else {
18937 /* OPC_LWC2, OPC_SWC2 */
18938 /* COP2: Not implemented. */
18939 generate_exception_err(ctx, EXCP_CpU, 2);
18940 }
18941 break;
18942 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18943 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
18944 if (ctx->insn_flags & ISA_MIPS32R6) {
18945 if (rs != 0) {
18946 /* OPC_BEQZC, OPC_BNEZC */
18947 gen_compute_compact_branch(ctx, op, rs, 0,
18948 sextract32(ctx->opcode << 2, 0, 23));
18949 } else {
18950 /* OPC_JIC, OPC_JIALC */
18951 gen_compute_compact_branch(ctx, op, 0, rt, imm);
18952 }
18953 } else {
18954 /* OPC_LWC2, OPC_SWC2 */
18955 /* COP2: Not implemented. */
18956 generate_exception_err(ctx, EXCP_CpU, 2);
18957 }
4ad40f36 18958 break;
bd277fa1 18959 case OPC_CP2:
d75c135e 18960 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
18961 /* Note that these instructions use different fields. */
18962 gen_loongson_multimedia(ctx, sa, rd, rt);
18963 break;
4ad40f36 18964
7a387fff 18965 case OPC_CP3:
fecd2646 18966 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 18967 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 18968 check_cp1_enabled(ctx);
36d23958
TS
18969 op1 = MASK_CP3(ctx->opcode);
18970 switch (op1) {
d9224450
MR
18971 case OPC_LUXC1:
18972 case OPC_SUXC1:
18973 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
18974 /* Fallthrough */
5a5012ec
TS
18975 case OPC_LWXC1:
18976 case OPC_LDXC1:
5a5012ec
TS
18977 case OPC_SWXC1:
18978 case OPC_SDXC1:
d9224450 18979 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 18980 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 18981 break;
e0c84da7 18982 case OPC_PREFX:
d9224450 18983 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 18984 /* Treat as NOP. */
e0c84da7 18985 break;
5a5012ec 18986 case OPC_ALNV_PS:
d9224450
MR
18987 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
18988 /* Fallthrough */
5a5012ec
TS
18989 case OPC_MADD_S:
18990 case OPC_MADD_D:
18991 case OPC_MADD_PS:
18992 case OPC_MSUB_S:
18993 case OPC_MSUB_D:
18994 case OPC_MSUB_PS:
18995 case OPC_NMADD_S:
18996 case OPC_NMADD_D:
18997 case OPC_NMADD_PS:
18998 case OPC_NMSUB_S:
18999 case OPC_NMSUB_D:
19000 case OPC_NMSUB_PS:
d9224450 19001 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19002 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19003 break;
36d23958 19004 default:
923617a3 19005 MIPS_INVAL("cp3");
e397ee33 19006 generate_exception (ctx, EXCP_RI);
36d23958
TS
19007 break;
19008 }
19009 } else {
e397ee33 19010 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19011 }
4ad40f36
FB
19012 break;
19013
d26bc211 19014#if defined(TARGET_MIPS64)
7a387fff 19015 /* MIPS64 opcodes */
7a387fff 19016 case OPC_LDL ... OPC_LDR:
bf7910c6 19017 case OPC_LLD:
fecd2646 19018 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19019 /* fall through */
fecd2646 19020 case OPC_LWU:
7a387fff 19021 case OPC_LD:
d75c135e 19022 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19023 check_mips_64(ctx);
d75c135e 19024 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19025 break;
19026 case OPC_SDL ... OPC_SDR:
fecd2646 19027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19028 /* fall through */
7a387fff 19029 case OPC_SD:
d75c135e 19030 check_insn(ctx, ISA_MIPS3);
e189e748 19031 check_mips_64(ctx);
5c13fdfd 19032 gen_st(ctx, op, rt, rs, imm);
7a387fff 19033 break;
d66c7132 19034 case OPC_SCD:
bf7910c6 19035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19036 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19037 check_mips_64(ctx);
19038 gen_st_cond(ctx, op, rt, rs, imm);
19039 break;
31837be3
YK
19040 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19041 if (ctx->insn_flags & ISA_MIPS32R6) {
19042 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19043 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19044 } else {
19045 /* OPC_DADDI */
19046 check_insn(ctx, ISA_MIPS3);
19047 check_mips_64(ctx);
19048 gen_arith_imm(ctx, op, rt, rs, imm);
19049 }
19050 break;
324d9e32 19051 case OPC_DADDIU:
d75c135e 19052 check_insn(ctx, ISA_MIPS3);
e189e748 19053 check_mips_64(ctx);
d75c135e 19054 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19055 break;
31837be3
YK
19056#else
19057 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19058 if (ctx->insn_flags & ISA_MIPS32R6) {
19059 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19060 } else {
19061 MIPS_INVAL("major opcode");
19062 generate_exception(ctx, EXCP_RI);
19063 }
19064 break;
6af0bf9c 19065#endif
d4ea6acd
LA
19066 case OPC_DAUI: /* OPC_JALX */
19067 if (ctx->insn_flags & ISA_MIPS32R6) {
19068#if defined(TARGET_MIPS64)
19069 /* OPC_DAUI */
19070 check_mips_64(ctx);
19071 if (rt != 0) {
19072 TCGv t0 = tcg_temp_new();
19073 gen_load_gpr(t0, rs);
19074 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19075 tcg_temp_free(t0);
19076 }
19077 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19078#else
19079 generate_exception(ctx, EXCP_RI);
19080 MIPS_INVAL("major opcode");
19081#endif
19082 } else {
19083 /* OPC_JALX */
19084 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19085 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19086 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19087 }
364d4831 19088 break;
4c789546 19089 case OPC_MSA: /* OPC_MDMX */
7a387fff 19090 /* MDMX: Not implemented. */
4c789546 19091 gen_msa(env, ctx);
d4ea6acd
LA
19092 break;
19093 case OPC_PCREL:
19094 check_insn(ctx, ISA_MIPS32R6);
19095 gen_pcrel(ctx, rs, imm);
19096 break;
6af0bf9c 19097 default: /* Invalid */
923617a3 19098 MIPS_INVAL("major opcode");
6af0bf9c
FB
19099 generate_exception(ctx, EXCP_RI);
19100 break;
19101 }
6af0bf9c
FB
19102}
19103
2cfc5f17 19104static inline void
6429db34
AF
19105gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19106 bool search_pc)
6af0bf9c 19107{
ed2803da 19108 CPUState *cs = CPU(cpu);
6429db34 19109 CPUMIPSState *env = &cpu->env;
278d0702 19110 DisasContext ctx;
6af0bf9c 19111 target_ulong pc_start;
fe237291 19112 target_ulong next_page_start;
a1d1bb31 19113 CPUBreakpoint *bp;
6af0bf9c 19114 int j, lj = -1;
2e70f6ef
PB
19115 int num_insns;
19116 int max_insns;
c9602061 19117 int insn_bytes;
339cd2a8 19118 int is_slot;
6af0bf9c 19119
93fcfe39
AL
19120 if (search_pc)
19121 qemu_log("search pc %d\n", search_pc);
4ad40f36 19122
6af0bf9c 19123 pc_start = tb->pc;
fe237291 19124 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19125 ctx.pc = pc_start;
4ad40f36 19126 ctx.saved_pc = -1;
ed2803da 19127 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19128 ctx.insn_flags = env->insn_flags;
5ab5c041 19129 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19130 ctx.tb = tb;
19131 ctx.bstate = BS_NONE;
e98c0d17 19132 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19133 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19134 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19135 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19136 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 19137 /* Restore delay slot state from the tb context. */
c068688b 19138 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19139 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
fd4a04eb 19140 restore_cpu_state(env, &ctx);
932e71cd 19141#ifdef CONFIG_USER_ONLY
0eaef5aa 19142 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19143#else
0eaef5aa 19144 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19145#endif
2e70f6ef
PB
19146 num_insns = 0;
19147 max_insns = tb->cflags & CF_COUNT_MASK;
19148 if (max_insns == 0)
19149 max_insns = CF_COUNT_MASK;
d12d51d5 19150 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19151 gen_tb_start(tb);
faf7aaa9 19152 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19153 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19154 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19155 if (bp->pc == ctx.pc) {
278d0702 19156 save_cpu_state(&ctx, 1);
4ad40f36 19157 ctx.bstate = BS_BRANCH;
895c2d04 19158 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
19159 /* Include the breakpoint location or the tb won't
19160 * be flushed when it must be. */
19161 ctx.pc += 4;
4ad40f36
FB
19162 goto done_generating;
19163 }
19164 }
19165 }
19166
6af0bf9c 19167 if (search_pc) {
fe700adb 19168 j = tcg_op_buf_count();
6af0bf9c
FB
19169 if (lj < j) {
19170 lj++;
19171 while (lj < j)
ab1103de 19172 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19173 }
25983cad 19174 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19175 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19176 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19177 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19178 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19179 }
2e70f6ef
PB
19180 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19181 gen_io_start();
c9602061 19182
339cd2a8 19183 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19184 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19185 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19186 insn_bytes = 4;
240ce26a 19187 decode_opc(env, &ctx);
d75c135e 19188 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19189 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19190 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19191 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19192 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19193 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
19194 } else {
19195 generate_exception(&ctx, EXCP_RI);
3c824109 19196 ctx.bstate = BS_STOP;
c9602061
NF
19197 break;
19198 }
31837be3 19199
b231c103 19200 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19201 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19202 MIPS_HFLAG_FBNSLOT))) {
19203 /* force to generate branch as there is neither delay nor
19204 forbidden slot */
19205 is_slot = 1;
b231c103
YK
19206 }
19207 }
339cd2a8 19208 if (is_slot) {
31837be3 19209 gen_branch(&ctx, insn_bytes);
c9602061
NF
19210 }
19211 ctx.pc += insn_bytes;
19212
2e70f6ef 19213 num_insns++;
4ad40f36 19214
7b270ef2
NF
19215 /* Execute a branch and its delay slot as a single instruction.
19216 This is what GDB expects and is consistent with what the
19217 hardware does (e.g. if a delay slot instruction faults, the
19218 reported PC is the PC of the branch). */
ed2803da 19219 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19220 break;
ed2803da 19221 }
4ad40f36 19222
fe237291 19223 if (ctx.pc >= next_page_start) {
6af0bf9c 19224 break;
fe237291 19225 }
4ad40f36 19226
fe700adb 19227 if (tcg_op_buf_full()) {
faf7aaa9 19228 break;
efd7f486 19229 }
faf7aaa9 19230
2e70f6ef
PB
19231 if (num_insns >= max_insns)
19232 break;
1b530a6d
AJ
19233
19234 if (singlestep)
19235 break;
6af0bf9c 19236 }
ed2803da 19237 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19238 gen_io_end();
ed2803da
AF
19239 }
19240 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19241 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 19242 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 19243 } else {
6958549d 19244 switch (ctx.bstate) {
16c00cb2 19245 case BS_STOP:
df1561e2
TS
19246 gen_goto_tb(&ctx, 0, ctx.pc);
19247 break;
16c00cb2 19248 case BS_NONE:
278d0702 19249 save_cpu_state(&ctx, 0);
16c00cb2
TS
19250 gen_goto_tb(&ctx, 0, ctx.pc);
19251 break;
5a5012ec 19252 case BS_EXCP:
57fec1fe 19253 tcg_gen_exit_tb(0);
16c00cb2 19254 break;
5a5012ec
TS
19255 case BS_BRANCH:
19256 default:
19257 break;
6958549d 19258 }
6af0bf9c 19259 }
4ad40f36 19260done_generating:
806f352d 19261 gen_tb_end(tb, num_insns);
0a7df5da 19262
6af0bf9c 19263 if (search_pc) {
fe700adb 19264 j = tcg_op_buf_count();
6af0bf9c
FB
19265 lj++;
19266 while (lj <= j)
ab1103de 19267 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19268 } else {
19269 tb->size = ctx.pc - pc_start;
2e70f6ef 19270 tb->icount = num_insns;
6af0bf9c
FB
19271 }
19272#ifdef DEBUG_DISAS
d12d51d5 19273 LOG_DISAS("\n");
8fec2b8c 19274 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19275 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 19276 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19277 qemu_log("\n");
6af0bf9c
FB
19278 }
19279#endif
6af0bf9c
FB
19280}
19281
7db13fae 19282void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19283{
6429db34 19284 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19285}
19286
7db13fae 19287void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19288{
6429db34 19289 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19290}
19291
7db13fae 19292static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19293 int flags)
6ea83fed
FB
19294{
19295 int i;
5e755519 19296 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19297
2a5612e6
SW
19298#define printfpr(fp) \
19299 do { \
19300 if (is_fpu64) \
19301 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19302 " fd:%13g fs:%13g psu: %13g\n", \
19303 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19304 (double)(fp)->fd, \
19305 (double)(fp)->fs[FP_ENDIAN_IDX], \
19306 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19307 else { \
19308 fpr_t tmp; \
19309 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19310 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19311 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19312 " fd:%13g fs:%13g psu:%13g\n", \
19313 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19314 (double)tmp.fd, \
19315 (double)tmp.fs[FP_ENDIAN_IDX], \
19316 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19317 } \
6ea83fed
FB
19318 } while(0)
19319
5a5012ec 19320
9a78eead
SW
19321 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19322 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19323 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19324 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19325 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19326 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19327 }
19328
19329#undef printfpr
19330}
19331
d26bc211 19332#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 19333/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 19334 sign-extended values on 64bit machines. */
c570fd16
TS
19335
19336#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19337
8706c382 19338static void
7db13fae 19339cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 19340 fprintf_function cpu_fprintf,
8706c382 19341 int flags)
c570fd16
TS
19342{
19343 int i;
19344
b5dc7732
TS
19345 if (!SIGN_EXT_P(env->active_tc.PC))
19346 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19347 if (!SIGN_EXT_P(env->active_tc.HI[0]))
19348 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19349 if (!SIGN_EXT_P(env->active_tc.LO[0]))
19350 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 19351 if (!SIGN_EXT_P(env->btarget))
3594c774 19352 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
19353
19354 for (i = 0; i < 32; i++) {
b5dc7732
TS
19355 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19356 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
19357 }
19358
19359 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 19360 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
19361 if (!SIGN_EXT_P(env->lladdr))
19362 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
19363}
19364#endif
19365
878096ee
AF
19366void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19367 int flags)
6af0bf9c 19368{
878096ee
AF
19369 MIPSCPU *cpu = MIPS_CPU(cs);
19370 CPUMIPSState *env = &cpu->env;
6af0bf9c 19371 int i;
3b46e624 19372
a7200c9f
SW
19373 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19374 " LO=0x" TARGET_FMT_lx " ds %04x "
19375 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19376 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19377 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19378 for (i = 0; i < 32; i++) {
19379 if ((i & 3) == 0)
19380 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19381 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19382 if ((i & 3) == 3)
19383 cpu_fprintf(f, "\n");
19384 }
568b600d 19385
3594c774 19386 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19387 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 19388 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 19389 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19390 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19391 env->CP0_Config2, env->CP0_Config3);
19392 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19393 env->CP0_Config4, env->CP0_Config5);
5e755519 19394 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19395 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 19396#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
19397 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19398#endif
6af0bf9c
FB
19399}
19400
78ce64f4 19401void mips_tcg_init(void)
39454628 19402{
f01be154 19403 int i;
39454628
TS
19404 static int inited;
19405
19406 /* Initialize various static tables. */
19407 if (inited)
6958549d 19408 return;
39454628 19409
a7812ae4 19410 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19411 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19412 for (i = 1; i < 32; i++)
a7812ae4 19413 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19414 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19415 regnames[i]);
d73ee8a2 19416
863f264d
YK
19417 for (i = 0; i < 32; i++) {
19418 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19419 msa_wr_d[i * 2] =
19420 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19421 /* The scalar floating-point unit (FPU) registers are mapped on
19422 * the MSA vector registers. */
19423 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19424 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19425 msa_wr_d[i * 2 + 1] =
19426 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19427 }
19428
a7812ae4 19429 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19430 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19431 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19432 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19433 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19434 regnames_HI[i]);
a7812ae4 19435 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19436 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19437 regnames_LO[i]);
4b2eb8d2 19438 }
a7812ae4 19439 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19440 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19441 "DSPControl");
1ba74fb8 19442 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19443 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19444 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19445 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19446 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19447 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19448
a7812ae4 19449 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19450 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19451 "fcr0");
19452 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19453 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19454 "fcr31");
39454628
TS
19455
19456 inited = 1;
19457}
19458
aaed909a
FB
19459#include "translate_init.c"
19460
30bf942d 19461MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19462{
0f71a709 19463 MIPSCPU *cpu;
6af0bf9c 19464 CPUMIPSState *env;
c227f099 19465 const mips_def_t *def;
6af0bf9c 19466
aaed909a
FB
19467 def = cpu_mips_find_by_name(cpu_model);
19468 if (!def)
19469 return NULL;
0f71a709
AF
19470 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19471 env = &cpu->env;
aaed909a
FB
19472 env->cpu_model = def;
19473
51cc2e78
BS
19474#ifndef CONFIG_USER_ONLY
19475 mmu_init(env, def);
19476#endif
19477 fpu_init(env, def);
19478 mvp_init(env, def);
c1caf1d9
AF
19479
19480 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19481
30bf942d 19482 return cpu;
6ae81775
TS
19483}
19484
1bba0dc9 19485void cpu_state_reset(CPUMIPSState *env)
6ae81775 19486{
55e5c285
AF
19487 MIPSCPU *cpu = mips_env_get_cpu(env);
19488 CPUState *cs = CPU(cpu);
6ae81775 19489
51cc2e78
BS
19490 /* Reset registers to their default values */
19491 env->CP0_PRid = env->cpu_model->CP0_PRid;
19492 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19493#ifdef TARGET_WORDS_BIGENDIAN
19494 env->CP0_Config0 |= (1 << CP0C0_BE);
19495#endif
19496 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19497 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19498 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19499 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19500 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19501 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19502 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19503 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19504 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19505 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19506 << env->cpu_model->CP0_LLAddr_shift;
19507 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19508 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19509 env->CCRes = env->cpu_model->CCRes;
19510 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19511 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19512 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19513 env->current_tc = 0;
19514 env->SEGBITS = env->cpu_model->SEGBITS;
19515 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19516#if defined(TARGET_MIPS64)
19517 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19518 env->SEGMask |= 3ULL << 62;
19519 }
19520#endif
19521 env->PABITS = env->cpu_model->PABITS;
19522 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19523 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19524 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19525 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19526 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19527 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19528 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19529 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19530 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19531 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19532 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19533 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19534 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19535 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19536 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19537 env->insn_flags = env->cpu_model->insn_flags;
19538
0eaef5aa 19539#if defined(CONFIG_USER_ONLY)
03e6e501 19540 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19541# ifdef TARGET_MIPS64
19542 /* Enable 64-bit register mode. */
19543 env->CP0_Status |= (1 << CP0St_PX);
19544# endif
19545# ifdef TARGET_ABI_MIPSN64
19546 /* Enable 64-bit address mode. */
19547 env->CP0_Status |= (1 << CP0St_UX);
19548# endif
94159135
MI
19549 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19550 hardware registers. */
19551 env->CP0_HWREna |= 0x0000000F;
91a75935 19552 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19553 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19554 }
6f0af304
PJ
19555 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19556 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19557 }
4d66261f
PJ
19558# if defined(TARGET_MIPS64)
19559 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19560 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19561 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19562 env->CP0_Status |= (1 << CP0St_FR);
19563 }
4d66261f 19564# endif
932e71cd
AJ
19565#else
19566 if (env->hflags & MIPS_HFLAG_BMASK) {
19567 /* If the exception was raised from a delay slot,
19568 come back to the jump. */
c3577479
MR
19569 env->CP0_ErrorEPC = (env->active_tc.PC
19570 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 19571 } else {
932e71cd
AJ
19572 env->CP0_ErrorEPC = env->active_tc.PC;
19573 }
19574 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19575 env->CP0_Random = env->tlb->nb_tlb - 1;
19576 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19577 env->CP0_Wired = 0;
0a2672b7
JH
19578 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19579 if (kvm_enabled()) {
19580 env->CP0_EBase |= 0x40000000;
19581 } else {
19582 env->CP0_EBase |= 0x80000000;
19583 }
932e71cd
AJ
19584 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19585 /* vectored interrupts not implemented, timer on int 7,
19586 no performance counters. */
19587 env->CP0_IntCtl = 0xe0000000;
19588 {
19589 int i;
19590
19591 for (i = 0; i < 7; i++) {
19592 env->CP0_WatchLo[i] = 0;
19593 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 19594 }
932e71cd
AJ
19595 env->CP0_WatchLo[7] = 0;
19596 env->CP0_WatchHi[7] = 0;
fd88b6ab 19597 }
932e71cd
AJ
19598 /* Count register increments in debug mode, EJTAG version 1 */
19599 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 19600
4b69c7e2
JH
19601 cpu_mips_store_count(env, 1);
19602
9e56e756
EI
19603 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19604 int i;
19605
19606 /* Only TC0 on VPE 0 starts as active. */
19607 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 19608 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
19609 env->tcs[i].CP0_TCHalt = 1;
19610 }
19611 env->active_tc.CP0_TCHalt = 1;
259186a7 19612 cs->halted = 1;
9e56e756 19613
55e5c285 19614 if (cs->cpu_index == 0) {
9e56e756
EI
19615 /* VPE0 starts up enabled. */
19616 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19617 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19618
19619 /* TC0 starts up unhalted. */
259186a7 19620 cs->halted = 0;
9e56e756
EI
19621 env->active_tc.CP0_TCHalt = 0;
19622 env->tcs[0].CP0_TCHalt = 0;
19623 /* With thread 0 active. */
19624 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19625 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19626 }
19627 }
51cc2e78 19628#endif
ddc584bd
LA
19629 if ((env->insn_flags & ISA_MIPS32R6) &&
19630 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19631 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19632 env->CP0_Status |= (1 << CP0St_FR);
19633 }
19634
863f264d
YK
19635 /* MSA */
19636 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19637 msa_reset(env);
19638 }
19639
03e6e501 19640 compute_hflags(env);
bb962386
MR
19641 restore_rounding_mode(env);
19642 restore_flush_mode(env);
27103424 19643 cs->exception_index = EXCP_NONE;
6af0bf9c 19644}
d2856f1a 19645
7db13fae 19646void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 19647{
25983cad 19648 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
19649 env->hflags &= ~MIPS_HFLAG_BMASK;
19650 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
19651 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19652 case MIPS_HFLAG_BR:
19653 break;
19654 case MIPS_HFLAG_BC:
19655 case MIPS_HFLAG_BL:
19656 case MIPS_HFLAG_B:
19657 env->btarget = gen_opc_btarget[pc_pos];
19658 break;
19659 }
d2856f1a 19660}
This page took 4.208294 seconds and 4 git commands to generate.