]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: Misaligned memory accesses for MSA
[mirror_qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
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;
be3a8c53 1417 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1418 uint32_t hflags, saved_hflags;
1419 int bstate;
1420 target_ulong btarget;
d279279e 1421 bool ulri;
e98c0d17 1422 int kscrexist;
7207c7f9 1423 bool rxi;
9456c2fb 1424 int ie;
aea14095
LA
1425 bool bi;
1426 bool bp;
8e9ade68
TS
1427} DisasContext;
1428
1429enum {
1430 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1431 * exception condition */
8e9ade68
TS
1432 BS_STOP = 1, /* We want to stop translation for any reason */
1433 BS_BRANCH = 2, /* We reached a branch condition */
1434 BS_EXCP = 3, /* We reached an exception condition */
1435};
1436
d73ee8a2
RH
1437static const char * const regnames[] = {
1438 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1439 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1440 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1441 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1442};
6af0bf9c 1443
d73ee8a2
RH
1444static const char * const regnames_HI[] = {
1445 "HI0", "HI1", "HI2", "HI3",
1446};
4b2eb8d2 1447
d73ee8a2
RH
1448static const char * const regnames_LO[] = {
1449 "LO0", "LO1", "LO2", "LO3",
1450};
4b2eb8d2 1451
d73ee8a2
RH
1452static const char * const fregnames[] = {
1453 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1454 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1455 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1456 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1457};
958fb4a9 1458
863f264d
YK
1459static const char * const msaregnames[] = {
1460 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1461 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1462 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1463 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1464 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1465 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1466 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1467 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1468 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1469 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1470 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1471 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1472 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1473 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1474 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1475 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1476};
1477
fb7729e2
RH
1478#define MIPS_DEBUG(fmt, ...) \
1479 do { \
1480 if (MIPS_DEBUG_DISAS) { \
1481 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1482 TARGET_FMT_lx ": %08x " fmt "\n", \
1483 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1484 } \
1485 } while (0)
1486
1487#define LOG_DISAS(...) \
1488 do { \
1489 if (MIPS_DEBUG_DISAS) { \
1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1491 } \
1492 } while (0)
958fb4a9 1493
8e9ade68 1494#define MIPS_INVAL(op) \
8e9ade68 1495 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1496 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1497
8e9ade68
TS
1498/* General purpose registers moves. */
1499static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1500{
8e9ade68
TS
1501 if (reg == 0)
1502 tcg_gen_movi_tl(t, 0);
1503 else
4b2eb8d2 1504 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1505}
1506
8e9ade68 1507static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1508{
8e9ade68 1509 if (reg != 0)
4b2eb8d2 1510 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1511}
1512
8e9ade68 1513/* Moves to/from shadow registers. */
be24bb4f 1514static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1515{
d9bea114 1516 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1517
1518 if (from == 0)
d9bea114 1519 tcg_gen_movi_tl(t0, 0);
8e9ade68 1520 else {
d9bea114 1521 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1522 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1523
7db13fae 1524 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1525 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1526 tcg_gen_andi_i32(t2, t2, 0xf);
1527 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1528 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1529 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1530
d9bea114 1531 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1532 tcg_temp_free_ptr(addr);
d9bea114 1533 tcg_temp_free_i32(t2);
8e9ade68 1534 }
d9bea114
AJ
1535 gen_store_gpr(t0, to);
1536 tcg_temp_free(t0);
aaa9128a
TS
1537}
1538
be24bb4f 1539static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1540{
be24bb4f 1541 if (to != 0) {
d9bea114
AJ
1542 TCGv t0 = tcg_temp_new();
1543 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1544 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1545
d9bea114 1546 gen_load_gpr(t0, from);
7db13fae 1547 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1548 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1549 tcg_gen_andi_i32(t2, t2, 0xf);
1550 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1551 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1552 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1553
d9bea114 1554 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1555 tcg_temp_free_ptr(addr);
d9bea114
AJ
1556 tcg_temp_free_i32(t2);
1557 tcg_temp_free(t0);
8e9ade68 1558 }
aaa9128a
TS
1559}
1560
eab9944c
LA
1561/* Tests */
1562static inline void gen_save_pc(target_ulong pc)
1563{
1564 tcg_gen_movi_tl(cpu_PC, pc);
1565}
1566
1567static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1568{
1569 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1570 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1571 gen_save_pc(ctx->pc);
1572 ctx->saved_pc = ctx->pc;
1573 }
1574 if (ctx->hflags != ctx->saved_hflags) {
1575 tcg_gen_movi_i32(hflags, ctx->hflags);
1576 ctx->saved_hflags = ctx->hflags;
1577 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1578 case MIPS_HFLAG_BR:
1579 break;
1580 case MIPS_HFLAG_BC:
1581 case MIPS_HFLAG_BL:
1582 case MIPS_HFLAG_B:
1583 tcg_gen_movi_tl(btarget, ctx->btarget);
1584 break;
1585 }
1586 }
1587}
1588
1589static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1590{
1591 ctx->saved_hflags = ctx->hflags;
1592 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1593 case MIPS_HFLAG_BR:
1594 break;
1595 case MIPS_HFLAG_BC:
1596 case MIPS_HFLAG_BL:
1597 case MIPS_HFLAG_B:
1598 ctx->btarget = env->btarget;
1599 break;
1600 }
1601}
1602
1603static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1604{
1605 TCGv_i32 texcp = tcg_const_i32(excp);
1606 TCGv_i32 terr = tcg_const_i32(err);
1607 save_cpu_state(ctx, 1);
1608 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1609 tcg_temp_free_i32(terr);
1610 tcg_temp_free_i32(texcp);
1611}
1612
1613static inline void generate_exception(DisasContext *ctx, int excp)
1614{
1615 save_cpu_state(ctx, 1);
1616 gen_helper_0e0i(raise_exception, excp);
1617}
1618
aaa9128a 1619/* Floating point register moves. */
7c979afd 1620static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1621{
7c979afd
LA
1622 if (ctx->hflags & MIPS_HFLAG_FRE) {
1623 generate_exception(ctx, EXCP_RI);
1624 }
d73ee8a2 1625 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1626}
1627
7c979afd 1628static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1629{
7c979afd
LA
1630 TCGv_i64 t64;
1631 if (ctx->hflags & MIPS_HFLAG_FRE) {
1632 generate_exception(ctx, EXCP_RI);
1633 }
1634 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1635 tcg_gen_extu_i32_i64(t64, t);
1636 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1637 tcg_temp_free_i64(t64);
6d066274
AJ
1638}
1639
7f6613ce 1640static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1641{
7f6613ce
PJ
1642 if (ctx->hflags & MIPS_HFLAG_F64) {
1643 TCGv_i64 t64 = tcg_temp_new_i64();
1644 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1645 tcg_gen_trunc_i64_i32(t, t64);
1646 tcg_temp_free_i64(t64);
1647 } else {
7c979afd 1648 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1649 }
6d066274
AJ
1650}
1651
7f6613ce 1652static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1653{
7f6613ce
PJ
1654 if (ctx->hflags & MIPS_HFLAG_F64) {
1655 TCGv_i64 t64 = tcg_temp_new_i64();
1656 tcg_gen_extu_i32_i64(t64, t);
1657 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1658 tcg_temp_free_i64(t64);
1659 } else {
7c979afd 1660 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1661 }
aa0bf00b 1662}
6ea83fed 1663
d73ee8a2 1664static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1665{
f364515c 1666 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1667 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1668 } else {
d73ee8a2 1669 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1670 }
1671}
6ea83fed 1672
d73ee8a2 1673static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1674{
f364515c 1675 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1676 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1677 } else {
d73ee8a2
RH
1678 TCGv_i64 t0;
1679 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1680 t0 = tcg_temp_new_i64();
6d066274 1681 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1682 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1683 tcg_temp_free_i64(t0);
aa0bf00b
TS
1684 }
1685}
6ea83fed 1686
d94536f4 1687static inline int get_fp_bit (int cc)
a16336e4 1688{
d94536f4
AJ
1689 if (cc)
1690 return 24 + cc;
1691 else
1692 return 23;
a16336e4
TS
1693}
1694
48d38ca5 1695/* Addresses computation */
941694d0 1696static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1697{
941694d0 1698 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1699
1700#if defined(TARGET_MIPS64)
01f72885 1701 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1702 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1703 }
1704#endif
4ad40f36
FB
1705}
1706
31837be3
YK
1707/* Addresses computation (translation time) */
1708static target_long addr_add(DisasContext *ctx, target_long base,
1709 target_long offset)
1710{
1711 target_long sum = base + offset;
1712
1713#if defined(TARGET_MIPS64)
1714 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1715 sum = (int32_t)sum;
1716 }
1717#endif
1718 return sum;
1719}
1720
356265ae 1721static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1722{
fe253235 1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1724 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1725}
1726
356265ae 1727static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1728{
fe253235 1729 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1730 generate_exception_err(ctx, EXCP_CpU, 1);
1731}
1732
b8aa4598
TS
1733/* Verify that the processor is running with COP1X instructions enabled.
1734 This is associated with the nabla symbol in the MIPS32 and MIPS64
1735 opcode tables. */
1736
356265ae 1737static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1738{
1739 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1740 generate_exception(ctx, EXCP_RI);
1741}
1742
1743/* Verify that the processor is running with 64-bit floating-point
1744 operations enabled. */
1745
356265ae 1746static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1747{
b8aa4598 1748 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1749 generate_exception(ctx, EXCP_RI);
1750}
1751
1752/*
1753 * Verify if floating point register is valid; an operation is not defined
1754 * if bit 0 of any register specification is set and the FR bit in the
1755 * Status register equals zero, since the register numbers specify an
1756 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1757 * in the Status register equals one, both even and odd register numbers
1758 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1759 *
1760 * Multiple 64 bit wide registers can be checked by calling
1761 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1762 */
356265ae 1763static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1764{
fe253235 1765 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1766 generate_exception(ctx, EXCP_RI);
1767}
1768
853c3240
JL
1769/* Verify that the processor is running with DSP instructions enabled.
1770 This is enabled by CP0 Status register MX(24) bit.
1771 */
1772
1773static inline void check_dsp(DisasContext *ctx)
1774{
1775 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1776 if (ctx->insn_flags & ASE_DSP) {
1777 generate_exception(ctx, EXCP_DSPDIS);
1778 } else {
1779 generate_exception(ctx, EXCP_RI);
1780 }
853c3240
JL
1781 }
1782}
1783
1784static inline void check_dspr2(DisasContext *ctx)
1785{
1786 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1787 if (ctx->insn_flags & ASE_DSP) {
1788 generate_exception(ctx, EXCP_DSPDIS);
1789 } else {
1790 generate_exception(ctx, EXCP_RI);
1791 }
853c3240
JL
1792 }
1793}
1794
3a95e3a7 1795/* This code generates a "reserved instruction" exception if the
e189e748 1796 CPU does not support the instruction set corresponding to flags. */
d75c135e 1797static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1798{
d75c135e 1799 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1800 generate_exception(ctx, EXCP_RI);
d75c135e 1801 }
3a95e3a7
TS
1802}
1803
fecd2646
LA
1804/* This code generates a "reserved instruction" exception if the
1805 CPU has corresponding flag set which indicates that the instruction
1806 has been removed. */
1807static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1808{
1809 if (unlikely(ctx->insn_flags & flags)) {
1810 generate_exception(ctx, EXCP_RI);
1811 }
1812}
1813
c7986fd6 1814#ifdef TARGET_MIPS64
e189e748
TS
1815/* This code generates a "reserved instruction" exception if 64-bit
1816 instructions are not enabled. */
356265ae 1817static inline void check_mips_64(DisasContext *ctx)
e189e748 1818{
fe253235 1819 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1820 generate_exception(ctx, EXCP_RI);
1821}
c7986fd6 1822#endif
e189e748 1823
8153667c
NF
1824/* Define small wrappers for gen_load_fpr* so that we have a uniform
1825 calling interface for 32 and 64-bit FPRs. No sense in changing
1826 all callers for gen_load_fpr32 when we need the CTX parameter for
1827 this one use. */
7c979afd 1828#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1829#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1830#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1831static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1832 int ft, int fs, int cc) \
1833{ \
1834 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1835 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1836 switch (ifmt) { \
1837 case FMT_PS: \
1838 check_cp1_64bitmode(ctx); \
1839 break; \
1840 case FMT_D: \
1841 if (abs) { \
1842 check_cop1x(ctx); \
1843 } \
1844 check_cp1_registers(ctx, fs | ft); \
1845 break; \
1846 case FMT_S: \
1847 if (abs) { \
1848 check_cop1x(ctx); \
1849 } \
1850 break; \
1851 } \
1852 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1853 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1854 switch (n) { \
895c2d04
BS
1855 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1856 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1857 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1858 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1859 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1860 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1861 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1862 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1863 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1864 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1865 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1866 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1867 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1868 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1869 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1870 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1871 default: abort(); \
1872 } \
1873 tcg_temp_free_i##bits (fp0); \
1874 tcg_temp_free_i##bits (fp1); \
1875}
1876
1877FOP_CONDS(, 0, d, FMT_D, 64)
1878FOP_CONDS(abs, 1, d, FMT_D, 64)
1879FOP_CONDS(, 0, s, FMT_S, 32)
1880FOP_CONDS(abs, 1, s, FMT_S, 32)
1881FOP_CONDS(, 0, ps, FMT_PS, 64)
1882FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1883#undef FOP_CONDS
3f493883
YK
1884
1885#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1886static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1887 int ft, int fs, int fd) \
1888{ \
1889 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1890 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1891 if (ifmt == FMT_D) { \
3f493883 1892 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1893 } \
1894 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1895 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1896 switch (n) { \
1897 case 0: \
1898 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 1: \
1901 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 2: \
1904 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 3: \
1907 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 4: \
1910 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 5: \
1913 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 6: \
1916 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 7: \
1919 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 8: \
1922 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 9: \
1925 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 10: \
1928 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 11: \
1931 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 12: \
1934 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 13: \
1937 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 case 14: \
1940 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1941 break; \
1942 case 15: \
1943 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1944 break; \
1945 case 17: \
1946 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 18: \
1949 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 19: \
1952 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 25: \
1955 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 26: \
1958 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 27: \
1961 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 default: \
1964 abort(); \
1965 } \
1966 STORE; \
1967 tcg_temp_free_i ## bits (fp0); \
1968 tcg_temp_free_i ## bits (fp1); \
1969}
1970
1971FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 1972FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 1973#undef FOP_CONDNS
8153667c
NF
1974#undef gen_ldcmp_fpr32
1975#undef gen_ldcmp_fpr64
1976
958fb4a9 1977/* load/store instructions. */
e7139c44 1978#ifdef CONFIG_USER_ONLY
d9bea114 1979#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1980static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1981{ \
1982 TCGv t0 = tcg_temp_new(); \
1983 tcg_gen_mov_tl(t0, arg1); \
1984 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1985 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1986 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1987 tcg_temp_free(t0); \
aaa9128a 1988}
e7139c44
AJ
1989#else
1990#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1991static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1992{ \
895c2d04 1993 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1994}
1995#endif
aaa9128a
TS
1996OP_LD_ATOMIC(ll,ld32s);
1997#if defined(TARGET_MIPS64)
1998OP_LD_ATOMIC(lld,ld64);
1999#endif
2000#undef OP_LD_ATOMIC
2001
590bc601
PB
2002#ifdef CONFIG_USER_ONLY
2003#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2004static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2005{ \
2006 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2007 TCGLabel *l1 = gen_new_label(); \
2008 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2009 \
2010 tcg_gen_andi_tl(t0, arg2, almask); \
2011 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2012 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2013 generate_exception(ctx, EXCP_AdES); \
2014 gen_set_label(l1); \
7db13fae 2015 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2016 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2017 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2018 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2019 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2020 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2021 gen_set_label(l2); \
2022 tcg_gen_movi_tl(t0, 0); \
2023 gen_store_gpr(t0, rt); \
2024 tcg_temp_free(t0); \
2025}
2026#else
2027#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2028static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2029{ \
2030 TCGv t0 = tcg_temp_new(); \
895c2d04 2031 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2032 gen_store_gpr(t0, rt); \
590bc601
PB
2033 tcg_temp_free(t0); \
2034}
2035#endif
590bc601 2036OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2037#if defined(TARGET_MIPS64)
590bc601 2038OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2039#endif
2040#undef OP_ST_ATOMIC
2041
662d7485
NF
2042static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2043 int base, int16_t offset)
2044{
2045 if (base == 0) {
2046 tcg_gen_movi_tl(addr, offset);
2047 } else if (offset == 0) {
2048 gen_load_gpr(addr, base);
2049 } else {
2050 tcg_gen_movi_tl(addr, offset);
2051 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2052 }
2053}
2054
364d4831
NF
2055static target_ulong pc_relative_pc (DisasContext *ctx)
2056{
2057 target_ulong pc = ctx->pc;
2058
2059 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2060 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2061
2062 pc -= branch_bytes;
2063 }
2064
2065 pc &= ~(target_ulong)3;
2066 return pc;
2067}
2068
5c13fdfd 2069/* Load */
d75c135e
AJ
2070static void gen_ld(DisasContext *ctx, uint32_t opc,
2071 int rt, int base, int16_t offset)
6af0bf9c 2072{
5c13fdfd 2073 const char *opn = "ld";
fc40787a 2074 TCGv t0, t1, t2;
afa88c3a 2075
d75c135e 2076 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2077 /* Loongson CPU uses a load to zero register for prefetch.
2078 We emulate it as a NOP. On other CPU we must perform the
2079 actual memory access. */
2080 MIPS_DEBUG("NOP");
2081 return;
2082 }
6af0bf9c 2083
afa88c3a 2084 t0 = tcg_temp_new();
662d7485 2085 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2086
6af0bf9c 2087 switch (opc) {
d26bc211 2088#if defined(TARGET_MIPS64)
6e473128 2089 case OPC_LWU:
be3a8c53
YK
2090 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2091 ctx->default_tcg_memop_mask);
78723684 2092 gen_store_gpr(t0, rt);
6e473128
TS
2093 opn = "lwu";
2094 break;
6af0bf9c 2095 case OPC_LD:
be3a8c53
YK
2096 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2097 ctx->default_tcg_memop_mask);
78723684 2098 gen_store_gpr(t0, rt);
6af0bf9c
FB
2099 opn = "ld";
2100 break;
7a387fff 2101 case OPC_LLD:
bf7910c6 2102 case R6_OPC_LLD:
b835e919 2103 save_cpu_state(ctx, 1);
5c13fdfd 2104 op_ld_lld(t0, t0, ctx);
78723684 2105 gen_store_gpr(t0, rt);
7a387fff
TS
2106 opn = "lld";
2107 break;
6af0bf9c 2108 case OPC_LDL:
3cee3050 2109 t1 = tcg_temp_new();
fc40787a
AJ
2110 tcg_gen_andi_tl(t1, t0, 7);
2111#ifndef TARGET_WORDS_BIGENDIAN
2112 tcg_gen_xori_tl(t1, t1, 7);
2113#endif
2114 tcg_gen_shli_tl(t1, t1, 3);
2115 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2116 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2117 tcg_gen_shl_tl(t0, t0, t1);
2118 tcg_gen_xori_tl(t1, t1, 63);
2119 t2 = tcg_const_tl(0x7fffffffffffffffull);
2120 tcg_gen_shr_tl(t2, t2, t1);
78723684 2121 gen_load_gpr(t1, rt);
fc40787a
AJ
2122 tcg_gen_and_tl(t1, t1, t2);
2123 tcg_temp_free(t2);
2124 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2125 tcg_temp_free(t1);
fc40787a 2126 gen_store_gpr(t0, rt);
6af0bf9c
FB
2127 opn = "ldl";
2128 break;
6af0bf9c 2129 case OPC_LDR:
3cee3050 2130 t1 = tcg_temp_new();
fc40787a
AJ
2131 tcg_gen_andi_tl(t1, t0, 7);
2132#ifdef TARGET_WORDS_BIGENDIAN
2133 tcg_gen_xori_tl(t1, t1, 7);
2134#endif
2135 tcg_gen_shli_tl(t1, t1, 3);
2136 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2137 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2138 tcg_gen_shr_tl(t0, t0, t1);
2139 tcg_gen_xori_tl(t1, t1, 63);
2140 t2 = tcg_const_tl(0xfffffffffffffffeull);
2141 tcg_gen_shl_tl(t2, t2, t1);
78723684 2142 gen_load_gpr(t1, rt);
fc40787a
AJ
2143 tcg_gen_and_tl(t1, t1, t2);
2144 tcg_temp_free(t2);
2145 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2146 tcg_temp_free(t1);
fc40787a 2147 gen_store_gpr(t0, rt);
6af0bf9c
FB
2148 opn = "ldr";
2149 break;
364d4831 2150 case OPC_LDPC:
3cee3050 2151 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2152 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2153 tcg_temp_free(t1);
5f68f5ae 2154 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2155 gen_store_gpr(t0, rt);
5c13fdfd 2156 opn = "ldpc";
364d4831 2157 break;
6af0bf9c 2158#endif
364d4831 2159 case OPC_LWPC:
3cee3050 2160 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2161 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2162 tcg_temp_free(t1);
5f68f5ae 2163 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2164 gen_store_gpr(t0, rt);
5c13fdfd 2165 opn = "lwpc";
364d4831 2166 break;
6af0bf9c 2167 case OPC_LW:
be3a8c53
YK
2168 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2169 ctx->default_tcg_memop_mask);
78723684 2170 gen_store_gpr(t0, rt);
6af0bf9c
FB
2171 opn = "lw";
2172 break;
6af0bf9c 2173 case OPC_LH:
be3a8c53
YK
2174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2175 ctx->default_tcg_memop_mask);
78723684 2176 gen_store_gpr(t0, rt);
6af0bf9c
FB
2177 opn = "lh";
2178 break;
6af0bf9c 2179 case OPC_LHU:
be3a8c53
YK
2180 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2181 ctx->default_tcg_memop_mask);
78723684 2182 gen_store_gpr(t0, rt);
6af0bf9c
FB
2183 opn = "lhu";
2184 break;
2185 case OPC_LB:
5f68f5ae 2186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2187 gen_store_gpr(t0, rt);
6af0bf9c
FB
2188 opn = "lb";
2189 break;
6af0bf9c 2190 case OPC_LBU:
5f68f5ae 2191 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2192 gen_store_gpr(t0, rt);
6af0bf9c
FB
2193 opn = "lbu";
2194 break;
2195 case OPC_LWL:
3cee3050 2196 t1 = tcg_temp_new();
fc40787a
AJ
2197 tcg_gen_andi_tl(t1, t0, 3);
2198#ifndef TARGET_WORDS_BIGENDIAN
2199 tcg_gen_xori_tl(t1, t1, 3);
2200#endif
2201 tcg_gen_shli_tl(t1, t1, 3);
2202 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2204 tcg_gen_shl_tl(t0, t0, t1);
2205 tcg_gen_xori_tl(t1, t1, 31);
2206 t2 = tcg_const_tl(0x7fffffffull);
2207 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2208 gen_load_gpr(t1, rt);
fc40787a
AJ
2209 tcg_gen_and_tl(t1, t1, t2);
2210 tcg_temp_free(t2);
2211 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2212 tcg_temp_free(t1);
fc40787a
AJ
2213 tcg_gen_ext32s_tl(t0, t0);
2214 gen_store_gpr(t0, rt);
6af0bf9c
FB
2215 opn = "lwl";
2216 break;
6af0bf9c 2217 case OPC_LWR:
3cee3050 2218 t1 = tcg_temp_new();
fc40787a
AJ
2219 tcg_gen_andi_tl(t1, t0, 3);
2220#ifdef TARGET_WORDS_BIGENDIAN
2221 tcg_gen_xori_tl(t1, t1, 3);
2222#endif
2223 tcg_gen_shli_tl(t1, t1, 3);
2224 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2226 tcg_gen_shr_tl(t0, t0, t1);
2227 tcg_gen_xori_tl(t1, t1, 31);
2228 t2 = tcg_const_tl(0xfffffffeull);
2229 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2230 gen_load_gpr(t1, rt);
fc40787a
AJ
2231 tcg_gen_and_tl(t1, t1, t2);
2232 tcg_temp_free(t2);
2233 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2234 tcg_temp_free(t1);
c728154b 2235 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2236 gen_store_gpr(t0, rt);
6af0bf9c
FB
2237 opn = "lwr";
2238 break;
6af0bf9c 2239 case OPC_LL:
4368b29a 2240 case R6_OPC_LL:
e7139c44 2241 save_cpu_state(ctx, 1);
5c13fdfd 2242 op_ld_ll(t0, t0, ctx);
78723684 2243 gen_store_gpr(t0, rt);
6af0bf9c
FB
2244 opn = "ll";
2245 break;
d66c7132 2246 }
2abf314d 2247 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2248 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2249 tcg_temp_free(t0);
d66c7132
AJ
2250}
2251
5c13fdfd
AJ
2252/* Store */
2253static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2254 int base, int16_t offset)
2255{
2256 const char *opn = "st";
2257 TCGv t0 = tcg_temp_new();
2258 TCGv t1 = tcg_temp_new();
2259
2260 gen_base_offset_addr(ctx, t0, base, offset);
2261 gen_load_gpr(t1, rt);
2262 switch (opc) {
2263#if defined(TARGET_MIPS64)
2264 case OPC_SD:
be3a8c53
YK
2265 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2266 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2267 opn = "sd";
2268 break;
2269 case OPC_SDL:
2270 save_cpu_state(ctx, 1);
895c2d04 2271 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2272 opn = "sdl";
2273 break;
2274 case OPC_SDR:
2275 save_cpu_state(ctx, 1);
895c2d04 2276 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2277 opn = "sdr";
2278 break;
2279#endif
2280 case OPC_SW:
be3a8c53
YK
2281 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2282 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2283 opn = "sw";
2284 break;
2285 case OPC_SH:
be3a8c53
YK
2286 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2287 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2288 opn = "sh";
2289 break;
2290 case OPC_SB:
5f68f5ae 2291 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2292 opn = "sb";
2293 break;
2294 case OPC_SWL:
2295 save_cpu_state(ctx, 1);
895c2d04 2296 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2297 opn = "swl";
2298 break;
2299 case OPC_SWR:
2300 save_cpu_state(ctx, 1);
895c2d04 2301 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2302 opn = "swr";
2303 break;
2304 }
2abf314d 2305 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2306 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2307 tcg_temp_free(t0);
2308 tcg_temp_free(t1);
2309}
2310
2311
d66c7132
AJ
2312/* Store conditional */
2313static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2314 int base, int16_t offset)
2315{
2316 const char *opn = "st_cond";
2317 TCGv t0, t1;
2318
2d2826b9 2319#ifdef CONFIG_USER_ONLY
d66c7132 2320 t0 = tcg_temp_local_new();
d66c7132 2321 t1 = tcg_temp_local_new();
2d2826b9
AJ
2322#else
2323 t0 = tcg_temp_new();
2324 t1 = tcg_temp_new();
2325#endif
2326 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2327 gen_load_gpr(t1, rt);
2328 switch (opc) {
2329#if defined(TARGET_MIPS64)
2330 case OPC_SCD:
bf7910c6 2331 case R6_OPC_SCD:
b835e919 2332 save_cpu_state(ctx, 1);
5c13fdfd 2333 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2334 opn = "scd";
2335 break;
2336#endif
6af0bf9c 2337 case OPC_SC:
4368b29a 2338 case R6_OPC_SC:
e7139c44 2339 save_cpu_state(ctx, 1);
5c13fdfd 2340 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2341 opn = "sc";
2342 break;
6af0bf9c 2343 }
2abf314d 2344 (void)opn; /* avoid a compiler warning */
6af0bf9c 2345 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2346 tcg_temp_free(t1);
d66c7132 2347 tcg_temp_free(t0);
6af0bf9c
FB
2348}
2349
6ea83fed 2350/* Load and store */
7a387fff 2351static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2352 int base, int16_t offset)
6ea83fed 2353{
923617a3 2354 const char *opn = "flt_ldst";
4e2474d6 2355 TCGv t0 = tcg_temp_new();
6ea83fed 2356
662d7485 2357 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2358 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2359 memory access. */
6ea83fed
FB
2360 switch (opc) {
2361 case OPC_LWC1:
b6d96bed 2362 {
a7812ae4 2363 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2364 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2365 ctx->default_tcg_memop_mask);
7c979afd 2366 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2367 tcg_temp_free_i32(fp0);
b6d96bed 2368 }
6ea83fed
FB
2369 opn = "lwc1";
2370 break;
2371 case OPC_SWC1:
b6d96bed 2372 {
a7812ae4 2373 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2374 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2375 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2376 ctx->default_tcg_memop_mask);
a7812ae4 2377 tcg_temp_free_i32(fp0);
b6d96bed 2378 }
6ea83fed
FB
2379 opn = "swc1";
2380 break;
2381 case OPC_LDC1:
b6d96bed 2382 {
a7812ae4 2383 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2384 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2385 ctx->default_tcg_memop_mask);
b6d96bed 2386 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2387 tcg_temp_free_i64(fp0);
b6d96bed 2388 }
6ea83fed
FB
2389 opn = "ldc1";
2390 break;
2391 case OPC_SDC1:
b6d96bed 2392 {
a7812ae4 2393 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2394 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2395 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2396 ctx->default_tcg_memop_mask);
a7812ae4 2397 tcg_temp_free_i64(fp0);
b6d96bed 2398 }
6ea83fed
FB
2399 opn = "sdc1";
2400 break;
2401 default:
923617a3 2402 MIPS_INVAL(opn);
e397ee33 2403 generate_exception(ctx, EXCP_RI);
78723684 2404 goto out;
6ea83fed 2405 }
2abf314d 2406 (void)opn; /* avoid a compiler warning */
6ea83fed 2407 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2408 out:
2409 tcg_temp_free(t0);
6ea83fed 2410}
6ea83fed 2411
5ab5c041
AJ
2412static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2413 int rs, int16_t imm)
26ebe468 2414{
5ab5c041 2415 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2416 check_cp1_enabled(ctx);
d9224450
MR
2417 switch (op) {
2418 case OPC_LDC1:
2419 case OPC_SDC1:
2420 check_insn(ctx, ISA_MIPS2);
2421 /* Fallthrough */
2422 default:
2423 gen_flt_ldst(ctx, op, rt, rs, imm);
2424 }
26ebe468
NF
2425 } else {
2426 generate_exception_err(ctx, EXCP_CpU, 1);
2427 }
2428}
2429
6af0bf9c 2430/* Arithmetic with immediate operand */
d75c135e
AJ
2431static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2432 int rt, int rs, int16_t imm)
6af0bf9c 2433{
324d9e32 2434 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2435 const char *opn = "imm arith";
6af0bf9c 2436
7a387fff 2437 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2438 /* If no destination, treat it as a NOP.
2439 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2440 MIPS_DEBUG("NOP");
324d9e32 2441 return;
6af0bf9c
FB
2442 }
2443 switch (opc) {
2444 case OPC_ADDI:
48d38ca5 2445 {
324d9e32
AJ
2446 TCGv t0 = tcg_temp_local_new();
2447 TCGv t1 = tcg_temp_new();
2448 TCGv t2 = tcg_temp_new();
42a268c2 2449 TCGLabel *l1 = gen_new_label();
48d38ca5 2450
324d9e32
AJ
2451 gen_load_gpr(t1, rs);
2452 tcg_gen_addi_tl(t0, t1, uimm);
2453 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2454
324d9e32
AJ
2455 tcg_gen_xori_tl(t1, t1, ~uimm);
2456 tcg_gen_xori_tl(t2, t0, uimm);
2457 tcg_gen_and_tl(t1, t1, t2);
2458 tcg_temp_free(t2);
2459 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2460 tcg_temp_free(t1);
48d38ca5
TS
2461 /* operands of same sign, result different sign */
2462 generate_exception(ctx, EXCP_OVERFLOW);
2463 gen_set_label(l1);
78723684 2464 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2465 gen_store_gpr(t0, rt);
2466 tcg_temp_free(t0);
48d38ca5 2467 }
6af0bf9c
FB
2468 opn = "addi";
2469 break;
2470 case OPC_ADDIU:
324d9e32
AJ
2471 if (rs != 0) {
2472 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2473 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2474 } else {
2475 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2476 }
6af0bf9c
FB
2477 opn = "addiu";
2478 break;
d26bc211 2479#if defined(TARGET_MIPS64)
7a387fff 2480 case OPC_DADDI:
48d38ca5 2481 {
324d9e32
AJ
2482 TCGv t0 = tcg_temp_local_new();
2483 TCGv t1 = tcg_temp_new();
2484 TCGv t2 = tcg_temp_new();
42a268c2 2485 TCGLabel *l1 = gen_new_label();
48d38ca5 2486
324d9e32
AJ
2487 gen_load_gpr(t1, rs);
2488 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2489
324d9e32
AJ
2490 tcg_gen_xori_tl(t1, t1, ~uimm);
2491 tcg_gen_xori_tl(t2, t0, uimm);
2492 tcg_gen_and_tl(t1, t1, t2);
2493 tcg_temp_free(t2);
2494 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2495 tcg_temp_free(t1);
48d38ca5
TS
2496 /* operands of same sign, result different sign */
2497 generate_exception(ctx, EXCP_OVERFLOW);
2498 gen_set_label(l1);
324d9e32
AJ
2499 gen_store_gpr(t0, rt);
2500 tcg_temp_free(t0);
48d38ca5 2501 }
7a387fff
TS
2502 opn = "daddi";
2503 break;
2504 case OPC_DADDIU:
324d9e32
AJ
2505 if (rs != 0) {
2506 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2507 } else {
2508 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2509 }
7a387fff
TS
2510 opn = "daddiu";
2511 break;
2512#endif
324d9e32 2513 }
2abf314d 2514 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2515 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2516}
2517
2518/* Logic with immediate operand */
d75c135e 2519static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2520 int rt, int rs, int16_t imm)
324d9e32
AJ
2521{
2522 target_ulong uimm;
324d9e32
AJ
2523
2524 if (rt == 0) {
2525 /* If no destination, treat it as a NOP. */
2526 MIPS_DEBUG("NOP");
2527 return;
2528 }
2529 uimm = (uint16_t)imm;
2530 switch (opc) {
6af0bf9c 2531 case OPC_ANDI:
324d9e32
AJ
2532 if (likely(rs != 0))
2533 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2534 else
2535 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2536 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2537 regnames[rs], uimm);
6af0bf9c
FB
2538 break;
2539 case OPC_ORI:
324d9e32
AJ
2540 if (rs != 0)
2541 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2542 else
2543 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2544 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2545 regnames[rs], uimm);
6af0bf9c
FB
2546 break;
2547 case OPC_XORI:
324d9e32
AJ
2548 if (likely(rs != 0))
2549 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2550 else
2551 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2552 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2553 regnames[rs], uimm);
6af0bf9c
FB
2554 break;
2555 case OPC_LUI:
d4ea6acd
LA
2556 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2557 /* OPC_AUI */
2558 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2560 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2561 } else {
2562 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2563 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2564 }
7c2c3ea3
EJ
2565 break;
2566
2567 default:
2568 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2569 break;
324d9e32 2570 }
324d9e32
AJ
2571}
2572
2573/* Set on less than with immediate operand */
d75c135e 2574static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2575 int rt, int rs, int16_t imm)
324d9e32
AJ
2576{
2577 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2578 const char *opn = "imm arith";
2579 TCGv t0;
2580
2581 if (rt == 0) {
2582 /* If no destination, treat it as a NOP. */
2583 MIPS_DEBUG("NOP");
2584 return;
2585 }
2586 t0 = tcg_temp_new();
2587 gen_load_gpr(t0, rs);
2588 switch (opc) {
2589 case OPC_SLTI:
e68dd28f 2590 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2591 opn = "slti";
2592 break;
2593 case OPC_SLTIU:
e68dd28f 2594 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2595 opn = "sltiu";
2596 break;
2597 }
2abf314d 2598 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2599 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2600 tcg_temp_free(t0);
2601}
2602
2603/* Shifts with immediate operand */
d75c135e 2604static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2605 int rt, int rs, int16_t imm)
2606{
2607 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2608 const char *opn = "imm shift";
2609 TCGv t0;
2610
2611 if (rt == 0) {
2612 /* If no destination, treat it as a NOP. */
2613 MIPS_DEBUG("NOP");
2614 return;
2615 }
2616
2617 t0 = tcg_temp_new();
2618 gen_load_gpr(t0, rs);
2619 switch (opc) {
6af0bf9c 2620 case OPC_SLL:
78723684 2621 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2622 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2623 opn = "sll";
2624 break;
2625 case OPC_SRA:
324d9e32 2626 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2627 opn = "sra";
2628 break;
2629 case OPC_SRL:
ea63e2c3
NF
2630 if (uimm != 0) {
2631 tcg_gen_ext32u_tl(t0, t0);
2632 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2633 } else {
2634 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2635 }
ea63e2c3
NF
2636 opn = "srl";
2637 break;
2638 case OPC_ROTR:
2639 if (uimm != 0) {
2640 TCGv_i32 t1 = tcg_temp_new_i32();
2641
2642 tcg_gen_trunc_tl_i32(t1, t0);
2643 tcg_gen_rotri_i32(t1, t1, uimm);
2644 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2645 tcg_temp_free_i32(t1);
3399e30f
NF
2646 } else {
2647 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2648 }
2649 opn = "rotr";
7a387fff 2650 break;
d26bc211 2651#if defined(TARGET_MIPS64)
7a387fff 2652 case OPC_DSLL:
324d9e32 2653 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2654 opn = "dsll";
2655 break;
2656 case OPC_DSRA:
324d9e32 2657 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2658 opn = "dsra";
2659 break;
2660 case OPC_DSRL:
ea63e2c3
NF
2661 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2662 opn = "dsrl";
2663 break;
2664 case OPC_DROTR:
2665 if (uimm != 0) {
2666 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2667 } else {
2668 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2669 }
ea63e2c3 2670 opn = "drotr";
7a387fff
TS
2671 break;
2672 case OPC_DSLL32:
324d9e32 2673 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2674 opn = "dsll32";
2675 break;
2676 case OPC_DSRA32:
324d9e32 2677 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2678 opn = "dsra32";
2679 break;
2680 case OPC_DSRL32:
ea63e2c3
NF
2681 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2682 opn = "dsrl32";
2683 break;
2684 case OPC_DROTR32:
2685 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2686 opn = "drotr32";
6af0bf9c 2687 break;
7a387fff 2688#endif
6af0bf9c 2689 }
2abf314d 2690 (void)opn; /* avoid a compiler warning */
93b12ccc 2691 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2692 tcg_temp_free(t0);
6af0bf9c
FB
2693}
2694
2695/* Arithmetic */
d75c135e
AJ
2696static void gen_arith(DisasContext *ctx, uint32_t opc,
2697 int rd, int rs, int rt)
6af0bf9c 2698{
923617a3 2699 const char *opn = "arith";
6af0bf9c 2700
7a387fff
TS
2701 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2702 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2703 /* If no destination, treat it as a NOP.
2704 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2705 MIPS_DEBUG("NOP");
460f00c4 2706 return;
185f0762 2707 }
460f00c4 2708
6af0bf9c
FB
2709 switch (opc) {
2710 case OPC_ADD:
48d38ca5 2711 {
460f00c4
AJ
2712 TCGv t0 = tcg_temp_local_new();
2713 TCGv t1 = tcg_temp_new();
2714 TCGv t2 = tcg_temp_new();
42a268c2 2715 TCGLabel *l1 = gen_new_label();
48d38ca5 2716
460f00c4
AJ
2717 gen_load_gpr(t1, rs);
2718 gen_load_gpr(t2, rt);
2719 tcg_gen_add_tl(t0, t1, t2);
2720 tcg_gen_ext32s_tl(t0, t0);
2721 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2722 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2723 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2724 tcg_temp_free(t2);
2725 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2726 tcg_temp_free(t1);
48d38ca5
TS
2727 /* operands of same sign, result different sign */
2728 generate_exception(ctx, EXCP_OVERFLOW);
2729 gen_set_label(l1);
460f00c4
AJ
2730 gen_store_gpr(t0, rd);
2731 tcg_temp_free(t0);
48d38ca5 2732 }
6af0bf9c
FB
2733 opn = "add";
2734 break;
2735 case OPC_ADDU:
460f00c4
AJ
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739 } else if (rs == 0 && rt != 0) {
2740 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741 } else if (rs != 0 && rt == 0) {
2742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2743 } else {
2744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2745 }
6af0bf9c
FB
2746 opn = "addu";
2747 break;
2748 case OPC_SUB:
48d38ca5 2749 {
460f00c4
AJ
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
42a268c2 2753 TCGLabel *l1 = gen_new_label();
48d38ca5 2754
460f00c4
AJ
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_sub_tl(t0, t1, t2);
2758 tcg_gen_ext32s_tl(t0, t0);
2759 tcg_gen_xor_tl(t2, t1, t2);
2760 tcg_gen_xor_tl(t1, t0, t1);
2761 tcg_gen_and_tl(t1, t1, t2);
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
31e3104f 2765 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
460f00c4
AJ
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
48d38ca5 2770 }
6af0bf9c
FB
2771 opn = "sub";
2772 break;
2773 case OPC_SUBU:
460f00c4
AJ
2774 if (rs != 0 && rt != 0) {
2775 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2776 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2777 } else if (rs == 0 && rt != 0) {
2778 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2779 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2780 } else if (rs != 0 && rt == 0) {
2781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2782 } else {
2783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2784 }
6af0bf9c
FB
2785 opn = "subu";
2786 break;
d26bc211 2787#if defined(TARGET_MIPS64)
7a387fff 2788 case OPC_DADD:
48d38ca5 2789 {
460f00c4
AJ
2790 TCGv t0 = tcg_temp_local_new();
2791 TCGv t1 = tcg_temp_new();
2792 TCGv t2 = tcg_temp_new();
42a268c2 2793 TCGLabel *l1 = gen_new_label();
48d38ca5 2794
460f00c4
AJ
2795 gen_load_gpr(t1, rs);
2796 gen_load_gpr(t2, rt);
2797 tcg_gen_add_tl(t0, t1, t2);
2798 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2799 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2800 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2801 tcg_temp_free(t2);
2802 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2803 tcg_temp_free(t1);
48d38ca5
TS
2804 /* operands of same sign, result different sign */
2805 generate_exception(ctx, EXCP_OVERFLOW);
2806 gen_set_label(l1);
460f00c4
AJ
2807 gen_store_gpr(t0, rd);
2808 tcg_temp_free(t0);
48d38ca5 2809 }
7a387fff
TS
2810 opn = "dadd";
2811 break;
2812 case OPC_DADDU:
460f00c4
AJ
2813 if (rs != 0 && rt != 0) {
2814 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2815 } else if (rs == 0 && rt != 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2817 } else if (rs != 0 && rt == 0) {
2818 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2819 } else {
2820 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2821 }
7a387fff
TS
2822 opn = "daddu";
2823 break;
2824 case OPC_DSUB:
48d38ca5 2825 {
460f00c4
AJ
2826 TCGv t0 = tcg_temp_local_new();
2827 TCGv t1 = tcg_temp_new();
2828 TCGv t2 = tcg_temp_new();
42a268c2 2829 TCGLabel *l1 = gen_new_label();
48d38ca5 2830
460f00c4
AJ
2831 gen_load_gpr(t1, rs);
2832 gen_load_gpr(t2, rt);
2833 tcg_gen_sub_tl(t0, t1, t2);
2834 tcg_gen_xor_tl(t2, t1, t2);
2835 tcg_gen_xor_tl(t1, t0, t1);
2836 tcg_gen_and_tl(t1, t1, t2);
2837 tcg_temp_free(t2);
2838 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2839 tcg_temp_free(t1);
31e3104f 2840 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2841 generate_exception(ctx, EXCP_OVERFLOW);
2842 gen_set_label(l1);
460f00c4
AJ
2843 gen_store_gpr(t0, rd);
2844 tcg_temp_free(t0);
48d38ca5 2845 }
7a387fff
TS
2846 opn = "dsub";
2847 break;
2848 case OPC_DSUBU:
460f00c4
AJ
2849 if (rs != 0 && rt != 0) {
2850 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851 } else if (rs == 0 && rt != 0) {
2852 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853 } else if (rs != 0 && rt == 0) {
2854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2855 } else {
2856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2857 }
7a387fff
TS
2858 opn = "dsubu";
2859 break;
2860#endif
460f00c4
AJ
2861 case OPC_MUL:
2862 if (likely(rs != 0 && rt != 0)) {
2863 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2864 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2865 } else {
2866 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2867 }
2868 opn = "mul";
6af0bf9c 2869 break;
460f00c4 2870 }
2abf314d 2871 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2872 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2873}
2874
2875/* Conditional move */
d75c135e 2876static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2877 int rd, int rs, int rt)
460f00c4
AJ
2878{
2879 const char *opn = "cond move";
acf12465 2880 TCGv t0, t1, t2;
460f00c4
AJ
2881
2882 if (rd == 0) {
acf12465 2883 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2884 MIPS_DEBUG("NOP");
2885 return;
2886 }
2887
acf12465
AJ
2888 t0 = tcg_temp_new();
2889 gen_load_gpr(t0, rt);
2890 t1 = tcg_const_tl(0);
2891 t2 = tcg_temp_new();
2892 gen_load_gpr(t2, rs);
460f00c4
AJ
2893 switch (opc) {
2894 case OPC_MOVN:
acf12465 2895 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2896 opn = "movn";
6af0bf9c 2897 break;
460f00c4 2898 case OPC_MOVZ:
acf12465 2899 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2900 opn = "movz";
2901 break;
b691d9d2
LA
2902 case OPC_SELNEZ:
2903 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2904 opn = "selnez";
2905 break;
2906 case OPC_SELEQZ:
2907 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2908 opn = "seleqz";
2909 break;
460f00c4 2910 }
acf12465
AJ
2911 tcg_temp_free(t2);
2912 tcg_temp_free(t1);
2913 tcg_temp_free(t0);
460f00c4 2914
2abf314d 2915 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2916 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2917}
2918
2919/* Logic */
d75c135e 2920static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2921 int rd, int rs, int rt)
460f00c4
AJ
2922{
2923 const char *opn = "logic";
2924
2925 if (rd == 0) {
2926 /* If no destination, treat it as a NOP. */
2927 MIPS_DEBUG("NOP");
2928 return;
2929 }
2930
2931 switch (opc) {
6af0bf9c 2932 case OPC_AND:
460f00c4
AJ
2933 if (likely(rs != 0 && rt != 0)) {
2934 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2935 } else {
2936 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2937 }
6af0bf9c
FB
2938 opn = "and";
2939 break;
2940 case OPC_NOR:
460f00c4
AJ
2941 if (rs != 0 && rt != 0) {
2942 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2943 } else if (rs == 0 && rt != 0) {
2944 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2945 } else if (rs != 0 && rt == 0) {
2946 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2947 } else {
2948 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2949 }
6af0bf9c
FB
2950 opn = "nor";
2951 break;
2952 case OPC_OR:
460f00c4
AJ
2953 if (likely(rs != 0 && rt != 0)) {
2954 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2955 } else if (rs == 0 && rt != 0) {
2956 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2957 } else if (rs != 0 && rt == 0) {
2958 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2959 } else {
2960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2961 }
6af0bf9c
FB
2962 opn = "or";
2963 break;
2964 case OPC_XOR:
460f00c4
AJ
2965 if (likely(rs != 0 && rt != 0)) {
2966 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2967 } else if (rs == 0 && rt != 0) {
2968 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2969 } else if (rs != 0 && rt == 0) {
2970 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2971 } else {
2972 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2973 }
6af0bf9c
FB
2974 opn = "xor";
2975 break;
460f00c4 2976 }
2abf314d 2977 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2978 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2979}
2980
2981/* Set on lower than */
d75c135e 2982static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2983 int rd, int rs, int rt)
460f00c4
AJ
2984{
2985 const char *opn = "slt";
2986 TCGv t0, t1;
2987
2988 if (rd == 0) {
2989 /* If no destination, treat it as a NOP. */
2990 MIPS_DEBUG("NOP");
2991 return;
2992 }
2993
2994 t0 = tcg_temp_new();
2995 t1 = tcg_temp_new();
2996 gen_load_gpr(t0, rs);
2997 gen_load_gpr(t1, rt);
2998 switch (opc) {
2999 case OPC_SLT:
e68dd28f 3000 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 3001 opn = "slt";
6af0bf9c 3002 break;
460f00c4 3003 case OPC_SLTU:
e68dd28f 3004 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3005 opn = "sltu";
3006 break;
3007 }
2abf314d 3008 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
3009 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3010 tcg_temp_free(t0);
3011 tcg_temp_free(t1);
3012}
20c4c97c 3013
460f00c4 3014/* Shifts */
d75c135e
AJ
3015static void gen_shift(DisasContext *ctx, uint32_t opc,
3016 int rd, int rs, int rt)
460f00c4
AJ
3017{
3018 const char *opn = "shifts";
3019 TCGv t0, t1;
20c4c97c 3020
460f00c4
AJ
3021 if (rd == 0) {
3022 /* If no destination, treat it as a NOP.
3023 For add & sub, we must generate the overflow exception when needed. */
3024 MIPS_DEBUG("NOP");
3025 return;
3026 }
3027
3028 t0 = tcg_temp_new();
3029 t1 = tcg_temp_new();
3030 gen_load_gpr(t0, rs);
3031 gen_load_gpr(t1, rt);
3032 switch (opc) {
6af0bf9c 3033 case OPC_SLLV:
78723684
TS
3034 tcg_gen_andi_tl(t0, t0, 0x1f);
3035 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3036 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3037 opn = "sllv";
3038 break;
3039 case OPC_SRAV:
78723684 3040 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3041 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3042 opn = "srav";
3043 break;
3044 case OPC_SRLV:
ea63e2c3
NF
3045 tcg_gen_ext32u_tl(t1, t1);
3046 tcg_gen_andi_tl(t0, t0, 0x1f);
3047 tcg_gen_shr_tl(t0, t1, t0);
3048 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3049 opn = "srlv";
3050 break;
3051 case OPC_ROTRV:
3052 {
3053 TCGv_i32 t2 = tcg_temp_new_i32();
3054 TCGv_i32 t3 = tcg_temp_new_i32();
3055
3056 tcg_gen_trunc_tl_i32(t2, t0);
3057 tcg_gen_trunc_tl_i32(t3, t1);
3058 tcg_gen_andi_i32(t2, t2, 0x1f);
3059 tcg_gen_rotr_i32(t2, t3, t2);
3060 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3061 tcg_temp_free_i32(t2);
3062 tcg_temp_free_i32(t3);
3063 opn = "rotrv";
5a63bcb2 3064 }
7a387fff 3065 break;
d26bc211 3066#if defined(TARGET_MIPS64)
7a387fff 3067 case OPC_DSLLV:
78723684 3068 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3069 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3070 opn = "dsllv";
3071 break;
3072 case OPC_DSRAV:
78723684 3073 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3074 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3075 opn = "dsrav";
3076 break;
3077 case OPC_DSRLV:
ea63e2c3
NF
3078 tcg_gen_andi_tl(t0, t0, 0x3f);
3079 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3080 opn = "dsrlv";
3081 break;
3082 case OPC_DROTRV:
3083 tcg_gen_andi_tl(t0, t0, 0x3f);
3084 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3085 opn = "drotrv";
6af0bf9c 3086 break;
7a387fff 3087#endif
6af0bf9c 3088 }
2abf314d 3089 (void)opn; /* avoid a compiler warning */
6af0bf9c 3090 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3091 tcg_temp_free(t0);
3092 tcg_temp_free(t1);
6af0bf9c
FB
3093}
3094
3095/* Arithmetic on HI/LO registers */
26135ead 3096static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3097{
923617a3 3098 const char *opn = "hilo";
6af0bf9c
FB
3099
3100 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3101 /* Treat as NOP. */
6af0bf9c 3102 MIPS_DEBUG("NOP");
a1f6684d 3103 return;
6af0bf9c 3104 }
4133498f 3105
4133498f
JL
3106 if (acc != 0) {
3107 check_dsp(ctx);
3108 }
3109
6af0bf9c
FB
3110 switch (opc) {
3111 case OPC_MFHI:
4133498f
JL
3112#if defined(TARGET_MIPS64)
3113 if (acc != 0) {
3114 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3115 } else
3116#endif
3117 {
3118 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3119 }
6af0bf9c
FB
3120 opn = "mfhi";
3121 break;
3122 case OPC_MFLO:
4133498f
JL
3123#if defined(TARGET_MIPS64)
3124 if (acc != 0) {
3125 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3126 } else
3127#endif
3128 {
3129 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3130 }
6af0bf9c
FB
3131 opn = "mflo";
3132 break;
3133 case OPC_MTHI:
4133498f
JL
3134 if (reg != 0) {
3135#if defined(TARGET_MIPS64)
3136 if (acc != 0) {
3137 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3138 } else
3139#endif
3140 {
3141 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3142 }
3143 } else {
3144 tcg_gen_movi_tl(cpu_HI[acc], 0);
3145 }
6af0bf9c
FB
3146 opn = "mthi";
3147 break;
3148 case OPC_MTLO:
4133498f
JL
3149 if (reg != 0) {
3150#if defined(TARGET_MIPS64)
3151 if (acc != 0) {
3152 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3153 } else
3154#endif
3155 {
3156 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3157 }
3158 } else {
3159 tcg_gen_movi_tl(cpu_LO[acc], 0);
3160 }
6af0bf9c
FB
3161 opn = "mtlo";
3162 break;
6af0bf9c 3163 }
2abf314d 3164 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3165 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3166}
3167
d4ea6acd
LA
3168static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3169 TCGMemOp memop)
3170{
3171 TCGv t0 = tcg_const_tl(addr);
3172 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3173 gen_store_gpr(t0, reg);
3174 tcg_temp_free(t0);
3175}
3176
3177static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3178{
3179 target_long offset;
3180 target_long addr;
3181
3182 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3183 case OPC_ADDIUPC:
3184 if (rs != 0) {
3185 offset = sextract32(ctx->opcode << 2, 0, 21);
3186 addr = addr_add(ctx, ctx->pc, offset);
3187 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3188 }
3189 break;
3190 case R6_OPC_LWPC:
3191 offset = sextract32(ctx->opcode << 2, 0, 21);
3192 addr = addr_add(ctx, ctx->pc, offset);
3193 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3194 break;
3195#if defined(TARGET_MIPS64)
3196 case OPC_LWUPC:
3197 check_mips_64(ctx);
3198 offset = sextract32(ctx->opcode << 2, 0, 21);
3199 addr = addr_add(ctx, ctx->pc, offset);
3200 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3201 break;
3202#endif
3203 default:
3204 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3205 case OPC_AUIPC:
3206 if (rs != 0) {
3207 offset = imm << 16;
3208 addr = addr_add(ctx, ctx->pc, offset);
3209 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3210 }
3211 break;
3212 case OPC_ALUIPC:
3213 if (rs != 0) {
3214 offset = imm << 16;
3215 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3216 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3217 }
3218 break;
3219#if defined(TARGET_MIPS64)
3220 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3221 case R6_OPC_LDPC + (1 << 16):
3222 case R6_OPC_LDPC + (2 << 16):
3223 case R6_OPC_LDPC + (3 << 16):
3224 check_mips_64(ctx);
3225 offset = sextract32(ctx->opcode << 3, 0, 21);
3226 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3227 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3228 break;
3229#endif
3230 default:
3231 MIPS_INVAL("OPC_PCREL");
3232 generate_exception(ctx, EXCP_RI);
3233 break;
3234 }
3235 break;
3236 }
3237}
3238
b42ee5e1
LA
3239static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3240{
3241 const char *opn = "r6 mul/div";
3242 TCGv t0, t1;
3243
3244 if (rd == 0) {
3245 /* Treat as NOP. */
3246 MIPS_DEBUG("NOP");
3247 return;
3248 }
3249
3250 t0 = tcg_temp_new();
3251 t1 = tcg_temp_new();
3252
3253 gen_load_gpr(t0, rs);
3254 gen_load_gpr(t1, rt);
3255
3256 switch (opc) {
3257 case R6_OPC_DIV:
3258 {
3259 TCGv t2 = tcg_temp_new();
3260 TCGv t3 = tcg_temp_new();
3261 tcg_gen_ext32s_tl(t0, t0);
3262 tcg_gen_ext32s_tl(t1, t1);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3271 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3272 tcg_temp_free(t3);
3273 tcg_temp_free(t2);
3274 }
3275 opn = "div";
3276 break;
3277 case R6_OPC_MOD:
3278 {
3279 TCGv t2 = tcg_temp_new();
3280 TCGv t3 = tcg_temp_new();
3281 tcg_gen_ext32s_tl(t0, t0);
3282 tcg_gen_ext32s_tl(t1, t1);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3285 tcg_gen_and_tl(t2, t2, t3);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3287 tcg_gen_or_tl(t2, t2, t3);
3288 tcg_gen_movi_tl(t3, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3290 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3291 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3292 tcg_temp_free(t3);
3293 tcg_temp_free(t2);
3294 }
3295 opn = "mod";
3296 break;
3297 case R6_OPC_DIVU:
3298 {
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_ext32u_tl(t0, t0);
3302 tcg_gen_ext32u_tl(t1, t1);
3303 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3304 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3305 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3308 }
3309 opn = "divu";
3310 break;
3311 case R6_OPC_MODU:
3312 {
3313 TCGv t2 = tcg_const_tl(0);
3314 TCGv t3 = tcg_const_tl(1);
3315 tcg_gen_ext32u_tl(t0, t0);
3316 tcg_gen_ext32u_tl(t1, t1);
3317 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3319 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3320 tcg_temp_free(t3);
3321 tcg_temp_free(t2);
3322 }
3323 opn = "modu";
3324 break;
3325 case R6_OPC_MUL:
3326 {
3327 TCGv_i32 t2 = tcg_temp_new_i32();
3328 TCGv_i32 t3 = tcg_temp_new_i32();
3329 tcg_gen_trunc_tl_i32(t2, t0);
3330 tcg_gen_trunc_tl_i32(t3, t1);
3331 tcg_gen_mul_i32(t2, t2, t3);
3332 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3333 tcg_temp_free_i32(t2);
3334 tcg_temp_free_i32(t3);
3335 }
3336 opn = "mul";
3337 break;
3338 case R6_OPC_MUH:
3339 {
3340 TCGv_i32 t2 = tcg_temp_new_i32();
3341 TCGv_i32 t3 = tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2, t0);
3343 tcg_gen_trunc_tl_i32(t3, t1);
3344 tcg_gen_muls2_i32(t2, t3, t2, t3);
3345 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346 tcg_temp_free_i32(t2);
3347 tcg_temp_free_i32(t3);
3348 }
3349 opn = "muh";
3350 break;
3351 case R6_OPC_MULU:
3352 {
3353 TCGv_i32 t2 = tcg_temp_new_i32();
3354 TCGv_i32 t3 = tcg_temp_new_i32();
3355 tcg_gen_trunc_tl_i32(t2, t0);
3356 tcg_gen_trunc_tl_i32(t3, t1);
3357 tcg_gen_mul_i32(t2, t2, t3);
3358 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3359 tcg_temp_free_i32(t2);
3360 tcg_temp_free_i32(t3);
3361 }
3362 opn = "mulu";
3363 break;
3364 case R6_OPC_MUHU:
3365 {
3366 TCGv_i32 t2 = tcg_temp_new_i32();
3367 TCGv_i32 t3 = tcg_temp_new_i32();
3368 tcg_gen_trunc_tl_i32(t2, t0);
3369 tcg_gen_trunc_tl_i32(t3, t1);
3370 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3371 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3372 tcg_temp_free_i32(t2);
3373 tcg_temp_free_i32(t3);
3374 }
3375 opn = "muhu";
3376 break;
3377#if defined(TARGET_MIPS64)
3378 case R6_OPC_DDIV:
3379 {
3380 TCGv t2 = tcg_temp_new();
3381 TCGv t3 = tcg_temp_new();
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3384 tcg_gen_and_tl(t2, t2, t3);
3385 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3386 tcg_gen_or_tl(t2, t2, t3);
3387 tcg_gen_movi_tl(t3, 0);
3388 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3389 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3390 tcg_temp_free(t3);
3391 tcg_temp_free(t2);
3392 }
3393 opn = "ddiv";
3394 break;
3395 case R6_OPC_DMOD:
3396 {
3397 TCGv t2 = tcg_temp_new();
3398 TCGv t3 = tcg_temp_new();
3399 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3400 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3401 tcg_gen_and_tl(t2, t2, t3);
3402 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3403 tcg_gen_or_tl(t2, t2, t3);
3404 tcg_gen_movi_tl(t3, 0);
3405 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3406 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
3409 }
3410 opn = "dmod";
3411 break;
3412 case R6_OPC_DDIVU:
3413 {
3414 TCGv t2 = tcg_const_tl(0);
3415 TCGv t3 = tcg_const_tl(1);
3416 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3417 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3418 tcg_temp_free(t3);
3419 tcg_temp_free(t2);
3420 }
3421 opn = "ddivu";
3422 break;
3423 case R6_OPC_DMODU:
3424 {
3425 TCGv t2 = tcg_const_tl(0);
3426 TCGv t3 = tcg_const_tl(1);
3427 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3428 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3429 tcg_temp_free(t3);
3430 tcg_temp_free(t2);
3431 }
3432 opn = "dmodu";
3433 break;
3434 case R6_OPC_DMUL:
3435 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3436 opn = "dmul";
3437 break;
3438 case R6_OPC_DMUH:
3439 {
3440 TCGv t2 = tcg_temp_new();
3441 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3442 tcg_temp_free(t2);
3443 }
3444 opn = "dmuh";
3445 break;
3446 case R6_OPC_DMULU:
3447 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3448 opn = "dmulu";
3449 break;
3450 case R6_OPC_DMUHU:
3451 {
3452 TCGv t2 = tcg_temp_new();
3453 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3454 tcg_temp_free(t2);
3455 }
3456 opn = "dmuhu";
3457 break;
3458#endif
3459 default:
3460 MIPS_INVAL(opn);
3461 generate_exception(ctx, EXCP_RI);
3462 goto out;
3463 }
3464 (void)opn; /* avoid a compiler warning */
3465 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3466 out:
3467 tcg_temp_free(t0);
3468 tcg_temp_free(t1);
3469}
3470
26135ead
RS
3471static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3472 int acc, int rs, int rt)
6af0bf9c 3473{
923617a3 3474 const char *opn = "mul/div";
d45f89f4
AJ
3475 TCGv t0, t1;
3476
51127181
AJ
3477 t0 = tcg_temp_new();
3478 t1 = tcg_temp_new();
6af0bf9c 3479
78723684
TS
3480 gen_load_gpr(t0, rs);
3481 gen_load_gpr(t1, rt);
51127181 3482
26135ead
RS
3483 if (acc != 0) {
3484 check_dsp(ctx);
3485 }
3486
6af0bf9c
FB
3487 switch (opc) {
3488 case OPC_DIV:
48d38ca5 3489 {
51127181
AJ
3490 TCGv t2 = tcg_temp_new();
3491 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3492 tcg_gen_ext32s_tl(t0, t0);
3493 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3494 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3495 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3496 tcg_gen_and_tl(t2, t2, t3);
3497 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3498 tcg_gen_or_tl(t2, t2, t3);
3499 tcg_gen_movi_tl(t3, 0);
3500 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3501 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3502 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3503 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3504 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3505 tcg_temp_free(t3);
3506 tcg_temp_free(t2);
48d38ca5 3507 }
6af0bf9c
FB
3508 opn = "div";
3509 break;
3510 case OPC_DIVU:
48d38ca5 3511 {
51127181
AJ
3512 TCGv t2 = tcg_const_tl(0);
3513 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3514 tcg_gen_ext32u_tl(t0, t0);
3515 tcg_gen_ext32u_tl(t1, t1);
51127181 3516 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3517 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3518 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3519 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3520 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3521 tcg_temp_free(t3);
3522 tcg_temp_free(t2);
48d38ca5 3523 }
6af0bf9c
FB
3524 opn = "divu";
3525 break;
3526 case OPC_MULT:
214c465f 3527 {
ce1dd5d1
RH
3528 TCGv_i32 t2 = tcg_temp_new_i32();
3529 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3530 tcg_gen_trunc_tl_i32(t2, t0);
3531 tcg_gen_trunc_tl_i32(t3, t1);
3532 tcg_gen_muls2_i32(t2, t3, t2, t3);
3533 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3534 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3535 tcg_temp_free_i32(t2);
3536 tcg_temp_free_i32(t3);
214c465f 3537 }
6af0bf9c
FB
3538 opn = "mult";
3539 break;
3540 case OPC_MULTU:
214c465f 3541 {
ce1dd5d1
RH
3542 TCGv_i32 t2 = tcg_temp_new_i32();
3543 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3544 tcg_gen_trunc_tl_i32(t2, t0);
3545 tcg_gen_trunc_tl_i32(t3, t1);
3546 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3547 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3548 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3549 tcg_temp_free_i32(t2);
3550 tcg_temp_free_i32(t3);
214c465f 3551 }
6af0bf9c
FB
3552 opn = "multu";
3553 break;
d26bc211 3554#if defined(TARGET_MIPS64)
7a387fff 3555 case OPC_DDIV:
48d38ca5 3556 {
51127181
AJ
3557 TCGv t2 = tcg_temp_new();
3558 TCGv t3 = tcg_temp_new();
3559 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3560 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3561 tcg_gen_and_tl(t2, t2, t3);
3562 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3563 tcg_gen_or_tl(t2, t2, t3);
3564 tcg_gen_movi_tl(t3, 0);
3565 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3566 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3567 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3568 tcg_temp_free(t3);
3569 tcg_temp_free(t2);
48d38ca5 3570 }
7a387fff
TS
3571 opn = "ddiv";
3572 break;
3573 case OPC_DDIVU:
48d38ca5 3574 {
51127181
AJ
3575 TCGv t2 = tcg_const_tl(0);
3576 TCGv t3 = tcg_const_tl(1);
3577 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3578 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3579 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3580 tcg_temp_free(t3);
3581 tcg_temp_free(t2);
48d38ca5 3582 }
7a387fff
TS
3583 opn = "ddivu";
3584 break;
3585 case OPC_DMULT:
26135ead 3586 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3587 opn = "dmult";
3588 break;
3589 case OPC_DMULTU:
26135ead 3590 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3591 opn = "dmultu";
3592 break;
3593#endif
6af0bf9c 3594 case OPC_MADD:
214c465f 3595 {
d45f89f4
AJ
3596 TCGv_i64 t2 = tcg_temp_new_i64();
3597 TCGv_i64 t3 = tcg_temp_new_i64();
3598
3599 tcg_gen_ext_tl_i64(t2, t0);
3600 tcg_gen_ext_tl_i64(t3, t1);
3601 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3602 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3603 tcg_gen_add_i64(t2, t2, t3);
3604 tcg_temp_free_i64(t3);
3605 tcg_gen_trunc_i64_tl(t0, t2);
3606 tcg_gen_shri_i64(t2, t2, 32);
3607 tcg_gen_trunc_i64_tl(t1, t2);
3608 tcg_temp_free_i64(t2);
4133498f
JL
3609 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3610 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3611 }
6af0bf9c
FB
3612 opn = "madd";
3613 break;
3614 case OPC_MADDU:
4133498f 3615 {
d45f89f4
AJ
3616 TCGv_i64 t2 = tcg_temp_new_i64();
3617 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3618
78723684
TS
3619 tcg_gen_ext32u_tl(t0, t0);
3620 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3621 tcg_gen_extu_tl_i64(t2, t0);
3622 tcg_gen_extu_tl_i64(t3, t1);
3623 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3624 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3625 tcg_gen_add_i64(t2, t2, t3);
3626 tcg_temp_free_i64(t3);
3627 tcg_gen_trunc_i64_tl(t0, t2);
3628 tcg_gen_shri_i64(t2, t2, 32);
3629 tcg_gen_trunc_i64_tl(t1, t2);
3630 tcg_temp_free_i64(t2);
4133498f
JL
3631 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3632 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3633 }
6af0bf9c
FB
3634 opn = "maddu";
3635 break;
3636 case OPC_MSUB:
214c465f 3637 {
d45f89f4
AJ
3638 TCGv_i64 t2 = tcg_temp_new_i64();
3639 TCGv_i64 t3 = tcg_temp_new_i64();
3640
3641 tcg_gen_ext_tl_i64(t2, t0);
3642 tcg_gen_ext_tl_i64(t3, t1);
3643 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3644 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3645 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3646 tcg_temp_free_i64(t3);
3647 tcg_gen_trunc_i64_tl(t0, t2);
3648 tcg_gen_shri_i64(t2, t2, 32);
3649 tcg_gen_trunc_i64_tl(t1, t2);
3650 tcg_temp_free_i64(t2);
4133498f
JL
3651 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3652 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3653 }
6af0bf9c
FB
3654 opn = "msub";
3655 break;
3656 case OPC_MSUBU:
214c465f 3657 {
d45f89f4
AJ
3658 TCGv_i64 t2 = tcg_temp_new_i64();
3659 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3660
78723684
TS
3661 tcg_gen_ext32u_tl(t0, t0);
3662 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3663 tcg_gen_extu_tl_i64(t2, t0);
3664 tcg_gen_extu_tl_i64(t3, t1);
3665 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3666 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3667 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3668 tcg_temp_free_i64(t3);
3669 tcg_gen_trunc_i64_tl(t0, t2);
3670 tcg_gen_shri_i64(t2, t2, 32);
3671 tcg_gen_trunc_i64_tl(t1, t2);
3672 tcg_temp_free_i64(t2);
4133498f
JL
3673 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3674 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3675 }
6af0bf9c
FB
3676 opn = "msubu";
3677 break;
3678 default:
923617a3 3679 MIPS_INVAL(opn);
6af0bf9c 3680 generate_exception(ctx, EXCP_RI);
78723684 3681 goto out;
6af0bf9c 3682 }
2abf314d 3683 (void)opn; /* avoid a compiler warning */
6af0bf9c 3684 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3685 out:
3686 tcg_temp_free(t0);
3687 tcg_temp_free(t1);
6af0bf9c
FB
3688}
3689
e9c71dd1
TS
3690static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3691 int rd, int rs, int rt)
3692{
3693 const char *opn = "mul vr54xx";
f157bfe1
AJ
3694 TCGv t0 = tcg_temp_new();
3695 TCGv t1 = tcg_temp_new();
e9c71dd1 3696
6c5c1e20
TS
3697 gen_load_gpr(t0, rs);
3698 gen_load_gpr(t1, rt);
e9c71dd1
TS
3699
3700 switch (opc) {
3701 case OPC_VR54XX_MULS:
895c2d04 3702 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3703 opn = "muls";
6958549d 3704 break;
e9c71dd1 3705 case OPC_VR54XX_MULSU:
895c2d04 3706 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3707 opn = "mulsu";
6958549d 3708 break;
e9c71dd1 3709 case OPC_VR54XX_MACC:
895c2d04 3710 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3711 opn = "macc";
6958549d 3712 break;
e9c71dd1 3713 case OPC_VR54XX_MACCU:
895c2d04 3714 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3715 opn = "maccu";
6958549d 3716 break;
e9c71dd1 3717 case OPC_VR54XX_MSAC:
895c2d04 3718 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3719 opn = "msac";
6958549d 3720 break;
e9c71dd1 3721 case OPC_VR54XX_MSACU:
895c2d04 3722 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3723 opn = "msacu";
6958549d 3724 break;
e9c71dd1 3725 case OPC_VR54XX_MULHI:
895c2d04 3726 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3727 opn = "mulhi";
6958549d 3728 break;
e9c71dd1 3729 case OPC_VR54XX_MULHIU:
895c2d04 3730 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3731 opn = "mulhiu";
6958549d 3732 break;
e9c71dd1 3733 case OPC_VR54XX_MULSHI:
895c2d04 3734 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3735 opn = "mulshi";
6958549d 3736 break;
e9c71dd1 3737 case OPC_VR54XX_MULSHIU:
895c2d04 3738 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3739 opn = "mulshiu";
6958549d 3740 break;
e9c71dd1 3741 case OPC_VR54XX_MACCHI:
895c2d04 3742 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3743 opn = "macchi";
6958549d 3744 break;
e9c71dd1 3745 case OPC_VR54XX_MACCHIU:
895c2d04 3746 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3747 opn = "macchiu";
6958549d 3748 break;
e9c71dd1 3749 case OPC_VR54XX_MSACHI:
895c2d04 3750 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3751 opn = "msachi";
6958549d 3752 break;
e9c71dd1 3753 case OPC_VR54XX_MSACHIU:
895c2d04 3754 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3755 opn = "msachiu";
6958549d 3756 break;
e9c71dd1
TS
3757 default:
3758 MIPS_INVAL("mul vr54xx");
3759 generate_exception(ctx, EXCP_RI);
6c5c1e20 3760 goto out;
e9c71dd1 3761 }
6c5c1e20 3762 gen_store_gpr(t0, rd);
2abf314d 3763 (void)opn; /* avoid a compiler warning */
e9c71dd1 3764 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3765
3766 out:
3767 tcg_temp_free(t0);
3768 tcg_temp_free(t1);
e9c71dd1
TS
3769}
3770
7a387fff 3771static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3772 int rd, int rs)
3773{
923617a3 3774 const char *opn = "CLx";
20e1fb52 3775 TCGv t0;
6c5c1e20 3776
6af0bf9c 3777 if (rd == 0) {
ead9360e 3778 /* Treat as NOP. */
6af0bf9c 3779 MIPS_DEBUG("NOP");
20e1fb52 3780 return;
6af0bf9c 3781 }
20e1fb52 3782 t0 = tcg_temp_new();
6c5c1e20 3783 gen_load_gpr(t0, rs);
6af0bf9c
FB
3784 switch (opc) {
3785 case OPC_CLO:
4267d3e6 3786 case R6_OPC_CLO:
20e1fb52 3787 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3788 opn = "clo";
3789 break;
3790 case OPC_CLZ:
4267d3e6 3791 case R6_OPC_CLZ:
20e1fb52 3792 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3793 opn = "clz";
3794 break;
d26bc211 3795#if defined(TARGET_MIPS64)
7a387fff 3796 case OPC_DCLO:
4267d3e6 3797 case R6_OPC_DCLO:
20e1fb52 3798 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3799 opn = "dclo";
3800 break;
3801 case OPC_DCLZ:
4267d3e6 3802 case R6_OPC_DCLZ:
20e1fb52 3803 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3804 opn = "dclz";
3805 break;
3806#endif
6af0bf9c 3807 }
2abf314d 3808 (void)opn; /* avoid a compiler warning */
6af0bf9c 3809 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3810 tcg_temp_free(t0);
6af0bf9c
FB
3811}
3812
161f85e6 3813/* Godson integer instructions */
bd277fa1
RH
3814static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3815 int rd, int rs, int rt)
161f85e6
AJ
3816{
3817 const char *opn = "loongson";
3818 TCGv t0, t1;
3819
3820 if (rd == 0) {
3821 /* Treat as NOP. */
3822 MIPS_DEBUG("NOP");
3823 return;
3824 }
3825
3826 switch (opc) {
3827 case OPC_MULT_G_2E:
3828 case OPC_MULT_G_2F:
3829 case OPC_MULTU_G_2E:
3830 case OPC_MULTU_G_2F:
3831#if defined(TARGET_MIPS64)
3832 case OPC_DMULT_G_2E:
3833 case OPC_DMULT_G_2F:
3834 case OPC_DMULTU_G_2E:
3835 case OPC_DMULTU_G_2F:
3836#endif
3837 t0 = tcg_temp_new();
3838 t1 = tcg_temp_new();
3839 break;
3840 default:
3841 t0 = tcg_temp_local_new();
3842 t1 = tcg_temp_local_new();
3843 break;
3844 }
3845
3846 gen_load_gpr(t0, rs);
3847 gen_load_gpr(t1, rt);
3848
3849 switch (opc) {
3850 case OPC_MULT_G_2E:
3851 case OPC_MULT_G_2F:
3852 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3853 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3854 opn = "mult.g";
3855 break;
3856 case OPC_MULTU_G_2E:
3857 case OPC_MULTU_G_2F:
3858 tcg_gen_ext32u_tl(t0, t0);
3859 tcg_gen_ext32u_tl(t1, t1);
3860 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3861 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3862 opn = "multu.g";
3863 break;
3864 case OPC_DIV_G_2E:
3865 case OPC_DIV_G_2F:
3866 {
42a268c2
RH
3867 TCGLabel *l1 = gen_new_label();
3868 TCGLabel *l2 = gen_new_label();
3869 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3870 tcg_gen_ext32s_tl(t0, t0);
3871 tcg_gen_ext32s_tl(t1, t1);
3872 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3874 tcg_gen_br(l3);
3875 gen_set_label(l1);
3876 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3877 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3878 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3879 tcg_gen_br(l3);
3880 gen_set_label(l2);
3881 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3882 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3883 gen_set_label(l3);
3884 }
3885 opn = "div.g";
3886 break;
3887 case OPC_DIVU_G_2E:
3888 case OPC_DIVU_G_2F:
3889 {
42a268c2
RH
3890 TCGLabel *l1 = gen_new_label();
3891 TCGLabel *l2 = 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_NE, t1, 0, l1);
3895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3896 tcg_gen_br(l2);
3897 gen_set_label(l1);
3898 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3899 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3900 gen_set_label(l2);
3901 }
3902 opn = "divu.g";
3903 break;
3904 case OPC_MOD_G_2E:
3905 case OPC_MOD_G_2F:
3906 {
42a268c2
RH
3907 TCGLabel *l1 = gen_new_label();
3908 TCGLabel *l2 = gen_new_label();
3909 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3910 tcg_gen_ext32u_tl(t0, t0);
3911 tcg_gen_ext32u_tl(t1, t1);
3912 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3913 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3915 gen_set_label(l1);
3916 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3917 tcg_gen_br(l3);
3918 gen_set_label(l2);
3919 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3920 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3921 gen_set_label(l3);
3922 }
3923 opn = "mod.g";
3924 break;
3925 case OPC_MODU_G_2E:
3926 case OPC_MODU_G_2F:
3927 {
42a268c2
RH
3928 TCGLabel *l1 = gen_new_label();
3929 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3930 tcg_gen_ext32u_tl(t0, t0);
3931 tcg_gen_ext32u_tl(t1, t1);
3932 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3933 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3934 tcg_gen_br(l2);
3935 gen_set_label(l1);
3936 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3937 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3938 gen_set_label(l2);
3939 }
3940 opn = "modu.g";
3941 break;
3942#if defined(TARGET_MIPS64)
3943 case OPC_DMULT_G_2E:
3944 case OPC_DMULT_G_2F:
3945 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3946 opn = "dmult.g";
3947 break;
3948 case OPC_DMULTU_G_2E:
3949 case OPC_DMULTU_G_2F:
3950 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3951 opn = "dmultu.g";
3952 break;
3953 case OPC_DDIV_G_2E:
3954 case OPC_DDIV_G_2F:
3955 {
42a268c2
RH
3956 TCGLabel *l1 = gen_new_label();
3957 TCGLabel *l2 = gen_new_label();
3958 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3959 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3961 tcg_gen_br(l3);
3962 gen_set_label(l1);
3963 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3964 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3965 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3966 tcg_gen_br(l3);
3967 gen_set_label(l2);
3968 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3969 gen_set_label(l3);
3970 }
3971 opn = "ddiv.g";
3972 break;
3973 case OPC_DDIVU_G_2E:
3974 case OPC_DDIVU_G_2F:
3975 {
42a268c2
RH
3976 TCGLabel *l1 = gen_new_label();
3977 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3978 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3979 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3980 tcg_gen_br(l2);
3981 gen_set_label(l1);
3982 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3983 gen_set_label(l2);
3984 }
3985 opn = "ddivu.g";
3986 break;
3987 case OPC_DMOD_G_2E:
3988 case OPC_DMOD_G_2F:
3989 {
42a268c2
RH
3990 TCGLabel *l1 = gen_new_label();
3991 TCGLabel *l2 = gen_new_label();
3992 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3993 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3994 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3995 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3996 gen_set_label(l1);
3997 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3998 tcg_gen_br(l3);
3999 gen_set_label(l2);
4000 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4001 gen_set_label(l3);
4002 }
4003 opn = "dmod.g";
4004 break;
4005 case OPC_DMODU_G_2E:
4006 case OPC_DMODU_G_2F:
4007 {
42a268c2
RH
4008 TCGLabel *l1 = gen_new_label();
4009 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4010 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4011 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4012 tcg_gen_br(l2);
4013 gen_set_label(l1);
4014 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4015 gen_set_label(l2);
4016 }
4017 opn = "dmodu.g";
4018 break;
4019#endif
4020 }
4021
2abf314d 4022 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4023 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4024 tcg_temp_free(t0);
4025 tcg_temp_free(t1);
4026}
4027
bd277fa1
RH
4028/* Loongson multimedia instructions */
4029static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4030{
4031 const char *opn = "loongson_cp2";
4032 uint32_t opc, shift_max;
4033 TCGv_i64 t0, t1;
4034
4035 opc = MASK_LMI(ctx->opcode);
4036 switch (opc) {
4037 case OPC_ADD_CP2:
4038 case OPC_SUB_CP2:
4039 case OPC_DADD_CP2:
4040 case OPC_DSUB_CP2:
4041 t0 = tcg_temp_local_new_i64();
4042 t1 = tcg_temp_local_new_i64();
4043 break;
4044 default:
4045 t0 = tcg_temp_new_i64();
4046 t1 = tcg_temp_new_i64();
4047 break;
4048 }
4049
4050 gen_load_fpr64(ctx, t0, rs);
4051 gen_load_fpr64(ctx, t1, rt);
4052
4053#define LMI_HELPER(UP, LO) \
4054 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4055#define LMI_HELPER_1(UP, LO) \
4056 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4057#define LMI_DIRECT(UP, LO, OP) \
4058 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4059
4060 switch (opc) {
4061 LMI_HELPER(PADDSH, paddsh);
4062 LMI_HELPER(PADDUSH, paddush);
4063 LMI_HELPER(PADDH, paddh);
4064 LMI_HELPER(PADDW, paddw);
4065 LMI_HELPER(PADDSB, paddsb);
4066 LMI_HELPER(PADDUSB, paddusb);
4067 LMI_HELPER(PADDB, paddb);
4068
4069 LMI_HELPER(PSUBSH, psubsh);
4070 LMI_HELPER(PSUBUSH, psubush);
4071 LMI_HELPER(PSUBH, psubh);
4072 LMI_HELPER(PSUBW, psubw);
4073 LMI_HELPER(PSUBSB, psubsb);
4074 LMI_HELPER(PSUBUSB, psubusb);
4075 LMI_HELPER(PSUBB, psubb);
4076
4077 LMI_HELPER(PSHUFH, pshufh);
4078 LMI_HELPER(PACKSSWH, packsswh);
4079 LMI_HELPER(PACKSSHB, packsshb);
4080 LMI_HELPER(PACKUSHB, packushb);
4081
4082 LMI_HELPER(PUNPCKLHW, punpcklhw);
4083 LMI_HELPER(PUNPCKHHW, punpckhhw);
4084 LMI_HELPER(PUNPCKLBH, punpcklbh);
4085 LMI_HELPER(PUNPCKHBH, punpckhbh);
4086 LMI_HELPER(PUNPCKLWD, punpcklwd);
4087 LMI_HELPER(PUNPCKHWD, punpckhwd);
4088
4089 LMI_HELPER(PAVGH, pavgh);
4090 LMI_HELPER(PAVGB, pavgb);
4091 LMI_HELPER(PMAXSH, pmaxsh);
4092 LMI_HELPER(PMINSH, pminsh);
4093 LMI_HELPER(PMAXUB, pmaxub);
4094 LMI_HELPER(PMINUB, pminub);
4095
4096 LMI_HELPER(PCMPEQW, pcmpeqw);
4097 LMI_HELPER(PCMPGTW, pcmpgtw);
4098 LMI_HELPER(PCMPEQH, pcmpeqh);
4099 LMI_HELPER(PCMPGTH, pcmpgth);
4100 LMI_HELPER(PCMPEQB, pcmpeqb);
4101 LMI_HELPER(PCMPGTB, pcmpgtb);
4102
4103 LMI_HELPER(PSLLW, psllw);
4104 LMI_HELPER(PSLLH, psllh);
4105 LMI_HELPER(PSRLW, psrlw);
4106 LMI_HELPER(PSRLH, psrlh);
4107 LMI_HELPER(PSRAW, psraw);
4108 LMI_HELPER(PSRAH, psrah);
4109
4110 LMI_HELPER(PMULLH, pmullh);
4111 LMI_HELPER(PMULHH, pmulhh);
4112 LMI_HELPER(PMULHUH, pmulhuh);
4113 LMI_HELPER(PMADDHW, pmaddhw);
4114
4115 LMI_HELPER(PASUBUB, pasubub);
4116 LMI_HELPER_1(BIADD, biadd);
4117 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4118
4119 LMI_DIRECT(PADDD, paddd, add);
4120 LMI_DIRECT(PSUBD, psubd, sub);
4121 LMI_DIRECT(XOR_CP2, xor, xor);
4122 LMI_DIRECT(NOR_CP2, nor, nor);
4123 LMI_DIRECT(AND_CP2, and, and);
4124 LMI_DIRECT(PANDN, pandn, andc);
4125 LMI_DIRECT(OR, or, or);
4126
4127 case OPC_PINSRH_0:
4128 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4129 opn = "pinsrh_0";
4130 break;
4131 case OPC_PINSRH_1:
4132 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4133 opn = "pinsrh_1";
4134 break;
4135 case OPC_PINSRH_2:
4136 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4137 opn = "pinsrh_2";
4138 break;
4139 case OPC_PINSRH_3:
4140 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4141 opn = "pinsrh_3";
4142 break;
4143
4144 case OPC_PEXTRH:
4145 tcg_gen_andi_i64(t1, t1, 3);
4146 tcg_gen_shli_i64(t1, t1, 4);
4147 tcg_gen_shr_i64(t0, t0, t1);
4148 tcg_gen_ext16u_i64(t0, t0);
4149 opn = "pextrh";
4150 break;
4151
4152 case OPC_ADDU_CP2:
4153 tcg_gen_add_i64(t0, t0, t1);
4154 tcg_gen_ext32s_i64(t0, t0);
4155 opn = "addu";
4156 break;
4157 case OPC_SUBU_CP2:
4158 tcg_gen_sub_i64(t0, t0, t1);
4159 tcg_gen_ext32s_i64(t0, t0);
4160 opn = "addu";
4161 break;
4162
4163 case OPC_SLL_CP2:
4164 opn = "sll";
4165 shift_max = 32;
4166 goto do_shift;
4167 case OPC_SRL_CP2:
4168 opn = "srl";
4169 shift_max = 32;
4170 goto do_shift;
4171 case OPC_SRA_CP2:
4172 opn = "sra";
4173 shift_max = 32;
4174 goto do_shift;
4175 case OPC_DSLL_CP2:
4176 opn = "dsll";
4177 shift_max = 64;
4178 goto do_shift;
4179 case OPC_DSRL_CP2:
4180 opn = "dsrl";
4181 shift_max = 64;
4182 goto do_shift;
4183 case OPC_DSRA_CP2:
4184 opn = "dsra";
4185 shift_max = 64;
4186 goto do_shift;
4187 do_shift:
4188 /* Make sure shift count isn't TCG undefined behaviour. */
4189 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4190
4191 switch (opc) {
4192 case OPC_SLL_CP2:
4193 case OPC_DSLL_CP2:
4194 tcg_gen_shl_i64(t0, t0, t1);
4195 break;
4196 case OPC_SRA_CP2:
4197 case OPC_DSRA_CP2:
4198 /* Since SRA is UndefinedResult without sign-extended inputs,
4199 we can treat SRA and DSRA the same. */
4200 tcg_gen_sar_i64(t0, t0, t1);
4201 break;
4202 case OPC_SRL_CP2:
4203 /* We want to shift in zeros for SRL; zero-extend first. */
4204 tcg_gen_ext32u_i64(t0, t0);
4205 /* FALLTHRU */
4206 case OPC_DSRL_CP2:
4207 tcg_gen_shr_i64(t0, t0, t1);
4208 break;
4209 }
4210
4211 if (shift_max == 32) {
4212 tcg_gen_ext32s_i64(t0, t0);
4213 }
4214
4215 /* Shifts larger than MAX produce zero. */
4216 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4217 tcg_gen_neg_i64(t1, t1);
4218 tcg_gen_and_i64(t0, t0, t1);
4219 break;
4220
4221 case OPC_ADD_CP2:
4222 case OPC_DADD_CP2:
4223 {
4224 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4225 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4226
4227 tcg_gen_mov_i64(t2, t0);
4228 tcg_gen_add_i64(t0, t1, t2);
4229 if (opc == OPC_ADD_CP2) {
4230 tcg_gen_ext32s_i64(t0, t0);
4231 }
4232 tcg_gen_xor_i64(t1, t1, t2);
4233 tcg_gen_xor_i64(t2, t2, t0);
4234 tcg_gen_andc_i64(t1, t2, t1);
4235 tcg_temp_free_i64(t2);
4236 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4237 generate_exception(ctx, EXCP_OVERFLOW);
4238 gen_set_label(lab);
4239
4240 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4241 break;
4242 }
4243
4244 case OPC_SUB_CP2:
4245 case OPC_DSUB_CP2:
4246 {
4247 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4248 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4249
4250 tcg_gen_mov_i64(t2, t0);
4251 tcg_gen_sub_i64(t0, t1, t2);
4252 if (opc == OPC_SUB_CP2) {
4253 tcg_gen_ext32s_i64(t0, t0);
4254 }
4255 tcg_gen_xor_i64(t1, t1, t2);
4256 tcg_gen_xor_i64(t2, t2, t0);
4257 tcg_gen_and_i64(t1, t1, t2);
4258 tcg_temp_free_i64(t2);
4259 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4260 generate_exception(ctx, EXCP_OVERFLOW);
4261 gen_set_label(lab);
4262
4263 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4264 break;
4265 }
4266
4267 case OPC_PMULUW:
4268 tcg_gen_ext32u_i64(t0, t0);
4269 tcg_gen_ext32u_i64(t1, t1);
4270 tcg_gen_mul_i64(t0, t0, t1);
4271 opn = "pmuluw";
4272 break;
4273
4274 case OPC_SEQU_CP2:
4275 case OPC_SEQ_CP2:
4276 case OPC_SLTU_CP2:
4277 case OPC_SLT_CP2:
4278 case OPC_SLEU_CP2:
4279 case OPC_SLE_CP2:
4280 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4281 FD field is the CC field? */
4282 default:
4283 MIPS_INVAL(opn);
4284 generate_exception(ctx, EXCP_RI);
4285 return;
4286 }
4287
4288#undef LMI_HELPER
4289#undef LMI_DIRECT
4290
4291 gen_store_fpr64(ctx, t0, rd);
4292
4293 (void)opn; /* avoid a compiler warning */
4294 MIPS_DEBUG("%s %s, %s, %s", opn,
4295 fregnames[rd], fregnames[rs], fregnames[rt]);
4296 tcg_temp_free_i64(t0);
4297 tcg_temp_free_i64(t1);
4298}
4299
6af0bf9c 4300/* Traps */
7a387fff 4301static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4302 int rs, int rt, int16_t imm)
4303{
4304 int cond;
cdc0faa6 4305 TCGv t0 = tcg_temp_new();
1ba74fb8 4306 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4307
4308 cond = 0;
4309 /* Load needed operands */
4310 switch (opc) {
4311 case OPC_TEQ:
4312 case OPC_TGE:
4313 case OPC_TGEU:
4314 case OPC_TLT:
4315 case OPC_TLTU:
4316 case OPC_TNE:
4317 /* Compare two registers */
4318 if (rs != rt) {
be24bb4f
TS
4319 gen_load_gpr(t0, rs);
4320 gen_load_gpr(t1, rt);
6af0bf9c
FB
4321 cond = 1;
4322 }
179e32bb 4323 break;
6af0bf9c
FB
4324 case OPC_TEQI:
4325 case OPC_TGEI:
4326 case OPC_TGEIU:
4327 case OPC_TLTI:
4328 case OPC_TLTIU:
4329 case OPC_TNEI:
4330 /* Compare register to immediate */
4331 if (rs != 0 || imm != 0) {
be24bb4f
TS
4332 gen_load_gpr(t0, rs);
4333 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4334 cond = 1;
4335 }
4336 break;
4337 }
4338 if (cond == 0) {
4339 switch (opc) {
4340 case OPC_TEQ: /* rs == rs */
4341 case OPC_TEQI: /* r0 == 0 */
4342 case OPC_TGE: /* rs >= rs */
4343 case OPC_TGEI: /* r0 >= 0 */
4344 case OPC_TGEU: /* rs >= rs unsigned */
4345 case OPC_TGEIU: /* r0 >= 0 unsigned */
4346 /* Always trap */
cdc0faa6 4347 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4348 break;
4349 case OPC_TLT: /* rs < rs */
4350 case OPC_TLTI: /* r0 < 0 */
4351 case OPC_TLTU: /* rs < rs unsigned */
4352 case OPC_TLTIU: /* r0 < 0 unsigned */
4353 case OPC_TNE: /* rs != rs */
4354 case OPC_TNEI: /* r0 != 0 */
ead9360e 4355 /* Never trap: treat as NOP. */
cdc0faa6 4356 break;
6af0bf9c
FB
4357 }
4358 } else {
42a268c2 4359 TCGLabel *l1 = gen_new_label();
cdc0faa6 4360
6af0bf9c
FB
4361 switch (opc) {
4362 case OPC_TEQ:
4363 case OPC_TEQI:
cdc0faa6 4364 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4365 break;
4366 case OPC_TGE:
4367 case OPC_TGEI:
cdc0faa6 4368 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4369 break;
4370 case OPC_TGEU:
4371 case OPC_TGEIU:
cdc0faa6 4372 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4373 break;
4374 case OPC_TLT:
4375 case OPC_TLTI:
cdc0faa6 4376 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4377 break;
4378 case OPC_TLTU:
4379 case OPC_TLTIU:
cdc0faa6 4380 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4381 break;
4382 case OPC_TNE:
4383 case OPC_TNEI:
cdc0faa6 4384 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4385 break;
6af0bf9c 4386 }
cdc0faa6 4387 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4388 gen_set_label(l1);
4389 }
be24bb4f
TS
4390 tcg_temp_free(t0);
4391 tcg_temp_free(t1);
6af0bf9c
FB
4392}
4393
356265ae 4394static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4395{
6e256c93
FB
4396 TranslationBlock *tb;
4397 tb = ctx->tb;
7b270ef2
NF
4398 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4399 likely(!ctx->singlestep_enabled)) {
57fec1fe 4400 tcg_gen_goto_tb(n);
9b9e4393 4401 gen_save_pc(dest);
8cfd0495 4402 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4403 } else {
9b9e4393 4404 gen_save_pc(dest);
7b270ef2
NF
4405 if (ctx->singlestep_enabled) {
4406 save_cpu_state(ctx, 0);
895c2d04 4407 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4408 }
57fec1fe 4409 tcg_gen_exit_tb(0);
6e256c93 4410 }
c53be334
FB
4411}
4412
6af0bf9c 4413/* Branches (before delay slot) */
7a387fff 4414static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4415 int insn_bytes,
b231c103
YK
4416 int rs, int rt, int32_t offset,
4417 int delayslot_size)
6af0bf9c 4418{
d077b6f7 4419 target_ulong btgt = -1;
3ad4bb2d 4420 int blink = 0;
2fdbad25 4421 int bcond_compute = 0;
1ba74fb8
AJ
4422 TCGv t0 = tcg_temp_new();
4423 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4424
4425 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4426#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4427 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4428 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4429#endif
3ad4bb2d 4430 generate_exception(ctx, EXCP_RI);
6c5c1e20 4431 goto out;
3ad4bb2d 4432 }
6af0bf9c 4433
6af0bf9c
FB
4434 /* Load needed operands */
4435 switch (opc) {
4436 case OPC_BEQ:
4437 case OPC_BEQL:
4438 case OPC_BNE:
4439 case OPC_BNEL:
4440 /* Compare two registers */
4441 if (rs != rt) {
6c5c1e20
TS
4442 gen_load_gpr(t0, rs);
4443 gen_load_gpr(t1, rt);
2fdbad25 4444 bcond_compute = 1;
6af0bf9c 4445 }
7dca4ad0 4446 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4447 break;
4448 case OPC_BGEZ:
4449 case OPC_BGEZAL:
4450 case OPC_BGEZALL:
4451 case OPC_BGEZL:
4452 case OPC_BGTZ:
4453 case OPC_BGTZL:
4454 case OPC_BLEZ:
4455 case OPC_BLEZL:
4456 case OPC_BLTZ:
4457 case OPC_BLTZAL:
4458 case OPC_BLTZALL:
4459 case OPC_BLTZL:
4460 /* Compare to zero */
4461 if (rs != 0) {
6c5c1e20 4462 gen_load_gpr(t0, rs);
2fdbad25 4463 bcond_compute = 1;
6af0bf9c 4464 }
7dca4ad0 4465 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4466 break;
e45a93e2
JL
4467 case OPC_BPOSGE32:
4468#if defined(TARGET_MIPS64)
4469 case OPC_BPOSGE64:
4470 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4471#else
4472 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4473#endif
4474 bcond_compute = 1;
4475 btgt = ctx->pc + insn_bytes + offset;
4476 break;
6af0bf9c
FB
4477 case OPC_J:
4478 case OPC_JAL:
364d4831 4479 case OPC_JALX:
6af0bf9c 4480 /* Jump to immediate */
7dca4ad0 4481 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4482 break;
4483 case OPC_JR:
4484 case OPC_JALR:
4485 /* Jump to register */
7a387fff
TS
4486 if (offset != 0 && offset != 16) {
4487 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4488 others are reserved. */
923617a3 4489 MIPS_INVAL("jump hint");
6af0bf9c 4490 generate_exception(ctx, EXCP_RI);
6c5c1e20 4491 goto out;
6af0bf9c 4492 }
d077b6f7 4493 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4494 break;
4495 default:
4496 MIPS_INVAL("branch/jump");
4497 generate_exception(ctx, EXCP_RI);
6c5c1e20 4498 goto out;
6af0bf9c 4499 }
2fdbad25 4500 if (bcond_compute == 0) {
6af0bf9c
FB
4501 /* No condition to be computed */
4502 switch (opc) {
4503 case OPC_BEQ: /* rx == rx */
4504 case OPC_BEQL: /* rx == rx likely */
4505 case OPC_BGEZ: /* 0 >= 0 */
4506 case OPC_BGEZL: /* 0 >= 0 likely */
4507 case OPC_BLEZ: /* 0 <= 0 */
4508 case OPC_BLEZL: /* 0 <= 0 likely */
4509 /* Always take */
4ad40f36 4510 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4511 MIPS_DEBUG("balways");
4512 break;
4513 case OPC_BGEZAL: /* 0 >= 0 */
4514 case OPC_BGEZALL: /* 0 >= 0 likely */
4515 /* Always take and link */
4516 blink = 31;
4ad40f36 4517 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4518 MIPS_DEBUG("balways and link");
4519 break;
4520 case OPC_BNE: /* rx != rx */
4521 case OPC_BGTZ: /* 0 > 0 */
4522 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4523 /* Treat as NOP. */
6af0bf9c 4524 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4525 goto out;
eeef26cd 4526 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4527 /* Handle as an unconditional branch to get correct delay
4528 slot checking. */
4529 blink = 31;
b231c103 4530 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4531 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4532 MIPS_DEBUG("bnever and link");
3c824109 4533 break;
eeef26cd 4534 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4535 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4536 /* Skip the instruction in the delay slot */
4537 MIPS_DEBUG("bnever, link and skip");
4538 ctx->pc += 4;
6c5c1e20 4539 goto out;
6af0bf9c
FB
4540 case OPC_BNEL: /* rx != rx likely */
4541 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4542 case OPC_BLTZL: /* 0 < 0 likely */
4543 /* Skip the instruction in the delay slot */
4544 MIPS_DEBUG("bnever and skip");
9898128f 4545 ctx->pc += 4;
6c5c1e20 4546 goto out;
6af0bf9c 4547 case OPC_J:
4ad40f36 4548 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4549 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4550 break;
364d4831
NF
4551 case OPC_JALX:
4552 ctx->hflags |= MIPS_HFLAG_BX;
4553 /* Fallthrough */
6af0bf9c
FB
4554 case OPC_JAL:
4555 blink = 31;
4ad40f36 4556 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4557 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4558 break;
4559 case OPC_JR:
4ad40f36 4560 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4561 MIPS_DEBUG("jr %s", regnames[rs]);
4562 break;
4563 case OPC_JALR:
4564 blink = rt;
4ad40f36 4565 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4566 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4567 break;
4568 default:
4569 MIPS_INVAL("branch/jump");
4570 generate_exception(ctx, EXCP_RI);
6c5c1e20 4571 goto out;
6af0bf9c
FB
4572 }
4573 } else {
4574 switch (opc) {
4575 case OPC_BEQ:
e68dd28f 4576 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4577 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4578 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4579 goto not_likely;
4580 case OPC_BEQL:
e68dd28f 4581 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4582 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4583 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4584 goto likely;
4585 case OPC_BNE:
e68dd28f 4586 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4587 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4588 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4589 goto not_likely;
4590 case OPC_BNEL:
e68dd28f 4591 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4592 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4593 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4594 goto likely;
4595 case OPC_BGEZ:
e68dd28f 4596 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4597 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4598 goto not_likely;
4599 case OPC_BGEZL:
e68dd28f 4600 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4601 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4602 goto likely;
4603 case OPC_BGEZAL:
e68dd28f 4604 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4605 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4606 blink = 31;
4607 goto not_likely;
4608 case OPC_BGEZALL:
e68dd28f 4609 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4610 blink = 31;
d077b6f7 4611 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4612 goto likely;
4613 case OPC_BGTZ:
e68dd28f 4614 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4615 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4616 goto not_likely;
4617 case OPC_BGTZL:
e68dd28f 4618 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4619 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4620 goto likely;
4621 case OPC_BLEZ:
e68dd28f 4622 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4623 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4624 goto not_likely;
4625 case OPC_BLEZL:
e68dd28f 4626 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4627 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4628 goto likely;
4629 case OPC_BLTZ:
e68dd28f 4630 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4631 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4632 goto not_likely;
4633 case OPC_BLTZL:
e68dd28f 4634 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4635 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4636 goto likely;
e45a93e2
JL
4637 case OPC_BPOSGE32:
4638 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4639 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4640 goto not_likely;
4641#if defined(TARGET_MIPS64)
4642 case OPC_BPOSGE64:
4643 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4644 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4645 goto not_likely;
4646#endif
6af0bf9c 4647 case OPC_BLTZAL:
e68dd28f 4648 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4649 blink = 31;
d077b6f7 4650 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4651 not_likely:
4ad40f36 4652 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4653 break;
4654 case OPC_BLTZALL:
e68dd28f 4655 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4656 blink = 31;
d077b6f7 4657 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4658 likely:
4ad40f36 4659 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4660 break;
c53f4a62
TS
4661 default:
4662 MIPS_INVAL("conditional branch/jump");
4663 generate_exception(ctx, EXCP_RI);
6c5c1e20 4664 goto out;
6af0bf9c 4665 }
6af0bf9c 4666 }
923617a3 4667 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4668 blink, ctx->hflags, btgt);
9b9e4393 4669
d077b6f7 4670 ctx->btarget = btgt;
b231c103
YK
4671
4672 switch (delayslot_size) {
4673 case 2:
4674 ctx->hflags |= MIPS_HFLAG_BDS16;
4675 break;
4676 case 4:
4677 ctx->hflags |= MIPS_HFLAG_BDS32;
4678 break;
4679 }
4680
6af0bf9c 4681 if (blink > 0) {
b231c103 4682 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4683 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4684
364d4831 4685 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4686 }
6c5c1e20
TS
4687
4688 out:
364d4831
NF
4689 if (insn_bytes == 2)
4690 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4691 tcg_temp_free(t0);
4692 tcg_temp_free(t1);
6af0bf9c
FB
4693}
4694
7a387fff
TS
4695/* special3 bitfield operations */
4696static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4697 int rs, int lsb, int msb)
7a387fff 4698{
a7812ae4
PB
4699 TCGv t0 = tcg_temp_new();
4700 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4701
4702 gen_load_gpr(t1, rs);
7a387fff
TS
4703 switch (opc) {
4704 case OPC_EXT:
4705 if (lsb + msb > 31)
4706 goto fail;
505ad7c2
AJ
4707 tcg_gen_shri_tl(t0, t1, lsb);
4708 if (msb != 31) {
4709 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4710 } else {
4711 tcg_gen_ext32s_tl(t0, t0);
4712 }
7a387fff 4713 break;
c6d6dd7c 4714#if defined(TARGET_MIPS64)
7a387fff 4715 case OPC_DEXTM:
505ad7c2
AJ
4716 tcg_gen_shri_tl(t0, t1, lsb);
4717 if (msb != 31) {
4718 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4719 }
7a387fff
TS
4720 break;
4721 case OPC_DEXTU:
505ad7c2
AJ
4722 tcg_gen_shri_tl(t0, t1, lsb + 32);
4723 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4724 break;
4725 case OPC_DEXT:
505ad7c2
AJ
4726 tcg_gen_shri_tl(t0, t1, lsb);
4727 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4728 break;
c6d6dd7c 4729#endif
7a387fff
TS
4730 case OPC_INS:
4731 if (lsb > msb)
4732 goto fail;
6c5c1e20 4733 gen_load_gpr(t0, rt);
e0d002f1 4734 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4735 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4736 break;
c6d6dd7c 4737#if defined(TARGET_MIPS64)
7a387fff 4738 case OPC_DINSM:
6c5c1e20 4739 gen_load_gpr(t0, rt);
e0d002f1 4740 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4741 break;
4742 case OPC_DINSU:
6c5c1e20 4743 gen_load_gpr(t0, rt);
e0d002f1 4744 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4745 break;
4746 case OPC_DINS:
6c5c1e20 4747 gen_load_gpr(t0, rt);
e0d002f1 4748 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4749 break;
c6d6dd7c 4750#endif
7a387fff
TS
4751 default:
4752fail:
4753 MIPS_INVAL("bitops");
4754 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4755 tcg_temp_free(t0);
4756 tcg_temp_free(t1);
7a387fff
TS
4757 return;
4758 }
6c5c1e20
TS
4759 gen_store_gpr(t0, rt);
4760 tcg_temp_free(t0);
4761 tcg_temp_free(t1);
7a387fff
TS
4762}
4763
49bcf33c
AJ
4764static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4765{
3a55fa47 4766 TCGv t0;
49bcf33c 4767
3a55fa47
AJ
4768 if (rd == 0) {
4769 /* If no destination, treat it as a NOP. */
4770 MIPS_DEBUG("NOP");
4771 return;
4772 }
4773
4774 t0 = tcg_temp_new();
4775 gen_load_gpr(t0, rt);
49bcf33c
AJ
4776 switch (op2) {
4777 case OPC_WSBH:
3a55fa47
AJ
4778 {
4779 TCGv t1 = tcg_temp_new();
4780
4781 tcg_gen_shri_tl(t1, t0, 8);
4782 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4783 tcg_gen_shli_tl(t0, t0, 8);
4784 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4785 tcg_gen_or_tl(t0, t0, t1);
4786 tcg_temp_free(t1);
4787 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4788 }
49bcf33c
AJ
4789 break;
4790 case OPC_SEB:
3a55fa47 4791 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4792 break;
4793 case OPC_SEH:
3a55fa47 4794 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4795 break;
4796#if defined(TARGET_MIPS64)
4797 case OPC_DSBH:
3a55fa47
AJ
4798 {
4799 TCGv t1 = tcg_temp_new();
4800
4801 tcg_gen_shri_tl(t1, t0, 8);
4802 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4803 tcg_gen_shli_tl(t0, t0, 8);
4804 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4805 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4806 tcg_temp_free(t1);
4807 }
49bcf33c
AJ
4808 break;
4809 case OPC_DSHD:
3a55fa47
AJ
4810 {
4811 TCGv t1 = tcg_temp_new();
4812
4813 tcg_gen_shri_tl(t1, t0, 16);
4814 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4815 tcg_gen_shli_tl(t0, t0, 16);
4816 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4817 tcg_gen_or_tl(t0, t0, t1);
4818 tcg_gen_shri_tl(t1, t0, 32);
4819 tcg_gen_shli_tl(t0, t0, 32);
4820 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4821 tcg_temp_free(t1);
4822 }
49bcf33c
AJ
4823 break;
4824#endif
4825 default:
4826 MIPS_INVAL("bsfhl");
4827 generate_exception(ctx, EXCP_RI);
4828 tcg_temp_free(t0);
49bcf33c
AJ
4829 return;
4830 }
49bcf33c 4831 tcg_temp_free(t0);
49bcf33c
AJ
4832}
4833
f1aa6320 4834#ifndef CONFIG_USER_ONLY
0eaef5aa 4835/* CP0 (MMU and control) */
d9bea114 4836static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4837{
d9bea114 4838 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4839
d9bea114
AJ
4840 tcg_gen_ld_i32(t0, cpu_env, off);
4841 tcg_gen_ext_i32_tl(arg, t0);
4842 tcg_temp_free_i32(t0);
4f57689a
TS
4843}
4844
d9bea114 4845static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4846{
d9bea114
AJ
4847 tcg_gen_ld_tl(arg, cpu_env, off);
4848 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4849}
4850
d9bea114 4851static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4852{
d9bea114 4853 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4854
d9bea114
AJ
4855 tcg_gen_trunc_tl_i32(t0, arg);
4856 tcg_gen_st_i32(t0, cpu_env, off);
4857 tcg_temp_free_i32(t0);
f1aa6320
TS
4858}
4859
d9bea114 4860static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4861{
d9bea114
AJ
4862 tcg_gen_ext32s_tl(arg, arg);
4863 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4864}
4865
e98c0d17
LA
4866static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4867{
4868 if (ctx->insn_flags & ISA_MIPS32R6) {
4869 tcg_gen_movi_tl(arg, 0);
4870 } else {
4871 tcg_gen_movi_tl(arg, ~0);
4872 }
4873}
4874
f31b035a
LA
4875#define CP0_CHECK(c) \
4876 do { \
4877 if (!(c)) { \
4878 goto cp0_unimplemented; \
4879 } \
4880 } while (0)
4881
d75c135e 4882static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4883{
7a387fff 4884 const char *rn = "invalid";
873eb012 4885
e189e748 4886 if (sel != 0)
d75c135e 4887 check_insn(ctx, ISA_MIPS32);
e189e748 4888
873eb012
TS
4889 switch (reg) {
4890 case 0:
7a387fff
TS
4891 switch (sel) {
4892 case 0:
7db13fae 4893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4894 rn = "Index";
4895 break;
4896 case 1:
f31b035a 4897 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4898 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4899 rn = "MVPControl";
ead9360e 4900 break;
7a387fff 4901 case 2:
f31b035a 4902 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4903 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4904 rn = "MVPConf0";
ead9360e 4905 break;
7a387fff 4906 case 3:
f31b035a 4907 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4908 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4909 rn = "MVPConf1";
ead9360e 4910 break;
7a387fff 4911 default:
f31b035a 4912 goto cp0_unimplemented;
7a387fff 4913 }
873eb012
TS
4914 break;
4915 case 1:
7a387fff
TS
4916 switch (sel) {
4917 case 0:
f31b035a 4918 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4919 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4920 rn = "Random";
2423f660 4921 break;
7a387fff 4922 case 1:
f31b035a 4923 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4924 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4925 rn = "VPEControl";
ead9360e 4926 break;
7a387fff 4927 case 2:
f31b035a 4928 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4930 rn = "VPEConf0";
ead9360e 4931 break;
7a387fff 4932 case 3:
f31b035a 4933 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4935 rn = "VPEConf1";
ead9360e 4936 break;
7a387fff 4937 case 4:
f31b035a 4938 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4939 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4940 rn = "YQMask";
ead9360e 4941 break;
7a387fff 4942 case 5:
f31b035a 4943 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4944 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4945 rn = "VPESchedule";
ead9360e 4946 break;
7a387fff 4947 case 6:
f31b035a 4948 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4949 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4950 rn = "VPEScheFBack";
ead9360e 4951 break;
7a387fff 4952 case 7:
f31b035a 4953 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4955 rn = "VPEOpt";
ead9360e 4956 break;
7a387fff 4957 default:
f31b035a 4958 goto cp0_unimplemented;
7a387fff 4959 }
873eb012
TS
4960 break;
4961 case 2:
7a387fff
TS
4962 switch (sel) {
4963 case 0:
7db13fae 4964 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4965#if defined(TARGET_MIPS64)
4966 if (ctx->rxi) {
4967 TCGv tmp = tcg_temp_new();
d3b1979d 4968 tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
7207c7f9
LA
4969 tcg_gen_shri_tl(tmp, tmp, 32);
4970 tcg_gen_or_tl(arg, arg, tmp);
4971 tcg_temp_free(tmp);
4972 }
4973#endif
d9bea114 4974 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4975 rn = "EntryLo0";
4976 break;
7a387fff 4977 case 1:
f31b035a 4978 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4979 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4980 rn = "TCStatus";
ead9360e 4981 break;
7a387fff 4982 case 2:
f31b035a 4983 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4984 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4985 rn = "TCBind";
ead9360e 4986 break;
7a387fff 4987 case 3:
f31b035a 4988 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4989 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4990 rn = "TCRestart";
ead9360e 4991 break;
7a387fff 4992 case 4:
f31b035a 4993 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4994 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4995 rn = "TCHalt";
ead9360e 4996 break;
7a387fff 4997 case 5:
f31b035a 4998 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4999 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5000 rn = "TCContext";
ead9360e 5001 break;
7a387fff 5002 case 6:
f31b035a 5003 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5004 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5005 rn = "TCSchedule";
ead9360e 5006 break;
7a387fff 5007 case 7:
f31b035a 5008 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5009 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5010 rn = "TCScheFBack";
ead9360e 5011 break;
7a387fff 5012 default:
f31b035a 5013 goto cp0_unimplemented;
7a387fff 5014 }
873eb012
TS
5015 break;
5016 case 3:
7a387fff
TS
5017 switch (sel) {
5018 case 0:
7db13fae 5019 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
5020#if defined(TARGET_MIPS64)
5021 if (ctx->rxi) {
5022 TCGv tmp = tcg_temp_new();
d3b1979d 5023 tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
7207c7f9
LA
5024 tcg_gen_shri_tl(tmp, tmp, 32);
5025 tcg_gen_or_tl(arg, arg, tmp);
5026 tcg_temp_free(tmp);
5027 }
5028#endif
d9bea114 5029 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5030 rn = "EntryLo1";
5031 break;
7a387fff 5032 default:
f31b035a 5033 goto cp0_unimplemented;
1579a72e 5034 }
873eb012
TS
5035 break;
5036 case 4:
7a387fff
TS
5037 switch (sel) {
5038 case 0:
7db13fae 5039 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5040 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5041 rn = "Context";
5042 break;
7a387fff 5043 case 1:
d9bea114 5044// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5045 rn = "ContextConfig";
f31b035a 5046 goto cp0_unimplemented;
2423f660 5047// break;
d279279e 5048 case 2:
f31b035a
LA
5049 CP0_CHECK(ctx->ulri);
5050 tcg_gen_ld32s_tl(arg, cpu_env,
5051 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5052 rn = "UserLocal";
d279279e 5053 break;
7a387fff 5054 default:
f31b035a 5055 goto cp0_unimplemented;
1579a72e 5056 }
873eb012
TS
5057 break;
5058 case 5:
7a387fff
TS
5059 switch (sel) {
5060 case 0:
7db13fae 5061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5062 rn = "PageMask";
5063 break;
7a387fff 5064 case 1:
d75c135e 5065 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5066 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5067 rn = "PageGrain";
5068 break;
7a387fff 5069 default:
f31b035a 5070 goto cp0_unimplemented;
1579a72e 5071 }
873eb012
TS
5072 break;
5073 case 6:
7a387fff
TS
5074 switch (sel) {
5075 case 0:
7db13fae 5076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5077 rn = "Wired";
5078 break;
7a387fff 5079 case 1:
d75c135e 5080 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5082 rn = "SRSConf0";
ead9360e 5083 break;
7a387fff 5084 case 2:
d75c135e 5085 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5087 rn = "SRSConf1";
ead9360e 5088 break;
7a387fff 5089 case 3:
d75c135e 5090 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5092 rn = "SRSConf2";
ead9360e 5093 break;
7a387fff 5094 case 4:
d75c135e 5095 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5097 rn = "SRSConf3";
ead9360e 5098 break;
7a387fff 5099 case 5:
d75c135e 5100 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5102 rn = "SRSConf4";
ead9360e 5103 break;
7a387fff 5104 default:
f31b035a 5105 goto cp0_unimplemented;
1579a72e 5106 }
873eb012 5107 break;
8c0fdd85 5108 case 7:
7a387fff
TS
5109 switch (sel) {
5110 case 0:
d75c135e 5111 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5113 rn = "HWREna";
5114 break;
7a387fff 5115 default:
f31b035a 5116 goto cp0_unimplemented;
1579a72e 5117 }
8c0fdd85 5118 break;
873eb012 5119 case 8:
7a387fff
TS
5120 switch (sel) {
5121 case 0:
7db13fae 5122 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5123 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5124 rn = "BadVAddr";
2423f660 5125 break;
aea14095 5126 case 1:
f31b035a
LA
5127 CP0_CHECK(ctx->bi);
5128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5129 rn = "BadInstr";
aea14095
LA
5130 break;
5131 case 2:
f31b035a
LA
5132 CP0_CHECK(ctx->bp);
5133 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5134 rn = "BadInstrP";
aea14095 5135 break;
7a387fff 5136 default:
f31b035a 5137 goto cp0_unimplemented;
aea14095 5138 }
873eb012
TS
5139 break;
5140 case 9:
7a387fff
TS
5141 switch (sel) {
5142 case 0:
2e70f6ef 5143 /* Mark as an IO operation because we read the time. */
bd79255d 5144 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5145 gen_io_start();
bd79255d 5146 }
895c2d04 5147 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5148 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5149 gen_io_end();
2e70f6ef 5150 }
55807224
EI
5151 /* Break the TB to be able to take timer interrupts immediately
5152 after reading count. */
5153 ctx->bstate = BS_STOP;
2423f660
TS
5154 rn = "Count";
5155 break;
5156 /* 6,7 are implementation dependent */
7a387fff 5157 default:
f31b035a 5158 goto cp0_unimplemented;
2423f660 5159 }
873eb012
TS
5160 break;
5161 case 10:
7a387fff
TS
5162 switch (sel) {
5163 case 0:
7db13fae 5164 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5165 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5166 rn = "EntryHi";
5167 break;
7a387fff 5168 default:
f31b035a 5169 goto cp0_unimplemented;
1579a72e 5170 }
873eb012
TS
5171 break;
5172 case 11:
7a387fff
TS
5173 switch (sel) {
5174 case 0:
7db13fae 5175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5176 rn = "Compare";
5177 break;
5178 /* 6,7 are implementation dependent */
7a387fff 5179 default:
f31b035a 5180 goto cp0_unimplemented;
2423f660 5181 }
873eb012
TS
5182 break;
5183 case 12:
7a387fff
TS
5184 switch (sel) {
5185 case 0:
7db13fae 5186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5187 rn = "Status";
5188 break;
7a387fff 5189 case 1:
d75c135e 5190 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5192 rn = "IntCtl";
5193 break;
7a387fff 5194 case 2:
d75c135e 5195 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5197 rn = "SRSCtl";
5198 break;
7a387fff 5199 case 3:
d75c135e 5200 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5202 rn = "SRSMap";
fd88b6ab 5203 break;
7a387fff 5204 default:
f31b035a 5205 goto cp0_unimplemented;
7a387fff 5206 }
873eb012
TS
5207 break;
5208 case 13:
7a387fff
TS
5209 switch (sel) {
5210 case 0:
7db13fae 5211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5212 rn = "Cause";
5213 break;
7a387fff 5214 default:
f31b035a 5215 goto cp0_unimplemented;
7a387fff 5216 }
873eb012
TS
5217 break;
5218 case 14:
7a387fff
TS
5219 switch (sel) {
5220 case 0:
7db13fae 5221 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5222 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5223 rn = "EPC";
5224 break;
7a387fff 5225 default:
f31b035a 5226 goto cp0_unimplemented;
1579a72e 5227 }
873eb012
TS
5228 break;
5229 case 15:
7a387fff
TS
5230 switch (sel) {
5231 case 0:
7db13fae 5232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5233 rn = "PRid";
5234 break;
7a387fff 5235 case 1:
d75c135e 5236 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5238 rn = "EBase";
5239 break;
7a387fff 5240 default:
f31b035a 5241 goto cp0_unimplemented;
7a387fff 5242 }
873eb012
TS
5243 break;
5244 case 16:
5245 switch (sel) {
5246 case 0:
7db13fae 5247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5248 rn = "Config";
5249 break;
5250 case 1:
7db13fae 5251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5252 rn = "Config1";
5253 break;
7a387fff 5254 case 2:
7db13fae 5255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5256 rn = "Config2";
5257 break;
5258 case 3:
7db13fae 5259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5260 rn = "Config3";
5261 break;
b4160af1
PJ
5262 case 4:
5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5264 rn = "Config4";
5265 break;
b4dd99a3
PJ
5266 case 5:
5267 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5268 rn = "Config5";
5269 break;
e397ee33
TS
5270 /* 6,7 are implementation dependent */
5271 case 6:
7db13fae 5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5273 rn = "Config6";
5274 break;
5275 case 7:
7db13fae 5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5277 rn = "Config7";
5278 break;
873eb012 5279 default:
f31b035a 5280 goto cp0_unimplemented;
873eb012
TS
5281 }
5282 break;
5283 case 17:
7a387fff
TS
5284 switch (sel) {
5285 case 0:
895c2d04 5286 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5287 rn = "LLAddr";
5288 break;
7a387fff 5289 default:
f31b035a 5290 goto cp0_unimplemented;
7a387fff 5291 }
873eb012
TS
5292 break;
5293 case 18:
7a387fff 5294 switch (sel) {
fd88b6ab 5295 case 0 ... 7:
895c2d04 5296 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5297 rn = "WatchLo";
5298 break;
7a387fff 5299 default:
f31b035a 5300 goto cp0_unimplemented;
7a387fff 5301 }
873eb012
TS
5302 break;
5303 case 19:
7a387fff 5304 switch (sel) {
fd88b6ab 5305 case 0 ...7:
895c2d04 5306 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5307 rn = "WatchHi";
5308 break;
7a387fff 5309 default:
f31b035a 5310 goto cp0_unimplemented;
7a387fff 5311 }
873eb012 5312 break;
8c0fdd85 5313 case 20:
7a387fff
TS
5314 switch (sel) {
5315 case 0:
d26bc211 5316#if defined(TARGET_MIPS64)
d75c135e 5317 check_insn(ctx, ISA_MIPS3);
7db13fae 5318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5319 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5320 rn = "XContext";
5321 break;
703eaf37 5322#endif
7a387fff 5323 default:
f31b035a 5324 goto cp0_unimplemented;
7a387fff 5325 }
8c0fdd85
TS
5326 break;
5327 case 21:
7a387fff 5328 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5329 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5330 switch (sel) {
5331 case 0:
7db13fae 5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5333 rn = "Framemask";
5334 break;
7a387fff 5335 default:
f31b035a 5336 goto cp0_unimplemented;
7a387fff 5337 }
8c0fdd85
TS
5338 break;
5339 case 22:
d9bea114 5340 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5341 rn = "'Diagnostic"; /* implementation dependent */
5342 break;
873eb012 5343 case 23:
7a387fff
TS
5344 switch (sel) {
5345 case 0:
895c2d04 5346 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5347 rn = "Debug";
5348 break;
7a387fff 5349 case 1:
d9bea114 5350// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5351 rn = "TraceControl";
5352// break;
7a387fff 5353 case 2:
d9bea114 5354// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5355 rn = "TraceControl2";
5356// break;
7a387fff 5357 case 3:
d9bea114 5358// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5359 rn = "UserTraceData";
5360// break;
7a387fff 5361 case 4:
d9bea114 5362// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5363 rn = "TraceBPC";
5364// break;
7a387fff 5365 default:
f31b035a 5366 goto cp0_unimplemented;
7a387fff 5367 }
873eb012
TS
5368 break;
5369 case 24:
7a387fff
TS
5370 switch (sel) {
5371 case 0:
f0b3f3ae 5372 /* EJTAG support */
7db13fae 5373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5374 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5375 rn = "DEPC";
5376 break;
7a387fff 5377 default:
f31b035a 5378 goto cp0_unimplemented;
7a387fff 5379 }
873eb012 5380 break;
8c0fdd85 5381 case 25:
7a387fff
TS
5382 switch (sel) {
5383 case 0:
7db13fae 5384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5385 rn = "Performance0";
7a387fff
TS
5386 break;
5387 case 1:
d9bea114 5388// gen_helper_mfc0_performance1(arg);
2423f660
TS
5389 rn = "Performance1";
5390// break;
7a387fff 5391 case 2:
d9bea114 5392// gen_helper_mfc0_performance2(arg);
2423f660
TS
5393 rn = "Performance2";
5394// break;
7a387fff 5395 case 3:
d9bea114 5396// gen_helper_mfc0_performance3(arg);
2423f660
TS
5397 rn = "Performance3";
5398// break;
7a387fff 5399 case 4:
d9bea114 5400// gen_helper_mfc0_performance4(arg);
2423f660
TS
5401 rn = "Performance4";
5402// break;
7a387fff 5403 case 5:
d9bea114 5404// gen_helper_mfc0_performance5(arg);
2423f660
TS
5405 rn = "Performance5";
5406// break;
7a387fff 5407 case 6:
d9bea114 5408// gen_helper_mfc0_performance6(arg);
2423f660
TS
5409 rn = "Performance6";
5410// break;
7a387fff 5411 case 7:
d9bea114 5412// gen_helper_mfc0_performance7(arg);
2423f660
TS
5413 rn = "Performance7";
5414// break;
7a387fff 5415 default:
f31b035a 5416 goto cp0_unimplemented;
7a387fff 5417 }
8c0fdd85
TS
5418 break;
5419 case 26:
d9bea114 5420 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5421 rn = "ECC";
5422 break;
8c0fdd85 5423 case 27:
7a387fff 5424 switch (sel) {
7a387fff 5425 case 0 ... 3:
d9bea114 5426 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5427 rn = "CacheErr";
5428 break;
7a387fff 5429 default:
f31b035a 5430 goto cp0_unimplemented;
7a387fff 5431 }
8c0fdd85 5432 break;
873eb012
TS
5433 case 28:
5434 switch (sel) {
5435 case 0:
7a387fff
TS
5436 case 2:
5437 case 4:
5438 case 6:
7db13fae 5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5440 rn = "TagLo";
5441 break;
5442 case 1:
7a387fff
TS
5443 case 3:
5444 case 5:
5445 case 7:
7db13fae 5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5447 rn = "DataLo";
5448 break;
5449 default:
f31b035a 5450 goto cp0_unimplemented;
873eb012
TS
5451 }
5452 break;
8c0fdd85 5453 case 29:
7a387fff
TS
5454 switch (sel) {
5455 case 0:
5456 case 2:
5457 case 4:
5458 case 6:
7db13fae 5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5460 rn = "TagHi";
5461 break;
5462 case 1:
5463 case 3:
5464 case 5:
5465 case 7:
7db13fae 5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5467 rn = "DataHi";
5468 break;
5469 default:
f31b035a 5470 goto cp0_unimplemented;
7a387fff 5471 }
8c0fdd85 5472 break;
873eb012 5473 case 30:
7a387fff
TS
5474 switch (sel) {
5475 case 0:
7db13fae 5476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5477 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5478 rn = "ErrorEPC";
5479 break;
7a387fff 5480 default:
f31b035a 5481 goto cp0_unimplemented;
7a387fff 5482 }
873eb012
TS
5483 break;
5484 case 31:
7a387fff
TS
5485 switch (sel) {
5486 case 0:
f0b3f3ae 5487 /* EJTAG support */
7db13fae 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5489 rn = "DESAVE";
5490 break;
e98c0d17 5491 case 2 ... 7:
f31b035a
LA
5492 CP0_CHECK(ctx->kscrexist & (1 << sel));
5493 tcg_gen_ld_tl(arg, cpu_env,
5494 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5495 tcg_gen_ext32s_tl(arg, arg);
5496 rn = "KScratch";
e98c0d17 5497 break;
7a387fff 5498 default:
f31b035a 5499 goto cp0_unimplemented;
7a387fff 5500 }
873eb012
TS
5501 break;
5502 default:
f31b035a 5503 goto cp0_unimplemented;
873eb012 5504 }
2abf314d 5505 (void)rn; /* avoid a compiler warning */
d12d51d5 5506 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5507 return;
5508
f31b035a 5509cp0_unimplemented:
d12d51d5 5510 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5511 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5512}
5513
d75c135e 5514static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5515{
7a387fff
TS
5516 const char *rn = "invalid";
5517
e189e748 5518 if (sel != 0)
d75c135e 5519 check_insn(ctx, ISA_MIPS32);
e189e748 5520
bd79255d 5521 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5522 gen_io_start();
bd79255d 5523 }
2e70f6ef 5524
8c0fdd85
TS
5525 switch (reg) {
5526 case 0:
7a387fff
TS
5527 switch (sel) {
5528 case 0:
895c2d04 5529 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5530 rn = "Index";
5531 break;
5532 case 1:
f31b035a 5533 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5534 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5535 rn = "MVPControl";
ead9360e 5536 break;
7a387fff 5537 case 2:
f31b035a 5538 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5539 /* ignored */
7a387fff 5540 rn = "MVPConf0";
ead9360e 5541 break;
7a387fff 5542 case 3:
f31b035a 5543 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5544 /* ignored */
7a387fff 5545 rn = "MVPConf1";
ead9360e 5546 break;
7a387fff 5547 default:
f31b035a 5548 goto cp0_unimplemented;
7a387fff 5549 }
8c0fdd85
TS
5550 break;
5551 case 1:
7a387fff
TS
5552 switch (sel) {
5553 case 0:
2423f660 5554 /* ignored */
7a387fff 5555 rn = "Random";
2423f660 5556 break;
7a387fff 5557 case 1:
f31b035a 5558 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5559 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5560 rn = "VPEControl";
ead9360e 5561 break;
7a387fff 5562 case 2:
f31b035a 5563 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5564 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5565 rn = "VPEConf0";
ead9360e 5566 break;
7a387fff 5567 case 3:
f31b035a 5568 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5569 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5570 rn = "VPEConf1";
ead9360e 5571 break;
7a387fff 5572 case 4:
f31b035a 5573 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5574 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5575 rn = "YQMask";
ead9360e 5576 break;
7a387fff 5577 case 5:
f31b035a 5578 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5579 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5580 rn = "VPESchedule";
ead9360e 5581 break;
7a387fff 5582 case 6:
f31b035a 5583 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5584 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5585 rn = "VPEScheFBack";
ead9360e 5586 break;
7a387fff 5587 case 7:
f31b035a 5588 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5589 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5590 rn = "VPEOpt";
ead9360e 5591 break;
7a387fff 5592 default:
f31b035a 5593 goto cp0_unimplemented;
7a387fff 5594 }
8c0fdd85
TS
5595 break;
5596 case 2:
7a387fff
TS
5597 switch (sel) {
5598 case 0:
895c2d04 5599 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5600 rn = "EntryLo0";
5601 break;
7a387fff 5602 case 1:
f31b035a 5603 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5604 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5605 rn = "TCStatus";
ead9360e 5606 break;
7a387fff 5607 case 2:
f31b035a 5608 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5609 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5610 rn = "TCBind";
ead9360e 5611 break;
7a387fff 5612 case 3:
f31b035a 5613 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5614 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5615 rn = "TCRestart";
ead9360e 5616 break;
7a387fff 5617 case 4:
f31b035a 5618 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5619 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5620 rn = "TCHalt";
ead9360e 5621 break;
7a387fff 5622 case 5:
f31b035a 5623 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5624 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5625 rn = "TCContext";
ead9360e 5626 break;
7a387fff 5627 case 6:
f31b035a 5628 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5629 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5630 rn = "TCSchedule";
ead9360e 5631 break;
7a387fff 5632 case 7:
f31b035a 5633 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5634 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5635 rn = "TCScheFBack";
ead9360e 5636 break;
7a387fff 5637 default:
f31b035a 5638 goto cp0_unimplemented;
7a387fff 5639 }
8c0fdd85
TS
5640 break;
5641 case 3:
7a387fff
TS
5642 switch (sel) {
5643 case 0:
895c2d04 5644 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5645 rn = "EntryLo1";
5646 break;
7a387fff 5647 default:
f31b035a 5648 goto cp0_unimplemented;
876d4b07 5649 }
8c0fdd85
TS
5650 break;
5651 case 4:
7a387fff
TS
5652 switch (sel) {
5653 case 0:
895c2d04 5654 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5655 rn = "Context";
5656 break;
7a387fff 5657 case 1:
895c2d04 5658// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5659 rn = "ContextConfig";
f31b035a 5660 goto cp0_unimplemented;
2423f660 5661// break;
d279279e 5662 case 2:
f31b035a
LA
5663 CP0_CHECK(ctx->ulri);
5664 tcg_gen_st_tl(arg, cpu_env,
5665 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5666 rn = "UserLocal";
d279279e 5667 break;
7a387fff 5668 default:
f31b035a 5669 goto cp0_unimplemented;
876d4b07 5670 }
8c0fdd85
TS
5671 break;
5672 case 5:
7a387fff
TS
5673 switch (sel) {
5674 case 0:
895c2d04 5675 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5676 rn = "PageMask";
5677 break;
7a387fff 5678 case 1:
d75c135e 5679 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5680 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5681 rn = "PageGrain";
5682 break;
7a387fff 5683 default:
f31b035a 5684 goto cp0_unimplemented;
876d4b07 5685 }
8c0fdd85
TS
5686 break;
5687 case 6:
7a387fff
TS
5688 switch (sel) {
5689 case 0:
895c2d04 5690 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5691 rn = "Wired";
5692 break;
7a387fff 5693 case 1:
d75c135e 5694 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5695 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5696 rn = "SRSConf0";
ead9360e 5697 break;
7a387fff 5698 case 2:
d75c135e 5699 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5700 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5701 rn = "SRSConf1";
ead9360e 5702 break;
7a387fff 5703 case 3:
d75c135e 5704 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5705 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5706 rn = "SRSConf2";
ead9360e 5707 break;
7a387fff 5708 case 4:
d75c135e 5709 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5710 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5711 rn = "SRSConf3";
ead9360e 5712 break;
7a387fff 5713 case 5:
d75c135e 5714 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5715 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5716 rn = "SRSConf4";
ead9360e 5717 break;
7a387fff 5718 default:
f31b035a 5719 goto cp0_unimplemented;
876d4b07 5720 }
8c0fdd85
TS
5721 break;
5722 case 7:
7a387fff
TS
5723 switch (sel) {
5724 case 0:
d75c135e 5725 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5726 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5727 ctx->bstate = BS_STOP;
2423f660
TS
5728 rn = "HWREna";
5729 break;
7a387fff 5730 default:
f31b035a 5731 goto cp0_unimplemented;
876d4b07 5732 }
8c0fdd85
TS
5733 break;
5734 case 8:
aea14095
LA
5735 switch (sel) {
5736 case 0:
5737 /* ignored */
5738 rn = "BadVAddr";
5739 break;
5740 case 1:
5741 /* ignored */
5742 rn = "BadInstr";
5743 break;
5744 case 2:
5745 /* ignored */
5746 rn = "BadInstrP";
5747 break;
5748 default:
f31b035a 5749 goto cp0_unimplemented;
aea14095 5750 }
8c0fdd85
TS
5751 break;
5752 case 9:
7a387fff
TS
5753 switch (sel) {
5754 case 0:
895c2d04 5755 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5756 rn = "Count";
5757 break;
876d4b07 5758 /* 6,7 are implementation dependent */
7a387fff 5759 default:
f31b035a 5760 goto cp0_unimplemented;
876d4b07 5761 }
8c0fdd85
TS
5762 break;
5763 case 10:
7a387fff
TS
5764 switch (sel) {
5765 case 0:
895c2d04 5766 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5767 rn = "EntryHi";
5768 break;
7a387fff 5769 default:
f31b035a 5770 goto cp0_unimplemented;
876d4b07 5771 }
8c0fdd85
TS
5772 break;
5773 case 11:
7a387fff
TS
5774 switch (sel) {
5775 case 0:
895c2d04 5776 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5777 rn = "Compare";
5778 break;
5779 /* 6,7 are implementation dependent */
7a387fff 5780 default:
f31b035a 5781 goto cp0_unimplemented;
876d4b07 5782 }
8c0fdd85
TS
5783 break;
5784 case 12:
7a387fff
TS
5785 switch (sel) {
5786 case 0:
867abc7e 5787 save_cpu_state(ctx, 1);
895c2d04 5788 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5789 /* BS_STOP isn't good enough here, hflags may have changed. */
5790 gen_save_pc(ctx->pc + 4);
5791 ctx->bstate = BS_EXCP;
2423f660
TS
5792 rn = "Status";
5793 break;
7a387fff 5794 case 1:
d75c135e 5795 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5796 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5797 /* Stop translation as we may have switched the execution mode */
5798 ctx->bstate = BS_STOP;
2423f660
TS
5799 rn = "IntCtl";
5800 break;
7a387fff 5801 case 2:
d75c135e 5802 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5803 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5804 /* Stop translation as we may have switched the execution mode */
5805 ctx->bstate = BS_STOP;
2423f660
TS
5806 rn = "SRSCtl";
5807 break;
7a387fff 5808 case 3:
d75c135e 5809 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5810 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5811 /* Stop translation as we may have switched the execution mode */
5812 ctx->bstate = BS_STOP;
2423f660 5813 rn = "SRSMap";
fd88b6ab 5814 break;
7a387fff 5815 default:
f31b035a 5816 goto cp0_unimplemented;
876d4b07 5817 }
8c0fdd85
TS
5818 break;
5819 case 13:
7a387fff
TS
5820 switch (sel) {
5821 case 0:
867abc7e 5822 save_cpu_state(ctx, 1);
895c2d04 5823 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5824 rn = "Cause";
5825 break;
7a387fff 5826 default:
f31b035a 5827 goto cp0_unimplemented;
876d4b07 5828 }
8c0fdd85
TS
5829 break;
5830 case 14:
7a387fff
TS
5831 switch (sel) {
5832 case 0:
7db13fae 5833 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5834 rn = "EPC";
5835 break;
7a387fff 5836 default:
f31b035a 5837 goto cp0_unimplemented;
876d4b07 5838 }
8c0fdd85
TS
5839 break;
5840 case 15:
7a387fff
TS
5841 switch (sel) {
5842 case 0:
2423f660
TS
5843 /* ignored */
5844 rn = "PRid";
5845 break;
7a387fff 5846 case 1:
d75c135e 5847 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5848 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5849 rn = "EBase";
5850 break;
7a387fff 5851 default:
f31b035a 5852 goto cp0_unimplemented;
1579a72e 5853 }
8c0fdd85
TS
5854 break;
5855 case 16:
5856 switch (sel) {
5857 case 0:
895c2d04 5858 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5859 rn = "Config";
2423f660
TS
5860 /* Stop translation as we may have switched the execution mode */
5861 ctx->bstate = BS_STOP;
7a387fff
TS
5862 break;
5863 case 1:
e397ee33 5864 /* ignored, read only */
7a387fff
TS
5865 rn = "Config1";
5866 break;
5867 case 2:
895c2d04 5868 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5869 rn = "Config2";
2423f660
TS
5870 /* Stop translation as we may have switched the execution mode */
5871 ctx->bstate = BS_STOP;
8c0fdd85 5872 break;
7a387fff 5873 case 3:
90f12d73 5874 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5875 rn = "Config3";
90f12d73
MR
5876 /* Stop translation as we may have switched the execution mode */
5877 ctx->bstate = BS_STOP;
7a387fff 5878 break;
b4160af1
PJ
5879 case 4:
5880 gen_helper_mtc0_config4(cpu_env, arg);
5881 rn = "Config4";
5882 ctx->bstate = BS_STOP;
5883 break;
b4dd99a3
PJ
5884 case 5:
5885 gen_helper_mtc0_config5(cpu_env, arg);
5886 rn = "Config5";
5887 /* Stop translation as we may have switched the execution mode */
5888 ctx->bstate = BS_STOP;
5889 break;
e397ee33
TS
5890 /* 6,7 are implementation dependent */
5891 case 6:
5892 /* ignored */
5893 rn = "Config6";
5894 break;
5895 case 7:
5896 /* ignored */
5897 rn = "Config7";
5898 break;
8c0fdd85
TS
5899 default:
5900 rn = "Invalid config selector";
f31b035a 5901 goto cp0_unimplemented;
8c0fdd85
TS
5902 }
5903 break;
5904 case 17:
7a387fff
TS
5905 switch (sel) {
5906 case 0:
895c2d04 5907 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5908 rn = "LLAddr";
5909 break;
7a387fff 5910 default:
f31b035a 5911 goto cp0_unimplemented;
7a387fff 5912 }
8c0fdd85
TS
5913 break;
5914 case 18:
7a387fff 5915 switch (sel) {
fd88b6ab 5916 case 0 ... 7:
895c2d04 5917 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5918 rn = "WatchLo";
5919 break;
7a387fff 5920 default:
f31b035a 5921 goto cp0_unimplemented;
7a387fff 5922 }
8c0fdd85
TS
5923 break;
5924 case 19:
7a387fff 5925 switch (sel) {
fd88b6ab 5926 case 0 ... 7:
895c2d04 5927 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5928 rn = "WatchHi";
5929 break;
7a387fff 5930 default:
f31b035a 5931 goto cp0_unimplemented;
7a387fff 5932 }
8c0fdd85
TS
5933 break;
5934 case 20:
7a387fff
TS
5935 switch (sel) {
5936 case 0:
d26bc211 5937#if defined(TARGET_MIPS64)
d75c135e 5938 check_insn(ctx, ISA_MIPS3);
895c2d04 5939 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5940 rn = "XContext";
5941 break;
703eaf37 5942#endif
7a387fff 5943 default:
f31b035a 5944 goto cp0_unimplemented;
7a387fff 5945 }
8c0fdd85
TS
5946 break;
5947 case 21:
7a387fff 5948 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5949 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5950 switch (sel) {
5951 case 0:
895c2d04 5952 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5953 rn = "Framemask";
5954 break;
7a387fff 5955 default:
f31b035a 5956 goto cp0_unimplemented;
7a387fff
TS
5957 }
5958 break;
8c0fdd85 5959 case 22:
7a387fff
TS
5960 /* ignored */
5961 rn = "Diagnostic"; /* implementation dependent */
2423f660 5962 break;
8c0fdd85 5963 case 23:
7a387fff
TS
5964 switch (sel) {
5965 case 0:
895c2d04 5966 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5967 /* BS_STOP isn't good enough here, hflags may have changed. */
5968 gen_save_pc(ctx->pc + 4);
5969 ctx->bstate = BS_EXCP;
2423f660
TS
5970 rn = "Debug";
5971 break;
7a387fff 5972 case 1:
895c2d04 5973// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5974 rn = "TraceControl";
8487327a
TS
5975 /* Stop translation as we may have switched the execution mode */
5976 ctx->bstate = BS_STOP;
2423f660 5977// break;
7a387fff 5978 case 2:
895c2d04 5979// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5980 rn = "TraceControl2";
8487327a
TS
5981 /* Stop translation as we may have switched the execution mode */
5982 ctx->bstate = BS_STOP;
2423f660 5983// break;
7a387fff 5984 case 3:
8487327a
TS
5985 /* Stop translation as we may have switched the execution mode */
5986 ctx->bstate = BS_STOP;
895c2d04 5987// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5988 rn = "UserTraceData";
8487327a
TS
5989 /* Stop translation as we may have switched the execution mode */
5990 ctx->bstate = BS_STOP;
2423f660 5991// break;
7a387fff 5992 case 4:
895c2d04 5993// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5994 /* Stop translation as we may have switched the execution mode */
5995 ctx->bstate = BS_STOP;
2423f660
TS
5996 rn = "TraceBPC";
5997// break;
7a387fff 5998 default:
f31b035a 5999 goto cp0_unimplemented;
7a387fff 6000 }
8c0fdd85
TS
6001 break;
6002 case 24:
7a387fff
TS
6003 switch (sel) {
6004 case 0:
f1aa6320 6005 /* EJTAG support */
7db13fae 6006 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6007 rn = "DEPC";
6008 break;
7a387fff 6009 default:
f31b035a 6010 goto cp0_unimplemented;
7a387fff 6011 }
8c0fdd85
TS
6012 break;
6013 case 25:
7a387fff
TS
6014 switch (sel) {
6015 case 0:
895c2d04 6016 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6017 rn = "Performance0";
6018 break;
7a387fff 6019 case 1:
d9bea114 6020// gen_helper_mtc0_performance1(arg);
2423f660
TS
6021 rn = "Performance1";
6022// break;
7a387fff 6023 case 2:
d9bea114 6024// gen_helper_mtc0_performance2(arg);
2423f660
TS
6025 rn = "Performance2";
6026// break;
7a387fff 6027 case 3:
d9bea114 6028// gen_helper_mtc0_performance3(arg);
2423f660
TS
6029 rn = "Performance3";
6030// break;
7a387fff 6031 case 4:
d9bea114 6032// gen_helper_mtc0_performance4(arg);
2423f660
TS
6033 rn = "Performance4";
6034// break;
7a387fff 6035 case 5:
d9bea114 6036// gen_helper_mtc0_performance5(arg);
2423f660
TS
6037 rn = "Performance5";
6038// break;
7a387fff 6039 case 6:
d9bea114 6040// gen_helper_mtc0_performance6(arg);
2423f660
TS
6041 rn = "Performance6";
6042// break;
7a387fff 6043 case 7:
d9bea114 6044// gen_helper_mtc0_performance7(arg);
2423f660
TS
6045 rn = "Performance7";
6046// break;
7a387fff 6047 default:
f31b035a 6048 goto cp0_unimplemented;
7a387fff 6049 }
8c0fdd85
TS
6050 break;
6051 case 26:
2423f660 6052 /* ignored */
8c0fdd85 6053 rn = "ECC";
2423f660 6054 break;
8c0fdd85 6055 case 27:
7a387fff
TS
6056 switch (sel) {
6057 case 0 ... 3:
2423f660
TS
6058 /* ignored */
6059 rn = "CacheErr";
6060 break;
7a387fff 6061 default:
f31b035a 6062 goto cp0_unimplemented;
7a387fff 6063 }
8c0fdd85
TS
6064 break;
6065 case 28:
6066 switch (sel) {
6067 case 0:
7a387fff
TS
6068 case 2:
6069 case 4:
6070 case 6:
895c2d04 6071 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6072 rn = "TagLo";
6073 break;
7a387fff
TS
6074 case 1:
6075 case 3:
6076 case 5:
6077 case 7:
895c2d04 6078 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6079 rn = "DataLo";
6080 break;
8c0fdd85 6081 default:
f31b035a 6082 goto cp0_unimplemented;
8c0fdd85
TS
6083 }
6084 break;
6085 case 29:
7a387fff
TS
6086 switch (sel) {
6087 case 0:
6088 case 2:
6089 case 4:
6090 case 6:
895c2d04 6091 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6092 rn = "TagHi";
6093 break;
6094 case 1:
6095 case 3:
6096 case 5:
6097 case 7:
895c2d04 6098 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6099 rn = "DataHi";
6100 break;
6101 default:
6102 rn = "invalid sel";
f31b035a 6103 goto cp0_unimplemented;
7a387fff 6104 }
8c0fdd85
TS
6105 break;
6106 case 30:
7a387fff
TS
6107 switch (sel) {
6108 case 0:
7db13fae 6109 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6110 rn = "ErrorEPC";
6111 break;
7a387fff 6112 default:
f31b035a 6113 goto cp0_unimplemented;
7a387fff 6114 }
8c0fdd85
TS
6115 break;
6116 case 31:
7a387fff
TS
6117 switch (sel) {
6118 case 0:
f1aa6320 6119 /* EJTAG support */
7db13fae 6120 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6121 rn = "DESAVE";
6122 break;
e98c0d17 6123 case 2 ... 7:
f31b035a
LA
6124 CP0_CHECK(ctx->kscrexist & (1 << sel));
6125 tcg_gen_st_tl(arg, cpu_env,
6126 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6127 rn = "KScratch";
e98c0d17 6128 break;
7a387fff 6129 default:
f31b035a 6130 goto cp0_unimplemented;
7a387fff 6131 }
2423f660
TS
6132 /* Stop translation as we may have switched the execution mode */
6133 ctx->bstate = BS_STOP;
8c0fdd85
TS
6134 break;
6135 default:
f31b035a 6136 goto cp0_unimplemented;
8c0fdd85 6137 }
2abf314d 6138 (void)rn; /* avoid a compiler warning */
d12d51d5 6139 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6140 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6141 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6142 gen_io_end();
6143 ctx->bstate = BS_STOP;
6144 }
8c0fdd85
TS
6145 return;
6146
f31b035a 6147cp0_unimplemented:
d12d51d5 6148 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6149}
6150
d26bc211 6151#if defined(TARGET_MIPS64)
d75c135e 6152static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6153{
6154 const char *rn = "invalid";
6155
e189e748 6156 if (sel != 0)
d75c135e 6157 check_insn(ctx, ISA_MIPS64);
e189e748 6158
9c2149c8
TS
6159 switch (reg) {
6160 case 0:
6161 switch (sel) {
6162 case 0:
7db13fae 6163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6164 rn = "Index";
6165 break;
6166 case 1:
f31b035a 6167 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6168 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6169 rn = "MVPControl";
ead9360e 6170 break;
9c2149c8 6171 case 2:
f31b035a 6172 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6173 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6174 rn = "MVPConf0";
ead9360e 6175 break;
9c2149c8 6176 case 3:
f31b035a 6177 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6178 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6179 rn = "MVPConf1";
ead9360e 6180 break;
9c2149c8 6181 default:
f31b035a 6182 goto cp0_unimplemented;
9c2149c8
TS
6183 }
6184 break;
6185 case 1:
6186 switch (sel) {
6187 case 0:
f31b035a 6188 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6189 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6190 rn = "Random";
2423f660 6191 break;
9c2149c8 6192 case 1:
f31b035a 6193 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6195 rn = "VPEControl";
ead9360e 6196 break;
9c2149c8 6197 case 2:
f31b035a 6198 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6200 rn = "VPEConf0";
ead9360e 6201 break;
9c2149c8 6202 case 3:
f31b035a 6203 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6205 rn = "VPEConf1";
ead9360e 6206 break;
9c2149c8 6207 case 4:
f31b035a 6208 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6209 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6210 rn = "YQMask";
ead9360e 6211 break;
9c2149c8 6212 case 5:
f31b035a 6213 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6215 rn = "VPESchedule";
ead9360e 6216 break;
9c2149c8 6217 case 6:
f31b035a 6218 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6219 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6220 rn = "VPEScheFBack";
ead9360e 6221 break;
9c2149c8 6222 case 7:
f31b035a 6223 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6224 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6225 rn = "VPEOpt";
ead9360e 6226 break;
9c2149c8 6227 default:
f31b035a 6228 goto cp0_unimplemented;
9c2149c8
TS
6229 }
6230 break;
6231 case 2:
6232 switch (sel) {
6233 case 0:
7db13fae 6234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6235 rn = "EntryLo0";
6236 break;
9c2149c8 6237 case 1:
f31b035a 6238 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6239 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6240 rn = "TCStatus";
ead9360e 6241 break;
9c2149c8 6242 case 2:
f31b035a 6243 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6244 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6245 rn = "TCBind";
ead9360e 6246 break;
9c2149c8 6247 case 3:
f31b035a 6248 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6249 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6250 rn = "TCRestart";
ead9360e 6251 break;
9c2149c8 6252 case 4:
f31b035a 6253 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6254 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6255 rn = "TCHalt";
ead9360e 6256 break;
9c2149c8 6257 case 5:
f31b035a 6258 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6259 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6260 rn = "TCContext";
ead9360e 6261 break;
9c2149c8 6262 case 6:
f31b035a 6263 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6264 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6265 rn = "TCSchedule";
ead9360e 6266 break;
9c2149c8 6267 case 7:
f31b035a 6268 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6269 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6270 rn = "TCScheFBack";
ead9360e 6271 break;
9c2149c8 6272 default:
f31b035a 6273 goto cp0_unimplemented;
9c2149c8
TS
6274 }
6275 break;
6276 case 3:
6277 switch (sel) {
6278 case 0:
7db13fae 6279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6280 rn = "EntryLo1";
6281 break;
9c2149c8 6282 default:
f31b035a 6283 goto cp0_unimplemented;
1579a72e 6284 }
9c2149c8
TS
6285 break;
6286 case 4:
6287 switch (sel) {
6288 case 0:
7db13fae 6289 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6290 rn = "Context";
6291 break;
9c2149c8 6292 case 1:
d9bea114 6293// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6294 rn = "ContextConfig";
f31b035a 6295 goto cp0_unimplemented;
2423f660 6296// break;
d279279e 6297 case 2:
f31b035a
LA
6298 CP0_CHECK(ctx->ulri);
6299 tcg_gen_ld_tl(arg, cpu_env,
6300 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6301 rn = "UserLocal";
d279279e 6302 break;
9c2149c8 6303 default:
f31b035a 6304 goto cp0_unimplemented;
876d4b07 6305 }
9c2149c8
TS
6306 break;
6307 case 5:
6308 switch (sel) {
6309 case 0:
7db13fae 6310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6311 rn = "PageMask";
6312 break;
9c2149c8 6313 case 1:
d75c135e 6314 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6316 rn = "PageGrain";
6317 break;
9c2149c8 6318 default:
f31b035a 6319 goto cp0_unimplemented;
876d4b07 6320 }
9c2149c8
TS
6321 break;
6322 case 6:
6323 switch (sel) {
6324 case 0:
7db13fae 6325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6326 rn = "Wired";
6327 break;
9c2149c8 6328 case 1:
d75c135e 6329 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6331 rn = "SRSConf0";
ead9360e 6332 break;
9c2149c8 6333 case 2:
d75c135e 6334 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6336 rn = "SRSConf1";
ead9360e 6337 break;
9c2149c8 6338 case 3:
d75c135e 6339 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6341 rn = "SRSConf2";
ead9360e 6342 break;
9c2149c8 6343 case 4:
d75c135e 6344 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6346 rn = "SRSConf3";
ead9360e 6347 break;
9c2149c8 6348 case 5:
d75c135e 6349 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6351 rn = "SRSConf4";
ead9360e 6352 break;
9c2149c8 6353 default:
f31b035a 6354 goto cp0_unimplemented;
876d4b07 6355 }
9c2149c8
TS
6356 break;
6357 case 7:
6358 switch (sel) {
6359 case 0:
d75c135e 6360 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6362 rn = "HWREna";
6363 break;
9c2149c8 6364 default:
f31b035a 6365 goto cp0_unimplemented;
876d4b07 6366 }
9c2149c8
TS
6367 break;
6368 case 8:
6369 switch (sel) {
6370 case 0:
7db13fae 6371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6372 rn = "BadVAddr";
2423f660 6373 break;
aea14095 6374 case 1:
f31b035a
LA
6375 CP0_CHECK(ctx->bi);
6376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6377 rn = "BadInstr";
aea14095
LA
6378 break;
6379 case 2:
f31b035a
LA
6380 CP0_CHECK(ctx->bp);
6381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6382 rn = "BadInstrP";
aea14095 6383 break;
9c2149c8 6384 default:
f31b035a 6385 goto cp0_unimplemented;
876d4b07 6386 }
9c2149c8
TS
6387 break;
6388 case 9:
6389 switch (sel) {
6390 case 0:
2e70f6ef 6391 /* Mark as an IO operation because we read the time. */
bd79255d 6392 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6393 gen_io_start();
bd79255d 6394 }
895c2d04 6395 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6396 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6397 gen_io_end();
2e70f6ef 6398 }
55807224
EI
6399 /* Break the TB to be able to take timer interrupts immediately
6400 after reading count. */
6401 ctx->bstate = BS_STOP;
2423f660
TS
6402 rn = "Count";
6403 break;
6404 /* 6,7 are implementation dependent */
9c2149c8 6405 default:
f31b035a 6406 goto cp0_unimplemented;
876d4b07 6407 }
9c2149c8
TS
6408 break;
6409 case 10:
6410 switch (sel) {
6411 case 0:
7db13fae 6412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6413 rn = "EntryHi";
6414 break;
9c2149c8 6415 default:
f31b035a 6416 goto cp0_unimplemented;
876d4b07 6417 }
9c2149c8
TS
6418 break;
6419 case 11:
6420 switch (sel) {
6421 case 0:
7db13fae 6422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6423 rn = "Compare";
6424 break;
876d4b07 6425 /* 6,7 are implementation dependent */
9c2149c8 6426 default:
f31b035a 6427 goto cp0_unimplemented;
876d4b07 6428 }
9c2149c8
TS
6429 break;
6430 case 12:
6431 switch (sel) {
6432 case 0:
7db13fae 6433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6434 rn = "Status";
6435 break;
9c2149c8 6436 case 1:
d75c135e 6437 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6439 rn = "IntCtl";
6440 break;
9c2149c8 6441 case 2:
d75c135e 6442 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6444 rn = "SRSCtl";
6445 break;
9c2149c8 6446 case 3:
d75c135e 6447 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6449 rn = "SRSMap";
6450 break;
9c2149c8 6451 default:
f31b035a 6452 goto cp0_unimplemented;
876d4b07 6453 }
9c2149c8
TS
6454 break;
6455 case 13:
6456 switch (sel) {
6457 case 0:
7db13fae 6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6459 rn = "Cause";
6460 break;
9c2149c8 6461 default:
f31b035a 6462 goto cp0_unimplemented;
876d4b07 6463 }
9c2149c8
TS
6464 break;
6465 case 14:
6466 switch (sel) {
6467 case 0:
7db13fae 6468 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6469 rn = "EPC";
6470 break;
9c2149c8 6471 default:
f31b035a 6472 goto cp0_unimplemented;
876d4b07 6473 }
9c2149c8
TS
6474 break;
6475 case 15:
6476 switch (sel) {
6477 case 0:
7db13fae 6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6479 rn = "PRid";
6480 break;
9c2149c8 6481 case 1:
d75c135e 6482 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6484 rn = "EBase";
6485 break;
9c2149c8 6486 default:
f31b035a 6487 goto cp0_unimplemented;
876d4b07 6488 }
9c2149c8
TS
6489 break;
6490 case 16:
6491 switch (sel) {
6492 case 0:
7db13fae 6493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6494 rn = "Config";
6495 break;
6496 case 1:
7db13fae 6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6498 rn = "Config1";
6499 break;
6500 case 2:
7db13fae 6501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6502 rn = "Config2";
6503 break;
6504 case 3:
7db13fae 6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6506 rn = "Config3";
6507 break;
faf1f68b
LA
6508 case 4:
6509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6510 rn = "Config4";
6511 break;
6512 case 5:
6513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6514 rn = "Config5";
6515 break;
9c2149c8 6516 /* 6,7 are implementation dependent */
f0b3f3ae 6517 case 6:
7db13fae 6518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6519 rn = "Config6";
6520 break;
6521 case 7:
7db13fae 6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6523 rn = "Config7";
6524 break;
9c2149c8 6525 default:
f31b035a 6526 goto cp0_unimplemented;
9c2149c8
TS
6527 }
6528 break;
6529 case 17:
6530 switch (sel) {
6531 case 0:
895c2d04 6532 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6533 rn = "LLAddr";
6534 break;
9c2149c8 6535 default:
f31b035a 6536 goto cp0_unimplemented;
9c2149c8
TS
6537 }
6538 break;
6539 case 18:
6540 switch (sel) {
fd88b6ab 6541 case 0 ... 7:
895c2d04 6542 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6543 rn = "WatchLo";
6544 break;
9c2149c8 6545 default:
f31b035a 6546 goto cp0_unimplemented;
9c2149c8
TS
6547 }
6548 break;
6549 case 19:
6550 switch (sel) {
fd88b6ab 6551 case 0 ... 7:
895c2d04 6552 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6553 rn = "WatchHi";
6554 break;
9c2149c8 6555 default:
f31b035a 6556 goto cp0_unimplemented;
9c2149c8
TS
6557 }
6558 break;
6559 case 20:
6560 switch (sel) {
6561 case 0:
d75c135e 6562 check_insn(ctx, ISA_MIPS3);
7db13fae 6563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6564 rn = "XContext";
6565 break;
9c2149c8 6566 default:
f31b035a 6567 goto cp0_unimplemented;
9c2149c8
TS
6568 }
6569 break;
6570 case 21:
6571 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6572 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6573 switch (sel) {
6574 case 0:
7db13fae 6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6576 rn = "Framemask";
6577 break;
9c2149c8 6578 default:
f31b035a 6579 goto cp0_unimplemented;
9c2149c8
TS
6580 }
6581 break;
6582 case 22:
d9bea114 6583 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6584 rn = "'Diagnostic"; /* implementation dependent */
6585 break;
9c2149c8
TS
6586 case 23:
6587 switch (sel) {
6588 case 0:
895c2d04 6589 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6590 rn = "Debug";
6591 break;
9c2149c8 6592 case 1:
895c2d04 6593// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6594 rn = "TraceControl";
6595// break;
9c2149c8 6596 case 2:
895c2d04 6597// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6598 rn = "TraceControl2";
6599// break;
9c2149c8 6600 case 3:
895c2d04 6601// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6602 rn = "UserTraceData";
6603// break;
9c2149c8 6604 case 4:
895c2d04 6605// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6606 rn = "TraceBPC";
6607// break;
9c2149c8 6608 default:
f31b035a 6609 goto cp0_unimplemented;
9c2149c8
TS
6610 }
6611 break;
6612 case 24:
6613 switch (sel) {
6614 case 0:
f0b3f3ae 6615 /* EJTAG support */
7db13fae 6616 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6617 rn = "DEPC";
6618 break;
9c2149c8 6619 default:
f31b035a 6620 goto cp0_unimplemented;
9c2149c8
TS
6621 }
6622 break;
6623 case 25:
6624 switch (sel) {
6625 case 0:
7db13fae 6626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6627 rn = "Performance0";
9c2149c8
TS
6628 break;
6629 case 1:
d9bea114 6630// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6631 rn = "Performance1";
6632// break;
9c2149c8 6633 case 2:
d9bea114 6634// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6635 rn = "Performance2";
6636// break;
9c2149c8 6637 case 3:
d9bea114 6638// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6639 rn = "Performance3";
6640// break;
9c2149c8 6641 case 4:
d9bea114 6642// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6643 rn = "Performance4";
6644// break;
9c2149c8 6645 case 5:
d9bea114 6646// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6647 rn = "Performance5";
6648// break;
9c2149c8 6649 case 6:
d9bea114 6650// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6651 rn = "Performance6";
6652// break;
9c2149c8 6653 case 7:
d9bea114 6654// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6655 rn = "Performance7";
6656// break;
9c2149c8 6657 default:
f31b035a 6658 goto cp0_unimplemented;
9c2149c8
TS
6659 }
6660 break;
6661 case 26:
d9bea114 6662 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6663 rn = "ECC";
6664 break;
9c2149c8
TS
6665 case 27:
6666 switch (sel) {
6667 /* ignored */
6668 case 0 ... 3:
d9bea114 6669 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6670 rn = "CacheErr";
6671 break;
9c2149c8 6672 default:
f31b035a 6673 goto cp0_unimplemented;
9c2149c8
TS
6674 }
6675 break;
6676 case 28:
6677 switch (sel) {
6678 case 0:
6679 case 2:
6680 case 4:
6681 case 6:
7db13fae 6682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6683 rn = "TagLo";
6684 break;
6685 case 1:
6686 case 3:
6687 case 5:
6688 case 7:
7db13fae 6689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6690 rn = "DataLo";
6691 break;
6692 default:
f31b035a 6693 goto cp0_unimplemented;
9c2149c8
TS
6694 }
6695 break;
6696 case 29:
6697 switch (sel) {
6698 case 0:
6699 case 2:
6700 case 4:
6701 case 6:
7db13fae 6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6703 rn = "TagHi";
6704 break;
6705 case 1:
6706 case 3:
6707 case 5:
6708 case 7:
7db13fae 6709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6710 rn = "DataHi";
6711 break;
6712 default:
f31b035a 6713 goto cp0_unimplemented;
9c2149c8
TS
6714 }
6715 break;
6716 case 30:
6717 switch (sel) {
6718 case 0:
7db13fae 6719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6720 rn = "ErrorEPC";
6721 break;
9c2149c8 6722 default:
f31b035a 6723 goto cp0_unimplemented;
9c2149c8
TS
6724 }
6725 break;
6726 case 31:
6727 switch (sel) {
6728 case 0:
f0b3f3ae 6729 /* EJTAG support */
7db13fae 6730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6731 rn = "DESAVE";
6732 break;
e98c0d17 6733 case 2 ... 7:
f31b035a
LA
6734 CP0_CHECK(ctx->kscrexist & (1 << sel));
6735 tcg_gen_ld_tl(arg, cpu_env,
6736 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6737 rn = "KScratch";
e98c0d17 6738 break;
9c2149c8 6739 default:
f31b035a 6740 goto cp0_unimplemented;
9c2149c8
TS
6741 }
6742 break;
6743 default:
f31b035a 6744 goto cp0_unimplemented;
9c2149c8 6745 }
2abf314d 6746 (void)rn; /* avoid a compiler warning */
d12d51d5 6747 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6748 return;
6749
f31b035a 6750cp0_unimplemented:
d12d51d5 6751 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6752 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6753}
6754
d75c135e 6755static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6756{
6757 const char *rn = "invalid";
6758
e189e748 6759 if (sel != 0)
d75c135e 6760 check_insn(ctx, ISA_MIPS64);
e189e748 6761
bd79255d 6762 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6763 gen_io_start();
bd79255d 6764 }
2e70f6ef 6765
9c2149c8
TS
6766 switch (reg) {
6767 case 0:
6768 switch (sel) {
6769 case 0:
895c2d04 6770 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6771 rn = "Index";
6772 break;
6773 case 1:
f31b035a 6774 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6775 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6776 rn = "MVPControl";
ead9360e 6777 break;
9c2149c8 6778 case 2:
f31b035a 6779 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6780 /* ignored */
9c2149c8 6781 rn = "MVPConf0";
ead9360e 6782 break;
9c2149c8 6783 case 3:
f31b035a 6784 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6785 /* ignored */
9c2149c8 6786 rn = "MVPConf1";
ead9360e 6787 break;
9c2149c8 6788 default:
f31b035a 6789 goto cp0_unimplemented;
9c2149c8
TS
6790 }
6791 break;
6792 case 1:
6793 switch (sel) {
6794 case 0:
2423f660 6795 /* ignored */
9c2149c8 6796 rn = "Random";
2423f660 6797 break;
9c2149c8 6798 case 1:
f31b035a 6799 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6800 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6801 rn = "VPEControl";
ead9360e 6802 break;
9c2149c8 6803 case 2:
f31b035a 6804 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6805 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6806 rn = "VPEConf0";
ead9360e 6807 break;
9c2149c8 6808 case 3:
f31b035a 6809 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6810 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6811 rn = "VPEConf1";
ead9360e 6812 break;
9c2149c8 6813 case 4:
f31b035a 6814 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6815 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6816 rn = "YQMask";
ead9360e 6817 break;
9c2149c8 6818 case 5:
f31b035a 6819 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6820 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6821 rn = "VPESchedule";
ead9360e 6822 break;
9c2149c8 6823 case 6:
f31b035a 6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6825 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6826 rn = "VPEScheFBack";
ead9360e 6827 break;
9c2149c8 6828 case 7:
f31b035a 6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6830 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6831 rn = "VPEOpt";
ead9360e 6832 break;
9c2149c8 6833 default:
f31b035a 6834 goto cp0_unimplemented;
9c2149c8
TS
6835 }
6836 break;
6837 case 2:
6838 switch (sel) {
6839 case 0:
7207c7f9 6840 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6841 rn = "EntryLo0";
6842 break;
9c2149c8 6843 case 1:
f31b035a 6844 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6845 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6846 rn = "TCStatus";
ead9360e 6847 break;
9c2149c8 6848 case 2:
f31b035a 6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6850 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6851 rn = "TCBind";
ead9360e 6852 break;
9c2149c8 6853 case 3:
f31b035a 6854 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6855 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6856 rn = "TCRestart";
ead9360e 6857 break;
9c2149c8 6858 case 4:
f31b035a 6859 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6860 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6861 rn = "TCHalt";
ead9360e 6862 break;
9c2149c8 6863 case 5:
f31b035a 6864 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6865 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6866 rn = "TCContext";
ead9360e 6867 break;
9c2149c8 6868 case 6:
f31b035a 6869 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6870 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6871 rn = "TCSchedule";
ead9360e 6872 break;
9c2149c8 6873 case 7:
f31b035a 6874 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6875 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6876 rn = "TCScheFBack";
ead9360e 6877 break;
9c2149c8 6878 default:
f31b035a 6879 goto cp0_unimplemented;
9c2149c8
TS
6880 }
6881 break;
6882 case 3:
6883 switch (sel) {
6884 case 0:
7207c7f9 6885 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6886 rn = "EntryLo1";
6887 break;
9c2149c8 6888 default:
f31b035a 6889 goto cp0_unimplemented;
876d4b07 6890 }
9c2149c8
TS
6891 break;
6892 case 4:
6893 switch (sel) {
6894 case 0:
895c2d04 6895 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6896 rn = "Context";
6897 break;
9c2149c8 6898 case 1:
895c2d04 6899// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6900 rn = "ContextConfig";
f31b035a 6901 goto cp0_unimplemented;
2423f660 6902// break;
d279279e 6903 case 2:
f31b035a
LA
6904 CP0_CHECK(ctx->ulri);
6905 tcg_gen_st_tl(arg, cpu_env,
6906 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6907 rn = "UserLocal";
d279279e 6908 break;
9c2149c8 6909 default:
f31b035a 6910 goto cp0_unimplemented;
876d4b07 6911 }
9c2149c8
TS
6912 break;
6913 case 5:
6914 switch (sel) {
6915 case 0:
895c2d04 6916 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6917 rn = "PageMask";
6918 break;
9c2149c8 6919 case 1:
d75c135e 6920 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6921 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6922 rn = "PageGrain";
6923 break;
9c2149c8 6924 default:
f31b035a 6925 goto cp0_unimplemented;
876d4b07 6926 }
9c2149c8
TS
6927 break;
6928 case 6:
6929 switch (sel) {
6930 case 0:
895c2d04 6931 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6932 rn = "Wired";
6933 break;
9c2149c8 6934 case 1:
d75c135e 6935 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6936 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6937 rn = "SRSConf0";
ead9360e 6938 break;
9c2149c8 6939 case 2:
d75c135e 6940 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6941 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6942 rn = "SRSConf1";
ead9360e 6943 break;
9c2149c8 6944 case 3:
d75c135e 6945 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6946 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6947 rn = "SRSConf2";
ead9360e 6948 break;
9c2149c8 6949 case 4:
d75c135e 6950 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6951 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6952 rn = "SRSConf3";
ead9360e 6953 break;
9c2149c8 6954 case 5:
d75c135e 6955 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6956 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6957 rn = "SRSConf4";
ead9360e 6958 break;
9c2149c8 6959 default:
f31b035a 6960 goto cp0_unimplemented;
876d4b07 6961 }
9c2149c8
TS
6962 break;
6963 case 7:
6964 switch (sel) {
6965 case 0:
d75c135e 6966 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6967 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6968 ctx->bstate = BS_STOP;
2423f660
TS
6969 rn = "HWREna";
6970 break;
9c2149c8 6971 default:
f31b035a 6972 goto cp0_unimplemented;
876d4b07 6973 }
9c2149c8
TS
6974 break;
6975 case 8:
aea14095
LA
6976 switch (sel) {
6977 case 0:
6978 /* ignored */
6979 rn = "BadVAddr";
6980 break;
6981 case 1:
6982 /* ignored */
6983 rn = "BadInstr";
6984 break;
6985 case 2:
6986 /* ignored */
6987 rn = "BadInstrP";
6988 break;
6989 default:
f31b035a 6990 goto cp0_unimplemented;
aea14095 6991 }
9c2149c8
TS
6992 break;
6993 case 9:
6994 switch (sel) {
6995 case 0:
895c2d04 6996 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6997 rn = "Count";
6998 break;
876d4b07 6999 /* 6,7 are implementation dependent */
9c2149c8 7000 default:
f31b035a 7001 goto cp0_unimplemented;
876d4b07
TS
7002 }
7003 /* Stop translation as we may have switched the execution mode */
7004 ctx->bstate = BS_STOP;
9c2149c8
TS
7005 break;
7006 case 10:
7007 switch (sel) {
7008 case 0:
895c2d04 7009 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7010 rn = "EntryHi";
7011 break;
9c2149c8 7012 default:
f31b035a 7013 goto cp0_unimplemented;
876d4b07 7014 }
9c2149c8
TS
7015 break;
7016 case 11:
7017 switch (sel) {
7018 case 0:
895c2d04 7019 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7020 rn = "Compare";
7021 break;
876d4b07 7022 /* 6,7 are implementation dependent */
9c2149c8 7023 default:
f31b035a 7024 goto cp0_unimplemented;
876d4b07 7025 }
de9a95f0
AJ
7026 /* Stop translation as we may have switched the execution mode */
7027 ctx->bstate = BS_STOP;
9c2149c8
TS
7028 break;
7029 case 12:
7030 switch (sel) {
7031 case 0:
867abc7e 7032 save_cpu_state(ctx, 1);
895c2d04 7033 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7034 /* BS_STOP isn't good enough here, hflags may have changed. */
7035 gen_save_pc(ctx->pc + 4);
7036 ctx->bstate = BS_EXCP;
2423f660
TS
7037 rn = "Status";
7038 break;
9c2149c8 7039 case 1:
d75c135e 7040 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7041 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7042 /* Stop translation as we may have switched the execution mode */
7043 ctx->bstate = BS_STOP;
2423f660
TS
7044 rn = "IntCtl";
7045 break;
9c2149c8 7046 case 2:
d75c135e 7047 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7048 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7049 /* Stop translation as we may have switched the execution mode */
7050 ctx->bstate = BS_STOP;
2423f660
TS
7051 rn = "SRSCtl";
7052 break;
9c2149c8 7053 case 3:
d75c135e 7054 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7055 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7056 /* Stop translation as we may have switched the execution mode */
7057 ctx->bstate = BS_STOP;
2423f660
TS
7058 rn = "SRSMap";
7059 break;
7060 default:
f31b035a 7061 goto cp0_unimplemented;
876d4b07 7062 }
9c2149c8
TS
7063 break;
7064 case 13:
7065 switch (sel) {
7066 case 0:
867abc7e 7067 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7068 /* Mark as an IO operation because we may trigger a software
7069 interrupt. */
bd79255d 7070 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7071 gen_io_start();
7072 }
895c2d04 7073 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7074 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7075 gen_io_end();
7076 }
7077 /* Stop translation as we may have triggered an intetrupt */
7078 ctx->bstate = BS_STOP;
2423f660
TS
7079 rn = "Cause";
7080 break;
9c2149c8 7081 default:
f31b035a 7082 goto cp0_unimplemented;
876d4b07 7083 }
9c2149c8
TS
7084 break;
7085 case 14:
7086 switch (sel) {
7087 case 0:
7db13fae 7088 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7089 rn = "EPC";
7090 break;
9c2149c8 7091 default:
f31b035a 7092 goto cp0_unimplemented;
876d4b07 7093 }
9c2149c8
TS
7094 break;
7095 case 15:
7096 switch (sel) {
7097 case 0:
2423f660
TS
7098 /* ignored */
7099 rn = "PRid";
7100 break;
9c2149c8 7101 case 1:
d75c135e 7102 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7103 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7104 rn = "EBase";
7105 break;
9c2149c8 7106 default:
f31b035a 7107 goto cp0_unimplemented;
876d4b07 7108 }
9c2149c8
TS
7109 break;
7110 case 16:
7111 switch (sel) {
7112 case 0:
895c2d04 7113 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7114 rn = "Config";
2423f660
TS
7115 /* Stop translation as we may have switched the execution mode */
7116 ctx->bstate = BS_STOP;
9c2149c8
TS
7117 break;
7118 case 1:
1fc7bf6e 7119 /* ignored, read only */
9c2149c8
TS
7120 rn = "Config1";
7121 break;
7122 case 2:
895c2d04 7123 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7124 rn = "Config2";
2423f660
TS
7125 /* Stop translation as we may have switched the execution mode */
7126 ctx->bstate = BS_STOP;
9c2149c8
TS
7127 break;
7128 case 3:
90f12d73 7129 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7130 rn = "Config3";
90f12d73
MR
7131 /* Stop translation as we may have switched the execution mode */
7132 ctx->bstate = BS_STOP;
9c2149c8 7133 break;
faf1f68b
LA
7134 case 4:
7135 /* currently ignored */
7136 rn = "Config4";
7137 break;
7138 case 5:
7139 gen_helper_mtc0_config5(cpu_env, arg);
7140 rn = "Config5";
7141 /* Stop translation as we may have switched the execution mode */
7142 ctx->bstate = BS_STOP;
7143 break;
9c2149c8
TS
7144 /* 6,7 are implementation dependent */
7145 default:
7146 rn = "Invalid config selector";
f31b035a 7147 goto cp0_unimplemented;
9c2149c8 7148 }
9c2149c8
TS
7149 break;
7150 case 17:
7151 switch (sel) {
7152 case 0:
895c2d04 7153 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7154 rn = "LLAddr";
7155 break;
9c2149c8 7156 default:
f31b035a 7157 goto cp0_unimplemented;
9c2149c8
TS
7158 }
7159 break;
7160 case 18:
7161 switch (sel) {
fd88b6ab 7162 case 0 ... 7:
895c2d04 7163 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7164 rn = "WatchLo";
7165 break;
9c2149c8 7166 default:
f31b035a 7167 goto cp0_unimplemented;
9c2149c8
TS
7168 }
7169 break;
7170 case 19:
7171 switch (sel) {
fd88b6ab 7172 case 0 ... 7:
895c2d04 7173 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7174 rn = "WatchHi";
7175 break;
9c2149c8 7176 default:
f31b035a 7177 goto cp0_unimplemented;
9c2149c8
TS
7178 }
7179 break;
7180 case 20:
7181 switch (sel) {
7182 case 0:
d75c135e 7183 check_insn(ctx, ISA_MIPS3);
895c2d04 7184 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7185 rn = "XContext";
7186 break;
9c2149c8 7187 default:
f31b035a 7188 goto cp0_unimplemented;
9c2149c8
TS
7189 }
7190 break;
7191 case 21:
7192 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7193 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7194 switch (sel) {
7195 case 0:
895c2d04 7196 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7197 rn = "Framemask";
7198 break;
9c2149c8 7199 default:
f31b035a 7200 goto cp0_unimplemented;
9c2149c8
TS
7201 }
7202 break;
7203 case 22:
7204 /* ignored */
7205 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7206 break;
9c2149c8
TS
7207 case 23:
7208 switch (sel) {
7209 case 0:
895c2d04 7210 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7211 /* BS_STOP isn't good enough here, hflags may have changed. */
7212 gen_save_pc(ctx->pc + 4);
7213 ctx->bstate = BS_EXCP;
2423f660
TS
7214 rn = "Debug";
7215 break;
9c2149c8 7216 case 1:
895c2d04 7217// gen_helper_mtc0_tracecontrol(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 = "TraceControl";
7221// break;
9c2149c8 7222 case 2:
895c2d04 7223// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7224 /* Stop translation as we may have switched the execution mode */
7225 ctx->bstate = BS_STOP;
2423f660
TS
7226 rn = "TraceControl2";
7227// break;
9c2149c8 7228 case 3:
895c2d04 7229// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7230 /* Stop translation as we may have switched the execution mode */
7231 ctx->bstate = BS_STOP;
2423f660
TS
7232 rn = "UserTraceData";
7233// break;
9c2149c8 7234 case 4:
895c2d04 7235// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7236 /* Stop translation as we may have switched the execution mode */
7237 ctx->bstate = BS_STOP;
2423f660
TS
7238 rn = "TraceBPC";
7239// break;
9c2149c8 7240 default:
f31b035a 7241 goto cp0_unimplemented;
9c2149c8 7242 }
9c2149c8
TS
7243 break;
7244 case 24:
7245 switch (sel) {
7246 case 0:
f1aa6320 7247 /* EJTAG support */
7db13fae 7248 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7249 rn = "DEPC";
7250 break;
9c2149c8 7251 default:
f31b035a 7252 goto cp0_unimplemented;
9c2149c8
TS
7253 }
7254 break;
7255 case 25:
7256 switch (sel) {
7257 case 0:
895c2d04 7258 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7259 rn = "Performance0";
7260 break;
9c2149c8 7261 case 1:
895c2d04 7262// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7263 rn = "Performance1";
7264// break;
9c2149c8 7265 case 2:
895c2d04 7266// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7267 rn = "Performance2";
7268// break;
9c2149c8 7269 case 3:
895c2d04 7270// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7271 rn = "Performance3";
7272// break;
9c2149c8 7273 case 4:
895c2d04 7274// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7275 rn = "Performance4";
7276// break;
9c2149c8 7277 case 5:
895c2d04 7278// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7279 rn = "Performance5";
7280// break;
9c2149c8 7281 case 6:
895c2d04 7282// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7283 rn = "Performance6";
7284// break;
9c2149c8 7285 case 7:
895c2d04 7286// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7287 rn = "Performance7";
7288// break;
9c2149c8 7289 default:
f31b035a 7290 goto cp0_unimplemented;
9c2149c8 7291 }
876d4b07 7292 break;
9c2149c8 7293 case 26:
876d4b07 7294 /* ignored */
9c2149c8 7295 rn = "ECC";
876d4b07 7296 break;
9c2149c8
TS
7297 case 27:
7298 switch (sel) {
7299 case 0 ... 3:
2423f660
TS
7300 /* ignored */
7301 rn = "CacheErr";
7302 break;
9c2149c8 7303 default:
f31b035a 7304 goto cp0_unimplemented;
9c2149c8 7305 }
876d4b07 7306 break;
9c2149c8
TS
7307 case 28:
7308 switch (sel) {
7309 case 0:
7310 case 2:
7311 case 4:
7312 case 6:
895c2d04 7313 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7314 rn = "TagLo";
7315 break;
7316 case 1:
7317 case 3:
7318 case 5:
7319 case 7:
895c2d04 7320 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7321 rn = "DataLo";
7322 break;
7323 default:
f31b035a 7324 goto cp0_unimplemented;
9c2149c8
TS
7325 }
7326 break;
7327 case 29:
7328 switch (sel) {
7329 case 0:
7330 case 2:
7331 case 4:
7332 case 6:
895c2d04 7333 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7334 rn = "TagHi";
7335 break;
7336 case 1:
7337 case 3:
7338 case 5:
7339 case 7:
895c2d04 7340 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7341 rn = "DataHi";
7342 break;
7343 default:
7344 rn = "invalid sel";
f31b035a 7345 goto cp0_unimplemented;
9c2149c8 7346 }
876d4b07 7347 break;
9c2149c8
TS
7348 case 30:
7349 switch (sel) {
7350 case 0:
7db13fae 7351 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7352 rn = "ErrorEPC";
7353 break;
9c2149c8 7354 default:
f31b035a 7355 goto cp0_unimplemented;
9c2149c8
TS
7356 }
7357 break;
7358 case 31:
7359 switch (sel) {
7360 case 0:
f1aa6320 7361 /* EJTAG support */
7db13fae 7362 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7363 rn = "DESAVE";
7364 break;
e98c0d17 7365 case 2 ... 7:
f31b035a
LA
7366 CP0_CHECK(ctx->kscrexist & (1 << sel));
7367 tcg_gen_st_tl(arg, cpu_env,
7368 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7369 rn = "KScratch";
e98c0d17 7370 break;
9c2149c8 7371 default:
f31b035a 7372 goto cp0_unimplemented;
9c2149c8 7373 }
876d4b07
TS
7374 /* Stop translation as we may have switched the execution mode */
7375 ctx->bstate = BS_STOP;
9c2149c8
TS
7376 break;
7377 default:
f31b035a 7378 goto cp0_unimplemented;
9c2149c8 7379 }
2abf314d 7380 (void)rn; /* avoid a compiler warning */
d12d51d5 7381 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7382 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7383 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7384 gen_io_end();
7385 ctx->bstate = BS_STOP;
7386 }
9c2149c8
TS
7387 return;
7388
f31b035a 7389cp0_unimplemented:
d12d51d5 7390 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7391}
d26bc211 7392#endif /* TARGET_MIPS64 */
9c2149c8 7393
7db13fae 7394static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7395 int u, int sel, int h)
7396{
7397 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7398 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7399
7400 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7401 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7402 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7403 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7404 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7405 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7406 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7407 else if (u == 0) {
7408 switch (rt) {
5a25ce94
EI
7409 case 1:
7410 switch (sel) {
7411 case 1:
895c2d04 7412 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7413 break;
7414 case 2:
895c2d04 7415 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7416 break;
7417 default:
7418 goto die;
7419 break;
7420 }
7421 break;
ead9360e
TS
7422 case 2:
7423 switch (sel) {
7424 case 1:
895c2d04 7425 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7426 break;
7427 case 2:
895c2d04 7428 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7429 break;
7430 case 3:
895c2d04 7431 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7432 break;
7433 case 4:
895c2d04 7434 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7435 break;
7436 case 5:
895c2d04 7437 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7438 break;
7439 case 6:
895c2d04 7440 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7441 break;
7442 case 7:
895c2d04 7443 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7444 break;
7445 default:
d75c135e 7446 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7447 break;
7448 }
7449 break;
7450 case 10:
7451 switch (sel) {
7452 case 0:
895c2d04 7453 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7454 break;
7455 default:
d75c135e 7456 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7457 break;
7458 }
7459 case 12:
7460 switch (sel) {
7461 case 0:
895c2d04 7462 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7463 break;
7464 default:
d75c135e 7465 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7466 break;
7467 }
5a25ce94
EI
7468 case 13:
7469 switch (sel) {
7470 case 0:
895c2d04 7471 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7472 break;
7473 default:
7474 goto die;
7475 break;
7476 }
7477 break;
7478 case 14:
7479 switch (sel) {
7480 case 0:
895c2d04 7481 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7482 break;
7483 default:
7484 goto die;
7485 break;
7486 }
7487 break;
7488 case 15:
7489 switch (sel) {
7490 case 1:
895c2d04 7491 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7492 break;
7493 default:
7494 goto die;
7495 break;
7496 }
7497 break;
7498 case 16:
7499 switch (sel) {
7500 case 0 ... 7:
895c2d04 7501 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7502 break;
7503 default:
7504 goto die;
7505 break;
7506 }
7507 break;
ead9360e
TS
7508 case 23:
7509 switch (sel) {
7510 case 0:
895c2d04 7511 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7512 break;
7513 default:
d75c135e 7514 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7515 break;
7516 }
7517 break;
7518 default:
d75c135e 7519 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7520 }
7521 } else switch (sel) {
7522 /* GPR registers. */
7523 case 0:
895c2d04 7524 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7525 break;
7526 /* Auxiliary CPU registers */
7527 case 1:
7528 switch (rt) {
7529 case 0:
895c2d04 7530 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7531 break;
7532 case 1:
895c2d04 7533 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7534 break;
7535 case 2:
895c2d04 7536 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7537 break;
7538 case 4:
895c2d04 7539 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7540 break;
7541 case 5:
895c2d04 7542 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7543 break;
7544 case 6:
895c2d04 7545 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7546 break;
7547 case 8:
895c2d04 7548 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7549 break;
7550 case 9:
895c2d04 7551 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7552 break;
7553 case 10:
895c2d04 7554 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7555 break;
7556 case 12:
895c2d04 7557 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7558 break;
7559 case 13:
895c2d04 7560 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7561 break;
7562 case 14:
895c2d04 7563 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7564 break;
7565 case 16:
895c2d04 7566 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7567 break;
7568 default:
7569 goto die;
7570 }
7571 break;
7572 /* Floating point (COP1). */
7573 case 2:
7574 /* XXX: For now we support only a single FPU context. */
7575 if (h == 0) {
a7812ae4 7576 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7577
7c979afd 7578 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7579 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7580 tcg_temp_free_i32(fp0);
ead9360e 7581 } else {
a7812ae4 7582 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7583
7f6613ce 7584 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7585 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7586 tcg_temp_free_i32(fp0);
ead9360e
TS
7587 }
7588 break;
7589 case 3:
7590 /* XXX: For now we support only a single FPU context. */
895c2d04 7591 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7592 break;
7593 /* COP2: Not implemented. */
7594 case 4:
7595 case 5:
7596 /* fall through */
7597 default:
7598 goto die;
7599 }
d12d51d5 7600 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7601 gen_store_gpr(t0, rd);
7602 tcg_temp_free(t0);
ead9360e
TS
7603 return;
7604
7605die:
1a3fd9c3 7606 tcg_temp_free(t0);
d12d51d5 7607 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7608 generate_exception(ctx, EXCP_RI);
7609}
7610
7db13fae 7611static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7612 int u, int sel, int h)
7613{
7614 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7615 TCGv t0 = tcg_temp_local_new();
ead9360e 7616
1a3fd9c3 7617 gen_load_gpr(t0, rt);
ead9360e 7618 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7619 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7620 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7621 /* NOP */ ;
7622 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7623 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7624 /* NOP */ ;
7625 else if (u == 0) {
7626 switch (rd) {
5a25ce94
EI
7627 case 1:
7628 switch (sel) {
7629 case 1:
895c2d04 7630 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7631 break;
7632 case 2:
895c2d04 7633 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7634 break;
7635 default:
7636 goto die;
7637 break;
7638 }
7639 break;
ead9360e
TS
7640 case 2:
7641 switch (sel) {
7642 case 1:
895c2d04 7643 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7644 break;
7645 case 2:
895c2d04 7646 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7647 break;
7648 case 3:
895c2d04 7649 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7650 break;
7651 case 4:
895c2d04 7652 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7653 break;
7654 case 5:
895c2d04 7655 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7656 break;
7657 case 6:
895c2d04 7658 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7659 break;
7660 case 7:
895c2d04 7661 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7662 break;
7663 default:
d75c135e 7664 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7665 break;
7666 }
7667 break;
7668 case 10:
7669 switch (sel) {
7670 case 0:
895c2d04 7671 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7672 break;
7673 default:
d75c135e 7674 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7675 break;
7676 }
7677 case 12:
7678 switch (sel) {
7679 case 0:
895c2d04 7680 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7681 break;
7682 default:
d75c135e 7683 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7684 break;
7685 }
5a25ce94
EI
7686 case 13:
7687 switch (sel) {
7688 case 0:
895c2d04 7689 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7690 break;
7691 default:
7692 goto die;
7693 break;
7694 }
7695 break;
7696 case 15:
7697 switch (sel) {
7698 case 1:
895c2d04 7699 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7700 break;
7701 default:
7702 goto die;
7703 break;
7704 }
7705 break;
ead9360e
TS
7706 case 23:
7707 switch (sel) {
7708 case 0:
895c2d04 7709 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7710 break;
7711 default:
d75c135e 7712 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7713 break;
7714 }
7715 break;
7716 default:
d75c135e 7717 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7718 }
7719 } else switch (sel) {
7720 /* GPR registers. */
7721 case 0:
895c2d04 7722 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7723 break;
7724 /* Auxiliary CPU registers */
7725 case 1:
7726 switch (rd) {
7727 case 0:
895c2d04 7728 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7729 break;
7730 case 1:
895c2d04 7731 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7732 break;
7733 case 2:
895c2d04 7734 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7735 break;
7736 case 4:
895c2d04 7737 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7738 break;
7739 case 5:
895c2d04 7740 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7741 break;
7742 case 6:
895c2d04 7743 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7744 break;
7745 case 8:
895c2d04 7746 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7747 break;
7748 case 9:
895c2d04 7749 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7750 break;
7751 case 10:
895c2d04 7752 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7753 break;
7754 case 12:
895c2d04 7755 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7756 break;
7757 case 13:
895c2d04 7758 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7759 break;
7760 case 14:
895c2d04 7761 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7762 break;
7763 case 16:
895c2d04 7764 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7765 break;
7766 default:
7767 goto die;
7768 }
7769 break;
7770 /* Floating point (COP1). */
7771 case 2:
7772 /* XXX: For now we support only a single FPU context. */
7773 if (h == 0) {
a7812ae4 7774 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7775
7776 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7777 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7778 tcg_temp_free_i32(fp0);
ead9360e 7779 } else {
a7812ae4 7780 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7781
7782 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7783 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7784 tcg_temp_free_i32(fp0);
ead9360e
TS
7785 }
7786 break;
7787 case 3:
7788 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7789 save_cpu_state(ctx, 1);
736d120a
PJ
7790 {
7791 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7792
7793 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7794 tcg_temp_free_i32(fs_tmp);
7795 }
4cf8a45f
YK
7796 /* Stop translation as we may have changed hflags */
7797 ctx->bstate = BS_STOP;
ead9360e
TS
7798 break;
7799 /* COP2: Not implemented. */
7800 case 4:
7801 case 5:
7802 /* fall through */
7803 default:
7804 goto die;
7805 }
d12d51d5 7806 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7807 tcg_temp_free(t0);
ead9360e
TS
7808 return;
7809
7810die:
1a3fd9c3 7811 tcg_temp_free(t0);
d12d51d5 7812 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7813 generate_exception(ctx, EXCP_RI);
7814}
7815
7db13fae 7816static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7817{
287c4b84 7818 const char *opn = "ldst";
6af0bf9c 7819
2e15497c 7820 check_cp0_enabled(ctx);
6af0bf9c
FB
7821 switch (opc) {
7822 case OPC_MFC0:
7823 if (rt == 0) {
ead9360e 7824 /* Treat as NOP. */
6af0bf9c
FB
7825 return;
7826 }
d75c135e 7827 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7828 opn = "mfc0";
7829 break;
7830 case OPC_MTC0:
1a3fd9c3 7831 {
1fc7bf6e 7832 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7833
7834 gen_load_gpr(t0, rt);
d75c135e 7835 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7836 tcg_temp_free(t0);
7837 }
6af0bf9c
FB
7838 opn = "mtc0";
7839 break;
d26bc211 7840#if defined(TARGET_MIPS64)
9c2149c8 7841 case OPC_DMFC0:
d75c135e 7842 check_insn(ctx, ISA_MIPS3);
9c2149c8 7843 if (rt == 0) {
ead9360e 7844 /* Treat as NOP. */
9c2149c8
TS
7845 return;
7846 }
d75c135e 7847 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7848 opn = "dmfc0";
7849 break;
7850 case OPC_DMTC0:
d75c135e 7851 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7852 {
1fc7bf6e 7853 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7854
7855 gen_load_gpr(t0, rt);
d75c135e 7856 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7857 tcg_temp_free(t0);
7858 }
9c2149c8
TS
7859 opn = "dmtc0";
7860 break;
534ce69f 7861#endif
ead9360e 7862 case OPC_MFTR:
d75c135e 7863 check_insn(ctx, ASE_MT);
ead9360e
TS
7864 if (rd == 0) {
7865 /* Treat as NOP. */
7866 return;
7867 }
6c5c1e20 7868 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7869 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7870 opn = "mftr";
7871 break;
7872 case OPC_MTTR:
d75c135e 7873 check_insn(ctx, ASE_MT);
6c5c1e20 7874 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7875 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7876 opn = "mttr";
7877 break;
6af0bf9c 7878 case OPC_TLBWI:
6af0bf9c 7879 opn = "tlbwi";
c01fccd2 7880 if (!env->tlb->helper_tlbwi)
29929e34 7881 goto die;
895c2d04 7882 gen_helper_tlbwi(cpu_env);
6af0bf9c 7883 break;
9456c2fb
LA
7884 case OPC_TLBINV:
7885 opn = "tlbinv";
7886 if (ctx->ie >= 2) {
7887 if (!env->tlb->helper_tlbinv) {
7888 goto die;
7889 }
7890 gen_helper_tlbinv(cpu_env);
7891 } /* treat as nop if TLBINV not supported */
7892 break;
7893 case OPC_TLBINVF:
7894 opn = "tlbinvf";
7895 if (ctx->ie >= 2) {
7896 if (!env->tlb->helper_tlbinvf) {
7897 goto die;
7898 }
7899 gen_helper_tlbinvf(cpu_env);
7900 } /* treat as nop if TLBINV not supported */
7901 break;
6af0bf9c 7902 case OPC_TLBWR:
6af0bf9c 7903 opn = "tlbwr";
c01fccd2 7904 if (!env->tlb->helper_tlbwr)
29929e34 7905 goto die;
895c2d04 7906 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7907 break;
7908 case OPC_TLBP:
6af0bf9c 7909 opn = "tlbp";
c01fccd2 7910 if (!env->tlb->helper_tlbp)
29929e34 7911 goto die;
895c2d04 7912 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7913 break;
7914 case OPC_TLBR:
6af0bf9c 7915 opn = "tlbr";
c01fccd2 7916 if (!env->tlb->helper_tlbr)
29929e34 7917 goto die;
895c2d04 7918 gen_helper_tlbr(cpu_env);
6af0bf9c 7919 break;
6af0bf9c
FB
7920 case OPC_ERET:
7921 opn = "eret";
d75c135e 7922 check_insn(ctx, ISA_MIPS2);
339cd2a8
LA
7923 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7924 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7925 MIPS_DEBUG("CTI in delay / forbidden slot");
7926 goto die;
7927 }
895c2d04 7928 gen_helper_eret(cpu_env);
6af0bf9c
FB
7929 ctx->bstate = BS_EXCP;
7930 break;
7931 case OPC_DERET:
7932 opn = "deret";
d75c135e 7933 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7934 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7935 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7936 MIPS_DEBUG("CTI in delay / forbidden slot");
7937 goto die;
7938 }
6af0bf9c 7939 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7940 MIPS_INVAL(opn);
6af0bf9c
FB
7941 generate_exception(ctx, EXCP_RI);
7942 } else {
895c2d04 7943 gen_helper_deret(cpu_env);
6af0bf9c
FB
7944 ctx->bstate = BS_EXCP;
7945 }
7946 break;
4ad40f36
FB
7947 case OPC_WAIT:
7948 opn = "wait";
d75c135e 7949 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7950 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7951 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7952 MIPS_DEBUG("CTI in delay / forbidden slot");
7953 goto die;
7954 }
4ad40f36
FB
7955 /* If we get an exception, we want to restart at next instruction */
7956 ctx->pc += 4;
7957 save_cpu_state(ctx, 1);
7958 ctx->pc -= 4;
895c2d04 7959 gen_helper_wait(cpu_env);
4ad40f36
FB
7960 ctx->bstate = BS_EXCP;
7961 break;
6af0bf9c 7962 default:
29929e34 7963 die:
923617a3 7964 MIPS_INVAL(opn);
6af0bf9c
FB
7965 generate_exception(ctx, EXCP_RI);
7966 return;
7967 }
2abf314d 7968 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7969 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7970}
f1aa6320 7971#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7972
6ea83fed 7973/* CP1 Branches (before delay slot) */
d75c135e
AJ
7974static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7975 int32_t cc, int32_t offset)
6ea83fed
FB
7976{
7977 target_ulong btarget;
923617a3 7978 const char *opn = "cp1 cond branch";
a7812ae4 7979 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7980
339cd2a8
LA
7981 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7982 MIPS_DEBUG("CTI in delay / forbidden slot");
7983 generate_exception(ctx, EXCP_RI);
7984 goto out;
7985 }
7986
e189e748 7987 if (cc != 0)
d75c135e 7988 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7989
6ea83fed
FB
7990 btarget = ctx->pc + 4 + offset;
7991
7a387fff
TS
7992 switch (op) {
7993 case OPC_BC1F:
d94536f4
AJ
7994 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7995 tcg_gen_not_i32(t0, t0);
7996 tcg_gen_andi_i32(t0, t0, 1);
7997 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7998 opn = "bc1f";
6ea83fed 7999 goto not_likely;
7a387fff 8000 case OPC_BC1FL:
d94536f4
AJ
8001 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8002 tcg_gen_not_i32(t0, t0);
8003 tcg_gen_andi_i32(t0, t0, 1);
8004 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8005 opn = "bc1fl";
6ea83fed 8006 goto likely;
7a387fff 8007 case OPC_BC1T:
d94536f4
AJ
8008 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8009 tcg_gen_andi_i32(t0, t0, 1);
8010 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8011 opn = "bc1t";
5a5012ec 8012 goto not_likely;
7a387fff 8013 case OPC_BC1TL:
d94536f4
AJ
8014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8015 tcg_gen_andi_i32(t0, t0, 1);
8016 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8017 opn = "bc1tl";
6ea83fed
FB
8018 likely:
8019 ctx->hflags |= MIPS_HFLAG_BL;
8020 break;
5a5012ec 8021 case OPC_BC1FANY2:
a16336e4 8022 {
d94536f4
AJ
8023 TCGv_i32 t1 = tcg_temp_new_i32();
8024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8025 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8026 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8027 tcg_temp_free_i32(t1);
d94536f4
AJ
8028 tcg_gen_andi_i32(t0, t0, 1);
8029 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8030 }
fd4a04eb 8031 opn = "bc1any2f";
5a5012ec
TS
8032 goto not_likely;
8033 case OPC_BC1TANY2:
a16336e4 8034 {
d94536f4
AJ
8035 TCGv_i32 t1 = tcg_temp_new_i32();
8036 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8037 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8038 tcg_gen_or_i32(t0, t0, t1);
8039 tcg_temp_free_i32(t1);
8040 tcg_gen_andi_i32(t0, t0, 1);
8041 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8042 }
fd4a04eb 8043 opn = "bc1any2t";
5a5012ec
TS
8044 goto not_likely;
8045 case OPC_BC1FANY4:
a16336e4 8046 {
d94536f4
AJ
8047 TCGv_i32 t1 = tcg_temp_new_i32();
8048 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8049 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8050 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8051 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8052 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8053 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8054 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8055 tcg_temp_free_i32(t1);
d94536f4
AJ
8056 tcg_gen_andi_i32(t0, t0, 1);
8057 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8058 }
fd4a04eb 8059 opn = "bc1any4f";
5a5012ec
TS
8060 goto not_likely;
8061 case OPC_BC1TANY4:
a16336e4 8062 {
d94536f4
AJ
8063 TCGv_i32 t1 = tcg_temp_new_i32();
8064 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8065 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8066 tcg_gen_or_i32(t0, t0, t1);
8067 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8068 tcg_gen_or_i32(t0, t0, t1);
8069 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8070 tcg_gen_or_i32(t0, t0, t1);
8071 tcg_temp_free_i32(t1);
8072 tcg_gen_andi_i32(t0, t0, 1);
8073 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8074 }
fd4a04eb 8075 opn = "bc1any4t";
5a5012ec
TS
8076 not_likely:
8077 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8078 break;
8079 default:
923617a3 8080 MIPS_INVAL(opn);
e397ee33 8081 generate_exception (ctx, EXCP_RI);
6c5c1e20 8082 goto out;
6ea83fed 8083 }
2abf314d 8084 (void)opn; /* avoid a compiler warning */
923617a3 8085 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8086 ctx->hflags, btarget);
8087 ctx->btarget = btarget;
b231c103 8088 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8089 out:
a7812ae4 8090 tcg_temp_free_i32(t0);
6ea83fed
FB
8091}
8092
31837be3
YK
8093/* R6 CP1 Branches */
8094static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8095 int32_t ft, int32_t offset)
8096{
8097 target_ulong btarget;
8098 const char *opn = "cp1 cond branch";
8099 TCGv_i64 t0 = tcg_temp_new_i64();
8100
8101 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8102#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8103 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8104 "\n", ctx->pc);
31837be3
YK
8105#endif
8106 generate_exception(ctx, EXCP_RI);
8107 goto out;
8108 }
8109
8110 gen_load_fpr64(ctx, t0, ft);
8111 tcg_gen_andi_i64(t0, t0, 1);
8112
8113 btarget = addr_add(ctx, ctx->pc + 4, offset);
8114
8115 switch (op) {
8116 case OPC_BC1EQZ:
8117 tcg_gen_xori_i64(t0, t0, 1);
8118 opn = "bc1eqz";
8119 ctx->hflags |= MIPS_HFLAG_BC;
8120 break;
8121 case OPC_BC1NEZ:
8122 /* t0 already set */
8123 opn = "bc1nez";
8124 ctx->hflags |= MIPS_HFLAG_BC;
8125 break;
8126 default:
8127 MIPS_INVAL(opn);
8128 generate_exception(ctx, EXCP_RI);
8129 goto out;
8130 }
8131
8132 tcg_gen_trunc_i64_tl(bcond, t0);
8133
8134 (void)opn; /* avoid a compiler warning */
8135 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8136 ctx->hflags, btarget);
8137 ctx->btarget = btarget;
85479575 8138 ctx->hflags |= MIPS_HFLAG_BDS32;
31837be3
YK
8139
8140out:
8141 tcg_temp_free_i64(t0);
8142}
8143
6af0bf9c 8144/* Coprocessor 1 (FPU) */
5a5012ec 8145
5a5012ec
TS
8146#define FOP(func, fmt) (((fmt) << 21) | (func))
8147
bf4120ad
NF
8148enum fopcode {
8149 OPC_ADD_S = FOP(0, FMT_S),
8150 OPC_SUB_S = FOP(1, FMT_S),
8151 OPC_MUL_S = FOP(2, FMT_S),
8152 OPC_DIV_S = FOP(3, FMT_S),
8153 OPC_SQRT_S = FOP(4, FMT_S),
8154 OPC_ABS_S = FOP(5, FMT_S),
8155 OPC_MOV_S = FOP(6, FMT_S),
8156 OPC_NEG_S = FOP(7, FMT_S),
8157 OPC_ROUND_L_S = FOP(8, FMT_S),
8158 OPC_TRUNC_L_S = FOP(9, FMT_S),
8159 OPC_CEIL_L_S = FOP(10, FMT_S),
8160 OPC_FLOOR_L_S = FOP(11, FMT_S),
8161 OPC_ROUND_W_S = FOP(12, FMT_S),
8162 OPC_TRUNC_W_S = FOP(13, FMT_S),
8163 OPC_CEIL_W_S = FOP(14, FMT_S),
8164 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8165 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8166 OPC_MOVCF_S = FOP(17, FMT_S),
8167 OPC_MOVZ_S = FOP(18, FMT_S),
8168 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8169 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8170 OPC_RECIP_S = FOP(21, FMT_S),
8171 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8172 OPC_SELNEZ_S = FOP(23, FMT_S),
8173 OPC_MADDF_S = FOP(24, FMT_S),
8174 OPC_MSUBF_S = FOP(25, FMT_S),
8175 OPC_RINT_S = FOP(26, FMT_S),
8176 OPC_CLASS_S = FOP(27, FMT_S),
8177 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8178 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8179 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8180 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8181 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8182 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8183 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8184 OPC_RSQRT2_S = FOP(31, FMT_S),
8185 OPC_CVT_D_S = FOP(33, FMT_S),
8186 OPC_CVT_W_S = FOP(36, FMT_S),
8187 OPC_CVT_L_S = FOP(37, FMT_S),
8188 OPC_CVT_PS_S = FOP(38, FMT_S),
8189 OPC_CMP_F_S = FOP (48, FMT_S),
8190 OPC_CMP_UN_S = FOP (49, FMT_S),
8191 OPC_CMP_EQ_S = FOP (50, FMT_S),
8192 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8193 OPC_CMP_OLT_S = FOP (52, FMT_S),
8194 OPC_CMP_ULT_S = FOP (53, FMT_S),
8195 OPC_CMP_OLE_S = FOP (54, FMT_S),
8196 OPC_CMP_ULE_S = FOP (55, FMT_S),
8197 OPC_CMP_SF_S = FOP (56, FMT_S),
8198 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8199 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8200 OPC_CMP_NGL_S = FOP (59, FMT_S),
8201 OPC_CMP_LT_S = FOP (60, FMT_S),
8202 OPC_CMP_NGE_S = FOP (61, FMT_S),
8203 OPC_CMP_LE_S = FOP (62, FMT_S),
8204 OPC_CMP_NGT_S = FOP (63, FMT_S),
8205
8206 OPC_ADD_D = FOP(0, FMT_D),
8207 OPC_SUB_D = FOP(1, FMT_D),
8208 OPC_MUL_D = FOP(2, FMT_D),
8209 OPC_DIV_D = FOP(3, FMT_D),
8210 OPC_SQRT_D = FOP(4, FMT_D),
8211 OPC_ABS_D = FOP(5, FMT_D),
8212 OPC_MOV_D = FOP(6, FMT_D),
8213 OPC_NEG_D = FOP(7, FMT_D),
8214 OPC_ROUND_L_D = FOP(8, FMT_D),
8215 OPC_TRUNC_L_D = FOP(9, FMT_D),
8216 OPC_CEIL_L_D = FOP(10, FMT_D),
8217 OPC_FLOOR_L_D = FOP(11, FMT_D),
8218 OPC_ROUND_W_D = FOP(12, FMT_D),
8219 OPC_TRUNC_W_D = FOP(13, FMT_D),
8220 OPC_CEIL_W_D = FOP(14, FMT_D),
8221 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8222 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8223 OPC_MOVCF_D = FOP(17, FMT_D),
8224 OPC_MOVZ_D = FOP(18, FMT_D),
8225 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8226 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8227 OPC_RECIP_D = FOP(21, FMT_D),
8228 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8229 OPC_SELNEZ_D = FOP(23, FMT_D),
8230 OPC_MADDF_D = FOP(24, FMT_D),
8231 OPC_MSUBF_D = FOP(25, FMT_D),
8232 OPC_RINT_D = FOP(26, FMT_D),
8233 OPC_CLASS_D = FOP(27, FMT_D),
8234 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8235 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8236 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8237 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8238 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8239 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8240 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8241 OPC_RSQRT2_D = FOP(31, FMT_D),
8242 OPC_CVT_S_D = FOP(32, FMT_D),
8243 OPC_CVT_W_D = FOP(36, FMT_D),
8244 OPC_CVT_L_D = FOP(37, FMT_D),
8245 OPC_CMP_F_D = FOP (48, FMT_D),
8246 OPC_CMP_UN_D = FOP (49, FMT_D),
8247 OPC_CMP_EQ_D = FOP (50, FMT_D),
8248 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8249 OPC_CMP_OLT_D = FOP (52, FMT_D),
8250 OPC_CMP_ULT_D = FOP (53, FMT_D),
8251 OPC_CMP_OLE_D = FOP (54, FMT_D),
8252 OPC_CMP_ULE_D = FOP (55, FMT_D),
8253 OPC_CMP_SF_D = FOP (56, FMT_D),
8254 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8255 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8256 OPC_CMP_NGL_D = FOP (59, FMT_D),
8257 OPC_CMP_LT_D = FOP (60, FMT_D),
8258 OPC_CMP_NGE_D = FOP (61, FMT_D),
8259 OPC_CMP_LE_D = FOP (62, FMT_D),
8260 OPC_CMP_NGT_D = FOP (63, FMT_D),
8261
8262 OPC_CVT_S_W = FOP(32, FMT_W),
8263 OPC_CVT_D_W = FOP(33, FMT_W),
8264 OPC_CVT_S_L = FOP(32, FMT_L),
8265 OPC_CVT_D_L = FOP(33, FMT_L),
8266 OPC_CVT_PS_PW = FOP(38, FMT_W),
8267
8268 OPC_ADD_PS = FOP(0, FMT_PS),
8269 OPC_SUB_PS = FOP(1, FMT_PS),
8270 OPC_MUL_PS = FOP(2, FMT_PS),
8271 OPC_DIV_PS = FOP(3, FMT_PS),
8272 OPC_ABS_PS = FOP(5, FMT_PS),
8273 OPC_MOV_PS = FOP(6, FMT_PS),
8274 OPC_NEG_PS = FOP(7, FMT_PS),
8275 OPC_MOVCF_PS = FOP(17, FMT_PS),
8276 OPC_MOVZ_PS = FOP(18, FMT_PS),
8277 OPC_MOVN_PS = FOP(19, FMT_PS),
8278 OPC_ADDR_PS = FOP(24, FMT_PS),
8279 OPC_MULR_PS = FOP(26, FMT_PS),
8280 OPC_RECIP2_PS = FOP(28, FMT_PS),
8281 OPC_RECIP1_PS = FOP(29, FMT_PS),
8282 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8283 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8284
8285 OPC_CVT_S_PU = FOP(32, FMT_PS),
8286 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8287 OPC_CVT_S_PL = FOP(40, FMT_PS),
8288 OPC_PLL_PS = FOP(44, FMT_PS),
8289 OPC_PLU_PS = FOP(45, FMT_PS),
8290 OPC_PUL_PS = FOP(46, FMT_PS),
8291 OPC_PUU_PS = FOP(47, FMT_PS),
8292 OPC_CMP_F_PS = FOP (48, FMT_PS),
8293 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8294 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8295 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8296 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8297 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8298 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8299 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8300 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8301 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8302 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8303 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8304 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8305 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8306 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8307 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8308};
8309
3f493883
YK
8310enum r6_f_cmp_op {
8311 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8312 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8313 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8314 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8315 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8316 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8317 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8318 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8319 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8320 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8321 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8322 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8323 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8324 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8325 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8326 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8327 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8328 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8329 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8330 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8331 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8332 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8333
8334 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8335 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8336 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8337 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8338 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8339 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8340 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8341 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8342 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8343 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8344 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8345 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8346 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8347 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8348 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8349 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8350 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8351 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8352 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8353 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8354 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8355 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8356};
7a387fff 8357static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8358{
923617a3 8359 const char *opn = "cp1 move";
72c3a3ee 8360 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8361
8362 switch (opc) {
8363 case OPC_MFC1:
b6d96bed 8364 {
a7812ae4 8365 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8366
7c979afd 8367 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8368 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8369 tcg_temp_free_i32(fp0);
6958549d 8370 }
6c5c1e20 8371 gen_store_gpr(t0, rt);
6ea83fed
FB
8372 opn = "mfc1";
8373 break;
8374 case OPC_MTC1:
6c5c1e20 8375 gen_load_gpr(t0, rt);
b6d96bed 8376 {
a7812ae4 8377 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8378
8379 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8380 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8381 tcg_temp_free_i32(fp0);
6958549d 8382 }
6ea83fed
FB
8383 opn = "mtc1";
8384 break;
8385 case OPC_CFC1:
895c2d04 8386 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8387 gen_store_gpr(t0, rt);
6ea83fed
FB
8388 opn = "cfc1";
8389 break;
8390 case OPC_CTC1:
6c5c1e20 8391 gen_load_gpr(t0, rt);
4cf8a45f 8392 save_cpu_state(ctx, 1);
736d120a
PJ
8393 {
8394 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8395
8396 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8397 tcg_temp_free_i32(fs_tmp);
8398 }
4cf8a45f
YK
8399 /* Stop translation as we may have changed hflags */
8400 ctx->bstate = BS_STOP;
6ea83fed
FB
8401 opn = "ctc1";
8402 break;
72c3a3ee 8403#if defined(TARGET_MIPS64)
9c2149c8 8404 case OPC_DMFC1:
72c3a3ee 8405 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8406 gen_store_gpr(t0, rt);
5a5012ec
TS
8407 opn = "dmfc1";
8408 break;
9c2149c8 8409 case OPC_DMTC1:
6c5c1e20 8410 gen_load_gpr(t0, rt);
72c3a3ee 8411 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8412 opn = "dmtc1";
8413 break;
72c3a3ee 8414#endif
5a5012ec 8415 case OPC_MFHC1:
b6d96bed 8416 {
a7812ae4 8417 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8418
7f6613ce 8419 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8420 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8421 tcg_temp_free_i32(fp0);
6958549d 8422 }
6c5c1e20 8423 gen_store_gpr(t0, rt);
5a5012ec
TS
8424 opn = "mfhc1";
8425 break;
8426 case OPC_MTHC1:
6c5c1e20 8427 gen_load_gpr(t0, rt);
b6d96bed 8428 {
a7812ae4 8429 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8430
8431 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8432 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8433 tcg_temp_free_i32(fp0);
6958549d 8434 }
5a5012ec
TS
8435 opn = "mthc1";
8436 break;
6ea83fed 8437 default:
923617a3 8438 MIPS_INVAL(opn);
e397ee33 8439 generate_exception (ctx, EXCP_RI);
6c5c1e20 8440 goto out;
6ea83fed 8441 }
2abf314d 8442 (void)opn; /* avoid a compiler warning */
6ea83fed 8443 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8444
8445 out:
8446 tcg_temp_free(t0);
6ea83fed
FB
8447}
8448
5a5012ec
TS
8449static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8450{
42a268c2 8451 TCGLabel *l1;
e214b9bb 8452 TCGCond cond;
af58f9ca
AJ
8453 TCGv_i32 t0;
8454
8455 if (rd == 0) {
8456 /* Treat as NOP. */
8457 return;
8458 }
6ea83fed 8459
e214b9bb 8460 if (tf)
e214b9bb 8461 cond = TCG_COND_EQ;
27848470
TS
8462 else
8463 cond = TCG_COND_NE;
8464
af58f9ca
AJ
8465 l1 = gen_new_label();
8466 t0 = tcg_temp_new_i32();
fa31af0e 8467 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8468 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8469 tcg_temp_free_i32(t0);
af58f9ca
AJ
8470 if (rs == 0) {
8471 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8472 } else {
8473 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8474 }
e214b9bb 8475 gen_set_label(l1);
5a5012ec
TS
8476}
8477
7c979afd
LA
8478static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8479 int tf)
a16336e4 8480{
a16336e4 8481 int cond;
cbc37b28 8482 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8483 TCGLabel *l1 = gen_new_label();
a16336e4 8484
a16336e4
TS
8485 if (tf)
8486 cond = TCG_COND_EQ;
8487 else
8488 cond = TCG_COND_NE;
8489
fa31af0e 8490 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8491 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8492 gen_load_fpr32(ctx, t0, fs);
8493 gen_store_fpr32(ctx, t0, fd);
a16336e4 8494 gen_set_label(l1);
cbc37b28 8495 tcg_temp_free_i32(t0);
5a5012ec 8496}
a16336e4 8497
b6d96bed 8498static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8499{
a16336e4 8500 int cond;
cbc37b28
AJ
8501 TCGv_i32 t0 = tcg_temp_new_i32();
8502 TCGv_i64 fp0;
42a268c2 8503 TCGLabel *l1 = gen_new_label();
a16336e4 8504
a16336e4
TS
8505 if (tf)
8506 cond = TCG_COND_EQ;
8507 else
8508 cond = TCG_COND_NE;
8509
fa31af0e 8510 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8511 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8512 tcg_temp_free_i32(t0);
11f94258 8513 fp0 = tcg_temp_new_i64();
9bf3eb2c 8514 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8515 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8516 tcg_temp_free_i64(fp0);
cbc37b28 8517 gen_set_label(l1);
a16336e4
TS
8518}
8519
7f6613ce
PJ
8520static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8521 int cc, int tf)
a16336e4
TS
8522{
8523 int cond;
cbc37b28 8524 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8525 TCGLabel *l1 = gen_new_label();
8526 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8527
8528 if (tf)
8529 cond = TCG_COND_EQ;
8530 else
8531 cond = TCG_COND_NE;
8532
fa31af0e 8533 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8534 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8535 gen_load_fpr32(ctx, t0, fs);
8536 gen_store_fpr32(ctx, t0, fd);
a16336e4 8537 gen_set_label(l1);
9bf3eb2c 8538
fa31af0e 8539 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8540 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8541 gen_load_fpr32h(ctx, t0, fs);
8542 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8543 tcg_temp_free_i32(t0);
a16336e4 8544 gen_set_label(l2);
a16336e4
TS
8545}
8546
e7f16abb
LA
8547static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8548 int fs)
8549{
8550 TCGv_i32 t1 = tcg_const_i32(0);
8551 TCGv_i32 fp0 = tcg_temp_new_i32();
8552 TCGv_i32 fp1 = tcg_temp_new_i32();
8553 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8554 gen_load_fpr32(ctx, fp0, fd);
8555 gen_load_fpr32(ctx, fp1, ft);
8556 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8557
8558 switch (op1) {
8559 case OPC_SEL_S:
8560 tcg_gen_andi_i32(fp0, fp0, 1);
8561 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8562 break;
8563 case OPC_SELEQZ_S:
8564 tcg_gen_andi_i32(fp1, fp1, 1);
8565 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8566 break;
8567 case OPC_SELNEZ_S:
8568 tcg_gen_andi_i32(fp1, fp1, 1);
8569 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8570 break;
8571 default:
8572 MIPS_INVAL("gen_sel_s");
8573 generate_exception (ctx, EXCP_RI);
8574 break;
8575 }
8576
7c979afd 8577 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8578 tcg_temp_free_i32(fp2);
8579 tcg_temp_free_i32(fp1);
8580 tcg_temp_free_i32(fp0);
8581 tcg_temp_free_i32(t1);
8582}
8583
8584static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8585 int fs)
8586{
8587 TCGv_i64 t1 = tcg_const_i64(0);
8588 TCGv_i64 fp0 = tcg_temp_new_i64();
8589 TCGv_i64 fp1 = tcg_temp_new_i64();
8590 TCGv_i64 fp2 = tcg_temp_new_i64();
8591 gen_load_fpr64(ctx, fp0, fd);
8592 gen_load_fpr64(ctx, fp1, ft);
8593 gen_load_fpr64(ctx, fp2, fs);
8594
8595 switch (op1) {
8596 case OPC_SEL_D:
8597 tcg_gen_andi_i64(fp0, fp0, 1);
8598 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8599 break;
8600 case OPC_SELEQZ_D:
8601 tcg_gen_andi_i64(fp1, fp1, 1);
8602 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8603 break;
8604 case OPC_SELNEZ_D:
8605 tcg_gen_andi_i64(fp1, fp1, 1);
8606 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8607 break;
8608 default:
8609 MIPS_INVAL("gen_sel_d");
8610 generate_exception (ctx, EXCP_RI);
8611 break;
8612 }
8613
8614 gen_store_fpr64(ctx, fp0, fd);
8615 tcg_temp_free_i64(fp2);
8616 tcg_temp_free_i64(fp1);
8617 tcg_temp_free_i64(fp0);
8618 tcg_temp_free_i64(t1);
8619}
6ea83fed 8620
bf4120ad 8621static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8622 int ft, int fs, int fd, int cc)
6ea83fed 8623{
923617a3 8624 const char *opn = "farith";
6ea83fed
FB
8625 const char *condnames[] = {
8626 "c.f",
8627 "c.un",
8628 "c.eq",
8629 "c.ueq",
8630 "c.olt",
8631 "c.ult",
8632 "c.ole",
8633 "c.ule",
8634 "c.sf",
8635 "c.ngle",
8636 "c.seq",
8637 "c.ngl",
8638 "c.lt",
8639 "c.nge",
8640 "c.le",
8641 "c.ngt",
8642 };
5a1e8ffb
TS
8643 const char *condnames_abs[] = {
8644 "cabs.f",
8645 "cabs.un",
8646 "cabs.eq",
8647 "cabs.ueq",
8648 "cabs.olt",
8649 "cabs.ult",
8650 "cabs.ole",
8651 "cabs.ule",
8652 "cabs.sf",
8653 "cabs.ngle",
8654 "cabs.seq",
8655 "cabs.ngl",
8656 "cabs.lt",
8657 "cabs.nge",
8658 "cabs.le",
8659 "cabs.ngt",
8660 };
8661 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8662 uint32_t func = ctx->opcode & 0x3f;
8663
bf4120ad
NF
8664 switch (op1) {
8665 case OPC_ADD_S:
b6d96bed 8666 {
a7812ae4
PB
8667 TCGv_i32 fp0 = tcg_temp_new_i32();
8668 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8669
7c979afd
LA
8670 gen_load_fpr32(ctx, fp0, fs);
8671 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8672 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8673 tcg_temp_free_i32(fp1);
7c979afd 8674 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8675 tcg_temp_free_i32(fp0);
b6d96bed 8676 }
5a5012ec 8677 opn = "add.s";
5a1e8ffb 8678 optype = BINOP;
5a5012ec 8679 break;
bf4120ad 8680 case OPC_SUB_S:
b6d96bed 8681 {
a7812ae4
PB
8682 TCGv_i32 fp0 = tcg_temp_new_i32();
8683 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8684
7c979afd
LA
8685 gen_load_fpr32(ctx, fp0, fs);
8686 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8687 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8688 tcg_temp_free_i32(fp1);
7c979afd 8689 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8690 tcg_temp_free_i32(fp0);
b6d96bed 8691 }
5a5012ec 8692 opn = "sub.s";
5a1e8ffb 8693 optype = BINOP;
5a5012ec 8694 break;
bf4120ad 8695 case OPC_MUL_S:
b6d96bed 8696 {
a7812ae4
PB
8697 TCGv_i32 fp0 = tcg_temp_new_i32();
8698 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8699
7c979afd
LA
8700 gen_load_fpr32(ctx, fp0, fs);
8701 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8702 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8703 tcg_temp_free_i32(fp1);
7c979afd 8704 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8705 tcg_temp_free_i32(fp0);
b6d96bed 8706 }
5a5012ec 8707 opn = "mul.s";
5a1e8ffb 8708 optype = BINOP;
5a5012ec 8709 break;
bf4120ad 8710 case OPC_DIV_S:
b6d96bed 8711 {
a7812ae4
PB
8712 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8714
7c979afd
LA
8715 gen_load_fpr32(ctx, fp0, fs);
8716 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8717 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8718 tcg_temp_free_i32(fp1);
7c979afd 8719 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8720 tcg_temp_free_i32(fp0);
b6d96bed 8721 }
5a5012ec 8722 opn = "div.s";
5a1e8ffb 8723 optype = BINOP;
5a5012ec 8724 break;
bf4120ad 8725 case OPC_SQRT_S:
b6d96bed 8726 {
a7812ae4 8727 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8728
7c979afd 8729 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8730 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8731 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8732 tcg_temp_free_i32(fp0);
b6d96bed 8733 }
5a5012ec
TS
8734 opn = "sqrt.s";
8735 break;
bf4120ad 8736 case OPC_ABS_S:
b6d96bed 8737 {
a7812ae4 8738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8739
7c979afd 8740 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8741 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8742 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8743 tcg_temp_free_i32(fp0);
b6d96bed 8744 }
5a5012ec
TS
8745 opn = "abs.s";
8746 break;
bf4120ad 8747 case OPC_MOV_S:
b6d96bed 8748 {
a7812ae4 8749 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8750
7c979afd
LA
8751 gen_load_fpr32(ctx, fp0, fs);
8752 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8753 tcg_temp_free_i32(fp0);
b6d96bed 8754 }
5a5012ec
TS
8755 opn = "mov.s";
8756 break;
bf4120ad 8757 case OPC_NEG_S:
b6d96bed 8758 {
a7812ae4 8759 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8760
7c979afd 8761 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8762 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8763 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8764 tcg_temp_free_i32(fp0);
b6d96bed 8765 }
5a5012ec
TS
8766 opn = "neg.s";
8767 break;
bf4120ad 8768 case OPC_ROUND_L_S:
5e755519 8769 check_cp1_64bitmode(ctx);
b6d96bed 8770 {
a7812ae4
PB
8771 TCGv_i32 fp32 = tcg_temp_new_i32();
8772 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8773
7c979afd 8774 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8775 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8776 tcg_temp_free_i32(fp32);
b6d96bed 8777 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8778 tcg_temp_free_i64(fp64);
b6d96bed 8779 }
5a5012ec
TS
8780 opn = "round.l.s";
8781 break;
bf4120ad 8782 case OPC_TRUNC_L_S:
5e755519 8783 check_cp1_64bitmode(ctx);
b6d96bed 8784 {
a7812ae4
PB
8785 TCGv_i32 fp32 = tcg_temp_new_i32();
8786 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8787
7c979afd 8788 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8789 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8790 tcg_temp_free_i32(fp32);
b6d96bed 8791 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8792 tcg_temp_free_i64(fp64);
b6d96bed 8793 }
5a5012ec
TS
8794 opn = "trunc.l.s";
8795 break;
bf4120ad 8796 case OPC_CEIL_L_S:
5e755519 8797 check_cp1_64bitmode(ctx);
b6d96bed 8798 {
a7812ae4
PB
8799 TCGv_i32 fp32 = tcg_temp_new_i32();
8800 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8801
7c979afd 8802 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8803 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8804 tcg_temp_free_i32(fp32);
b6d96bed 8805 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8806 tcg_temp_free_i64(fp64);
b6d96bed 8807 }
5a5012ec
TS
8808 opn = "ceil.l.s";
8809 break;
bf4120ad 8810 case OPC_FLOOR_L_S:
5e755519 8811 check_cp1_64bitmode(ctx);
b6d96bed 8812 {
a7812ae4
PB
8813 TCGv_i32 fp32 = tcg_temp_new_i32();
8814 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8815
7c979afd 8816 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8817 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8818 tcg_temp_free_i32(fp32);
b6d96bed 8819 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8820 tcg_temp_free_i64(fp64);
b6d96bed 8821 }
5a5012ec
TS
8822 opn = "floor.l.s";
8823 break;
bf4120ad 8824 case OPC_ROUND_W_S:
b6d96bed 8825 {
a7812ae4 8826 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8827
7c979afd 8828 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8829 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8830 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8831 tcg_temp_free_i32(fp0);
b6d96bed 8832 }
5a5012ec
TS
8833 opn = "round.w.s";
8834 break;
bf4120ad 8835 case OPC_TRUNC_W_S:
b6d96bed 8836 {
a7812ae4 8837 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8838
7c979afd 8839 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8840 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8841 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8842 tcg_temp_free_i32(fp0);
b6d96bed 8843 }
5a5012ec
TS
8844 opn = "trunc.w.s";
8845 break;
bf4120ad 8846 case OPC_CEIL_W_S:
b6d96bed 8847 {
a7812ae4 8848 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8849
7c979afd 8850 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8851 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8852 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8853 tcg_temp_free_i32(fp0);
b6d96bed 8854 }
5a5012ec
TS
8855 opn = "ceil.w.s";
8856 break;
bf4120ad 8857 case OPC_FLOOR_W_S:
b6d96bed 8858 {
a7812ae4 8859 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8860
7c979afd 8861 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8862 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8863 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8864 tcg_temp_free_i32(fp0);
b6d96bed 8865 }
5a5012ec
TS
8866 opn = "floor.w.s";
8867 break;
e7f16abb
LA
8868 case OPC_SEL_S:
8869 check_insn(ctx, ISA_MIPS32R6);
8870 gen_sel_s(ctx, op1, fd, ft, fs);
8871 opn = "sel.s";
8872 break;
8873 case OPC_SELEQZ_S:
8874 check_insn(ctx, ISA_MIPS32R6);
8875 gen_sel_s(ctx, op1, fd, ft, fs);
8876 opn = "seleqz.s";
8877 break;
8878 case OPC_SELNEZ_S:
8879 check_insn(ctx, ISA_MIPS32R6);
8880 gen_sel_s(ctx, op1, fd, ft, fs);
8881 opn = "selnez.s";
8882 break;
bf4120ad 8883 case OPC_MOVCF_S:
fecd2646 8884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8885 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8886 opn = "movcf.s";
8887 break;
bf4120ad 8888 case OPC_MOVZ_S:
fecd2646 8889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8890 {
42a268c2 8891 TCGLabel *l1 = gen_new_label();
c9297f4d 8892 TCGv_i32 fp0;
a16336e4 8893
c9297f4d
AJ
8894 if (ft != 0) {
8895 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8896 }
8897 fp0 = tcg_temp_new_i32();
7c979afd
LA
8898 gen_load_fpr32(ctx, fp0, fs);
8899 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8900 tcg_temp_free_i32(fp0);
a16336e4
TS
8901 gen_set_label(l1);
8902 }
5a5012ec
TS
8903 opn = "movz.s";
8904 break;
bf4120ad 8905 case OPC_MOVN_S:
fecd2646 8906 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8907 {
42a268c2 8908 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8909 TCGv_i32 fp0;
8910
8911 if (ft != 0) {
8912 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8913 fp0 = tcg_temp_new_i32();
7c979afd
LA
8914 gen_load_fpr32(ctx, fp0, fs);
8915 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8916 tcg_temp_free_i32(fp0);
8917 gen_set_label(l1);
8918 }
a16336e4 8919 }
5a5012ec
TS
8920 opn = "movn.s";
8921 break;
bf4120ad 8922 case OPC_RECIP_S:
b8aa4598 8923 check_cop1x(ctx);
b6d96bed 8924 {
a7812ae4 8925 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8926
7c979afd 8927 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8928 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8929 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8930 tcg_temp_free_i32(fp0);
b6d96bed 8931 }
57fa1fb3
TS
8932 opn = "recip.s";
8933 break;
bf4120ad 8934 case OPC_RSQRT_S:
b8aa4598 8935 check_cop1x(ctx);
b6d96bed 8936 {
a7812ae4 8937 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8938
7c979afd 8939 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8940 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8941 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8942 tcg_temp_free_i32(fp0);
b6d96bed 8943 }
57fa1fb3
TS
8944 opn = "rsqrt.s";
8945 break;
e7f16abb
LA
8946 case OPC_MADDF_S:
8947 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8948 {
a7812ae4
PB
8949 TCGv_i32 fp0 = tcg_temp_new_i32();
8950 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8951 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8952 gen_load_fpr32(ctx, fp0, fs);
8953 gen_load_fpr32(ctx, fp1, ft);
8954 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8955 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8956 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 8957 tcg_temp_free_i32(fp2);
a7812ae4 8958 tcg_temp_free_i32(fp1);
a7812ae4 8959 tcg_temp_free_i32(fp0);
e7f16abb 8960 opn = "maddf.s";
b6d96bed 8961 }
57fa1fb3 8962 break;
e7f16abb
LA
8963 case OPC_MSUBF_S:
8964 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8965 {
a7812ae4 8966 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8967 TCGv_i32 fp1 = tcg_temp_new_i32();
8968 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8969 gen_load_fpr32(ctx, fp0, fs);
8970 gen_load_fpr32(ctx, fp1, ft);
8971 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8972 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8973 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8974 tcg_temp_free_i32(fp2);
8975 tcg_temp_free_i32(fp1);
a7812ae4 8976 tcg_temp_free_i32(fp0);
e7f16abb 8977 opn = "msubf.s";
b6d96bed 8978 }
57fa1fb3 8979 break;
e7f16abb
LA
8980 case OPC_RINT_S:
8981 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8982 {
a7812ae4 8983 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8984 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8985 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 8986 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8987 tcg_temp_free_i32(fp0);
e7f16abb 8988 opn = "rint.s";
b6d96bed 8989 }
57fa1fb3 8990 break;
e7f16abb
LA
8991 case OPC_CLASS_S:
8992 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8993 {
e7f16abb 8994 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8995 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8996 gen_helper_float_class_s(fp0, fp0);
7c979afd 8997 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8998 tcg_temp_free_i32(fp0);
8999 opn = "class.s";
9000 }
9001 break;
9002 case OPC_MIN_S: /* OPC_RECIP2_S */
9003 if (ctx->insn_flags & ISA_MIPS32R6) {
9004 /* OPC_MIN_S */
a7812ae4
PB
9005 TCGv_i32 fp0 = tcg_temp_new_i32();
9006 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9007 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9008 gen_load_fpr32(ctx, fp0, fs);
9009 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9010 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9011 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9012 tcg_temp_free_i32(fp2);
9013 tcg_temp_free_i32(fp1);
9014 tcg_temp_free_i32(fp0);
9015 opn = "min.s";
9016 } else {
9017 /* OPC_RECIP2_S */
9018 check_cp1_64bitmode(ctx);
9019 {
9020 TCGv_i32 fp0 = tcg_temp_new_i32();
9021 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9022
7c979afd
LA
9023 gen_load_fpr32(ctx, fp0, fs);
9024 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9025 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9026 tcg_temp_free_i32(fp1);
7c979afd 9027 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9028 tcg_temp_free_i32(fp0);
9029 }
9030 opn = "recip2.s";
9031 }
9032 break;
9033 case OPC_MINA_S: /* OPC_RECIP1_S */
9034 if (ctx->insn_flags & ISA_MIPS32R6) {
9035 /* OPC_MINA_S */
9036 TCGv_i32 fp0 = tcg_temp_new_i32();
9037 TCGv_i32 fp1 = tcg_temp_new_i32();
9038 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9039 gen_load_fpr32(ctx, fp0, fs);
9040 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9041 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9042 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9043 tcg_temp_free_i32(fp2);
9044 tcg_temp_free_i32(fp1);
9045 tcg_temp_free_i32(fp0);
9046 opn = "mina.s";
9047 } else {
9048 /* OPC_RECIP1_S */
9049 check_cp1_64bitmode(ctx);
9050 {
9051 TCGv_i32 fp0 = tcg_temp_new_i32();
9052
7c979afd 9053 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9054 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9055 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9056 tcg_temp_free_i32(fp0);
9057 }
9058 opn = "recip1.s";
9059 }
9060 break;
9061 case OPC_MAX_S: /* OPC_RSQRT1_S */
9062 if (ctx->insn_flags & ISA_MIPS32R6) {
9063 /* OPC_MAX_S */
9064 TCGv_i32 fp0 = tcg_temp_new_i32();
9065 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9066 gen_load_fpr32(ctx, fp0, fs);
9067 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9068 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9069 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9070 tcg_temp_free_i32(fp1);
9071 tcg_temp_free_i32(fp0);
9072 opn = "max.s";
9073 } else {
9074 /* OPC_RSQRT1_S */
9075 check_cp1_64bitmode(ctx);
9076 {
9077 TCGv_i32 fp0 = tcg_temp_new_i32();
9078
7c979afd 9079 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9080 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9081 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9082 tcg_temp_free_i32(fp0);
9083 }
9084 opn = "rsqrt1.s";
9085 }
9086 break;
9087 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9088 if (ctx->insn_flags & ISA_MIPS32R6) {
9089 /* OPC_MAXA_S */
9090 TCGv_i32 fp0 = tcg_temp_new_i32();
9091 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9092 gen_load_fpr32(ctx, fp0, fs);
9093 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9094 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9095 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9096 tcg_temp_free_i32(fp1);
a7812ae4 9097 tcg_temp_free_i32(fp0);
e7f16abb
LA
9098 opn = "maxa.s";
9099 } else {
9100 /* OPC_RSQRT2_S */
9101 check_cp1_64bitmode(ctx);
9102 {
9103 TCGv_i32 fp0 = tcg_temp_new_i32();
9104 TCGv_i32 fp1 = tcg_temp_new_i32();
9105
7c979afd
LA
9106 gen_load_fpr32(ctx, fp0, fs);
9107 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9108 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9109 tcg_temp_free_i32(fp1);
7c979afd 9110 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9111 tcg_temp_free_i32(fp0);
9112 }
9113 opn = "rsqrt2.s";
b6d96bed 9114 }
57fa1fb3 9115 break;
bf4120ad 9116 case OPC_CVT_D_S:
5e755519 9117 check_cp1_registers(ctx, fd);
b6d96bed 9118 {
a7812ae4
PB
9119 TCGv_i32 fp32 = tcg_temp_new_i32();
9120 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9121
7c979afd 9122 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9123 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9124 tcg_temp_free_i32(fp32);
b6d96bed 9125 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9126 tcg_temp_free_i64(fp64);
b6d96bed 9127 }
5a5012ec
TS
9128 opn = "cvt.d.s";
9129 break;
bf4120ad 9130 case OPC_CVT_W_S:
b6d96bed 9131 {
a7812ae4 9132 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9133
7c979afd 9134 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9135 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9136 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9137 tcg_temp_free_i32(fp0);
b6d96bed 9138 }
5a5012ec
TS
9139 opn = "cvt.w.s";
9140 break;
bf4120ad 9141 case OPC_CVT_L_S:
5e755519 9142 check_cp1_64bitmode(ctx);
b6d96bed 9143 {
a7812ae4
PB
9144 TCGv_i32 fp32 = tcg_temp_new_i32();
9145 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9146
7c979afd 9147 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9148 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9149 tcg_temp_free_i32(fp32);
b6d96bed 9150 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9151 tcg_temp_free_i64(fp64);
b6d96bed 9152 }
5a5012ec
TS
9153 opn = "cvt.l.s";
9154 break;
bf4120ad 9155 case OPC_CVT_PS_S:
fecd2646 9156 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9157 check_cp1_64bitmode(ctx);
b6d96bed 9158 {
a7812ae4
PB
9159 TCGv_i64 fp64 = tcg_temp_new_i64();
9160 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9161 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9162
7c979afd
LA
9163 gen_load_fpr32(ctx, fp32_0, fs);
9164 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9165 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9166 tcg_temp_free_i32(fp32_1);
9167 tcg_temp_free_i32(fp32_0);
36aa55dc 9168 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9169 tcg_temp_free_i64(fp64);
b6d96bed 9170 }
5a5012ec
TS
9171 opn = "cvt.ps.s";
9172 break;
bf4120ad
NF
9173 case OPC_CMP_F_S:
9174 case OPC_CMP_UN_S:
9175 case OPC_CMP_EQ_S:
9176 case OPC_CMP_UEQ_S:
9177 case OPC_CMP_OLT_S:
9178 case OPC_CMP_ULT_S:
9179 case OPC_CMP_OLE_S:
9180 case OPC_CMP_ULE_S:
9181 case OPC_CMP_SF_S:
9182 case OPC_CMP_NGLE_S:
9183 case OPC_CMP_SEQ_S:
9184 case OPC_CMP_NGL_S:
9185 case OPC_CMP_LT_S:
9186 case OPC_CMP_NGE_S:
9187 case OPC_CMP_LE_S:
9188 case OPC_CMP_NGT_S:
fecd2646 9189 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9190 if (ctx->opcode & (1 << 6)) {
9191 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9192 opn = condnames_abs[func-48];
9193 } else {
9194 gen_cmp_s(ctx, func-48, ft, fs, cc);
9195 opn = condnames[func-48];
5a1e8ffb 9196 }
5a5012ec 9197 break;
bf4120ad 9198 case OPC_ADD_D:
5e755519 9199 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9200 {
a7812ae4
PB
9201 TCGv_i64 fp0 = tcg_temp_new_i64();
9202 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9203
9204 gen_load_fpr64(ctx, fp0, fs);
9205 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9206 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9207 tcg_temp_free_i64(fp1);
b6d96bed 9208 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9209 tcg_temp_free_i64(fp0);
b6d96bed 9210 }
6ea83fed 9211 opn = "add.d";
5a1e8ffb 9212 optype = BINOP;
6ea83fed 9213 break;
bf4120ad 9214 case OPC_SUB_D:
5e755519 9215 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9216 {
a7812ae4
PB
9217 TCGv_i64 fp0 = tcg_temp_new_i64();
9218 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9219
9220 gen_load_fpr64(ctx, fp0, fs);
9221 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9222 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9223 tcg_temp_free_i64(fp1);
b6d96bed 9224 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9225 tcg_temp_free_i64(fp0);
b6d96bed 9226 }
6ea83fed 9227 opn = "sub.d";
5a1e8ffb 9228 optype = BINOP;
6ea83fed 9229 break;
bf4120ad 9230 case OPC_MUL_D:
5e755519 9231 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9232 {
a7812ae4
PB
9233 TCGv_i64 fp0 = tcg_temp_new_i64();
9234 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9235
9236 gen_load_fpr64(ctx, fp0, fs);
9237 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9238 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9239 tcg_temp_free_i64(fp1);
b6d96bed 9240 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9241 tcg_temp_free_i64(fp0);
b6d96bed 9242 }
6ea83fed 9243 opn = "mul.d";
5a1e8ffb 9244 optype = BINOP;
6ea83fed 9245 break;
bf4120ad 9246 case OPC_DIV_D:
5e755519 9247 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9248 {
a7812ae4
PB
9249 TCGv_i64 fp0 = tcg_temp_new_i64();
9250 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9251
9252 gen_load_fpr64(ctx, fp0, fs);
9253 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9254 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9255 tcg_temp_free_i64(fp1);
b6d96bed 9256 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9257 tcg_temp_free_i64(fp0);
b6d96bed 9258 }
6ea83fed 9259 opn = "div.d";
5a1e8ffb 9260 optype = BINOP;
6ea83fed 9261 break;
bf4120ad 9262 case OPC_SQRT_D:
5e755519 9263 check_cp1_registers(ctx, fs | fd);
b6d96bed 9264 {
a7812ae4 9265 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9266
9267 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9268 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9269 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9270 tcg_temp_free_i64(fp0);
b6d96bed 9271 }
6ea83fed
FB
9272 opn = "sqrt.d";
9273 break;
bf4120ad 9274 case OPC_ABS_D:
5e755519 9275 check_cp1_registers(ctx, fs | fd);
b6d96bed 9276 {
a7812ae4 9277 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9278
9279 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9280 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9281 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9282 tcg_temp_free_i64(fp0);
b6d96bed 9283 }
6ea83fed
FB
9284 opn = "abs.d";
9285 break;
bf4120ad 9286 case OPC_MOV_D:
5e755519 9287 check_cp1_registers(ctx, fs | fd);
b6d96bed 9288 {
a7812ae4 9289 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9290
9291 gen_load_fpr64(ctx, fp0, fs);
9292 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9293 tcg_temp_free_i64(fp0);
b6d96bed 9294 }
6ea83fed
FB
9295 opn = "mov.d";
9296 break;
bf4120ad 9297 case OPC_NEG_D:
5e755519 9298 check_cp1_registers(ctx, fs | fd);
b6d96bed 9299 {
a7812ae4 9300 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9301
9302 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9303 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9304 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9305 tcg_temp_free_i64(fp0);
b6d96bed 9306 }
6ea83fed
FB
9307 opn = "neg.d";
9308 break;
bf4120ad 9309 case OPC_ROUND_L_D:
5e755519 9310 check_cp1_64bitmode(ctx);
b6d96bed 9311 {
a7812ae4 9312 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9313
9314 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9315 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9316 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9317 tcg_temp_free_i64(fp0);
b6d96bed 9318 }
5a5012ec
TS
9319 opn = "round.l.d";
9320 break;
bf4120ad 9321 case OPC_TRUNC_L_D:
5e755519 9322 check_cp1_64bitmode(ctx);
b6d96bed 9323 {
a7812ae4 9324 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9325
9326 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9327 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9328 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9329 tcg_temp_free_i64(fp0);
b6d96bed 9330 }
5a5012ec
TS
9331 opn = "trunc.l.d";
9332 break;
bf4120ad 9333 case OPC_CEIL_L_D:
5e755519 9334 check_cp1_64bitmode(ctx);
b6d96bed 9335 {
a7812ae4 9336 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9337
9338 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9339 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9340 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9341 tcg_temp_free_i64(fp0);
b6d96bed 9342 }
5a5012ec
TS
9343 opn = "ceil.l.d";
9344 break;
bf4120ad 9345 case OPC_FLOOR_L_D:
5e755519 9346 check_cp1_64bitmode(ctx);
b6d96bed 9347 {
a7812ae4 9348 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9349
9350 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9351 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9352 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9353 tcg_temp_free_i64(fp0);
b6d96bed 9354 }
5a5012ec
TS
9355 opn = "floor.l.d";
9356 break;
bf4120ad 9357 case OPC_ROUND_W_D:
5e755519 9358 check_cp1_registers(ctx, fs);
b6d96bed 9359 {
a7812ae4
PB
9360 TCGv_i32 fp32 = tcg_temp_new_i32();
9361 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9362
9363 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9364 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9365 tcg_temp_free_i64(fp64);
7c979afd 9366 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9367 tcg_temp_free_i32(fp32);
b6d96bed 9368 }
6ea83fed
FB
9369 opn = "round.w.d";
9370 break;
bf4120ad 9371 case OPC_TRUNC_W_D:
5e755519 9372 check_cp1_registers(ctx, fs);
b6d96bed 9373 {
a7812ae4
PB
9374 TCGv_i32 fp32 = tcg_temp_new_i32();
9375 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9376
9377 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9378 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9379 tcg_temp_free_i64(fp64);
7c979afd 9380 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9381 tcg_temp_free_i32(fp32);
b6d96bed 9382 }
6ea83fed
FB
9383 opn = "trunc.w.d";
9384 break;
bf4120ad 9385 case OPC_CEIL_W_D:
5e755519 9386 check_cp1_registers(ctx, fs);
b6d96bed 9387 {
a7812ae4
PB
9388 TCGv_i32 fp32 = tcg_temp_new_i32();
9389 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9390
9391 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9392 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9393 tcg_temp_free_i64(fp64);
7c979afd 9394 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9395 tcg_temp_free_i32(fp32);
b6d96bed 9396 }
6ea83fed
FB
9397 opn = "ceil.w.d";
9398 break;
bf4120ad 9399 case OPC_FLOOR_W_D:
5e755519 9400 check_cp1_registers(ctx, fs);
b6d96bed 9401 {
a7812ae4
PB
9402 TCGv_i32 fp32 = tcg_temp_new_i32();
9403 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9404
9405 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9406 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9407 tcg_temp_free_i64(fp64);
7c979afd 9408 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9409 tcg_temp_free_i32(fp32);
b6d96bed 9410 }
7a387fff 9411 opn = "floor.w.d";
6ea83fed 9412 break;
e7f16abb
LA
9413 case OPC_SEL_D:
9414 check_insn(ctx, ISA_MIPS32R6);
9415 gen_sel_d(ctx, op1, fd, ft, fs);
9416 opn = "sel.d";
9417 break;
9418 case OPC_SELEQZ_D:
9419 check_insn(ctx, ISA_MIPS32R6);
9420 gen_sel_d(ctx, op1, fd, ft, fs);
9421 opn = "seleqz.d";
9422 break;
9423 case OPC_SELNEZ_D:
9424 check_insn(ctx, ISA_MIPS32R6);
9425 gen_sel_d(ctx, op1, fd, ft, fs);
9426 opn = "selnez.d";
9427 break;
bf4120ad 9428 case OPC_MOVCF_D:
fecd2646 9429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9430 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9431 opn = "movcf.d";
dd016883 9432 break;
bf4120ad 9433 case OPC_MOVZ_D:
fecd2646 9434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9435 {
42a268c2 9436 TCGLabel *l1 = gen_new_label();
c9297f4d 9437 TCGv_i64 fp0;
a16336e4 9438
c9297f4d
AJ
9439 if (ft != 0) {
9440 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9441 }
9442 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9443 gen_load_fpr64(ctx, fp0, fs);
9444 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9445 tcg_temp_free_i64(fp0);
a16336e4
TS
9446 gen_set_label(l1);
9447 }
5a5012ec
TS
9448 opn = "movz.d";
9449 break;
bf4120ad 9450 case OPC_MOVN_D:
fecd2646 9451 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9452 {
42a268c2 9453 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9454 TCGv_i64 fp0;
9455
9456 if (ft != 0) {
9457 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9458 fp0 = tcg_temp_new_i64();
9459 gen_load_fpr64(ctx, fp0, fs);
9460 gen_store_fpr64(ctx, fp0, fd);
9461 tcg_temp_free_i64(fp0);
9462 gen_set_label(l1);
9463 }
a16336e4 9464 }
5a5012ec 9465 opn = "movn.d";
6ea83fed 9466 break;
bf4120ad 9467 case OPC_RECIP_D:
b8aa4598 9468 check_cp1_64bitmode(ctx);
b6d96bed 9469 {
a7812ae4 9470 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9471
9472 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9473 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9474 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9475 tcg_temp_free_i64(fp0);
b6d96bed 9476 }
57fa1fb3
TS
9477 opn = "recip.d";
9478 break;
bf4120ad 9479 case OPC_RSQRT_D:
b8aa4598 9480 check_cp1_64bitmode(ctx);
b6d96bed 9481 {
a7812ae4 9482 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9483
9484 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9485 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9486 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9487 tcg_temp_free_i64(fp0);
b6d96bed 9488 }
57fa1fb3
TS
9489 opn = "rsqrt.d";
9490 break;
e7f16abb
LA
9491 case OPC_MADDF_D:
9492 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9493 {
a7812ae4
PB
9494 TCGv_i64 fp0 = tcg_temp_new_i64();
9495 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9496 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9497 gen_load_fpr64(ctx, fp0, fs);
9498 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9499 gen_load_fpr64(ctx, fp2, fd);
9500 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9501 gen_store_fpr64(ctx, fp2, fd);
9502 tcg_temp_free_i64(fp2);
a7812ae4 9503 tcg_temp_free_i64(fp1);
a7812ae4 9504 tcg_temp_free_i64(fp0);
e7f16abb 9505 opn = "maddf.d";
b6d96bed 9506 }
57fa1fb3 9507 break;
e7f16abb
LA
9508 case OPC_MSUBF_D:
9509 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9510 {
a7812ae4 9511 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9512 TCGv_i64 fp1 = tcg_temp_new_i64();
9513 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9514 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9515 gen_load_fpr64(ctx, fp1, ft);
9516 gen_load_fpr64(ctx, fp2, fd);
9517 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9518 gen_store_fpr64(ctx, fp2, fd);
9519 tcg_temp_free_i64(fp2);
9520 tcg_temp_free_i64(fp1);
a7812ae4 9521 tcg_temp_free_i64(fp0);
e7f16abb 9522 opn = "msubf.d";
b6d96bed 9523 }
57fa1fb3 9524 break;
e7f16abb
LA
9525 case OPC_RINT_D:
9526 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9527 {
a7812ae4 9528 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9529 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9530 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9532 tcg_temp_free_i64(fp0);
e7f16abb 9533 opn = "rint.d";
b6d96bed 9534 }
57fa1fb3 9535 break;
e7f16abb
LA
9536 case OPC_CLASS_D:
9537 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9538 {
e7f16abb
LA
9539 TCGv_i64 fp0 = tcg_temp_new_i64();
9540 gen_load_fpr64(ctx, fp0, fs);
9541 gen_helper_float_class_d(fp0, fp0);
9542 gen_store_fpr64(ctx, fp0, fd);
9543 tcg_temp_free_i64(fp0);
9544 opn = "class.d";
9545 }
9546 break;
9547 case OPC_MIN_D: /* OPC_RECIP2_D */
9548 if (ctx->insn_flags & ISA_MIPS32R6) {
9549 /* OPC_MIN_D */
a7812ae4
PB
9550 TCGv_i64 fp0 = tcg_temp_new_i64();
9551 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9552 gen_load_fpr64(ctx, fp0, fs);
9553 gen_load_fpr64(ctx, fp1, ft);
9554 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9555 gen_store_fpr64(ctx, fp1, fd);
9556 tcg_temp_free_i64(fp1);
9557 tcg_temp_free_i64(fp0);
9558 opn = "min.d";
9559 } else {
9560 /* OPC_RECIP2_D */
9561 check_cp1_64bitmode(ctx);
9562 {
9563 TCGv_i64 fp0 = tcg_temp_new_i64();
9564 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9565
e7f16abb
LA
9566 gen_load_fpr64(ctx, fp0, fs);
9567 gen_load_fpr64(ctx, fp1, ft);
9568 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9569 tcg_temp_free_i64(fp1);
9570 gen_store_fpr64(ctx, fp0, fd);
9571 tcg_temp_free_i64(fp0);
9572 }
9573 opn = "recip2.d";
9574 }
9575 break;
9576 case OPC_MINA_D: /* OPC_RECIP1_D */
9577 if (ctx->insn_flags & ISA_MIPS32R6) {
9578 /* OPC_MINA_D */
9579 TCGv_i64 fp0 = tcg_temp_new_i64();
9580 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9581 gen_load_fpr64(ctx, fp0, fs);
9582 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9583 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9584 gen_store_fpr64(ctx, fp1, fd);
9585 tcg_temp_free_i64(fp1);
9586 tcg_temp_free_i64(fp0);
9587 opn = "mina.d";
9588 } else {
9589 /* OPC_RECIP1_D */
9590 check_cp1_64bitmode(ctx);
9591 {
9592 TCGv_i64 fp0 = tcg_temp_new_i64();
9593
9594 gen_load_fpr64(ctx, fp0, fs);
9595 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9596 gen_store_fpr64(ctx, fp0, fd);
9597 tcg_temp_free_i64(fp0);
9598 }
9599 opn = "recip1.d";
9600 }
9601 break;
9602 case OPC_MAX_D: /* OPC_RSQRT1_D */
9603 if (ctx->insn_flags & ISA_MIPS32R6) {
9604 /* OPC_MAX_D */
9605 TCGv_i64 fp0 = tcg_temp_new_i64();
9606 TCGv_i64 fp1 = tcg_temp_new_i64();
9607 gen_load_fpr64(ctx, fp0, fs);
9608 gen_load_fpr64(ctx, fp1, ft);
9609 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9610 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9611 tcg_temp_free_i64(fp1);
a7812ae4 9612 tcg_temp_free_i64(fp0);
e7f16abb
LA
9613 opn = "max.d";
9614 } else {
9615 /* OPC_RSQRT1_D */
9616 check_cp1_64bitmode(ctx);
9617 {
9618 TCGv_i64 fp0 = tcg_temp_new_i64();
9619
9620 gen_load_fpr64(ctx, fp0, fs);
9621 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9622 gen_store_fpr64(ctx, fp0, fd);
9623 tcg_temp_free_i64(fp0);
9624 }
9625 opn = "rsqrt1.d";
9626 }
9627 break;
9628 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9629 if (ctx->insn_flags & ISA_MIPS32R6) {
9630 /* OPC_MAXA_D */
9631 TCGv_i64 fp0 = tcg_temp_new_i64();
9632 TCGv_i64 fp1 = tcg_temp_new_i64();
9633 gen_load_fpr64(ctx, fp0, fs);
9634 gen_load_fpr64(ctx, fp1, ft);
9635 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9636 gen_store_fpr64(ctx, fp1, fd);
9637 tcg_temp_free_i64(fp1);
9638 tcg_temp_free_i64(fp0);
9639 opn = "maxa.d";
9640 } else {
9641 /* OPC_RSQRT2_D */
9642 check_cp1_64bitmode(ctx);
9643 {
9644 TCGv_i64 fp0 = tcg_temp_new_i64();
9645 TCGv_i64 fp1 = tcg_temp_new_i64();
9646
9647 gen_load_fpr64(ctx, fp0, fs);
9648 gen_load_fpr64(ctx, fp1, ft);
9649 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9650 tcg_temp_free_i64(fp1);
9651 gen_store_fpr64(ctx, fp0, fd);
9652 tcg_temp_free_i64(fp0);
9653 }
9654 opn = "rsqrt2.d";
b6d96bed 9655 }
57fa1fb3 9656 break;
bf4120ad
NF
9657 case OPC_CMP_F_D:
9658 case OPC_CMP_UN_D:
9659 case OPC_CMP_EQ_D:
9660 case OPC_CMP_UEQ_D:
9661 case OPC_CMP_OLT_D:
9662 case OPC_CMP_ULT_D:
9663 case OPC_CMP_OLE_D:
9664 case OPC_CMP_ULE_D:
9665 case OPC_CMP_SF_D:
9666 case OPC_CMP_NGLE_D:
9667 case OPC_CMP_SEQ_D:
9668 case OPC_CMP_NGL_D:
9669 case OPC_CMP_LT_D:
9670 case OPC_CMP_NGE_D:
9671 case OPC_CMP_LE_D:
9672 case OPC_CMP_NGT_D:
fecd2646 9673 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9674 if (ctx->opcode & (1 << 6)) {
9675 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9676 opn = condnames_abs[func-48];
9677 } else {
9678 gen_cmp_d(ctx, func-48, ft, fs, cc);
9679 opn = condnames[func-48];
5a1e8ffb 9680 }
6ea83fed 9681 break;
bf4120ad 9682 case OPC_CVT_S_D:
5e755519 9683 check_cp1_registers(ctx, fs);
b6d96bed 9684 {
a7812ae4
PB
9685 TCGv_i32 fp32 = tcg_temp_new_i32();
9686 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9687
9688 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9689 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9690 tcg_temp_free_i64(fp64);
7c979afd 9691 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9692 tcg_temp_free_i32(fp32);
b6d96bed 9693 }
5a5012ec
TS
9694 opn = "cvt.s.d";
9695 break;
bf4120ad 9696 case OPC_CVT_W_D:
5e755519 9697 check_cp1_registers(ctx, fs);
b6d96bed 9698 {
a7812ae4
PB
9699 TCGv_i32 fp32 = tcg_temp_new_i32();
9700 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9701
9702 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9703 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9704 tcg_temp_free_i64(fp64);
7c979afd 9705 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9706 tcg_temp_free_i32(fp32);
b6d96bed 9707 }
5a5012ec
TS
9708 opn = "cvt.w.d";
9709 break;
bf4120ad 9710 case OPC_CVT_L_D:
5e755519 9711 check_cp1_64bitmode(ctx);
b6d96bed 9712 {
a7812ae4 9713 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9714
9715 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9716 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9717 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9718 tcg_temp_free_i64(fp0);
b6d96bed 9719 }
5a5012ec
TS
9720 opn = "cvt.l.d";
9721 break;
bf4120ad 9722 case OPC_CVT_S_W:
b6d96bed 9723 {
a7812ae4 9724 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9725
7c979afd 9726 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9727 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9728 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9729 tcg_temp_free_i32(fp0);
b6d96bed 9730 }
5a5012ec 9731 opn = "cvt.s.w";
6ea83fed 9732 break;
bf4120ad 9733 case OPC_CVT_D_W:
5e755519 9734 check_cp1_registers(ctx, fd);
b6d96bed 9735 {
a7812ae4
PB
9736 TCGv_i32 fp32 = tcg_temp_new_i32();
9737 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9738
7c979afd 9739 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9740 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9741 tcg_temp_free_i32(fp32);
b6d96bed 9742 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9743 tcg_temp_free_i64(fp64);
b6d96bed 9744 }
5a5012ec
TS
9745 opn = "cvt.d.w";
9746 break;
bf4120ad 9747 case OPC_CVT_S_L:
5e755519 9748 check_cp1_64bitmode(ctx);
b6d96bed 9749 {
a7812ae4
PB
9750 TCGv_i32 fp32 = tcg_temp_new_i32();
9751 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9752
9753 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9754 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9755 tcg_temp_free_i64(fp64);
7c979afd 9756 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9757 tcg_temp_free_i32(fp32);
b6d96bed 9758 }
5a5012ec
TS
9759 opn = "cvt.s.l";
9760 break;
bf4120ad 9761 case OPC_CVT_D_L:
5e755519 9762 check_cp1_64bitmode(ctx);
b6d96bed 9763 {
a7812ae4 9764 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9765
9766 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9767 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9768 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9769 tcg_temp_free_i64(fp0);
b6d96bed 9770 }
5a5012ec
TS
9771 opn = "cvt.d.l";
9772 break;
bf4120ad 9773 case OPC_CVT_PS_PW:
fecd2646 9774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9775 check_cp1_64bitmode(ctx);
b6d96bed 9776 {
a7812ae4 9777 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9778
9779 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9780 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9781 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9782 tcg_temp_free_i64(fp0);
b6d96bed 9783 }
5a5012ec
TS
9784 opn = "cvt.ps.pw";
9785 break;
bf4120ad 9786 case OPC_ADD_PS:
5e755519 9787 check_cp1_64bitmode(ctx);
b6d96bed 9788 {
a7812ae4
PB
9789 TCGv_i64 fp0 = tcg_temp_new_i64();
9790 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9791
9792 gen_load_fpr64(ctx, fp0, fs);
9793 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9794 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9795 tcg_temp_free_i64(fp1);
b6d96bed 9796 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9797 tcg_temp_free_i64(fp0);
b6d96bed 9798 }
5a5012ec 9799 opn = "add.ps";
6ea83fed 9800 break;
bf4120ad 9801 case OPC_SUB_PS:
5e755519 9802 check_cp1_64bitmode(ctx);
b6d96bed 9803 {
a7812ae4
PB
9804 TCGv_i64 fp0 = tcg_temp_new_i64();
9805 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9806
9807 gen_load_fpr64(ctx, fp0, fs);
9808 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9809 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9810 tcg_temp_free_i64(fp1);
b6d96bed 9811 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9812 tcg_temp_free_i64(fp0);
b6d96bed 9813 }
5a5012ec 9814 opn = "sub.ps";
6ea83fed 9815 break;
bf4120ad 9816 case OPC_MUL_PS:
5e755519 9817 check_cp1_64bitmode(ctx);
b6d96bed 9818 {
a7812ae4
PB
9819 TCGv_i64 fp0 = tcg_temp_new_i64();
9820 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9821
9822 gen_load_fpr64(ctx, fp0, fs);
9823 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9824 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9825 tcg_temp_free_i64(fp1);
b6d96bed 9826 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9827 tcg_temp_free_i64(fp0);
b6d96bed 9828 }
5a5012ec 9829 opn = "mul.ps";
6ea83fed 9830 break;
bf4120ad 9831 case OPC_ABS_PS:
5e755519 9832 check_cp1_64bitmode(ctx);
b6d96bed 9833 {
a7812ae4 9834 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9835
9836 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9837 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9838 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9839 tcg_temp_free_i64(fp0);
b6d96bed 9840 }
5a5012ec 9841 opn = "abs.ps";
6ea83fed 9842 break;
bf4120ad 9843 case OPC_MOV_PS:
5e755519 9844 check_cp1_64bitmode(ctx);
b6d96bed 9845 {
a7812ae4 9846 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9847
9848 gen_load_fpr64(ctx, fp0, fs);
9849 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9850 tcg_temp_free_i64(fp0);
b6d96bed 9851 }
5a5012ec 9852 opn = "mov.ps";
6ea83fed 9853 break;
bf4120ad 9854 case OPC_NEG_PS:
5e755519 9855 check_cp1_64bitmode(ctx);
b6d96bed 9856 {
a7812ae4 9857 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9858
9859 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9860 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9861 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9862 tcg_temp_free_i64(fp0);
b6d96bed 9863 }
5a5012ec 9864 opn = "neg.ps";
6ea83fed 9865 break;
bf4120ad 9866 case OPC_MOVCF_PS:
5e755519 9867 check_cp1_64bitmode(ctx);
7f6613ce 9868 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9869 opn = "movcf.ps";
6ea83fed 9870 break;
bf4120ad 9871 case OPC_MOVZ_PS:
5e755519 9872 check_cp1_64bitmode(ctx);
a16336e4 9873 {
42a268c2 9874 TCGLabel *l1 = gen_new_label();
30a3848b 9875 TCGv_i64 fp0;
a16336e4 9876
c9297f4d
AJ
9877 if (ft != 0)
9878 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9879 fp0 = tcg_temp_new_i64();
9880 gen_load_fpr64(ctx, fp0, fs);
9881 gen_store_fpr64(ctx, fp0, fd);
9882 tcg_temp_free_i64(fp0);
a16336e4
TS
9883 gen_set_label(l1);
9884 }
5a5012ec 9885 opn = "movz.ps";
6ea83fed 9886 break;
bf4120ad 9887 case OPC_MOVN_PS:
5e755519 9888 check_cp1_64bitmode(ctx);
a16336e4 9889 {
42a268c2 9890 TCGLabel *l1 = gen_new_label();
30a3848b 9891 TCGv_i64 fp0;
c9297f4d
AJ
9892
9893 if (ft != 0) {
9894 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9895 fp0 = tcg_temp_new_i64();
9896 gen_load_fpr64(ctx, fp0, fs);
9897 gen_store_fpr64(ctx, fp0, fd);
9898 tcg_temp_free_i64(fp0);
9899 gen_set_label(l1);
9900 }
a16336e4 9901 }
5a5012ec 9902 opn = "movn.ps";
6ea83fed 9903 break;
bf4120ad 9904 case OPC_ADDR_PS:
5e755519 9905 check_cp1_64bitmode(ctx);
b6d96bed 9906 {
a7812ae4
PB
9907 TCGv_i64 fp0 = tcg_temp_new_i64();
9908 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9909
9910 gen_load_fpr64(ctx, fp0, ft);
9911 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9912 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9913 tcg_temp_free_i64(fp1);
b6d96bed 9914 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9915 tcg_temp_free_i64(fp0);
b6d96bed 9916 }
fbcc6828
TS
9917 opn = "addr.ps";
9918 break;
bf4120ad 9919 case OPC_MULR_PS:
5e755519 9920 check_cp1_64bitmode(ctx);
b6d96bed 9921 {
a7812ae4
PB
9922 TCGv_i64 fp0 = tcg_temp_new_i64();
9923 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9924
9925 gen_load_fpr64(ctx, fp0, ft);
9926 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9927 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9928 tcg_temp_free_i64(fp1);
b6d96bed 9929 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9930 tcg_temp_free_i64(fp0);
b6d96bed 9931 }
57fa1fb3
TS
9932 opn = "mulr.ps";
9933 break;
bf4120ad 9934 case OPC_RECIP2_PS:
5e755519 9935 check_cp1_64bitmode(ctx);
b6d96bed 9936 {
a7812ae4
PB
9937 TCGv_i64 fp0 = tcg_temp_new_i64();
9938 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9939
9940 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9941 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9942 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9943 tcg_temp_free_i64(fp1);
b6d96bed 9944 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9945 tcg_temp_free_i64(fp0);
b6d96bed 9946 }
57fa1fb3
TS
9947 opn = "recip2.ps";
9948 break;
bf4120ad 9949 case OPC_RECIP1_PS:
5e755519 9950 check_cp1_64bitmode(ctx);
b6d96bed 9951 {
a7812ae4 9952 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9953
9954 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9955 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9956 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9957 tcg_temp_free_i64(fp0);
b6d96bed 9958 }
57fa1fb3
TS
9959 opn = "recip1.ps";
9960 break;
bf4120ad 9961 case OPC_RSQRT1_PS:
5e755519 9962 check_cp1_64bitmode(ctx);
b6d96bed 9963 {
a7812ae4 9964 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9965
9966 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9967 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9968 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9969 tcg_temp_free_i64(fp0);
b6d96bed 9970 }
57fa1fb3
TS
9971 opn = "rsqrt1.ps";
9972 break;
bf4120ad 9973 case OPC_RSQRT2_PS:
5e755519 9974 check_cp1_64bitmode(ctx);
b6d96bed 9975 {
a7812ae4
PB
9976 TCGv_i64 fp0 = tcg_temp_new_i64();
9977 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9978
9979 gen_load_fpr64(ctx, fp0, fs);
9980 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9981 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9982 tcg_temp_free_i64(fp1);
b6d96bed 9983 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9984 tcg_temp_free_i64(fp0);
b6d96bed 9985 }
57fa1fb3
TS
9986 opn = "rsqrt2.ps";
9987 break;
bf4120ad 9988 case OPC_CVT_S_PU:
5e755519 9989 check_cp1_64bitmode(ctx);
b6d96bed 9990 {
a7812ae4 9991 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9992
7f6613ce 9993 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9994 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 9995 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9996 tcg_temp_free_i32(fp0);
b6d96bed 9997 }
5a5012ec 9998 opn = "cvt.s.pu";
dd016883 9999 break;
bf4120ad 10000 case OPC_CVT_PW_PS:
5e755519 10001 check_cp1_64bitmode(ctx);
b6d96bed 10002 {
a7812ae4 10003 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10004
10005 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10006 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10007 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10008 tcg_temp_free_i64(fp0);
b6d96bed 10009 }
5a5012ec 10010 opn = "cvt.pw.ps";
6ea83fed 10011 break;
bf4120ad 10012 case OPC_CVT_S_PL:
5e755519 10013 check_cp1_64bitmode(ctx);
b6d96bed 10014 {
a7812ae4 10015 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10016
7c979afd 10017 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10018 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10019 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10020 tcg_temp_free_i32(fp0);
b6d96bed 10021 }
5a5012ec 10022 opn = "cvt.s.pl";
6ea83fed 10023 break;
bf4120ad 10024 case OPC_PLL_PS:
5e755519 10025 check_cp1_64bitmode(ctx);
b6d96bed 10026 {
a7812ae4
PB
10027 TCGv_i32 fp0 = tcg_temp_new_i32();
10028 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10029
7c979afd
LA
10030 gen_load_fpr32(ctx, fp0, fs);
10031 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10032 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10033 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10034 tcg_temp_free_i32(fp0);
10035 tcg_temp_free_i32(fp1);
b6d96bed 10036 }
5a5012ec 10037 opn = "pll.ps";
6ea83fed 10038 break;
bf4120ad 10039 case OPC_PLU_PS:
5e755519 10040 check_cp1_64bitmode(ctx);
b6d96bed 10041 {
a7812ae4
PB
10042 TCGv_i32 fp0 = tcg_temp_new_i32();
10043 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10044
7c979afd 10045 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10046 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10047 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10048 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10049 tcg_temp_free_i32(fp0);
10050 tcg_temp_free_i32(fp1);
b6d96bed 10051 }
5a5012ec
TS
10052 opn = "plu.ps";
10053 break;
bf4120ad 10054 case OPC_PUL_PS:
5e755519 10055 check_cp1_64bitmode(ctx);
b6d96bed 10056 {
a7812ae4
PB
10057 TCGv_i32 fp0 = tcg_temp_new_i32();
10058 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10059
7f6613ce 10060 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10061 gen_load_fpr32(ctx, fp1, ft);
10062 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10063 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10064 tcg_temp_free_i32(fp0);
10065 tcg_temp_free_i32(fp1);
b6d96bed 10066 }
5a5012ec
TS
10067 opn = "pul.ps";
10068 break;
bf4120ad 10069 case OPC_PUU_PS:
5e755519 10070 check_cp1_64bitmode(ctx);
b6d96bed 10071 {
a7812ae4
PB
10072 TCGv_i32 fp0 = tcg_temp_new_i32();
10073 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10074
7f6613ce
PJ
10075 gen_load_fpr32h(ctx, fp0, fs);
10076 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10077 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10078 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10079 tcg_temp_free_i32(fp0);
10080 tcg_temp_free_i32(fp1);
b6d96bed 10081 }
5a5012ec
TS
10082 opn = "puu.ps";
10083 break;
bf4120ad
NF
10084 case OPC_CMP_F_PS:
10085 case OPC_CMP_UN_PS:
10086 case OPC_CMP_EQ_PS:
10087 case OPC_CMP_UEQ_PS:
10088 case OPC_CMP_OLT_PS:
10089 case OPC_CMP_ULT_PS:
10090 case OPC_CMP_OLE_PS:
10091 case OPC_CMP_ULE_PS:
10092 case OPC_CMP_SF_PS:
10093 case OPC_CMP_NGLE_PS:
10094 case OPC_CMP_SEQ_PS:
10095 case OPC_CMP_NGL_PS:
10096 case OPC_CMP_LT_PS:
10097 case OPC_CMP_NGE_PS:
10098 case OPC_CMP_LE_PS:
10099 case OPC_CMP_NGT_PS:
8153667c
NF
10100 if (ctx->opcode & (1 << 6)) {
10101 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10102 opn = condnames_abs[func-48];
10103 } else {
10104 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10105 opn = condnames[func-48];
5a1e8ffb 10106 }
6ea83fed 10107 break;
5a5012ec 10108 default:
923617a3 10109 MIPS_INVAL(opn);
e397ee33 10110 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10111 return;
10112 }
2abf314d 10113 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10114 switch (optype) {
10115 case BINOP:
6ea83fed 10116 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10117 break;
10118 case CMPOP:
10119 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10120 break;
10121 default:
6ea83fed 10122 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10123 break;
10124 }
6ea83fed 10125}
6af0bf9c 10126
5a5012ec 10127/* Coprocessor 3 (FPU) */
5e755519
TS
10128static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10129 int fd, int fs, int base, int index)
7a387fff 10130{
923617a3 10131 const char *opn = "extended float load/store";
93b12ccc 10132 int store = 0;
4e2474d6 10133 TCGv t0 = tcg_temp_new();
7a387fff 10134
93b12ccc 10135 if (base == 0) {
6c5c1e20 10136 gen_load_gpr(t0, index);
93b12ccc 10137 } else if (index == 0) {
6c5c1e20 10138 gen_load_gpr(t0, base);
93b12ccc 10139 } else {
05168674 10140 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10141 }
5a5012ec 10142 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10143 memory access. */
5a5012ec
TS
10144 switch (opc) {
10145 case OPC_LWXC1:
8c0ab41f 10146 check_cop1x(ctx);
b6d96bed 10147 {
a7812ae4 10148 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10149
5f68f5ae 10150 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10151 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10152 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10153 tcg_temp_free_i32(fp0);
b6d96bed 10154 }
5a5012ec
TS
10155 opn = "lwxc1";
10156 break;
10157 case OPC_LDXC1:
8c0ab41f
AJ
10158 check_cop1x(ctx);
10159 check_cp1_registers(ctx, fd);
b6d96bed 10160 {
a7812ae4 10161 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10162 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10163 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10164 tcg_temp_free_i64(fp0);
b6d96bed 10165 }
5a5012ec
TS
10166 opn = "ldxc1";
10167 break;
10168 case OPC_LUXC1:
8c0ab41f 10169 check_cp1_64bitmode(ctx);
6c5c1e20 10170 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10171 {
a7812ae4 10172 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10173
5f68f5ae 10174 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10175 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10176 tcg_temp_free_i64(fp0);
b6d96bed 10177 }
5a5012ec
TS
10178 opn = "luxc1";
10179 break;
10180 case OPC_SWXC1:
8c0ab41f 10181 check_cop1x(ctx);
b6d96bed 10182 {
a7812ae4 10183 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10184 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10185 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10186 tcg_temp_free_i32(fp0);
b6d96bed 10187 }
5a5012ec 10188 opn = "swxc1";
93b12ccc 10189 store = 1;
5a5012ec
TS
10190 break;
10191 case OPC_SDXC1:
8c0ab41f
AJ
10192 check_cop1x(ctx);
10193 check_cp1_registers(ctx, fs);
b6d96bed 10194 {
a7812ae4 10195 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10196 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10197 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10198 tcg_temp_free_i64(fp0);
b6d96bed 10199 }
5a5012ec 10200 opn = "sdxc1";
93b12ccc 10201 store = 1;
5a5012ec
TS
10202 break;
10203 case OPC_SUXC1:
8c0ab41f 10204 check_cp1_64bitmode(ctx);
6c5c1e20 10205 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10206 {
a7812ae4 10207 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10208 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10209 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10210 tcg_temp_free_i64(fp0);
b6d96bed 10211 }
5a5012ec 10212 opn = "suxc1";
93b12ccc 10213 store = 1;
5a5012ec 10214 break;
5a5012ec 10215 }
6c5c1e20 10216 tcg_temp_free(t0);
2abf314d 10217 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10218 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10219 regnames[index], regnames[base]);
5a5012ec
TS
10220}
10221
5e755519
TS
10222static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10223 int fd, int fr, int fs, int ft)
5a5012ec 10224{
923617a3 10225 const char *opn = "flt3_arith";
5a5012ec 10226
5a5012ec
TS
10227 switch (opc) {
10228 case OPC_ALNV_PS:
b8aa4598 10229 check_cp1_64bitmode(ctx);
a16336e4 10230 {
a7812ae4 10231 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10232 TCGv_i32 fp = tcg_temp_new_i32();
10233 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10234 TCGLabel *l1 = gen_new_label();
10235 TCGLabel *l2 = gen_new_label();
a16336e4 10236
6c5c1e20
TS
10237 gen_load_gpr(t0, fr);
10238 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10239
10240 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10241 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10242 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10243 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10244 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10245 tcg_gen_br(l2);
10246 gen_set_label(l1);
6c5c1e20
TS
10247 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10248 tcg_temp_free(t0);
a16336e4 10249#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10250 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10251 gen_load_fpr32h(ctx, fph, ft);
10252 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10253 gen_store_fpr32(ctx, fph, fd);
a16336e4 10254#else
7f6613ce 10255 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10256 gen_load_fpr32(ctx, fp, ft);
10257 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10258 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10259#endif
10260 gen_set_label(l2);
c905fdac
AJ
10261 tcg_temp_free_i32(fp);
10262 tcg_temp_free_i32(fph);
a16336e4 10263 }
5a5012ec
TS
10264 opn = "alnv.ps";
10265 break;
10266 case OPC_MADD_S:
b8aa4598 10267 check_cop1x(ctx);
b6d96bed 10268 {
a7812ae4
PB
10269 TCGv_i32 fp0 = tcg_temp_new_i32();
10270 TCGv_i32 fp1 = tcg_temp_new_i32();
10271 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10272
7c979afd
LA
10273 gen_load_fpr32(ctx, fp0, fs);
10274 gen_load_fpr32(ctx, fp1, ft);
10275 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10276 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10277 tcg_temp_free_i32(fp0);
10278 tcg_temp_free_i32(fp1);
7c979afd 10279 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10280 tcg_temp_free_i32(fp2);
b6d96bed 10281 }
5a5012ec
TS
10282 opn = "madd.s";
10283 break;
10284 case OPC_MADD_D:
b8aa4598
TS
10285 check_cop1x(ctx);
10286 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10287 {
a7812ae4
PB
10288 TCGv_i64 fp0 = tcg_temp_new_i64();
10289 TCGv_i64 fp1 = tcg_temp_new_i64();
10290 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10291
10292 gen_load_fpr64(ctx, fp0, fs);
10293 gen_load_fpr64(ctx, fp1, ft);
10294 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10295 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10296 tcg_temp_free_i64(fp0);
10297 tcg_temp_free_i64(fp1);
b6d96bed 10298 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10299 tcg_temp_free_i64(fp2);
b6d96bed 10300 }
5a5012ec
TS
10301 opn = "madd.d";
10302 break;
10303 case OPC_MADD_PS:
b8aa4598 10304 check_cp1_64bitmode(ctx);
b6d96bed 10305 {
a7812ae4
PB
10306 TCGv_i64 fp0 = tcg_temp_new_i64();
10307 TCGv_i64 fp1 = tcg_temp_new_i64();
10308 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10309
10310 gen_load_fpr64(ctx, fp0, fs);
10311 gen_load_fpr64(ctx, fp1, ft);
10312 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10313 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10314 tcg_temp_free_i64(fp0);
10315 tcg_temp_free_i64(fp1);
b6d96bed 10316 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10317 tcg_temp_free_i64(fp2);
b6d96bed 10318 }
5a5012ec
TS
10319 opn = "madd.ps";
10320 break;
10321 case OPC_MSUB_S:
b8aa4598 10322 check_cop1x(ctx);
b6d96bed 10323 {
a7812ae4
PB
10324 TCGv_i32 fp0 = tcg_temp_new_i32();
10325 TCGv_i32 fp1 = tcg_temp_new_i32();
10326 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10327
7c979afd
LA
10328 gen_load_fpr32(ctx, fp0, fs);
10329 gen_load_fpr32(ctx, fp1, ft);
10330 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10331 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10332 tcg_temp_free_i32(fp0);
10333 tcg_temp_free_i32(fp1);
7c979afd 10334 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10335 tcg_temp_free_i32(fp2);
b6d96bed 10336 }
5a5012ec
TS
10337 opn = "msub.s";
10338 break;
10339 case OPC_MSUB_D:
b8aa4598
TS
10340 check_cop1x(ctx);
10341 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10342 {
a7812ae4
PB
10343 TCGv_i64 fp0 = tcg_temp_new_i64();
10344 TCGv_i64 fp1 = tcg_temp_new_i64();
10345 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10346
10347 gen_load_fpr64(ctx, fp0, fs);
10348 gen_load_fpr64(ctx, fp1, ft);
10349 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10350 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10351 tcg_temp_free_i64(fp0);
10352 tcg_temp_free_i64(fp1);
b6d96bed 10353 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10354 tcg_temp_free_i64(fp2);
b6d96bed 10355 }
5a5012ec
TS
10356 opn = "msub.d";
10357 break;
10358 case OPC_MSUB_PS:
b8aa4598 10359 check_cp1_64bitmode(ctx);
b6d96bed 10360 {
a7812ae4
PB
10361 TCGv_i64 fp0 = tcg_temp_new_i64();
10362 TCGv_i64 fp1 = tcg_temp_new_i64();
10363 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10364
10365 gen_load_fpr64(ctx, fp0, fs);
10366 gen_load_fpr64(ctx, fp1, ft);
10367 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10368 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10369 tcg_temp_free_i64(fp0);
10370 tcg_temp_free_i64(fp1);
b6d96bed 10371 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10372 tcg_temp_free_i64(fp2);
b6d96bed 10373 }
5a5012ec
TS
10374 opn = "msub.ps";
10375 break;
10376 case OPC_NMADD_S:
b8aa4598 10377 check_cop1x(ctx);
b6d96bed 10378 {
a7812ae4
PB
10379 TCGv_i32 fp0 = tcg_temp_new_i32();
10380 TCGv_i32 fp1 = tcg_temp_new_i32();
10381 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10382
7c979afd
LA
10383 gen_load_fpr32(ctx, fp0, fs);
10384 gen_load_fpr32(ctx, fp1, ft);
10385 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10386 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10387 tcg_temp_free_i32(fp0);
10388 tcg_temp_free_i32(fp1);
7c979afd 10389 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10390 tcg_temp_free_i32(fp2);
b6d96bed 10391 }
5a5012ec
TS
10392 opn = "nmadd.s";
10393 break;
10394 case OPC_NMADD_D:
b8aa4598
TS
10395 check_cop1x(ctx);
10396 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10397 {
a7812ae4
PB
10398 TCGv_i64 fp0 = tcg_temp_new_i64();
10399 TCGv_i64 fp1 = tcg_temp_new_i64();
10400 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10401
10402 gen_load_fpr64(ctx, fp0, fs);
10403 gen_load_fpr64(ctx, fp1, ft);
10404 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10405 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10406 tcg_temp_free_i64(fp0);
10407 tcg_temp_free_i64(fp1);
b6d96bed 10408 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10409 tcg_temp_free_i64(fp2);
b6d96bed 10410 }
5a5012ec
TS
10411 opn = "nmadd.d";
10412 break;
10413 case OPC_NMADD_PS:
b8aa4598 10414 check_cp1_64bitmode(ctx);
b6d96bed 10415 {
a7812ae4
PB
10416 TCGv_i64 fp0 = tcg_temp_new_i64();
10417 TCGv_i64 fp1 = tcg_temp_new_i64();
10418 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10419
10420 gen_load_fpr64(ctx, fp0, fs);
10421 gen_load_fpr64(ctx, fp1, ft);
10422 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10423 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10424 tcg_temp_free_i64(fp0);
10425 tcg_temp_free_i64(fp1);
b6d96bed 10426 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10427 tcg_temp_free_i64(fp2);
b6d96bed 10428 }
5a5012ec
TS
10429 opn = "nmadd.ps";
10430 break;
10431 case OPC_NMSUB_S:
b8aa4598 10432 check_cop1x(ctx);
b6d96bed 10433 {
a7812ae4
PB
10434 TCGv_i32 fp0 = tcg_temp_new_i32();
10435 TCGv_i32 fp1 = tcg_temp_new_i32();
10436 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10437
7c979afd
LA
10438 gen_load_fpr32(ctx, fp0, fs);
10439 gen_load_fpr32(ctx, fp1, ft);
10440 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10441 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10442 tcg_temp_free_i32(fp0);
10443 tcg_temp_free_i32(fp1);
7c979afd 10444 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10445 tcg_temp_free_i32(fp2);
b6d96bed 10446 }
5a5012ec
TS
10447 opn = "nmsub.s";
10448 break;
10449 case OPC_NMSUB_D:
b8aa4598
TS
10450 check_cop1x(ctx);
10451 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10452 {
a7812ae4
PB
10453 TCGv_i64 fp0 = tcg_temp_new_i64();
10454 TCGv_i64 fp1 = tcg_temp_new_i64();
10455 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10456
10457 gen_load_fpr64(ctx, fp0, fs);
10458 gen_load_fpr64(ctx, fp1, ft);
10459 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10460 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10461 tcg_temp_free_i64(fp0);
10462 tcg_temp_free_i64(fp1);
b6d96bed 10463 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10464 tcg_temp_free_i64(fp2);
b6d96bed 10465 }
5a5012ec
TS
10466 opn = "nmsub.d";
10467 break;
10468 case OPC_NMSUB_PS:
b8aa4598 10469 check_cp1_64bitmode(ctx);
b6d96bed 10470 {
a7812ae4
PB
10471 TCGv_i64 fp0 = tcg_temp_new_i64();
10472 TCGv_i64 fp1 = tcg_temp_new_i64();
10473 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10474
10475 gen_load_fpr64(ctx, fp0, fs);
10476 gen_load_fpr64(ctx, fp1, ft);
10477 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10478 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10479 tcg_temp_free_i64(fp0);
10480 tcg_temp_free_i64(fp1);
b6d96bed 10481 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10482 tcg_temp_free_i64(fp2);
b6d96bed 10483 }
5a5012ec
TS
10484 opn = "nmsub.ps";
10485 break;
923617a3
TS
10486 default:
10487 MIPS_INVAL(opn);
5a5012ec
TS
10488 generate_exception (ctx, EXCP_RI);
10489 return;
10490 }
2abf314d 10491 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10492 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10493 fregnames[fs], fregnames[ft]);
7a387fff
TS
10494}
10495
d75c135e 10496static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10497{
10498 TCGv t0;
10499
b3167288
RH
10500#if !defined(CONFIG_USER_ONLY)
10501 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10502 Therefore only check the ISA in system mode. */
d75c135e 10503 check_insn(ctx, ISA_MIPS32R2);
b3167288 10504#endif
26ebe468
NF
10505 t0 = tcg_temp_new();
10506
10507 switch (rd) {
10508 case 0:
10509 save_cpu_state(ctx, 1);
895c2d04 10510 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10511 gen_store_gpr(t0, rt);
10512 break;
10513 case 1:
10514 save_cpu_state(ctx, 1);
895c2d04 10515 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10516 gen_store_gpr(t0, rt);
10517 break;
10518 case 2:
10519 save_cpu_state(ctx, 1);
895c2d04 10520 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10521 gen_store_gpr(t0, rt);
10522 break;
10523 case 3:
10524 save_cpu_state(ctx, 1);
895c2d04 10525 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10526 gen_store_gpr(t0, rt);
10527 break;
10528 case 29:
10529#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10530 tcg_gen_ld_tl(t0, cpu_env,
10531 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10532 gen_store_gpr(t0, rt);
10533 break;
10534#else
d279279e
PJ
10535 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10536 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10537 tcg_gen_ld_tl(t0, cpu_env,
10538 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10539 gen_store_gpr(t0, rt);
10540 } else {
10541 generate_exception(ctx, EXCP_RI);
10542 }
10543 break;
26ebe468
NF
10544#endif
10545 default: /* Invalid */
10546 MIPS_INVAL("rdhwr");
10547 generate_exception(ctx, EXCP_RI);
10548 break;
10549 }
10550 tcg_temp_free(t0);
10551}
10552
a5f53390
LA
10553static inline void clear_branch_hflags(DisasContext *ctx)
10554{
10555 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10556 if (ctx->bstate == BS_NONE) {
10557 save_cpu_state(ctx, 0);
10558 } else {
10559 /* it is not safe to save ctx->hflags as hflags may be changed
10560 in execution time by the instruction in delay / forbidden slot. */
10561 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10562 }
10563}
10564
31837be3 10565static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10566{
10567 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10568 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10569 /* Branches completion */
a5f53390 10570 clear_branch_hflags(ctx);
c9602061 10571 ctx->bstate = BS_BRANCH;
c9602061 10572 /* FIXME: Need to clear can_do_io. */
364d4831 10573 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10574 case MIPS_HFLAG_FBNSLOT:
10575 MIPS_DEBUG("forbidden slot");
10576 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10577 break;
c9602061
NF
10578 case MIPS_HFLAG_B:
10579 /* unconditional branch */
10580 MIPS_DEBUG("unconditional branch");
364d4831
NF
10581 if (proc_hflags & MIPS_HFLAG_BX) {
10582 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10583 }
c9602061
NF
10584 gen_goto_tb(ctx, 0, ctx->btarget);
10585 break;
10586 case MIPS_HFLAG_BL:
10587 /* blikely taken case */
10588 MIPS_DEBUG("blikely branch taken");
10589 gen_goto_tb(ctx, 0, ctx->btarget);
10590 break;
10591 case MIPS_HFLAG_BC:
10592 /* Conditional branch */
10593 MIPS_DEBUG("conditional branch");
10594 {
42a268c2 10595 TCGLabel *l1 = gen_new_label();
c9602061
NF
10596
10597 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10598 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10599 gen_set_label(l1);
10600 gen_goto_tb(ctx, 0, ctx->btarget);
10601 }
10602 break;
10603 case MIPS_HFLAG_BR:
10604 /* unconditional branch to register */
10605 MIPS_DEBUG("branch to register");
d75c135e 10606 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10607 TCGv t0 = tcg_temp_new();
10608 TCGv_i32 t1 = tcg_temp_new_i32();
10609
10610 tcg_gen_andi_tl(t0, btarget, 0x1);
10611 tcg_gen_trunc_tl_i32(t1, t0);
10612 tcg_temp_free(t0);
10613 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10614 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10615 tcg_gen_or_i32(hflags, hflags, t1);
10616 tcg_temp_free_i32(t1);
10617
10618 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10619 } else {
10620 tcg_gen_mov_tl(cpu_PC, btarget);
10621 }
c9602061
NF
10622 if (ctx->singlestep_enabled) {
10623 save_cpu_state(ctx, 0);
895c2d04 10624 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10625 }
10626 tcg_gen_exit_tb(0);
10627 break;
10628 default:
a5f53390
LA
10629 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10630 abort();
c9602061
NF
10631 }
10632 }
10633}
10634
7a387fff 10635/* ISA extensions (ASEs) */
6af0bf9c 10636/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10637
10638/* MIPS16 major opcodes */
10639enum {
10640 M16_OPC_ADDIUSP = 0x00,
10641 M16_OPC_ADDIUPC = 0x01,
10642 M16_OPC_B = 0x02,
10643 M16_OPC_JAL = 0x03,
10644 M16_OPC_BEQZ = 0x04,
10645 M16_OPC_BNEQZ = 0x05,
10646 M16_OPC_SHIFT = 0x06,
10647 M16_OPC_LD = 0x07,
10648 M16_OPC_RRIA = 0x08,
10649 M16_OPC_ADDIU8 = 0x09,
10650 M16_OPC_SLTI = 0x0a,
10651 M16_OPC_SLTIU = 0x0b,
10652 M16_OPC_I8 = 0x0c,
10653 M16_OPC_LI = 0x0d,
10654 M16_OPC_CMPI = 0x0e,
10655 M16_OPC_SD = 0x0f,
10656 M16_OPC_LB = 0x10,
10657 M16_OPC_LH = 0x11,
10658 M16_OPC_LWSP = 0x12,
10659 M16_OPC_LW = 0x13,
10660 M16_OPC_LBU = 0x14,
10661 M16_OPC_LHU = 0x15,
10662 M16_OPC_LWPC = 0x16,
10663 M16_OPC_LWU = 0x17,
10664 M16_OPC_SB = 0x18,
10665 M16_OPC_SH = 0x19,
10666 M16_OPC_SWSP = 0x1a,
10667 M16_OPC_SW = 0x1b,
10668 M16_OPC_RRR = 0x1c,
10669 M16_OPC_RR = 0x1d,
10670 M16_OPC_EXTEND = 0x1e,
10671 M16_OPC_I64 = 0x1f
10672};
10673
10674/* I8 funct field */
10675enum {
10676 I8_BTEQZ = 0x0,
10677 I8_BTNEZ = 0x1,
10678 I8_SWRASP = 0x2,
10679 I8_ADJSP = 0x3,
10680 I8_SVRS = 0x4,
10681 I8_MOV32R = 0x5,
10682 I8_MOVR32 = 0x7
10683};
10684
10685/* RRR f field */
10686enum {
10687 RRR_DADDU = 0x0,
10688 RRR_ADDU = 0x1,
10689 RRR_DSUBU = 0x2,
10690 RRR_SUBU = 0x3
10691};
10692
10693/* RR funct field */
10694enum {
10695 RR_JR = 0x00,
10696 RR_SDBBP = 0x01,
10697 RR_SLT = 0x02,
10698 RR_SLTU = 0x03,
10699 RR_SLLV = 0x04,
10700 RR_BREAK = 0x05,
10701 RR_SRLV = 0x06,
10702 RR_SRAV = 0x07,
10703 RR_DSRL = 0x08,
10704 RR_CMP = 0x0a,
10705 RR_NEG = 0x0b,
10706 RR_AND = 0x0c,
10707 RR_OR = 0x0d,
10708 RR_XOR = 0x0e,
10709 RR_NOT = 0x0f,
10710 RR_MFHI = 0x10,
10711 RR_CNVT = 0x11,
10712 RR_MFLO = 0x12,
10713 RR_DSRA = 0x13,
10714 RR_DSLLV = 0x14,
10715 RR_DSRLV = 0x16,
10716 RR_DSRAV = 0x17,
10717 RR_MULT = 0x18,
10718 RR_MULTU = 0x19,
10719 RR_DIV = 0x1a,
10720 RR_DIVU = 0x1b,
10721 RR_DMULT = 0x1c,
10722 RR_DMULTU = 0x1d,
10723 RR_DDIV = 0x1e,
10724 RR_DDIVU = 0x1f
10725};
10726
10727/* I64 funct field */
10728enum {
10729 I64_LDSP = 0x0,
10730 I64_SDSP = 0x1,
10731 I64_SDRASP = 0x2,
10732 I64_DADJSP = 0x3,
10733 I64_LDPC = 0x4,
364d4831 10734 I64_DADDIU5 = 0x5,
6ea219d0
NF
10735 I64_DADDIUPC = 0x6,
10736 I64_DADDIUSP = 0x7
10737};
10738
10739/* RR ry field for CNVT */
10740enum {
10741 RR_RY_CNVT_ZEB = 0x0,
10742 RR_RY_CNVT_ZEH = 0x1,
10743 RR_RY_CNVT_ZEW = 0x2,
10744 RR_RY_CNVT_SEB = 0x4,
10745 RR_RY_CNVT_SEH = 0x5,
10746 RR_RY_CNVT_SEW = 0x6,
10747};
10748
364d4831
NF
10749static int xlat (int r)
10750{
10751 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10752
10753 return map[r];
10754}
10755
10756static void gen_mips16_save (DisasContext *ctx,
10757 int xsregs, int aregs,
10758 int do_ra, int do_s0, int do_s1,
10759 int framesize)
10760{
10761 TCGv t0 = tcg_temp_new();
10762 TCGv t1 = tcg_temp_new();
c48245f0 10763 TCGv t2 = tcg_temp_new();
364d4831
NF
10764 int args, astatic;
10765
10766 switch (aregs) {
10767 case 0:
10768 case 1:
10769 case 2:
10770 case 3:
10771 case 11:
10772 args = 0;
10773 break;
10774 case 4:
10775 case 5:
10776 case 6:
10777 case 7:
10778 args = 1;
10779 break;
10780 case 8:
10781 case 9:
10782 case 10:
10783 args = 2;
10784 break;
10785 case 12:
10786 case 13:
10787 args = 3;
10788 break;
10789 case 14:
10790 args = 4;
10791 break;
10792 default:
10793 generate_exception(ctx, EXCP_RI);
10794 return;
10795 }
10796
10797 switch (args) {
10798 case 4:
10799 gen_base_offset_addr(ctx, t0, 29, 12);
10800 gen_load_gpr(t1, 7);
5f68f5ae 10801 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10802 /* Fall through */
10803 case 3:
10804 gen_base_offset_addr(ctx, t0, 29, 8);
10805 gen_load_gpr(t1, 6);
5f68f5ae 10806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10807 /* Fall through */
10808 case 2:
10809 gen_base_offset_addr(ctx, t0, 29, 4);
10810 gen_load_gpr(t1, 5);
5f68f5ae 10811 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10812 /* Fall through */
10813 case 1:
10814 gen_base_offset_addr(ctx, t0, 29, 0);
10815 gen_load_gpr(t1, 4);
5f68f5ae 10816 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10817 }
10818
10819 gen_load_gpr(t0, 29);
10820
5f68f5ae 10821#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10822 tcg_gen_movi_tl(t2, -4); \
10823 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10824 gen_load_gpr(t1, reg); \
10825 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10826 } while (0)
10827
10828 if (do_ra) {
10829 DECR_AND_STORE(31);
10830 }
10831
10832 switch (xsregs) {
10833 case 7:
10834 DECR_AND_STORE(30);
10835 /* Fall through */
10836 case 6:
10837 DECR_AND_STORE(23);
10838 /* Fall through */
10839 case 5:
10840 DECR_AND_STORE(22);
10841 /* Fall through */
10842 case 4:
10843 DECR_AND_STORE(21);
10844 /* Fall through */
10845 case 3:
10846 DECR_AND_STORE(20);
10847 /* Fall through */
10848 case 2:
10849 DECR_AND_STORE(19);
10850 /* Fall through */
10851 case 1:
10852 DECR_AND_STORE(18);
10853 }
10854
10855 if (do_s1) {
10856 DECR_AND_STORE(17);
10857 }
10858 if (do_s0) {
10859 DECR_AND_STORE(16);
10860 }
10861
10862 switch (aregs) {
10863 case 0:
10864 case 4:
10865 case 8:
10866 case 12:
10867 case 14:
10868 astatic = 0;
10869 break;
10870 case 1:
10871 case 5:
10872 case 9:
10873 case 13:
10874 astatic = 1;
10875 break;
10876 case 2:
10877 case 6:
10878 case 10:
10879 astatic = 2;
10880 break;
10881 case 3:
10882 case 7:
10883 astatic = 3;
10884 break;
10885 case 11:
10886 astatic = 4;
10887 break;
10888 default:
10889 generate_exception(ctx, EXCP_RI);
10890 return;
10891 }
10892
10893 if (astatic > 0) {
10894 DECR_AND_STORE(7);
10895 if (astatic > 1) {
10896 DECR_AND_STORE(6);
10897 if (astatic > 2) {
10898 DECR_AND_STORE(5);
10899 if (astatic > 3) {
10900 DECR_AND_STORE(4);
10901 }
10902 }
10903 }
10904 }
10905#undef DECR_AND_STORE
10906
c48245f0
MR
10907 tcg_gen_movi_tl(t2, -framesize);
10908 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10909 tcg_temp_free(t0);
10910 tcg_temp_free(t1);
c48245f0 10911 tcg_temp_free(t2);
364d4831
NF
10912}
10913
10914static void gen_mips16_restore (DisasContext *ctx,
10915 int xsregs, int aregs,
10916 int do_ra, int do_s0, int do_s1,
10917 int framesize)
10918{
10919 int astatic;
10920 TCGv t0 = tcg_temp_new();
10921 TCGv t1 = tcg_temp_new();
c48245f0 10922 TCGv t2 = tcg_temp_new();
364d4831 10923
c48245f0
MR
10924 tcg_gen_movi_tl(t2, framesize);
10925 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 10926
5f68f5ae 10927#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
10928 tcg_gen_movi_tl(t2, -4); \
10929 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10930 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10931 gen_store_gpr(t1, reg); \
364d4831
NF
10932 } while (0)
10933
10934 if (do_ra) {
10935 DECR_AND_LOAD(31);
10936 }
10937
10938 switch (xsregs) {
10939 case 7:
10940 DECR_AND_LOAD(30);
10941 /* Fall through */
10942 case 6:
10943 DECR_AND_LOAD(23);
10944 /* Fall through */
10945 case 5:
10946 DECR_AND_LOAD(22);
10947 /* Fall through */
10948 case 4:
10949 DECR_AND_LOAD(21);
10950 /* Fall through */
10951 case 3:
10952 DECR_AND_LOAD(20);
10953 /* Fall through */
10954 case 2:
10955 DECR_AND_LOAD(19);
10956 /* Fall through */
10957 case 1:
10958 DECR_AND_LOAD(18);
10959 }
10960
10961 if (do_s1) {
10962 DECR_AND_LOAD(17);
10963 }
10964 if (do_s0) {
10965 DECR_AND_LOAD(16);
10966 }
10967
10968 switch (aregs) {
10969 case 0:
10970 case 4:
10971 case 8:
10972 case 12:
10973 case 14:
10974 astatic = 0;
10975 break;
10976 case 1:
10977 case 5:
10978 case 9:
10979 case 13:
10980 astatic = 1;
10981 break;
10982 case 2:
10983 case 6:
10984 case 10:
10985 astatic = 2;
10986 break;
10987 case 3:
10988 case 7:
10989 astatic = 3;
10990 break;
10991 case 11:
10992 astatic = 4;
10993 break;
10994 default:
10995 generate_exception(ctx, EXCP_RI);
10996 return;
10997 }
10998
10999 if (astatic > 0) {
11000 DECR_AND_LOAD(7);
11001 if (astatic > 1) {
11002 DECR_AND_LOAD(6);
11003 if (astatic > 2) {
11004 DECR_AND_LOAD(5);
11005 if (astatic > 3) {
11006 DECR_AND_LOAD(4);
11007 }
11008 }
11009 }
11010 }
11011#undef DECR_AND_LOAD
11012
c48245f0
MR
11013 tcg_gen_movi_tl(t2, framesize);
11014 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11015 tcg_temp_free(t0);
11016 tcg_temp_free(t1);
c48245f0 11017 tcg_temp_free(t2);
364d4831
NF
11018}
11019
11020static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11021 int is_64_bit, int extended)
11022{
11023 TCGv t0;
11024
11025 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11026 generate_exception(ctx, EXCP_RI);
11027 return;
11028 }
11029
11030 t0 = tcg_temp_new();
11031
11032 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11033 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11034 if (!is_64_bit) {
11035 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11036 }
11037
11038 tcg_temp_free(t0);
11039}
11040
11041#if defined(TARGET_MIPS64)
d75c135e 11042static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11043 int ry, int funct, int16_t offset,
11044 int extended)
11045{
11046 switch (funct) {
11047 case I64_LDSP:
d9224450 11048 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11049 check_mips_64(ctx);
11050 offset = extended ? offset : offset << 3;
d75c135e 11051 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11052 break;
11053 case I64_SDSP:
d9224450 11054 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11055 check_mips_64(ctx);
11056 offset = extended ? offset : offset << 3;
5c13fdfd 11057 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11058 break;
11059 case I64_SDRASP:
d9224450 11060 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11061 check_mips_64(ctx);
11062 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11063 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11064 break;
11065 case I64_DADJSP:
d9224450 11066 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11067 check_mips_64(ctx);
11068 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11069 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11070 break;
11071 case I64_LDPC:
d9224450
MR
11072 check_insn(ctx, ISA_MIPS3);
11073 check_mips_64(ctx);
364d4831
NF
11074 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11075 generate_exception(ctx, EXCP_RI);
11076 } else {
11077 offset = extended ? offset : offset << 3;
d75c135e 11078 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11079 }
11080 break;
11081 case I64_DADDIU5:
d9224450 11082 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11083 check_mips_64(ctx);
11084 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11085 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11086 break;
11087 case I64_DADDIUPC:
d9224450 11088 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11089 check_mips_64(ctx);
11090 offset = extended ? offset : offset << 2;
11091 gen_addiupc(ctx, ry, offset, 1, extended);
11092 break;
11093 case I64_DADDIUSP:
d9224450 11094 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11095 check_mips_64(ctx);
11096 offset = extended ? offset : offset << 2;
d75c135e 11097 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11098 break;
11099 }
11100}
11101#endif
11102
240ce26a 11103static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11104{
895c2d04 11105 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11106 int op, rx, ry, funct, sa;
11107 int16_t imm, offset;
11108
11109 ctx->opcode = (ctx->opcode << 16) | extend;
11110 op = (ctx->opcode >> 11) & 0x1f;
11111 sa = (ctx->opcode >> 22) & 0x1f;
11112 funct = (ctx->opcode >> 8) & 0x7;
11113 rx = xlat((ctx->opcode >> 8) & 0x7);
11114 ry = xlat((ctx->opcode >> 5) & 0x7);
11115 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11116 | ((ctx->opcode >> 21) & 0x3f) << 5
11117 | (ctx->opcode & 0x1f));
11118
11119 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11120 counterparts. */
11121 switch (op) {
11122 case M16_OPC_ADDIUSP:
d75c135e 11123 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11124 break;
11125 case M16_OPC_ADDIUPC:
11126 gen_addiupc(ctx, rx, imm, 0, 1);
11127 break;
11128 case M16_OPC_B:
b231c103 11129 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11130 /* No delay slot, so just process as a normal instruction */
11131 break;
11132 case M16_OPC_BEQZ:
b231c103 11133 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11134 /* No delay slot, so just process as a normal instruction */
11135 break;
11136 case M16_OPC_BNEQZ:
b231c103 11137 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11138 /* No delay slot, so just process as a normal instruction */
11139 break;
11140 case M16_OPC_SHIFT:
11141 switch (ctx->opcode & 0x3) {
11142 case 0x0:
d75c135e 11143 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11144 break;
11145 case 0x1:
11146#if defined(TARGET_MIPS64)
11147 check_mips_64(ctx);
d75c135e 11148 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11149#else
11150 generate_exception(ctx, EXCP_RI);
11151#endif
11152 break;
11153 case 0x2:
d75c135e 11154 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11155 break;
11156 case 0x3:
d75c135e 11157 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11158 break;
11159 }
11160 break;
11161#if defined(TARGET_MIPS64)
11162 case M16_OPC_LD:
d9224450 11163 check_insn(ctx, ISA_MIPS3);
d75de749 11164 check_mips_64(ctx);
d75c135e 11165 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11166 break;
11167#endif
11168 case M16_OPC_RRIA:
11169 imm = ctx->opcode & 0xf;
11170 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11171 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11172 imm = (int16_t) (imm << 1) >> 1;
11173 if ((ctx->opcode >> 4) & 0x1) {
11174#if defined(TARGET_MIPS64)
11175 check_mips_64(ctx);
d75c135e 11176 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11177#else
11178 generate_exception(ctx, EXCP_RI);
11179#endif
11180 } else {
d75c135e 11181 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11182 }
11183 break;
11184 case M16_OPC_ADDIU8:
d75c135e 11185 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11186 break;
11187 case M16_OPC_SLTI:
d75c135e 11188 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11189 break;
11190 case M16_OPC_SLTIU:
d75c135e 11191 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11192 break;
11193 case M16_OPC_I8:
11194 switch (funct) {
11195 case I8_BTEQZ:
b231c103 11196 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11197 break;
11198 case I8_BTNEZ:
b231c103 11199 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11200 break;
11201 case I8_SWRASP:
5c13fdfd 11202 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11203 break;
11204 case I8_ADJSP:
d75c135e 11205 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11206 break;
11207 case I8_SVRS:
d9224450 11208 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11209 {
11210 int xsregs = (ctx->opcode >> 24) & 0x7;
11211 int aregs = (ctx->opcode >> 16) & 0xf;
11212 int do_ra = (ctx->opcode >> 6) & 0x1;
11213 int do_s0 = (ctx->opcode >> 5) & 0x1;
11214 int do_s1 = (ctx->opcode >> 4) & 0x1;
11215 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11216 | (ctx->opcode & 0xf)) << 3;
11217
11218 if (ctx->opcode & (1 << 7)) {
11219 gen_mips16_save(ctx, xsregs, aregs,
11220 do_ra, do_s0, do_s1,
11221 framesize);
11222 } else {
11223 gen_mips16_restore(ctx, xsregs, aregs,
11224 do_ra, do_s0, do_s1,
11225 framesize);
11226 }
11227 }
11228 break;
11229 default:
11230 generate_exception(ctx, EXCP_RI);
11231 break;
11232 }
11233 break;
11234 case M16_OPC_LI:
11235 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11236 break;
11237 case M16_OPC_CMPI:
11238 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11239 break;
11240#if defined(TARGET_MIPS64)
11241 case M16_OPC_SD:
d9224450
MR
11242 check_insn(ctx, ISA_MIPS3);
11243 check_mips_64(ctx);
5c13fdfd 11244 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11245 break;
11246#endif
11247 case M16_OPC_LB:
d75c135e 11248 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11249 break;
11250 case M16_OPC_LH:
d75c135e 11251 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11252 break;
11253 case M16_OPC_LWSP:
d75c135e 11254 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11255 break;
11256 case M16_OPC_LW:
d75c135e 11257 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11258 break;
11259 case M16_OPC_LBU:
d75c135e 11260 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11261 break;
11262 case M16_OPC_LHU:
d75c135e 11263 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11264 break;
11265 case M16_OPC_LWPC:
d75c135e 11266 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11267 break;
11268#if defined(TARGET_MIPS64)
11269 case M16_OPC_LWU:
d9224450
MR
11270 check_insn(ctx, ISA_MIPS3);
11271 check_mips_64(ctx);
d75c135e 11272 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11273 break;
11274#endif
11275 case M16_OPC_SB:
5c13fdfd 11276 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11277 break;
11278 case M16_OPC_SH:
5c13fdfd 11279 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11280 break;
11281 case M16_OPC_SWSP:
5c13fdfd 11282 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11283 break;
11284 case M16_OPC_SW:
5c13fdfd 11285 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11286 break;
11287#if defined(TARGET_MIPS64)
11288 case M16_OPC_I64:
d75c135e 11289 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11290 break;
11291#endif
11292 default:
11293 generate_exception(ctx, EXCP_RI);
11294 break;
11295 }
11296
11297 return 4;
11298}
11299
240ce26a 11300static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11301{
11302 int rx, ry;
11303 int sa;
11304 int op, cnvt_op, op1, offset;
11305 int funct;
11306 int n_bytes;
11307
11308 op = (ctx->opcode >> 11) & 0x1f;
11309 sa = (ctx->opcode >> 2) & 0x7;
11310 sa = sa == 0 ? 8 : sa;
11311 rx = xlat((ctx->opcode >> 8) & 0x7);
11312 cnvt_op = (ctx->opcode >> 5) & 0x7;
11313 ry = xlat((ctx->opcode >> 5) & 0x7);
11314 op1 = offset = ctx->opcode & 0x1f;
11315
11316 n_bytes = 2;
11317
11318 switch (op) {
11319 case M16_OPC_ADDIUSP:
11320 {
11321 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11322
d75c135e 11323 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11324 }
11325 break;
11326 case M16_OPC_ADDIUPC:
11327 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11328 break;
11329 case M16_OPC_B:
11330 offset = (ctx->opcode & 0x7ff) << 1;
11331 offset = (int16_t)(offset << 4) >> 4;
b231c103 11332 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11333 /* No delay slot, so just process as a normal instruction */
11334 break;
11335 case M16_OPC_JAL:
895c2d04 11336 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11337 offset = (((ctx->opcode & 0x1f) << 21)
11338 | ((ctx->opcode >> 5) & 0x1f) << 16
11339 | offset) << 2;
b231c103
YK
11340 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11341 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11342 n_bytes = 4;
364d4831
NF
11343 break;
11344 case M16_OPC_BEQZ:
b231c103
YK
11345 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11346 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11347 /* No delay slot, so just process as a normal instruction */
11348 break;
11349 case M16_OPC_BNEQZ:
b231c103
YK
11350 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11351 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11352 /* No delay slot, so just process as a normal instruction */
11353 break;
11354 case M16_OPC_SHIFT:
11355 switch (ctx->opcode & 0x3) {
11356 case 0x0:
d75c135e 11357 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11358 break;
11359 case 0x1:
11360#if defined(TARGET_MIPS64)
d9224450 11361 check_insn(ctx, ISA_MIPS3);
364d4831 11362 check_mips_64(ctx);
d75c135e 11363 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11364#else
11365 generate_exception(ctx, EXCP_RI);
11366#endif
11367 break;
11368 case 0x2:
d75c135e 11369 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11370 break;
11371 case 0x3:
d75c135e 11372 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11373 break;
11374 }
11375 break;
11376#if defined(TARGET_MIPS64)
11377 case M16_OPC_LD:
d9224450 11378 check_insn(ctx, ISA_MIPS3);
364d4831 11379 check_mips_64(ctx);
d75c135e 11380 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11381 break;
11382#endif
11383 case M16_OPC_RRIA:
11384 {
11385 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11386
11387 if ((ctx->opcode >> 4) & 1) {
11388#if defined(TARGET_MIPS64)
d9224450 11389 check_insn(ctx, ISA_MIPS3);
364d4831 11390 check_mips_64(ctx);
d75c135e 11391 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11392#else
11393 generate_exception(ctx, EXCP_RI);
11394#endif
11395 } else {
d75c135e 11396 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11397 }
11398 }
11399 break;
11400 case M16_OPC_ADDIU8:
11401 {
11402 int16_t imm = (int8_t) ctx->opcode;
11403
d75c135e 11404 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11405 }
11406 break;
11407 case M16_OPC_SLTI:
11408 {
11409 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11410 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11411 }
11412 break;
11413 case M16_OPC_SLTIU:
11414 {
11415 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11416 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11417 }
11418 break;
11419 case M16_OPC_I8:
11420 {
11421 int reg32;
11422
11423 funct = (ctx->opcode >> 8) & 0x7;
11424 switch (funct) {
11425 case I8_BTEQZ:
11426 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11427 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11428 break;
11429 case I8_BTNEZ:
11430 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11431 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11432 break;
11433 case I8_SWRASP:
5c13fdfd 11434 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11435 break;
11436 case I8_ADJSP:
d75c135e 11437 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11438 ((int8_t)ctx->opcode) << 3);
11439 break;
11440 case I8_SVRS:
d9224450 11441 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11442 {
11443 int do_ra = ctx->opcode & (1 << 6);
11444 int do_s0 = ctx->opcode & (1 << 5);
11445 int do_s1 = ctx->opcode & (1 << 4);
11446 int framesize = ctx->opcode & 0xf;
11447
11448 if (framesize == 0) {
11449 framesize = 128;
11450 } else {
11451 framesize = framesize << 3;
11452 }
11453
11454 if (ctx->opcode & (1 << 7)) {
11455 gen_mips16_save(ctx, 0, 0,
11456 do_ra, do_s0, do_s1, framesize);
11457 } else {
11458 gen_mips16_restore(ctx, 0, 0,
11459 do_ra, do_s0, do_s1, framesize);
11460 }
11461 }
11462 break;
11463 case I8_MOV32R:
11464 {
11465 int rz = xlat(ctx->opcode & 0x7);
11466
11467 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11468 ((ctx->opcode >> 5) & 0x7);
d75c135e 11469 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11470 }
11471 break;
11472 case I8_MOVR32:
11473 reg32 = ctx->opcode & 0x1f;
d75c135e 11474 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11475 break;
11476 default:
11477 generate_exception(ctx, EXCP_RI);
11478 break;
11479 }
11480 }
11481 break;
11482 case M16_OPC_LI:
11483 {
11484 int16_t imm = (uint8_t) ctx->opcode;
11485
d75c135e 11486 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11487 }
11488 break;
11489 case M16_OPC_CMPI:
11490 {
11491 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11492 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11493 }
11494 break;
11495#if defined(TARGET_MIPS64)
11496 case M16_OPC_SD:
d9224450 11497 check_insn(ctx, ISA_MIPS3);
364d4831 11498 check_mips_64(ctx);
5c13fdfd 11499 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11500 break;
11501#endif
11502 case M16_OPC_LB:
d75c135e 11503 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11504 break;
11505 case M16_OPC_LH:
d75c135e 11506 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11507 break;
11508 case M16_OPC_LWSP:
d75c135e 11509 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11510 break;
11511 case M16_OPC_LW:
d75c135e 11512 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11513 break;
11514 case M16_OPC_LBU:
d75c135e 11515 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11516 break;
11517 case M16_OPC_LHU:
d75c135e 11518 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11519 break;
11520 case M16_OPC_LWPC:
d75c135e 11521 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11522 break;
11523#if defined (TARGET_MIPS64)
11524 case M16_OPC_LWU:
d9224450 11525 check_insn(ctx, ISA_MIPS3);
364d4831 11526 check_mips_64(ctx);
d75c135e 11527 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11528 break;
11529#endif
11530 case M16_OPC_SB:
5c13fdfd 11531 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11532 break;
11533 case M16_OPC_SH:
5c13fdfd 11534 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11535 break;
11536 case M16_OPC_SWSP:
5c13fdfd 11537 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11538 break;
11539 case M16_OPC_SW:
5c13fdfd 11540 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11541 break;
11542 case M16_OPC_RRR:
11543 {
11544 int rz = xlat((ctx->opcode >> 2) & 0x7);
11545 int mips32_op;
11546
11547 switch (ctx->opcode & 0x3) {
11548 case RRR_ADDU:
11549 mips32_op = OPC_ADDU;
11550 break;
11551 case RRR_SUBU:
11552 mips32_op = OPC_SUBU;
11553 break;
11554#if defined(TARGET_MIPS64)
11555 case RRR_DADDU:
11556 mips32_op = OPC_DADDU;
d9224450 11557 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11558 check_mips_64(ctx);
11559 break;
11560 case RRR_DSUBU:
11561 mips32_op = OPC_DSUBU;
d9224450 11562 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11563 check_mips_64(ctx);
11564 break;
11565#endif
11566 default:
11567 generate_exception(ctx, EXCP_RI);
11568 goto done;
11569 }
11570
d75c135e 11571 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11572 done:
11573 ;
11574 }
11575 break;
11576 case M16_OPC_RR:
11577 switch (op1) {
11578 case RR_JR:
11579 {
11580 int nd = (ctx->opcode >> 7) & 0x1;
11581 int link = (ctx->opcode >> 6) & 0x1;
11582 int ra = (ctx->opcode >> 5) & 0x1;
11583
d9224450
MR
11584 if (nd) {
11585 check_insn(ctx, ISA_MIPS32);
11586 }
11587
364d4831 11588 if (link) {
b231c103 11589 op = OPC_JALR;
364d4831
NF
11590 } else {
11591 op = OPC_JR;
11592 }
11593
b231c103
YK
11594 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11595 (nd ? 0 : 2));
364d4831
NF
11596 }
11597 break;
11598 case RR_SDBBP:
11599 /* XXX: not clear which exception should be raised
11600 * when in debug mode...
11601 */
d75c135e 11602 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11603 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11604 generate_exception(ctx, EXCP_DBp);
11605 } else {
11606 generate_exception(ctx, EXCP_DBp);
11607 }
11608 break;
11609 case RR_SLT:
d75c135e 11610 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11611 break;
11612 case RR_SLTU:
d75c135e 11613 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11614 break;
11615 case RR_BREAK:
11616 generate_exception(ctx, EXCP_BREAK);
11617 break;
11618 case RR_SLLV:
d75c135e 11619 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11620 break;
11621 case RR_SRLV:
d75c135e 11622 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11623 break;
11624 case RR_SRAV:
d75c135e 11625 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11626 break;
11627#if defined (TARGET_MIPS64)
11628 case RR_DSRL:
d9224450 11629 check_insn(ctx, ISA_MIPS3);
364d4831 11630 check_mips_64(ctx);
d75c135e 11631 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11632 break;
11633#endif
11634 case RR_CMP:
d75c135e 11635 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11636 break;
11637 case RR_NEG:
d75c135e 11638 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11639 break;
11640 case RR_AND:
d75c135e 11641 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11642 break;
11643 case RR_OR:
d75c135e 11644 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11645 break;
11646 case RR_XOR:
d75c135e 11647 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11648 break;
11649 case RR_NOT:
d75c135e 11650 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11651 break;
11652 case RR_MFHI:
26135ead 11653 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11654 break;
11655 case RR_CNVT:
d9224450 11656 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11657 switch (cnvt_op) {
11658 case RR_RY_CNVT_ZEB:
11659 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11660 break;
11661 case RR_RY_CNVT_ZEH:
11662 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11663 break;
11664 case RR_RY_CNVT_SEB:
11665 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11666 break;
11667 case RR_RY_CNVT_SEH:
11668 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11669 break;
11670#if defined (TARGET_MIPS64)
11671 case RR_RY_CNVT_ZEW:
d9224450 11672 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11673 check_mips_64(ctx);
11674 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11675 break;
11676 case RR_RY_CNVT_SEW:
d9224450 11677 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11678 check_mips_64(ctx);
11679 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11680 break;
11681#endif
11682 default:
11683 generate_exception(ctx, EXCP_RI);
11684 break;
11685 }
11686 break;
11687 case RR_MFLO:
26135ead 11688 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11689 break;
11690#if defined (TARGET_MIPS64)
11691 case RR_DSRA:
d9224450 11692 check_insn(ctx, ISA_MIPS3);
364d4831 11693 check_mips_64(ctx);
d75c135e 11694 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11695 break;
11696 case RR_DSLLV:
d9224450 11697 check_insn(ctx, ISA_MIPS3);
364d4831 11698 check_mips_64(ctx);
d75c135e 11699 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11700 break;
11701 case RR_DSRLV:
d9224450 11702 check_insn(ctx, ISA_MIPS3);
364d4831 11703 check_mips_64(ctx);
d75c135e 11704 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11705 break;
11706 case RR_DSRAV:
d9224450 11707 check_insn(ctx, ISA_MIPS3);
364d4831 11708 check_mips_64(ctx);
d75c135e 11709 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11710 break;
11711#endif
11712 case RR_MULT:
26135ead 11713 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11714 break;
11715 case RR_MULTU:
26135ead 11716 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11717 break;
11718 case RR_DIV:
26135ead 11719 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11720 break;
11721 case RR_DIVU:
26135ead 11722 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11723 break;
11724#if defined (TARGET_MIPS64)
11725 case RR_DMULT:
d9224450 11726 check_insn(ctx, ISA_MIPS3);
364d4831 11727 check_mips_64(ctx);
26135ead 11728 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11729 break;
11730 case RR_DMULTU:
d9224450 11731 check_insn(ctx, ISA_MIPS3);
364d4831 11732 check_mips_64(ctx);
26135ead 11733 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11734 break;
11735 case RR_DDIV:
d9224450 11736 check_insn(ctx, ISA_MIPS3);
364d4831 11737 check_mips_64(ctx);
26135ead 11738 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11739 break;
11740 case RR_DDIVU:
d9224450 11741 check_insn(ctx, ISA_MIPS3);
364d4831 11742 check_mips_64(ctx);
26135ead 11743 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11744 break;
11745#endif
11746 default:
11747 generate_exception(ctx, EXCP_RI);
11748 break;
11749 }
11750 break;
11751 case M16_OPC_EXTEND:
240ce26a 11752 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11753 n_bytes = 4;
11754 break;
11755#if defined(TARGET_MIPS64)
11756 case M16_OPC_I64:
11757 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11758 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11759 break;
11760#endif
11761 default:
11762 generate_exception(ctx, EXCP_RI);
11763 break;
11764 }
11765
11766 return n_bytes;
11767}
11768
211da992 11769/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11770
211da992
CWR
11771/*
11772 * microMIPS32/microMIPS64 major opcodes
11773 *
11774 * 1. MIPS Architecture for Programmers Volume II-B:
11775 * The microMIPS32 Instruction Set (Revision 3.05)
11776 *
11777 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11778 *
11779 * 2. MIPS Architecture For Programmers Volume II-A:
11780 * The MIPS64 Instruction Set (Revision 3.51)
11781 */
6af0bf9c 11782
3c824109
NF
11783enum {
11784 POOL32A = 0x00,
11785 POOL16A = 0x01,
11786 LBU16 = 0x02,
11787 MOVE16 = 0x03,
11788 ADDI32 = 0x04,
11789 LBU32 = 0x05,
11790 SB32 = 0x06,
11791 LB32 = 0x07,
11792
11793 POOL32B = 0x08,
11794 POOL16B = 0x09,
11795 LHU16 = 0x0a,
11796 ANDI16 = 0x0b,
11797 ADDIU32 = 0x0c,
11798 LHU32 = 0x0d,
11799 SH32 = 0x0e,
11800 LH32 = 0x0f,
11801
11802 POOL32I = 0x10,
11803 POOL16C = 0x11,
11804 LWSP16 = 0x12,
11805 POOL16D = 0x13,
11806 ORI32 = 0x14,
11807 POOL32F = 0x15,
211da992
CWR
11808 POOL32S = 0x16, /* MIPS64 */
11809 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11810
211da992 11811 /* 0x1f is reserved */
3c824109
NF
11812 POOL32C = 0x18,
11813 LWGP16 = 0x19,
11814 LW16 = 0x1a,
11815 POOL16E = 0x1b,
11816 XORI32 = 0x1c,
11817 JALS32 = 0x1d,
11818 ADDIUPC = 0x1e,
3c824109
NF
11819
11820 /* 0x20 is reserved */
11821 RES_20 = 0x20,
11822 POOL16F = 0x21,
11823 SB16 = 0x22,
11824 BEQZ16 = 0x23,
11825 SLTI32 = 0x24,
11826 BEQ32 = 0x25,
11827 SWC132 = 0x26,
11828 LWC132 = 0x27,
11829
11830 /* 0x28 and 0x29 are reserved */
11831 RES_28 = 0x28,
11832 RES_29 = 0x29,
11833 SH16 = 0x2a,
11834 BNEZ16 = 0x2b,
11835 SLTIU32 = 0x2c,
11836 BNE32 = 0x2d,
11837 SDC132 = 0x2e,
11838 LDC132 = 0x2f,
11839
11840 /* 0x30 and 0x31 are reserved */
11841 RES_30 = 0x30,
11842 RES_31 = 0x31,
11843 SWSP16 = 0x32,
11844 B16 = 0x33,
11845 ANDI32 = 0x34,
11846 J32 = 0x35,
211da992
CWR
11847 SD32 = 0x36, /* MIPS64 */
11848 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11849
11850 /* 0x38 and 0x39 are reserved */
11851 RES_38 = 0x38,
11852 RES_39 = 0x39,
11853 SW16 = 0x3a,
11854 LI16 = 0x3b,
11855 JALX32 = 0x3c,
11856 JAL32 = 0x3d,
11857 SW32 = 0x3e,
11858 LW32 = 0x3f
11859};
11860
11861/* POOL32A encoding of minor opcode field */
11862
11863enum {
11864 /* These opcodes are distinguished only by bits 9..6; those bits are
11865 * what are recorded below. */
11866 SLL32 = 0x0,
11867 SRL32 = 0x1,
11868 SRA = 0x2,
11869 ROTR = 0x3,
11870
11871 SLLV = 0x0,
11872 SRLV = 0x1,
11873 SRAV = 0x2,
11874 ROTRV = 0x3,
11875 ADD = 0x4,
11876 ADDU32 = 0x5,
11877 SUB = 0x6,
11878 SUBU32 = 0x7,
11879 MUL = 0x8,
11880 AND = 0x9,
11881 OR32 = 0xa,
11882 NOR = 0xb,
11883 XOR32 = 0xc,
11884 SLT = 0xd,
11885 SLTU = 0xe,
11886
11887 MOVN = 0x0,
11888 MOVZ = 0x1,
11889 LWXS = 0x4,
11890
11891 /* The following can be distinguished by their lower 6 bits. */
11892 INS = 0x0c,
11893 EXT = 0x2c,
11894 POOL32AXF = 0x3c
11895};
11896
11897/* POOL32AXF encoding of minor opcode field extension */
11898
d132c79f
CWR
11899/*
11900 * 1. MIPS Architecture for Programmers Volume II-B:
11901 * The microMIPS32 Instruction Set (Revision 3.05)
11902 *
11903 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11904 *
11905 * 2. MIPS Architecture for Programmers VolumeIV-e:
11906 * The MIPS DSP Application-Specific Extension
11907 * to the microMIPS32 Architecture (Revision 2.34)
11908 *
11909 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11910 */
11911
3c824109
NF
11912enum {
11913 /* bits 11..6 */
11914 TEQ = 0x00,
11915 TGE = 0x08,
11916 TGEU = 0x10,
11917 TLT = 0x20,
11918 TLTU = 0x28,
11919 TNE = 0x30,
11920
11921 MFC0 = 0x03,
11922 MTC0 = 0x0b,
11923
d132c79f
CWR
11924 /* begin of microMIPS32 DSP */
11925
3c824109
NF
11926 /* bits 13..12 for 0x01 */
11927 MFHI_ACC = 0x0,
11928 MFLO_ACC = 0x1,
11929 MTHI_ACC = 0x2,
11930 MTLO_ACC = 0x3,
11931
11932 /* bits 13..12 for 0x2a */
11933 MADD_ACC = 0x0,
11934 MADDU_ACC = 0x1,
11935 MSUB_ACC = 0x2,
11936 MSUBU_ACC = 0x3,
11937
11938 /* bits 13..12 for 0x32 */
11939 MULT_ACC = 0x0,
6801038b 11940 MULTU_ACC = 0x1,
3c824109 11941
d132c79f
CWR
11942 /* end of microMIPS32 DSP */
11943
3c824109
NF
11944 /* bits 15..12 for 0x2c */
11945 SEB = 0x2,
11946 SEH = 0x3,
11947 CLO = 0x4,
11948 CLZ = 0x5,
11949 RDHWR = 0x6,
11950 WSBH = 0x7,
11951 MULT = 0x8,
11952 MULTU = 0x9,
11953 DIV = 0xa,
11954 DIVU = 0xb,
11955 MADD = 0xc,
11956 MADDU = 0xd,
11957 MSUB = 0xe,
11958 MSUBU = 0xf,
11959
11960 /* bits 15..12 for 0x34 */
11961 MFC2 = 0x4,
11962 MTC2 = 0x5,
11963 MFHC2 = 0x8,
11964 MTHC2 = 0x9,
11965 CFC2 = 0xc,
11966 CTC2 = 0xd,
11967
11968 /* bits 15..12 for 0x3c */
11969 JALR = 0x0,
11970 JR = 0x0, /* alias */
11971 JALR_HB = 0x1,
11972 JALRS = 0x4,
11973 JALRS_HB = 0x5,
11974
11975 /* bits 15..12 for 0x05 */
11976 RDPGPR = 0xe,
11977 WRPGPR = 0xf,
11978
11979 /* bits 15..12 for 0x0d */
11980 TLBP = 0x0,
11981 TLBR = 0x1,
11982 TLBWI = 0x2,
11983 TLBWR = 0x3,
11984 WAIT = 0x9,
11985 IRET = 0xd,
11986 DERET = 0xe,
11987 ERET = 0xf,
11988
11989 /* bits 15..12 for 0x15 */
11990 DMT = 0x0,
11991 DVPE = 0x1,
11992 EMT = 0x2,
11993 EVPE = 0x3,
11994
11995 /* bits 15..12 for 0x1d */
11996 DI = 0x4,
11997 EI = 0x5,
11998
11999 /* bits 15..12 for 0x2d */
12000 SYNC = 0x6,
12001 SYSCALL = 0x8,
12002 SDBBP = 0xd,
12003
12004 /* bits 15..12 for 0x35 */
12005 MFHI32 = 0x0,
12006 MFLO32 = 0x1,
12007 MTHI32 = 0x2,
12008 MTLO32 = 0x3,
12009};
12010
12011/* POOL32B encoding of minor opcode field (bits 15..12) */
12012
12013enum {
12014 LWC2 = 0x0,
12015 LWP = 0x1,
12016 LDP = 0x4,
12017 LWM32 = 0x5,
12018 CACHE = 0x6,
12019 LDM = 0x7,
12020 SWC2 = 0x8,
12021 SWP = 0x9,
12022 SDP = 0xc,
12023 SWM32 = 0xd,
12024 SDM = 0xf
12025};
12026
12027/* POOL32C encoding of minor opcode field (bits 15..12) */
12028
12029enum {
12030 LWL = 0x0,
12031 SWL = 0x8,
12032 LWR = 0x1,
12033 SWR = 0x9,
12034 PREF = 0x2,
12035 /* 0xa is reserved */
12036 LL = 0x3,
12037 SC = 0xb,
12038 LDL = 0x4,
12039 SDL = 0xc,
12040 LDR = 0x5,
12041 SDR = 0xd,
12042 /* 0x6 is reserved */
12043 LWU = 0xe,
12044 LLD = 0x7,
12045 SCD = 0xf
12046};
12047
12048/* POOL32F encoding of minor opcode field (bits 5..0) */
12049
12050enum {
12051 /* These are the bit 7..6 values */
12052 ADD_FMT = 0x0,
12053 MOVN_FMT = 0x0,
12054
12055 SUB_FMT = 0x1,
12056 MOVZ_FMT = 0x1,
12057
12058 MUL_FMT = 0x2,
12059
12060 DIV_FMT = 0x3,
12061
12062 /* These are the bit 8..6 values */
12063 RSQRT2_FMT = 0x0,
12064 MOVF_FMT = 0x0,
12065
12066 LWXC1 = 0x1,
12067 MOVT_FMT = 0x1,
12068
12069 PLL_PS = 0x2,
12070 SWXC1 = 0x2,
12071
12072 PLU_PS = 0x3,
12073 LDXC1 = 0x3,
12074
12075 PUL_PS = 0x4,
12076 SDXC1 = 0x4,
12077 RECIP2_FMT = 0x4,
12078
12079 PUU_PS = 0x5,
12080 LUXC1 = 0x5,
12081
12082 CVT_PS_S = 0x6,
12083 SUXC1 = 0x6,
12084 ADDR_PS = 0x6,
12085 PREFX = 0x6,
12086
12087 MULR_PS = 0x7,
12088
12089 MADD_S = 0x01,
12090 MADD_D = 0x09,
12091 MADD_PS = 0x11,
12092 ALNV_PS = 0x19,
12093 MSUB_S = 0x21,
12094 MSUB_D = 0x29,
12095 MSUB_PS = 0x31,
12096
12097 NMADD_S = 0x02,
12098 NMADD_D = 0x0a,
12099 NMADD_PS = 0x12,
12100 NMSUB_S = 0x22,
12101 NMSUB_D = 0x2a,
12102 NMSUB_PS = 0x32,
12103
12104 POOL32FXF = 0x3b,
12105
12106 CABS_COND_FMT = 0x1c, /* MIPS3D */
12107 C_COND_FMT = 0x3c
12108};
12109
12110/* POOL32Fxf encoding of minor opcode extension field */
12111
12112enum {
12113 CVT_L = 0x04,
12114 RSQRT_FMT = 0x08,
12115 FLOOR_L = 0x0c,
12116 CVT_PW_PS = 0x1c,
12117 CVT_W = 0x24,
12118 SQRT_FMT = 0x28,
12119 FLOOR_W = 0x2c,
12120 CVT_PS_PW = 0x3c,
12121 CFC1 = 0x40,
12122 RECIP_FMT = 0x48,
12123 CEIL_L = 0x4c,
12124 CTC1 = 0x60,
12125 CEIL_W = 0x6c,
12126 MFC1 = 0x80,
12127 CVT_S_PL = 0x84,
12128 TRUNC_L = 0x8c,
12129 MTC1 = 0xa0,
12130 CVT_S_PU = 0xa4,
12131 TRUNC_W = 0xac,
12132 MFHC1 = 0xc0,
12133 ROUND_L = 0xcc,
12134 MTHC1 = 0xe0,
12135 ROUND_W = 0xec,
12136
12137 MOV_FMT = 0x01,
12138 MOVF = 0x05,
12139 ABS_FMT = 0x0d,
12140 RSQRT1_FMT = 0x1d,
12141 MOVT = 0x25,
12142 NEG_FMT = 0x2d,
12143 CVT_D = 0x4d,
12144 RECIP1_FMT = 0x5d,
12145 CVT_S = 0x6d
12146};
12147
12148/* POOL32I encoding of minor opcode field (bits 25..21) */
12149
12150enum {
12151 BLTZ = 0x00,
12152 BLTZAL = 0x01,
12153 BGEZ = 0x02,
12154 BGEZAL = 0x03,
12155 BLEZ = 0x04,
12156 BNEZC = 0x05,
12157 BGTZ = 0x06,
12158 BEQZC = 0x07,
12159 TLTI = 0x08,
12160 TGEI = 0x09,
12161 TLTIU = 0x0a,
12162 TGEIU = 0x0b,
12163 TNEI = 0x0c,
12164 LUI = 0x0d,
12165 TEQI = 0x0e,
12166 SYNCI = 0x10,
12167 BLTZALS = 0x11,
12168 BGEZALS = 0x13,
12169 BC2F = 0x14,
12170 BC2T = 0x15,
12171 BPOSGE64 = 0x1a,
12172 BPOSGE32 = 0x1b,
12173 /* These overlap and are distinguished by bit16 of the instruction */
12174 BC1F = 0x1c,
12175 BC1T = 0x1d,
12176 BC1ANY2F = 0x1c,
12177 BC1ANY2T = 0x1d,
12178 BC1ANY4F = 0x1e,
12179 BC1ANY4T = 0x1f
12180};
12181
12182/* POOL16A encoding of minor opcode field */
12183
12184enum {
12185 ADDU16 = 0x0,
12186 SUBU16 = 0x1
12187};
12188
12189/* POOL16B encoding of minor opcode field */
12190
12191enum {
12192 SLL16 = 0x0,
12193 SRL16 = 0x1
12194};
12195
12196/* POOL16C encoding of minor opcode field */
12197
12198enum {
12199 NOT16 = 0x00,
12200 XOR16 = 0x04,
12201 AND16 = 0x08,
12202 OR16 = 0x0c,
12203 LWM16 = 0x10,
12204 SWM16 = 0x14,
12205 JR16 = 0x18,
12206 JRC16 = 0x1a,
12207 JALR16 = 0x1c,
12208 JALR16S = 0x1e,
12209 MFHI16 = 0x20,
12210 MFLO16 = 0x24,
12211 BREAK16 = 0x28,
12212 SDBBP16 = 0x2c,
12213 JRADDIUSP = 0x30
12214};
12215
12216/* POOL16D encoding of minor opcode field */
12217
12218enum {
12219 ADDIUS5 = 0x0,
12220 ADDIUSP = 0x1
12221};
12222
12223/* POOL16E encoding of minor opcode field */
12224
12225enum {
12226 ADDIUR2 = 0x0,
12227 ADDIUR1SP = 0x1
12228};
12229
12230static int mmreg (int r)
12231{
12232 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12233
12234 return map[r];
12235}
12236
12237/* Used for 16-bit store instructions. */
12238static int mmreg2 (int r)
12239{
12240 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12241
12242 return map[r];
12243}
12244
12245#define uMIPS_RD(op) ((op >> 7) & 0x7)
12246#define uMIPS_RS(op) ((op >> 4) & 0x7)
12247#define uMIPS_RS2(op) uMIPS_RS(op)
12248#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12249#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12250#define uMIPS_RS5(op) (op & 0x1f)
12251
12252/* Signed immediate */
12253#define SIMM(op, start, width) \
12254 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12255 << (32-width)) \
12256 >> (32-width))
12257/* Zero-extended immediate */
12258#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12259
d75c135e 12260static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12261{
12262 int rd = mmreg(uMIPS_RD(ctx->opcode));
12263
d75c135e 12264 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12265}
12266
d75c135e 12267static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12268{
12269 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12270 int rd = mmreg(uMIPS_RD(ctx->opcode));
12271 int rs = mmreg(uMIPS_RS(ctx->opcode));
12272
d75c135e 12273 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12274}
12275
d75c135e 12276static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12277{
12278 int encoded = ZIMM(ctx->opcode, 1, 9);
12279 int decoded;
12280
12281 if (encoded <= 1) {
12282 decoded = 256 + encoded;
12283 } else if (encoded <= 255) {
12284 decoded = encoded;
12285 } else if (encoded <= 509) {
12286 decoded = encoded - 512;
12287 } else {
12288 decoded = encoded - 768;
12289 }
12290
d75c135e 12291 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12292}
12293
d75c135e 12294static void gen_addius5(DisasContext *ctx)
3c824109
NF
12295{
12296 int imm = SIMM(ctx->opcode, 1, 4);
12297 int rd = (ctx->opcode >> 5) & 0x1f;
12298
d75c135e 12299 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12300}
12301
d75c135e 12302static void gen_andi16(DisasContext *ctx)
3c824109
NF
12303{
12304 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12305 31, 32, 63, 64, 255, 32768, 65535 };
12306 int rd = mmreg(uMIPS_RD(ctx->opcode));
12307 int rs = mmreg(uMIPS_RS(ctx->opcode));
12308 int encoded = ZIMM(ctx->opcode, 0, 4);
12309
d75c135e 12310 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12311}
12312
12313static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12314 int base, int16_t offset)
12315{
e1050a76 12316 const char *opn = "ldst_multiple";
3c824109
NF
12317 TCGv t0, t1;
12318 TCGv_i32 t2;
12319
12320 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12321 generate_exception(ctx, EXCP_RI);
12322 return;
12323 }
12324
12325 t0 = tcg_temp_new();
12326
12327 gen_base_offset_addr(ctx, t0, base, offset);
12328
12329 t1 = tcg_const_tl(reglist);
12330 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12331
3c824109
NF
12332 save_cpu_state(ctx, 1);
12333 switch (opc) {
12334 case LWM32:
895c2d04 12335 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12336 opn = "lwm";
3c824109
NF
12337 break;
12338 case SWM32:
895c2d04 12339 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12340 opn = "swm";
3c824109
NF
12341 break;
12342#ifdef TARGET_MIPS64
12343 case LDM:
895c2d04 12344 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12345 opn = "ldm";
3c824109
NF
12346 break;
12347 case SDM:
895c2d04 12348 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12349 opn = "sdm";
3c824109 12350 break;
6af0bf9c 12351#endif
3c824109 12352 }
e1050a76 12353 (void)opn;
3c824109
NF
12354 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12355 tcg_temp_free(t0);
33087598 12356 tcg_temp_free(t1);
3c824109
NF
12357 tcg_temp_free_i32(t2);
12358}
6af0bf9c 12359
3c824109 12360
240ce26a 12361static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12362{
3c824109
NF
12363 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12364 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12365
3c824109
NF
12366 switch (((ctx->opcode) >> 4) & 0x3f) {
12367 case NOT16 + 0:
12368 case NOT16 + 1:
12369 case NOT16 + 2:
12370 case NOT16 + 3:
d75c135e 12371 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12372 break;
12373 case XOR16 + 0:
12374 case XOR16 + 1:
12375 case XOR16 + 2:
12376 case XOR16 + 3:
d75c135e 12377 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12378 break;
12379 case AND16 + 0:
12380 case AND16 + 1:
12381 case AND16 + 2:
12382 case AND16 + 3:
d75c135e 12383 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12384 break;
12385 case OR16 + 0:
12386 case OR16 + 1:
12387 case OR16 + 2:
12388 case OR16 + 3:
d75c135e 12389 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12390 break;
12391 case LWM16 + 0:
12392 case LWM16 + 1:
12393 case LWM16 + 2:
12394 case LWM16 + 3:
12395 {
12396 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12397 int offset = ZIMM(ctx->opcode, 0, 4);
12398
12399 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12400 29, offset << 2);
12401 }
12402 break;
12403 case SWM16 + 0:
12404 case SWM16 + 1:
12405 case SWM16 + 2:
12406 case SWM16 + 3:
12407 {
12408 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12409 int offset = ZIMM(ctx->opcode, 0, 4);
12410
12411 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12412 29, offset << 2);
12413 }
12414 break;
12415 case JR16 + 0:
12416 case JR16 + 1:
12417 {
12418 int reg = ctx->opcode & 0x1f;
12419
b231c103 12420 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12421 }
3c824109
NF
12422 break;
12423 case JRC16 + 0:
12424 case JRC16 + 1:
12425 {
12426 int reg = ctx->opcode & 0x1f;
b231c103 12427 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12428 /* Let normal delay slot handling in our caller take us
12429 to the branch target. */
12430 }
12431 break;
12432 case JALR16 + 0:
12433 case JALR16 + 1:
b231c103
YK
12434 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12435 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12436 break;
3c824109
NF
12437 case JALR16S + 0:
12438 case JALR16S + 1:
b231c103
YK
12439 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12440 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12441 break;
12442 case MFHI16 + 0:
12443 case MFHI16 + 1:
26135ead 12444 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12445 break;
12446 case MFLO16 + 0:
12447 case MFLO16 + 1:
26135ead 12448 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12449 break;
12450 case BREAK16:
12451 generate_exception(ctx, EXCP_BREAK);
12452 break;
12453 case SDBBP16:
12454 /* XXX: not clear which exception should be raised
12455 * when in debug mode...
12456 */
d75c135e 12457 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12458 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12459 generate_exception(ctx, EXCP_DBp);
12460 } else {
12461 generate_exception(ctx, EXCP_DBp);
12462 }
12463 break;
12464 case JRADDIUSP + 0:
12465 case JRADDIUSP + 1:
12466 {
12467 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12468 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12469 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12470 /* Let normal delay slot handling in our caller take us
12471 to the branch target. */
12472 }
12473 break;
12474 default:
12475 generate_exception(ctx, EXCP_RI);
12476 break;
12477 }
12478}
12479
12480static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12481{
12482 TCGv t0 = tcg_temp_new();
12483 TCGv t1 = tcg_temp_new();
12484
12485 gen_load_gpr(t0, base);
12486
12487 if (index != 0) {
12488 gen_load_gpr(t1, index);
12489 tcg_gen_shli_tl(t1, t1, 2);
12490 gen_op_addr_add(ctx, t0, t1, t0);
12491 }
12492
5f68f5ae 12493 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12494 gen_store_gpr(t1, rd);
12495
12496 tcg_temp_free(t0);
12497 tcg_temp_free(t1);
12498}
12499
12500static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12501 int base, int16_t offset)
12502{
12503 const char *opn = "ldst_pair";
12504 TCGv t0, t1;
12505
36c6711b 12506 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12507 generate_exception(ctx, EXCP_RI);
d796321b
FB
12508 return;
12509 }
12510
3c824109
NF
12511 t0 = tcg_temp_new();
12512 t1 = tcg_temp_new();
8e9ade68 12513
3c824109
NF
12514 gen_base_offset_addr(ctx, t0, base, offset);
12515
12516 switch (opc) {
12517 case LWP:
36c6711b
EJ
12518 if (rd == base) {
12519 generate_exception(ctx, EXCP_RI);
12520 return;
12521 }
5f68f5ae 12522 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12523 gen_store_gpr(t1, rd);
12524 tcg_gen_movi_tl(t1, 4);
12525 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12526 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12527 gen_store_gpr(t1, rd+1);
12528 opn = "lwp";
12529 break;
12530 case SWP:
3c824109 12531 gen_load_gpr(t1, rd);
5f68f5ae 12532 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12533 tcg_gen_movi_tl(t1, 4);
12534 gen_op_addr_add(ctx, t0, t0, t1);
12535 gen_load_gpr(t1, rd+1);
5f68f5ae 12536 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12537 opn = "swp";
12538 break;
12539#ifdef TARGET_MIPS64
12540 case LDP:
36c6711b
EJ
12541 if (rd == base) {
12542 generate_exception(ctx, EXCP_RI);
12543 return;
12544 }
5f68f5ae 12545 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12546 gen_store_gpr(t1, rd);
12547 tcg_gen_movi_tl(t1, 8);
12548 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12549 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12550 gen_store_gpr(t1, rd+1);
12551 opn = "ldp";
12552 break;
12553 case SDP:
3c824109 12554 gen_load_gpr(t1, rd);
5f68f5ae 12555 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12556 tcg_gen_movi_tl(t1, 8);
12557 gen_op_addr_add(ctx, t0, t0, t1);
12558 gen_load_gpr(t1, rd+1);
5f68f5ae 12559 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12560 opn = "sdp";
12561 break;
12562#endif
6af0bf9c 12563 }
2abf314d 12564 (void)opn; /* avoid a compiler warning */
3c824109
NF
12565 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12566 tcg_temp_free(t0);
12567 tcg_temp_free(t1);
12568}
618b0fe9 12569
240ce26a 12570static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12571{
12572 int extension = (ctx->opcode >> 6) & 0x3f;
12573 int minor = (ctx->opcode >> 12) & 0xf;
12574 uint32_t mips32_op;
12575
12576 switch (extension) {
12577 case TEQ:
12578 mips32_op = OPC_TEQ;
12579 goto do_trap;
12580 case TGE:
12581 mips32_op = OPC_TGE;
12582 goto do_trap;
12583 case TGEU:
12584 mips32_op = OPC_TGEU;
12585 goto do_trap;
12586 case TLT:
12587 mips32_op = OPC_TLT;
12588 goto do_trap;
12589 case TLTU:
12590 mips32_op = OPC_TLTU;
12591 goto do_trap;
12592 case TNE:
12593 mips32_op = OPC_TNE;
12594 do_trap:
12595 gen_trap(ctx, mips32_op, rs, rt, -1);
12596 break;
12597#ifndef CONFIG_USER_ONLY
12598 case MFC0:
12599 case MFC0 + 32:
2e15497c 12600 check_cp0_enabled(ctx);
3c824109
NF
12601 if (rt == 0) {
12602 /* Treat as NOP. */
12603 break;
12604 }
d75c135e 12605 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12606 break;
12607 case MTC0:
12608 case MTC0 + 32:
2e15497c 12609 check_cp0_enabled(ctx);
3c824109
NF
12610 {
12611 TCGv t0 = tcg_temp_new();
618b0fe9 12612
3c824109 12613 gen_load_gpr(t0, rt);
d75c135e 12614 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12615 tcg_temp_free(t0);
12616 }
12617 break;
12618#endif
a1fc6246
LA
12619 case 0x2a:
12620 switch (minor & 3) {
12621 case MADD_ACC:
12622 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12623 break;
12624 case MADDU_ACC:
12625 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12626 break;
12627 case MSUB_ACC:
12628 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12629 break;
12630 case MSUBU_ACC:
12631 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12632 break;
12633 default:
12634 goto pool32axf_invalid;
12635 }
12636 break;
12637 case 0x32:
12638 switch (minor & 3) {
12639 case MULT_ACC:
12640 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12641 break;
12642 case MULTU_ACC:
12643 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12644 break;
12645 default:
12646 goto pool32axf_invalid;
12647 }
12648 break;
3c824109
NF
12649 case 0x2c:
12650 switch (minor) {
12651 case SEB:
12652 gen_bshfl(ctx, OPC_SEB, rs, rt);
12653 break;
12654 case SEH:
12655 gen_bshfl(ctx, OPC_SEH, rs, rt);
12656 break;
12657 case CLO:
12658 mips32_op = OPC_CLO;
12659 goto do_cl;
12660 case CLZ:
12661 mips32_op = OPC_CLZ;
12662 do_cl:
d75c135e 12663 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12664 gen_cl(ctx, mips32_op, rt, rs);
12665 break;
12666 case RDHWR:
d75c135e 12667 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12668 break;
12669 case WSBH:
12670 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12671 break;
12672 case MULT:
12673 mips32_op = OPC_MULT;
26135ead 12674 goto do_mul;
3c824109
NF
12675 case MULTU:
12676 mips32_op = OPC_MULTU;
26135ead 12677 goto do_mul;
3c824109
NF
12678 case DIV:
12679 mips32_op = OPC_DIV;
26135ead 12680 goto do_div;
3c824109
NF
12681 case DIVU:
12682 mips32_op = OPC_DIVU;
26135ead
RS
12683 goto do_div;
12684 do_div:
12685 check_insn(ctx, ISA_MIPS32);
12686 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12687 break;
3c824109
NF
12688 case MADD:
12689 mips32_op = OPC_MADD;
26135ead 12690 goto do_mul;
3c824109
NF
12691 case MADDU:
12692 mips32_op = OPC_MADDU;
26135ead 12693 goto do_mul;
3c824109
NF
12694 case MSUB:
12695 mips32_op = OPC_MSUB;
26135ead 12696 goto do_mul;
3c824109
NF
12697 case MSUBU:
12698 mips32_op = OPC_MSUBU;
26135ead 12699 do_mul:
d75c135e 12700 check_insn(ctx, ISA_MIPS32);
a1fc6246 12701 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12702 break;
12703 default:
12704 goto pool32axf_invalid;
12705 }
12706 break;
12707 case 0x34:
12708 switch (minor) {
12709 case MFC2:
12710 case MTC2:
12711 case MFHC2:
12712 case MTHC2:
12713 case CFC2:
12714 case CTC2:
12715 generate_exception_err(ctx, EXCP_CpU, 2);
12716 break;
12717 default:
12718 goto pool32axf_invalid;
12719 }
12720 break;
12721 case 0x3c:
12722 switch (minor) {
12723 case JALR:
12724 case JALR_HB:
b231c103
YK
12725 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12726 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12727 break;
12728 case JALRS:
12729 case JALRS_HB:
b231c103
YK
12730 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12731 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12732 break;
12733 default:
12734 goto pool32axf_invalid;
12735 }
12736 break;
12737 case 0x05:
12738 switch (minor) {
12739 case RDPGPR:
2e15497c 12740 check_cp0_enabled(ctx);
d75c135e 12741 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12742 gen_load_srsgpr(rt, rs);
12743 break;
12744 case WRPGPR:
2e15497c 12745 check_cp0_enabled(ctx);
d75c135e 12746 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12747 gen_store_srsgpr(rt, rs);
12748 break;
12749 default:
12750 goto pool32axf_invalid;
12751 }
12752 break;
12753#ifndef CONFIG_USER_ONLY
12754 case 0x0d:
12755 switch (minor) {
12756 case TLBP:
12757 mips32_op = OPC_TLBP;
12758 goto do_cp0;
12759 case TLBR:
12760 mips32_op = OPC_TLBR;
12761 goto do_cp0;
12762 case TLBWI:
12763 mips32_op = OPC_TLBWI;
12764 goto do_cp0;
12765 case TLBWR:
12766 mips32_op = OPC_TLBWR;
12767 goto do_cp0;
12768 case WAIT:
12769 mips32_op = OPC_WAIT;
12770 goto do_cp0;
12771 case DERET:
12772 mips32_op = OPC_DERET;
12773 goto do_cp0;
12774 case ERET:
12775 mips32_op = OPC_ERET;
12776 do_cp0:
12777 gen_cp0(env, ctx, mips32_op, rt, rs);
12778 break;
12779 default:
12780 goto pool32axf_invalid;
12781 }
12782 break;
12783 case 0x1d:
12784 switch (minor) {
12785 case DI:
2e15497c 12786 check_cp0_enabled(ctx);
3c824109
NF
12787 {
12788 TCGv t0 = tcg_temp_new();
12789
12790 save_cpu_state(ctx, 1);
895c2d04 12791 gen_helper_di(t0, cpu_env);
3c824109
NF
12792 gen_store_gpr(t0, rs);
12793 /* Stop translation as we may have switched the execution mode */
12794 ctx->bstate = BS_STOP;
12795 tcg_temp_free(t0);
12796 }
12797 break;
12798 case EI:
2e15497c 12799 check_cp0_enabled(ctx);
3c824109
NF
12800 {
12801 TCGv t0 = tcg_temp_new();
12802
12803 save_cpu_state(ctx, 1);
895c2d04 12804 gen_helper_ei(t0, cpu_env);
3c824109
NF
12805 gen_store_gpr(t0, rs);
12806 /* Stop translation as we may have switched the execution mode */
12807 ctx->bstate = BS_STOP;
12808 tcg_temp_free(t0);
12809 }
12810 break;
12811 default:
12812 goto pool32axf_invalid;
12813 }
12814 break;
12815#endif
12816 case 0x2d:
12817 switch (minor) {
12818 case SYNC:
12819 /* NOP */
12820 break;
12821 case SYSCALL:
12822 generate_exception(ctx, EXCP_SYSCALL);
12823 ctx->bstate = BS_STOP;
12824 break;
12825 case SDBBP:
d75c135e 12826 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12827 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12828 generate_exception(ctx, EXCP_DBp);
12829 } else {
12830 generate_exception(ctx, EXCP_DBp);
12831 }
12832 break;
12833 default:
12834 goto pool32axf_invalid;
12835 }
12836 break;
a1fc6246 12837 case 0x01:
26135ead 12838 switch (minor & 3) {
a1fc6246 12839 case MFHI_ACC:
26135ead 12840 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12841 break;
a1fc6246 12842 case MFLO_ACC:
26135ead 12843 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12844 break;
a1fc6246 12845 case MTHI_ACC:
26135ead 12846 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12847 break;
a1fc6246 12848 case MTLO_ACC:
26135ead 12849 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12850 break;
12851 default:
12852 goto pool32axf_invalid;
12853 }
12854 break;
a1fc6246
LA
12855 case 0x35:
12856 switch (minor) {
12857 case MFHI32:
12858 gen_HILO(ctx, OPC_MFHI, 0, rs);
12859 break;
12860 case MFLO32:
12861 gen_HILO(ctx, OPC_MFLO, 0, rs);
12862 break;
12863 case MTHI32:
12864 gen_HILO(ctx, OPC_MTHI, 0, rs);
12865 break;
12866 case MTLO32:
12867 gen_HILO(ctx, OPC_MTLO, 0, rs);
12868 break;
12869 default:
12870 goto pool32axf_invalid;
12871 }
12872 break;
3c824109
NF
12873 default:
12874 pool32axf_invalid:
12875 MIPS_INVAL("pool32axf");
12876 generate_exception(ctx, EXCP_RI);
12877 break;
12878 }
12879}
12880
12881/* Values for microMIPS fmt field. Variable-width, depending on which
12882 formats the instruction supports. */
12883
12884enum {
12885 FMT_SD_S = 0,
12886 FMT_SD_D = 1,
12887
12888 FMT_SDPS_S = 0,
12889 FMT_SDPS_D = 1,
12890 FMT_SDPS_PS = 2,
12891
12892 FMT_SWL_S = 0,
12893 FMT_SWL_W = 1,
12894 FMT_SWL_L = 2,
12895
12896 FMT_DWL_D = 0,
12897 FMT_DWL_W = 1,
12898 FMT_DWL_L = 2
12899};
12900
d75c135e 12901static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12902{
12903 int extension = (ctx->opcode >> 6) & 0x3ff;
12904 uint32_t mips32_op;
12905
12906#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12907#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12908#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12909
12910 switch (extension) {
12911 case FLOAT_1BIT_FMT(CFC1, 0):
12912 mips32_op = OPC_CFC1;
12913 goto do_cp1;
12914 case FLOAT_1BIT_FMT(CTC1, 0):
12915 mips32_op = OPC_CTC1;
12916 goto do_cp1;
12917 case FLOAT_1BIT_FMT(MFC1, 0):
12918 mips32_op = OPC_MFC1;
12919 goto do_cp1;
12920 case FLOAT_1BIT_FMT(MTC1, 0):
12921 mips32_op = OPC_MTC1;
12922 goto do_cp1;
12923 case FLOAT_1BIT_FMT(MFHC1, 0):
12924 mips32_op = OPC_MFHC1;
12925 goto do_cp1;
12926 case FLOAT_1BIT_FMT(MTHC1, 0):
12927 mips32_op = OPC_MTHC1;
12928 do_cp1:
12929 gen_cp1(ctx, mips32_op, rt, rs);
12930 break;
12931
12932 /* Reciprocal square root */
12933 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12934 mips32_op = OPC_RSQRT_S;
12935 goto do_unaryfp;
12936 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12937 mips32_op = OPC_RSQRT_D;
12938 goto do_unaryfp;
12939
12940 /* Square root */
12941 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12942 mips32_op = OPC_SQRT_S;
12943 goto do_unaryfp;
12944 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12945 mips32_op = OPC_SQRT_D;
12946 goto do_unaryfp;
12947
12948 /* Reciprocal */
12949 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12950 mips32_op = OPC_RECIP_S;
12951 goto do_unaryfp;
12952 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12953 mips32_op = OPC_RECIP_D;
12954 goto do_unaryfp;
12955
12956 /* Floor */
12957 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12958 mips32_op = OPC_FLOOR_L_S;
12959 goto do_unaryfp;
12960 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12961 mips32_op = OPC_FLOOR_L_D;
12962 goto do_unaryfp;
12963 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12964 mips32_op = OPC_FLOOR_W_S;
12965 goto do_unaryfp;
12966 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12967 mips32_op = OPC_FLOOR_W_D;
12968 goto do_unaryfp;
12969
12970 /* Ceiling */
12971 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12972 mips32_op = OPC_CEIL_L_S;
12973 goto do_unaryfp;
12974 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12975 mips32_op = OPC_CEIL_L_D;
12976 goto do_unaryfp;
12977 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12978 mips32_op = OPC_CEIL_W_S;
12979 goto do_unaryfp;
12980 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12981 mips32_op = OPC_CEIL_W_D;
12982 goto do_unaryfp;
12983
12984 /* Truncation */
12985 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12986 mips32_op = OPC_TRUNC_L_S;
12987 goto do_unaryfp;
12988 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12989 mips32_op = OPC_TRUNC_L_D;
12990 goto do_unaryfp;
12991 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12992 mips32_op = OPC_TRUNC_W_S;
12993 goto do_unaryfp;
12994 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12995 mips32_op = OPC_TRUNC_W_D;
12996 goto do_unaryfp;
12997
12998 /* Round */
12999 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13000 mips32_op = OPC_ROUND_L_S;
13001 goto do_unaryfp;
13002 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13003 mips32_op = OPC_ROUND_L_D;
13004 goto do_unaryfp;
13005 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13006 mips32_op = OPC_ROUND_W_S;
13007 goto do_unaryfp;
13008 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13009 mips32_op = OPC_ROUND_W_D;
13010 goto do_unaryfp;
13011
13012 /* Integer to floating-point conversion */
13013 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13014 mips32_op = OPC_CVT_L_S;
13015 goto do_unaryfp;
13016 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13017 mips32_op = OPC_CVT_L_D;
13018 goto do_unaryfp;
13019 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13020 mips32_op = OPC_CVT_W_S;
13021 goto do_unaryfp;
13022 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13023 mips32_op = OPC_CVT_W_D;
13024 goto do_unaryfp;
13025
13026 /* Paired-foo conversions */
13027 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13028 mips32_op = OPC_CVT_S_PL;
13029 goto do_unaryfp;
13030 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13031 mips32_op = OPC_CVT_S_PU;
13032 goto do_unaryfp;
13033 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13034 mips32_op = OPC_CVT_PW_PS;
13035 goto do_unaryfp;
13036 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13037 mips32_op = OPC_CVT_PS_PW;
13038 goto do_unaryfp;
13039
13040 /* Floating-point moves */
13041 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13042 mips32_op = OPC_MOV_S;
13043 goto do_unaryfp;
13044 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13045 mips32_op = OPC_MOV_D;
13046 goto do_unaryfp;
13047 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13048 mips32_op = OPC_MOV_PS;
13049 goto do_unaryfp;
13050
13051 /* Absolute value */
13052 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13053 mips32_op = OPC_ABS_S;
13054 goto do_unaryfp;
13055 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13056 mips32_op = OPC_ABS_D;
13057 goto do_unaryfp;
13058 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13059 mips32_op = OPC_ABS_PS;
13060 goto do_unaryfp;
13061
13062 /* Negation */
13063 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13064 mips32_op = OPC_NEG_S;
13065 goto do_unaryfp;
13066 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13067 mips32_op = OPC_NEG_D;
13068 goto do_unaryfp;
13069 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13070 mips32_op = OPC_NEG_PS;
13071 goto do_unaryfp;
13072
13073 /* Reciprocal square root step */
13074 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13075 mips32_op = OPC_RSQRT1_S;
13076 goto do_unaryfp;
13077 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13078 mips32_op = OPC_RSQRT1_D;
13079 goto do_unaryfp;
13080 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13081 mips32_op = OPC_RSQRT1_PS;
13082 goto do_unaryfp;
13083
13084 /* Reciprocal step */
13085 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13086 mips32_op = OPC_RECIP1_S;
13087 goto do_unaryfp;
13088 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13089 mips32_op = OPC_RECIP1_S;
13090 goto do_unaryfp;
13091 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13092 mips32_op = OPC_RECIP1_PS;
13093 goto do_unaryfp;
13094
13095 /* Conversions from double */
13096 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13097 mips32_op = OPC_CVT_D_S;
13098 goto do_unaryfp;
13099 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13100 mips32_op = OPC_CVT_D_W;
13101 goto do_unaryfp;
13102 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13103 mips32_op = OPC_CVT_D_L;
13104 goto do_unaryfp;
13105
13106 /* Conversions from single */
13107 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13108 mips32_op = OPC_CVT_S_D;
13109 goto do_unaryfp;
13110 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13111 mips32_op = OPC_CVT_S_W;
13112 goto do_unaryfp;
13113 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13114 mips32_op = OPC_CVT_S_L;
13115 do_unaryfp:
13116 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13117 break;
13118
13119 /* Conditional moves on floating-point codes */
13120 case COND_FLOAT_MOV(MOVT, 0):
13121 case COND_FLOAT_MOV(MOVT, 1):
13122 case COND_FLOAT_MOV(MOVT, 2):
13123 case COND_FLOAT_MOV(MOVT, 3):
13124 case COND_FLOAT_MOV(MOVT, 4):
13125 case COND_FLOAT_MOV(MOVT, 5):
13126 case COND_FLOAT_MOV(MOVT, 6):
13127 case COND_FLOAT_MOV(MOVT, 7):
13128 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13129 break;
13130 case COND_FLOAT_MOV(MOVF, 0):
13131 case COND_FLOAT_MOV(MOVF, 1):
13132 case COND_FLOAT_MOV(MOVF, 2):
13133 case COND_FLOAT_MOV(MOVF, 3):
13134 case COND_FLOAT_MOV(MOVF, 4):
13135 case COND_FLOAT_MOV(MOVF, 5):
13136 case COND_FLOAT_MOV(MOVF, 6):
13137 case COND_FLOAT_MOV(MOVF, 7):
13138 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13139 break;
13140 default:
13141 MIPS_INVAL("pool32fxf");
13142 generate_exception(ctx, EXCP_RI);
13143 break;
13144 }
13145}
13146
7db13fae 13147static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13148 uint16_t insn_hw1)
3c824109
NF
13149{
13150 int32_t offset;
13151 uint16_t insn;
13152 int rt, rs, rd, rr;
13153 int16_t imm;
13154 uint32_t op, minor, mips32_op;
13155 uint32_t cond, fmt, cc;
13156
895c2d04 13157 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13158 ctx->opcode = (ctx->opcode << 16) | insn;
13159
13160 rt = (ctx->opcode >> 21) & 0x1f;
13161 rs = (ctx->opcode >> 16) & 0x1f;
13162 rd = (ctx->opcode >> 11) & 0x1f;
13163 rr = (ctx->opcode >> 6) & 0x1f;
13164 imm = (int16_t) ctx->opcode;
13165
13166 op = (ctx->opcode >> 26) & 0x3f;
13167 switch (op) {
13168 case POOL32A:
13169 minor = ctx->opcode & 0x3f;
13170 switch (minor) {
13171 case 0x00:
13172 minor = (ctx->opcode >> 6) & 0xf;
13173 switch (minor) {
13174 case SLL32:
13175 mips32_op = OPC_SLL;
13176 goto do_shifti;
13177 case SRA:
13178 mips32_op = OPC_SRA;
13179 goto do_shifti;
13180 case SRL32:
13181 mips32_op = OPC_SRL;
13182 goto do_shifti;
13183 case ROTR:
13184 mips32_op = OPC_ROTR;
13185 do_shifti:
d75c135e 13186 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13187 break;
13188 default:
13189 goto pool32a_invalid;
13190 }
13191 break;
13192 case 0x10:
13193 minor = (ctx->opcode >> 6) & 0xf;
13194 switch (minor) {
13195 /* Arithmetic */
13196 case ADD:
13197 mips32_op = OPC_ADD;
13198 goto do_arith;
13199 case ADDU32:
13200 mips32_op = OPC_ADDU;
13201 goto do_arith;
13202 case SUB:
13203 mips32_op = OPC_SUB;
13204 goto do_arith;
13205 case SUBU32:
13206 mips32_op = OPC_SUBU;
13207 goto do_arith;
13208 case MUL:
13209 mips32_op = OPC_MUL;
13210 do_arith:
d75c135e 13211 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13212 break;
13213 /* Shifts */
13214 case SLLV:
13215 mips32_op = OPC_SLLV;
13216 goto do_shift;
13217 case SRLV:
13218 mips32_op = OPC_SRLV;
13219 goto do_shift;
13220 case SRAV:
13221 mips32_op = OPC_SRAV;
13222 goto do_shift;
13223 case ROTRV:
13224 mips32_op = OPC_ROTRV;
13225 do_shift:
d75c135e 13226 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13227 break;
13228 /* Logical operations */
13229 case AND:
13230 mips32_op = OPC_AND;
13231 goto do_logic;
13232 case OR32:
13233 mips32_op = OPC_OR;
13234 goto do_logic;
13235 case NOR:
13236 mips32_op = OPC_NOR;
13237 goto do_logic;
13238 case XOR32:
13239 mips32_op = OPC_XOR;
13240 do_logic:
d75c135e 13241 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13242 break;
13243 /* Set less than */
13244 case SLT:
13245 mips32_op = OPC_SLT;
13246 goto do_slt;
13247 case SLTU:
13248 mips32_op = OPC_SLTU;
13249 do_slt:
d75c135e 13250 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13251 break;
13252 default:
13253 goto pool32a_invalid;
13254 }
13255 break;
13256 case 0x18:
13257 minor = (ctx->opcode >> 6) & 0xf;
13258 switch (minor) {
13259 /* Conditional moves */
13260 case MOVN:
13261 mips32_op = OPC_MOVN;
13262 goto do_cmov;
13263 case MOVZ:
13264 mips32_op = OPC_MOVZ;
13265 do_cmov:
d75c135e 13266 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13267 break;
13268 case LWXS:
13269 gen_ldxs(ctx, rs, rt, rd);
13270 break;
13271 default:
13272 goto pool32a_invalid;
13273 }
13274 break;
13275 case INS:
13276 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13277 return;
13278 case EXT:
13279 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13280 return;
13281 case POOL32AXF:
240ce26a 13282 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13283 break;
13284 case 0x07:
13285 generate_exception(ctx, EXCP_BREAK);
13286 break;
13287 default:
13288 pool32a_invalid:
13289 MIPS_INVAL("pool32a");
13290 generate_exception(ctx, EXCP_RI);
13291 break;
13292 }
13293 break;
13294 case POOL32B:
13295 minor = (ctx->opcode >> 12) & 0xf;
13296 switch (minor) {
13297 case CACHE:
2e15497c 13298 check_cp0_enabled(ctx);
3c824109
NF
13299 /* Treat as no-op. */
13300 break;
13301 case LWC2:
13302 case SWC2:
13303 /* COP2: Not implemented. */
13304 generate_exception_err(ctx, EXCP_CpU, 2);
13305 break;
3c824109
NF
13306#ifdef TARGET_MIPS64
13307 case LDP:
13308 case SDP:
d9224450
MR
13309 check_insn(ctx, ISA_MIPS3);
13310 check_mips_64(ctx);
13311 /* Fallthrough */
3c824109 13312#endif
d9224450
MR
13313 case LWP:
13314 case SWP:
3c824109
NF
13315 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13316 break;
3c824109
NF
13317#ifdef TARGET_MIPS64
13318 case LDM:
13319 case SDM:
d9224450
MR
13320 check_insn(ctx, ISA_MIPS3);
13321 check_mips_64(ctx);
13322 /* Fallthrough */
3c824109 13323#endif
d9224450
MR
13324 case LWM32:
13325 case SWM32:
3c824109
NF
13326 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13327 break;
13328 default:
13329 MIPS_INVAL("pool32b");
13330 generate_exception(ctx, EXCP_RI);
13331 break;
13332 }
13333 break;
13334 case POOL32F:
5ab5c041 13335 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13336 minor = ctx->opcode & 0x3f;
13337 check_cp1_enabled(ctx);
13338 switch (minor) {
13339 case ALNV_PS:
13340 mips32_op = OPC_ALNV_PS;
13341 goto do_madd;
13342 case MADD_S:
13343 mips32_op = OPC_MADD_S;
13344 goto do_madd;
13345 case MADD_D:
13346 mips32_op = OPC_MADD_D;
13347 goto do_madd;
13348 case MADD_PS:
13349 mips32_op = OPC_MADD_PS;
13350 goto do_madd;
13351 case MSUB_S:
13352 mips32_op = OPC_MSUB_S;
13353 goto do_madd;
13354 case MSUB_D:
13355 mips32_op = OPC_MSUB_D;
13356 goto do_madd;
13357 case MSUB_PS:
13358 mips32_op = OPC_MSUB_PS;
13359 goto do_madd;
13360 case NMADD_S:
13361 mips32_op = OPC_NMADD_S;
13362 goto do_madd;
13363 case NMADD_D:
13364 mips32_op = OPC_NMADD_D;
13365 goto do_madd;
13366 case NMADD_PS:
13367 mips32_op = OPC_NMADD_PS;
13368 goto do_madd;
13369 case NMSUB_S:
13370 mips32_op = OPC_NMSUB_S;
13371 goto do_madd;
13372 case NMSUB_D:
13373 mips32_op = OPC_NMSUB_D;
13374 goto do_madd;
13375 case NMSUB_PS:
13376 mips32_op = OPC_NMSUB_PS;
13377 do_madd:
13378 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13379 break;
13380 case CABS_COND_FMT:
13381 cond = (ctx->opcode >> 6) & 0xf;
13382 cc = (ctx->opcode >> 13) & 0x7;
13383 fmt = (ctx->opcode >> 10) & 0x3;
13384 switch (fmt) {
13385 case 0x0:
13386 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13387 break;
13388 case 0x1:
13389 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13390 break;
13391 case 0x2:
13392 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13393 break;
13394 default:
13395 goto pool32f_invalid;
13396 }
13397 break;
13398 case C_COND_FMT:
13399 cond = (ctx->opcode >> 6) & 0xf;
13400 cc = (ctx->opcode >> 13) & 0x7;
13401 fmt = (ctx->opcode >> 10) & 0x3;
13402 switch (fmt) {
13403 case 0x0:
13404 gen_cmp_s(ctx, cond, rt, rs, cc);
13405 break;
13406 case 0x1:
13407 gen_cmp_d(ctx, cond, rt, rs, cc);
13408 break;
13409 case 0x2:
13410 gen_cmp_ps(ctx, cond, rt, rs, cc);
13411 break;
13412 default:
13413 goto pool32f_invalid;
13414 }
13415 break;
13416 case POOL32FXF:
d75c135e 13417 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13418 break;
13419 case 0x00:
13420 /* PLL foo */
13421 switch ((ctx->opcode >> 6) & 0x7) {
13422 case PLL_PS:
13423 mips32_op = OPC_PLL_PS;
13424 goto do_ps;
13425 case PLU_PS:
13426 mips32_op = OPC_PLU_PS;
13427 goto do_ps;
13428 case PUL_PS:
13429 mips32_op = OPC_PUL_PS;
13430 goto do_ps;
13431 case PUU_PS:
13432 mips32_op = OPC_PUU_PS;
13433 goto do_ps;
13434 case CVT_PS_S:
13435 mips32_op = OPC_CVT_PS_S;
13436 do_ps:
13437 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13438 break;
13439 default:
13440 goto pool32f_invalid;
13441 }
13442 break;
13443 case 0x08:
13444 /* [LS][WDU]XC1 */
13445 switch ((ctx->opcode >> 6) & 0x7) {
13446 case LWXC1:
13447 mips32_op = OPC_LWXC1;
13448 goto do_ldst_cp1;
13449 case SWXC1:
13450 mips32_op = OPC_SWXC1;
13451 goto do_ldst_cp1;
13452 case LDXC1:
13453 mips32_op = OPC_LDXC1;
13454 goto do_ldst_cp1;
13455 case SDXC1:
13456 mips32_op = OPC_SDXC1;
13457 goto do_ldst_cp1;
13458 case LUXC1:
13459 mips32_op = OPC_LUXC1;
13460 goto do_ldst_cp1;
13461 case SUXC1:
13462 mips32_op = OPC_SUXC1;
13463 do_ldst_cp1:
13464 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13465 break;
13466 default:
13467 goto pool32f_invalid;
13468 }
13469 break;
13470 case 0x18:
13471 /* 3D insns */
13472 fmt = (ctx->opcode >> 9) & 0x3;
13473 switch ((ctx->opcode >> 6) & 0x7) {
13474 case RSQRT2_FMT:
13475 switch (fmt) {
13476 case FMT_SDPS_S:
13477 mips32_op = OPC_RSQRT2_S;
13478 goto do_3d;
13479 case FMT_SDPS_D:
13480 mips32_op = OPC_RSQRT2_D;
13481 goto do_3d;
13482 case FMT_SDPS_PS:
13483 mips32_op = OPC_RSQRT2_PS;
13484 goto do_3d;
13485 default:
13486 goto pool32f_invalid;
13487 }
13488 break;
13489 case RECIP2_FMT:
13490 switch (fmt) {
13491 case FMT_SDPS_S:
13492 mips32_op = OPC_RECIP2_S;
13493 goto do_3d;
13494 case FMT_SDPS_D:
13495 mips32_op = OPC_RECIP2_D;
13496 goto do_3d;
13497 case FMT_SDPS_PS:
13498 mips32_op = OPC_RECIP2_PS;
13499 goto do_3d;
13500 default:
13501 goto pool32f_invalid;
13502 }
13503 break;
13504 case ADDR_PS:
13505 mips32_op = OPC_ADDR_PS;
13506 goto do_3d;
13507 case MULR_PS:
13508 mips32_op = OPC_MULR_PS;
13509 do_3d:
13510 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13511 break;
13512 default:
13513 goto pool32f_invalid;
13514 }
13515 break;
13516 case 0x20:
13517 /* MOV[FT].fmt and PREFX */
13518 cc = (ctx->opcode >> 13) & 0x7;
13519 fmt = (ctx->opcode >> 9) & 0x3;
13520 switch ((ctx->opcode >> 6) & 0x7) {
13521 case MOVF_FMT:
13522 switch (fmt) {
13523 case FMT_SDPS_S:
7c979afd 13524 gen_movcf_s(ctx, rs, rt, cc, 0);
3c824109
NF
13525 break;
13526 case FMT_SDPS_D:
13527 gen_movcf_d(ctx, rs, rt, cc, 0);
13528 break;
13529 case FMT_SDPS_PS:
7f6613ce 13530 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13531 break;
13532 default:
13533 goto pool32f_invalid;
13534 }
13535 break;
13536 case MOVT_FMT:
13537 switch (fmt) {
13538 case FMT_SDPS_S:
7c979afd 13539 gen_movcf_s(ctx, rs, rt, cc, 1);
3c824109
NF
13540 break;
13541 case FMT_SDPS_D:
13542 gen_movcf_d(ctx, rs, rt, cc, 1);
13543 break;
13544 case FMT_SDPS_PS:
7f6613ce 13545 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13546 break;
13547 default:
13548 goto pool32f_invalid;
13549 }
13550 break;
13551 case PREFX:
13552 break;
13553 default:
13554 goto pool32f_invalid;
13555 }
13556 break;
13557#define FINSN_3ARG_SDPS(prfx) \
13558 switch ((ctx->opcode >> 8) & 0x3) { \
13559 case FMT_SDPS_S: \
13560 mips32_op = OPC_##prfx##_S; \
13561 goto do_fpop; \
13562 case FMT_SDPS_D: \
13563 mips32_op = OPC_##prfx##_D; \
13564 goto do_fpop; \
13565 case FMT_SDPS_PS: \
13566 mips32_op = OPC_##prfx##_PS; \
13567 goto do_fpop; \
13568 default: \
13569 goto pool32f_invalid; \
13570 }
13571 case 0x30:
13572 /* regular FP ops */
13573 switch ((ctx->opcode >> 6) & 0x3) {
13574 case ADD_FMT:
13575 FINSN_3ARG_SDPS(ADD);
13576 break;
13577 case SUB_FMT:
13578 FINSN_3ARG_SDPS(SUB);
13579 break;
13580 case MUL_FMT:
13581 FINSN_3ARG_SDPS(MUL);
13582 break;
13583 case DIV_FMT:
13584 fmt = (ctx->opcode >> 8) & 0x3;
13585 if (fmt == 1) {
13586 mips32_op = OPC_DIV_D;
13587 } else if (fmt == 0) {
13588 mips32_op = OPC_DIV_S;
13589 } else {
13590 goto pool32f_invalid;
13591 }
13592 goto do_fpop;
13593 default:
13594 goto pool32f_invalid;
13595 }
13596 break;
13597 case 0x38:
13598 /* cmovs */
13599 switch ((ctx->opcode >> 6) & 0x3) {
13600 case MOVN_FMT:
13601 FINSN_3ARG_SDPS(MOVN);
13602 break;
13603 case MOVZ_FMT:
13604 FINSN_3ARG_SDPS(MOVZ);
13605 break;
13606 default:
13607 goto pool32f_invalid;
13608 }
13609 break;
13610 do_fpop:
13611 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13612 break;
13613 default:
13614 pool32f_invalid:
13615 MIPS_INVAL("pool32f");
13616 generate_exception(ctx, EXCP_RI);
13617 break;
13618 }
13619 } else {
13620 generate_exception_err(ctx, EXCP_CpU, 1);
13621 }
13622 break;
13623 case POOL32I:
13624 minor = (ctx->opcode >> 21) & 0x1f;
13625 switch (minor) {
13626 case BLTZ:
b231c103
YK
13627 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13628 break;
3c824109 13629 case BLTZAL:
b231c103
YK
13630 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13631 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13632 break;
3c824109 13633 case BLTZALS:
b231c103
YK
13634 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13635 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13636 break;
3c824109 13637 case BGEZ:
b231c103
YK
13638 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13639 break;
3c824109 13640 case BGEZAL:
b231c103
YK
13641 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13642 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13643 break;
3c824109 13644 case BGEZALS:
b231c103
YK
13645 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13646 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13647 break;
3c824109 13648 case BLEZ:
b231c103
YK
13649 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13650 break;
3c824109 13651 case BGTZ:
b231c103 13652 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13653 break;
13654
13655 /* Traps */
13656 case TLTI:
13657 mips32_op = OPC_TLTI;
13658 goto do_trapi;
13659 case TGEI:
13660 mips32_op = OPC_TGEI;
13661 goto do_trapi;
13662 case TLTIU:
13663 mips32_op = OPC_TLTIU;
13664 goto do_trapi;
13665 case TGEIU:
13666 mips32_op = OPC_TGEIU;
13667 goto do_trapi;
13668 case TNEI:
13669 mips32_op = OPC_TNEI;
13670 goto do_trapi;
13671 case TEQI:
13672 mips32_op = OPC_TEQI;
13673 do_trapi:
13674 gen_trap(ctx, mips32_op, rs, -1, imm);
13675 break;
13676
13677 case BNEZC:
13678 case BEQZC:
13679 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13680 4, rs, 0, imm << 1, 0);
3c824109
NF
13681 /* Compact branches don't have a delay slot, so just let
13682 the normal delay slot handling take us to the branch
13683 target. */
13684 break;
13685 case LUI:
5e88759a 13686 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
13687 break;
13688 case SYNCI:
a83bddd6
DZ
13689 /* Break the TB to be able to sync copied instructions
13690 immediately */
13691 ctx->bstate = BS_STOP;
3c824109
NF
13692 break;
13693 case BC2F:
13694 case BC2T:
13695 /* COP2: Not implemented. */
13696 generate_exception_err(ctx, EXCP_CpU, 2);
13697 break;
13698 case BC1F:
13699 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13700 goto do_cp1branch;
13701 case BC1T:
13702 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13703 goto do_cp1branch;
13704 case BC1ANY4F:
13705 mips32_op = OPC_BC1FANY4;
13706 goto do_cp1mips3d;
13707 case BC1ANY4T:
13708 mips32_op = OPC_BC1TANY4;
13709 do_cp1mips3d:
13710 check_cop1x(ctx);
d75c135e 13711 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13712 /* Fall through */
13713 do_cp1branch:
272f458d
MR
13714 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13715 check_cp1_enabled(ctx);
13716 gen_compute_branch1(ctx, mips32_op,
13717 (ctx->opcode >> 18) & 0x7, imm << 1);
13718 } else {
13719 generate_exception_err(ctx, EXCP_CpU, 1);
13720 }
3c824109
NF
13721 break;
13722 case BPOSGE64:
13723 case BPOSGE32:
13724 /* MIPS DSP: not implemented */
13725 /* Fall through */
13726 default:
13727 MIPS_INVAL("pool32i");
13728 generate_exception(ctx, EXCP_RI);
13729 break;
13730 }
13731 break;
13732 case POOL32C:
13733 minor = (ctx->opcode >> 12) & 0xf;
13734 switch (minor) {
13735 case LWL:
13736 mips32_op = OPC_LWL;
5c13fdfd 13737 goto do_ld_lr;
3c824109
NF
13738 case SWL:
13739 mips32_op = OPC_SWL;
5c13fdfd 13740 goto do_st_lr;
3c824109
NF
13741 case LWR:
13742 mips32_op = OPC_LWR;
5c13fdfd 13743 goto do_ld_lr;
3c824109
NF
13744 case SWR:
13745 mips32_op = OPC_SWR;
5c13fdfd 13746 goto do_st_lr;
3c824109
NF
13747#if defined(TARGET_MIPS64)
13748 case LDL:
d9224450
MR
13749 check_insn(ctx, ISA_MIPS3);
13750 check_mips_64(ctx);
3c824109 13751 mips32_op = OPC_LDL;
5c13fdfd 13752 goto do_ld_lr;
3c824109 13753 case SDL:
d9224450
MR
13754 check_insn(ctx, ISA_MIPS3);
13755 check_mips_64(ctx);
3c824109 13756 mips32_op = OPC_SDL;
5c13fdfd 13757 goto do_st_lr;
3c824109 13758 case LDR:
d9224450
MR
13759 check_insn(ctx, ISA_MIPS3);
13760 check_mips_64(ctx);
3c824109 13761 mips32_op = OPC_LDR;
5c13fdfd 13762 goto do_ld_lr;
3c824109 13763 case SDR:
d9224450
MR
13764 check_insn(ctx, ISA_MIPS3);
13765 check_mips_64(ctx);
3c824109 13766 mips32_op = OPC_SDR;
5c13fdfd 13767 goto do_st_lr;
3c824109 13768 case LWU:
d9224450
MR
13769 check_insn(ctx, ISA_MIPS3);
13770 check_mips_64(ctx);
3c824109 13771 mips32_op = OPC_LWU;
5c13fdfd 13772 goto do_ld_lr;
3c824109 13773 case LLD:
d9224450
MR
13774 check_insn(ctx, ISA_MIPS3);
13775 check_mips_64(ctx);
3c824109 13776 mips32_op = OPC_LLD;
5c13fdfd 13777 goto do_ld_lr;
3c824109
NF
13778#endif
13779 case LL:
13780 mips32_op = OPC_LL;
5c13fdfd
AJ
13781 goto do_ld_lr;
13782 do_ld_lr:
d75c135e 13783 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13784 break;
13785 do_st_lr:
13786 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13787 break;
13788 case SC:
13789 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13790 break;
13791#if defined(TARGET_MIPS64)
13792 case SCD:
d9224450
MR
13793 check_insn(ctx, ISA_MIPS3);
13794 check_mips_64(ctx);
3c824109
NF
13795 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13796 break;
13797#endif
13798 case PREF:
13799 /* Treat as no-op */
13800 break;
13801 default:
13802 MIPS_INVAL("pool32c");
13803 generate_exception(ctx, EXCP_RI);
13804 break;
13805 }
13806 break;
13807 case ADDI32:
13808 mips32_op = OPC_ADDI;
13809 goto do_addi;
13810 case ADDIU32:
13811 mips32_op = OPC_ADDIU;
13812 do_addi:
d75c135e 13813 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13814 break;
13815
13816 /* Logical operations */
13817 case ORI32:
13818 mips32_op = OPC_ORI;
13819 goto do_logici;
13820 case XORI32:
13821 mips32_op = OPC_XORI;
13822 goto do_logici;
13823 case ANDI32:
13824 mips32_op = OPC_ANDI;
13825 do_logici:
d75c135e 13826 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13827 break;
13828
13829 /* Set less than immediate */
13830 case SLTI32:
13831 mips32_op = OPC_SLTI;
13832 goto do_slti;
13833 case SLTIU32:
13834 mips32_op = OPC_SLTIU;
13835 do_slti:
d75c135e 13836 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13837 break;
13838 case JALX32:
13839 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13840 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13841 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13842 break;
13843 case JALS32:
13844 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13845 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13846 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13847 break;
13848 case BEQ32:
b231c103 13849 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13850 break;
13851 case BNE32:
b231c103 13852 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13853 break;
13854 case J32:
13855 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13856 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13857 break;
13858 case JAL32:
13859 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13860 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13861 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13862 break;
13863 /* Floating point (COP1) */
13864 case LWC132:
13865 mips32_op = OPC_LWC1;
13866 goto do_cop1;
13867 case LDC132:
13868 mips32_op = OPC_LDC1;
13869 goto do_cop1;
13870 case SWC132:
13871 mips32_op = OPC_SWC1;
13872 goto do_cop1;
13873 case SDC132:
13874 mips32_op = OPC_SDC1;
13875 do_cop1:
5ab5c041 13876 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13877 break;
13878 case ADDIUPC:
13879 {
13880 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13881 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13882
13883 gen_addiupc(ctx, reg, offset, 0, 0);
13884 }
13885 break;
13886 /* Loads and stores */
13887 case LB32:
13888 mips32_op = OPC_LB;
5c13fdfd 13889 goto do_ld;
3c824109
NF
13890 case LBU32:
13891 mips32_op = OPC_LBU;
5c13fdfd 13892 goto do_ld;
3c824109
NF
13893 case LH32:
13894 mips32_op = OPC_LH;
5c13fdfd 13895 goto do_ld;
3c824109
NF
13896 case LHU32:
13897 mips32_op = OPC_LHU;
5c13fdfd 13898 goto do_ld;
3c824109
NF
13899 case LW32:
13900 mips32_op = OPC_LW;
5c13fdfd 13901 goto do_ld;
3c824109
NF
13902#ifdef TARGET_MIPS64
13903 case LD32:
d9224450
MR
13904 check_insn(ctx, ISA_MIPS3);
13905 check_mips_64(ctx);
3c824109 13906 mips32_op = OPC_LD;
5c13fdfd 13907 goto do_ld;
3c824109 13908 case SD32:
d9224450
MR
13909 check_insn(ctx, ISA_MIPS3);
13910 check_mips_64(ctx);
3c824109 13911 mips32_op = OPC_SD;
5c13fdfd 13912 goto do_st;
3c824109
NF
13913#endif
13914 case SB32:
13915 mips32_op = OPC_SB;
5c13fdfd 13916 goto do_st;
3c824109
NF
13917 case SH32:
13918 mips32_op = OPC_SH;
5c13fdfd 13919 goto do_st;
3c824109
NF
13920 case SW32:
13921 mips32_op = OPC_SW;
5c13fdfd
AJ
13922 goto do_st;
13923 do_ld:
d75c135e 13924 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13925 break;
13926 do_st:
13927 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13928 break;
13929 default:
13930 generate_exception(ctx, EXCP_RI);
13931 break;
13932 }
13933}
13934
240ce26a 13935static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13936{
13937 uint32_t op;
13938
13939 /* make sure instructions are on a halfword boundary */
13940 if (ctx->pc & 0x1) {
13941 env->CP0_BadVAddr = ctx->pc;
13942 generate_exception(ctx, EXCP_AdEL);
13943 ctx->bstate = BS_STOP;
13944 return 2;
13945 }
13946
13947 op = (ctx->opcode >> 10) & 0x3f;
13948 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13949 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13950 switch (op & 0x7) { /* MSB-3..MSB-5 */
13951 case 0:
13952 /* POOL32A, POOL32B, POOL32I, POOL32C */
13953 case 4:
13954 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13955 case 5:
13956 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13957 case 6:
13958 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13959 case 7:
13960 /* LB32, LH32, LWC132, LDC132, LW32 */
13961 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13962 generate_exception(ctx, EXCP_RI);
13963 /* Just stop translation; the user is confused. */
13964 ctx->bstate = BS_STOP;
13965 return 2;
13966 }
13967 break;
b231c103
YK
13968 case 1:
13969 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13970 case 2:
13971 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13972 case 3:
13973 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13974 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13975 generate_exception(ctx, EXCP_RI);
13976 /* Just stop translation; the user is confused. */
13977 ctx->bstate = BS_STOP;
13978 return 2;
13979 }
13980 break;
3c824109
NF
13981 }
13982 }
b231c103 13983
3c824109
NF
13984 switch (op) {
13985 case POOL16A:
13986 {
13987 int rd = mmreg(uMIPS_RD(ctx->opcode));
13988 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13989 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13990 uint32_t opc = 0;
13991
13992 switch (ctx->opcode & 0x1) {
13993 case ADDU16:
13994 opc = OPC_ADDU;
13995 break;
13996 case SUBU16:
13997 opc = OPC_SUBU;
13998 break;
13999 }
14000
d75c135e 14001 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
14002 }
14003 break;
14004 case POOL16B:
14005 {
14006 int rd = mmreg(uMIPS_RD(ctx->opcode));
14007 int rs = mmreg(uMIPS_RS(ctx->opcode));
14008 int amount = (ctx->opcode >> 1) & 0x7;
14009 uint32_t opc = 0;
14010 amount = amount == 0 ? 8 : amount;
14011
14012 switch (ctx->opcode & 0x1) {
14013 case SLL16:
14014 opc = OPC_SLL;
14015 break;
14016 case SRL16:
14017 opc = OPC_SRL;
14018 break;
14019 }
14020
d75c135e 14021 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14022 }
14023 break;
14024 case POOL16C:
240ce26a 14025 gen_pool16c_insn(ctx);
3c824109
NF
14026 break;
14027 case LWGP16:
14028 {
14029 int rd = mmreg(uMIPS_RD(ctx->opcode));
14030 int rb = 28; /* GP */
14031 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14032
d75c135e 14033 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14034 }
14035 break;
14036 case POOL16F:
14037 if (ctx->opcode & 1) {
14038 generate_exception(ctx, EXCP_RI);
14039 } else {
14040 /* MOVEP */
14041 int enc_dest = uMIPS_RD(ctx->opcode);
14042 int enc_rt = uMIPS_RS2(ctx->opcode);
14043 int enc_rs = uMIPS_RS1(ctx->opcode);
14044 int rd, rs, re, rt;
14045 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14046 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14047 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14048
14049 rd = rd_enc[enc_dest];
14050 re = re_enc[enc_dest];
14051 rs = rs_rt_enc[enc_rs];
14052 rt = rs_rt_enc[enc_rt];
14053
7215d7e7
MR
14054 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14055 gen_arith(ctx, OPC_ADDU, re, rt, 0);
3c824109
NF
14056 }
14057 break;
14058 case LBU16:
14059 {
14060 int rd = mmreg(uMIPS_RD(ctx->opcode));
14061 int rb = mmreg(uMIPS_RS(ctx->opcode));
14062 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14063 offset = (offset == 0xf ? -1 : offset);
14064
d75c135e 14065 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14066 }
14067 break;
14068 case LHU16:
14069 {
14070 int rd = mmreg(uMIPS_RD(ctx->opcode));
14071 int rb = mmreg(uMIPS_RS(ctx->opcode));
14072 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14073
d75c135e 14074 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14075 }
14076 break;
14077 case LWSP16:
14078 {
14079 int rd = (ctx->opcode >> 5) & 0x1f;
14080 int rb = 29; /* SP */
14081 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14082
d75c135e 14083 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14084 }
14085 break;
14086 case LW16:
14087 {
14088 int rd = mmreg(uMIPS_RD(ctx->opcode));
14089 int rb = mmreg(uMIPS_RS(ctx->opcode));
14090 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14091
d75c135e 14092 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14093 }
14094 break;
14095 case SB16:
14096 {
14097 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14098 int rb = mmreg(uMIPS_RS(ctx->opcode));
14099 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14100
5c13fdfd 14101 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14102 }
14103 break;
14104 case SH16:
14105 {
14106 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14107 int rb = mmreg(uMIPS_RS(ctx->opcode));
14108 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14109
5c13fdfd 14110 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14111 }
14112 break;
14113 case SWSP16:
14114 {
14115 int rd = (ctx->opcode >> 5) & 0x1f;
14116 int rb = 29; /* SP */
14117 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14118
5c13fdfd 14119 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14120 }
14121 break;
14122 case SW16:
14123 {
14124 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14125 int rb = mmreg(uMIPS_RS(ctx->opcode));
14126 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14127
5c13fdfd 14128 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14129 }
14130 break;
14131 case MOVE16:
14132 {
14133 int rd = uMIPS_RD5(ctx->opcode);
14134 int rs = uMIPS_RS5(ctx->opcode);
14135
7215d7e7 14136 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14137 }
14138 break;
14139 case ANDI16:
d75c135e 14140 gen_andi16(ctx);
3c824109
NF
14141 break;
14142 case POOL16D:
14143 switch (ctx->opcode & 0x1) {
14144 case ADDIUS5:
d75c135e 14145 gen_addius5(ctx);
3c824109
NF
14146 break;
14147 case ADDIUSP:
d75c135e 14148 gen_addiusp(ctx);
3c824109
NF
14149 break;
14150 }
14151 break;
14152 case POOL16E:
14153 switch (ctx->opcode & 0x1) {
14154 case ADDIUR2:
d75c135e 14155 gen_addiur2(ctx);
3c824109
NF
14156 break;
14157 case ADDIUR1SP:
d75c135e 14158 gen_addiur1sp(ctx);
3c824109
NF
14159 break;
14160 }
14161 break;
14162 case B16:
14163 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14164 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14165 break;
14166 case BNEZ16:
14167 case BEQZ16:
14168 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14169 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14170 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14171 break;
14172 case LI16:
14173 {
14174 int reg = mmreg(uMIPS_RD(ctx->opcode));
14175 int imm = ZIMM(ctx->opcode, 0, 7);
14176
14177 imm = (imm == 0x7f ? -1 : imm);
14178 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14179 }
14180 break;
14181 case RES_20:
14182 case RES_28:
14183 case RES_29:
14184 case RES_30:
14185 case RES_31:
14186 case RES_38:
14187 case RES_39:
14188 generate_exception(ctx, EXCP_RI);
14189 break;
14190 default:
240ce26a 14191 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14192 return 4;
14193 }
14194
14195 return 2;
14196}
14197
14198/* SmartMIPS extension to MIPS32 */
14199
14200#if defined(TARGET_MIPS64)
14201
14202/* MDMX extension to MIPS64 */
14203
14204#endif
14205
9b1a1d68 14206/* MIPSDSP functions. */
d75c135e 14207static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14208 int rd, int base, int offset)
14209{
14210 const char *opn = "ldx";
14211 TCGv t0;
14212
9b1a1d68
JL
14213 check_dsp(ctx);
14214 t0 = tcg_temp_new();
14215
14216 if (base == 0) {
14217 gen_load_gpr(t0, offset);
14218 } else if (offset == 0) {
14219 gen_load_gpr(t0, base);
14220 } else {
14221 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14222 }
14223
9b1a1d68
JL
14224 switch (opc) {
14225 case OPC_LBUX:
5f68f5ae 14226 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14227 gen_store_gpr(t0, rd);
14228 opn = "lbux";
14229 break;
14230 case OPC_LHX:
5f68f5ae 14231 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14232 gen_store_gpr(t0, rd);
14233 opn = "lhx";
14234 break;
14235 case OPC_LWX:
5f68f5ae 14236 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14237 gen_store_gpr(t0, rd);
14238 opn = "lwx";
14239 break;
14240#if defined(TARGET_MIPS64)
14241 case OPC_LDX:
5f68f5ae 14242 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14243 gen_store_gpr(t0, rd);
14244 opn = "ldx";
14245 break;
14246#endif
14247 }
14248 (void)opn; /* avoid a compiler warning */
14249 MIPS_DEBUG("%s %s, %s(%s)", opn,
14250 regnames[rd], regnames[offset], regnames[base]);
14251 tcg_temp_free(t0);
14252}
14253
461c08df
JL
14254static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14255 int ret, int v1, int v2)
14256{
14257 const char *opn = "mipsdsp arith";
14258 TCGv v1_t;
14259 TCGv v2_t;
14260
14261 if (ret == 0) {
14262 /* Treat as NOP. */
14263 MIPS_DEBUG("NOP");
14264 return;
14265 }
14266
14267 v1_t = tcg_temp_new();
14268 v2_t = tcg_temp_new();
14269
14270 gen_load_gpr(v1_t, v1);
14271 gen_load_gpr(v2_t, v2);
14272
14273 switch (op1) {
14274 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14275 case OPC_MULT_G_2E:
14276 check_dspr2(ctx);
14277 switch (op2) {
14278 case OPC_ADDUH_QB:
14279 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14280 break;
14281 case OPC_ADDUH_R_QB:
14282 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14283 break;
14284 case OPC_ADDQH_PH:
14285 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14286 break;
14287 case OPC_ADDQH_R_PH:
14288 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14289 break;
14290 case OPC_ADDQH_W:
14291 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14292 break;
14293 case OPC_ADDQH_R_W:
14294 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14295 break;
14296 case OPC_SUBUH_QB:
14297 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14298 break;
14299 case OPC_SUBUH_R_QB:
14300 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14301 break;
14302 case OPC_SUBQH_PH:
14303 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14304 break;
14305 case OPC_SUBQH_R_PH:
14306 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14307 break;
14308 case OPC_SUBQH_W:
14309 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14310 break;
14311 case OPC_SUBQH_R_W:
14312 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14313 break;
14314 }
14315 break;
14316 case OPC_ABSQ_S_PH_DSP:
14317 switch (op2) {
14318 case OPC_ABSQ_S_QB:
14319 check_dspr2(ctx);
14320 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14321 break;
14322 case OPC_ABSQ_S_PH:
14323 check_dsp(ctx);
14324 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14325 break;
14326 case OPC_ABSQ_S_W:
14327 check_dsp(ctx);
14328 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14329 break;
14330 case OPC_PRECEQ_W_PHL:
14331 check_dsp(ctx);
14332 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14333 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14334 break;
14335 case OPC_PRECEQ_W_PHR:
14336 check_dsp(ctx);
14337 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14338 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14339 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14340 break;
14341 case OPC_PRECEQU_PH_QBL:
14342 check_dsp(ctx);
14343 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14344 break;
14345 case OPC_PRECEQU_PH_QBR:
14346 check_dsp(ctx);
14347 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14348 break;
14349 case OPC_PRECEQU_PH_QBLA:
14350 check_dsp(ctx);
14351 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14352 break;
14353 case OPC_PRECEQU_PH_QBRA:
14354 check_dsp(ctx);
14355 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14356 break;
14357 case OPC_PRECEU_PH_QBL:
14358 check_dsp(ctx);
14359 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14360 break;
14361 case OPC_PRECEU_PH_QBR:
14362 check_dsp(ctx);
14363 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14364 break;
14365 case OPC_PRECEU_PH_QBLA:
14366 check_dsp(ctx);
14367 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14368 break;
14369 case OPC_PRECEU_PH_QBRA:
14370 check_dsp(ctx);
14371 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14372 break;
14373 }
14374 break;
14375 case OPC_ADDU_QB_DSP:
14376 switch (op2) {
14377 case OPC_ADDQ_PH:
14378 check_dsp(ctx);
14379 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14380 break;
14381 case OPC_ADDQ_S_PH:
14382 check_dsp(ctx);
14383 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14384 break;
14385 case OPC_ADDQ_S_W:
14386 check_dsp(ctx);
14387 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14388 break;
14389 case OPC_ADDU_QB:
14390 check_dsp(ctx);
14391 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14392 break;
14393 case OPC_ADDU_S_QB:
14394 check_dsp(ctx);
14395 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14396 break;
14397 case OPC_ADDU_PH:
14398 check_dspr2(ctx);
14399 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14400 break;
14401 case OPC_ADDU_S_PH:
14402 check_dspr2(ctx);
14403 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14404 break;
14405 case OPC_SUBQ_PH:
14406 check_dsp(ctx);
14407 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14408 break;
14409 case OPC_SUBQ_S_PH:
14410 check_dsp(ctx);
14411 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14412 break;
14413 case OPC_SUBQ_S_W:
14414 check_dsp(ctx);
14415 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14416 break;
14417 case OPC_SUBU_QB:
14418 check_dsp(ctx);
14419 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14420 break;
14421 case OPC_SUBU_S_QB:
14422 check_dsp(ctx);
14423 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14424 break;
14425 case OPC_SUBU_PH:
14426 check_dspr2(ctx);
14427 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14428 break;
14429 case OPC_SUBU_S_PH:
14430 check_dspr2(ctx);
14431 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14432 break;
14433 case OPC_ADDSC:
14434 check_dsp(ctx);
14435 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14436 break;
14437 case OPC_ADDWC:
14438 check_dsp(ctx);
14439 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14440 break;
14441 case OPC_MODSUB:
14442 check_dsp(ctx);
14443 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14444 break;
14445 case OPC_RADDU_W_QB:
14446 check_dsp(ctx);
14447 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14448 break;
14449 }
14450 break;
14451 case OPC_CMPU_EQ_QB_DSP:
14452 switch (op2) {
14453 case OPC_PRECR_QB_PH:
14454 check_dspr2(ctx);
14455 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14456 break;
14457 case OPC_PRECRQ_QB_PH:
14458 check_dsp(ctx);
14459 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14460 break;
14461 case OPC_PRECR_SRA_PH_W:
14462 check_dspr2(ctx);
14463 {
14464 TCGv_i32 sa_t = tcg_const_i32(v2);
14465 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14466 cpu_gpr[ret]);
14467 tcg_temp_free_i32(sa_t);
14468 break;
14469 }
14470 case OPC_PRECR_SRA_R_PH_W:
14471 check_dspr2(ctx);
14472 {
14473 TCGv_i32 sa_t = tcg_const_i32(v2);
14474 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14475 cpu_gpr[ret]);
14476 tcg_temp_free_i32(sa_t);
14477 break;
14478 }
14479 case OPC_PRECRQ_PH_W:
14480 check_dsp(ctx);
14481 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14482 break;
14483 case OPC_PRECRQ_RS_PH_W:
14484 check_dsp(ctx);
14485 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14486 break;
14487 case OPC_PRECRQU_S_QB_PH:
14488 check_dsp(ctx);
14489 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14490 break;
14491 }
14492 break;
14493#ifdef TARGET_MIPS64
14494 case OPC_ABSQ_S_QH_DSP:
14495 switch (op2) {
14496 case OPC_PRECEQ_L_PWL:
14497 check_dsp(ctx);
14498 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14499 break;
14500 case OPC_PRECEQ_L_PWR:
14501 check_dsp(ctx);
14502 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14503 break;
14504 case OPC_PRECEQ_PW_QHL:
14505 check_dsp(ctx);
14506 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14507 break;
14508 case OPC_PRECEQ_PW_QHR:
14509 check_dsp(ctx);
14510 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14511 break;
14512 case OPC_PRECEQ_PW_QHLA:
14513 check_dsp(ctx);
14514 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14515 break;
14516 case OPC_PRECEQ_PW_QHRA:
14517 check_dsp(ctx);
14518 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14519 break;
14520 case OPC_PRECEQU_QH_OBL:
14521 check_dsp(ctx);
14522 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14523 break;
14524 case OPC_PRECEQU_QH_OBR:
14525 check_dsp(ctx);
14526 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14527 break;
14528 case OPC_PRECEQU_QH_OBLA:
14529 check_dsp(ctx);
14530 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14531 break;
14532 case OPC_PRECEQU_QH_OBRA:
14533 check_dsp(ctx);
14534 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14535 break;
14536 case OPC_PRECEU_QH_OBL:
14537 check_dsp(ctx);
14538 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14539 break;
14540 case OPC_PRECEU_QH_OBR:
14541 check_dsp(ctx);
14542 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14543 break;
14544 case OPC_PRECEU_QH_OBLA:
14545 check_dsp(ctx);
14546 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14547 break;
14548 case OPC_PRECEU_QH_OBRA:
14549 check_dsp(ctx);
14550 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14551 break;
14552 case OPC_ABSQ_S_OB:
14553 check_dspr2(ctx);
14554 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14555 break;
14556 case OPC_ABSQ_S_PW:
14557 check_dsp(ctx);
14558 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14559 break;
14560 case OPC_ABSQ_S_QH:
14561 check_dsp(ctx);
14562 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14563 break;
14564 }
14565 break;
14566 case OPC_ADDU_OB_DSP:
14567 switch (op2) {
14568 case OPC_RADDU_L_OB:
14569 check_dsp(ctx);
14570 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14571 break;
14572 case OPC_SUBQ_PW:
14573 check_dsp(ctx);
14574 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14575 break;
14576 case OPC_SUBQ_S_PW:
14577 check_dsp(ctx);
14578 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14579 break;
14580 case OPC_SUBQ_QH:
14581 check_dsp(ctx);
14582 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14583 break;
14584 case OPC_SUBQ_S_QH:
14585 check_dsp(ctx);
14586 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14587 break;
14588 case OPC_SUBU_OB:
14589 check_dsp(ctx);
14590 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14591 break;
14592 case OPC_SUBU_S_OB:
14593 check_dsp(ctx);
14594 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14595 break;
14596 case OPC_SUBU_QH:
14597 check_dspr2(ctx);
14598 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14599 break;
14600 case OPC_SUBU_S_QH:
14601 check_dspr2(ctx);
14602 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14603 break;
14604 case OPC_SUBUH_OB:
14605 check_dspr2(ctx);
14606 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14607 break;
14608 case OPC_SUBUH_R_OB:
14609 check_dspr2(ctx);
14610 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14611 break;
14612 case OPC_ADDQ_PW:
14613 check_dsp(ctx);
14614 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14615 break;
14616 case OPC_ADDQ_S_PW:
14617 check_dsp(ctx);
14618 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14619 break;
14620 case OPC_ADDQ_QH:
14621 check_dsp(ctx);
14622 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14623 break;
14624 case OPC_ADDQ_S_QH:
14625 check_dsp(ctx);
14626 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14627 break;
14628 case OPC_ADDU_OB:
14629 check_dsp(ctx);
14630 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14631 break;
14632 case OPC_ADDU_S_OB:
14633 check_dsp(ctx);
14634 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14635 break;
14636 case OPC_ADDU_QH:
14637 check_dspr2(ctx);
14638 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14639 break;
14640 case OPC_ADDU_S_QH:
14641 check_dspr2(ctx);
14642 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14643 break;
14644 case OPC_ADDUH_OB:
14645 check_dspr2(ctx);
14646 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14647 break;
14648 case OPC_ADDUH_R_OB:
14649 check_dspr2(ctx);
14650 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14651 break;
14652 }
14653 break;
14654 case OPC_CMPU_EQ_OB_DSP:
14655 switch (op2) {
14656 case OPC_PRECR_OB_QH:
14657 check_dspr2(ctx);
14658 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14659 break;
14660 case OPC_PRECR_SRA_QH_PW:
14661 check_dspr2(ctx);
14662 {
14663 TCGv_i32 ret_t = tcg_const_i32(ret);
14664 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14665 tcg_temp_free_i32(ret_t);
14666 break;
14667 }
14668 case OPC_PRECR_SRA_R_QH_PW:
14669 check_dspr2(ctx);
14670 {
14671 TCGv_i32 sa_v = tcg_const_i32(ret);
14672 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14673 tcg_temp_free_i32(sa_v);
14674 break;
14675 }
14676 case OPC_PRECRQ_OB_QH:
14677 check_dsp(ctx);
14678 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14679 break;
14680 case OPC_PRECRQ_PW_L:
14681 check_dsp(ctx);
14682 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14683 break;
14684 case OPC_PRECRQ_QH_PW:
14685 check_dsp(ctx);
14686 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14687 break;
14688 case OPC_PRECRQ_RS_QH_PW:
14689 check_dsp(ctx);
14690 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14691 break;
14692 case OPC_PRECRQU_S_OB_QH:
14693 check_dsp(ctx);
14694 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14695 break;
14696 }
14697 break;
14698#endif
14699 }
14700
14701 tcg_temp_free(v1_t);
14702 tcg_temp_free(v2_t);
14703
14704 (void)opn; /* avoid a compiler warning */
14705 MIPS_DEBUG("%s", opn);
14706}
9b1a1d68 14707
77c5fa8b
JL
14708static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14709 int ret, int v1, int v2)
14710{
14711 uint32_t op2;
14712 const char *opn = "mipsdsp shift";
14713 TCGv t0;
14714 TCGv v1_t;
14715 TCGv v2_t;
14716
14717 if (ret == 0) {
14718 /* Treat as NOP. */
14719 MIPS_DEBUG("NOP");
14720 return;
14721 }
14722
14723 t0 = tcg_temp_new();
14724 v1_t = tcg_temp_new();
14725 v2_t = tcg_temp_new();
14726
14727 tcg_gen_movi_tl(t0, v1);
14728 gen_load_gpr(v1_t, v1);
14729 gen_load_gpr(v2_t, v2);
14730
14731 switch (opc) {
14732 case OPC_SHLL_QB_DSP:
14733 {
14734 op2 = MASK_SHLL_QB(ctx->opcode);
14735 switch (op2) {
14736 case OPC_SHLL_QB:
14737 check_dsp(ctx);
14738 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14739 break;
14740 case OPC_SHLLV_QB:
14741 check_dsp(ctx);
14742 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14743 break;
14744 case OPC_SHLL_PH:
14745 check_dsp(ctx);
14746 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14747 break;
14748 case OPC_SHLLV_PH:
14749 check_dsp(ctx);
14750 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14751 break;
14752 case OPC_SHLL_S_PH:
14753 check_dsp(ctx);
14754 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14755 break;
14756 case OPC_SHLLV_S_PH:
14757 check_dsp(ctx);
14758 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14759 break;
14760 case OPC_SHLL_S_W:
14761 check_dsp(ctx);
14762 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14763 break;
14764 case OPC_SHLLV_S_W:
14765 check_dsp(ctx);
14766 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14767 break;
14768 case OPC_SHRL_QB:
14769 check_dsp(ctx);
14770 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14771 break;
14772 case OPC_SHRLV_QB:
14773 check_dsp(ctx);
14774 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14775 break;
14776 case OPC_SHRL_PH:
14777 check_dspr2(ctx);
14778 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14779 break;
14780 case OPC_SHRLV_PH:
14781 check_dspr2(ctx);
14782 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14783 break;
14784 case OPC_SHRA_QB:
14785 check_dspr2(ctx);
14786 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14787 break;
14788 case OPC_SHRA_R_QB:
14789 check_dspr2(ctx);
14790 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14791 break;
14792 case OPC_SHRAV_QB:
14793 check_dspr2(ctx);
14794 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14795 break;
14796 case OPC_SHRAV_R_QB:
14797 check_dspr2(ctx);
14798 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14799 break;
14800 case OPC_SHRA_PH:
14801 check_dsp(ctx);
14802 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14803 break;
14804 case OPC_SHRA_R_PH:
14805 check_dsp(ctx);
14806 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14807 break;
14808 case OPC_SHRAV_PH:
14809 check_dsp(ctx);
14810 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14811 break;
14812 case OPC_SHRAV_R_PH:
14813 check_dsp(ctx);
14814 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14815 break;
14816 case OPC_SHRA_R_W:
14817 check_dsp(ctx);
14818 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14819 break;
14820 case OPC_SHRAV_R_W:
14821 check_dsp(ctx);
14822 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14823 break;
14824 default: /* Invalid */
14825 MIPS_INVAL("MASK SHLL.QB");
14826 generate_exception(ctx, EXCP_RI);
14827 break;
14828 }
14829 break;
14830 }
14831#ifdef TARGET_MIPS64
14832 case OPC_SHLL_OB_DSP:
14833 op2 = MASK_SHLL_OB(ctx->opcode);
14834 switch (op2) {
14835 case OPC_SHLL_PW:
14836 check_dsp(ctx);
14837 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14838 break;
14839 case OPC_SHLLV_PW:
14840 check_dsp(ctx);
14841 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14842 break;
14843 case OPC_SHLL_S_PW:
14844 check_dsp(ctx);
14845 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14846 break;
14847 case OPC_SHLLV_S_PW:
14848 check_dsp(ctx);
14849 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14850 break;
14851 case OPC_SHLL_OB:
14852 check_dsp(ctx);
14853 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14854 break;
14855 case OPC_SHLLV_OB:
14856 check_dsp(ctx);
14857 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14858 break;
14859 case OPC_SHLL_QH:
14860 check_dsp(ctx);
14861 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14862 break;
14863 case OPC_SHLLV_QH:
14864 check_dsp(ctx);
14865 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14866 break;
14867 case OPC_SHLL_S_QH:
14868 check_dsp(ctx);
14869 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14870 break;
14871 case OPC_SHLLV_S_QH:
14872 check_dsp(ctx);
14873 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14874 break;
14875 case OPC_SHRA_OB:
14876 check_dspr2(ctx);
14877 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14878 break;
14879 case OPC_SHRAV_OB:
14880 check_dspr2(ctx);
14881 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14882 break;
14883 case OPC_SHRA_R_OB:
14884 check_dspr2(ctx);
14885 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14886 break;
14887 case OPC_SHRAV_R_OB:
14888 check_dspr2(ctx);
14889 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14890 break;
14891 case OPC_SHRA_PW:
14892 check_dsp(ctx);
14893 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14894 break;
14895 case OPC_SHRAV_PW:
14896 check_dsp(ctx);
14897 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14898 break;
14899 case OPC_SHRA_R_PW:
14900 check_dsp(ctx);
14901 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14902 break;
14903 case OPC_SHRAV_R_PW:
14904 check_dsp(ctx);
14905 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14906 break;
14907 case OPC_SHRA_QH:
14908 check_dsp(ctx);
14909 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14910 break;
14911 case OPC_SHRAV_QH:
14912 check_dsp(ctx);
14913 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14914 break;
14915 case OPC_SHRA_R_QH:
14916 check_dsp(ctx);
14917 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14918 break;
14919 case OPC_SHRAV_R_QH:
14920 check_dsp(ctx);
14921 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14922 break;
14923 case OPC_SHRL_OB:
14924 check_dsp(ctx);
14925 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14926 break;
14927 case OPC_SHRLV_OB:
14928 check_dsp(ctx);
14929 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14930 break;
14931 case OPC_SHRL_QH:
14932 check_dspr2(ctx);
14933 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14934 break;
14935 case OPC_SHRLV_QH:
14936 check_dspr2(ctx);
14937 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14938 break;
14939 default: /* Invalid */
14940 MIPS_INVAL("MASK SHLL.OB");
14941 generate_exception(ctx, EXCP_RI);
14942 break;
14943 }
14944 break;
14945#endif
14946 }
14947
14948 tcg_temp_free(t0);
14949 tcg_temp_free(v1_t);
14950 tcg_temp_free(v2_t);
14951 (void)opn; /* avoid a compiler warning */
14952 MIPS_DEBUG("%s", opn);
14953}
14954
a22260ae
JL
14955static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14956 int ret, int v1, int v2, int check_ret)
14957{
14958 const char *opn = "mipsdsp multiply";
14959 TCGv_i32 t0;
14960 TCGv v1_t;
14961 TCGv v2_t;
14962
14963 if ((ret == 0) && (check_ret == 1)) {
14964 /* Treat as NOP. */
14965 MIPS_DEBUG("NOP");
14966 return;
14967 }
14968
14969 t0 = tcg_temp_new_i32();
14970 v1_t = tcg_temp_new();
14971 v2_t = tcg_temp_new();
14972
14973 tcg_gen_movi_i32(t0, ret);
14974 gen_load_gpr(v1_t, v1);
14975 gen_load_gpr(v2_t, v2);
14976
14977 switch (op1) {
14978 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14979 * the same mask and op1. */
14980 case OPC_MULT_G_2E:
639eadb9 14981 check_dspr2(ctx);
a22260ae
JL
14982 switch (op2) {
14983 case OPC_MUL_PH:
14984 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14985 break;
14986 case OPC_MUL_S_PH:
14987 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14988 break;
14989 case OPC_MULQ_S_W:
14990 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14991 break;
14992 case OPC_MULQ_RS_W:
14993 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14994 break;
14995 }
14996 break;
14997 case OPC_DPA_W_PH_DSP:
14998 switch (op2) {
14999 case OPC_DPAU_H_QBL:
15000 check_dsp(ctx);
15001 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15002 break;
15003 case OPC_DPAU_H_QBR:
15004 check_dsp(ctx);
15005 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15006 break;
15007 case OPC_DPSU_H_QBL:
15008 check_dsp(ctx);
15009 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15010 break;
15011 case OPC_DPSU_H_QBR:
15012 check_dsp(ctx);
15013 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15014 break;
15015 case OPC_DPA_W_PH:
15016 check_dspr2(ctx);
15017 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15018 break;
15019 case OPC_DPAX_W_PH:
15020 check_dspr2(ctx);
15021 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15022 break;
15023 case OPC_DPAQ_S_W_PH:
15024 check_dsp(ctx);
15025 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15026 break;
15027 case OPC_DPAQX_S_W_PH:
15028 check_dspr2(ctx);
15029 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15030 break;
15031 case OPC_DPAQX_SA_W_PH:
15032 check_dspr2(ctx);
15033 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15034 break;
15035 case OPC_DPS_W_PH:
15036 check_dspr2(ctx);
15037 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15038 break;
15039 case OPC_DPSX_W_PH:
15040 check_dspr2(ctx);
15041 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15042 break;
15043 case OPC_DPSQ_S_W_PH:
15044 check_dsp(ctx);
15045 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15046 break;
15047 case OPC_DPSQX_S_W_PH:
15048 check_dspr2(ctx);
15049 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15050 break;
15051 case OPC_DPSQX_SA_W_PH:
15052 check_dspr2(ctx);
15053 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15054 break;
15055 case OPC_MULSAQ_S_W_PH:
15056 check_dsp(ctx);
15057 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15058 break;
15059 case OPC_DPAQ_SA_L_W:
15060 check_dsp(ctx);
15061 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15062 break;
15063 case OPC_DPSQ_SA_L_W:
15064 check_dsp(ctx);
15065 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15066 break;
15067 case OPC_MAQ_S_W_PHL:
15068 check_dsp(ctx);
15069 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15070 break;
15071 case OPC_MAQ_S_W_PHR:
15072 check_dsp(ctx);
15073 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15074 break;
15075 case OPC_MAQ_SA_W_PHL:
15076 check_dsp(ctx);
15077 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15078 break;
15079 case OPC_MAQ_SA_W_PHR:
15080 check_dsp(ctx);
15081 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15082 break;
15083 case OPC_MULSA_W_PH:
15084 check_dspr2(ctx);
15085 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15086 break;
15087 }
15088 break;
15089#ifdef TARGET_MIPS64
15090 case OPC_DPAQ_W_QH_DSP:
15091 {
15092 int ac = ret & 0x03;
15093 tcg_gen_movi_i32(t0, ac);
15094
15095 switch (op2) {
15096 case OPC_DMADD:
15097 check_dsp(ctx);
15098 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15099 break;
15100 case OPC_DMADDU:
15101 check_dsp(ctx);
15102 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15103 break;
15104 case OPC_DMSUB:
15105 check_dsp(ctx);
15106 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15107 break;
15108 case OPC_DMSUBU:
15109 check_dsp(ctx);
15110 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15111 break;
15112 case OPC_DPA_W_QH:
15113 check_dspr2(ctx);
15114 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15115 break;
15116 case OPC_DPAQ_S_W_QH:
15117 check_dsp(ctx);
15118 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15119 break;
15120 case OPC_DPAQ_SA_L_PW:
15121 check_dsp(ctx);
15122 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15123 break;
15124 case OPC_DPAU_H_OBL:
15125 check_dsp(ctx);
15126 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15127 break;
15128 case OPC_DPAU_H_OBR:
15129 check_dsp(ctx);
15130 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15131 break;
15132 case OPC_DPS_W_QH:
15133 check_dspr2(ctx);
15134 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15135 break;
15136 case OPC_DPSQ_S_W_QH:
15137 check_dsp(ctx);
15138 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15139 break;
15140 case OPC_DPSQ_SA_L_PW:
15141 check_dsp(ctx);
15142 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15143 break;
15144 case OPC_DPSU_H_OBL:
15145 check_dsp(ctx);
15146 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15147 break;
15148 case OPC_DPSU_H_OBR:
15149 check_dsp(ctx);
15150 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15151 break;
15152 case OPC_MAQ_S_L_PWL:
15153 check_dsp(ctx);
15154 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15155 break;
15156 case OPC_MAQ_S_L_PWR:
15157 check_dsp(ctx);
15158 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15159 break;
15160 case OPC_MAQ_S_W_QHLL:
15161 check_dsp(ctx);
15162 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15163 break;
15164 case OPC_MAQ_SA_W_QHLL:
15165 check_dsp(ctx);
15166 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15167 break;
15168 case OPC_MAQ_S_W_QHLR:
15169 check_dsp(ctx);
15170 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15171 break;
15172 case OPC_MAQ_SA_W_QHLR:
15173 check_dsp(ctx);
15174 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15175 break;
15176 case OPC_MAQ_S_W_QHRL:
15177 check_dsp(ctx);
15178 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15179 break;
15180 case OPC_MAQ_SA_W_QHRL:
15181 check_dsp(ctx);
15182 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15183 break;
15184 case OPC_MAQ_S_W_QHRR:
15185 check_dsp(ctx);
15186 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15187 break;
15188 case OPC_MAQ_SA_W_QHRR:
15189 check_dsp(ctx);
15190 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15191 break;
15192 case OPC_MULSAQ_S_L_PW:
15193 check_dsp(ctx);
15194 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15195 break;
15196 case OPC_MULSAQ_S_W_QH:
15197 check_dsp(ctx);
15198 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15199 break;
15200 }
15201 }
15202 break;
15203#endif
15204 case OPC_ADDU_QB_DSP:
15205 switch (op2) {
15206 case OPC_MULEU_S_PH_QBL:
15207 check_dsp(ctx);
15208 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15209 break;
15210 case OPC_MULEU_S_PH_QBR:
15211 check_dsp(ctx);
15212 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15213 break;
15214 case OPC_MULQ_RS_PH:
15215 check_dsp(ctx);
15216 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15217 break;
15218 case OPC_MULEQ_S_W_PHL:
15219 check_dsp(ctx);
15220 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15221 break;
15222 case OPC_MULEQ_S_W_PHR:
15223 check_dsp(ctx);
15224 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15225 break;
15226 case OPC_MULQ_S_PH:
15227 check_dspr2(ctx);
15228 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15229 break;
15230 }
15231 break;
15232#ifdef TARGET_MIPS64
15233 case OPC_ADDU_OB_DSP:
15234 switch (op2) {
15235 case OPC_MULEQ_S_PW_QHL:
15236 check_dsp(ctx);
15237 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15238 break;
15239 case OPC_MULEQ_S_PW_QHR:
15240 check_dsp(ctx);
15241 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15242 break;
15243 case OPC_MULEU_S_QH_OBL:
15244 check_dsp(ctx);
15245 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15246 break;
15247 case OPC_MULEU_S_QH_OBR:
15248 check_dsp(ctx);
15249 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15250 break;
15251 case OPC_MULQ_RS_QH:
15252 check_dsp(ctx);
15253 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15254 break;
15255 }
15256 break;
15257#endif
15258 }
15259
15260 tcg_temp_free_i32(t0);
15261 tcg_temp_free(v1_t);
15262 tcg_temp_free(v2_t);
15263
15264 (void)opn; /* avoid a compiler warning */
15265 MIPS_DEBUG("%s", opn);
15266
15267}
15268
d75c135e 15269static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15270 int ret, int val)
15271{
15272 const char *opn = "mipsdsp Bit/ Manipulation";
15273 int16_t imm;
15274 TCGv t0;
15275 TCGv val_t;
15276
15277 if (ret == 0) {
15278 /* Treat as NOP. */
15279 MIPS_DEBUG("NOP");
15280 return;
15281 }
15282
15283 t0 = tcg_temp_new();
15284 val_t = tcg_temp_new();
15285 gen_load_gpr(val_t, val);
15286
15287 switch (op1) {
15288 case OPC_ABSQ_S_PH_DSP:
15289 switch (op2) {
15290 case OPC_BITREV:
15291 check_dsp(ctx);
15292 gen_helper_bitrev(cpu_gpr[ret], val_t);
15293 break;
15294 case OPC_REPL_QB:
15295 check_dsp(ctx);
15296 {
15297 target_long result;
15298 imm = (ctx->opcode >> 16) & 0xFF;
15299 result = (uint32_t)imm << 24 |
15300 (uint32_t)imm << 16 |
15301 (uint32_t)imm << 8 |
15302 (uint32_t)imm;
15303 result = (int32_t)result;
15304 tcg_gen_movi_tl(cpu_gpr[ret], result);
15305 }
15306 break;
15307 case OPC_REPLV_QB:
15308 check_dsp(ctx);
15309 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15310 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15311 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15312 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15313 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15314 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15315 break;
15316 case OPC_REPL_PH:
15317 check_dsp(ctx);
15318 {
15319 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15320 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15321 tcg_gen_movi_tl(cpu_gpr[ret], \
15322 (target_long)((int32_t)imm << 16 | \
c4aaba92 15323 (uint16_t)imm));
1cb6686c
JL
15324 }
15325 break;
15326 case OPC_REPLV_PH:
15327 check_dsp(ctx);
15328 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15329 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15330 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15331 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15332 break;
15333 }
15334 break;
15335#ifdef TARGET_MIPS64
15336 case OPC_ABSQ_S_QH_DSP:
15337 switch (op2) {
15338 case OPC_REPL_OB:
15339 check_dsp(ctx);
15340 {
15341 target_long temp;
15342
15343 imm = (ctx->opcode >> 16) & 0xFF;
15344 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15345 temp = (temp << 16) | temp;
15346 temp = (temp << 32) | temp;
15347 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15348 break;
15349 }
15350 case OPC_REPL_PW:
15351 check_dsp(ctx);
15352 {
15353 target_long temp;
15354
15355 imm = (ctx->opcode >> 16) & 0x03FF;
15356 imm = (int16_t)(imm << 6) >> 6;
15357 temp = ((target_long)imm << 32) \
15358 | ((target_long)imm & 0xFFFFFFFF);
15359 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15360 break;
15361 }
15362 case OPC_REPL_QH:
15363 check_dsp(ctx);
15364 {
15365 target_long temp;
15366
15367 imm = (ctx->opcode >> 16) & 0x03FF;
15368 imm = (int16_t)(imm << 6) >> 6;
15369
15370 temp = ((uint64_t)(uint16_t)imm << 48) |
15371 ((uint64_t)(uint16_t)imm << 32) |
15372 ((uint64_t)(uint16_t)imm << 16) |
15373 (uint64_t)(uint16_t)imm;
15374 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15375 break;
15376 }
15377 case OPC_REPLV_OB:
15378 check_dsp(ctx);
15379 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15380 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15381 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15382 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15383 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15384 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15385 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15386 break;
15387 case OPC_REPLV_PW:
15388 check_dsp(ctx);
15389 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15390 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15391 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15392 break;
15393 case OPC_REPLV_QH:
15394 check_dsp(ctx);
15395 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15396 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15397 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15398 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15399 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15400 break;
15401 }
15402 break;
15403#endif
15404 }
15405 tcg_temp_free(t0);
15406 tcg_temp_free(val_t);
15407
15408 (void)opn; /* avoid a compiler warning */
15409 MIPS_DEBUG("%s", opn);
15410}
15411
26690560
JL
15412static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15413 uint32_t op1, uint32_t op2,
15414 int ret, int v1, int v2, int check_ret)
15415{
15416 const char *opn = "mipsdsp add compare pick";
26690560
JL
15417 TCGv t1;
15418 TCGv v1_t;
15419 TCGv v2_t;
15420
15421 if ((ret == 0) && (check_ret == 1)) {
15422 /* Treat as NOP. */
15423 MIPS_DEBUG("NOP");
15424 return;
15425 }
15426
26690560
JL
15427 t1 = tcg_temp_new();
15428 v1_t = tcg_temp_new();
15429 v2_t = tcg_temp_new();
15430
15431 gen_load_gpr(v1_t, v1);
15432 gen_load_gpr(v2_t, v2);
15433
15434 switch (op1) {
26690560
JL
15435 case OPC_CMPU_EQ_QB_DSP:
15436 switch (op2) {
15437 case OPC_CMPU_EQ_QB:
15438 check_dsp(ctx);
15439 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15440 break;
15441 case OPC_CMPU_LT_QB:
15442 check_dsp(ctx);
15443 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15444 break;
15445 case OPC_CMPU_LE_QB:
15446 check_dsp(ctx);
15447 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15448 break;
15449 case OPC_CMPGU_EQ_QB:
15450 check_dsp(ctx);
15451 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15452 break;
15453 case OPC_CMPGU_LT_QB:
15454 check_dsp(ctx);
15455 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15456 break;
15457 case OPC_CMPGU_LE_QB:
15458 check_dsp(ctx);
15459 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15460 break;
15461 case OPC_CMPGDU_EQ_QB:
15462 check_dspr2(ctx);
15463 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15464 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15465 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15466 tcg_gen_shli_tl(t1, t1, 24);
15467 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15468 break;
15469 case OPC_CMPGDU_LT_QB:
15470 check_dspr2(ctx);
15471 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15472 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15473 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15474 tcg_gen_shli_tl(t1, t1, 24);
15475 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15476 break;
15477 case OPC_CMPGDU_LE_QB:
15478 check_dspr2(ctx);
15479 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15480 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15481 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15482 tcg_gen_shli_tl(t1, t1, 24);
15483 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15484 break;
15485 case OPC_CMP_EQ_PH:
15486 check_dsp(ctx);
15487 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15488 break;
15489 case OPC_CMP_LT_PH:
15490 check_dsp(ctx);
15491 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15492 break;
15493 case OPC_CMP_LE_PH:
15494 check_dsp(ctx);
15495 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15496 break;
15497 case OPC_PICK_QB:
15498 check_dsp(ctx);
15499 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15500 break;
15501 case OPC_PICK_PH:
15502 check_dsp(ctx);
15503 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15504 break;
15505 case OPC_PACKRL_PH:
15506 check_dsp(ctx);
15507 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15508 break;
15509 }
15510 break;
15511#ifdef TARGET_MIPS64
15512 case OPC_CMPU_EQ_OB_DSP:
15513 switch (op2) {
15514 case OPC_CMP_EQ_PW:
15515 check_dsp(ctx);
15516 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15517 break;
15518 case OPC_CMP_LT_PW:
15519 check_dsp(ctx);
15520 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15521 break;
15522 case OPC_CMP_LE_PW:
15523 check_dsp(ctx);
15524 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15525 break;
15526 case OPC_CMP_EQ_QH:
15527 check_dsp(ctx);
15528 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15529 break;
15530 case OPC_CMP_LT_QH:
15531 check_dsp(ctx);
15532 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15533 break;
15534 case OPC_CMP_LE_QH:
15535 check_dsp(ctx);
15536 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15537 break;
15538 case OPC_CMPGDU_EQ_OB:
15539 check_dspr2(ctx);
15540 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15541 break;
15542 case OPC_CMPGDU_LT_OB:
15543 check_dspr2(ctx);
15544 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15545 break;
15546 case OPC_CMPGDU_LE_OB:
15547 check_dspr2(ctx);
15548 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15549 break;
15550 case OPC_CMPGU_EQ_OB:
15551 check_dsp(ctx);
15552 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15553 break;
15554 case OPC_CMPGU_LT_OB:
15555 check_dsp(ctx);
15556 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15557 break;
15558 case OPC_CMPGU_LE_OB:
15559 check_dsp(ctx);
15560 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15561 break;
15562 case OPC_CMPU_EQ_OB:
15563 check_dsp(ctx);
15564 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15565 break;
15566 case OPC_CMPU_LT_OB:
15567 check_dsp(ctx);
15568 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15569 break;
15570 case OPC_CMPU_LE_OB:
15571 check_dsp(ctx);
15572 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15573 break;
15574 case OPC_PACKRL_PW:
15575 check_dsp(ctx);
15576 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15577 break;
15578 case OPC_PICK_OB:
15579 check_dsp(ctx);
15580 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15581 break;
15582 case OPC_PICK_PW:
15583 check_dsp(ctx);
15584 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15585 break;
15586 case OPC_PICK_QH:
15587 check_dsp(ctx);
15588 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15589 break;
15590 }
15591 break;
df6126a7
AJ
15592#endif
15593 }
15594
15595 tcg_temp_free(t1);
15596 tcg_temp_free(v1_t);
15597 tcg_temp_free(v2_t);
15598
15599 (void)opn; /* avoid a compiler warning */
15600 MIPS_DEBUG("%s", opn);
15601}
15602
15603static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15604 uint32_t op1, int rt, int rs, int sa)
15605{
15606 const char *opn = "mipsdsp append/dappend";
15607 TCGv t0;
15608
15609 check_dspr2(ctx);
15610
15611 if (rt == 0) {
15612 /* Treat as NOP. */
15613 MIPS_DEBUG("NOP");
15614 return;
15615 }
15616
15617 t0 = tcg_temp_new();
15618 gen_load_gpr(t0, rs);
15619
15620 switch (op1) {
15621 case OPC_APPEND_DSP:
15622 switch (MASK_APPEND(ctx->opcode)) {
15623 case OPC_APPEND:
15624 if (sa != 0) {
15625 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15626 }
15627 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15628 break;
15629 case OPC_PREPEND:
15630 if (sa != 0) {
15631 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15632 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15633 tcg_gen_shli_tl(t0, t0, 32 - sa);
15634 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15635 }
15636 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15637 break;
15638 case OPC_BALIGN:
15639 sa &= 3;
15640 if (sa != 0 && sa != 2) {
15641 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15642 tcg_gen_ext32u_tl(t0, t0);
15643 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15644 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15645 }
15646 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15647 break;
15648 default: /* Invalid */
15649 MIPS_INVAL("MASK APPEND");
15650 generate_exception(ctx, EXCP_RI);
15651 break;
15652 }
15653 break;
15654#ifdef TARGET_MIPS64
26690560 15655 case OPC_DAPPEND_DSP:
df6126a7 15656 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15657 case OPC_DAPPEND:
df6126a7
AJ
15658 if (sa != 0) {
15659 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15660 }
26690560
JL
15661 break;
15662 case OPC_PREPENDD:
df6126a7
AJ
15663 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15664 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15665 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15666 break;
15667 case OPC_PREPENDW:
df6126a7
AJ
15668 if (sa != 0) {
15669 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15670 tcg_gen_shli_tl(t0, t0, 64 - sa);
15671 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15672 }
26690560
JL
15673 break;
15674 case OPC_DBALIGN:
df6126a7
AJ
15675 sa &= 7;
15676 if (sa != 0 && sa != 2 && sa != 4) {
15677 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15678 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15679 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15680 }
26690560
JL
15681 break;
15682 default: /* Invalid */
15683 MIPS_INVAL("MASK DAPPEND");
15684 generate_exception(ctx, EXCP_RI);
15685 break;
15686 }
15687 break;
15688#endif
15689 }
df6126a7 15690 tcg_temp_free(t0);
26690560
JL
15691 (void)opn; /* avoid a compiler warning */
15692 MIPS_DEBUG("%s", opn);
15693}
15694
b53371ed
JL
15695static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15696 int ret, int v1, int v2, int check_ret)
15697
15698{
15699 const char *opn = "mipsdsp accumulator";
15700 TCGv t0;
15701 TCGv t1;
15702 TCGv v1_t;
15703 TCGv v2_t;
15704 int16_t imm;
15705
15706 if ((ret == 0) && (check_ret == 1)) {
15707 /* Treat as NOP. */
15708 MIPS_DEBUG("NOP");
15709 return;
15710 }
15711
15712 t0 = tcg_temp_new();
15713 t1 = tcg_temp_new();
15714 v1_t = tcg_temp_new();
15715 v2_t = tcg_temp_new();
15716
15717 gen_load_gpr(v1_t, v1);
15718 gen_load_gpr(v2_t, v2);
15719
15720 switch (op1) {
15721 case OPC_EXTR_W_DSP:
15722 check_dsp(ctx);
15723 switch (op2) {
15724 case OPC_EXTR_W:
15725 tcg_gen_movi_tl(t0, v2);
15726 tcg_gen_movi_tl(t1, v1);
15727 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15728 break;
15729 case OPC_EXTR_R_W:
15730 tcg_gen_movi_tl(t0, v2);
15731 tcg_gen_movi_tl(t1, v1);
15732 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15733 break;
15734 case OPC_EXTR_RS_W:
15735 tcg_gen_movi_tl(t0, v2);
15736 tcg_gen_movi_tl(t1, v1);
15737 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15738 break;
15739 case OPC_EXTR_S_H:
15740 tcg_gen_movi_tl(t0, v2);
15741 tcg_gen_movi_tl(t1, v1);
15742 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15743 break;
15744 case OPC_EXTRV_S_H:
15745 tcg_gen_movi_tl(t0, v2);
15746 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15747 break;
15748 case OPC_EXTRV_W:
15749 tcg_gen_movi_tl(t0, v2);
15750 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15751 break;
15752 case OPC_EXTRV_R_W:
15753 tcg_gen_movi_tl(t0, v2);
15754 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15755 break;
15756 case OPC_EXTRV_RS_W:
15757 tcg_gen_movi_tl(t0, v2);
15758 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15759 break;
15760 case OPC_EXTP:
15761 tcg_gen_movi_tl(t0, v2);
15762 tcg_gen_movi_tl(t1, v1);
15763 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15764 break;
15765 case OPC_EXTPV:
15766 tcg_gen_movi_tl(t0, v2);
15767 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15768 break;
15769 case OPC_EXTPDP:
15770 tcg_gen_movi_tl(t0, v2);
15771 tcg_gen_movi_tl(t1, v1);
15772 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15773 break;
15774 case OPC_EXTPDPV:
15775 tcg_gen_movi_tl(t0, v2);
15776 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15777 break;
15778 case OPC_SHILO:
15779 imm = (ctx->opcode >> 20) & 0x3F;
15780 tcg_gen_movi_tl(t0, ret);
15781 tcg_gen_movi_tl(t1, imm);
15782 gen_helper_shilo(t0, t1, cpu_env);
15783 break;
15784 case OPC_SHILOV:
15785 tcg_gen_movi_tl(t0, ret);
15786 gen_helper_shilo(t0, v1_t, cpu_env);
15787 break;
15788 case OPC_MTHLIP:
15789 tcg_gen_movi_tl(t0, ret);
15790 gen_helper_mthlip(t0, v1_t, cpu_env);
15791 break;
15792 case OPC_WRDSP:
15793 imm = (ctx->opcode >> 11) & 0x3FF;
15794 tcg_gen_movi_tl(t0, imm);
15795 gen_helper_wrdsp(v1_t, t0, cpu_env);
15796 break;
15797 case OPC_RDDSP:
15798 imm = (ctx->opcode >> 16) & 0x03FF;
15799 tcg_gen_movi_tl(t0, imm);
15800 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15801 break;
15802 }
15803 break;
15804#ifdef TARGET_MIPS64
15805 case OPC_DEXTR_W_DSP:
15806 check_dsp(ctx);
15807 switch (op2) {
15808 case OPC_DMTHLIP:
15809 tcg_gen_movi_tl(t0, ret);
15810 gen_helper_dmthlip(v1_t, t0, cpu_env);
15811 break;
15812 case OPC_DSHILO:
15813 {
15814 int shift = (ctx->opcode >> 19) & 0x7F;
15815 int ac = (ctx->opcode >> 11) & 0x03;
15816 tcg_gen_movi_tl(t0, shift);
15817 tcg_gen_movi_tl(t1, ac);
15818 gen_helper_dshilo(t0, t1, cpu_env);
15819 break;
15820 }
15821 case OPC_DSHILOV:
15822 {
15823 int ac = (ctx->opcode >> 11) & 0x03;
15824 tcg_gen_movi_tl(t0, ac);
15825 gen_helper_dshilo(v1_t, t0, cpu_env);
15826 break;
15827 }
15828 case OPC_DEXTP:
15829 tcg_gen_movi_tl(t0, v2);
15830 tcg_gen_movi_tl(t1, v1);
15831
15832 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15833 break;
15834 case OPC_DEXTPV:
15835 tcg_gen_movi_tl(t0, v2);
15836 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15837 break;
15838 case OPC_DEXTPDP:
15839 tcg_gen_movi_tl(t0, v2);
15840 tcg_gen_movi_tl(t1, v1);
15841 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15842 break;
15843 case OPC_DEXTPDPV:
15844 tcg_gen_movi_tl(t0, v2);
15845 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15846 break;
15847 case OPC_DEXTR_L:
15848 tcg_gen_movi_tl(t0, v2);
15849 tcg_gen_movi_tl(t1, v1);
15850 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15851 break;
15852 case OPC_DEXTR_R_L:
15853 tcg_gen_movi_tl(t0, v2);
15854 tcg_gen_movi_tl(t1, v1);
15855 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15856 break;
15857 case OPC_DEXTR_RS_L:
15858 tcg_gen_movi_tl(t0, v2);
15859 tcg_gen_movi_tl(t1, v1);
15860 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15861 break;
15862 case OPC_DEXTR_W:
15863 tcg_gen_movi_tl(t0, v2);
15864 tcg_gen_movi_tl(t1, v1);
15865 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15866 break;
15867 case OPC_DEXTR_R_W:
15868 tcg_gen_movi_tl(t0, v2);
15869 tcg_gen_movi_tl(t1, v1);
15870 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15871 break;
15872 case OPC_DEXTR_RS_W:
15873 tcg_gen_movi_tl(t0, v2);
15874 tcg_gen_movi_tl(t1, v1);
15875 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15876 break;
15877 case OPC_DEXTR_S_H:
15878 tcg_gen_movi_tl(t0, v2);
15879 tcg_gen_movi_tl(t1, v1);
15880 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15881 break;
15882 case OPC_DEXTRV_S_H:
15883 tcg_gen_movi_tl(t0, v2);
15884 tcg_gen_movi_tl(t1, v1);
15885 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15886 break;
15887 case OPC_DEXTRV_L:
15888 tcg_gen_movi_tl(t0, v2);
15889 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15890 break;
15891 case OPC_DEXTRV_R_L:
15892 tcg_gen_movi_tl(t0, v2);
15893 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15894 break;
15895 case OPC_DEXTRV_RS_L:
15896 tcg_gen_movi_tl(t0, v2);
15897 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15898 break;
15899 case OPC_DEXTRV_W:
15900 tcg_gen_movi_tl(t0, v2);
15901 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15902 break;
15903 case OPC_DEXTRV_R_W:
15904 tcg_gen_movi_tl(t0, v2);
15905 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15906 break;
15907 case OPC_DEXTRV_RS_W:
15908 tcg_gen_movi_tl(t0, v2);
15909 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15910 break;
15911 }
15912 break;
15913#endif
15914 }
15915
15916 tcg_temp_free(t0);
15917 tcg_temp_free(t1);
15918 tcg_temp_free(v1_t);
15919 tcg_temp_free(v2_t);
15920
15921 (void)opn; /* avoid a compiler warning */
15922 MIPS_DEBUG("%s", opn);
15923}
15924
9b1a1d68
JL
15925/* End MIPSDSP functions. */
15926
31837be3
YK
15927/* Compact Branches */
15928static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15929 int rs, int rt, int32_t offset)
15930{
15931 int bcond_compute = 0;
15932 TCGv t0 = tcg_temp_new();
15933 TCGv t1 = tcg_temp_new();
15934
15935 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15936#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15937 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15938 "\n", ctx->pc);
31837be3
YK
15939#endif
15940 generate_exception(ctx, EXCP_RI);
15941 goto out;
15942 }
15943
15944 /* Load needed operands and calculate btarget */
15945 switch (opc) {
15946 /* compact branch */
15947 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15948 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15949 gen_load_gpr(t0, rs);
15950 gen_load_gpr(t1, rt);
15951 bcond_compute = 1;
15952 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15953 if (rs <= rt && rs == 0) {
15954 /* OPC_BEQZALC, OPC_BNEZALC */
15955 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15956 }
15957 break;
15958 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15959 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15960 gen_load_gpr(t0, rs);
15961 gen_load_gpr(t1, rt);
15962 bcond_compute = 1;
15963 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15964 break;
15965 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15966 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15967 if (rs == 0 || rs == rt) {
15968 /* OPC_BLEZALC, OPC_BGEZALC */
15969 /* OPC_BGTZALC, OPC_BLTZALC */
15970 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15971 }
15972 gen_load_gpr(t0, rs);
15973 gen_load_gpr(t1, rt);
15974 bcond_compute = 1;
15975 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15976 break;
15977 case OPC_BC:
15978 case OPC_BALC:
15979 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15980 break;
15981 case OPC_BEQZC:
15982 case OPC_BNEZC:
15983 if (rs != 0) {
15984 /* OPC_BEQZC, OPC_BNEZC */
15985 gen_load_gpr(t0, rs);
15986 bcond_compute = 1;
15987 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15988 } else {
15989 /* OPC_JIC, OPC_JIALC */
15990 TCGv tbase = tcg_temp_new();
15991 TCGv toffset = tcg_temp_new();
15992
15993 gen_load_gpr(tbase, rt);
15994 tcg_gen_movi_tl(toffset, offset);
15995 gen_op_addr_add(ctx, btarget, tbase, toffset);
15996 tcg_temp_free(tbase);
15997 tcg_temp_free(toffset);
15998 }
15999 break;
16000 default:
16001 MIPS_INVAL("Compact branch/jump");
16002 generate_exception(ctx, EXCP_RI);
16003 goto out;
16004 }
16005
16006 if (bcond_compute == 0) {
16007 /* Uncoditional compact branch */
16008 switch (opc) {
16009 case OPC_JIALC:
16010 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16011 /* Fallthrough */
16012 case OPC_JIC:
16013 ctx->hflags |= MIPS_HFLAG_BR;
16014 break;
16015 case OPC_BALC:
16016 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16017 /* Fallthrough */
16018 case OPC_BC:
16019 ctx->hflags |= MIPS_HFLAG_B;
16020 break;
16021 default:
16022 MIPS_INVAL("Compact branch/jump");
16023 generate_exception(ctx, EXCP_RI);
16024 goto out;
16025 }
16026
16027 /* Generating branch here as compact branches don't have delay slot */
16028 gen_branch(ctx, 4);
16029 } else {
16030 /* Conditional compact branch */
42a268c2 16031 TCGLabel *fs = gen_new_label();
31837be3
YK
16032 save_cpu_state(ctx, 0);
16033
16034 switch (opc) {
16035 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
16036 if (rs == 0 && rt != 0) {
16037 /* OPC_BLEZALC */
339cd2a8 16038 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16039 } else if (rs != 0 && rt != 0 && rs == rt) {
16040 /* OPC_BGEZALC */
339cd2a8 16041 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16042 } else {
16043 /* OPC_BGEUC */
339cd2a8 16044 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
16045 }
16046 break;
16047 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16048 if (rs == 0 && rt != 0) {
16049 /* OPC_BGTZALC */
339cd2a8 16050 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16051 } else if (rs != 0 && rt != 0 && rs == rt) {
16052 /* OPC_BLTZALC */
339cd2a8 16053 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16054 } else {
16055 /* OPC_BLTUC */
339cd2a8 16056 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
16057 }
16058 break;
16059 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16060 if (rs == 0 && rt != 0) {
16061 /* OPC_BLEZC */
339cd2a8 16062 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16063 } else if (rs != 0 && rt != 0 && rs == rt) {
16064 /* OPC_BGEZC */
339cd2a8 16065 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16066 } else {
16067 /* OPC_BGEC */
339cd2a8 16068 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
16069 }
16070 break;
16071 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16072 if (rs == 0 && rt != 0) {
16073 /* OPC_BGTZC */
339cd2a8 16074 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16075 } else if (rs != 0 && rt != 0 && rs == rt) {
16076 /* OPC_BLTZC */
339cd2a8 16077 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16078 } else {
16079 /* OPC_BLTC */
339cd2a8 16080 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
16081 }
16082 break;
16083 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16084 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16085 if (rs >= rt) {
16086 /* OPC_BOVC, OPC_BNVC */
16087 TCGv t2 = tcg_temp_new();
16088 TCGv t3 = tcg_temp_new();
16089 TCGv t4 = tcg_temp_new();
16090 TCGv input_overflow = tcg_temp_new();
16091
16092 gen_load_gpr(t0, rs);
16093 gen_load_gpr(t1, rt);
16094 tcg_gen_ext32s_tl(t2, t0);
16095 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
16096 tcg_gen_ext32s_tl(t3, t1);
16097 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
16098 tcg_gen_or_tl(input_overflow, input_overflow, t4);
16099
16100 tcg_gen_add_tl(t4, t2, t3);
16101 tcg_gen_ext32s_tl(t4, t4);
16102 tcg_gen_xor_tl(t2, t2, t3);
16103 tcg_gen_xor_tl(t3, t4, t3);
16104 tcg_gen_andc_tl(t2, t3, t2);
16105 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
16106 tcg_gen_or_tl(t4, t4, input_overflow);
16107 if (opc == OPC_BOVC) {
16108 /* OPC_BOVC */
339cd2a8 16109 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
16110 } else {
16111 /* OPC_BNVC */
339cd2a8 16112 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
16113 }
16114 tcg_temp_free(input_overflow);
16115 tcg_temp_free(t4);
16116 tcg_temp_free(t3);
16117 tcg_temp_free(t2);
16118 } else if (rs < rt && rs == 0) {
16119 /* OPC_BEQZALC, OPC_BNEZALC */
16120 if (opc == OPC_BEQZALC) {
16121 /* OPC_BEQZALC */
339cd2a8 16122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
16123 } else {
16124 /* OPC_BNEZALC */
339cd2a8 16125 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
16126 }
16127 } else {
16128 /* OPC_BEQC, OPC_BNEC */
16129 if (opc == OPC_BEQC) {
16130 /* OPC_BEQC */
339cd2a8 16131 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
16132 } else {
16133 /* OPC_BNEC */
339cd2a8 16134 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
16135 }
16136 }
16137 break;
16138 case OPC_BEQZC:
339cd2a8 16139 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
16140 break;
16141 case OPC_BNEZC:
339cd2a8 16142 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16143 break;
16144 default:
16145 MIPS_INVAL("Compact conditional branch/jump");
16146 generate_exception(ctx, EXCP_RI);
16147 goto out;
16148 }
16149
16150 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16151 gen_goto_tb(ctx, 1, ctx->btarget);
16152 gen_set_label(fs);
16153
16154 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16155 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16156 }
16157
16158out:
16159 tcg_temp_free(t0);
16160 tcg_temp_free(t1);
16161}
16162
10dc65db
LA
16163static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16164{
4267d3e6 16165 int rs, rt, rd, sa;
b42ee5e1 16166 uint32_t op1, op2;
10dc65db
LA
16167
16168 rs = (ctx->opcode >> 21) & 0x1f;
16169 rt = (ctx->opcode >> 16) & 0x1f;
16170 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16171 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16172
16173 op1 = MASK_SPECIAL(ctx->opcode);
16174 switch (op1) {
d4ea6acd
LA
16175 case OPC_LSA:
16176 if (rd != 0) {
16177 int imm2 = extract32(ctx->opcode, 6, 3);
16178 TCGv t0 = tcg_temp_new();
16179 TCGv t1 = tcg_temp_new();
16180 gen_load_gpr(t0, rs);
16181 gen_load_gpr(t1, rt);
16182 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16183 tcg_gen_add_tl(t0, t0, t1);
16184 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16185 tcg_temp_free(t1);
16186 tcg_temp_free(t0);
16187 }
16188 break;
b42ee5e1
LA
16189 case OPC_MULT ... OPC_DIVU:
16190 op2 = MASK_R6_MULDIV(ctx->opcode);
16191 switch (op2) {
16192 case R6_OPC_MUL:
16193 case R6_OPC_MUH:
16194 case R6_OPC_MULU:
16195 case R6_OPC_MUHU:
16196 case R6_OPC_DIV:
16197 case R6_OPC_MOD:
16198 case R6_OPC_DIVU:
16199 case R6_OPC_MODU:
16200 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16201 break;
16202 default:
16203 MIPS_INVAL("special_r6 muldiv");
16204 generate_exception(ctx, EXCP_RI);
16205 break;
16206 }
16207 break;
10dc65db
LA
16208 case OPC_SELEQZ:
16209 case OPC_SELNEZ:
16210 gen_cond_move(ctx, op1, rd, rs, rt);
16211 break;
4267d3e6
LA
16212 case R6_OPC_CLO:
16213 case R6_OPC_CLZ:
16214 if (rt == 0 && sa == 1) {
16215 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16216 We need additionally to check other fields */
16217 gen_cl(ctx, op1, rd, rs);
16218 } else {
16219 generate_exception(ctx, EXCP_RI);
16220 }
16221 break;
16222 case R6_OPC_SDBBP:
faf1f68b
LA
16223 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16224 generate_exception(ctx, EXCP_RI);
16225 } else {
16226 generate_exception(ctx, EXCP_DBp);
16227 }
4267d3e6 16228 break;
b42ee5e1 16229#if defined(TARGET_MIPS64)
d4ea6acd
LA
16230 case OPC_DLSA:
16231 check_mips_64(ctx);
16232 if (rd != 0) {
16233 int imm2 = extract32(ctx->opcode, 6, 3);
16234 TCGv t0 = tcg_temp_new();
16235 TCGv t1 = tcg_temp_new();
16236 gen_load_gpr(t0, rs);
16237 gen_load_gpr(t1, rt);
16238 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16239 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16240 tcg_temp_free(t1);
16241 tcg_temp_free(t0);
16242 }
16243 break;
4267d3e6
LA
16244 case R6_OPC_DCLO:
16245 case R6_OPC_DCLZ:
16246 if (rt == 0 && sa == 1) {
16247 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16248 We need additionally to check other fields */
16249 check_mips_64(ctx);
16250 gen_cl(ctx, op1, rd, rs);
16251 } else {
16252 generate_exception(ctx, EXCP_RI);
16253 }
16254 break;
b42ee5e1
LA
16255 case OPC_DMULT ... OPC_DDIVU:
16256 op2 = MASK_R6_MULDIV(ctx->opcode);
16257 switch (op2) {
16258 case R6_OPC_DMUL:
16259 case R6_OPC_DMUH:
16260 case R6_OPC_DMULU:
16261 case R6_OPC_DMUHU:
16262 case R6_OPC_DDIV:
16263 case R6_OPC_DMOD:
16264 case R6_OPC_DDIVU:
16265 case R6_OPC_DMODU:
16266 check_mips_64(ctx);
16267 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16268 break;
16269 default:
16270 MIPS_INVAL("special_r6 muldiv");
16271 generate_exception(ctx, EXCP_RI);
16272 break;
16273 }
16274 break;
16275#endif
10dc65db
LA
16276 default: /* Invalid */
16277 MIPS_INVAL("special_r6");
16278 generate_exception(ctx, EXCP_RI);
16279 break;
16280 }
16281}
16282
16283static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16284{
b42ee5e1 16285 int rs, rt, rd, sa;
10dc65db
LA
16286 uint32_t op1;
16287
16288 rs = (ctx->opcode >> 21) & 0x1f;
16289 rt = (ctx->opcode >> 16) & 0x1f;
16290 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16291 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16292
16293 op1 = MASK_SPECIAL(ctx->opcode);
16294 switch (op1) {
16295 case OPC_MOVN: /* Conditional move */
16296 case OPC_MOVZ:
16297 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16298 INSN_LOONGSON2E | INSN_LOONGSON2F);
16299 gen_cond_move(ctx, op1, rd, rs, rt);
16300 break;
16301 case OPC_MFHI: /* Move from HI/LO */
16302 case OPC_MFLO:
16303 gen_HILO(ctx, op1, rs & 3, rd);
16304 break;
16305 case OPC_MTHI:
16306 case OPC_MTLO: /* Move to HI/LO */
16307 gen_HILO(ctx, op1, rd & 3, rs);
16308 break;
16309 case OPC_MOVCI:
16310 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16311 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16312 check_cp1_enabled(ctx);
16313 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16314 (ctx->opcode >> 16) & 1);
16315 } else {
16316 generate_exception_err(ctx, EXCP_CpU, 1);
16317 }
16318 break;
b42ee5e1
LA
16319 case OPC_MULT:
16320 case OPC_MULTU:
16321 if (sa) {
16322 check_insn(ctx, INSN_VR54XX);
16323 op1 = MASK_MUL_VR54XX(ctx->opcode);
16324 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16325 } else {
16326 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16327 }
16328 break;
16329 case OPC_DIV:
16330 case OPC_DIVU:
16331 gen_muldiv(ctx, op1, 0, rs, rt);
16332 break;
16333#if defined(TARGET_MIPS64)
16334 case OPC_DMULT ... OPC_DDIVU:
16335 check_insn(ctx, ISA_MIPS3);
16336 check_mips_64(ctx);
16337 gen_muldiv(ctx, op1, 0, rs, rt);
16338 break;
16339#endif
0aefa333 16340 case OPC_JR:
b231c103 16341 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16342 break;
4267d3e6
LA
16343 case OPC_SPIM:
16344#ifdef MIPS_STRICT_STANDARD
16345 MIPS_INVAL("SPIM");
16346 generate_exception(ctx, EXCP_RI);
16347#else
16348 /* Implemented as RI exception for now. */
16349 MIPS_INVAL("spim (unofficial)");
16350 generate_exception(ctx, EXCP_RI);
16351#endif
16352 break;
10dc65db
LA
16353 default: /* Invalid */
16354 MIPS_INVAL("special_legacy");
16355 generate_exception(ctx, EXCP_RI);
16356 break;
16357 }
16358}
16359
099e5b4d 16360static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16361{
3c824109 16362 int rs, rt, rd, sa;
099e5b4d 16363 uint32_t op1;
3c824109 16364
3c824109
NF
16365 rs = (ctx->opcode >> 21) & 0x1f;
16366 rt = (ctx->opcode >> 16) & 0x1f;
16367 rd = (ctx->opcode >> 11) & 0x1f;
16368 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16369
16370 op1 = MASK_SPECIAL(ctx->opcode);
16371 switch (op1) {
16372 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16373 if (sa == 5 && rd == 0 &&
16374 rs == 0 && rt == 0) { /* PAUSE */
16375 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16376 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16377 MIPS_DEBUG("CTI in delay / forbidden slot");
16378 generate_exception(ctx, EXCP_RI);
16379 break;
16380 }
16381 }
16382 /* Fallthrough */
099e5b4d
LA
16383 case OPC_SRA:
16384 gen_shift_imm(ctx, op1, rd, rt, sa);
16385 break;
16386 case OPC_SRL:
16387 switch ((ctx->opcode >> 21) & 0x1f) {
16388 case 1:
16389 /* rotr is decoded as srl on non-R2 CPUs */
16390 if (ctx->insn_flags & ISA_MIPS32R2) {
16391 op1 = OPC_ROTR;
ea63e2c3 16392 }
099e5b4d
LA
16393 /* Fallthrough */
16394 case 0:
16395 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16396 break;
099e5b4d
LA
16397 default:
16398 generate_exception(ctx, EXCP_RI);
ea63e2c3 16399 break;
099e5b4d
LA
16400 }
16401 break;
099e5b4d
LA
16402 case OPC_ADD ... OPC_SUBU:
16403 gen_arith(ctx, op1, rd, rs, rt);
16404 break;
16405 case OPC_SLLV: /* Shifts */
16406 case OPC_SRAV:
16407 gen_shift(ctx, op1, rd, rs, rt);
16408 break;
16409 case OPC_SRLV:
16410 switch ((ctx->opcode >> 6) & 0x1f) {
16411 case 1:
16412 /* rotrv is decoded as srlv on non-R2 CPUs */
16413 if (ctx->insn_flags & ISA_MIPS32R2) {
16414 op1 = OPC_ROTRV;
26135ead 16415 }
099e5b4d
LA
16416 /* Fallthrough */
16417 case 0:
16418 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16419 break;
099e5b4d
LA
16420 default:
16421 generate_exception(ctx, EXCP_RI);
6af0bf9c 16422 break;
099e5b4d
LA
16423 }
16424 break;
16425 case OPC_SLT: /* Set on less than */
16426 case OPC_SLTU:
16427 gen_slt(ctx, op1, rd, rs, rt);
16428 break;
16429 case OPC_AND: /* Logic*/
16430 case OPC_OR:
16431 case OPC_NOR:
16432 case OPC_XOR:
16433 gen_logic(ctx, op1, rd, rs, rt);
16434 break;
0aefa333 16435 case OPC_JALR:
b231c103 16436 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16437 break;
16438 case OPC_TGE ... OPC_TEQ: /* Traps */
16439 case OPC_TNE:
d9224450 16440 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16441 gen_trap(ctx, op1, rs, rt, -1);
16442 break;
d4ea6acd 16443 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16444 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16445 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16446 decode_opc_special_r6(env, ctx);
16447 } else {
16448 /* Pmon entry point, also R4010 selsl */
b48cfdff 16449#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16450 MIPS_INVAL("PMON / selsl");
16451 generate_exception(ctx, EXCP_RI);
b48cfdff 16452#else
d4ea6acd 16453 gen_helper_0e0i(pmon, sa);
b48cfdff 16454#endif
d4ea6acd 16455 }
099e5b4d
LA
16456 break;
16457 case OPC_SYSCALL:
16458 generate_exception(ctx, EXCP_SYSCALL);
16459 ctx->bstate = BS_STOP;
16460 break;
16461 case OPC_BREAK:
16462 generate_exception(ctx, EXCP_BREAK);
16463 break;
099e5b4d 16464 case OPC_SYNC:
d9224450 16465 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16466 /* Treat as NOP. */
16467 break;
4ad40f36 16468
d26bc211 16469#if defined(TARGET_MIPS64)
099e5b4d
LA
16470 /* MIPS64 specific opcodes */
16471 case OPC_DSLL:
16472 case OPC_DSRA:
16473 case OPC_DSLL32:
16474 case OPC_DSRA32:
16475 check_insn(ctx, ISA_MIPS3);
16476 check_mips_64(ctx);
16477 gen_shift_imm(ctx, op1, rd, rt, sa);
16478 break;
16479 case OPC_DSRL:
16480 switch ((ctx->opcode >> 21) & 0x1f) {
16481 case 1:
16482 /* drotr is decoded as dsrl on non-R2 CPUs */
16483 if (ctx->insn_flags & ISA_MIPS32R2) {
16484 op1 = OPC_DROTR;
ea63e2c3 16485 }
099e5b4d
LA
16486 /* Fallthrough */
16487 case 0:
d75c135e 16488 check_insn(ctx, ISA_MIPS3);
e189e748 16489 check_mips_64(ctx);
099e5b4d 16490 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16491 break;
099e5b4d
LA
16492 default:
16493 generate_exception(ctx, EXCP_RI);
460f00c4 16494 break;
099e5b4d
LA
16495 }
16496 break;
16497 case OPC_DSRL32:
16498 switch ((ctx->opcode >> 21) & 0x1f) {
16499 case 1:
16500 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16501 if (ctx->insn_flags & ISA_MIPS32R2) {
16502 op1 = OPC_DROTR32;
ea63e2c3 16503 }
099e5b4d
LA
16504 /* Fallthrough */
16505 case 0:
d75c135e 16506 check_insn(ctx, ISA_MIPS3);
e189e748 16507 check_mips_64(ctx);
099e5b4d 16508 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16509 break;
099e5b4d 16510 default:
6af0bf9c
FB
16511 generate_exception(ctx, EXCP_RI);
16512 break;
16513 }
16514 break;
099e5b4d
LA
16515 case OPC_DADD ... OPC_DSUBU:
16516 check_insn(ctx, ISA_MIPS3);
16517 check_mips_64(ctx);
16518 gen_arith(ctx, op1, rd, rs, rt);
16519 break;
16520 case OPC_DSLLV:
16521 case OPC_DSRAV:
16522 check_insn(ctx, ISA_MIPS3);
16523 check_mips_64(ctx);
16524 gen_shift(ctx, op1, rd, rs, rt);
16525 break;
16526 case OPC_DSRLV:
16527 switch ((ctx->opcode >> 6) & 0x1f) {
16528 case 1:
16529 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16530 if (ctx->insn_flags & ISA_MIPS32R2) {
16531 op1 = OPC_DROTRV;
6af0bf9c 16532 }
099e5b4d
LA
16533 /* Fallthrough */
16534 case 0:
16535 check_insn(ctx, ISA_MIPS3);
e189e748 16536 check_mips_64(ctx);
099e5b4d 16537 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16538 break;
099e5b4d 16539 default:
6af0bf9c
FB
16540 generate_exception(ctx, EXCP_RI);
16541 break;
16542 }
16543 break;
f7685877
YK
16544 case OPC_DLSA:
16545 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16546 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16547 decode_opc_special_r6(env, ctx);
16548 }
16549 break;
099e5b4d 16550#endif
10dc65db
LA
16551 default:
16552 if (ctx->insn_flags & ISA_MIPS32R6) {
16553 decode_opc_special_r6(env, ctx);
16554 } else {
16555 decode_opc_special_legacy(env, ctx);
16556 }
16557 }
16558}
16559
10dc65db 16560static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16561{
16562 int rs, rt, rd;
16563 uint32_t op1;
6c5c1e20 16564
4267d3e6
LA
16565 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16566
099e5b4d
LA
16567 rs = (ctx->opcode >> 21) & 0x1f;
16568 rt = (ctx->opcode >> 16) & 0x1f;
16569 rd = (ctx->opcode >> 11) & 0x1f;
16570
16571 op1 = MASK_SPECIAL2(ctx->opcode);
16572 switch (op1) {
16573 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16574 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16575 check_insn(ctx, ISA_MIPS32);
16576 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16577 break;
16578 case OPC_MUL:
099e5b4d
LA
16579 gen_arith(ctx, op1, rd, rs, rt);
16580 break;
fac5a073
LA
16581 case OPC_DIV_G_2F:
16582 case OPC_DIVU_G_2F:
16583 case OPC_MULT_G_2F:
16584 case OPC_MULTU_G_2F:
16585 case OPC_MOD_G_2F:
16586 case OPC_MODU_G_2F:
16587 check_insn(ctx, INSN_LOONGSON2F);
16588 gen_loongson_integer(ctx, op1, rd, rs, rt);
16589 break;
099e5b4d
LA
16590 case OPC_CLO:
16591 case OPC_CLZ:
16592 check_insn(ctx, ISA_MIPS32);
16593 gen_cl(ctx, op1, rd, rs);
16594 break;
16595 case OPC_SDBBP:
16596 /* XXX: not clear which exception should be raised
16597 * when in debug mode...
16598 */
16599 check_insn(ctx, ISA_MIPS32);
16600 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16601 generate_exception(ctx, EXCP_DBp);
16602 } else {
16603 generate_exception(ctx, EXCP_DBp);
16604 }
16605 /* Treat as NOP. */
16606 break;
9b1a1d68 16607#if defined(TARGET_MIPS64)
099e5b4d
LA
16608 case OPC_DCLO:
16609 case OPC_DCLZ:
16610 check_insn(ctx, ISA_MIPS64);
16611 check_mips_64(ctx);
16612 gen_cl(ctx, op1, rd, rs);
16613 break;
4267d3e6
LA
16614 case OPC_DMULT_G_2F:
16615 case OPC_DMULTU_G_2F:
16616 case OPC_DDIV_G_2F:
16617 case OPC_DDIVU_G_2F:
16618 case OPC_DMOD_G_2F:
16619 case OPC_DMODU_G_2F:
16620 check_insn(ctx, INSN_LOONGSON2F);
16621 gen_loongson_integer(ctx, op1, rd, rs, rt);
16622 break;
10dc65db 16623#endif
4267d3e6
LA
16624 default: /* Invalid */
16625 MIPS_INVAL("special2_legacy");
16626 generate_exception(ctx, EXCP_RI);
16627 break;
10dc65db
LA
16628 }
16629}
16630
16631static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16632{
15eacb9b
YK
16633 int rs, rt, rd, sa;
16634 uint32_t op1, op2;
10dc65db
LA
16635 int16_t imm;
16636
16637 rs = (ctx->opcode >> 21) & 0x1f;
16638 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16639 rd = (ctx->opcode >> 11) & 0x1f;
16640 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16641 imm = (int16_t)ctx->opcode >> 7;
16642
16643 op1 = MASK_SPECIAL3(ctx->opcode);
16644 switch (op1) {
bf7910c6
LA
16645 case R6_OPC_PREF:
16646 if (rt >= 24) {
16647 /* hint codes 24-31 are reserved and signal RI */
16648 generate_exception(ctx, EXCP_RI);
16649 }
16650 /* Treat as NOP. */
16651 break;
16652 case R6_OPC_CACHE:
16653 /* Treat as NOP. */
16654 break;
10dc65db
LA
16655 case R6_OPC_SC:
16656 gen_st_cond(ctx, op1, rt, rs, imm);
16657 break;
16658 case R6_OPC_LL:
16659 gen_ld(ctx, op1, rt, rs, imm);
16660 break;
15eacb9b
YK
16661 case OPC_BSHFL:
16662 {
16663 if (rd == 0) {
16664 /* Treat as NOP. */
16665 break;
16666 }
16667 TCGv t0 = tcg_temp_new();
16668 gen_load_gpr(t0, rt);
16669
16670 op2 = MASK_BSHFL(ctx->opcode);
16671 switch (op2) {
16672 case OPC_ALIGN ... OPC_ALIGN_END:
16673 sa &= 3;
16674 if (sa == 0) {
16675 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16676 } else {
16677 TCGv t1 = tcg_temp_new();
16678 TCGv_i64 t2 = tcg_temp_new_i64();
16679 gen_load_gpr(t1, rs);
16680 tcg_gen_concat_tl_i64(t2, t1, t0);
16681 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16682#if defined(TARGET_MIPS64)
16683 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16684#else
16685 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16686#endif
16687 tcg_temp_free_i64(t2);
16688 tcg_temp_free(t1);
16689 }
16690 break;
16691 case OPC_BITSWAP:
16692 gen_helper_bitswap(cpu_gpr[rd], t0);
16693 break;
16694 }
16695 tcg_temp_free(t0);
16696 }
16697 break;
bf7910c6
LA
16698#if defined(TARGET_MIPS64)
16699 case R6_OPC_SCD:
16700 gen_st_cond(ctx, op1, rt, rs, imm);
16701 break;
16702 case R6_OPC_LLD:
16703 gen_ld(ctx, op1, rt, rs, imm);
16704 break;
15eacb9b
YK
16705 case OPC_DBSHFL:
16706 check_mips_64(ctx);
16707 {
16708 if (rd == 0) {
16709 /* Treat as NOP. */
16710 break;
16711 }
16712 TCGv t0 = tcg_temp_new();
16713 gen_load_gpr(t0, rt);
16714
16715 op2 = MASK_DBSHFL(ctx->opcode);
16716 switch (op2) {
16717 case OPC_DALIGN ... OPC_DALIGN_END:
16718 sa &= 7;
16719 if (sa == 0) {
16720 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16721 } else {
16722 TCGv t1 = tcg_temp_new();
16723 gen_load_gpr(t1, rs);
16724 tcg_gen_shli_tl(t0, t0, 8 * sa);
16725 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16726 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16727 tcg_temp_free(t1);
16728 }
16729 break;
16730 case OPC_DBITSWAP:
16731 gen_helper_dbitswap(cpu_gpr[rd], t0);
16732 break;
16733 }
16734 tcg_temp_free(t0);
16735 }
16736 break;
bf7910c6 16737#endif
10dc65db
LA
16738 default: /* Invalid */
16739 MIPS_INVAL("special3_r6");
16740 generate_exception(ctx, EXCP_RI);
16741 break;
16742 }
16743}
16744
16745static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16746{
fac5a073 16747 int rs, rt, rd;
099e5b4d 16748 uint32_t op1, op2;
099e5b4d
LA
16749
16750 rs = (ctx->opcode >> 21) & 0x1f;
16751 rt = (ctx->opcode >> 16) & 0x1f;
16752 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16753
16754 op1 = MASK_SPECIAL3(ctx->opcode);
16755 switch (op1) {
099e5b4d
LA
16756 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16757 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16758 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16759 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16760 * the same mask and op1. */
16761 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16762 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16763 switch (op2) {
099e5b4d
LA
16764 case OPC_ADDUH_QB:
16765 case OPC_ADDUH_R_QB:
16766 case OPC_ADDQH_PH:
16767 case OPC_ADDQH_R_PH:
16768 case OPC_ADDQH_W:
16769 case OPC_ADDQH_R_W:
16770 case OPC_SUBUH_QB:
16771 case OPC_SUBUH_R_QB:
16772 case OPC_SUBQH_PH:
16773 case OPC_SUBQH_R_PH:
16774 case OPC_SUBQH_W:
16775 case OPC_SUBQH_R_W:
461c08df
JL
16776 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16777 break;
099e5b4d
LA
16778 case OPC_MUL_PH:
16779 case OPC_MUL_S_PH:
16780 case OPC_MULQ_S_W:
16781 case OPC_MULQ_RS_W:
16782 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16783 break;
461c08df 16784 default:
099e5b4d 16785 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16786 generate_exception(ctx, EXCP_RI);
16787 break;
16788 }
099e5b4d
LA
16789 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16790 gen_loongson_integer(ctx, op1, rd, rs, rt);
16791 } else {
16792 generate_exception(ctx, EXCP_RI);
16793 }
16794 break;
16795 case OPC_LX_DSP:
16796 op2 = MASK_LX(ctx->opcode);
16797 switch (op2) {
16798#if defined(TARGET_MIPS64)
16799 case OPC_LDX:
16800#endif
16801 case OPC_LBUX:
16802 case OPC_LHX:
16803 case OPC_LWX:
16804 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16805 break;
16806 default: /* Invalid */
16807 MIPS_INVAL("MASK LX");
16808 generate_exception(ctx, EXCP_RI);
16809 break;
16810 }
16811 break;
16812 case OPC_ABSQ_S_PH_DSP:
16813 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16814 switch (op2) {
16815 case OPC_ABSQ_S_QB:
16816 case OPC_ABSQ_S_PH:
16817 case OPC_ABSQ_S_W:
16818 case OPC_PRECEQ_W_PHL:
16819 case OPC_PRECEQ_W_PHR:
16820 case OPC_PRECEQU_PH_QBL:
16821 case OPC_PRECEQU_PH_QBR:
16822 case OPC_PRECEQU_PH_QBLA:
16823 case OPC_PRECEQU_PH_QBRA:
16824 case OPC_PRECEU_PH_QBL:
16825 case OPC_PRECEU_PH_QBR:
16826 case OPC_PRECEU_PH_QBLA:
16827 case OPC_PRECEU_PH_QBRA:
16828 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16829 break;
16830 case OPC_BITREV:
16831 case OPC_REPL_QB:
16832 case OPC_REPLV_QB:
16833 case OPC_REPL_PH:
16834 case OPC_REPLV_PH:
16835 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16836 break;
16837 default:
16838 MIPS_INVAL("MASK ABSQ_S.PH");
16839 generate_exception(ctx, EXCP_RI);
16840 break;
16841 }
16842 break;
16843 case OPC_ADDU_QB_DSP:
16844 op2 = MASK_ADDU_QB(ctx->opcode);
16845 switch (op2) {
16846 case OPC_ADDQ_PH:
16847 case OPC_ADDQ_S_PH:
16848 case OPC_ADDQ_S_W:
16849 case OPC_ADDU_QB:
16850 case OPC_ADDU_S_QB:
16851 case OPC_ADDU_PH:
16852 case OPC_ADDU_S_PH:
16853 case OPC_SUBQ_PH:
16854 case OPC_SUBQ_S_PH:
16855 case OPC_SUBQ_S_W:
16856 case OPC_SUBU_QB:
16857 case OPC_SUBU_S_QB:
16858 case OPC_SUBU_PH:
16859 case OPC_SUBU_S_PH:
16860 case OPC_ADDSC:
16861 case OPC_ADDWC:
16862 case OPC_MODSUB:
16863 case OPC_RADDU_W_QB:
16864 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16865 break;
16866 case OPC_MULEU_S_PH_QBL:
16867 case OPC_MULEU_S_PH_QBR:
16868 case OPC_MULQ_RS_PH:
16869 case OPC_MULEQ_S_W_PHL:
16870 case OPC_MULEQ_S_W_PHR:
16871 case OPC_MULQ_S_PH:
16872 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16873 break;
16874 default: /* Invalid */
16875 MIPS_INVAL("MASK ADDU.QB");
16876 generate_exception(ctx, EXCP_RI);
461c08df 16877 break;
461c08df 16878
099e5b4d
LA
16879 }
16880 break;
16881 case OPC_CMPU_EQ_QB_DSP:
16882 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16883 switch (op2) {
16884 case OPC_PRECR_SRA_PH_W:
16885 case OPC_PRECR_SRA_R_PH_W:
16886 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16887 break;
099e5b4d
LA
16888 case OPC_PRECR_QB_PH:
16889 case OPC_PRECRQ_QB_PH:
16890 case OPC_PRECRQ_PH_W:
16891 case OPC_PRECRQ_RS_PH_W:
16892 case OPC_PRECRQU_S_QB_PH:
16893 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16894 break;
099e5b4d
LA
16895 case OPC_CMPU_EQ_QB:
16896 case OPC_CMPU_LT_QB:
16897 case OPC_CMPU_LE_QB:
16898 case OPC_CMP_EQ_PH:
16899 case OPC_CMP_LT_PH:
16900 case OPC_CMP_LE_PH:
16901 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16902 break;
099e5b4d
LA
16903 case OPC_CMPGU_EQ_QB:
16904 case OPC_CMPGU_LT_QB:
16905 case OPC_CMPGU_LE_QB:
16906 case OPC_CMPGDU_EQ_QB:
16907 case OPC_CMPGDU_LT_QB:
16908 case OPC_CMPGDU_LE_QB:
16909 case OPC_PICK_QB:
16910 case OPC_PICK_PH:
16911 case OPC_PACKRL_PH:
16912 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16913 break;
16914 default: /* Invalid */
16915 MIPS_INVAL("MASK CMPU.EQ.QB");
16916 generate_exception(ctx, EXCP_RI);
16917 break;
16918 }
16919 break;
16920 case OPC_SHLL_QB_DSP:
16921 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16922 break;
16923 case OPC_DPA_W_PH_DSP:
16924 op2 = MASK_DPA_W_PH(ctx->opcode);
16925 switch (op2) {
16926 case OPC_DPAU_H_QBL:
16927 case OPC_DPAU_H_QBR:
16928 case OPC_DPSU_H_QBL:
16929 case OPC_DPSU_H_QBR:
16930 case OPC_DPA_W_PH:
16931 case OPC_DPAX_W_PH:
16932 case OPC_DPAQ_S_W_PH:
16933 case OPC_DPAQX_S_W_PH:
16934 case OPC_DPAQX_SA_W_PH:
16935 case OPC_DPS_W_PH:
16936 case OPC_DPSX_W_PH:
16937 case OPC_DPSQ_S_W_PH:
16938 case OPC_DPSQX_S_W_PH:
16939 case OPC_DPSQX_SA_W_PH:
16940 case OPC_MULSAQ_S_W_PH:
16941 case OPC_DPAQ_SA_L_W:
16942 case OPC_DPSQ_SA_L_W:
16943 case OPC_MAQ_S_W_PHL:
16944 case OPC_MAQ_S_W_PHR:
16945 case OPC_MAQ_SA_W_PHL:
16946 case OPC_MAQ_SA_W_PHR:
16947 case OPC_MULSA_W_PH:
16948 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16949 break;
16950 default: /* Invalid */
16951 MIPS_INVAL("MASK DPAW.PH");
16952 generate_exception(ctx, EXCP_RI);
16953 break;
16954 }
16955 break;
16956 case OPC_INSV_DSP:
16957 op2 = MASK_INSV(ctx->opcode);
16958 switch (op2) {
16959 case OPC_INSV:
16960 check_dsp(ctx);
16961 {
16962 TCGv t0, t1;
16963
16964 if (rt == 0) {
16965 MIPS_DEBUG("NOP");
16966 break;
16967 }
16968
16969 t0 = tcg_temp_new();
16970 t1 = tcg_temp_new();
16971
16972 gen_load_gpr(t0, rt);
16973 gen_load_gpr(t1, rs);
16974
16975 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16976
16977 tcg_temp_free(t0);
16978 tcg_temp_free(t1);
a22260ae
JL
16979 break;
16980 }
099e5b4d
LA
16981 default: /* Invalid */
16982 MIPS_INVAL("MASK INSV");
16983 generate_exception(ctx, EXCP_RI);
16984 break;
16985 }
16986 break;
16987 case OPC_APPEND_DSP:
16988 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16989 break;
16990 case OPC_EXTR_W_DSP:
16991 op2 = MASK_EXTR_W(ctx->opcode);
16992 switch (op2) {
16993 case OPC_EXTR_W:
16994 case OPC_EXTR_R_W:
16995 case OPC_EXTR_RS_W:
16996 case OPC_EXTR_S_H:
16997 case OPC_EXTRV_S_H:
16998 case OPC_EXTRV_W:
16999 case OPC_EXTRV_R_W:
17000 case OPC_EXTRV_RS_W:
17001 case OPC_EXTP:
17002 case OPC_EXTPV:
17003 case OPC_EXTPDP:
17004 case OPC_EXTPDPV:
17005 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17006 break;
17007 case OPC_RDDSP:
17008 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17009 break;
17010 case OPC_SHILO:
17011 case OPC_SHILOV:
17012 case OPC_MTHLIP:
17013 case OPC_WRDSP:
17014 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17015 break;
17016 default: /* Invalid */
17017 MIPS_INVAL("MASK EXTR.W");
17018 generate_exception(ctx, EXCP_RI);
17019 break;
17020 }
17021 break;
099e5b4d 17022#if defined(TARGET_MIPS64)
fac5a073
LA
17023 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17024 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17025 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17026 check_insn(ctx, INSN_LOONGSON2E);
17027 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17028 break;
099e5b4d
LA
17029 case OPC_ABSQ_S_QH_DSP:
17030 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17031 switch (op2) {
17032 case OPC_PRECEQ_L_PWL:
17033 case OPC_PRECEQ_L_PWR:
17034 case OPC_PRECEQ_PW_QHL:
17035 case OPC_PRECEQ_PW_QHR:
17036 case OPC_PRECEQ_PW_QHLA:
17037 case OPC_PRECEQ_PW_QHRA:
17038 case OPC_PRECEQU_QH_OBL:
17039 case OPC_PRECEQU_QH_OBR:
17040 case OPC_PRECEQU_QH_OBLA:
17041 case OPC_PRECEQU_QH_OBRA:
17042 case OPC_PRECEU_QH_OBL:
17043 case OPC_PRECEU_QH_OBR:
17044 case OPC_PRECEU_QH_OBLA:
17045 case OPC_PRECEU_QH_OBRA:
17046 case OPC_ABSQ_S_OB:
17047 case OPC_ABSQ_S_PW:
17048 case OPC_ABSQ_S_QH:
17049 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17050 break;
17051 case OPC_REPL_OB:
17052 case OPC_REPL_PW:
17053 case OPC_REPL_QH:
17054 case OPC_REPLV_OB:
17055 case OPC_REPLV_PW:
17056 case OPC_REPLV_QH:
17057 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17058 break;
17059 default: /* Invalid */
17060 MIPS_INVAL("MASK ABSQ_S.QH");
17061 generate_exception(ctx, EXCP_RI);
17062 break;
17063 }
17064 break;
17065 case OPC_ADDU_OB_DSP:
17066 op2 = MASK_ADDU_OB(ctx->opcode);
17067 switch (op2) {
17068 case OPC_RADDU_L_OB:
17069 case OPC_SUBQ_PW:
17070 case OPC_SUBQ_S_PW:
17071 case OPC_SUBQ_QH:
17072 case OPC_SUBQ_S_QH:
17073 case OPC_SUBU_OB:
17074 case OPC_SUBU_S_OB:
17075 case OPC_SUBU_QH:
17076 case OPC_SUBU_S_QH:
17077 case OPC_SUBUH_OB:
17078 case OPC_SUBUH_R_OB:
17079 case OPC_ADDQ_PW:
17080 case OPC_ADDQ_S_PW:
17081 case OPC_ADDQ_QH:
17082 case OPC_ADDQ_S_QH:
17083 case OPC_ADDU_OB:
17084 case OPC_ADDU_S_OB:
17085 case OPC_ADDU_QH:
17086 case OPC_ADDU_S_QH:
17087 case OPC_ADDUH_OB:
17088 case OPC_ADDUH_R_OB:
17089 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17090 break;
099e5b4d
LA
17091 case OPC_MULEQ_S_PW_QHL:
17092 case OPC_MULEQ_S_PW_QHR:
17093 case OPC_MULEU_S_QH_OBL:
17094 case OPC_MULEU_S_QH_OBR:
17095 case OPC_MULQ_RS_QH:
17096 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17097 break;
099e5b4d
LA
17098 default: /* Invalid */
17099 MIPS_INVAL("MASK ADDU.OB");
17100 generate_exception(ctx, EXCP_RI);
26690560 17101 break;
099e5b4d
LA
17102 }
17103 break;
17104 case OPC_CMPU_EQ_OB_DSP:
17105 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17106 switch (op2) {
17107 case OPC_PRECR_SRA_QH_PW:
17108 case OPC_PRECR_SRA_R_QH_PW:
17109 /* Return value is rt. */
17110 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17111 break;
099e5b4d
LA
17112 case OPC_PRECR_OB_QH:
17113 case OPC_PRECRQ_OB_QH:
17114 case OPC_PRECRQ_PW_L:
17115 case OPC_PRECRQ_QH_PW:
17116 case OPC_PRECRQ_RS_QH_PW:
17117 case OPC_PRECRQU_S_OB_QH:
17118 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17119 break;
099e5b4d
LA
17120 case OPC_CMPU_EQ_OB:
17121 case OPC_CMPU_LT_OB:
17122 case OPC_CMPU_LE_OB:
17123 case OPC_CMP_EQ_QH:
17124 case OPC_CMP_LT_QH:
17125 case OPC_CMP_LE_QH:
17126 case OPC_CMP_EQ_PW:
17127 case OPC_CMP_LT_PW:
17128 case OPC_CMP_LE_PW:
17129 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17130 break;
099e5b4d
LA
17131 case OPC_CMPGDU_EQ_OB:
17132 case OPC_CMPGDU_LT_OB:
17133 case OPC_CMPGDU_LE_OB:
17134 case OPC_CMPGU_EQ_OB:
17135 case OPC_CMPGU_LT_OB:
17136 case OPC_CMPGU_LE_OB:
17137 case OPC_PACKRL_PW:
17138 case OPC_PICK_OB:
17139 case OPC_PICK_PW:
17140 case OPC_PICK_QH:
17141 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17142 break;
099e5b4d
LA
17143 default: /* Invalid */
17144 MIPS_INVAL("MASK CMPU_EQ.OB");
17145 generate_exception(ctx, EXCP_RI);
161f85e6 17146 break;
099e5b4d
LA
17147 }
17148 break;
17149 case OPC_DAPPEND_DSP:
17150 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17151 break;
17152 case OPC_DEXTR_W_DSP:
17153 op2 = MASK_DEXTR_W(ctx->opcode);
17154 switch (op2) {
17155 case OPC_DEXTP:
17156 case OPC_DEXTPDP:
17157 case OPC_DEXTPDPV:
17158 case OPC_DEXTPV:
17159 case OPC_DEXTR_L:
17160 case OPC_DEXTR_R_L:
17161 case OPC_DEXTR_RS_L:
17162 case OPC_DEXTR_W:
17163 case OPC_DEXTR_R_W:
17164 case OPC_DEXTR_RS_W:
17165 case OPC_DEXTR_S_H:
17166 case OPC_DEXTRV_L:
17167 case OPC_DEXTRV_R_L:
17168 case OPC_DEXTRV_RS_L:
17169 case OPC_DEXTRV_S_H:
17170 case OPC_DEXTRV_W:
17171 case OPC_DEXTRV_R_W:
17172 case OPC_DEXTRV_RS_W:
17173 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17174 break;
099e5b4d
LA
17175 case OPC_DMTHLIP:
17176 case OPC_DSHILO:
17177 case OPC_DSHILOV:
17178 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17179 break;
099e5b4d
LA
17180 default: /* Invalid */
17181 MIPS_INVAL("MASK EXTR.W");
17182 generate_exception(ctx, EXCP_RI);
461c08df 17183 break;
099e5b4d
LA
17184 }
17185 break;
17186 case OPC_DPAQ_W_QH_DSP:
17187 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17188 switch (op2) {
17189 case OPC_DPAU_H_OBL:
17190 case OPC_DPAU_H_OBR:
17191 case OPC_DPSU_H_OBL:
17192 case OPC_DPSU_H_OBR:
17193 case OPC_DPA_W_QH:
17194 case OPC_DPAQ_S_W_QH:
17195 case OPC_DPS_W_QH:
17196 case OPC_DPSQ_S_W_QH:
17197 case OPC_MULSAQ_S_W_QH:
17198 case OPC_DPAQ_SA_L_PW:
17199 case OPC_DPSQ_SA_L_PW:
17200 case OPC_MULSAQ_S_L_PW:
17201 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17202 break;
17203 case OPC_MAQ_S_W_QHLL:
17204 case OPC_MAQ_S_W_QHLR:
17205 case OPC_MAQ_S_W_QHRL:
17206 case OPC_MAQ_S_W_QHRR:
17207 case OPC_MAQ_SA_W_QHLL:
17208 case OPC_MAQ_SA_W_QHLR:
17209 case OPC_MAQ_SA_W_QHRL:
17210 case OPC_MAQ_SA_W_QHRR:
17211 case OPC_MAQ_S_L_PWL:
17212 case OPC_MAQ_S_L_PWR:
17213 case OPC_DMADD:
17214 case OPC_DMADDU:
17215 case OPC_DMSUB:
17216 case OPC_DMSUBU:
17217 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17218 break;
099e5b4d
LA
17219 default: /* Invalid */
17220 MIPS_INVAL("MASK DPAQ.W.QH");
17221 generate_exception(ctx, EXCP_RI);
b53371ed 17222 break;
099e5b4d
LA
17223 }
17224 break;
17225 case OPC_DINSV_DSP:
17226 op2 = MASK_INSV(ctx->opcode);
17227 switch (op2) {
17228 case OPC_DINSV:
17229 {
17230 TCGv t0, t1;
17231
17232 if (rt == 0) {
17233 MIPS_DEBUG("NOP");
a22260ae
JL
17234 break;
17235 }
099e5b4d 17236 check_dsp(ctx);
1cb6686c 17237
099e5b4d
LA
17238 t0 = tcg_temp_new();
17239 t1 = tcg_temp_new();
1cb6686c 17240
099e5b4d
LA
17241 gen_load_gpr(t0, rt);
17242 gen_load_gpr(t1, rs);
1cb6686c 17243
099e5b4d 17244 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17245
099e5b4d
LA
17246 tcg_temp_free(t0);
17247 tcg_temp_free(t1);
77c5fa8b 17248 break;
099e5b4d 17249 }
7a387fff 17250 default: /* Invalid */
099e5b4d 17251 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17252 generate_exception(ctx, EXCP_RI);
17253 break;
17254 }
17255 break;
099e5b4d
LA
17256 case OPC_SHLL_OB_DSP:
17257 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17258 break;
17259#endif
fac5a073
LA
17260 default: /* Invalid */
17261 MIPS_INVAL("special3_legacy");
17262 generate_exception(ctx, EXCP_RI);
17263 break;
17264 }
17265}
17266
17267static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17268{
17269 int rs, rt, rd, sa;
17270 uint32_t op1, op2;
17271
17272 rs = (ctx->opcode >> 21) & 0x1f;
17273 rt = (ctx->opcode >> 16) & 0x1f;
17274 rd = (ctx->opcode >> 11) & 0x1f;
17275 sa = (ctx->opcode >> 6) & 0x1f;
17276
17277 op1 = MASK_SPECIAL3(ctx->opcode);
17278 switch (op1) {
17279 case OPC_EXT:
17280 case OPC_INS:
17281 check_insn(ctx, ISA_MIPS32R2);
17282 gen_bitops(ctx, op1, rt, rs, sa, rd);
17283 break;
17284 case OPC_BSHFL:
fac5a073 17285 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17286 switch (op2) {
17287 case OPC_ALIGN ... OPC_ALIGN_END:
17288 case OPC_BITSWAP:
17289 check_insn(ctx, ISA_MIPS32R6);
17290 decode_opc_special3_r6(env, ctx);
17291 break;
17292 default:
17293 check_insn(ctx, ISA_MIPS32R2);
17294 gen_bshfl(ctx, op2, rt, rd);
17295 break;
17296 }
fac5a073
LA
17297 break;
17298#if defined(TARGET_MIPS64)
17299 case OPC_DEXTM ... OPC_DEXT:
17300 case OPC_DINSM ... OPC_DINS:
17301 check_insn(ctx, ISA_MIPS64R2);
17302 check_mips_64(ctx);
17303 gen_bitops(ctx, op1, rt, rs, sa, rd);
17304 break;
17305 case OPC_DBSHFL:
fac5a073 17306 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17307 switch (op2) {
17308 case OPC_DALIGN ... OPC_DALIGN_END:
17309 case OPC_DBITSWAP:
17310 check_insn(ctx, ISA_MIPS32R6);
17311 decode_opc_special3_r6(env, ctx);
17312 break;
17313 default:
17314 check_insn(ctx, ISA_MIPS64R2);
17315 check_mips_64(ctx);
17316 op2 = MASK_DBSHFL(ctx->opcode);
17317 gen_bshfl(ctx, op2, rt, rd);
17318 break;
17319 }
fac5a073
LA
17320 break;
17321#endif
17322 case OPC_RDHWR:
17323 gen_rdhwr(ctx, rt, rd);
17324 break;
17325 case OPC_FORK:
17326 check_insn(ctx, ASE_MT);
17327 {
17328 TCGv t0 = tcg_temp_new();
17329 TCGv t1 = tcg_temp_new();
17330
17331 gen_load_gpr(t0, rt);
17332 gen_load_gpr(t1, rs);
17333 gen_helper_fork(t0, t1);
17334 tcg_temp_free(t0);
17335 tcg_temp_free(t1);
17336 }
17337 break;
17338 case OPC_YIELD:
17339 check_insn(ctx, ASE_MT);
17340 {
17341 TCGv t0 = tcg_temp_new();
17342
17343 save_cpu_state(ctx, 1);
17344 gen_load_gpr(t0, rs);
17345 gen_helper_yield(t0, cpu_env, t0);
17346 gen_store_gpr(t0, rd);
17347 tcg_temp_free(t0);
17348 }
17349 break;
10dc65db
LA
17350 default:
17351 if (ctx->insn_flags & ISA_MIPS32R6) {
17352 decode_opc_special3_r6(env, ctx);
17353 } else {
17354 decode_opc_special3_legacy(env, ctx);
17355 }
099e5b4d
LA
17356 }
17357}
17358
863f264d
YK
17359/* MIPS SIMD Architecture (MSA) */
17360static inline int check_msa_access(DisasContext *ctx)
17361{
17362 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17363 !(ctx->hflags & MIPS_HFLAG_F64))) {
17364 generate_exception(ctx, EXCP_RI);
17365 return 0;
17366 }
17367
17368 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17369 if (ctx->insn_flags & ASE_MSA) {
17370 generate_exception(ctx, EXCP_MSADIS);
17371 return 0;
17372 } else {
17373 generate_exception(ctx, EXCP_RI);
17374 return 0;
17375 }
17376 }
17377 return 1;
17378}
17379
5692c6e1
YK
17380static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17381{
17382 /* generates tcg ops to check if any element is 0 */
17383 /* Note this function only works with MSA_WRLEN = 128 */
17384 uint64_t eval_zero_or_big = 0;
17385 uint64_t eval_big = 0;
17386 TCGv_i64 t0 = tcg_temp_new_i64();
17387 TCGv_i64 t1 = tcg_temp_new_i64();
17388 switch (df) {
17389 case DF_BYTE:
17390 eval_zero_or_big = 0x0101010101010101ULL;
17391 eval_big = 0x8080808080808080ULL;
17392 break;
17393 case DF_HALF:
17394 eval_zero_or_big = 0x0001000100010001ULL;
17395 eval_big = 0x8000800080008000ULL;
17396 break;
17397 case DF_WORD:
17398 eval_zero_or_big = 0x0000000100000001ULL;
17399 eval_big = 0x8000000080000000ULL;
17400 break;
17401 case DF_DOUBLE:
17402 eval_zero_or_big = 0x0000000000000001ULL;
17403 eval_big = 0x8000000000000000ULL;
17404 break;
17405 }
17406 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17407 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17408 tcg_gen_andi_i64(t0, t0, eval_big);
17409 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17410 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17411 tcg_gen_andi_i64(t1, t1, eval_big);
17412 tcg_gen_or_i64(t0, t0, t1);
17413 /* if all bits are zero then all elements are not zero */
17414 /* if some bit is non-zero then some element is zero */
17415 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17416 tcg_gen_trunc_i64_tl(tresult, t0);
17417 tcg_temp_free_i64(t0);
17418 tcg_temp_free_i64(t1);
17419}
17420
17421static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17422{
17423 uint8_t df = (ctx->opcode >> 21) & 0x3;
17424 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17425 int64_t s16 = (int16_t)ctx->opcode;
17426
17427 check_msa_access(ctx);
17428
17429 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17430 MIPS_DEBUG("CTI in delay / forbidden slot");
17431 generate_exception(ctx, EXCP_RI);
17432 return;
17433 }
17434 switch (op1) {
17435 case OPC_BZ_V:
17436 case OPC_BNZ_V:
17437 {
17438 TCGv_i64 t0 = tcg_temp_new_i64();
17439 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17440 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17441 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17442 tcg_gen_trunc_i64_tl(bcond, t0);
17443 tcg_temp_free_i64(t0);
17444 }
17445 break;
17446 case OPC_BZ_B:
17447 case OPC_BZ_H:
17448 case OPC_BZ_W:
17449 case OPC_BZ_D:
17450 gen_check_zero_element(bcond, df, wt);
17451 break;
17452 case OPC_BNZ_B:
17453 case OPC_BNZ_H:
17454 case OPC_BNZ_W:
17455 case OPC_BNZ_D:
17456 gen_check_zero_element(bcond, df, wt);
17457 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17458 break;
17459 }
17460
17461 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17462
17463 ctx->hflags |= MIPS_HFLAG_BC;
17464 ctx->hflags |= MIPS_HFLAG_BDS32;
17465}
17466
4c789546
YK
17467static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17468{
17469#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17470 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17471 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17472 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17473
17474 TCGv_i32 twd = tcg_const_i32(wd);
17475 TCGv_i32 tws = tcg_const_i32(ws);
17476 TCGv_i32 ti8 = tcg_const_i32(i8);
17477
17478 switch (MASK_MSA_I8(ctx->opcode)) {
17479 case OPC_ANDI_B:
17480 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17481 break;
17482 case OPC_ORI_B:
17483 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17484 break;
17485 case OPC_NORI_B:
17486 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17487 break;
17488 case OPC_XORI_B:
17489 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17490 break;
17491 case OPC_BMNZI_B:
17492 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17493 break;
17494 case OPC_BMZI_B:
17495 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17496 break;
17497 case OPC_BSELI_B:
17498 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17499 break;
17500 case OPC_SHF_B:
17501 case OPC_SHF_H:
17502 case OPC_SHF_W:
17503 {
17504 uint8_t df = (ctx->opcode >> 24) & 0x3;
17505 if (df == DF_DOUBLE) {
17506 generate_exception(ctx, EXCP_RI);
17507 } else {
17508 TCGv_i32 tdf = tcg_const_i32(df);
17509 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17510 tcg_temp_free_i32(tdf);
17511 }
17512 }
17513 break;
17514 default:
17515 MIPS_INVAL("MSA instruction");
17516 generate_exception(ctx, EXCP_RI);
17517 break;
17518 }
17519
17520 tcg_temp_free_i32(twd);
17521 tcg_temp_free_i32(tws);
17522 tcg_temp_free_i32(ti8);
17523}
17524
80e71591
YK
17525static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17526{
17527#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17528 uint8_t df = (ctx->opcode >> 21) & 0x3;
17529 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17530 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17531 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17532 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17533
17534 TCGv_i32 tdf = tcg_const_i32(df);
17535 TCGv_i32 twd = tcg_const_i32(wd);
17536 TCGv_i32 tws = tcg_const_i32(ws);
17537 TCGv_i32 timm = tcg_temp_new_i32();
17538 tcg_gen_movi_i32(timm, u5);
17539
17540 switch (MASK_MSA_I5(ctx->opcode)) {
17541 case OPC_ADDVI_df:
17542 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17543 break;
17544 case OPC_SUBVI_df:
17545 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17546 break;
17547 case OPC_MAXI_S_df:
17548 tcg_gen_movi_i32(timm, s5);
17549 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17550 break;
17551 case OPC_MAXI_U_df:
17552 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17553 break;
17554 case OPC_MINI_S_df:
17555 tcg_gen_movi_i32(timm, s5);
17556 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17557 break;
17558 case OPC_MINI_U_df:
17559 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17560 break;
17561 case OPC_CEQI_df:
17562 tcg_gen_movi_i32(timm, s5);
17563 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17564 break;
17565 case OPC_CLTI_S_df:
17566 tcg_gen_movi_i32(timm, s5);
17567 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17568 break;
17569 case OPC_CLTI_U_df:
17570 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17571 break;
17572 case OPC_CLEI_S_df:
17573 tcg_gen_movi_i32(timm, s5);
17574 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17575 break;
17576 case OPC_CLEI_U_df:
17577 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17578 break;
17579 case OPC_LDI_df:
17580 {
17581 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17582 tcg_gen_movi_i32(timm, s10);
17583 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17584 }
17585 break;
17586 default:
17587 MIPS_INVAL("MSA instruction");
17588 generate_exception(ctx, EXCP_RI);
17589 break;
17590 }
17591
17592 tcg_temp_free_i32(tdf);
17593 tcg_temp_free_i32(twd);
17594 tcg_temp_free_i32(tws);
17595 tcg_temp_free_i32(timm);
17596}
17597
d4cf28de
YK
17598static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17599{
17600#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17601 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17602 uint32_t df = 0, m = 0;
17603 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17604 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17605
17606 TCGv_i32 tdf;
17607 TCGv_i32 tm;
17608 TCGv_i32 twd;
17609 TCGv_i32 tws;
17610
17611 if ((dfm & 0x40) == 0x00) {
17612 m = dfm & 0x3f;
17613 df = DF_DOUBLE;
17614 } else if ((dfm & 0x60) == 0x40) {
17615 m = dfm & 0x1f;
17616 df = DF_WORD;
17617 } else if ((dfm & 0x70) == 0x60) {
17618 m = dfm & 0x0f;
17619 df = DF_HALF;
17620 } else if ((dfm & 0x78) == 0x70) {
17621 m = dfm & 0x7;
17622 df = DF_BYTE;
17623 } else {
17624 generate_exception(ctx, EXCP_RI);
17625 return;
17626 }
17627
17628 tdf = tcg_const_i32(df);
17629 tm = tcg_const_i32(m);
17630 twd = tcg_const_i32(wd);
17631 tws = tcg_const_i32(ws);
17632
17633 switch (MASK_MSA_BIT(ctx->opcode)) {
17634 case OPC_SLLI_df:
17635 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17636 break;
17637 case OPC_SRAI_df:
17638 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17639 break;
17640 case OPC_SRLI_df:
17641 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17642 break;
17643 case OPC_BCLRI_df:
17644 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17645 break;
17646 case OPC_BSETI_df:
17647 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17648 break;
17649 case OPC_BNEGI_df:
17650 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17651 break;
17652 case OPC_BINSLI_df:
17653 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17654 break;
17655 case OPC_BINSRI_df:
17656 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17657 break;
17658 case OPC_SAT_S_df:
17659 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17660 break;
17661 case OPC_SAT_U_df:
17662 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17663 break;
17664 case OPC_SRARI_df:
17665 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17666 break;
17667 case OPC_SRLRI_df:
17668 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17669 break;
17670 default:
17671 MIPS_INVAL("MSA instruction");
17672 generate_exception(ctx, EXCP_RI);
17673 break;
17674 }
17675
17676 tcg_temp_free_i32(tdf);
17677 tcg_temp_free_i32(tm);
17678 tcg_temp_free_i32(twd);
17679 tcg_temp_free_i32(tws);
17680}
17681
28f99f08
YK
17682static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17683{
17684#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17685 uint8_t df = (ctx->opcode >> 21) & 0x3;
17686 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17687 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17688 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17689
17690 TCGv_i32 tdf = tcg_const_i32(df);
17691 TCGv_i32 twd = tcg_const_i32(wd);
17692 TCGv_i32 tws = tcg_const_i32(ws);
17693 TCGv_i32 twt = tcg_const_i32(wt);
17694
17695 switch (MASK_MSA_3R(ctx->opcode)) {
17696 case OPC_SLL_df:
17697 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17698 break;
17699 case OPC_ADDV_df:
17700 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17701 break;
17702 case OPC_CEQ_df:
17703 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17704 break;
17705 case OPC_ADD_A_df:
17706 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17707 break;
17708 case OPC_SUBS_S_df:
17709 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17710 break;
17711 case OPC_MULV_df:
17712 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17713 break;
17714 case OPC_SLD_df:
17715 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17716 break;
17717 case OPC_VSHF_df:
17718 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17719 break;
17720 case OPC_SRA_df:
17721 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17722 break;
17723 case OPC_SUBV_df:
17724 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17725 break;
17726 case OPC_ADDS_A_df:
17727 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17728 break;
17729 case OPC_SUBS_U_df:
17730 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17731 break;
17732 case OPC_MADDV_df:
17733 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17734 break;
17735 case OPC_SPLAT_df:
17736 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17737 break;
17738 case OPC_SRAR_df:
17739 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17740 break;
17741 case OPC_SRL_df:
17742 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17743 break;
17744 case OPC_MAX_S_df:
17745 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17746 break;
17747 case OPC_CLT_S_df:
17748 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17749 break;
17750 case OPC_ADDS_S_df:
17751 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17752 break;
17753 case OPC_SUBSUS_U_df:
17754 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17755 break;
17756 case OPC_MSUBV_df:
17757 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17758 break;
17759 case OPC_PCKEV_df:
17760 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17761 break;
17762 case OPC_SRLR_df:
17763 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17764 break;
17765 case OPC_BCLR_df:
17766 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17767 break;
17768 case OPC_MAX_U_df:
17769 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17770 break;
17771 case OPC_CLT_U_df:
17772 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17773 break;
17774 case OPC_ADDS_U_df:
17775 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17776 break;
17777 case OPC_SUBSUU_S_df:
17778 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17779 break;
17780 case OPC_PCKOD_df:
17781 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17782 break;
17783 case OPC_BSET_df:
17784 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17785 break;
17786 case OPC_MIN_S_df:
17787 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17788 break;
17789 case OPC_CLE_S_df:
17790 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17791 break;
17792 case OPC_AVE_S_df:
17793 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17794 break;
17795 case OPC_ASUB_S_df:
17796 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17797 break;
17798 case OPC_DIV_S_df:
17799 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17800 break;
17801 case OPC_ILVL_df:
17802 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17803 break;
17804 case OPC_BNEG_df:
17805 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17806 break;
17807 case OPC_MIN_U_df:
17808 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17809 break;
17810 case OPC_CLE_U_df:
17811 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17812 break;
17813 case OPC_AVE_U_df:
17814 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17815 break;
17816 case OPC_ASUB_U_df:
17817 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17818 break;
17819 case OPC_DIV_U_df:
17820 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17821 break;
17822 case OPC_ILVR_df:
17823 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17824 break;
17825 case OPC_BINSL_df:
17826 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17827 break;
17828 case OPC_MAX_A_df:
17829 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17830 break;
17831 case OPC_AVER_S_df:
17832 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17833 break;
17834 case OPC_MOD_S_df:
17835 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17836 break;
17837 case OPC_ILVEV_df:
17838 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17839 break;
17840 case OPC_BINSR_df:
17841 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17842 break;
17843 case OPC_MIN_A_df:
17844 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17845 break;
17846 case OPC_AVER_U_df:
17847 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17848 break;
17849 case OPC_MOD_U_df:
17850 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17851 break;
17852 case OPC_ILVOD_df:
17853 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17854 break;
17855
17856 case OPC_DOTP_S_df:
17857 case OPC_DOTP_U_df:
17858 case OPC_DPADD_S_df:
17859 case OPC_DPADD_U_df:
17860 case OPC_DPSUB_S_df:
17861 case OPC_HADD_S_df:
17862 case OPC_DPSUB_U_df:
17863 case OPC_HADD_U_df:
17864 case OPC_HSUB_S_df:
17865 case OPC_HSUB_U_df:
17866 if (df == DF_BYTE) {
17867 generate_exception(ctx, EXCP_RI);
17868 }
17869 switch (MASK_MSA_3R(ctx->opcode)) {
17870 case OPC_DOTP_S_df:
17871 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17872 break;
17873 case OPC_DOTP_U_df:
17874 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17875 break;
17876 case OPC_DPADD_S_df:
17877 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17878 break;
17879 case OPC_DPADD_U_df:
17880 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17881 break;
17882 case OPC_DPSUB_S_df:
17883 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17884 break;
17885 case OPC_HADD_S_df:
17886 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17887 break;
17888 case OPC_DPSUB_U_df:
17889 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17890 break;
17891 case OPC_HADD_U_df:
17892 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17893 break;
17894 case OPC_HSUB_S_df:
17895 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17896 break;
17897 case OPC_HSUB_U_df:
17898 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17899 break;
17900 }
17901 break;
17902 default:
17903 MIPS_INVAL("MSA instruction");
17904 generate_exception(ctx, EXCP_RI);
17905 break;
17906 }
17907 tcg_temp_free_i32(twd);
17908 tcg_temp_free_i32(tws);
17909 tcg_temp_free_i32(twt);
17910 tcg_temp_free_i32(tdf);
17911}
17912
1e608ec1
YK
17913static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17914{
17915#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17916 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17917 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17918 TCGv telm = tcg_temp_new();
17919 TCGv_i32 tsr = tcg_const_i32(source);
17920 TCGv_i32 tdt = tcg_const_i32(dest);
17921
17922 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17923 case OPC_CTCMSA:
17924 gen_load_gpr(telm, source);
17925 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17926 break;
17927 case OPC_CFCMSA:
17928 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17929 gen_store_gpr(telm, dest);
17930 break;
17931 case OPC_MOVE_V:
17932 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17933 break;
17934 default:
17935 MIPS_INVAL("MSA instruction");
17936 generate_exception(ctx, EXCP_RI);
17937 break;
17938 }
17939
17940 tcg_temp_free(telm);
17941 tcg_temp_free_i32(tdt);
17942 tcg_temp_free_i32(tsr);
17943}
17944
17945static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17946 uint32_t n)
17947{
17948#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17949 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17950 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17951
17952 TCGv_i32 tws = tcg_const_i32(ws);
17953 TCGv_i32 twd = tcg_const_i32(wd);
17954 TCGv_i32 tn = tcg_const_i32(n);
17955 TCGv_i32 tdf = tcg_const_i32(df);
17956
17957 switch (MASK_MSA_ELM(ctx->opcode)) {
17958 case OPC_SLDI_df:
17959 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17960 break;
17961 case OPC_SPLATI_df:
17962 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17963 break;
17964 case OPC_INSVE_df:
17965 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17966 break;
17967 case OPC_COPY_S_df:
17968 case OPC_COPY_U_df:
17969 case OPC_INSERT_df:
17970#if !defined(TARGET_MIPS64)
17971 /* Double format valid only for MIPS64 */
17972 if (df == DF_DOUBLE) {
17973 generate_exception(ctx, EXCP_RI);
17974 break;
17975 }
17976#endif
17977 switch (MASK_MSA_ELM(ctx->opcode)) {
17978 case OPC_COPY_S_df:
17979 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
17980 break;
17981 case OPC_COPY_U_df:
17982 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
17983 break;
17984 case OPC_INSERT_df:
17985 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
17986 break;
17987 }
17988 break;
17989 default:
17990 MIPS_INVAL("MSA instruction");
17991 generate_exception(ctx, EXCP_RI);
17992 }
17993 tcg_temp_free_i32(twd);
17994 tcg_temp_free_i32(tws);
17995 tcg_temp_free_i32(tn);
17996 tcg_temp_free_i32(tdf);
17997}
17998
17999static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18000{
18001 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18002 uint32_t df = 0, n = 0;
18003
18004 if ((dfn & 0x30) == 0x00) {
18005 n = dfn & 0x0f;
18006 df = DF_BYTE;
18007 } else if ((dfn & 0x38) == 0x20) {
18008 n = dfn & 0x07;
18009 df = DF_HALF;
18010 } else if ((dfn & 0x3c) == 0x30) {
18011 n = dfn & 0x03;
18012 df = DF_WORD;
18013 } else if ((dfn & 0x3e) == 0x38) {
18014 n = dfn & 0x01;
18015 df = DF_DOUBLE;
18016 } else if (dfn == 0x3E) {
18017 /* CTCMSA, CFCMSA, MOVE.V */
18018 gen_msa_elm_3e(env, ctx);
18019 return;
18020 } else {
18021 generate_exception(ctx, EXCP_RI);
18022 return;
18023 }
18024
18025 gen_msa_elm_df(env, ctx, df, n);
18026}
18027
7d05b9c8
YK
18028static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18029{
18030#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18031 uint8_t df = (ctx->opcode >> 21) & 0x1;
18032 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18033 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18034 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18035
18036 TCGv_i32 twd = tcg_const_i32(wd);
18037 TCGv_i32 tws = tcg_const_i32(ws);
18038 TCGv_i32 twt = tcg_const_i32(wt);
18039 TCGv_i32 tdf = tcg_temp_new_i32();
18040
18041 /* adjust df value for floating-point instruction */
18042 tcg_gen_movi_i32(tdf, df + 2);
18043
18044 switch (MASK_MSA_3RF(ctx->opcode)) {
18045 case OPC_FCAF_df:
18046 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18047 break;
18048 case OPC_FADD_df:
18049 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18050 break;
18051 case OPC_FCUN_df:
18052 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18053 break;
18054 case OPC_FSUB_df:
18055 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18056 break;
18057 case OPC_FCOR_df:
18058 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18059 break;
18060 case OPC_FCEQ_df:
18061 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18062 break;
18063 case OPC_FMUL_df:
18064 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18065 break;
18066 case OPC_FCUNE_df:
18067 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18068 break;
18069 case OPC_FCUEQ_df:
18070 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18071 break;
18072 case OPC_FDIV_df:
18073 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18074 break;
18075 case OPC_FCNE_df:
18076 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18077 break;
18078 case OPC_FCLT_df:
18079 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18080 break;
18081 case OPC_FMADD_df:
18082 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18083 break;
18084 case OPC_MUL_Q_df:
18085 tcg_gen_movi_i32(tdf, df + 1);
18086 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18087 break;
18088 case OPC_FCULT_df:
18089 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18090 break;
18091 case OPC_FMSUB_df:
18092 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18093 break;
18094 case OPC_MADD_Q_df:
18095 tcg_gen_movi_i32(tdf, df + 1);
18096 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18097 break;
18098 case OPC_FCLE_df:
18099 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18100 break;
18101 case OPC_MSUB_Q_df:
18102 tcg_gen_movi_i32(tdf, df + 1);
18103 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18104 break;
18105 case OPC_FCULE_df:
18106 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18107 break;
18108 case OPC_FEXP2_df:
18109 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18110 break;
18111 case OPC_FSAF_df:
18112 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18113 break;
18114 case OPC_FEXDO_df:
18115 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18116 break;
18117 case OPC_FSUN_df:
18118 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18119 break;
18120 case OPC_FSOR_df:
18121 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18122 break;
18123 case OPC_FSEQ_df:
18124 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18125 break;
18126 case OPC_FTQ_df:
18127 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18128 break;
18129 case OPC_FSUNE_df:
18130 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18131 break;
18132 case OPC_FSUEQ_df:
18133 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18134 break;
18135 case OPC_FSNE_df:
18136 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18137 break;
18138 case OPC_FSLT_df:
18139 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18140 break;
18141 case OPC_FMIN_df:
18142 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18143 break;
18144 case OPC_MULR_Q_df:
18145 tcg_gen_movi_i32(tdf, df + 1);
18146 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18147 break;
18148 case OPC_FSULT_df:
18149 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18150 break;
18151 case OPC_FMIN_A_df:
18152 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18153 break;
18154 case OPC_MADDR_Q_df:
18155 tcg_gen_movi_i32(tdf, df + 1);
18156 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18157 break;
18158 case OPC_FSLE_df:
18159 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18160 break;
18161 case OPC_FMAX_df:
18162 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18163 break;
18164 case OPC_MSUBR_Q_df:
18165 tcg_gen_movi_i32(tdf, df + 1);
18166 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18167 break;
18168 case OPC_FSULE_df:
18169 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18170 break;
18171 case OPC_FMAX_A_df:
18172 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18173 break;
18174 default:
18175 MIPS_INVAL("MSA instruction");
18176 generate_exception(ctx, EXCP_RI);
18177 break;
18178 }
18179
18180 tcg_temp_free_i32(twd);
18181 tcg_temp_free_i32(tws);
18182 tcg_temp_free_i32(twt);
18183 tcg_temp_free_i32(tdf);
18184}
18185
cbe50b9a
YK
18186static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18187{
18188#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18189 (op & (0x7 << 18)))
18190 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18191 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18192 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18193 uint8_t df = (ctx->opcode >> 16) & 0x3;
18194 TCGv_i32 twd = tcg_const_i32(wd);
18195 TCGv_i32 tws = tcg_const_i32(ws);
18196 TCGv_i32 twt = tcg_const_i32(wt);
18197 TCGv_i32 tdf = tcg_const_i32(df);
18198
18199 switch (MASK_MSA_2R(ctx->opcode)) {
18200 case OPC_FILL_df:
18201#if !defined(TARGET_MIPS64)
18202 /* Double format valid only for MIPS64 */
18203 if (df == DF_DOUBLE) {
18204 generate_exception(ctx, EXCP_RI);
18205 break;
18206 }
18207#endif
18208 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18209 break;
18210 case OPC_PCNT_df:
18211 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18212 break;
18213 case OPC_NLOC_df:
18214 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18215 break;
18216 case OPC_NLZC_df:
18217 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18218 break;
18219 default:
18220 MIPS_INVAL("MSA instruction");
18221 generate_exception(ctx, EXCP_RI);
18222 break;
18223 }
18224
18225 tcg_temp_free_i32(twd);
18226 tcg_temp_free_i32(tws);
18227 tcg_temp_free_i32(twt);
18228 tcg_temp_free_i32(tdf);
18229}
18230
3bdeb688
YK
18231static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18232{
18233#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18234 (op & (0xf << 17)))
18235 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18236 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18237 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18238 uint8_t df = (ctx->opcode >> 16) & 0x1;
18239 TCGv_i32 twd = tcg_const_i32(wd);
18240 TCGv_i32 tws = tcg_const_i32(ws);
18241 TCGv_i32 twt = tcg_const_i32(wt);
18242 /* adjust df value for floating-point instruction */
18243 TCGv_i32 tdf = tcg_const_i32(df + 2);
18244
18245 switch (MASK_MSA_2RF(ctx->opcode)) {
18246 case OPC_FCLASS_df:
18247 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18248 break;
18249 case OPC_FTRUNC_S_df:
18250 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18251 break;
18252 case OPC_FTRUNC_U_df:
18253 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18254 break;
18255 case OPC_FSQRT_df:
18256 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18257 break;
18258 case OPC_FRSQRT_df:
18259 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18260 break;
18261 case OPC_FRCP_df:
18262 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18263 break;
18264 case OPC_FRINT_df:
18265 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18266 break;
18267 case OPC_FLOG2_df:
18268 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18269 break;
18270 case OPC_FEXUPL_df:
18271 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18272 break;
18273 case OPC_FEXUPR_df:
18274 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18275 break;
18276 case OPC_FFQL_df:
18277 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18278 break;
18279 case OPC_FFQR_df:
18280 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18281 break;
18282 case OPC_FTINT_S_df:
18283 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18284 break;
18285 case OPC_FTINT_U_df:
18286 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18287 break;
18288 case OPC_FFINT_S_df:
18289 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18290 break;
18291 case OPC_FFINT_U_df:
18292 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18293 break;
18294 }
18295
18296 tcg_temp_free_i32(twd);
18297 tcg_temp_free_i32(tws);
18298 tcg_temp_free_i32(twt);
18299 tcg_temp_free_i32(tdf);
18300}
18301
cbe50b9a
YK
18302static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18303{
18304#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18305 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18306 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18307 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18308 TCGv_i32 twd = tcg_const_i32(wd);
18309 TCGv_i32 tws = tcg_const_i32(ws);
18310 TCGv_i32 twt = tcg_const_i32(wt);
18311
18312 switch (MASK_MSA_VEC(ctx->opcode)) {
18313 case OPC_AND_V:
18314 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18315 break;
18316 case OPC_OR_V:
18317 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18318 break;
18319 case OPC_NOR_V:
18320 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18321 break;
18322 case OPC_XOR_V:
18323 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18324 break;
18325 case OPC_BMNZ_V:
18326 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18327 break;
18328 case OPC_BMZ_V:
18329 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18330 break;
18331 case OPC_BSEL_V:
18332 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18333 break;
18334 default:
18335 MIPS_INVAL("MSA instruction");
18336 generate_exception(ctx, EXCP_RI);
18337 break;
18338 }
18339
18340 tcg_temp_free_i32(twd);
18341 tcg_temp_free_i32(tws);
18342 tcg_temp_free_i32(twt);
18343}
18344
18345static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18346{
18347 switch (MASK_MSA_VEC(ctx->opcode)) {
18348 case OPC_AND_V:
18349 case OPC_OR_V:
18350 case OPC_NOR_V:
18351 case OPC_XOR_V:
18352 case OPC_BMNZ_V:
18353 case OPC_BMZ_V:
18354 case OPC_BSEL_V:
18355 gen_msa_vec_v(env, ctx);
18356 break;
18357 case OPC_MSA_2R:
18358 gen_msa_2r(env, ctx);
18359 break;
3bdeb688
YK
18360 case OPC_MSA_2RF:
18361 gen_msa_2rf(env, ctx);
18362 break;
cbe50b9a
YK
18363 default:
18364 MIPS_INVAL("MSA instruction");
18365 generate_exception(ctx, EXCP_RI);
18366 break;
18367 }
18368}
18369
4c789546
YK
18370static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18371{
18372 uint32_t opcode = ctx->opcode;
18373 check_insn(ctx, ASE_MSA);
18374 check_msa_access(ctx);
18375
18376 switch (MASK_MSA_MINOR(opcode)) {
18377 case OPC_MSA_I8_00:
18378 case OPC_MSA_I8_01:
18379 case OPC_MSA_I8_02:
18380 gen_msa_i8(env, ctx);
18381 break;
80e71591
YK
18382 case OPC_MSA_I5_06:
18383 case OPC_MSA_I5_07:
18384 gen_msa_i5(env, ctx);
18385 break;
d4cf28de
YK
18386 case OPC_MSA_BIT_09:
18387 case OPC_MSA_BIT_0A:
18388 gen_msa_bit(env, ctx);
18389 break;
28f99f08
YK
18390 case OPC_MSA_3R_0D:
18391 case OPC_MSA_3R_0E:
18392 case OPC_MSA_3R_0F:
18393 case OPC_MSA_3R_10:
18394 case OPC_MSA_3R_11:
18395 case OPC_MSA_3R_12:
18396 case OPC_MSA_3R_13:
18397 case OPC_MSA_3R_14:
18398 case OPC_MSA_3R_15:
18399 gen_msa_3r(env, ctx);
18400 break;
1e608ec1
YK
18401 case OPC_MSA_ELM:
18402 gen_msa_elm(env, ctx);
18403 break;
7d05b9c8
YK
18404 case OPC_MSA_3RF_1A:
18405 case OPC_MSA_3RF_1B:
18406 case OPC_MSA_3RF_1C:
18407 gen_msa_3rf(env, ctx);
18408 break;
cbe50b9a
YK
18409 case OPC_MSA_VEC:
18410 gen_msa_vec(env, ctx);
18411 break;
f7685877
YK
18412 case OPC_LD_B:
18413 case OPC_LD_H:
18414 case OPC_LD_W:
18415 case OPC_LD_D:
18416 case OPC_ST_B:
18417 case OPC_ST_H:
18418 case OPC_ST_W:
18419 case OPC_ST_D:
18420 {
18421 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18422 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18423 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18424 uint8_t df = (ctx->opcode >> 0) & 0x3;
18425
f7685877 18426 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18427 TCGv taddr = tcg_temp_new();
18428 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18429
18430 switch (MASK_MSA_MINOR(opcode)) {
18431 case OPC_LD_B:
adc370a4
YK
18432 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18433 break;
f7685877 18434 case OPC_LD_H:
adc370a4
YK
18435 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18436 break;
f7685877 18437 case OPC_LD_W:
adc370a4
YK
18438 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18439 break;
f7685877 18440 case OPC_LD_D:
adc370a4 18441 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18442 break;
18443 case OPC_ST_B:
adc370a4
YK
18444 gen_helper_msa_st_b(cpu_env, twd, taddr);
18445 break;
f7685877 18446 case OPC_ST_H:
adc370a4
YK
18447 gen_helper_msa_st_h(cpu_env, twd, taddr);
18448 break;
f7685877 18449 case OPC_ST_W:
adc370a4
YK
18450 gen_helper_msa_st_w(cpu_env, twd, taddr);
18451 break;
f7685877 18452 case OPC_ST_D:
adc370a4 18453 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18454 break;
18455 }
18456
18457 tcg_temp_free_i32(twd);
adc370a4 18458 tcg_temp_free(taddr);
f7685877
YK
18459 }
18460 break;
4c789546
YK
18461 default:
18462 MIPS_INVAL("MSA instruction");
18463 generate_exception(ctx, EXCP_RI);
18464 break;
18465 }
18466
18467}
18468
d2bfa6e6 18469static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18470{
18471 int32_t offset;
18472 int rs, rt, rd, sa;
18473 uint32_t op, op1;
18474 int16_t imm;
18475
18476 /* make sure instructions are on a word boundary */
18477 if (ctx->pc & 0x3) {
18478 env->CP0_BadVAddr = ctx->pc;
aea14095 18479 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
62c68869 18480 ctx->bstate = BS_STOP;
099e5b4d
LA
18481 return;
18482 }
18483
18484 /* Handle blikely not taken case */
18485 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18486 TCGLabel *l1 = gen_new_label();
099e5b4d
LA
18487
18488 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18489 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18490 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18491 gen_goto_tb(ctx, 1, ctx->pc + 4);
18492 gen_set_label(l1);
18493 }
18494
18495 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18496 tcg_gen_debug_insn_start(ctx->pc);
18497 }
18498
18499 op = MASK_OP_MAJOR(ctx->opcode);
18500 rs = (ctx->opcode >> 21) & 0x1f;
18501 rt = (ctx->opcode >> 16) & 0x1f;
18502 rd = (ctx->opcode >> 11) & 0x1f;
18503 sa = (ctx->opcode >> 6) & 0x1f;
18504 imm = (int16_t)ctx->opcode;
18505 switch (op) {
18506 case OPC_SPECIAL:
18507 decode_opc_special(env, ctx);
18508 break;
18509 case OPC_SPECIAL2:
4267d3e6 18510 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18511 break;
18512 case OPC_SPECIAL3:
18513 decode_opc_special3(env, ctx);
18514 break;
7a387fff
TS
18515 case OPC_REGIMM:
18516 op1 = MASK_REGIMM(ctx->opcode);
18517 switch (op1) {
fecd2646
LA
18518 case OPC_BLTZL: /* REGIMM branches */
18519 case OPC_BGEZL:
18520 case OPC_BLTZALL:
18521 case OPC_BGEZALL:
d9224450 18522 check_insn(ctx, ISA_MIPS2);
fecd2646 18523 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18524 /* Fallthrough */
fecd2646
LA
18525 case OPC_BLTZ:
18526 case OPC_BGEZ:
b231c103 18527 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18528 break;
fecd2646
LA
18529 case OPC_BLTZAL:
18530 case OPC_BGEZAL:
0aefa333
YK
18531 if (ctx->insn_flags & ISA_MIPS32R6) {
18532 if (rs == 0) {
18533 /* OPC_NAL, OPC_BAL */
b231c103 18534 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18535 } else {
18536 generate_exception(ctx, EXCP_RI);
18537 }
18538 } else {
b231c103 18539 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18540 }
c9602061 18541 break;
7a387fff
TS
18542 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18543 case OPC_TNEI:
d9224450 18544 check_insn(ctx, ISA_MIPS2);
fecd2646 18545 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18546 gen_trap(ctx, op1, rs, -1, imm);
18547 break;
18548 case OPC_SYNCI:
d75c135e 18549 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18550 /* Break the TB to be able to sync copied instructions
18551 immediately */
18552 ctx->bstate = BS_STOP;
6af0bf9c 18553 break;
e45a93e2
JL
18554 case OPC_BPOSGE32: /* MIPS DSP branch */
18555#if defined(TARGET_MIPS64)
18556 case OPC_BPOSGE64:
18557#endif
18558 check_dsp(ctx);
b231c103 18559 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18560 break;
d4ea6acd
LA
18561#if defined(TARGET_MIPS64)
18562 case OPC_DAHI:
18563 check_insn(ctx, ISA_MIPS32R6);
18564 check_mips_64(ctx);
18565 if (rs != 0) {
18566 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18567 }
18568 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18569 break;
18570 case OPC_DATI:
18571 check_insn(ctx, ISA_MIPS32R6);
18572 check_mips_64(ctx);
18573 if (rs != 0) {
18574 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18575 }
18576 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18577 break;
18578#endif
6af0bf9c 18579 default: /* Invalid */
923617a3 18580 MIPS_INVAL("regimm");
6af0bf9c
FB
18581 generate_exception(ctx, EXCP_RI);
18582 break;
18583 }
18584 break;
7a387fff 18585 case OPC_CP0:
387a8fe5 18586 check_cp0_enabled(ctx);
7a387fff 18587 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18588 switch (op1) {
7a387fff
TS
18589 case OPC_MFC0:
18590 case OPC_MTC0:
ead9360e
TS
18591 case OPC_MFTR:
18592 case OPC_MTTR:
d26bc211 18593#if defined(TARGET_MIPS64)
7a387fff
TS
18594 case OPC_DMFC0:
18595 case OPC_DMTC0:
18596#endif
f1aa6320 18597#ifndef CONFIG_USER_ONLY
932e71cd 18598 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 18599#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18600 break;
18601 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 18602#ifndef CONFIG_USER_ONLY
932e71cd 18603 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 18604#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18605 break;
18606 case OPC_MFMC0:
8706c382 18607#ifndef CONFIG_USER_ONLY
932e71cd 18608 {
099e5b4d 18609 uint32_t op2;
35fbce2c 18610 TCGv t0 = tcg_temp_new();
6c5c1e20 18611
0eaef5aa 18612 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
18613 switch (op2) {
18614 case OPC_DMT:
d75c135e 18615 check_insn(ctx, ASE_MT);
9ed5726c 18616 gen_helper_dmt(t0);
35fbce2c 18617 gen_store_gpr(t0, rt);
6c5c1e20
TS
18618 break;
18619 case OPC_EMT:
d75c135e 18620 check_insn(ctx, ASE_MT);
9ed5726c 18621 gen_helper_emt(t0);
35fbce2c 18622 gen_store_gpr(t0, rt);
da80682b 18623 break;
6c5c1e20 18624 case OPC_DVPE:
d75c135e 18625 check_insn(ctx, ASE_MT);
895c2d04 18626 gen_helper_dvpe(t0, cpu_env);
35fbce2c 18627 gen_store_gpr(t0, rt);
6c5c1e20
TS
18628 break;
18629 case OPC_EVPE:
d75c135e 18630 check_insn(ctx, ASE_MT);
895c2d04 18631 gen_helper_evpe(t0, cpu_env);
35fbce2c 18632 gen_store_gpr(t0, rt);
6c5c1e20
TS
18633 break;
18634 case OPC_DI:
d75c135e 18635 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18636 save_cpu_state(ctx, 1);
895c2d04 18637 gen_helper_di(t0, cpu_env);
35fbce2c 18638 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18639 /* Stop translation as we may have switched
18640 the execution mode. */
6c5c1e20
TS
18641 ctx->bstate = BS_STOP;
18642 break;
18643 case OPC_EI:
d75c135e 18644 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18645 save_cpu_state(ctx, 1);
895c2d04 18646 gen_helper_ei(t0, cpu_env);
35fbce2c 18647 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18648 /* Stop translation as we may have switched
18649 the execution mode. */
6c5c1e20
TS
18650 ctx->bstate = BS_STOP;
18651 break;
18652 default: /* Invalid */
18653 MIPS_INVAL("mfmc0");
18654 generate_exception(ctx, EXCP_RI);
18655 break;
18656 }
6c5c1e20 18657 tcg_temp_free(t0);
7a387fff 18658 }
0eaef5aa 18659#endif /* !CONFIG_USER_ONLY */
6af0bf9c 18660 break;
7a387fff 18661 case OPC_RDPGPR:
d75c135e 18662 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18663 gen_load_srsgpr(rt, rd);
ead9360e 18664 break;
7a387fff 18665 case OPC_WRPGPR:
d75c135e 18666 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18667 gen_store_srsgpr(rt, rd);
38121543 18668 break;
6af0bf9c 18669 default:
923617a3 18670 MIPS_INVAL("cp0");
7a387fff 18671 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
18672 break;
18673 }
18674 break;
31837be3
YK
18675 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18676 if (ctx->insn_flags & ISA_MIPS32R6) {
18677 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18678 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18679 } else {
18680 /* OPC_ADDI */
18681 /* Arithmetic with immediate opcode */
18682 gen_arith_imm(ctx, op, rt, rs, imm);
18683 }
18684 break;
324d9e32 18685 case OPC_ADDIU:
d75c135e 18686 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18687 break;
324d9e32
AJ
18688 case OPC_SLTI: /* Set on less than with immediate opcode */
18689 case OPC_SLTIU:
d75c135e 18690 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
18691 break;
18692 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 18693 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
18694 case OPC_ORI:
18695 case OPC_XORI:
d75c135e 18696 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 18697 break;
7a387fff
TS
18698 case OPC_J ... OPC_JAL: /* Jump */
18699 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18700 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 18701 break;
31837be3
YK
18702 /* Branch */
18703 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18704 if (ctx->insn_flags & ISA_MIPS32R6) {
18705 if (rt == 0) {
18706 generate_exception(ctx, EXCP_RI);
18707 break;
18708 }
18709 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18710 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18711 } else {
18712 /* OPC_BLEZL */
b231c103 18713 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18714 }
18715 break;
18716 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18717 if (ctx->insn_flags & ISA_MIPS32R6) {
18718 if (rt == 0) {
18719 generate_exception(ctx, EXCP_RI);
18720 break;
18721 }
18722 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18723 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18724 } else {
18725 /* OPC_BGTZL */
b231c103 18726 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18727 }
18728 break;
18729 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18730 if (rt == 0) {
18731 /* OPC_BLEZ */
b231c103 18732 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18733 } else {
18734 check_insn(ctx, ISA_MIPS32R6);
18735 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18736 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18737 }
18738 break;
18739 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18740 if (rt == 0) {
18741 /* OPC_BGTZ */
b231c103 18742 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18743 } else {
18744 check_insn(ctx, ISA_MIPS32R6);
18745 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18746 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18747 }
18748 break;
18749 case OPC_BEQL:
18750 case OPC_BNEL:
d9224450 18751 check_insn(ctx, ISA_MIPS2);
fecd2646 18752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18753 /* Fallthrough */
31837be3
YK
18754 case OPC_BEQ:
18755 case OPC_BNE:
b231c103 18756 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 18757 break;
d9224450
MR
18758 case OPC_LL: /* Load and stores */
18759 check_insn(ctx, ISA_MIPS2);
18760 /* Fallthrough */
18761 case OPC_LWL:
fecd2646
LA
18762 case OPC_LWR:
18763 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18764 /* Fallthrough */
fecd2646
LA
18765 case OPC_LB ... OPC_LH:
18766 case OPC_LW ... OPC_LHU:
d75c135e 18767 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 18768 break;
fecd2646 18769 case OPC_SWL:
7a387fff 18770 case OPC_SWR:
fecd2646 18771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18772 /* fall through */
fecd2646
LA
18773 case OPC_SB ... OPC_SH:
18774 case OPC_SW:
5c13fdfd 18775 gen_st(ctx, op, rt, rs, imm);
7a387fff 18776 break;
d66c7132 18777 case OPC_SC:
d9224450 18778 check_insn(ctx, ISA_MIPS2);
4368b29a 18779 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
18780 gen_st_cond(ctx, op, rt, rs, imm);
18781 break;
7a387fff 18782 case OPC_CACHE:
bf7910c6 18783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 18784 check_cp0_enabled(ctx);
d75c135e 18785 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 18786 /* Treat as NOP. */
34ae7b51 18787 break;
7a387fff 18788 case OPC_PREF:
bf7910c6 18789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18790 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 18791 /* Treat as NOP. */
6af0bf9c 18792 break;
4ad40f36 18793
923617a3 18794 /* Floating point (COP1). */
7a387fff
TS
18795 case OPC_LWC1:
18796 case OPC_LDC1:
18797 case OPC_SWC1:
18798 case OPC_SDC1:
5ab5c041 18799 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
18800 break;
18801
7a387fff 18802 case OPC_CP1:
5692c6e1
YK
18803 op1 = MASK_CP1(ctx->opcode);
18804
18805 switch (op1) {
18806 case OPC_MFHC1:
18807 case OPC_MTHC1:
5e755519 18808 check_cp1_enabled(ctx);
5692c6e1
YK
18809 check_insn(ctx, ISA_MIPS32R2);
18810 case OPC_MFC1:
18811 case OPC_CFC1:
18812 case OPC_MTC1:
18813 case OPC_CTC1:
18814 check_cp1_enabled(ctx);
18815 gen_cp1(ctx, op1, rt, rd);
18816 break;
d26bc211 18817#if defined(TARGET_MIPS64)
5692c6e1
YK
18818 case OPC_DMFC1:
18819 case OPC_DMTC1:
18820 check_cp1_enabled(ctx);
18821 check_insn(ctx, ISA_MIPS3);
d9224450 18822 check_mips_64(ctx);
5692c6e1
YK
18823 gen_cp1(ctx, op1, rt, rd);
18824 break;
e189e748 18825#endif
5692c6e1
YK
18826 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18827 check_cp1_enabled(ctx);
18828 if (ctx->insn_flags & ISA_MIPS32R6) {
18829 /* OPC_BC1EQZ */
31837be3
YK
18830 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18831 rt, imm << 2);
5692c6e1
YK
18832 } else {
18833 /* OPC_BC1ANY2 */
b8aa4598 18834 check_cop1x(ctx);
d75c135e 18835 check_insn(ctx, ASE_MIPS3D);
d75c135e 18836 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 18837 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
18838 }
18839 break;
18840 case OPC_BC1NEZ:
18841 check_cp1_enabled(ctx);
18842 check_insn(ctx, ISA_MIPS32R6);
18843 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18844 rt, imm << 2);
18845 break;
18846 case OPC_BC1ANY4:
18847 check_cp1_enabled(ctx);
18848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18849 check_cop1x(ctx);
18850 check_insn(ctx, ASE_MIPS3D);
18851 /* fall through */
18852 case OPC_BC1:
18853 check_cp1_enabled(ctx);
18854 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18855 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18856 (rt >> 2) & 0x7, imm << 2);
18857 break;
18858 case OPC_PS_FMT:
18859 check_cp1_enabled(ctx);
18860 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18861 /* fall through */
5692c6e1
YK
18862 case OPC_S_FMT:
18863 case OPC_D_FMT:
18864 check_cp1_enabled(ctx);
18865 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18866 (imm >> 8) & 0x7);
18867 break;
18868 case OPC_W_FMT:
18869 case OPC_L_FMT:
18870 {
18871 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18872 check_cp1_enabled(ctx);
18873 if (ctx->insn_flags & ISA_MIPS32R6) {
18874 switch (r6_op) {
18875 case R6_OPC_CMP_AF_S:
18876 case R6_OPC_CMP_UN_S:
18877 case R6_OPC_CMP_EQ_S:
18878 case R6_OPC_CMP_UEQ_S:
18879 case R6_OPC_CMP_LT_S:
18880 case R6_OPC_CMP_ULT_S:
18881 case R6_OPC_CMP_LE_S:
18882 case R6_OPC_CMP_ULE_S:
18883 case R6_OPC_CMP_SAF_S:
18884 case R6_OPC_CMP_SUN_S:
18885 case R6_OPC_CMP_SEQ_S:
18886 case R6_OPC_CMP_SEUQ_S:
18887 case R6_OPC_CMP_SLT_S:
18888 case R6_OPC_CMP_SULT_S:
18889 case R6_OPC_CMP_SLE_S:
18890 case R6_OPC_CMP_SULE_S:
18891 case R6_OPC_CMP_OR_S:
18892 case R6_OPC_CMP_UNE_S:
18893 case R6_OPC_CMP_NE_S:
18894 case R6_OPC_CMP_SOR_S:
18895 case R6_OPC_CMP_SUNE_S:
18896 case R6_OPC_CMP_SNE_S:
18897 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18898 break;
18899 case R6_OPC_CMP_AF_D:
18900 case R6_OPC_CMP_UN_D:
18901 case R6_OPC_CMP_EQ_D:
18902 case R6_OPC_CMP_UEQ_D:
18903 case R6_OPC_CMP_LT_D:
18904 case R6_OPC_CMP_ULT_D:
18905 case R6_OPC_CMP_LE_D:
18906 case R6_OPC_CMP_ULE_D:
18907 case R6_OPC_CMP_SAF_D:
18908 case R6_OPC_CMP_SUN_D:
18909 case R6_OPC_CMP_SEQ_D:
18910 case R6_OPC_CMP_SEUQ_D:
18911 case R6_OPC_CMP_SLT_D:
18912 case R6_OPC_CMP_SULT_D:
18913 case R6_OPC_CMP_SLE_D:
18914 case R6_OPC_CMP_SULE_D:
18915 case R6_OPC_CMP_OR_D:
18916 case R6_OPC_CMP_UNE_D:
18917 case R6_OPC_CMP_NE_D:
18918 case R6_OPC_CMP_SOR_D:
18919 case R6_OPC_CMP_SUNE_D:
18920 case R6_OPC_CMP_SNE_D:
18921 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18922 break;
18923 default:
d2bfa6e6
MR
18924 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
18925 rt, rd, sa, (imm >> 8) & 0x7);
18926
5692c6e1 18927 break;
3f493883 18928 }
5692c6e1
YK
18929 } else {
18930 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18931 (imm >> 8) & 0x7);
36d23958 18932 }
5692c6e1
YK
18933 break;
18934 }
18935 case OPC_BZ_V:
18936 case OPC_BNZ_V:
18937 case OPC_BZ_B:
18938 case OPC_BZ_H:
18939 case OPC_BZ_W:
18940 case OPC_BZ_D:
18941 case OPC_BNZ_B:
18942 case OPC_BNZ_H:
18943 case OPC_BNZ_W:
18944 case OPC_BNZ_D:
18945 check_insn(ctx, ASE_MSA);
18946 gen_msa_branch(env, ctx, op1);
18947 break;
18948 default:
18949 MIPS_INVAL("cp1");
18950 generate_exception(ctx, EXCP_RI);
18951 break;
6ea83fed 18952 }
4ad40f36
FB
18953 break;
18954
31837be3
YK
18955 /* Compact branches [R6] and COP2 [non-R6] */
18956 case OPC_BC: /* OPC_LWC2 */
18957 case OPC_BALC: /* OPC_SWC2 */
18958 if (ctx->insn_flags & ISA_MIPS32R6) {
18959 /* OPC_BC, OPC_BALC */
18960 gen_compute_compact_branch(ctx, op, 0, 0,
18961 sextract32(ctx->opcode << 2, 0, 28));
18962 } else {
18963 /* OPC_LWC2, OPC_SWC2 */
18964 /* COP2: Not implemented. */
18965 generate_exception_err(ctx, EXCP_CpU, 2);
18966 }
18967 break;
18968 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18969 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
18970 if (ctx->insn_flags & ISA_MIPS32R6) {
18971 if (rs != 0) {
18972 /* OPC_BEQZC, OPC_BNEZC */
18973 gen_compute_compact_branch(ctx, op, rs, 0,
18974 sextract32(ctx->opcode << 2, 0, 23));
18975 } else {
18976 /* OPC_JIC, OPC_JIALC */
18977 gen_compute_compact_branch(ctx, op, 0, rt, imm);
18978 }
18979 } else {
18980 /* OPC_LWC2, OPC_SWC2 */
18981 /* COP2: Not implemented. */
18982 generate_exception_err(ctx, EXCP_CpU, 2);
18983 }
4ad40f36 18984 break;
bd277fa1 18985 case OPC_CP2:
d75c135e 18986 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
18987 /* Note that these instructions use different fields. */
18988 gen_loongson_multimedia(ctx, sa, rd, rt);
18989 break;
4ad40f36 18990
7a387fff 18991 case OPC_CP3:
fecd2646 18992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 18993 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 18994 check_cp1_enabled(ctx);
36d23958
TS
18995 op1 = MASK_CP3(ctx->opcode);
18996 switch (op1) {
d9224450
MR
18997 case OPC_LUXC1:
18998 case OPC_SUXC1:
18999 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19000 /* Fallthrough */
5a5012ec
TS
19001 case OPC_LWXC1:
19002 case OPC_LDXC1:
5a5012ec
TS
19003 case OPC_SWXC1:
19004 case OPC_SDXC1:
d9224450 19005 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19006 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19007 break;
e0c84da7 19008 case OPC_PREFX:
d9224450 19009 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19010 /* Treat as NOP. */
e0c84da7 19011 break;
5a5012ec 19012 case OPC_ALNV_PS:
d9224450
MR
19013 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19014 /* Fallthrough */
5a5012ec
TS
19015 case OPC_MADD_S:
19016 case OPC_MADD_D:
19017 case OPC_MADD_PS:
19018 case OPC_MSUB_S:
19019 case OPC_MSUB_D:
19020 case OPC_MSUB_PS:
19021 case OPC_NMADD_S:
19022 case OPC_NMADD_D:
19023 case OPC_NMADD_PS:
19024 case OPC_NMSUB_S:
19025 case OPC_NMSUB_D:
19026 case OPC_NMSUB_PS:
d9224450 19027 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19028 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19029 break;
36d23958 19030 default:
923617a3 19031 MIPS_INVAL("cp3");
e397ee33 19032 generate_exception (ctx, EXCP_RI);
36d23958
TS
19033 break;
19034 }
19035 } else {
e397ee33 19036 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19037 }
4ad40f36
FB
19038 break;
19039
d26bc211 19040#if defined(TARGET_MIPS64)
7a387fff 19041 /* MIPS64 opcodes */
7a387fff 19042 case OPC_LDL ... OPC_LDR:
bf7910c6 19043 case OPC_LLD:
fecd2646 19044 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19045 /* fall through */
fecd2646 19046 case OPC_LWU:
7a387fff 19047 case OPC_LD:
d75c135e 19048 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19049 check_mips_64(ctx);
d75c135e 19050 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19051 break;
19052 case OPC_SDL ... OPC_SDR:
fecd2646 19053 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19054 /* fall through */
7a387fff 19055 case OPC_SD:
d75c135e 19056 check_insn(ctx, ISA_MIPS3);
e189e748 19057 check_mips_64(ctx);
5c13fdfd 19058 gen_st(ctx, op, rt, rs, imm);
7a387fff 19059 break;
d66c7132 19060 case OPC_SCD:
bf7910c6 19061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19062 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19063 check_mips_64(ctx);
19064 gen_st_cond(ctx, op, rt, rs, imm);
19065 break;
31837be3
YK
19066 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19067 if (ctx->insn_flags & ISA_MIPS32R6) {
19068 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19069 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19070 } else {
19071 /* OPC_DADDI */
19072 check_insn(ctx, ISA_MIPS3);
19073 check_mips_64(ctx);
19074 gen_arith_imm(ctx, op, rt, rs, imm);
19075 }
19076 break;
324d9e32 19077 case OPC_DADDIU:
d75c135e 19078 check_insn(ctx, ISA_MIPS3);
e189e748 19079 check_mips_64(ctx);
d75c135e 19080 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19081 break;
31837be3
YK
19082#else
19083 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19084 if (ctx->insn_flags & ISA_MIPS32R6) {
19085 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19086 } else {
19087 MIPS_INVAL("major opcode");
19088 generate_exception(ctx, EXCP_RI);
19089 }
19090 break;
6af0bf9c 19091#endif
d4ea6acd
LA
19092 case OPC_DAUI: /* OPC_JALX */
19093 if (ctx->insn_flags & ISA_MIPS32R6) {
19094#if defined(TARGET_MIPS64)
19095 /* OPC_DAUI */
19096 check_mips_64(ctx);
19097 if (rt != 0) {
19098 TCGv t0 = tcg_temp_new();
19099 gen_load_gpr(t0, rs);
19100 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19101 tcg_temp_free(t0);
19102 }
19103 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19104#else
19105 generate_exception(ctx, EXCP_RI);
19106 MIPS_INVAL("major opcode");
19107#endif
19108 } else {
19109 /* OPC_JALX */
19110 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19111 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19112 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19113 }
364d4831 19114 break;
4c789546 19115 case OPC_MSA: /* OPC_MDMX */
7a387fff 19116 /* MDMX: Not implemented. */
4c789546 19117 gen_msa(env, ctx);
d4ea6acd
LA
19118 break;
19119 case OPC_PCREL:
19120 check_insn(ctx, ISA_MIPS32R6);
19121 gen_pcrel(ctx, rs, imm);
19122 break;
6af0bf9c 19123 default: /* Invalid */
923617a3 19124 MIPS_INVAL("major opcode");
6af0bf9c
FB
19125 generate_exception(ctx, EXCP_RI);
19126 break;
19127 }
6af0bf9c
FB
19128}
19129
2cfc5f17 19130static inline void
6429db34
AF
19131gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19132 bool search_pc)
6af0bf9c 19133{
ed2803da 19134 CPUState *cs = CPU(cpu);
6429db34 19135 CPUMIPSState *env = &cpu->env;
278d0702 19136 DisasContext ctx;
6af0bf9c 19137 target_ulong pc_start;
fe237291 19138 target_ulong next_page_start;
a1d1bb31 19139 CPUBreakpoint *bp;
6af0bf9c 19140 int j, lj = -1;
2e70f6ef
PB
19141 int num_insns;
19142 int max_insns;
c9602061 19143 int insn_bytes;
339cd2a8 19144 int is_slot;
6af0bf9c 19145
93fcfe39
AL
19146 if (search_pc)
19147 qemu_log("search pc %d\n", search_pc);
4ad40f36 19148
6af0bf9c 19149 pc_start = tb->pc;
fe237291 19150 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19151 ctx.pc = pc_start;
4ad40f36 19152 ctx.saved_pc = -1;
ed2803da 19153 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19154 ctx.insn_flags = env->insn_flags;
5ab5c041 19155 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19156 ctx.tb = tb;
19157 ctx.bstate = BS_NONE;
e98c0d17 19158 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19159 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19160 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19161 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19162 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 19163 /* Restore delay slot state from the tb context. */
c068688b 19164 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19165 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
fd4a04eb 19166 restore_cpu_state(env, &ctx);
932e71cd 19167#ifdef CONFIG_USER_ONLY
0eaef5aa 19168 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19169#else
0eaef5aa 19170 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19171#endif
be3a8c53
YK
19172 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19173 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19174 num_insns = 0;
19175 max_insns = tb->cflags & CF_COUNT_MASK;
19176 if (max_insns == 0)
19177 max_insns = CF_COUNT_MASK;
d12d51d5 19178 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19179 gen_tb_start(tb);
faf7aaa9 19180 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19181 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19182 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19183 if (bp->pc == ctx.pc) {
278d0702 19184 save_cpu_state(&ctx, 1);
4ad40f36 19185 ctx.bstate = BS_BRANCH;
895c2d04 19186 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
19187 /* Include the breakpoint location or the tb won't
19188 * be flushed when it must be. */
19189 ctx.pc += 4;
4ad40f36
FB
19190 goto done_generating;
19191 }
19192 }
19193 }
19194
6af0bf9c 19195 if (search_pc) {
fe700adb 19196 j = tcg_op_buf_count();
6af0bf9c
FB
19197 if (lj < j) {
19198 lj++;
19199 while (lj < j)
ab1103de 19200 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19201 }
25983cad 19202 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19203 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19204 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19205 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19206 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19207 }
2e70f6ef
PB
19208 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19209 gen_io_start();
c9602061 19210
339cd2a8 19211 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19212 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19213 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19214 insn_bytes = 4;
240ce26a 19215 decode_opc(env, &ctx);
d75c135e 19216 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19217 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19218 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19219 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19220 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19221 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
19222 } else {
19223 generate_exception(&ctx, EXCP_RI);
3c824109 19224 ctx.bstate = BS_STOP;
c9602061
NF
19225 break;
19226 }
31837be3 19227
b231c103 19228 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19229 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19230 MIPS_HFLAG_FBNSLOT))) {
19231 /* force to generate branch as there is neither delay nor
19232 forbidden slot */
19233 is_slot = 1;
b231c103
YK
19234 }
19235 }
339cd2a8 19236 if (is_slot) {
31837be3 19237 gen_branch(&ctx, insn_bytes);
c9602061
NF
19238 }
19239 ctx.pc += insn_bytes;
19240
2e70f6ef 19241 num_insns++;
4ad40f36 19242
7b270ef2
NF
19243 /* Execute a branch and its delay slot as a single instruction.
19244 This is what GDB expects and is consistent with what the
19245 hardware does (e.g. if a delay slot instruction faults, the
19246 reported PC is the PC of the branch). */
ed2803da 19247 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19248 break;
ed2803da 19249 }
4ad40f36 19250
fe237291 19251 if (ctx.pc >= next_page_start) {
6af0bf9c 19252 break;
fe237291 19253 }
4ad40f36 19254
fe700adb 19255 if (tcg_op_buf_full()) {
faf7aaa9 19256 break;
efd7f486 19257 }
faf7aaa9 19258
2e70f6ef
PB
19259 if (num_insns >= max_insns)
19260 break;
1b530a6d
AJ
19261
19262 if (singlestep)
19263 break;
6af0bf9c 19264 }
ed2803da 19265 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19266 gen_io_end();
ed2803da
AF
19267 }
19268 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19269 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 19270 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 19271 } else {
6958549d 19272 switch (ctx.bstate) {
16c00cb2 19273 case BS_STOP:
df1561e2
TS
19274 gen_goto_tb(&ctx, 0, ctx.pc);
19275 break;
16c00cb2 19276 case BS_NONE:
278d0702 19277 save_cpu_state(&ctx, 0);
16c00cb2
TS
19278 gen_goto_tb(&ctx, 0, ctx.pc);
19279 break;
5a5012ec 19280 case BS_EXCP:
57fec1fe 19281 tcg_gen_exit_tb(0);
16c00cb2 19282 break;
5a5012ec
TS
19283 case BS_BRANCH:
19284 default:
19285 break;
6958549d 19286 }
6af0bf9c 19287 }
4ad40f36 19288done_generating:
806f352d 19289 gen_tb_end(tb, num_insns);
0a7df5da 19290
6af0bf9c 19291 if (search_pc) {
fe700adb 19292 j = tcg_op_buf_count();
6af0bf9c
FB
19293 lj++;
19294 while (lj <= j)
ab1103de 19295 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19296 } else {
19297 tb->size = ctx.pc - pc_start;
2e70f6ef 19298 tb->icount = num_insns;
6af0bf9c
FB
19299 }
19300#ifdef DEBUG_DISAS
d12d51d5 19301 LOG_DISAS("\n");
8fec2b8c 19302 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19303 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 19304 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19305 qemu_log("\n");
6af0bf9c
FB
19306 }
19307#endif
6af0bf9c
FB
19308}
19309
7db13fae 19310void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19311{
6429db34 19312 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19313}
19314
7db13fae 19315void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19316{
6429db34 19317 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19318}
19319
7db13fae 19320static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19321 int flags)
6ea83fed
FB
19322{
19323 int i;
5e755519 19324 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19325
2a5612e6
SW
19326#define printfpr(fp) \
19327 do { \
19328 if (is_fpu64) \
19329 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19330 " fd:%13g fs:%13g psu: %13g\n", \
19331 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19332 (double)(fp)->fd, \
19333 (double)(fp)->fs[FP_ENDIAN_IDX], \
19334 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19335 else { \
19336 fpr_t tmp; \
19337 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19338 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19339 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19340 " fd:%13g fs:%13g psu:%13g\n", \
19341 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19342 (double)tmp.fd, \
19343 (double)tmp.fs[FP_ENDIAN_IDX], \
19344 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19345 } \
6ea83fed
FB
19346 } while(0)
19347
5a5012ec 19348
9a78eead
SW
19349 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19350 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19351 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19352 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19353 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19354 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19355 }
19356
19357#undef printfpr
19358}
19359
d26bc211 19360#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 19361/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 19362 sign-extended values on 64bit machines. */
c570fd16
TS
19363
19364#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19365
8706c382 19366static void
7db13fae 19367cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 19368 fprintf_function cpu_fprintf,
8706c382 19369 int flags)
c570fd16
TS
19370{
19371 int i;
19372
b5dc7732
TS
19373 if (!SIGN_EXT_P(env->active_tc.PC))
19374 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19375 if (!SIGN_EXT_P(env->active_tc.HI[0]))
19376 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19377 if (!SIGN_EXT_P(env->active_tc.LO[0]))
19378 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 19379 if (!SIGN_EXT_P(env->btarget))
3594c774 19380 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
19381
19382 for (i = 0; i < 32; i++) {
b5dc7732
TS
19383 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19384 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
19385 }
19386
19387 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 19388 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
19389 if (!SIGN_EXT_P(env->lladdr))
19390 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
19391}
19392#endif
19393
878096ee
AF
19394void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19395 int flags)
6af0bf9c 19396{
878096ee
AF
19397 MIPSCPU *cpu = MIPS_CPU(cs);
19398 CPUMIPSState *env = &cpu->env;
6af0bf9c 19399 int i;
3b46e624 19400
a7200c9f
SW
19401 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19402 " LO=0x" TARGET_FMT_lx " ds %04x "
19403 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19404 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19405 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19406 for (i = 0; i < 32; i++) {
19407 if ((i & 3) == 0)
19408 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19409 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19410 if ((i & 3) == 3)
19411 cpu_fprintf(f, "\n");
19412 }
568b600d 19413
3594c774 19414 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19415 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 19416 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 19417 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19418 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19419 env->CP0_Config2, env->CP0_Config3);
19420 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19421 env->CP0_Config4, env->CP0_Config5);
5e755519 19422 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19423 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 19424#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
19425 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19426#endif
6af0bf9c
FB
19427}
19428
78ce64f4 19429void mips_tcg_init(void)
39454628 19430{
f01be154 19431 int i;
39454628
TS
19432 static int inited;
19433
19434 /* Initialize various static tables. */
19435 if (inited)
6958549d 19436 return;
39454628 19437
a7812ae4 19438 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19439 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19440 for (i = 1; i < 32; i++)
a7812ae4 19441 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19442 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19443 regnames[i]);
d73ee8a2 19444
863f264d
YK
19445 for (i = 0; i < 32; i++) {
19446 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19447 msa_wr_d[i * 2] =
19448 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19449 /* The scalar floating-point unit (FPU) registers are mapped on
19450 * the MSA vector registers. */
19451 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19452 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19453 msa_wr_d[i * 2 + 1] =
19454 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19455 }
19456
a7812ae4 19457 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19458 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19459 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19460 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19461 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19462 regnames_HI[i]);
a7812ae4 19463 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19464 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19465 regnames_LO[i]);
4b2eb8d2 19466 }
a7812ae4 19467 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19468 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19469 "DSPControl");
1ba74fb8 19470 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19471 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19472 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19473 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19474 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19475 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19476
a7812ae4 19477 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19478 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19479 "fcr0");
19480 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19481 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19482 "fcr31");
39454628
TS
19483
19484 inited = 1;
19485}
19486
aaed909a
FB
19487#include "translate_init.c"
19488
30bf942d 19489MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19490{
0f71a709 19491 MIPSCPU *cpu;
6af0bf9c 19492 CPUMIPSState *env;
c227f099 19493 const mips_def_t *def;
6af0bf9c 19494
aaed909a
FB
19495 def = cpu_mips_find_by_name(cpu_model);
19496 if (!def)
19497 return NULL;
0f71a709
AF
19498 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19499 env = &cpu->env;
aaed909a
FB
19500 env->cpu_model = def;
19501
51cc2e78
BS
19502#ifndef CONFIG_USER_ONLY
19503 mmu_init(env, def);
19504#endif
19505 fpu_init(env, def);
19506 mvp_init(env, def);
c1caf1d9
AF
19507
19508 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19509
30bf942d 19510 return cpu;
6ae81775
TS
19511}
19512
1bba0dc9 19513void cpu_state_reset(CPUMIPSState *env)
6ae81775 19514{
55e5c285
AF
19515 MIPSCPU *cpu = mips_env_get_cpu(env);
19516 CPUState *cs = CPU(cpu);
6ae81775 19517
51cc2e78
BS
19518 /* Reset registers to their default values */
19519 env->CP0_PRid = env->cpu_model->CP0_PRid;
19520 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19521#ifdef TARGET_WORDS_BIGENDIAN
19522 env->CP0_Config0 |= (1 << CP0C0_BE);
19523#endif
19524 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19525 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19526 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19527 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19528 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19529 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19530 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19531 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19532 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19533 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19534 << env->cpu_model->CP0_LLAddr_shift;
19535 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19536 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19537 env->CCRes = env->cpu_model->CCRes;
19538 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19539 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19540 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19541 env->current_tc = 0;
19542 env->SEGBITS = env->cpu_model->SEGBITS;
19543 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19544#if defined(TARGET_MIPS64)
19545 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19546 env->SEGMask |= 3ULL << 62;
19547 }
19548#endif
19549 env->PABITS = env->cpu_model->PABITS;
19550 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19551 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19552 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19553 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19554 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19555 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19556 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19557 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19558 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19559 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19560 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19561 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19562 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19563 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19564 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19565 env->insn_flags = env->cpu_model->insn_flags;
19566
0eaef5aa 19567#if defined(CONFIG_USER_ONLY)
03e6e501 19568 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19569# ifdef TARGET_MIPS64
19570 /* Enable 64-bit register mode. */
19571 env->CP0_Status |= (1 << CP0St_PX);
19572# endif
19573# ifdef TARGET_ABI_MIPSN64
19574 /* Enable 64-bit address mode. */
19575 env->CP0_Status |= (1 << CP0St_UX);
19576# endif
94159135
MI
19577 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19578 hardware registers. */
19579 env->CP0_HWREna |= 0x0000000F;
91a75935 19580 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19581 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19582 }
6f0af304
PJ
19583 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19584 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19585 }
4d66261f
PJ
19586# if defined(TARGET_MIPS64)
19587 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19588 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19589 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19590 env->CP0_Status |= (1 << CP0St_FR);
19591 }
4d66261f 19592# endif
932e71cd
AJ
19593#else
19594 if (env->hflags & MIPS_HFLAG_BMASK) {
19595 /* If the exception was raised from a delay slot,
19596 come back to the jump. */
c3577479
MR
19597 env->CP0_ErrorEPC = (env->active_tc.PC
19598 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 19599 } else {
932e71cd
AJ
19600 env->CP0_ErrorEPC = env->active_tc.PC;
19601 }
19602 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19603 env->CP0_Random = env->tlb->nb_tlb - 1;
19604 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19605 env->CP0_Wired = 0;
0a2672b7
JH
19606 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19607 if (kvm_enabled()) {
19608 env->CP0_EBase |= 0x40000000;
19609 } else {
19610 env->CP0_EBase |= 0x80000000;
19611 }
932e71cd
AJ
19612 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19613 /* vectored interrupts not implemented, timer on int 7,
19614 no performance counters. */
19615 env->CP0_IntCtl = 0xe0000000;
19616 {
19617 int i;
19618
19619 for (i = 0; i < 7; i++) {
19620 env->CP0_WatchLo[i] = 0;
19621 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 19622 }
932e71cd
AJ
19623 env->CP0_WatchLo[7] = 0;
19624 env->CP0_WatchHi[7] = 0;
fd88b6ab 19625 }
932e71cd
AJ
19626 /* Count register increments in debug mode, EJTAG version 1 */
19627 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 19628
4b69c7e2
JH
19629 cpu_mips_store_count(env, 1);
19630
9e56e756
EI
19631 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19632 int i;
19633
19634 /* Only TC0 on VPE 0 starts as active. */
19635 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 19636 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
19637 env->tcs[i].CP0_TCHalt = 1;
19638 }
19639 env->active_tc.CP0_TCHalt = 1;
259186a7 19640 cs->halted = 1;
9e56e756 19641
55e5c285 19642 if (cs->cpu_index == 0) {
9e56e756
EI
19643 /* VPE0 starts up enabled. */
19644 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19645 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19646
19647 /* TC0 starts up unhalted. */
259186a7 19648 cs->halted = 0;
9e56e756
EI
19649 env->active_tc.CP0_TCHalt = 0;
19650 env->tcs[0].CP0_TCHalt = 0;
19651 /* With thread 0 active. */
19652 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19653 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19654 }
19655 }
51cc2e78 19656#endif
ddc584bd
LA
19657 if ((env->insn_flags & ISA_MIPS32R6) &&
19658 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19659 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19660 env->CP0_Status |= (1 << CP0St_FR);
19661 }
19662
863f264d
YK
19663 /* MSA */
19664 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19665 msa_reset(env);
19666 }
19667
03e6e501 19668 compute_hflags(env);
bb962386
MR
19669 restore_rounding_mode(env);
19670 restore_flush_mode(env);
27103424 19671 cs->exception_index = EXCP_NONE;
6af0bf9c 19672}
d2856f1a 19673
7db13fae 19674void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 19675{
25983cad 19676 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
19677 env->hflags &= ~MIPS_HFLAG_BMASK;
19678 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
19679 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19680 case MIPS_HFLAG_BR:
19681 break;
19682 case MIPS_HFLAG_BC:
19683 case MIPS_HFLAG_BL:
19684 case MIPS_HFLAG_B:
19685 env->btarget = gen_opc_btarget[pc_pos];
19686 break;
19687 }
d2856f1a 19688}