]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: add MSA 3RF format instructions
[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;
1417 uint32_t hflags, saved_hflags;
1418 int bstate;
1419 target_ulong btarget;
d279279e 1420 bool ulri;
e98c0d17 1421 int kscrexist;
7207c7f9 1422 bool rxi;
9456c2fb 1423 int ie;
aea14095
LA
1424 bool bi;
1425 bool bp;
8e9ade68
TS
1426} DisasContext;
1427
1428enum {
1429 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1430 * exception condition */
8e9ade68
TS
1431 BS_STOP = 1, /* We want to stop translation for any reason */
1432 BS_BRANCH = 2, /* We reached a branch condition */
1433 BS_EXCP = 3, /* We reached an exception condition */
1434};
1435
d73ee8a2
RH
1436static const char * const regnames[] = {
1437 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1438 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1439 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1440 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1441};
6af0bf9c 1442
d73ee8a2
RH
1443static const char * const regnames_HI[] = {
1444 "HI0", "HI1", "HI2", "HI3",
1445};
4b2eb8d2 1446
d73ee8a2
RH
1447static const char * const regnames_LO[] = {
1448 "LO0", "LO1", "LO2", "LO3",
1449};
4b2eb8d2 1450
d73ee8a2
RH
1451static const char * const fregnames[] = {
1452 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1453 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1454 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1455 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1456};
958fb4a9 1457
863f264d
YK
1458static const char * const msaregnames[] = {
1459 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1460 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1461 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1462 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1463 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1464 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1465 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1466 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1467 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1468 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1469 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1470 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1471 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1472 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1473 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1474 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1475};
1476
fb7729e2
RH
1477#define MIPS_DEBUG(fmt, ...) \
1478 do { \
1479 if (MIPS_DEBUG_DISAS) { \
1480 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1481 TARGET_FMT_lx ": %08x " fmt "\n", \
1482 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1483 } \
1484 } while (0)
1485
1486#define LOG_DISAS(...) \
1487 do { \
1488 if (MIPS_DEBUG_DISAS) { \
1489 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1490 } \
1491 } while (0)
958fb4a9 1492
8e9ade68 1493#define MIPS_INVAL(op) \
8e9ade68 1494 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1495 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1496
8e9ade68
TS
1497/* General purpose registers moves. */
1498static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1499{
8e9ade68
TS
1500 if (reg == 0)
1501 tcg_gen_movi_tl(t, 0);
1502 else
4b2eb8d2 1503 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1504}
1505
8e9ade68 1506static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1507{
8e9ade68 1508 if (reg != 0)
4b2eb8d2 1509 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1510}
1511
8e9ade68 1512/* Moves to/from shadow registers. */
be24bb4f 1513static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1514{
d9bea114 1515 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1516
1517 if (from == 0)
d9bea114 1518 tcg_gen_movi_tl(t0, 0);
8e9ade68 1519 else {
d9bea114 1520 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1521 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1522
7db13fae 1523 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1524 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1525 tcg_gen_andi_i32(t2, t2, 0xf);
1526 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1527 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1528 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1529
d9bea114 1530 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1531 tcg_temp_free_ptr(addr);
d9bea114 1532 tcg_temp_free_i32(t2);
8e9ade68 1533 }
d9bea114
AJ
1534 gen_store_gpr(t0, to);
1535 tcg_temp_free(t0);
aaa9128a
TS
1536}
1537
be24bb4f 1538static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1539{
be24bb4f 1540 if (to != 0) {
d9bea114
AJ
1541 TCGv t0 = tcg_temp_new();
1542 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1543 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1544
d9bea114 1545 gen_load_gpr(t0, from);
7db13fae 1546 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1547 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1548 tcg_gen_andi_i32(t2, t2, 0xf);
1549 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1550 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1551 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1552
d9bea114 1553 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1554 tcg_temp_free_ptr(addr);
d9bea114
AJ
1555 tcg_temp_free_i32(t2);
1556 tcg_temp_free(t0);
8e9ade68 1557 }
aaa9128a
TS
1558}
1559
aaa9128a 1560/* Floating point register moves. */
d73ee8a2 1561static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1562{
d73ee8a2 1563 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1564}
1565
d73ee8a2 1566static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1567{
d73ee8a2
RH
1568 TCGv_i64 t64 = tcg_temp_new_i64();
1569 tcg_gen_extu_i32_i64(t64, t);
1570 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1571 tcg_temp_free_i64(t64);
6d066274
AJ
1572}
1573
7f6613ce 1574static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1575{
7f6613ce
PJ
1576 if (ctx->hflags & MIPS_HFLAG_F64) {
1577 TCGv_i64 t64 = tcg_temp_new_i64();
1578 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1579 tcg_gen_trunc_i64_i32(t, t64);
1580 tcg_temp_free_i64(t64);
1581 } else {
1582 gen_load_fpr32(t, reg | 1);
1583 }
6d066274
AJ
1584}
1585
7f6613ce 1586static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1587{
7f6613ce
PJ
1588 if (ctx->hflags & MIPS_HFLAG_F64) {
1589 TCGv_i64 t64 = tcg_temp_new_i64();
1590 tcg_gen_extu_i32_i64(t64, t);
1591 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1592 tcg_temp_free_i64(t64);
1593 } else {
1594 gen_store_fpr32(t, reg | 1);
1595 }
aa0bf00b 1596}
6ea83fed 1597
d73ee8a2 1598static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1599{
f364515c 1600 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1601 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1602 } else {
d73ee8a2 1603 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1604 }
1605}
6ea83fed 1606
d73ee8a2 1607static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1608{
f364515c 1609 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1610 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1611 } else {
d73ee8a2
RH
1612 TCGv_i64 t0;
1613 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1614 t0 = tcg_temp_new_i64();
6d066274 1615 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1616 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1617 tcg_temp_free_i64(t0);
aa0bf00b
TS
1618 }
1619}
6ea83fed 1620
d94536f4 1621static inline int get_fp_bit (int cc)
a16336e4 1622{
d94536f4
AJ
1623 if (cc)
1624 return 24 + cc;
1625 else
1626 return 23;
a16336e4
TS
1627}
1628
30898801 1629/* Tests */
8e9ade68
TS
1630static inline void gen_save_pc(target_ulong pc)
1631{
1eb75d4a 1632 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1633}
30898801 1634
356265ae 1635static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1636{
d12d51d5 1637 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1638 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1639 gen_save_pc(ctx->pc);
6af0bf9c
FB
1640 ctx->saved_pc = ctx->pc;
1641 }
1642 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1643 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1644 ctx->saved_hflags = ctx->hflags;
364d4831 1645 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1646 case MIPS_HFLAG_BR:
5a5012ec
TS
1647 break;
1648 case MIPS_HFLAG_BC:
5a5012ec 1649 case MIPS_HFLAG_BL:
5a5012ec 1650 case MIPS_HFLAG_B:
d077b6f7 1651 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1652 break;
6af0bf9c
FB
1653 }
1654 }
1655}
1656
7db13fae 1657static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1658{
fd4a04eb 1659 ctx->saved_hflags = ctx->hflags;
364d4831 1660 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1661 case MIPS_HFLAG_BR:
fd4a04eb
TS
1662 break;
1663 case MIPS_HFLAG_BC:
1664 case MIPS_HFLAG_BL:
39454628 1665 case MIPS_HFLAG_B:
fd4a04eb 1666 ctx->btarget = env->btarget;
fd4a04eb 1667 break;
5a5012ec
TS
1668 }
1669}
1670
356265ae 1671static inline void
48d38ca5 1672generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1673{
a7812ae4
PB
1674 TCGv_i32 texcp = tcg_const_i32(excp);
1675 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1676 save_cpu_state(ctx, 1);
895c2d04 1677 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1678 tcg_temp_free_i32(terr);
1679 tcg_temp_free_i32(texcp);
aaa9128a
TS
1680}
1681
356265ae 1682static inline void
48d38ca5 1683generate_exception (DisasContext *ctx, int excp)
aaa9128a 1684{
6af0bf9c 1685 save_cpu_state(ctx, 1);
895c2d04 1686 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1687}
1688
48d38ca5 1689/* Addresses computation */
941694d0 1690static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1691{
941694d0 1692 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1693
1694#if defined(TARGET_MIPS64)
01f72885 1695 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1696 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1697 }
1698#endif
4ad40f36
FB
1699}
1700
31837be3
YK
1701/* Addresses computation (translation time) */
1702static target_long addr_add(DisasContext *ctx, target_long base,
1703 target_long offset)
1704{
1705 target_long sum = base + offset;
1706
1707#if defined(TARGET_MIPS64)
1708 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1709 sum = (int32_t)sum;
1710 }
1711#endif
1712 return sum;
1713}
1714
356265ae 1715static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1716{
fe253235 1717 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1718 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1719}
1720
356265ae 1721static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1722{
fe253235 1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1724 generate_exception_err(ctx, EXCP_CpU, 1);
1725}
1726
b8aa4598
TS
1727/* Verify that the processor is running with COP1X instructions enabled.
1728 This is associated with the nabla symbol in the MIPS32 and MIPS64
1729 opcode tables. */
1730
356265ae 1731static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1732{
1733 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1734 generate_exception(ctx, EXCP_RI);
1735}
1736
1737/* Verify that the processor is running with 64-bit floating-point
1738 operations enabled. */
1739
356265ae 1740static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1741{
b8aa4598 1742 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1743 generate_exception(ctx, EXCP_RI);
1744}
1745
1746/*
1747 * Verify if floating point register is valid; an operation is not defined
1748 * if bit 0 of any register specification is set and the FR bit in the
1749 * Status register equals zero, since the register numbers specify an
1750 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1751 * in the Status register equals one, both even and odd register numbers
1752 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1753 *
1754 * Multiple 64 bit wide registers can be checked by calling
1755 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1756 */
356265ae 1757static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1758{
fe253235 1759 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1760 generate_exception(ctx, EXCP_RI);
1761}
1762
853c3240
JL
1763/* Verify that the processor is running with DSP instructions enabled.
1764 This is enabled by CP0 Status register MX(24) bit.
1765 */
1766
1767static inline void check_dsp(DisasContext *ctx)
1768{
1769 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1770 if (ctx->insn_flags & ASE_DSP) {
1771 generate_exception(ctx, EXCP_DSPDIS);
1772 } else {
1773 generate_exception(ctx, EXCP_RI);
1774 }
853c3240
JL
1775 }
1776}
1777
1778static inline void check_dspr2(DisasContext *ctx)
1779{
1780 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1781 if (ctx->insn_flags & ASE_DSP) {
1782 generate_exception(ctx, EXCP_DSPDIS);
1783 } else {
1784 generate_exception(ctx, EXCP_RI);
1785 }
853c3240
JL
1786 }
1787}
1788
3a95e3a7 1789/* This code generates a "reserved instruction" exception if the
e189e748 1790 CPU does not support the instruction set corresponding to flags. */
d75c135e 1791static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1792{
d75c135e 1793 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1794 generate_exception(ctx, EXCP_RI);
d75c135e 1795 }
3a95e3a7
TS
1796}
1797
fecd2646
LA
1798/* This code generates a "reserved instruction" exception if the
1799 CPU has corresponding flag set which indicates that the instruction
1800 has been removed. */
1801static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1802{
1803 if (unlikely(ctx->insn_flags & flags)) {
1804 generate_exception(ctx, EXCP_RI);
1805 }
1806}
1807
c7986fd6 1808#ifdef TARGET_MIPS64
e189e748
TS
1809/* This code generates a "reserved instruction" exception if 64-bit
1810 instructions are not enabled. */
356265ae 1811static inline void check_mips_64(DisasContext *ctx)
e189e748 1812{
fe253235 1813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1814 generate_exception(ctx, EXCP_RI);
1815}
c7986fd6 1816#endif
e189e748 1817
8153667c
NF
1818/* Define small wrappers for gen_load_fpr* so that we have a uniform
1819 calling interface for 32 and 64-bit FPRs. No sense in changing
1820 all callers for gen_load_fpr32 when we need the CTX parameter for
1821 this one use. */
1822#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1823#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1824#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1825static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1826 int ft, int fs, int cc) \
1827{ \
1828 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1829 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1830 switch (ifmt) { \
1831 case FMT_PS: \
1832 check_cp1_64bitmode(ctx); \
1833 break; \
1834 case FMT_D: \
1835 if (abs) { \
1836 check_cop1x(ctx); \
1837 } \
1838 check_cp1_registers(ctx, fs | ft); \
1839 break; \
1840 case FMT_S: \
1841 if (abs) { \
1842 check_cop1x(ctx); \
1843 } \
1844 break; \
1845 } \
1846 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1847 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1848 switch (n) { \
895c2d04
BS
1849 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1850 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1851 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1852 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1853 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1854 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1855 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1856 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1857 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1858 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1859 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1860 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1861 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1862 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1863 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1864 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1865 default: abort(); \
1866 } \
1867 tcg_temp_free_i##bits (fp0); \
1868 tcg_temp_free_i##bits (fp1); \
1869}
1870
1871FOP_CONDS(, 0, d, FMT_D, 64)
1872FOP_CONDS(abs, 1, d, FMT_D, 64)
1873FOP_CONDS(, 0, s, FMT_S, 32)
1874FOP_CONDS(abs, 1, s, FMT_S, 32)
1875FOP_CONDS(, 0, ps, FMT_PS, 64)
1876FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1877#undef FOP_CONDS
3f493883
YK
1878
1879#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1880static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1881 int ft, int fs, int fd) \
1882{ \
1883 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1884 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1885 switch (ifmt) { \
1886 case FMT_D: \
1887 check_cp1_registers(ctx, fs | ft | fd); \
1888 break; \
1889 } \
1890 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1891 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1892 switch (n) { \
1893 case 0: \
1894 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1895 break; \
1896 case 1: \
1897 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1898 break; \
1899 case 2: \
1900 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1901 break; \
1902 case 3: \
1903 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1904 break; \
1905 case 4: \
1906 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1907 break; \
1908 case 5: \
1909 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1910 break; \
1911 case 6: \
1912 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1913 break; \
1914 case 7: \
1915 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1916 break; \
1917 case 8: \
1918 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1919 break; \
1920 case 9: \
1921 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1922 break; \
1923 case 10: \
1924 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1925 break; \
1926 case 11: \
1927 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1928 break; \
1929 case 12: \
1930 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1931 break; \
1932 case 13: \
1933 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1934 break; \
1935 case 14: \
1936 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1937 break; \
1938 case 15: \
1939 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1940 break; \
1941 case 17: \
1942 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1943 break; \
1944 case 18: \
1945 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 19: \
1948 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 25: \
1951 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 26: \
1954 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 27: \
1957 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 default: \
1960 abort(); \
1961 } \
1962 STORE; \
1963 tcg_temp_free_i ## bits (fp0); \
1964 tcg_temp_free_i ## bits (fp1); \
1965}
1966
1967FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1968FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1969#undef FOP_CONDNS
8153667c
NF
1970#undef gen_ldcmp_fpr32
1971#undef gen_ldcmp_fpr64
1972
958fb4a9 1973/* load/store instructions. */
e7139c44 1974#ifdef CONFIG_USER_ONLY
d9bea114 1975#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1976static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1977{ \
1978 TCGv t0 = tcg_temp_new(); \
1979 tcg_gen_mov_tl(t0, arg1); \
1980 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1981 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1982 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1983 tcg_temp_free(t0); \
aaa9128a 1984}
e7139c44
AJ
1985#else
1986#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1987static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1988{ \
895c2d04 1989 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1990}
1991#endif
aaa9128a
TS
1992OP_LD_ATOMIC(ll,ld32s);
1993#if defined(TARGET_MIPS64)
1994OP_LD_ATOMIC(lld,ld64);
1995#endif
1996#undef OP_LD_ATOMIC
1997
590bc601
PB
1998#ifdef CONFIG_USER_ONLY
1999#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2000static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2001{ \
2002 TCGv t0 = tcg_temp_new(); \
2003 int l1 = gen_new_label(); \
2004 int l2 = gen_new_label(); \
2005 \
2006 tcg_gen_andi_tl(t0, arg2, almask); \
2007 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2008 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2009 generate_exception(ctx, EXCP_AdES); \
2010 gen_set_label(l1); \
7db13fae 2011 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2012 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2013 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2014 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2015 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2016 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2017 gen_set_label(l2); \
2018 tcg_gen_movi_tl(t0, 0); \
2019 gen_store_gpr(t0, rt); \
2020 tcg_temp_free(t0); \
2021}
2022#else
2023#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2024static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2025{ \
2026 TCGv t0 = tcg_temp_new(); \
895c2d04 2027 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2028 gen_store_gpr(t0, rt); \
590bc601
PB
2029 tcg_temp_free(t0); \
2030}
2031#endif
590bc601 2032OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2033#if defined(TARGET_MIPS64)
590bc601 2034OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2035#endif
2036#undef OP_ST_ATOMIC
2037
662d7485
NF
2038static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2039 int base, int16_t offset)
2040{
2041 if (base == 0) {
2042 tcg_gen_movi_tl(addr, offset);
2043 } else if (offset == 0) {
2044 gen_load_gpr(addr, base);
2045 } else {
2046 tcg_gen_movi_tl(addr, offset);
2047 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2048 }
2049}
2050
364d4831
NF
2051static target_ulong pc_relative_pc (DisasContext *ctx)
2052{
2053 target_ulong pc = ctx->pc;
2054
2055 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2056 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2057
2058 pc -= branch_bytes;
2059 }
2060
2061 pc &= ~(target_ulong)3;
2062 return pc;
2063}
2064
5c13fdfd 2065/* Load */
d75c135e
AJ
2066static void gen_ld(DisasContext *ctx, uint32_t opc,
2067 int rt, int base, int16_t offset)
6af0bf9c 2068{
5c13fdfd 2069 const char *opn = "ld";
fc40787a 2070 TCGv t0, t1, t2;
afa88c3a 2071
d75c135e 2072 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2073 /* Loongson CPU uses a load to zero register for prefetch.
2074 We emulate it as a NOP. On other CPU we must perform the
2075 actual memory access. */
2076 MIPS_DEBUG("NOP");
2077 return;
2078 }
6af0bf9c 2079
afa88c3a 2080 t0 = tcg_temp_new();
662d7485 2081 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2082
6af0bf9c 2083 switch (opc) {
d26bc211 2084#if defined(TARGET_MIPS64)
6e473128 2085 case OPC_LWU:
5f68f5ae 2086 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 2087 gen_store_gpr(t0, rt);
6e473128
TS
2088 opn = "lwu";
2089 break;
6af0bf9c 2090 case OPC_LD:
5f68f5ae 2091 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 2092 gen_store_gpr(t0, rt);
6af0bf9c
FB
2093 opn = "ld";
2094 break;
7a387fff 2095 case OPC_LLD:
bf7910c6 2096 case R6_OPC_LLD:
b835e919 2097 save_cpu_state(ctx, 1);
5c13fdfd 2098 op_ld_lld(t0, t0, ctx);
78723684 2099 gen_store_gpr(t0, rt);
7a387fff
TS
2100 opn = "lld";
2101 break;
6af0bf9c 2102 case OPC_LDL:
3cee3050 2103 t1 = tcg_temp_new();
fc40787a
AJ
2104 tcg_gen_andi_tl(t1, t0, 7);
2105#ifndef TARGET_WORDS_BIGENDIAN
2106 tcg_gen_xori_tl(t1, t1, 7);
2107#endif
2108 tcg_gen_shli_tl(t1, t1, 3);
2109 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2110 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2111 tcg_gen_shl_tl(t0, t0, t1);
2112 tcg_gen_xori_tl(t1, t1, 63);
2113 t2 = tcg_const_tl(0x7fffffffffffffffull);
2114 tcg_gen_shr_tl(t2, t2, t1);
78723684 2115 gen_load_gpr(t1, rt);
fc40787a
AJ
2116 tcg_gen_and_tl(t1, t1, t2);
2117 tcg_temp_free(t2);
2118 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2119 tcg_temp_free(t1);
fc40787a 2120 gen_store_gpr(t0, rt);
6af0bf9c
FB
2121 opn = "ldl";
2122 break;
6af0bf9c 2123 case OPC_LDR:
3cee3050 2124 t1 = tcg_temp_new();
fc40787a
AJ
2125 tcg_gen_andi_tl(t1, t0, 7);
2126#ifdef TARGET_WORDS_BIGENDIAN
2127 tcg_gen_xori_tl(t1, t1, 7);
2128#endif
2129 tcg_gen_shli_tl(t1, t1, 3);
2130 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2132 tcg_gen_shr_tl(t0, t0, t1);
2133 tcg_gen_xori_tl(t1, t1, 63);
2134 t2 = tcg_const_tl(0xfffffffffffffffeull);
2135 tcg_gen_shl_tl(t2, t2, t1);
78723684 2136 gen_load_gpr(t1, rt);
fc40787a
AJ
2137 tcg_gen_and_tl(t1, t1, t2);
2138 tcg_temp_free(t2);
2139 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2140 tcg_temp_free(t1);
fc40787a 2141 gen_store_gpr(t0, rt);
6af0bf9c
FB
2142 opn = "ldr";
2143 break;
364d4831 2144 case OPC_LDPC:
3cee3050 2145 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2146 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2147 tcg_temp_free(t1);
5f68f5ae 2148 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2149 gen_store_gpr(t0, rt);
5c13fdfd 2150 opn = "ldpc";
364d4831 2151 break;
6af0bf9c 2152#endif
364d4831 2153 case OPC_LWPC:
3cee3050 2154 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2155 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2156 tcg_temp_free(t1);
5f68f5ae 2157 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2158 gen_store_gpr(t0, rt);
5c13fdfd 2159 opn = "lwpc";
364d4831 2160 break;
6af0bf9c 2161 case OPC_LW:
5f68f5ae 2162 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 2163 gen_store_gpr(t0, rt);
6af0bf9c
FB
2164 opn = "lw";
2165 break;
6af0bf9c 2166 case OPC_LH:
5f68f5ae 2167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 2168 gen_store_gpr(t0, rt);
6af0bf9c
FB
2169 opn = "lh";
2170 break;
6af0bf9c 2171 case OPC_LHU:
5f68f5ae 2172 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 2173 gen_store_gpr(t0, rt);
6af0bf9c
FB
2174 opn = "lhu";
2175 break;
2176 case OPC_LB:
5f68f5ae 2177 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2178 gen_store_gpr(t0, rt);
6af0bf9c
FB
2179 opn = "lb";
2180 break;
6af0bf9c 2181 case OPC_LBU:
5f68f5ae 2182 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2183 gen_store_gpr(t0, rt);
6af0bf9c
FB
2184 opn = "lbu";
2185 break;
2186 case OPC_LWL:
3cee3050 2187 t1 = tcg_temp_new();
fc40787a
AJ
2188 tcg_gen_andi_tl(t1, t0, 3);
2189#ifndef TARGET_WORDS_BIGENDIAN
2190 tcg_gen_xori_tl(t1, t1, 3);
2191#endif
2192 tcg_gen_shli_tl(t1, t1, 3);
2193 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2195 tcg_gen_shl_tl(t0, t0, t1);
2196 tcg_gen_xori_tl(t1, t1, 31);
2197 t2 = tcg_const_tl(0x7fffffffull);
2198 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2199 gen_load_gpr(t1, rt);
fc40787a
AJ
2200 tcg_gen_and_tl(t1, t1, t2);
2201 tcg_temp_free(t2);
2202 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2203 tcg_temp_free(t1);
fc40787a
AJ
2204 tcg_gen_ext32s_tl(t0, t0);
2205 gen_store_gpr(t0, rt);
6af0bf9c
FB
2206 opn = "lwl";
2207 break;
6af0bf9c 2208 case OPC_LWR:
3cee3050 2209 t1 = tcg_temp_new();
fc40787a
AJ
2210 tcg_gen_andi_tl(t1, t0, 3);
2211#ifdef TARGET_WORDS_BIGENDIAN
2212 tcg_gen_xori_tl(t1, t1, 3);
2213#endif
2214 tcg_gen_shli_tl(t1, t1, 3);
2215 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2217 tcg_gen_shr_tl(t0, t0, t1);
2218 tcg_gen_xori_tl(t1, t1, 31);
2219 t2 = tcg_const_tl(0xfffffffeull);
2220 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2221 gen_load_gpr(t1, rt);
fc40787a
AJ
2222 tcg_gen_and_tl(t1, t1, t2);
2223 tcg_temp_free(t2);
2224 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2225 tcg_temp_free(t1);
c728154b 2226 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2227 gen_store_gpr(t0, rt);
6af0bf9c
FB
2228 opn = "lwr";
2229 break;
6af0bf9c 2230 case OPC_LL:
4368b29a 2231 case R6_OPC_LL:
e7139c44 2232 save_cpu_state(ctx, 1);
5c13fdfd 2233 op_ld_ll(t0, t0, ctx);
78723684 2234 gen_store_gpr(t0, rt);
6af0bf9c
FB
2235 opn = "ll";
2236 break;
d66c7132 2237 }
2abf314d 2238 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2239 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2240 tcg_temp_free(t0);
d66c7132
AJ
2241}
2242
5c13fdfd
AJ
2243/* Store */
2244static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2245 int base, int16_t offset)
2246{
2247 const char *opn = "st";
2248 TCGv t0 = tcg_temp_new();
2249 TCGv t1 = tcg_temp_new();
2250
2251 gen_base_offset_addr(ctx, t0, base, offset);
2252 gen_load_gpr(t1, rt);
2253 switch (opc) {
2254#if defined(TARGET_MIPS64)
2255 case OPC_SD:
5f68f5ae 2256 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
2257 opn = "sd";
2258 break;
2259 case OPC_SDL:
2260 save_cpu_state(ctx, 1);
895c2d04 2261 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2262 opn = "sdl";
2263 break;
2264 case OPC_SDR:
2265 save_cpu_state(ctx, 1);
895c2d04 2266 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2267 opn = "sdr";
2268 break;
2269#endif
2270 case OPC_SW:
5f68f5ae 2271 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2272 opn = "sw";
2273 break;
2274 case OPC_SH:
5f68f5ae 2275 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2276 opn = "sh";
2277 break;
2278 case OPC_SB:
5f68f5ae 2279 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2280 opn = "sb";
2281 break;
2282 case OPC_SWL:
2283 save_cpu_state(ctx, 1);
895c2d04 2284 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2285 opn = "swl";
2286 break;
2287 case OPC_SWR:
2288 save_cpu_state(ctx, 1);
895c2d04 2289 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2290 opn = "swr";
2291 break;
2292 }
2abf314d 2293 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2294 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2295 tcg_temp_free(t0);
2296 tcg_temp_free(t1);
2297}
2298
2299
d66c7132
AJ
2300/* Store conditional */
2301static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2302 int base, int16_t offset)
2303{
2304 const char *opn = "st_cond";
2305 TCGv t0, t1;
2306
2d2826b9 2307#ifdef CONFIG_USER_ONLY
d66c7132 2308 t0 = tcg_temp_local_new();
d66c7132 2309 t1 = tcg_temp_local_new();
2d2826b9
AJ
2310#else
2311 t0 = tcg_temp_new();
2312 t1 = tcg_temp_new();
2313#endif
2314 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2315 gen_load_gpr(t1, rt);
2316 switch (opc) {
2317#if defined(TARGET_MIPS64)
2318 case OPC_SCD:
bf7910c6 2319 case R6_OPC_SCD:
b835e919 2320 save_cpu_state(ctx, 1);
5c13fdfd 2321 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2322 opn = "scd";
2323 break;
2324#endif
6af0bf9c 2325 case OPC_SC:
4368b29a 2326 case R6_OPC_SC:
e7139c44 2327 save_cpu_state(ctx, 1);
5c13fdfd 2328 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2329 opn = "sc";
2330 break;
6af0bf9c 2331 }
2abf314d 2332 (void)opn; /* avoid a compiler warning */
6af0bf9c 2333 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2334 tcg_temp_free(t1);
d66c7132 2335 tcg_temp_free(t0);
6af0bf9c
FB
2336}
2337
6ea83fed 2338/* Load and store */
7a387fff 2339static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2340 int base, int16_t offset)
6ea83fed 2341{
923617a3 2342 const char *opn = "flt_ldst";
4e2474d6 2343 TCGv t0 = tcg_temp_new();
6ea83fed 2344
662d7485 2345 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2346 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2347 memory access. */
6ea83fed
FB
2348 switch (opc) {
2349 case OPC_LWC1:
b6d96bed 2350 {
a7812ae4 2351 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2352 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2353 gen_store_fpr32(fp0, ft);
a7812ae4 2354 tcg_temp_free_i32(fp0);
b6d96bed 2355 }
6ea83fed
FB
2356 opn = "lwc1";
2357 break;
2358 case OPC_SWC1:
b6d96bed 2359 {
a7812ae4 2360 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2361 gen_load_fpr32(fp0, ft);
5f68f5ae 2362 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2363 tcg_temp_free_i32(fp0);
b6d96bed 2364 }
6ea83fed
FB
2365 opn = "swc1";
2366 break;
2367 case OPC_LDC1:
b6d96bed 2368 {
a7812ae4 2369 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2370 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2371 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2372 tcg_temp_free_i64(fp0);
b6d96bed 2373 }
6ea83fed
FB
2374 opn = "ldc1";
2375 break;
2376 case OPC_SDC1:
b6d96bed 2377 {
a7812ae4 2378 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2379 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2380 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2381 tcg_temp_free_i64(fp0);
b6d96bed 2382 }
6ea83fed
FB
2383 opn = "sdc1";
2384 break;
2385 default:
923617a3 2386 MIPS_INVAL(opn);
e397ee33 2387 generate_exception(ctx, EXCP_RI);
78723684 2388 goto out;
6ea83fed 2389 }
2abf314d 2390 (void)opn; /* avoid a compiler warning */
6ea83fed 2391 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2392 out:
2393 tcg_temp_free(t0);
6ea83fed 2394}
6ea83fed 2395
5ab5c041
AJ
2396static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2397 int rs, int16_t imm)
26ebe468 2398{
5ab5c041 2399 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
2400 check_cp1_enabled(ctx);
2401 gen_flt_ldst(ctx, op, rt, rs, imm);
2402 } else {
2403 generate_exception_err(ctx, EXCP_CpU, 1);
2404 }
2405}
2406
6af0bf9c 2407/* Arithmetic with immediate operand */
d75c135e
AJ
2408static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2409 int rt, int rs, int16_t imm)
6af0bf9c 2410{
324d9e32 2411 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2412 const char *opn = "imm arith";
6af0bf9c 2413
7a387fff 2414 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2415 /* If no destination, treat it as a NOP.
2416 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2417 MIPS_DEBUG("NOP");
324d9e32 2418 return;
6af0bf9c
FB
2419 }
2420 switch (opc) {
2421 case OPC_ADDI:
48d38ca5 2422 {
324d9e32
AJ
2423 TCGv t0 = tcg_temp_local_new();
2424 TCGv t1 = tcg_temp_new();
2425 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2426 int l1 = gen_new_label();
2427
324d9e32
AJ
2428 gen_load_gpr(t1, rs);
2429 tcg_gen_addi_tl(t0, t1, uimm);
2430 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2431
324d9e32
AJ
2432 tcg_gen_xori_tl(t1, t1, ~uimm);
2433 tcg_gen_xori_tl(t2, t0, uimm);
2434 tcg_gen_and_tl(t1, t1, t2);
2435 tcg_temp_free(t2);
2436 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2437 tcg_temp_free(t1);
48d38ca5
TS
2438 /* operands of same sign, result different sign */
2439 generate_exception(ctx, EXCP_OVERFLOW);
2440 gen_set_label(l1);
78723684 2441 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2442 gen_store_gpr(t0, rt);
2443 tcg_temp_free(t0);
48d38ca5 2444 }
6af0bf9c
FB
2445 opn = "addi";
2446 break;
2447 case OPC_ADDIU:
324d9e32
AJ
2448 if (rs != 0) {
2449 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2450 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2451 } else {
2452 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2453 }
6af0bf9c
FB
2454 opn = "addiu";
2455 break;
d26bc211 2456#if defined(TARGET_MIPS64)
7a387fff 2457 case OPC_DADDI:
48d38ca5 2458 {
324d9e32
AJ
2459 TCGv t0 = tcg_temp_local_new();
2460 TCGv t1 = tcg_temp_new();
2461 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2462 int l1 = gen_new_label();
2463
324d9e32
AJ
2464 gen_load_gpr(t1, rs);
2465 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2466
324d9e32
AJ
2467 tcg_gen_xori_tl(t1, t1, ~uimm);
2468 tcg_gen_xori_tl(t2, t0, uimm);
2469 tcg_gen_and_tl(t1, t1, t2);
2470 tcg_temp_free(t2);
2471 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2472 tcg_temp_free(t1);
48d38ca5
TS
2473 /* operands of same sign, result different sign */
2474 generate_exception(ctx, EXCP_OVERFLOW);
2475 gen_set_label(l1);
324d9e32
AJ
2476 gen_store_gpr(t0, rt);
2477 tcg_temp_free(t0);
48d38ca5 2478 }
7a387fff
TS
2479 opn = "daddi";
2480 break;
2481 case OPC_DADDIU:
324d9e32
AJ
2482 if (rs != 0) {
2483 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2484 } else {
2485 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2486 }
7a387fff
TS
2487 opn = "daddiu";
2488 break;
2489#endif
324d9e32 2490 }
2abf314d 2491 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2492 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2493}
2494
2495/* Logic with immediate operand */
d75c135e 2496static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2497 int rt, int rs, int16_t imm)
324d9e32
AJ
2498{
2499 target_ulong uimm;
324d9e32
AJ
2500
2501 if (rt == 0) {
2502 /* If no destination, treat it as a NOP. */
2503 MIPS_DEBUG("NOP");
2504 return;
2505 }
2506 uimm = (uint16_t)imm;
2507 switch (opc) {
6af0bf9c 2508 case OPC_ANDI:
324d9e32
AJ
2509 if (likely(rs != 0))
2510 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2511 else
2512 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2513 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2514 regnames[rs], uimm);
6af0bf9c
FB
2515 break;
2516 case OPC_ORI:
324d9e32
AJ
2517 if (rs != 0)
2518 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2519 else
2520 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2521 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2522 regnames[rs], uimm);
6af0bf9c
FB
2523 break;
2524 case OPC_XORI:
324d9e32
AJ
2525 if (likely(rs != 0))
2526 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2527 else
2528 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2529 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2530 regnames[rs], uimm);
6af0bf9c
FB
2531 break;
2532 case OPC_LUI:
d4ea6acd
LA
2533 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2534 /* OPC_AUI */
2535 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2536 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2537 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2538 } else {
2539 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2540 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2541 }
7c2c3ea3
EJ
2542 break;
2543
2544 default:
2545 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2546 break;
324d9e32 2547 }
324d9e32
AJ
2548}
2549
2550/* Set on less than with immediate operand */
d75c135e 2551static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2552 int rt, int rs, int16_t imm)
324d9e32
AJ
2553{
2554 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2555 const char *opn = "imm arith";
2556 TCGv t0;
2557
2558 if (rt == 0) {
2559 /* If no destination, treat it as a NOP. */
2560 MIPS_DEBUG("NOP");
2561 return;
2562 }
2563 t0 = tcg_temp_new();
2564 gen_load_gpr(t0, rs);
2565 switch (opc) {
2566 case OPC_SLTI:
e68dd28f 2567 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2568 opn = "slti";
2569 break;
2570 case OPC_SLTIU:
e68dd28f 2571 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2572 opn = "sltiu";
2573 break;
2574 }
2abf314d 2575 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2576 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2577 tcg_temp_free(t0);
2578}
2579
2580/* Shifts with immediate operand */
d75c135e 2581static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2582 int rt, int rs, int16_t imm)
2583{
2584 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2585 const char *opn = "imm shift";
2586 TCGv t0;
2587
2588 if (rt == 0) {
2589 /* If no destination, treat it as a NOP. */
2590 MIPS_DEBUG("NOP");
2591 return;
2592 }
2593
2594 t0 = tcg_temp_new();
2595 gen_load_gpr(t0, rs);
2596 switch (opc) {
6af0bf9c 2597 case OPC_SLL:
78723684 2598 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2599 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2600 opn = "sll";
2601 break;
2602 case OPC_SRA:
324d9e32 2603 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2604 opn = "sra";
2605 break;
2606 case OPC_SRL:
ea63e2c3
NF
2607 if (uimm != 0) {
2608 tcg_gen_ext32u_tl(t0, t0);
2609 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2610 } else {
2611 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2612 }
ea63e2c3
NF
2613 opn = "srl";
2614 break;
2615 case OPC_ROTR:
2616 if (uimm != 0) {
2617 TCGv_i32 t1 = tcg_temp_new_i32();
2618
2619 tcg_gen_trunc_tl_i32(t1, t0);
2620 tcg_gen_rotri_i32(t1, t1, uimm);
2621 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2622 tcg_temp_free_i32(t1);
3399e30f
NF
2623 } else {
2624 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2625 }
2626 opn = "rotr";
7a387fff 2627 break;
d26bc211 2628#if defined(TARGET_MIPS64)
7a387fff 2629 case OPC_DSLL:
324d9e32 2630 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2631 opn = "dsll";
2632 break;
2633 case OPC_DSRA:
324d9e32 2634 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2635 opn = "dsra";
2636 break;
2637 case OPC_DSRL:
ea63e2c3
NF
2638 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2639 opn = "dsrl";
2640 break;
2641 case OPC_DROTR:
2642 if (uimm != 0) {
2643 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2644 } else {
2645 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2646 }
ea63e2c3 2647 opn = "drotr";
7a387fff
TS
2648 break;
2649 case OPC_DSLL32:
324d9e32 2650 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2651 opn = "dsll32";
2652 break;
2653 case OPC_DSRA32:
324d9e32 2654 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2655 opn = "dsra32";
2656 break;
2657 case OPC_DSRL32:
ea63e2c3
NF
2658 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2659 opn = "dsrl32";
2660 break;
2661 case OPC_DROTR32:
2662 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2663 opn = "drotr32";
6af0bf9c 2664 break;
7a387fff 2665#endif
6af0bf9c 2666 }
2abf314d 2667 (void)opn; /* avoid a compiler warning */
93b12ccc 2668 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2669 tcg_temp_free(t0);
6af0bf9c
FB
2670}
2671
2672/* Arithmetic */
d75c135e
AJ
2673static void gen_arith(DisasContext *ctx, uint32_t opc,
2674 int rd, int rs, int rt)
6af0bf9c 2675{
923617a3 2676 const char *opn = "arith";
6af0bf9c 2677
7a387fff
TS
2678 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2679 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2680 /* If no destination, treat it as a NOP.
2681 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2682 MIPS_DEBUG("NOP");
460f00c4 2683 return;
185f0762 2684 }
460f00c4 2685
6af0bf9c
FB
2686 switch (opc) {
2687 case OPC_ADD:
48d38ca5 2688 {
460f00c4
AJ
2689 TCGv t0 = tcg_temp_local_new();
2690 TCGv t1 = tcg_temp_new();
2691 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2692 int l1 = gen_new_label();
2693
460f00c4
AJ
2694 gen_load_gpr(t1, rs);
2695 gen_load_gpr(t2, rt);
2696 tcg_gen_add_tl(t0, t1, t2);
2697 tcg_gen_ext32s_tl(t0, t0);
2698 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2699 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2700 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2701 tcg_temp_free(t2);
2702 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2703 tcg_temp_free(t1);
48d38ca5
TS
2704 /* operands of same sign, result different sign */
2705 generate_exception(ctx, EXCP_OVERFLOW);
2706 gen_set_label(l1);
460f00c4
AJ
2707 gen_store_gpr(t0, rd);
2708 tcg_temp_free(t0);
48d38ca5 2709 }
6af0bf9c
FB
2710 opn = "add";
2711 break;
2712 case OPC_ADDU:
460f00c4
AJ
2713 if (rs != 0 && rt != 0) {
2714 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2715 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2716 } else if (rs == 0 && rt != 0) {
2717 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2718 } else if (rs != 0 && rt == 0) {
2719 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2720 } else {
2721 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2722 }
6af0bf9c
FB
2723 opn = "addu";
2724 break;
2725 case OPC_SUB:
48d38ca5 2726 {
460f00c4
AJ
2727 TCGv t0 = tcg_temp_local_new();
2728 TCGv t1 = tcg_temp_new();
2729 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2730 int l1 = gen_new_label();
2731
460f00c4
AJ
2732 gen_load_gpr(t1, rs);
2733 gen_load_gpr(t2, rt);
2734 tcg_gen_sub_tl(t0, t1, t2);
2735 tcg_gen_ext32s_tl(t0, t0);
2736 tcg_gen_xor_tl(t2, t1, t2);
2737 tcg_gen_xor_tl(t1, t0, t1);
2738 tcg_gen_and_tl(t1, t1, t2);
2739 tcg_temp_free(t2);
2740 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2741 tcg_temp_free(t1);
31e3104f 2742 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2743 generate_exception(ctx, EXCP_OVERFLOW);
2744 gen_set_label(l1);
460f00c4
AJ
2745 gen_store_gpr(t0, rd);
2746 tcg_temp_free(t0);
48d38ca5 2747 }
6af0bf9c
FB
2748 opn = "sub";
2749 break;
2750 case OPC_SUBU:
460f00c4
AJ
2751 if (rs != 0 && rt != 0) {
2752 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2753 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2754 } else if (rs == 0 && rt != 0) {
2755 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2756 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2757 } else if (rs != 0 && rt == 0) {
2758 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2759 } else {
2760 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2761 }
6af0bf9c
FB
2762 opn = "subu";
2763 break;
d26bc211 2764#if defined(TARGET_MIPS64)
7a387fff 2765 case OPC_DADD:
48d38ca5 2766 {
460f00c4
AJ
2767 TCGv t0 = tcg_temp_local_new();
2768 TCGv t1 = tcg_temp_new();
2769 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2770 int l1 = gen_new_label();
2771
460f00c4
AJ
2772 gen_load_gpr(t1, rs);
2773 gen_load_gpr(t2, rt);
2774 tcg_gen_add_tl(t0, t1, t2);
2775 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2776 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2777 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2778 tcg_temp_free(t2);
2779 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2780 tcg_temp_free(t1);
48d38ca5
TS
2781 /* operands of same sign, result different sign */
2782 generate_exception(ctx, EXCP_OVERFLOW);
2783 gen_set_label(l1);
460f00c4
AJ
2784 gen_store_gpr(t0, rd);
2785 tcg_temp_free(t0);
48d38ca5 2786 }
7a387fff
TS
2787 opn = "dadd";
2788 break;
2789 case OPC_DADDU:
460f00c4
AJ
2790 if (rs != 0 && rt != 0) {
2791 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2792 } else if (rs == 0 && rt != 0) {
2793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2794 } else if (rs != 0 && rt == 0) {
2795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2796 } else {
2797 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2798 }
7a387fff
TS
2799 opn = "daddu";
2800 break;
2801 case OPC_DSUB:
48d38ca5 2802 {
460f00c4
AJ
2803 TCGv t0 = tcg_temp_local_new();
2804 TCGv t1 = tcg_temp_new();
2805 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2806 int l1 = gen_new_label();
2807
460f00c4
AJ
2808 gen_load_gpr(t1, rs);
2809 gen_load_gpr(t2, rt);
2810 tcg_gen_sub_tl(t0, t1, t2);
2811 tcg_gen_xor_tl(t2, t1, t2);
2812 tcg_gen_xor_tl(t1, t0, t1);
2813 tcg_gen_and_tl(t1, t1, t2);
2814 tcg_temp_free(t2);
2815 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2816 tcg_temp_free(t1);
31e3104f 2817 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2818 generate_exception(ctx, EXCP_OVERFLOW);
2819 gen_set_label(l1);
460f00c4
AJ
2820 gen_store_gpr(t0, rd);
2821 tcg_temp_free(t0);
48d38ca5 2822 }
7a387fff
TS
2823 opn = "dsub";
2824 break;
2825 case OPC_DSUBU:
460f00c4
AJ
2826 if (rs != 0 && rt != 0) {
2827 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2828 } else if (rs == 0 && rt != 0) {
2829 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2830 } else if (rs != 0 && rt == 0) {
2831 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2832 } else {
2833 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2834 }
7a387fff
TS
2835 opn = "dsubu";
2836 break;
2837#endif
460f00c4
AJ
2838 case OPC_MUL:
2839 if (likely(rs != 0 && rt != 0)) {
2840 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2841 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2842 } else {
2843 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2844 }
2845 opn = "mul";
6af0bf9c 2846 break;
460f00c4 2847 }
2abf314d 2848 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2849 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2850}
2851
2852/* Conditional move */
d75c135e 2853static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2854 int rd, int rs, int rt)
460f00c4
AJ
2855{
2856 const char *opn = "cond move";
acf12465 2857 TCGv t0, t1, t2;
460f00c4
AJ
2858
2859 if (rd == 0) {
acf12465 2860 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2861 MIPS_DEBUG("NOP");
2862 return;
2863 }
2864
acf12465
AJ
2865 t0 = tcg_temp_new();
2866 gen_load_gpr(t0, rt);
2867 t1 = tcg_const_tl(0);
2868 t2 = tcg_temp_new();
2869 gen_load_gpr(t2, rs);
460f00c4
AJ
2870 switch (opc) {
2871 case OPC_MOVN:
acf12465 2872 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2873 opn = "movn";
6af0bf9c 2874 break;
460f00c4 2875 case OPC_MOVZ:
acf12465 2876 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2877 opn = "movz";
2878 break;
b691d9d2
LA
2879 case OPC_SELNEZ:
2880 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2881 opn = "selnez";
2882 break;
2883 case OPC_SELEQZ:
2884 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2885 opn = "seleqz";
2886 break;
460f00c4 2887 }
acf12465
AJ
2888 tcg_temp_free(t2);
2889 tcg_temp_free(t1);
2890 tcg_temp_free(t0);
460f00c4 2891
2abf314d 2892 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2893 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2894}
2895
2896/* Logic */
d75c135e 2897static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2898 int rd, int rs, int rt)
460f00c4
AJ
2899{
2900 const char *opn = "logic";
2901
2902 if (rd == 0) {
2903 /* If no destination, treat it as a NOP. */
2904 MIPS_DEBUG("NOP");
2905 return;
2906 }
2907
2908 switch (opc) {
6af0bf9c 2909 case OPC_AND:
460f00c4
AJ
2910 if (likely(rs != 0 && rt != 0)) {
2911 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2912 } else {
2913 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2914 }
6af0bf9c
FB
2915 opn = "and";
2916 break;
2917 case OPC_NOR:
460f00c4
AJ
2918 if (rs != 0 && rt != 0) {
2919 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2920 } else if (rs == 0 && rt != 0) {
2921 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2922 } else if (rs != 0 && rt == 0) {
2923 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2924 } else {
2925 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2926 }
6af0bf9c
FB
2927 opn = "nor";
2928 break;
2929 case OPC_OR:
460f00c4
AJ
2930 if (likely(rs != 0 && rt != 0)) {
2931 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2932 } else if (rs == 0 && rt != 0) {
2933 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2934 } else if (rs != 0 && rt == 0) {
2935 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2936 } else {
2937 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2938 }
6af0bf9c
FB
2939 opn = "or";
2940 break;
2941 case OPC_XOR:
460f00c4
AJ
2942 if (likely(rs != 0 && rt != 0)) {
2943 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2944 } else if (rs == 0 && rt != 0) {
2945 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2946 } else if (rs != 0 && rt == 0) {
2947 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2948 } else {
2949 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2950 }
6af0bf9c
FB
2951 opn = "xor";
2952 break;
460f00c4 2953 }
2abf314d 2954 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2955 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2956}
2957
2958/* Set on lower than */
d75c135e 2959static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2960 int rd, int rs, int rt)
460f00c4
AJ
2961{
2962 const char *opn = "slt";
2963 TCGv t0, t1;
2964
2965 if (rd == 0) {
2966 /* If no destination, treat it as a NOP. */
2967 MIPS_DEBUG("NOP");
2968 return;
2969 }
2970
2971 t0 = tcg_temp_new();
2972 t1 = tcg_temp_new();
2973 gen_load_gpr(t0, rs);
2974 gen_load_gpr(t1, rt);
2975 switch (opc) {
2976 case OPC_SLT:
e68dd28f 2977 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2978 opn = "slt";
6af0bf9c 2979 break;
460f00c4 2980 case OPC_SLTU:
e68dd28f 2981 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2982 opn = "sltu";
2983 break;
2984 }
2abf314d 2985 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2986 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2987 tcg_temp_free(t0);
2988 tcg_temp_free(t1);
2989}
20c4c97c 2990
460f00c4 2991/* Shifts */
d75c135e
AJ
2992static void gen_shift(DisasContext *ctx, uint32_t opc,
2993 int rd, int rs, int rt)
460f00c4
AJ
2994{
2995 const char *opn = "shifts";
2996 TCGv t0, t1;
20c4c97c 2997
460f00c4
AJ
2998 if (rd == 0) {
2999 /* If no destination, treat it as a NOP.
3000 For add & sub, we must generate the overflow exception when needed. */
3001 MIPS_DEBUG("NOP");
3002 return;
3003 }
3004
3005 t0 = tcg_temp_new();
3006 t1 = tcg_temp_new();
3007 gen_load_gpr(t0, rs);
3008 gen_load_gpr(t1, rt);
3009 switch (opc) {
6af0bf9c 3010 case OPC_SLLV:
78723684
TS
3011 tcg_gen_andi_tl(t0, t0, 0x1f);
3012 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3013 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3014 opn = "sllv";
3015 break;
3016 case OPC_SRAV:
78723684 3017 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3018 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3019 opn = "srav";
3020 break;
3021 case OPC_SRLV:
ea63e2c3
NF
3022 tcg_gen_ext32u_tl(t1, t1);
3023 tcg_gen_andi_tl(t0, t0, 0x1f);
3024 tcg_gen_shr_tl(t0, t1, t0);
3025 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3026 opn = "srlv";
3027 break;
3028 case OPC_ROTRV:
3029 {
3030 TCGv_i32 t2 = tcg_temp_new_i32();
3031 TCGv_i32 t3 = tcg_temp_new_i32();
3032
3033 tcg_gen_trunc_tl_i32(t2, t0);
3034 tcg_gen_trunc_tl_i32(t3, t1);
3035 tcg_gen_andi_i32(t2, t2, 0x1f);
3036 tcg_gen_rotr_i32(t2, t3, t2);
3037 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3038 tcg_temp_free_i32(t2);
3039 tcg_temp_free_i32(t3);
3040 opn = "rotrv";
5a63bcb2 3041 }
7a387fff 3042 break;
d26bc211 3043#if defined(TARGET_MIPS64)
7a387fff 3044 case OPC_DSLLV:
78723684 3045 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3046 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3047 opn = "dsllv";
3048 break;
3049 case OPC_DSRAV:
78723684 3050 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3051 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3052 opn = "dsrav";
3053 break;
3054 case OPC_DSRLV:
ea63e2c3
NF
3055 tcg_gen_andi_tl(t0, t0, 0x3f);
3056 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3057 opn = "dsrlv";
3058 break;
3059 case OPC_DROTRV:
3060 tcg_gen_andi_tl(t0, t0, 0x3f);
3061 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3062 opn = "drotrv";
6af0bf9c 3063 break;
7a387fff 3064#endif
6af0bf9c 3065 }
2abf314d 3066 (void)opn; /* avoid a compiler warning */
6af0bf9c 3067 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3068 tcg_temp_free(t0);
3069 tcg_temp_free(t1);
6af0bf9c
FB
3070}
3071
3072/* Arithmetic on HI/LO registers */
26135ead 3073static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3074{
923617a3 3075 const char *opn = "hilo";
6af0bf9c
FB
3076
3077 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3078 /* Treat as NOP. */
6af0bf9c 3079 MIPS_DEBUG("NOP");
a1f6684d 3080 return;
6af0bf9c 3081 }
4133498f 3082
4133498f
JL
3083 if (acc != 0) {
3084 check_dsp(ctx);
3085 }
3086
6af0bf9c
FB
3087 switch (opc) {
3088 case OPC_MFHI:
4133498f
JL
3089#if defined(TARGET_MIPS64)
3090 if (acc != 0) {
3091 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3092 } else
3093#endif
3094 {
3095 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3096 }
6af0bf9c
FB
3097 opn = "mfhi";
3098 break;
3099 case OPC_MFLO:
4133498f
JL
3100#if defined(TARGET_MIPS64)
3101 if (acc != 0) {
3102 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3103 } else
3104#endif
3105 {
3106 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3107 }
6af0bf9c
FB
3108 opn = "mflo";
3109 break;
3110 case OPC_MTHI:
4133498f
JL
3111 if (reg != 0) {
3112#if defined(TARGET_MIPS64)
3113 if (acc != 0) {
3114 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3115 } else
3116#endif
3117 {
3118 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3119 }
3120 } else {
3121 tcg_gen_movi_tl(cpu_HI[acc], 0);
3122 }
6af0bf9c
FB
3123 opn = "mthi";
3124 break;
3125 case OPC_MTLO:
4133498f
JL
3126 if (reg != 0) {
3127#if defined(TARGET_MIPS64)
3128 if (acc != 0) {
3129 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3130 } else
3131#endif
3132 {
3133 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3134 }
3135 } else {
3136 tcg_gen_movi_tl(cpu_LO[acc], 0);
3137 }
6af0bf9c
FB
3138 opn = "mtlo";
3139 break;
6af0bf9c 3140 }
2abf314d 3141 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3142 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3143}
3144
d4ea6acd
LA
3145static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3146 TCGMemOp memop)
3147{
3148 TCGv t0 = tcg_const_tl(addr);
3149 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3150 gen_store_gpr(t0, reg);
3151 tcg_temp_free(t0);
3152}
3153
3154static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3155{
3156 target_long offset;
3157 target_long addr;
3158
3159 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3160 case OPC_ADDIUPC:
3161 if (rs != 0) {
3162 offset = sextract32(ctx->opcode << 2, 0, 21);
3163 addr = addr_add(ctx, ctx->pc, offset);
3164 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3165 }
3166 break;
3167 case R6_OPC_LWPC:
3168 offset = sextract32(ctx->opcode << 2, 0, 21);
3169 addr = addr_add(ctx, ctx->pc, offset);
3170 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3171 break;
3172#if defined(TARGET_MIPS64)
3173 case OPC_LWUPC:
3174 check_mips_64(ctx);
3175 offset = sextract32(ctx->opcode << 2, 0, 21);
3176 addr = addr_add(ctx, ctx->pc, offset);
3177 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3178 break;
3179#endif
3180 default:
3181 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3182 case OPC_AUIPC:
3183 if (rs != 0) {
3184 offset = imm << 16;
3185 addr = addr_add(ctx, ctx->pc, offset);
3186 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3187 }
3188 break;
3189 case OPC_ALUIPC:
3190 if (rs != 0) {
3191 offset = imm << 16;
3192 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3193 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3194 }
3195 break;
3196#if defined(TARGET_MIPS64)
3197 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3198 case R6_OPC_LDPC + (1 << 16):
3199 case R6_OPC_LDPC + (2 << 16):
3200 case R6_OPC_LDPC + (3 << 16):
3201 check_mips_64(ctx);
3202 offset = sextract32(ctx->opcode << 3, 0, 21);
3203 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3204 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3205 break;
3206#endif
3207 default:
3208 MIPS_INVAL("OPC_PCREL");
3209 generate_exception(ctx, EXCP_RI);
3210 break;
3211 }
3212 break;
3213 }
3214}
3215
b42ee5e1
LA
3216static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3217{
3218 const char *opn = "r6 mul/div";
3219 TCGv t0, t1;
3220
3221 if (rd == 0) {
3222 /* Treat as NOP. */
3223 MIPS_DEBUG("NOP");
3224 return;
3225 }
3226
3227 t0 = tcg_temp_new();
3228 t1 = tcg_temp_new();
3229
3230 gen_load_gpr(t0, rs);
3231 gen_load_gpr(t1, rt);
3232
3233 switch (opc) {
3234 case R6_OPC_DIV:
3235 {
3236 TCGv t2 = tcg_temp_new();
3237 TCGv t3 = tcg_temp_new();
3238 tcg_gen_ext32s_tl(t0, t0);
3239 tcg_gen_ext32s_tl(t1, t1);
3240 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3241 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3242 tcg_gen_and_tl(t2, t2, t3);
3243 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3244 tcg_gen_or_tl(t2, t2, t3);
3245 tcg_gen_movi_tl(t3, 0);
3246 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3247 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3248 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3249 tcg_temp_free(t3);
3250 tcg_temp_free(t2);
3251 }
3252 opn = "div";
3253 break;
3254 case R6_OPC_MOD:
3255 {
3256 TCGv t2 = tcg_temp_new();
3257 TCGv t3 = tcg_temp_new();
3258 tcg_gen_ext32s_tl(t0, t0);
3259 tcg_gen_ext32s_tl(t1, t1);
3260 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3261 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3262 tcg_gen_and_tl(t2, t2, t3);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3264 tcg_gen_or_tl(t2, t2, t3);
3265 tcg_gen_movi_tl(t3, 0);
3266 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3267 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3268 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3269 tcg_temp_free(t3);
3270 tcg_temp_free(t2);
3271 }
3272 opn = "mod";
3273 break;
3274 case R6_OPC_DIVU:
3275 {
3276 TCGv t2 = tcg_const_tl(0);
3277 TCGv t3 = tcg_const_tl(1);
3278 tcg_gen_ext32u_tl(t0, t0);
3279 tcg_gen_ext32u_tl(t1, t1);
3280 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3281 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3282 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3283 tcg_temp_free(t3);
3284 tcg_temp_free(t2);
3285 }
3286 opn = "divu";
3287 break;
3288 case R6_OPC_MODU:
3289 {
3290 TCGv t2 = tcg_const_tl(0);
3291 TCGv t3 = tcg_const_tl(1);
3292 tcg_gen_ext32u_tl(t0, t0);
3293 tcg_gen_ext32u_tl(t1, t1);
3294 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3295 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3296 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3297 tcg_temp_free(t3);
3298 tcg_temp_free(t2);
3299 }
3300 opn = "modu";
3301 break;
3302 case R6_OPC_MUL:
3303 {
3304 TCGv_i32 t2 = tcg_temp_new_i32();
3305 TCGv_i32 t3 = tcg_temp_new_i32();
3306 tcg_gen_trunc_tl_i32(t2, t0);
3307 tcg_gen_trunc_tl_i32(t3, t1);
3308 tcg_gen_mul_i32(t2, t2, t3);
3309 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3310 tcg_temp_free_i32(t2);
3311 tcg_temp_free_i32(t3);
3312 }
3313 opn = "mul";
3314 break;
3315 case R6_OPC_MUH:
3316 {
3317 TCGv_i32 t2 = tcg_temp_new_i32();
3318 TCGv_i32 t3 = tcg_temp_new_i32();
3319 tcg_gen_trunc_tl_i32(t2, t0);
3320 tcg_gen_trunc_tl_i32(t3, t1);
3321 tcg_gen_muls2_i32(t2, t3, t2, t3);
3322 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3323 tcg_temp_free_i32(t2);
3324 tcg_temp_free_i32(t3);
3325 }
3326 opn = "muh";
3327 break;
3328 case R6_OPC_MULU:
3329 {
3330 TCGv_i32 t2 = tcg_temp_new_i32();
3331 TCGv_i32 t3 = tcg_temp_new_i32();
3332 tcg_gen_trunc_tl_i32(t2, t0);
3333 tcg_gen_trunc_tl_i32(t3, t1);
3334 tcg_gen_mul_i32(t2, t2, t3);
3335 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3336 tcg_temp_free_i32(t2);
3337 tcg_temp_free_i32(t3);
3338 }
3339 opn = "mulu";
3340 break;
3341 case R6_OPC_MUHU:
3342 {
3343 TCGv_i32 t2 = tcg_temp_new_i32();
3344 TCGv_i32 t3 = tcg_temp_new_i32();
3345 tcg_gen_trunc_tl_i32(t2, t0);
3346 tcg_gen_trunc_tl_i32(t3, t1);
3347 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3348 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3349 tcg_temp_free_i32(t2);
3350 tcg_temp_free_i32(t3);
3351 }
3352 opn = "muhu";
3353 break;
3354#if defined(TARGET_MIPS64)
3355 case R6_OPC_DDIV:
3356 {
3357 TCGv t2 = tcg_temp_new();
3358 TCGv t3 = tcg_temp_new();
3359 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3360 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3361 tcg_gen_and_tl(t2, t2, t3);
3362 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3363 tcg_gen_or_tl(t2, t2, t3);
3364 tcg_gen_movi_tl(t3, 0);
3365 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3366 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3367 tcg_temp_free(t3);
3368 tcg_temp_free(t2);
3369 }
3370 opn = "ddiv";
3371 break;
3372 case R6_OPC_DMOD:
3373 {
3374 TCGv t2 = tcg_temp_new();
3375 TCGv t3 = tcg_temp_new();
3376 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3377 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3378 tcg_gen_and_tl(t2, t2, t3);
3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3380 tcg_gen_or_tl(t2, t2, t3);
3381 tcg_gen_movi_tl(t3, 0);
3382 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3383 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3384 tcg_temp_free(t3);
3385 tcg_temp_free(t2);
3386 }
3387 opn = "dmod";
3388 break;
3389 case R6_OPC_DDIVU:
3390 {
3391 TCGv t2 = tcg_const_tl(0);
3392 TCGv t3 = tcg_const_tl(1);
3393 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3394 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3395 tcg_temp_free(t3);
3396 tcg_temp_free(t2);
3397 }
3398 opn = "ddivu";
3399 break;
3400 case R6_OPC_DMODU:
3401 {
3402 TCGv t2 = tcg_const_tl(0);
3403 TCGv t3 = tcg_const_tl(1);
3404 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3405 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3406 tcg_temp_free(t3);
3407 tcg_temp_free(t2);
3408 }
3409 opn = "dmodu";
3410 break;
3411 case R6_OPC_DMUL:
3412 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3413 opn = "dmul";
3414 break;
3415 case R6_OPC_DMUH:
3416 {
3417 TCGv t2 = tcg_temp_new();
3418 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3419 tcg_temp_free(t2);
3420 }
3421 opn = "dmuh";
3422 break;
3423 case R6_OPC_DMULU:
3424 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3425 opn = "dmulu";
3426 break;
3427 case R6_OPC_DMUHU:
3428 {
3429 TCGv t2 = tcg_temp_new();
3430 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3431 tcg_temp_free(t2);
3432 }
3433 opn = "dmuhu";
3434 break;
3435#endif
3436 default:
3437 MIPS_INVAL(opn);
3438 generate_exception(ctx, EXCP_RI);
3439 goto out;
3440 }
3441 (void)opn; /* avoid a compiler warning */
3442 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3443 out:
3444 tcg_temp_free(t0);
3445 tcg_temp_free(t1);
3446}
3447
26135ead
RS
3448static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3449 int acc, int rs, int rt)
6af0bf9c 3450{
923617a3 3451 const char *opn = "mul/div";
d45f89f4
AJ
3452 TCGv t0, t1;
3453
51127181
AJ
3454 t0 = tcg_temp_new();
3455 t1 = tcg_temp_new();
6af0bf9c 3456
78723684
TS
3457 gen_load_gpr(t0, rs);
3458 gen_load_gpr(t1, rt);
51127181 3459
26135ead
RS
3460 if (acc != 0) {
3461 check_dsp(ctx);
3462 }
3463
6af0bf9c
FB
3464 switch (opc) {
3465 case OPC_DIV:
48d38ca5 3466 {
51127181
AJ
3467 TCGv t2 = tcg_temp_new();
3468 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3469 tcg_gen_ext32s_tl(t0, t0);
3470 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3471 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3472 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3473 tcg_gen_and_tl(t2, t2, t3);
3474 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3475 tcg_gen_or_tl(t2, t2, t3);
3476 tcg_gen_movi_tl(t3, 0);
3477 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3478 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3479 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3480 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3481 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3482 tcg_temp_free(t3);
3483 tcg_temp_free(t2);
48d38ca5 3484 }
6af0bf9c
FB
3485 opn = "div";
3486 break;
3487 case OPC_DIVU:
48d38ca5 3488 {
51127181
AJ
3489 TCGv t2 = tcg_const_tl(0);
3490 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3491 tcg_gen_ext32u_tl(t0, t0);
3492 tcg_gen_ext32u_tl(t1, t1);
51127181 3493 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3494 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3495 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3496 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3497 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3498 tcg_temp_free(t3);
3499 tcg_temp_free(t2);
48d38ca5 3500 }
6af0bf9c
FB
3501 opn = "divu";
3502 break;
3503 case OPC_MULT:
214c465f 3504 {
ce1dd5d1
RH
3505 TCGv_i32 t2 = tcg_temp_new_i32();
3506 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3507 tcg_gen_trunc_tl_i32(t2, t0);
3508 tcg_gen_trunc_tl_i32(t3, t1);
3509 tcg_gen_muls2_i32(t2, t3, t2, t3);
3510 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3511 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3512 tcg_temp_free_i32(t2);
3513 tcg_temp_free_i32(t3);
214c465f 3514 }
6af0bf9c
FB
3515 opn = "mult";
3516 break;
3517 case OPC_MULTU:
214c465f 3518 {
ce1dd5d1
RH
3519 TCGv_i32 t2 = tcg_temp_new_i32();
3520 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3521 tcg_gen_trunc_tl_i32(t2, t0);
3522 tcg_gen_trunc_tl_i32(t3, t1);
3523 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3524 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3525 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3526 tcg_temp_free_i32(t2);
3527 tcg_temp_free_i32(t3);
214c465f 3528 }
6af0bf9c
FB
3529 opn = "multu";
3530 break;
d26bc211 3531#if defined(TARGET_MIPS64)
7a387fff 3532 case OPC_DDIV:
48d38ca5 3533 {
51127181
AJ
3534 TCGv t2 = tcg_temp_new();
3535 TCGv t3 = tcg_temp_new();
3536 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3537 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3538 tcg_gen_and_tl(t2, t2, t3);
3539 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3540 tcg_gen_or_tl(t2, t2, t3);
3541 tcg_gen_movi_tl(t3, 0);
3542 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3543 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3544 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3545 tcg_temp_free(t3);
3546 tcg_temp_free(t2);
48d38ca5 3547 }
7a387fff
TS
3548 opn = "ddiv";
3549 break;
3550 case OPC_DDIVU:
48d38ca5 3551 {
51127181
AJ
3552 TCGv t2 = tcg_const_tl(0);
3553 TCGv t3 = tcg_const_tl(1);
3554 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3555 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3556 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3557 tcg_temp_free(t3);
3558 tcg_temp_free(t2);
48d38ca5 3559 }
7a387fff
TS
3560 opn = "ddivu";
3561 break;
3562 case OPC_DMULT:
26135ead 3563 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3564 opn = "dmult";
3565 break;
3566 case OPC_DMULTU:
26135ead 3567 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3568 opn = "dmultu";
3569 break;
3570#endif
6af0bf9c 3571 case OPC_MADD:
214c465f 3572 {
d45f89f4
AJ
3573 TCGv_i64 t2 = tcg_temp_new_i64();
3574 TCGv_i64 t3 = tcg_temp_new_i64();
3575
3576 tcg_gen_ext_tl_i64(t2, t0);
3577 tcg_gen_ext_tl_i64(t3, t1);
3578 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3579 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3580 tcg_gen_add_i64(t2, t2, t3);
3581 tcg_temp_free_i64(t3);
3582 tcg_gen_trunc_i64_tl(t0, t2);
3583 tcg_gen_shri_i64(t2, t2, 32);
3584 tcg_gen_trunc_i64_tl(t1, t2);
3585 tcg_temp_free_i64(t2);
4133498f
JL
3586 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3587 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3588 }
6af0bf9c
FB
3589 opn = "madd";
3590 break;
3591 case OPC_MADDU:
4133498f 3592 {
d45f89f4
AJ
3593 TCGv_i64 t2 = tcg_temp_new_i64();
3594 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3595
78723684
TS
3596 tcg_gen_ext32u_tl(t0, t0);
3597 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3598 tcg_gen_extu_tl_i64(t2, t0);
3599 tcg_gen_extu_tl_i64(t3, t1);
3600 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3601 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3602 tcg_gen_add_i64(t2, t2, t3);
3603 tcg_temp_free_i64(t3);
3604 tcg_gen_trunc_i64_tl(t0, t2);
3605 tcg_gen_shri_i64(t2, t2, 32);
3606 tcg_gen_trunc_i64_tl(t1, t2);
3607 tcg_temp_free_i64(t2);
4133498f
JL
3608 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3609 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3610 }
6af0bf9c
FB
3611 opn = "maddu";
3612 break;
3613 case OPC_MSUB:
214c465f 3614 {
d45f89f4
AJ
3615 TCGv_i64 t2 = tcg_temp_new_i64();
3616 TCGv_i64 t3 = tcg_temp_new_i64();
3617
3618 tcg_gen_ext_tl_i64(t2, t0);
3619 tcg_gen_ext_tl_i64(t3, t1);
3620 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3621 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3622 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3623 tcg_temp_free_i64(t3);
3624 tcg_gen_trunc_i64_tl(t0, t2);
3625 tcg_gen_shri_i64(t2, t2, 32);
3626 tcg_gen_trunc_i64_tl(t1, t2);
3627 tcg_temp_free_i64(t2);
4133498f
JL
3628 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3629 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3630 }
6af0bf9c
FB
3631 opn = "msub";
3632 break;
3633 case OPC_MSUBU:
214c465f 3634 {
d45f89f4
AJ
3635 TCGv_i64 t2 = tcg_temp_new_i64();
3636 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3637
78723684
TS
3638 tcg_gen_ext32u_tl(t0, t0);
3639 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3640 tcg_gen_extu_tl_i64(t2, t0);
3641 tcg_gen_extu_tl_i64(t3, t1);
3642 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3643 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3644 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3645 tcg_temp_free_i64(t3);
3646 tcg_gen_trunc_i64_tl(t0, t2);
3647 tcg_gen_shri_i64(t2, t2, 32);
3648 tcg_gen_trunc_i64_tl(t1, t2);
3649 tcg_temp_free_i64(t2);
4133498f
JL
3650 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3651 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3652 }
6af0bf9c
FB
3653 opn = "msubu";
3654 break;
3655 default:
923617a3 3656 MIPS_INVAL(opn);
6af0bf9c 3657 generate_exception(ctx, EXCP_RI);
78723684 3658 goto out;
6af0bf9c 3659 }
2abf314d 3660 (void)opn; /* avoid a compiler warning */
6af0bf9c 3661 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3662 out:
3663 tcg_temp_free(t0);
3664 tcg_temp_free(t1);
6af0bf9c
FB
3665}
3666
e9c71dd1
TS
3667static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3668 int rd, int rs, int rt)
3669{
3670 const char *opn = "mul vr54xx";
f157bfe1
AJ
3671 TCGv t0 = tcg_temp_new();
3672 TCGv t1 = tcg_temp_new();
e9c71dd1 3673
6c5c1e20
TS
3674 gen_load_gpr(t0, rs);
3675 gen_load_gpr(t1, rt);
e9c71dd1
TS
3676
3677 switch (opc) {
3678 case OPC_VR54XX_MULS:
895c2d04 3679 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3680 opn = "muls";
6958549d 3681 break;
e9c71dd1 3682 case OPC_VR54XX_MULSU:
895c2d04 3683 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3684 opn = "mulsu";
6958549d 3685 break;
e9c71dd1 3686 case OPC_VR54XX_MACC:
895c2d04 3687 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3688 opn = "macc";
6958549d 3689 break;
e9c71dd1 3690 case OPC_VR54XX_MACCU:
895c2d04 3691 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3692 opn = "maccu";
6958549d 3693 break;
e9c71dd1 3694 case OPC_VR54XX_MSAC:
895c2d04 3695 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3696 opn = "msac";
6958549d 3697 break;
e9c71dd1 3698 case OPC_VR54XX_MSACU:
895c2d04 3699 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3700 opn = "msacu";
6958549d 3701 break;
e9c71dd1 3702 case OPC_VR54XX_MULHI:
895c2d04 3703 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3704 opn = "mulhi";
6958549d 3705 break;
e9c71dd1 3706 case OPC_VR54XX_MULHIU:
895c2d04 3707 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3708 opn = "mulhiu";
6958549d 3709 break;
e9c71dd1 3710 case OPC_VR54XX_MULSHI:
895c2d04 3711 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3712 opn = "mulshi";
6958549d 3713 break;
e9c71dd1 3714 case OPC_VR54XX_MULSHIU:
895c2d04 3715 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3716 opn = "mulshiu";
6958549d 3717 break;
e9c71dd1 3718 case OPC_VR54XX_MACCHI:
895c2d04 3719 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3720 opn = "macchi";
6958549d 3721 break;
e9c71dd1 3722 case OPC_VR54XX_MACCHIU:
895c2d04 3723 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3724 opn = "macchiu";
6958549d 3725 break;
e9c71dd1 3726 case OPC_VR54XX_MSACHI:
895c2d04 3727 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3728 opn = "msachi";
6958549d 3729 break;
e9c71dd1 3730 case OPC_VR54XX_MSACHIU:
895c2d04 3731 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3732 opn = "msachiu";
6958549d 3733 break;
e9c71dd1
TS
3734 default:
3735 MIPS_INVAL("mul vr54xx");
3736 generate_exception(ctx, EXCP_RI);
6c5c1e20 3737 goto out;
e9c71dd1 3738 }
6c5c1e20 3739 gen_store_gpr(t0, rd);
2abf314d 3740 (void)opn; /* avoid a compiler warning */
e9c71dd1 3741 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3742
3743 out:
3744 tcg_temp_free(t0);
3745 tcg_temp_free(t1);
e9c71dd1
TS
3746}
3747
7a387fff 3748static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3749 int rd, int rs)
3750{
923617a3 3751 const char *opn = "CLx";
20e1fb52 3752 TCGv t0;
6c5c1e20 3753
6af0bf9c 3754 if (rd == 0) {
ead9360e 3755 /* Treat as NOP. */
6af0bf9c 3756 MIPS_DEBUG("NOP");
20e1fb52 3757 return;
6af0bf9c 3758 }
20e1fb52 3759 t0 = tcg_temp_new();
6c5c1e20 3760 gen_load_gpr(t0, rs);
6af0bf9c
FB
3761 switch (opc) {
3762 case OPC_CLO:
4267d3e6 3763 case R6_OPC_CLO:
20e1fb52 3764 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3765 opn = "clo";
3766 break;
3767 case OPC_CLZ:
4267d3e6 3768 case R6_OPC_CLZ:
20e1fb52 3769 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3770 opn = "clz";
3771 break;
d26bc211 3772#if defined(TARGET_MIPS64)
7a387fff 3773 case OPC_DCLO:
4267d3e6 3774 case R6_OPC_DCLO:
20e1fb52 3775 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3776 opn = "dclo";
3777 break;
3778 case OPC_DCLZ:
4267d3e6 3779 case R6_OPC_DCLZ:
20e1fb52 3780 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3781 opn = "dclz";
3782 break;
3783#endif
6af0bf9c 3784 }
2abf314d 3785 (void)opn; /* avoid a compiler warning */
6af0bf9c 3786 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3787 tcg_temp_free(t0);
6af0bf9c
FB
3788}
3789
161f85e6 3790/* Godson integer instructions */
bd277fa1
RH
3791static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3792 int rd, int rs, int rt)
161f85e6
AJ
3793{
3794 const char *opn = "loongson";
3795 TCGv t0, t1;
3796
3797 if (rd == 0) {
3798 /* Treat as NOP. */
3799 MIPS_DEBUG("NOP");
3800 return;
3801 }
3802
3803 switch (opc) {
3804 case OPC_MULT_G_2E:
3805 case OPC_MULT_G_2F:
3806 case OPC_MULTU_G_2E:
3807 case OPC_MULTU_G_2F:
3808#if defined(TARGET_MIPS64)
3809 case OPC_DMULT_G_2E:
3810 case OPC_DMULT_G_2F:
3811 case OPC_DMULTU_G_2E:
3812 case OPC_DMULTU_G_2F:
3813#endif
3814 t0 = tcg_temp_new();
3815 t1 = tcg_temp_new();
3816 break;
3817 default:
3818 t0 = tcg_temp_local_new();
3819 t1 = tcg_temp_local_new();
3820 break;
3821 }
3822
3823 gen_load_gpr(t0, rs);
3824 gen_load_gpr(t1, rt);
3825
3826 switch (opc) {
3827 case OPC_MULT_G_2E:
3828 case OPC_MULT_G_2F:
3829 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3830 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3831 opn = "mult.g";
3832 break;
3833 case OPC_MULTU_G_2E:
3834 case OPC_MULTU_G_2F:
3835 tcg_gen_ext32u_tl(t0, t0);
3836 tcg_gen_ext32u_tl(t1, t1);
3837 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3838 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3839 opn = "multu.g";
3840 break;
3841 case OPC_DIV_G_2E:
3842 case OPC_DIV_G_2F:
3843 {
3844 int l1 = gen_new_label();
3845 int l2 = gen_new_label();
3846 int l3 = gen_new_label();
3847 tcg_gen_ext32s_tl(t0, t0);
3848 tcg_gen_ext32s_tl(t1, t1);
3849 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3850 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3851 tcg_gen_br(l3);
3852 gen_set_label(l1);
3853 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3854 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3855 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3856 tcg_gen_br(l3);
3857 gen_set_label(l2);
3858 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3859 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3860 gen_set_label(l3);
3861 }
3862 opn = "div.g";
3863 break;
3864 case OPC_DIVU_G_2E:
3865 case OPC_DIVU_G_2F:
3866 {
3867 int l1 = gen_new_label();
3868 int l2 = gen_new_label();
3869 tcg_gen_ext32u_tl(t0, t0);
3870 tcg_gen_ext32u_tl(t1, t1);
3871 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3872 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3873 tcg_gen_br(l2);
3874 gen_set_label(l1);
3875 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3876 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3877 gen_set_label(l2);
3878 }
3879 opn = "divu.g";
3880 break;
3881 case OPC_MOD_G_2E:
3882 case OPC_MOD_G_2F:
3883 {
3884 int l1 = gen_new_label();
3885 int l2 = gen_new_label();
3886 int l3 = gen_new_label();
3887 tcg_gen_ext32u_tl(t0, t0);
3888 tcg_gen_ext32u_tl(t1, t1);
3889 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3890 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3891 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3892 gen_set_label(l1);
3893 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3894 tcg_gen_br(l3);
3895 gen_set_label(l2);
3896 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3897 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3898 gen_set_label(l3);
3899 }
3900 opn = "mod.g";
3901 break;
3902 case OPC_MODU_G_2E:
3903 case OPC_MODU_G_2F:
3904 {
3905 int l1 = gen_new_label();
3906 int l2 = gen_new_label();
3907 tcg_gen_ext32u_tl(t0, t0);
3908 tcg_gen_ext32u_tl(t1, t1);
3909 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3910 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3911 tcg_gen_br(l2);
3912 gen_set_label(l1);
3913 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3914 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3915 gen_set_label(l2);
3916 }
3917 opn = "modu.g";
3918 break;
3919#if defined(TARGET_MIPS64)
3920 case OPC_DMULT_G_2E:
3921 case OPC_DMULT_G_2F:
3922 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3923 opn = "dmult.g";
3924 break;
3925 case OPC_DMULTU_G_2E:
3926 case OPC_DMULTU_G_2F:
3927 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3928 opn = "dmultu.g";
3929 break;
3930 case OPC_DDIV_G_2E:
3931 case OPC_DDIV_G_2F:
3932 {
3933 int l1 = gen_new_label();
3934 int l2 = gen_new_label();
3935 int l3 = gen_new_label();
3936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3937 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3938 tcg_gen_br(l3);
3939 gen_set_label(l1);
3940 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3941 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3942 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3943 tcg_gen_br(l3);
3944 gen_set_label(l2);
3945 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3946 gen_set_label(l3);
3947 }
3948 opn = "ddiv.g";
3949 break;
3950 case OPC_DDIVU_G_2E:
3951 case OPC_DDIVU_G_2F:
3952 {
3953 int l1 = gen_new_label();
3954 int l2 = gen_new_label();
3955 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3956 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3957 tcg_gen_br(l2);
3958 gen_set_label(l1);
3959 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3960 gen_set_label(l2);
3961 }
3962 opn = "ddivu.g";
3963 break;
3964 case OPC_DMOD_G_2E:
3965 case OPC_DMOD_G_2F:
3966 {
3967 int l1 = gen_new_label();
3968 int l2 = gen_new_label();
3969 int l3 = gen_new_label();
3970 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3971 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3972 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3973 gen_set_label(l1);
3974 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3975 tcg_gen_br(l3);
3976 gen_set_label(l2);
3977 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3978 gen_set_label(l3);
3979 }
3980 opn = "dmod.g";
3981 break;
3982 case OPC_DMODU_G_2E:
3983 case OPC_DMODU_G_2F:
3984 {
3985 int l1 = gen_new_label();
3986 int l2 = gen_new_label();
3987 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3988 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3989 tcg_gen_br(l2);
3990 gen_set_label(l1);
3991 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3992 gen_set_label(l2);
3993 }
3994 opn = "dmodu.g";
3995 break;
3996#endif
3997 }
3998
2abf314d 3999 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4000 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4001 tcg_temp_free(t0);
4002 tcg_temp_free(t1);
4003}
4004
bd277fa1
RH
4005/* Loongson multimedia instructions */
4006static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4007{
4008 const char *opn = "loongson_cp2";
4009 uint32_t opc, shift_max;
4010 TCGv_i64 t0, t1;
4011
4012 opc = MASK_LMI(ctx->opcode);
4013 switch (opc) {
4014 case OPC_ADD_CP2:
4015 case OPC_SUB_CP2:
4016 case OPC_DADD_CP2:
4017 case OPC_DSUB_CP2:
4018 t0 = tcg_temp_local_new_i64();
4019 t1 = tcg_temp_local_new_i64();
4020 break;
4021 default:
4022 t0 = tcg_temp_new_i64();
4023 t1 = tcg_temp_new_i64();
4024 break;
4025 }
4026
4027 gen_load_fpr64(ctx, t0, rs);
4028 gen_load_fpr64(ctx, t1, rt);
4029
4030#define LMI_HELPER(UP, LO) \
4031 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4032#define LMI_HELPER_1(UP, LO) \
4033 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4034#define LMI_DIRECT(UP, LO, OP) \
4035 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4036
4037 switch (opc) {
4038 LMI_HELPER(PADDSH, paddsh);
4039 LMI_HELPER(PADDUSH, paddush);
4040 LMI_HELPER(PADDH, paddh);
4041 LMI_HELPER(PADDW, paddw);
4042 LMI_HELPER(PADDSB, paddsb);
4043 LMI_HELPER(PADDUSB, paddusb);
4044 LMI_HELPER(PADDB, paddb);
4045
4046 LMI_HELPER(PSUBSH, psubsh);
4047 LMI_HELPER(PSUBUSH, psubush);
4048 LMI_HELPER(PSUBH, psubh);
4049 LMI_HELPER(PSUBW, psubw);
4050 LMI_HELPER(PSUBSB, psubsb);
4051 LMI_HELPER(PSUBUSB, psubusb);
4052 LMI_HELPER(PSUBB, psubb);
4053
4054 LMI_HELPER(PSHUFH, pshufh);
4055 LMI_HELPER(PACKSSWH, packsswh);
4056 LMI_HELPER(PACKSSHB, packsshb);
4057 LMI_HELPER(PACKUSHB, packushb);
4058
4059 LMI_HELPER(PUNPCKLHW, punpcklhw);
4060 LMI_HELPER(PUNPCKHHW, punpckhhw);
4061 LMI_HELPER(PUNPCKLBH, punpcklbh);
4062 LMI_HELPER(PUNPCKHBH, punpckhbh);
4063 LMI_HELPER(PUNPCKLWD, punpcklwd);
4064 LMI_HELPER(PUNPCKHWD, punpckhwd);
4065
4066 LMI_HELPER(PAVGH, pavgh);
4067 LMI_HELPER(PAVGB, pavgb);
4068 LMI_HELPER(PMAXSH, pmaxsh);
4069 LMI_HELPER(PMINSH, pminsh);
4070 LMI_HELPER(PMAXUB, pmaxub);
4071 LMI_HELPER(PMINUB, pminub);
4072
4073 LMI_HELPER(PCMPEQW, pcmpeqw);
4074 LMI_HELPER(PCMPGTW, pcmpgtw);
4075 LMI_HELPER(PCMPEQH, pcmpeqh);
4076 LMI_HELPER(PCMPGTH, pcmpgth);
4077 LMI_HELPER(PCMPEQB, pcmpeqb);
4078 LMI_HELPER(PCMPGTB, pcmpgtb);
4079
4080 LMI_HELPER(PSLLW, psllw);
4081 LMI_HELPER(PSLLH, psllh);
4082 LMI_HELPER(PSRLW, psrlw);
4083 LMI_HELPER(PSRLH, psrlh);
4084 LMI_HELPER(PSRAW, psraw);
4085 LMI_HELPER(PSRAH, psrah);
4086
4087 LMI_HELPER(PMULLH, pmullh);
4088 LMI_HELPER(PMULHH, pmulhh);
4089 LMI_HELPER(PMULHUH, pmulhuh);
4090 LMI_HELPER(PMADDHW, pmaddhw);
4091
4092 LMI_HELPER(PASUBUB, pasubub);
4093 LMI_HELPER_1(BIADD, biadd);
4094 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4095
4096 LMI_DIRECT(PADDD, paddd, add);
4097 LMI_DIRECT(PSUBD, psubd, sub);
4098 LMI_DIRECT(XOR_CP2, xor, xor);
4099 LMI_DIRECT(NOR_CP2, nor, nor);
4100 LMI_DIRECT(AND_CP2, and, and);
4101 LMI_DIRECT(PANDN, pandn, andc);
4102 LMI_DIRECT(OR, or, or);
4103
4104 case OPC_PINSRH_0:
4105 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4106 opn = "pinsrh_0";
4107 break;
4108 case OPC_PINSRH_1:
4109 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4110 opn = "pinsrh_1";
4111 break;
4112 case OPC_PINSRH_2:
4113 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4114 opn = "pinsrh_2";
4115 break;
4116 case OPC_PINSRH_3:
4117 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4118 opn = "pinsrh_3";
4119 break;
4120
4121 case OPC_PEXTRH:
4122 tcg_gen_andi_i64(t1, t1, 3);
4123 tcg_gen_shli_i64(t1, t1, 4);
4124 tcg_gen_shr_i64(t0, t0, t1);
4125 tcg_gen_ext16u_i64(t0, t0);
4126 opn = "pextrh";
4127 break;
4128
4129 case OPC_ADDU_CP2:
4130 tcg_gen_add_i64(t0, t0, t1);
4131 tcg_gen_ext32s_i64(t0, t0);
4132 opn = "addu";
4133 break;
4134 case OPC_SUBU_CP2:
4135 tcg_gen_sub_i64(t0, t0, t1);
4136 tcg_gen_ext32s_i64(t0, t0);
4137 opn = "addu";
4138 break;
4139
4140 case OPC_SLL_CP2:
4141 opn = "sll";
4142 shift_max = 32;
4143 goto do_shift;
4144 case OPC_SRL_CP2:
4145 opn = "srl";
4146 shift_max = 32;
4147 goto do_shift;
4148 case OPC_SRA_CP2:
4149 opn = "sra";
4150 shift_max = 32;
4151 goto do_shift;
4152 case OPC_DSLL_CP2:
4153 opn = "dsll";
4154 shift_max = 64;
4155 goto do_shift;
4156 case OPC_DSRL_CP2:
4157 opn = "dsrl";
4158 shift_max = 64;
4159 goto do_shift;
4160 case OPC_DSRA_CP2:
4161 opn = "dsra";
4162 shift_max = 64;
4163 goto do_shift;
4164 do_shift:
4165 /* Make sure shift count isn't TCG undefined behaviour. */
4166 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4167
4168 switch (opc) {
4169 case OPC_SLL_CP2:
4170 case OPC_DSLL_CP2:
4171 tcg_gen_shl_i64(t0, t0, t1);
4172 break;
4173 case OPC_SRA_CP2:
4174 case OPC_DSRA_CP2:
4175 /* Since SRA is UndefinedResult without sign-extended inputs,
4176 we can treat SRA and DSRA the same. */
4177 tcg_gen_sar_i64(t0, t0, t1);
4178 break;
4179 case OPC_SRL_CP2:
4180 /* We want to shift in zeros for SRL; zero-extend first. */
4181 tcg_gen_ext32u_i64(t0, t0);
4182 /* FALLTHRU */
4183 case OPC_DSRL_CP2:
4184 tcg_gen_shr_i64(t0, t0, t1);
4185 break;
4186 }
4187
4188 if (shift_max == 32) {
4189 tcg_gen_ext32s_i64(t0, t0);
4190 }
4191
4192 /* Shifts larger than MAX produce zero. */
4193 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4194 tcg_gen_neg_i64(t1, t1);
4195 tcg_gen_and_i64(t0, t0, t1);
4196 break;
4197
4198 case OPC_ADD_CP2:
4199 case OPC_DADD_CP2:
4200 {
4201 TCGv_i64 t2 = tcg_temp_new_i64();
4202 int lab = gen_new_label();
4203
4204 tcg_gen_mov_i64(t2, t0);
4205 tcg_gen_add_i64(t0, t1, t2);
4206 if (opc == OPC_ADD_CP2) {
4207 tcg_gen_ext32s_i64(t0, t0);
4208 }
4209 tcg_gen_xor_i64(t1, t1, t2);
4210 tcg_gen_xor_i64(t2, t2, t0);
4211 tcg_gen_andc_i64(t1, t2, t1);
4212 tcg_temp_free_i64(t2);
4213 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4214 generate_exception(ctx, EXCP_OVERFLOW);
4215 gen_set_label(lab);
4216
4217 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4218 break;
4219 }
4220
4221 case OPC_SUB_CP2:
4222 case OPC_DSUB_CP2:
4223 {
4224 TCGv_i64 t2 = tcg_temp_new_i64();
4225 int lab = gen_new_label();
4226
4227 tcg_gen_mov_i64(t2, t0);
4228 tcg_gen_sub_i64(t0, t1, t2);
4229 if (opc == OPC_SUB_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_and_i64(t1, t1, t2);
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_SUB_CP2 ? "sub" : "dsub");
4241 break;
4242 }
4243
4244 case OPC_PMULUW:
4245 tcg_gen_ext32u_i64(t0, t0);
4246 tcg_gen_ext32u_i64(t1, t1);
4247 tcg_gen_mul_i64(t0, t0, t1);
4248 opn = "pmuluw";
4249 break;
4250
4251 case OPC_SEQU_CP2:
4252 case OPC_SEQ_CP2:
4253 case OPC_SLTU_CP2:
4254 case OPC_SLT_CP2:
4255 case OPC_SLEU_CP2:
4256 case OPC_SLE_CP2:
4257 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4258 FD field is the CC field? */
4259 default:
4260 MIPS_INVAL(opn);
4261 generate_exception(ctx, EXCP_RI);
4262 return;
4263 }
4264
4265#undef LMI_HELPER
4266#undef LMI_DIRECT
4267
4268 gen_store_fpr64(ctx, t0, rd);
4269
4270 (void)opn; /* avoid a compiler warning */
4271 MIPS_DEBUG("%s %s, %s, %s", opn,
4272 fregnames[rd], fregnames[rs], fregnames[rt]);
4273 tcg_temp_free_i64(t0);
4274 tcg_temp_free_i64(t1);
4275}
4276
6af0bf9c 4277/* Traps */
7a387fff 4278static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4279 int rs, int rt, int16_t imm)
4280{
4281 int cond;
cdc0faa6 4282 TCGv t0 = tcg_temp_new();
1ba74fb8 4283 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4284
4285 cond = 0;
4286 /* Load needed operands */
4287 switch (opc) {
4288 case OPC_TEQ:
4289 case OPC_TGE:
4290 case OPC_TGEU:
4291 case OPC_TLT:
4292 case OPC_TLTU:
4293 case OPC_TNE:
4294 /* Compare two registers */
4295 if (rs != rt) {
be24bb4f
TS
4296 gen_load_gpr(t0, rs);
4297 gen_load_gpr(t1, rt);
6af0bf9c
FB
4298 cond = 1;
4299 }
179e32bb 4300 break;
6af0bf9c
FB
4301 case OPC_TEQI:
4302 case OPC_TGEI:
4303 case OPC_TGEIU:
4304 case OPC_TLTI:
4305 case OPC_TLTIU:
4306 case OPC_TNEI:
4307 /* Compare register to immediate */
4308 if (rs != 0 || imm != 0) {
be24bb4f
TS
4309 gen_load_gpr(t0, rs);
4310 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4311 cond = 1;
4312 }
4313 break;
4314 }
4315 if (cond == 0) {
4316 switch (opc) {
4317 case OPC_TEQ: /* rs == rs */
4318 case OPC_TEQI: /* r0 == 0 */
4319 case OPC_TGE: /* rs >= rs */
4320 case OPC_TGEI: /* r0 >= 0 */
4321 case OPC_TGEU: /* rs >= rs unsigned */
4322 case OPC_TGEIU: /* r0 >= 0 unsigned */
4323 /* Always trap */
cdc0faa6 4324 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4325 break;
4326 case OPC_TLT: /* rs < rs */
4327 case OPC_TLTI: /* r0 < 0 */
4328 case OPC_TLTU: /* rs < rs unsigned */
4329 case OPC_TLTIU: /* r0 < 0 unsigned */
4330 case OPC_TNE: /* rs != rs */
4331 case OPC_TNEI: /* r0 != 0 */
ead9360e 4332 /* Never trap: treat as NOP. */
cdc0faa6 4333 break;
6af0bf9c
FB
4334 }
4335 } else {
cdc0faa6
AJ
4336 int l1 = gen_new_label();
4337
6af0bf9c
FB
4338 switch (opc) {
4339 case OPC_TEQ:
4340 case OPC_TEQI:
cdc0faa6 4341 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4342 break;
4343 case OPC_TGE:
4344 case OPC_TGEI:
cdc0faa6 4345 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4346 break;
4347 case OPC_TGEU:
4348 case OPC_TGEIU:
cdc0faa6 4349 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4350 break;
4351 case OPC_TLT:
4352 case OPC_TLTI:
cdc0faa6 4353 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4354 break;
4355 case OPC_TLTU:
4356 case OPC_TLTIU:
cdc0faa6 4357 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4358 break;
4359 case OPC_TNE:
4360 case OPC_TNEI:
cdc0faa6 4361 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4362 break;
6af0bf9c 4363 }
cdc0faa6 4364 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4365 gen_set_label(l1);
4366 }
be24bb4f
TS
4367 tcg_temp_free(t0);
4368 tcg_temp_free(t1);
6af0bf9c
FB
4369}
4370
356265ae 4371static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4372{
6e256c93
FB
4373 TranslationBlock *tb;
4374 tb = ctx->tb;
7b270ef2
NF
4375 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4376 likely(!ctx->singlestep_enabled)) {
57fec1fe 4377 tcg_gen_goto_tb(n);
9b9e4393 4378 gen_save_pc(dest);
8cfd0495 4379 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4380 } else {
9b9e4393 4381 gen_save_pc(dest);
7b270ef2
NF
4382 if (ctx->singlestep_enabled) {
4383 save_cpu_state(ctx, 0);
895c2d04 4384 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4385 }
57fec1fe 4386 tcg_gen_exit_tb(0);
6e256c93 4387 }
c53be334
FB
4388}
4389
6af0bf9c 4390/* Branches (before delay slot) */
7a387fff 4391static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4392 int insn_bytes,
b231c103
YK
4393 int rs, int rt, int32_t offset,
4394 int delayslot_size)
6af0bf9c 4395{
d077b6f7 4396 target_ulong btgt = -1;
3ad4bb2d 4397 int blink = 0;
2fdbad25 4398 int bcond_compute = 0;
1ba74fb8
AJ
4399 TCGv t0 = tcg_temp_new();
4400 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4401
4402 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4403#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4404 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4405 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4406#endif
3ad4bb2d 4407 generate_exception(ctx, EXCP_RI);
6c5c1e20 4408 goto out;
3ad4bb2d 4409 }
6af0bf9c 4410
6af0bf9c
FB
4411 /* Load needed operands */
4412 switch (opc) {
4413 case OPC_BEQ:
4414 case OPC_BEQL:
4415 case OPC_BNE:
4416 case OPC_BNEL:
4417 /* Compare two registers */
4418 if (rs != rt) {
6c5c1e20
TS
4419 gen_load_gpr(t0, rs);
4420 gen_load_gpr(t1, rt);
2fdbad25 4421 bcond_compute = 1;
6af0bf9c 4422 }
7dca4ad0 4423 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4424 break;
4425 case OPC_BGEZ:
4426 case OPC_BGEZAL:
4427 case OPC_BGEZALL:
4428 case OPC_BGEZL:
4429 case OPC_BGTZ:
4430 case OPC_BGTZL:
4431 case OPC_BLEZ:
4432 case OPC_BLEZL:
4433 case OPC_BLTZ:
4434 case OPC_BLTZAL:
4435 case OPC_BLTZALL:
4436 case OPC_BLTZL:
4437 /* Compare to zero */
4438 if (rs != 0) {
6c5c1e20 4439 gen_load_gpr(t0, rs);
2fdbad25 4440 bcond_compute = 1;
6af0bf9c 4441 }
7dca4ad0 4442 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4443 break;
e45a93e2
JL
4444 case OPC_BPOSGE32:
4445#if defined(TARGET_MIPS64)
4446 case OPC_BPOSGE64:
4447 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4448#else
4449 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4450#endif
4451 bcond_compute = 1;
4452 btgt = ctx->pc + insn_bytes + offset;
4453 break;
6af0bf9c
FB
4454 case OPC_J:
4455 case OPC_JAL:
364d4831 4456 case OPC_JALX:
6af0bf9c 4457 /* Jump to immediate */
7dca4ad0 4458 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4459 break;
4460 case OPC_JR:
4461 case OPC_JALR:
4462 /* Jump to register */
7a387fff
TS
4463 if (offset != 0 && offset != 16) {
4464 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4465 others are reserved. */
923617a3 4466 MIPS_INVAL("jump hint");
6af0bf9c 4467 generate_exception(ctx, EXCP_RI);
6c5c1e20 4468 goto out;
6af0bf9c 4469 }
d077b6f7 4470 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4471 break;
4472 default:
4473 MIPS_INVAL("branch/jump");
4474 generate_exception(ctx, EXCP_RI);
6c5c1e20 4475 goto out;
6af0bf9c 4476 }
2fdbad25 4477 if (bcond_compute == 0) {
6af0bf9c
FB
4478 /* No condition to be computed */
4479 switch (opc) {
4480 case OPC_BEQ: /* rx == rx */
4481 case OPC_BEQL: /* rx == rx likely */
4482 case OPC_BGEZ: /* 0 >= 0 */
4483 case OPC_BGEZL: /* 0 >= 0 likely */
4484 case OPC_BLEZ: /* 0 <= 0 */
4485 case OPC_BLEZL: /* 0 <= 0 likely */
4486 /* Always take */
4ad40f36 4487 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4488 MIPS_DEBUG("balways");
4489 break;
4490 case OPC_BGEZAL: /* 0 >= 0 */
4491 case OPC_BGEZALL: /* 0 >= 0 likely */
4492 /* Always take and link */
4493 blink = 31;
4ad40f36 4494 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4495 MIPS_DEBUG("balways and link");
4496 break;
4497 case OPC_BNE: /* rx != rx */
4498 case OPC_BGTZ: /* 0 > 0 */
4499 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4500 /* Treat as NOP. */
6af0bf9c 4501 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4502 goto out;
eeef26cd 4503 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4504 /* Handle as an unconditional branch to get correct delay
4505 slot checking. */
4506 blink = 31;
b231c103 4507 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4508 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4509 MIPS_DEBUG("bnever and link");
3c824109 4510 break;
eeef26cd 4511 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4512 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4513 /* Skip the instruction in the delay slot */
4514 MIPS_DEBUG("bnever, link and skip");
4515 ctx->pc += 4;
6c5c1e20 4516 goto out;
6af0bf9c
FB
4517 case OPC_BNEL: /* rx != rx likely */
4518 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4519 case OPC_BLTZL: /* 0 < 0 likely */
4520 /* Skip the instruction in the delay slot */
4521 MIPS_DEBUG("bnever and skip");
9898128f 4522 ctx->pc += 4;
6c5c1e20 4523 goto out;
6af0bf9c 4524 case OPC_J:
4ad40f36 4525 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4526 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4527 break;
364d4831
NF
4528 case OPC_JALX:
4529 ctx->hflags |= MIPS_HFLAG_BX;
4530 /* Fallthrough */
6af0bf9c
FB
4531 case OPC_JAL:
4532 blink = 31;
4ad40f36 4533 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4534 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4535 break;
4536 case OPC_JR:
4ad40f36 4537 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4538 MIPS_DEBUG("jr %s", regnames[rs]);
4539 break;
4540 case OPC_JALR:
4541 blink = rt;
4ad40f36 4542 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4543 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4544 break;
4545 default:
4546 MIPS_INVAL("branch/jump");
4547 generate_exception(ctx, EXCP_RI);
6c5c1e20 4548 goto out;
6af0bf9c
FB
4549 }
4550 } else {
4551 switch (opc) {
4552 case OPC_BEQ:
e68dd28f 4553 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4554 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4555 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4556 goto not_likely;
4557 case OPC_BEQL:
e68dd28f 4558 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4559 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4560 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4561 goto likely;
4562 case OPC_BNE:
e68dd28f 4563 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4564 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4565 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4566 goto not_likely;
4567 case OPC_BNEL:
e68dd28f 4568 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4569 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4570 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4571 goto likely;
4572 case OPC_BGEZ:
e68dd28f 4573 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4574 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4575 goto not_likely;
4576 case OPC_BGEZL:
e68dd28f 4577 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4578 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4579 goto likely;
4580 case OPC_BGEZAL:
e68dd28f 4581 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4582 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4583 blink = 31;
4584 goto not_likely;
4585 case OPC_BGEZALL:
e68dd28f 4586 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4587 blink = 31;
d077b6f7 4588 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4589 goto likely;
4590 case OPC_BGTZ:
e68dd28f 4591 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4592 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4593 goto not_likely;
4594 case OPC_BGTZL:
e68dd28f 4595 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4596 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4597 goto likely;
4598 case OPC_BLEZ:
e68dd28f 4599 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4600 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4601 goto not_likely;
4602 case OPC_BLEZL:
e68dd28f 4603 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4604 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4605 goto likely;
4606 case OPC_BLTZ:
e68dd28f 4607 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4608 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4609 goto not_likely;
4610 case OPC_BLTZL:
e68dd28f 4611 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4612 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4613 goto likely;
e45a93e2
JL
4614 case OPC_BPOSGE32:
4615 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4616 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4617 goto not_likely;
4618#if defined(TARGET_MIPS64)
4619 case OPC_BPOSGE64:
4620 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4621 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4622 goto not_likely;
4623#endif
6af0bf9c 4624 case OPC_BLTZAL:
e68dd28f 4625 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4626 blink = 31;
d077b6f7 4627 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4628 not_likely:
4ad40f36 4629 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4630 break;
4631 case OPC_BLTZALL:
e68dd28f 4632 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4633 blink = 31;
d077b6f7 4634 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4635 likely:
4ad40f36 4636 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4637 break;
c53f4a62
TS
4638 default:
4639 MIPS_INVAL("conditional branch/jump");
4640 generate_exception(ctx, EXCP_RI);
6c5c1e20 4641 goto out;
6af0bf9c 4642 }
6af0bf9c 4643 }
923617a3 4644 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4645 blink, ctx->hflags, btgt);
9b9e4393 4646
d077b6f7 4647 ctx->btarget = btgt;
b231c103
YK
4648
4649 switch (delayslot_size) {
4650 case 2:
4651 ctx->hflags |= MIPS_HFLAG_BDS16;
4652 break;
4653 case 4:
4654 ctx->hflags |= MIPS_HFLAG_BDS32;
4655 break;
4656 }
4657
6af0bf9c 4658 if (blink > 0) {
b231c103 4659 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4660 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4661
364d4831 4662 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4663 }
6c5c1e20
TS
4664
4665 out:
364d4831
NF
4666 if (insn_bytes == 2)
4667 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4668 tcg_temp_free(t0);
4669 tcg_temp_free(t1);
6af0bf9c
FB
4670}
4671
7a387fff
TS
4672/* special3 bitfield operations */
4673static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4674 int rs, int lsb, int msb)
7a387fff 4675{
a7812ae4
PB
4676 TCGv t0 = tcg_temp_new();
4677 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4678
4679 gen_load_gpr(t1, rs);
7a387fff
TS
4680 switch (opc) {
4681 case OPC_EXT:
4682 if (lsb + msb > 31)
4683 goto fail;
505ad7c2
AJ
4684 tcg_gen_shri_tl(t0, t1, lsb);
4685 if (msb != 31) {
4686 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4687 } else {
4688 tcg_gen_ext32s_tl(t0, t0);
4689 }
7a387fff 4690 break;
c6d6dd7c 4691#if defined(TARGET_MIPS64)
7a387fff 4692 case OPC_DEXTM:
505ad7c2
AJ
4693 tcg_gen_shri_tl(t0, t1, lsb);
4694 if (msb != 31) {
4695 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4696 }
7a387fff
TS
4697 break;
4698 case OPC_DEXTU:
505ad7c2
AJ
4699 tcg_gen_shri_tl(t0, t1, lsb + 32);
4700 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4701 break;
4702 case OPC_DEXT:
505ad7c2
AJ
4703 tcg_gen_shri_tl(t0, t1, lsb);
4704 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4705 break;
c6d6dd7c 4706#endif
7a387fff
TS
4707 case OPC_INS:
4708 if (lsb > msb)
4709 goto fail;
6c5c1e20 4710 gen_load_gpr(t0, rt);
e0d002f1 4711 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4712 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4713 break;
c6d6dd7c 4714#if defined(TARGET_MIPS64)
7a387fff 4715 case OPC_DINSM:
6c5c1e20 4716 gen_load_gpr(t0, rt);
e0d002f1 4717 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4718 break;
4719 case OPC_DINSU:
6c5c1e20 4720 gen_load_gpr(t0, rt);
e0d002f1 4721 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4722 break;
4723 case OPC_DINS:
6c5c1e20 4724 gen_load_gpr(t0, rt);
e0d002f1 4725 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4726 break;
c6d6dd7c 4727#endif
7a387fff
TS
4728 default:
4729fail:
4730 MIPS_INVAL("bitops");
4731 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4732 tcg_temp_free(t0);
4733 tcg_temp_free(t1);
7a387fff
TS
4734 return;
4735 }
6c5c1e20
TS
4736 gen_store_gpr(t0, rt);
4737 tcg_temp_free(t0);
4738 tcg_temp_free(t1);
7a387fff
TS
4739}
4740
49bcf33c
AJ
4741static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4742{
3a55fa47 4743 TCGv t0;
49bcf33c 4744
3a55fa47
AJ
4745 if (rd == 0) {
4746 /* If no destination, treat it as a NOP. */
4747 MIPS_DEBUG("NOP");
4748 return;
4749 }
4750
4751 t0 = tcg_temp_new();
4752 gen_load_gpr(t0, rt);
49bcf33c
AJ
4753 switch (op2) {
4754 case OPC_WSBH:
3a55fa47
AJ
4755 {
4756 TCGv t1 = tcg_temp_new();
4757
4758 tcg_gen_shri_tl(t1, t0, 8);
4759 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4760 tcg_gen_shli_tl(t0, t0, 8);
4761 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4762 tcg_gen_or_tl(t0, t0, t1);
4763 tcg_temp_free(t1);
4764 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4765 }
49bcf33c
AJ
4766 break;
4767 case OPC_SEB:
3a55fa47 4768 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4769 break;
4770 case OPC_SEH:
3a55fa47 4771 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4772 break;
4773#if defined(TARGET_MIPS64)
4774 case OPC_DSBH:
3a55fa47
AJ
4775 {
4776 TCGv t1 = tcg_temp_new();
4777
4778 tcg_gen_shri_tl(t1, t0, 8);
4779 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4780 tcg_gen_shli_tl(t0, t0, 8);
4781 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4782 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4783 tcg_temp_free(t1);
4784 }
49bcf33c
AJ
4785 break;
4786 case OPC_DSHD:
3a55fa47
AJ
4787 {
4788 TCGv t1 = tcg_temp_new();
4789
4790 tcg_gen_shri_tl(t1, t0, 16);
4791 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4792 tcg_gen_shli_tl(t0, t0, 16);
4793 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4794 tcg_gen_or_tl(t0, t0, t1);
4795 tcg_gen_shri_tl(t1, t0, 32);
4796 tcg_gen_shli_tl(t0, t0, 32);
4797 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4798 tcg_temp_free(t1);
4799 }
49bcf33c
AJ
4800 break;
4801#endif
4802 default:
4803 MIPS_INVAL("bsfhl");
4804 generate_exception(ctx, EXCP_RI);
4805 tcg_temp_free(t0);
49bcf33c
AJ
4806 return;
4807 }
49bcf33c 4808 tcg_temp_free(t0);
49bcf33c
AJ
4809}
4810
f1aa6320 4811#ifndef CONFIG_USER_ONLY
0eaef5aa 4812/* CP0 (MMU and control) */
d9bea114 4813static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4814{
d9bea114 4815 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4816
d9bea114
AJ
4817 tcg_gen_ld_i32(t0, cpu_env, off);
4818 tcg_gen_ext_i32_tl(arg, t0);
4819 tcg_temp_free_i32(t0);
4f57689a
TS
4820}
4821
d9bea114 4822static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4823{
d9bea114
AJ
4824 tcg_gen_ld_tl(arg, cpu_env, off);
4825 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4826}
4827
d9bea114 4828static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4829{
d9bea114 4830 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4831
d9bea114
AJ
4832 tcg_gen_trunc_tl_i32(t0, arg);
4833 tcg_gen_st_i32(t0, cpu_env, off);
4834 tcg_temp_free_i32(t0);
f1aa6320
TS
4835}
4836
d9bea114 4837static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4838{
d9bea114
AJ
4839 tcg_gen_ext32s_tl(arg, arg);
4840 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4841}
4842
e98c0d17
LA
4843static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4844{
4845 if (ctx->insn_flags & ISA_MIPS32R6) {
4846 tcg_gen_movi_tl(arg, 0);
4847 } else {
4848 tcg_gen_movi_tl(arg, ~0);
4849 }
4850}
4851
f31b035a
LA
4852#define CP0_CHECK(c) \
4853 do { \
4854 if (!(c)) { \
4855 goto cp0_unimplemented; \
4856 } \
4857 } while (0)
4858
d75c135e 4859static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4860{
7a387fff 4861 const char *rn = "invalid";
873eb012 4862
e189e748 4863 if (sel != 0)
d75c135e 4864 check_insn(ctx, ISA_MIPS32);
e189e748 4865
873eb012
TS
4866 switch (reg) {
4867 case 0:
7a387fff
TS
4868 switch (sel) {
4869 case 0:
7db13fae 4870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4871 rn = "Index";
4872 break;
4873 case 1:
f31b035a 4874 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4875 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4876 rn = "MVPControl";
ead9360e 4877 break;
7a387fff 4878 case 2:
f31b035a 4879 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4880 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4881 rn = "MVPConf0";
ead9360e 4882 break;
7a387fff 4883 case 3:
f31b035a 4884 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4885 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4886 rn = "MVPConf1";
ead9360e 4887 break;
7a387fff 4888 default:
f31b035a 4889 goto cp0_unimplemented;
7a387fff 4890 }
873eb012
TS
4891 break;
4892 case 1:
7a387fff
TS
4893 switch (sel) {
4894 case 0:
f31b035a 4895 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4896 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4897 rn = "Random";
2423f660 4898 break;
7a387fff 4899 case 1:
f31b035a 4900 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4902 rn = "VPEControl";
ead9360e 4903 break;
7a387fff 4904 case 2:
f31b035a 4905 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4907 rn = "VPEConf0";
ead9360e 4908 break;
7a387fff 4909 case 3:
f31b035a 4910 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4912 rn = "VPEConf1";
ead9360e 4913 break;
7a387fff 4914 case 4:
f31b035a 4915 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4916 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4917 rn = "YQMask";
ead9360e 4918 break;
7a387fff 4919 case 5:
f31b035a 4920 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4921 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4922 rn = "VPESchedule";
ead9360e 4923 break;
7a387fff 4924 case 6:
f31b035a 4925 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4926 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4927 rn = "VPEScheFBack";
ead9360e 4928 break;
7a387fff 4929 case 7:
f31b035a 4930 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4932 rn = "VPEOpt";
ead9360e 4933 break;
7a387fff 4934 default:
f31b035a 4935 goto cp0_unimplemented;
7a387fff 4936 }
873eb012
TS
4937 break;
4938 case 2:
7a387fff
TS
4939 switch (sel) {
4940 case 0:
7db13fae 4941 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4942#if defined(TARGET_MIPS64)
4943 if (ctx->rxi) {
4944 TCGv tmp = tcg_temp_new();
4945 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
4946 tcg_gen_shri_tl(tmp, tmp, 32);
4947 tcg_gen_or_tl(arg, arg, tmp);
4948 tcg_temp_free(tmp);
4949 }
4950#endif
d9bea114 4951 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4952 rn = "EntryLo0";
4953 break;
7a387fff 4954 case 1:
f31b035a 4955 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4956 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4957 rn = "TCStatus";
ead9360e 4958 break;
7a387fff 4959 case 2:
f31b035a 4960 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4961 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4962 rn = "TCBind";
ead9360e 4963 break;
7a387fff 4964 case 3:
f31b035a 4965 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4966 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4967 rn = "TCRestart";
ead9360e 4968 break;
7a387fff 4969 case 4:
f31b035a 4970 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4971 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4972 rn = "TCHalt";
ead9360e 4973 break;
7a387fff 4974 case 5:
f31b035a 4975 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4976 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4977 rn = "TCContext";
ead9360e 4978 break;
7a387fff 4979 case 6:
f31b035a 4980 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4981 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4982 rn = "TCSchedule";
ead9360e 4983 break;
7a387fff 4984 case 7:
f31b035a 4985 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4986 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4987 rn = "TCScheFBack";
ead9360e 4988 break;
7a387fff 4989 default:
f31b035a 4990 goto cp0_unimplemented;
7a387fff 4991 }
873eb012
TS
4992 break;
4993 case 3:
7a387fff
TS
4994 switch (sel) {
4995 case 0:
7db13fae 4996 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
4997#if defined(TARGET_MIPS64)
4998 if (ctx->rxi) {
4999 TCGv tmp = tcg_temp_new();
5000 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
5001 tcg_gen_shri_tl(tmp, tmp, 32);
5002 tcg_gen_or_tl(arg, arg, tmp);
5003 tcg_temp_free(tmp);
5004 }
5005#endif
d9bea114 5006 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5007 rn = "EntryLo1";
5008 break;
7a387fff 5009 default:
f31b035a 5010 goto cp0_unimplemented;
1579a72e 5011 }
873eb012
TS
5012 break;
5013 case 4:
7a387fff
TS
5014 switch (sel) {
5015 case 0:
7db13fae 5016 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5017 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5018 rn = "Context";
5019 break;
7a387fff 5020 case 1:
d9bea114 5021// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5022 rn = "ContextConfig";
f31b035a 5023 goto cp0_unimplemented;
2423f660 5024// break;
d279279e 5025 case 2:
f31b035a
LA
5026 CP0_CHECK(ctx->ulri);
5027 tcg_gen_ld32s_tl(arg, cpu_env,
5028 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5029 rn = "UserLocal";
d279279e 5030 break;
7a387fff 5031 default:
f31b035a 5032 goto cp0_unimplemented;
1579a72e 5033 }
873eb012
TS
5034 break;
5035 case 5:
7a387fff
TS
5036 switch (sel) {
5037 case 0:
7db13fae 5038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5039 rn = "PageMask";
5040 break;
7a387fff 5041 case 1:
d75c135e 5042 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5044 rn = "PageGrain";
5045 break;
7a387fff 5046 default:
f31b035a 5047 goto cp0_unimplemented;
1579a72e 5048 }
873eb012
TS
5049 break;
5050 case 6:
7a387fff
TS
5051 switch (sel) {
5052 case 0:
7db13fae 5053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5054 rn = "Wired";
5055 break;
7a387fff 5056 case 1:
d75c135e 5057 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5059 rn = "SRSConf0";
ead9360e 5060 break;
7a387fff 5061 case 2:
d75c135e 5062 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5064 rn = "SRSConf1";
ead9360e 5065 break;
7a387fff 5066 case 3:
d75c135e 5067 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5069 rn = "SRSConf2";
ead9360e 5070 break;
7a387fff 5071 case 4:
d75c135e 5072 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5074 rn = "SRSConf3";
ead9360e 5075 break;
7a387fff 5076 case 5:
d75c135e 5077 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5078 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5079 rn = "SRSConf4";
ead9360e 5080 break;
7a387fff 5081 default:
f31b035a 5082 goto cp0_unimplemented;
1579a72e 5083 }
873eb012 5084 break;
8c0fdd85 5085 case 7:
7a387fff
TS
5086 switch (sel) {
5087 case 0:
d75c135e 5088 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5090 rn = "HWREna";
5091 break;
7a387fff 5092 default:
f31b035a 5093 goto cp0_unimplemented;
1579a72e 5094 }
8c0fdd85 5095 break;
873eb012 5096 case 8:
7a387fff
TS
5097 switch (sel) {
5098 case 0:
7db13fae 5099 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5100 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5101 rn = "BadVAddr";
2423f660 5102 break;
aea14095 5103 case 1:
f31b035a
LA
5104 CP0_CHECK(ctx->bi);
5105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5106 rn = "BadInstr";
aea14095
LA
5107 break;
5108 case 2:
f31b035a
LA
5109 CP0_CHECK(ctx->bp);
5110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5111 rn = "BadInstrP";
aea14095 5112 break;
7a387fff 5113 default:
f31b035a 5114 goto cp0_unimplemented;
aea14095 5115 }
873eb012
TS
5116 break;
5117 case 9:
7a387fff
TS
5118 switch (sel) {
5119 case 0:
2e70f6ef
PB
5120 /* Mark as an IO operation because we read the time. */
5121 if (use_icount)
5122 gen_io_start();
895c2d04 5123 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5124 if (use_icount) {
5125 gen_io_end();
2e70f6ef 5126 }
55807224
EI
5127 /* Break the TB to be able to take timer interrupts immediately
5128 after reading count. */
5129 ctx->bstate = BS_STOP;
2423f660
TS
5130 rn = "Count";
5131 break;
5132 /* 6,7 are implementation dependent */
7a387fff 5133 default:
f31b035a 5134 goto cp0_unimplemented;
2423f660 5135 }
873eb012
TS
5136 break;
5137 case 10:
7a387fff
TS
5138 switch (sel) {
5139 case 0:
7db13fae 5140 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5141 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5142 rn = "EntryHi";
5143 break;
7a387fff 5144 default:
f31b035a 5145 goto cp0_unimplemented;
1579a72e 5146 }
873eb012
TS
5147 break;
5148 case 11:
7a387fff
TS
5149 switch (sel) {
5150 case 0:
7db13fae 5151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5152 rn = "Compare";
5153 break;
5154 /* 6,7 are implementation dependent */
7a387fff 5155 default:
f31b035a 5156 goto cp0_unimplemented;
2423f660 5157 }
873eb012
TS
5158 break;
5159 case 12:
7a387fff
TS
5160 switch (sel) {
5161 case 0:
7db13fae 5162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5163 rn = "Status";
5164 break;
7a387fff 5165 case 1:
d75c135e 5166 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5168 rn = "IntCtl";
5169 break;
7a387fff 5170 case 2:
d75c135e 5171 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5173 rn = "SRSCtl";
5174 break;
7a387fff 5175 case 3:
d75c135e 5176 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5178 rn = "SRSMap";
fd88b6ab 5179 break;
7a387fff 5180 default:
f31b035a 5181 goto cp0_unimplemented;
7a387fff 5182 }
873eb012
TS
5183 break;
5184 case 13:
7a387fff
TS
5185 switch (sel) {
5186 case 0:
7db13fae 5187 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5188 rn = "Cause";
5189 break;
7a387fff 5190 default:
f31b035a 5191 goto cp0_unimplemented;
7a387fff 5192 }
873eb012
TS
5193 break;
5194 case 14:
7a387fff
TS
5195 switch (sel) {
5196 case 0:
7db13fae 5197 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5198 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5199 rn = "EPC";
5200 break;
7a387fff 5201 default:
f31b035a 5202 goto cp0_unimplemented;
1579a72e 5203 }
873eb012
TS
5204 break;
5205 case 15:
7a387fff
TS
5206 switch (sel) {
5207 case 0:
7db13fae 5208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5209 rn = "PRid";
5210 break;
7a387fff 5211 case 1:
d75c135e 5212 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5213 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5214 rn = "EBase";
5215 break;
7a387fff 5216 default:
f31b035a 5217 goto cp0_unimplemented;
7a387fff 5218 }
873eb012
TS
5219 break;
5220 case 16:
5221 switch (sel) {
5222 case 0:
7db13fae 5223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5224 rn = "Config";
5225 break;
5226 case 1:
7db13fae 5227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5228 rn = "Config1";
5229 break;
7a387fff 5230 case 2:
7db13fae 5231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5232 rn = "Config2";
5233 break;
5234 case 3:
7db13fae 5235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5236 rn = "Config3";
5237 break;
b4160af1
PJ
5238 case 4:
5239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5240 rn = "Config4";
5241 break;
b4dd99a3
PJ
5242 case 5:
5243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5244 rn = "Config5";
5245 break;
e397ee33
TS
5246 /* 6,7 are implementation dependent */
5247 case 6:
7db13fae 5248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5249 rn = "Config6";
5250 break;
5251 case 7:
7db13fae 5252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5253 rn = "Config7";
5254 break;
873eb012 5255 default:
f31b035a 5256 goto cp0_unimplemented;
873eb012
TS
5257 }
5258 break;
5259 case 17:
7a387fff
TS
5260 switch (sel) {
5261 case 0:
895c2d04 5262 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5263 rn = "LLAddr";
5264 break;
7a387fff 5265 default:
f31b035a 5266 goto cp0_unimplemented;
7a387fff 5267 }
873eb012
TS
5268 break;
5269 case 18:
7a387fff 5270 switch (sel) {
fd88b6ab 5271 case 0 ... 7:
895c2d04 5272 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5273 rn = "WatchLo";
5274 break;
7a387fff 5275 default:
f31b035a 5276 goto cp0_unimplemented;
7a387fff 5277 }
873eb012
TS
5278 break;
5279 case 19:
7a387fff 5280 switch (sel) {
fd88b6ab 5281 case 0 ...7:
895c2d04 5282 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5283 rn = "WatchHi";
5284 break;
7a387fff 5285 default:
f31b035a 5286 goto cp0_unimplemented;
7a387fff 5287 }
873eb012 5288 break;
8c0fdd85 5289 case 20:
7a387fff
TS
5290 switch (sel) {
5291 case 0:
d26bc211 5292#if defined(TARGET_MIPS64)
d75c135e 5293 check_insn(ctx, ISA_MIPS3);
7db13fae 5294 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5295 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5296 rn = "XContext";
5297 break;
703eaf37 5298#endif
7a387fff 5299 default:
f31b035a 5300 goto cp0_unimplemented;
7a387fff 5301 }
8c0fdd85
TS
5302 break;
5303 case 21:
7a387fff 5304 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5305 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5306 switch (sel) {
5307 case 0:
7db13fae 5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5309 rn = "Framemask";
5310 break;
7a387fff 5311 default:
f31b035a 5312 goto cp0_unimplemented;
7a387fff 5313 }
8c0fdd85
TS
5314 break;
5315 case 22:
d9bea114 5316 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5317 rn = "'Diagnostic"; /* implementation dependent */
5318 break;
873eb012 5319 case 23:
7a387fff
TS
5320 switch (sel) {
5321 case 0:
895c2d04 5322 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5323 rn = "Debug";
5324 break;
7a387fff 5325 case 1:
d9bea114 5326// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5327 rn = "TraceControl";
5328// break;
7a387fff 5329 case 2:
d9bea114 5330// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5331 rn = "TraceControl2";
5332// break;
7a387fff 5333 case 3:
d9bea114 5334// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5335 rn = "UserTraceData";
5336// break;
7a387fff 5337 case 4:
d9bea114 5338// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5339 rn = "TraceBPC";
5340// break;
7a387fff 5341 default:
f31b035a 5342 goto cp0_unimplemented;
7a387fff 5343 }
873eb012
TS
5344 break;
5345 case 24:
7a387fff
TS
5346 switch (sel) {
5347 case 0:
f0b3f3ae 5348 /* EJTAG support */
7db13fae 5349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5350 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5351 rn = "DEPC";
5352 break;
7a387fff 5353 default:
f31b035a 5354 goto cp0_unimplemented;
7a387fff 5355 }
873eb012 5356 break;
8c0fdd85 5357 case 25:
7a387fff
TS
5358 switch (sel) {
5359 case 0:
7db13fae 5360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5361 rn = "Performance0";
7a387fff
TS
5362 break;
5363 case 1:
d9bea114 5364// gen_helper_mfc0_performance1(arg);
2423f660
TS
5365 rn = "Performance1";
5366// break;
7a387fff 5367 case 2:
d9bea114 5368// gen_helper_mfc0_performance2(arg);
2423f660
TS
5369 rn = "Performance2";
5370// break;
7a387fff 5371 case 3:
d9bea114 5372// gen_helper_mfc0_performance3(arg);
2423f660
TS
5373 rn = "Performance3";
5374// break;
7a387fff 5375 case 4:
d9bea114 5376// gen_helper_mfc0_performance4(arg);
2423f660
TS
5377 rn = "Performance4";
5378// break;
7a387fff 5379 case 5:
d9bea114 5380// gen_helper_mfc0_performance5(arg);
2423f660
TS
5381 rn = "Performance5";
5382// break;
7a387fff 5383 case 6:
d9bea114 5384// gen_helper_mfc0_performance6(arg);
2423f660
TS
5385 rn = "Performance6";
5386// break;
7a387fff 5387 case 7:
d9bea114 5388// gen_helper_mfc0_performance7(arg);
2423f660
TS
5389 rn = "Performance7";
5390// break;
7a387fff 5391 default:
f31b035a 5392 goto cp0_unimplemented;
7a387fff 5393 }
8c0fdd85
TS
5394 break;
5395 case 26:
d9bea114 5396 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5397 rn = "ECC";
5398 break;
8c0fdd85 5399 case 27:
7a387fff 5400 switch (sel) {
7a387fff 5401 case 0 ... 3:
d9bea114 5402 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5403 rn = "CacheErr";
5404 break;
7a387fff 5405 default:
f31b035a 5406 goto cp0_unimplemented;
7a387fff 5407 }
8c0fdd85 5408 break;
873eb012
TS
5409 case 28:
5410 switch (sel) {
5411 case 0:
7a387fff
TS
5412 case 2:
5413 case 4:
5414 case 6:
7db13fae 5415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5416 rn = "TagLo";
5417 break;
5418 case 1:
7a387fff
TS
5419 case 3:
5420 case 5:
5421 case 7:
7db13fae 5422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5423 rn = "DataLo";
5424 break;
5425 default:
f31b035a 5426 goto cp0_unimplemented;
873eb012
TS
5427 }
5428 break;
8c0fdd85 5429 case 29:
7a387fff
TS
5430 switch (sel) {
5431 case 0:
5432 case 2:
5433 case 4:
5434 case 6:
7db13fae 5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5436 rn = "TagHi";
5437 break;
5438 case 1:
5439 case 3:
5440 case 5:
5441 case 7:
7db13fae 5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5443 rn = "DataHi";
5444 break;
5445 default:
f31b035a 5446 goto cp0_unimplemented;
7a387fff 5447 }
8c0fdd85 5448 break;
873eb012 5449 case 30:
7a387fff
TS
5450 switch (sel) {
5451 case 0:
7db13fae 5452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5453 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5454 rn = "ErrorEPC";
5455 break;
7a387fff 5456 default:
f31b035a 5457 goto cp0_unimplemented;
7a387fff 5458 }
873eb012
TS
5459 break;
5460 case 31:
7a387fff
TS
5461 switch (sel) {
5462 case 0:
f0b3f3ae 5463 /* EJTAG support */
7db13fae 5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5465 rn = "DESAVE";
5466 break;
e98c0d17 5467 case 2 ... 7:
f31b035a
LA
5468 CP0_CHECK(ctx->kscrexist & (1 << sel));
5469 tcg_gen_ld_tl(arg, cpu_env,
5470 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5471 tcg_gen_ext32s_tl(arg, arg);
5472 rn = "KScratch";
e98c0d17 5473 break;
7a387fff 5474 default:
f31b035a 5475 goto cp0_unimplemented;
7a387fff 5476 }
873eb012
TS
5477 break;
5478 default:
f31b035a 5479 goto cp0_unimplemented;
873eb012 5480 }
2abf314d 5481 (void)rn; /* avoid a compiler warning */
d12d51d5 5482 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5483 return;
5484
f31b035a 5485cp0_unimplemented:
d12d51d5 5486 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5487 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5488}
5489
d75c135e 5490static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5491{
7a387fff
TS
5492 const char *rn = "invalid";
5493
e189e748 5494 if (sel != 0)
d75c135e 5495 check_insn(ctx, ISA_MIPS32);
e189e748 5496
2e70f6ef
PB
5497 if (use_icount)
5498 gen_io_start();
5499
8c0fdd85
TS
5500 switch (reg) {
5501 case 0:
7a387fff
TS
5502 switch (sel) {
5503 case 0:
895c2d04 5504 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5505 rn = "Index";
5506 break;
5507 case 1:
f31b035a 5508 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5509 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5510 rn = "MVPControl";
ead9360e 5511 break;
7a387fff 5512 case 2:
f31b035a 5513 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5514 /* ignored */
7a387fff 5515 rn = "MVPConf0";
ead9360e 5516 break;
7a387fff 5517 case 3:
f31b035a 5518 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5519 /* ignored */
7a387fff 5520 rn = "MVPConf1";
ead9360e 5521 break;
7a387fff 5522 default:
f31b035a 5523 goto cp0_unimplemented;
7a387fff 5524 }
8c0fdd85
TS
5525 break;
5526 case 1:
7a387fff
TS
5527 switch (sel) {
5528 case 0:
2423f660 5529 /* ignored */
7a387fff 5530 rn = "Random";
2423f660 5531 break;
7a387fff 5532 case 1:
f31b035a 5533 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5534 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5535 rn = "VPEControl";
ead9360e 5536 break;
7a387fff 5537 case 2:
f31b035a 5538 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5539 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5540 rn = "VPEConf0";
ead9360e 5541 break;
7a387fff 5542 case 3:
f31b035a 5543 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5544 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5545 rn = "VPEConf1";
ead9360e 5546 break;
7a387fff 5547 case 4:
f31b035a 5548 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5549 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5550 rn = "YQMask";
ead9360e 5551 break;
7a387fff 5552 case 5:
f31b035a 5553 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5554 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5555 rn = "VPESchedule";
ead9360e 5556 break;
7a387fff 5557 case 6:
f31b035a 5558 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5559 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5560 rn = "VPEScheFBack";
ead9360e 5561 break;
7a387fff 5562 case 7:
f31b035a 5563 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5564 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5565 rn = "VPEOpt";
ead9360e 5566 break;
7a387fff 5567 default:
f31b035a 5568 goto cp0_unimplemented;
7a387fff 5569 }
8c0fdd85
TS
5570 break;
5571 case 2:
7a387fff
TS
5572 switch (sel) {
5573 case 0:
895c2d04 5574 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5575 rn = "EntryLo0";
5576 break;
7a387fff 5577 case 1:
f31b035a 5578 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5579 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5580 rn = "TCStatus";
ead9360e 5581 break;
7a387fff 5582 case 2:
f31b035a 5583 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5584 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5585 rn = "TCBind";
ead9360e 5586 break;
7a387fff 5587 case 3:
f31b035a 5588 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5589 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5590 rn = "TCRestart";
ead9360e 5591 break;
7a387fff 5592 case 4:
f31b035a 5593 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5594 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5595 rn = "TCHalt";
ead9360e 5596 break;
7a387fff 5597 case 5:
f31b035a 5598 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5599 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5600 rn = "TCContext";
ead9360e 5601 break;
7a387fff 5602 case 6:
f31b035a 5603 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5604 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5605 rn = "TCSchedule";
ead9360e 5606 break;
7a387fff 5607 case 7:
f31b035a 5608 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5609 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5610 rn = "TCScheFBack";
ead9360e 5611 break;
7a387fff 5612 default:
f31b035a 5613 goto cp0_unimplemented;
7a387fff 5614 }
8c0fdd85
TS
5615 break;
5616 case 3:
7a387fff
TS
5617 switch (sel) {
5618 case 0:
895c2d04 5619 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5620 rn = "EntryLo1";
5621 break;
7a387fff 5622 default:
f31b035a 5623 goto cp0_unimplemented;
876d4b07 5624 }
8c0fdd85
TS
5625 break;
5626 case 4:
7a387fff
TS
5627 switch (sel) {
5628 case 0:
895c2d04 5629 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5630 rn = "Context";
5631 break;
7a387fff 5632 case 1:
895c2d04 5633// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5634 rn = "ContextConfig";
f31b035a 5635 goto cp0_unimplemented;
2423f660 5636// break;
d279279e 5637 case 2:
f31b035a
LA
5638 CP0_CHECK(ctx->ulri);
5639 tcg_gen_st_tl(arg, cpu_env,
5640 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5641 rn = "UserLocal";
d279279e 5642 break;
7a387fff 5643 default:
f31b035a 5644 goto cp0_unimplemented;
876d4b07 5645 }
8c0fdd85
TS
5646 break;
5647 case 5:
7a387fff
TS
5648 switch (sel) {
5649 case 0:
895c2d04 5650 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5651 rn = "PageMask";
5652 break;
7a387fff 5653 case 1:
d75c135e 5654 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5655 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5656 rn = "PageGrain";
5657 break;
7a387fff 5658 default:
f31b035a 5659 goto cp0_unimplemented;
876d4b07 5660 }
8c0fdd85
TS
5661 break;
5662 case 6:
7a387fff
TS
5663 switch (sel) {
5664 case 0:
895c2d04 5665 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5666 rn = "Wired";
5667 break;
7a387fff 5668 case 1:
d75c135e 5669 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5670 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5671 rn = "SRSConf0";
ead9360e 5672 break;
7a387fff 5673 case 2:
d75c135e 5674 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5675 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5676 rn = "SRSConf1";
ead9360e 5677 break;
7a387fff 5678 case 3:
d75c135e 5679 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5680 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5681 rn = "SRSConf2";
ead9360e 5682 break;
7a387fff 5683 case 4:
d75c135e 5684 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5685 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5686 rn = "SRSConf3";
ead9360e 5687 break;
7a387fff 5688 case 5:
d75c135e 5689 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5690 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5691 rn = "SRSConf4";
ead9360e 5692 break;
7a387fff 5693 default:
f31b035a 5694 goto cp0_unimplemented;
876d4b07 5695 }
8c0fdd85
TS
5696 break;
5697 case 7:
7a387fff
TS
5698 switch (sel) {
5699 case 0:
d75c135e 5700 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5701 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5702 ctx->bstate = BS_STOP;
2423f660
TS
5703 rn = "HWREna";
5704 break;
7a387fff 5705 default:
f31b035a 5706 goto cp0_unimplemented;
876d4b07 5707 }
8c0fdd85
TS
5708 break;
5709 case 8:
aea14095
LA
5710 switch (sel) {
5711 case 0:
5712 /* ignored */
5713 rn = "BadVAddr";
5714 break;
5715 case 1:
5716 /* ignored */
5717 rn = "BadInstr";
5718 break;
5719 case 2:
5720 /* ignored */
5721 rn = "BadInstrP";
5722 break;
5723 default:
f31b035a 5724 goto cp0_unimplemented;
aea14095 5725 }
8c0fdd85
TS
5726 break;
5727 case 9:
7a387fff
TS
5728 switch (sel) {
5729 case 0:
895c2d04 5730 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5731 rn = "Count";
5732 break;
876d4b07 5733 /* 6,7 are implementation dependent */
7a387fff 5734 default:
f31b035a 5735 goto cp0_unimplemented;
876d4b07 5736 }
8c0fdd85
TS
5737 break;
5738 case 10:
7a387fff
TS
5739 switch (sel) {
5740 case 0:
895c2d04 5741 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5742 rn = "EntryHi";
5743 break;
7a387fff 5744 default:
f31b035a 5745 goto cp0_unimplemented;
876d4b07 5746 }
8c0fdd85
TS
5747 break;
5748 case 11:
7a387fff
TS
5749 switch (sel) {
5750 case 0:
895c2d04 5751 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5752 rn = "Compare";
5753 break;
5754 /* 6,7 are implementation dependent */
7a387fff 5755 default:
f31b035a 5756 goto cp0_unimplemented;
876d4b07 5757 }
8c0fdd85
TS
5758 break;
5759 case 12:
7a387fff
TS
5760 switch (sel) {
5761 case 0:
867abc7e 5762 save_cpu_state(ctx, 1);
895c2d04 5763 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5764 /* BS_STOP isn't good enough here, hflags may have changed. */
5765 gen_save_pc(ctx->pc + 4);
5766 ctx->bstate = BS_EXCP;
2423f660
TS
5767 rn = "Status";
5768 break;
7a387fff 5769 case 1:
d75c135e 5770 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5771 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5772 /* Stop translation as we may have switched the execution mode */
5773 ctx->bstate = BS_STOP;
2423f660
TS
5774 rn = "IntCtl";
5775 break;
7a387fff 5776 case 2:
d75c135e 5777 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5778 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5779 /* Stop translation as we may have switched the execution mode */
5780 ctx->bstate = BS_STOP;
2423f660
TS
5781 rn = "SRSCtl";
5782 break;
7a387fff 5783 case 3:
d75c135e 5784 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5785 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5786 /* Stop translation as we may have switched the execution mode */
5787 ctx->bstate = BS_STOP;
2423f660 5788 rn = "SRSMap";
fd88b6ab 5789 break;
7a387fff 5790 default:
f31b035a 5791 goto cp0_unimplemented;
876d4b07 5792 }
8c0fdd85
TS
5793 break;
5794 case 13:
7a387fff
TS
5795 switch (sel) {
5796 case 0:
867abc7e 5797 save_cpu_state(ctx, 1);
895c2d04 5798 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5799 rn = "Cause";
5800 break;
7a387fff 5801 default:
f31b035a 5802 goto cp0_unimplemented;
876d4b07 5803 }
8c0fdd85
TS
5804 break;
5805 case 14:
7a387fff
TS
5806 switch (sel) {
5807 case 0:
7db13fae 5808 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5809 rn = "EPC";
5810 break;
7a387fff 5811 default:
f31b035a 5812 goto cp0_unimplemented;
876d4b07 5813 }
8c0fdd85
TS
5814 break;
5815 case 15:
7a387fff
TS
5816 switch (sel) {
5817 case 0:
2423f660
TS
5818 /* ignored */
5819 rn = "PRid";
5820 break;
7a387fff 5821 case 1:
d75c135e 5822 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5823 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5824 rn = "EBase";
5825 break;
7a387fff 5826 default:
f31b035a 5827 goto cp0_unimplemented;
1579a72e 5828 }
8c0fdd85
TS
5829 break;
5830 case 16:
5831 switch (sel) {
5832 case 0:
895c2d04 5833 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5834 rn = "Config";
2423f660
TS
5835 /* Stop translation as we may have switched the execution mode */
5836 ctx->bstate = BS_STOP;
7a387fff
TS
5837 break;
5838 case 1:
e397ee33 5839 /* ignored, read only */
7a387fff
TS
5840 rn = "Config1";
5841 break;
5842 case 2:
895c2d04 5843 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5844 rn = "Config2";
2423f660
TS
5845 /* Stop translation as we may have switched the execution mode */
5846 ctx->bstate = BS_STOP;
8c0fdd85 5847 break;
7a387fff 5848 case 3:
e397ee33 5849 /* ignored, read only */
7a387fff
TS
5850 rn = "Config3";
5851 break;
b4160af1
PJ
5852 case 4:
5853 gen_helper_mtc0_config4(cpu_env, arg);
5854 rn = "Config4";
5855 ctx->bstate = BS_STOP;
5856 break;
b4dd99a3
PJ
5857 case 5:
5858 gen_helper_mtc0_config5(cpu_env, arg);
5859 rn = "Config5";
5860 /* Stop translation as we may have switched the execution mode */
5861 ctx->bstate = BS_STOP;
5862 break;
e397ee33
TS
5863 /* 6,7 are implementation dependent */
5864 case 6:
5865 /* ignored */
5866 rn = "Config6";
5867 break;
5868 case 7:
5869 /* ignored */
5870 rn = "Config7";
5871 break;
8c0fdd85
TS
5872 default:
5873 rn = "Invalid config selector";
f31b035a 5874 goto cp0_unimplemented;
8c0fdd85
TS
5875 }
5876 break;
5877 case 17:
7a387fff
TS
5878 switch (sel) {
5879 case 0:
895c2d04 5880 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5881 rn = "LLAddr";
5882 break;
7a387fff 5883 default:
f31b035a 5884 goto cp0_unimplemented;
7a387fff 5885 }
8c0fdd85
TS
5886 break;
5887 case 18:
7a387fff 5888 switch (sel) {
fd88b6ab 5889 case 0 ... 7:
895c2d04 5890 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5891 rn = "WatchLo";
5892 break;
7a387fff 5893 default:
f31b035a 5894 goto cp0_unimplemented;
7a387fff 5895 }
8c0fdd85
TS
5896 break;
5897 case 19:
7a387fff 5898 switch (sel) {
fd88b6ab 5899 case 0 ... 7:
895c2d04 5900 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5901 rn = "WatchHi";
5902 break;
7a387fff 5903 default:
f31b035a 5904 goto cp0_unimplemented;
7a387fff 5905 }
8c0fdd85
TS
5906 break;
5907 case 20:
7a387fff
TS
5908 switch (sel) {
5909 case 0:
d26bc211 5910#if defined(TARGET_MIPS64)
d75c135e 5911 check_insn(ctx, ISA_MIPS3);
895c2d04 5912 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5913 rn = "XContext";
5914 break;
703eaf37 5915#endif
7a387fff 5916 default:
f31b035a 5917 goto cp0_unimplemented;
7a387fff 5918 }
8c0fdd85
TS
5919 break;
5920 case 21:
7a387fff 5921 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5922 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5923 switch (sel) {
5924 case 0:
895c2d04 5925 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5926 rn = "Framemask";
5927 break;
7a387fff 5928 default:
f31b035a 5929 goto cp0_unimplemented;
7a387fff
TS
5930 }
5931 break;
8c0fdd85 5932 case 22:
7a387fff
TS
5933 /* ignored */
5934 rn = "Diagnostic"; /* implementation dependent */
2423f660 5935 break;
8c0fdd85 5936 case 23:
7a387fff
TS
5937 switch (sel) {
5938 case 0:
895c2d04 5939 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5940 /* BS_STOP isn't good enough here, hflags may have changed. */
5941 gen_save_pc(ctx->pc + 4);
5942 ctx->bstate = BS_EXCP;
2423f660
TS
5943 rn = "Debug";
5944 break;
7a387fff 5945 case 1:
895c2d04 5946// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5947 rn = "TraceControl";
8487327a
TS
5948 /* Stop translation as we may have switched the execution mode */
5949 ctx->bstate = BS_STOP;
2423f660 5950// break;
7a387fff 5951 case 2:
895c2d04 5952// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5953 rn = "TraceControl2";
8487327a
TS
5954 /* Stop translation as we may have switched the execution mode */
5955 ctx->bstate = BS_STOP;
2423f660 5956// break;
7a387fff 5957 case 3:
8487327a
TS
5958 /* Stop translation as we may have switched the execution mode */
5959 ctx->bstate = BS_STOP;
895c2d04 5960// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5961 rn = "UserTraceData";
8487327a
TS
5962 /* Stop translation as we may have switched the execution mode */
5963 ctx->bstate = BS_STOP;
2423f660 5964// break;
7a387fff 5965 case 4:
895c2d04 5966// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5967 /* Stop translation as we may have switched the execution mode */
5968 ctx->bstate = BS_STOP;
2423f660
TS
5969 rn = "TraceBPC";
5970// break;
7a387fff 5971 default:
f31b035a 5972 goto cp0_unimplemented;
7a387fff 5973 }
8c0fdd85
TS
5974 break;
5975 case 24:
7a387fff
TS
5976 switch (sel) {
5977 case 0:
f1aa6320 5978 /* EJTAG support */
7db13fae 5979 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5980 rn = "DEPC";
5981 break;
7a387fff 5982 default:
f31b035a 5983 goto cp0_unimplemented;
7a387fff 5984 }
8c0fdd85
TS
5985 break;
5986 case 25:
7a387fff
TS
5987 switch (sel) {
5988 case 0:
895c2d04 5989 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5990 rn = "Performance0";
5991 break;
7a387fff 5992 case 1:
d9bea114 5993// gen_helper_mtc0_performance1(arg);
2423f660
TS
5994 rn = "Performance1";
5995// break;
7a387fff 5996 case 2:
d9bea114 5997// gen_helper_mtc0_performance2(arg);
2423f660
TS
5998 rn = "Performance2";
5999// break;
7a387fff 6000 case 3:
d9bea114 6001// gen_helper_mtc0_performance3(arg);
2423f660
TS
6002 rn = "Performance3";
6003// break;
7a387fff 6004 case 4:
d9bea114 6005// gen_helper_mtc0_performance4(arg);
2423f660
TS
6006 rn = "Performance4";
6007// break;
7a387fff 6008 case 5:
d9bea114 6009// gen_helper_mtc0_performance5(arg);
2423f660
TS
6010 rn = "Performance5";
6011// break;
7a387fff 6012 case 6:
d9bea114 6013// gen_helper_mtc0_performance6(arg);
2423f660
TS
6014 rn = "Performance6";
6015// break;
7a387fff 6016 case 7:
d9bea114 6017// gen_helper_mtc0_performance7(arg);
2423f660
TS
6018 rn = "Performance7";
6019// break;
7a387fff 6020 default:
f31b035a 6021 goto cp0_unimplemented;
7a387fff 6022 }
8c0fdd85
TS
6023 break;
6024 case 26:
2423f660 6025 /* ignored */
8c0fdd85 6026 rn = "ECC";
2423f660 6027 break;
8c0fdd85 6028 case 27:
7a387fff
TS
6029 switch (sel) {
6030 case 0 ... 3:
2423f660
TS
6031 /* ignored */
6032 rn = "CacheErr";
6033 break;
7a387fff 6034 default:
f31b035a 6035 goto cp0_unimplemented;
7a387fff 6036 }
8c0fdd85
TS
6037 break;
6038 case 28:
6039 switch (sel) {
6040 case 0:
7a387fff
TS
6041 case 2:
6042 case 4:
6043 case 6:
895c2d04 6044 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6045 rn = "TagLo";
6046 break;
7a387fff
TS
6047 case 1:
6048 case 3:
6049 case 5:
6050 case 7:
895c2d04 6051 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6052 rn = "DataLo";
6053 break;
8c0fdd85 6054 default:
f31b035a 6055 goto cp0_unimplemented;
8c0fdd85
TS
6056 }
6057 break;
6058 case 29:
7a387fff
TS
6059 switch (sel) {
6060 case 0:
6061 case 2:
6062 case 4:
6063 case 6:
895c2d04 6064 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6065 rn = "TagHi";
6066 break;
6067 case 1:
6068 case 3:
6069 case 5:
6070 case 7:
895c2d04 6071 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6072 rn = "DataHi";
6073 break;
6074 default:
6075 rn = "invalid sel";
f31b035a 6076 goto cp0_unimplemented;
7a387fff 6077 }
8c0fdd85
TS
6078 break;
6079 case 30:
7a387fff
TS
6080 switch (sel) {
6081 case 0:
7db13fae 6082 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6083 rn = "ErrorEPC";
6084 break;
7a387fff 6085 default:
f31b035a 6086 goto cp0_unimplemented;
7a387fff 6087 }
8c0fdd85
TS
6088 break;
6089 case 31:
7a387fff
TS
6090 switch (sel) {
6091 case 0:
f1aa6320 6092 /* EJTAG support */
7db13fae 6093 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6094 rn = "DESAVE";
6095 break;
e98c0d17 6096 case 2 ... 7:
f31b035a
LA
6097 CP0_CHECK(ctx->kscrexist & (1 << sel));
6098 tcg_gen_st_tl(arg, cpu_env,
6099 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6100 rn = "KScratch";
e98c0d17 6101 break;
7a387fff 6102 default:
f31b035a 6103 goto cp0_unimplemented;
7a387fff 6104 }
2423f660
TS
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx->bstate = BS_STOP;
8c0fdd85
TS
6107 break;
6108 default:
f31b035a 6109 goto cp0_unimplemented;
8c0fdd85 6110 }
2abf314d 6111 (void)rn; /* avoid a compiler warning */
d12d51d5 6112 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6113 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6114 if (use_icount) {
6115 gen_io_end();
6116 ctx->bstate = BS_STOP;
6117 }
8c0fdd85
TS
6118 return;
6119
f31b035a 6120cp0_unimplemented:
d12d51d5 6121 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6122}
6123
d26bc211 6124#if defined(TARGET_MIPS64)
d75c135e 6125static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6126{
6127 const char *rn = "invalid";
6128
e189e748 6129 if (sel != 0)
d75c135e 6130 check_insn(ctx, ISA_MIPS64);
e189e748 6131
9c2149c8
TS
6132 switch (reg) {
6133 case 0:
6134 switch (sel) {
6135 case 0:
7db13fae 6136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6137 rn = "Index";
6138 break;
6139 case 1:
f31b035a 6140 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6141 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6142 rn = "MVPControl";
ead9360e 6143 break;
9c2149c8 6144 case 2:
f31b035a 6145 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6146 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6147 rn = "MVPConf0";
ead9360e 6148 break;
9c2149c8 6149 case 3:
f31b035a 6150 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6151 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6152 rn = "MVPConf1";
ead9360e 6153 break;
9c2149c8 6154 default:
f31b035a 6155 goto cp0_unimplemented;
9c2149c8
TS
6156 }
6157 break;
6158 case 1:
6159 switch (sel) {
6160 case 0:
f31b035a 6161 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6162 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6163 rn = "Random";
2423f660 6164 break;
9c2149c8 6165 case 1:
f31b035a 6166 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6168 rn = "VPEControl";
ead9360e 6169 break;
9c2149c8 6170 case 2:
f31b035a 6171 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6173 rn = "VPEConf0";
ead9360e 6174 break;
9c2149c8 6175 case 3:
f31b035a 6176 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6178 rn = "VPEConf1";
ead9360e 6179 break;
9c2149c8 6180 case 4:
f31b035a 6181 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6183 rn = "YQMask";
ead9360e 6184 break;
9c2149c8 6185 case 5:
f31b035a 6186 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6187 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6188 rn = "VPESchedule";
ead9360e 6189 break;
9c2149c8 6190 case 6:
f31b035a 6191 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6192 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6193 rn = "VPEScheFBack";
ead9360e 6194 break;
9c2149c8 6195 case 7:
f31b035a 6196 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6197 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6198 rn = "VPEOpt";
ead9360e 6199 break;
9c2149c8 6200 default:
f31b035a 6201 goto cp0_unimplemented;
9c2149c8
TS
6202 }
6203 break;
6204 case 2:
6205 switch (sel) {
6206 case 0:
7db13fae 6207 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6208 rn = "EntryLo0";
6209 break;
9c2149c8 6210 case 1:
f31b035a 6211 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6212 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6213 rn = "TCStatus";
ead9360e 6214 break;
9c2149c8 6215 case 2:
f31b035a 6216 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6217 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6218 rn = "TCBind";
ead9360e 6219 break;
9c2149c8 6220 case 3:
f31b035a 6221 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6222 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6223 rn = "TCRestart";
ead9360e 6224 break;
9c2149c8 6225 case 4:
f31b035a 6226 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6227 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6228 rn = "TCHalt";
ead9360e 6229 break;
9c2149c8 6230 case 5:
f31b035a 6231 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6232 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6233 rn = "TCContext";
ead9360e 6234 break;
9c2149c8 6235 case 6:
f31b035a 6236 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6237 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6238 rn = "TCSchedule";
ead9360e 6239 break;
9c2149c8 6240 case 7:
f31b035a 6241 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6242 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6243 rn = "TCScheFBack";
ead9360e 6244 break;
9c2149c8 6245 default:
f31b035a 6246 goto cp0_unimplemented;
9c2149c8
TS
6247 }
6248 break;
6249 case 3:
6250 switch (sel) {
6251 case 0:
7db13fae 6252 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6253 rn = "EntryLo1";
6254 break;
9c2149c8 6255 default:
f31b035a 6256 goto cp0_unimplemented;
1579a72e 6257 }
9c2149c8
TS
6258 break;
6259 case 4:
6260 switch (sel) {
6261 case 0:
7db13fae 6262 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6263 rn = "Context";
6264 break;
9c2149c8 6265 case 1:
d9bea114 6266// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6267 rn = "ContextConfig";
f31b035a 6268 goto cp0_unimplemented;
2423f660 6269// break;
d279279e 6270 case 2:
f31b035a
LA
6271 CP0_CHECK(ctx->ulri);
6272 tcg_gen_ld_tl(arg, cpu_env,
6273 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6274 rn = "UserLocal";
d279279e 6275 break;
9c2149c8 6276 default:
f31b035a 6277 goto cp0_unimplemented;
876d4b07 6278 }
9c2149c8
TS
6279 break;
6280 case 5:
6281 switch (sel) {
6282 case 0:
7db13fae 6283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6284 rn = "PageMask";
6285 break;
9c2149c8 6286 case 1:
d75c135e 6287 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6289 rn = "PageGrain";
6290 break;
9c2149c8 6291 default:
f31b035a 6292 goto cp0_unimplemented;
876d4b07 6293 }
9c2149c8
TS
6294 break;
6295 case 6:
6296 switch (sel) {
6297 case 0:
7db13fae 6298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6299 rn = "Wired";
6300 break;
9c2149c8 6301 case 1:
d75c135e 6302 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6304 rn = "SRSConf0";
ead9360e 6305 break;
9c2149c8 6306 case 2:
d75c135e 6307 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6309 rn = "SRSConf1";
ead9360e 6310 break;
9c2149c8 6311 case 3:
d75c135e 6312 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6314 rn = "SRSConf2";
ead9360e 6315 break;
9c2149c8 6316 case 4:
d75c135e 6317 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6319 rn = "SRSConf3";
ead9360e 6320 break;
9c2149c8 6321 case 5:
d75c135e 6322 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6324 rn = "SRSConf4";
ead9360e 6325 break;
9c2149c8 6326 default:
f31b035a 6327 goto cp0_unimplemented;
876d4b07 6328 }
9c2149c8
TS
6329 break;
6330 case 7:
6331 switch (sel) {
6332 case 0:
d75c135e 6333 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6335 rn = "HWREna";
6336 break;
9c2149c8 6337 default:
f31b035a 6338 goto cp0_unimplemented;
876d4b07 6339 }
9c2149c8
TS
6340 break;
6341 case 8:
6342 switch (sel) {
6343 case 0:
7db13fae 6344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6345 rn = "BadVAddr";
2423f660 6346 break;
aea14095 6347 case 1:
f31b035a
LA
6348 CP0_CHECK(ctx->bi);
6349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6350 rn = "BadInstr";
aea14095
LA
6351 break;
6352 case 2:
f31b035a
LA
6353 CP0_CHECK(ctx->bp);
6354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6355 rn = "BadInstrP";
aea14095 6356 break;
9c2149c8 6357 default:
f31b035a 6358 goto cp0_unimplemented;
876d4b07 6359 }
9c2149c8
TS
6360 break;
6361 case 9:
6362 switch (sel) {
6363 case 0:
2e70f6ef
PB
6364 /* Mark as an IO operation because we read the time. */
6365 if (use_icount)
6366 gen_io_start();
895c2d04 6367 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
6368 if (use_icount) {
6369 gen_io_end();
2e70f6ef 6370 }
55807224
EI
6371 /* Break the TB to be able to take timer interrupts immediately
6372 after reading count. */
6373 ctx->bstate = BS_STOP;
2423f660
TS
6374 rn = "Count";
6375 break;
6376 /* 6,7 are implementation dependent */
9c2149c8 6377 default:
f31b035a 6378 goto cp0_unimplemented;
876d4b07 6379 }
9c2149c8
TS
6380 break;
6381 case 10:
6382 switch (sel) {
6383 case 0:
7db13fae 6384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6385 rn = "EntryHi";
6386 break;
9c2149c8 6387 default:
f31b035a 6388 goto cp0_unimplemented;
876d4b07 6389 }
9c2149c8
TS
6390 break;
6391 case 11:
6392 switch (sel) {
6393 case 0:
7db13fae 6394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6395 rn = "Compare";
6396 break;
876d4b07 6397 /* 6,7 are implementation dependent */
9c2149c8 6398 default:
f31b035a 6399 goto cp0_unimplemented;
876d4b07 6400 }
9c2149c8
TS
6401 break;
6402 case 12:
6403 switch (sel) {
6404 case 0:
7db13fae 6405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6406 rn = "Status";
6407 break;
9c2149c8 6408 case 1:
d75c135e 6409 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6411 rn = "IntCtl";
6412 break;
9c2149c8 6413 case 2:
d75c135e 6414 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6416 rn = "SRSCtl";
6417 break;
9c2149c8 6418 case 3:
d75c135e 6419 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6421 rn = "SRSMap";
6422 break;
9c2149c8 6423 default:
f31b035a 6424 goto cp0_unimplemented;
876d4b07 6425 }
9c2149c8
TS
6426 break;
6427 case 13:
6428 switch (sel) {
6429 case 0:
7db13fae 6430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6431 rn = "Cause";
6432 break;
9c2149c8 6433 default:
f31b035a 6434 goto cp0_unimplemented;
876d4b07 6435 }
9c2149c8
TS
6436 break;
6437 case 14:
6438 switch (sel) {
6439 case 0:
7db13fae 6440 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6441 rn = "EPC";
6442 break;
9c2149c8 6443 default:
f31b035a 6444 goto cp0_unimplemented;
876d4b07 6445 }
9c2149c8
TS
6446 break;
6447 case 15:
6448 switch (sel) {
6449 case 0:
7db13fae 6450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6451 rn = "PRid";
6452 break;
9c2149c8 6453 case 1:
d75c135e 6454 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6456 rn = "EBase";
6457 break;
9c2149c8 6458 default:
f31b035a 6459 goto cp0_unimplemented;
876d4b07 6460 }
9c2149c8
TS
6461 break;
6462 case 16:
6463 switch (sel) {
6464 case 0:
7db13fae 6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6466 rn = "Config";
6467 break;
6468 case 1:
7db13fae 6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6470 rn = "Config1";
6471 break;
6472 case 2:
7db13fae 6473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6474 rn = "Config2";
6475 break;
6476 case 3:
7db13fae 6477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6478 rn = "Config3";
6479 break;
faf1f68b
LA
6480 case 4:
6481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6482 rn = "Config4";
6483 break;
6484 case 5:
6485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6486 rn = "Config5";
6487 break;
9c2149c8 6488 /* 6,7 are implementation dependent */
f0b3f3ae 6489 case 6:
7db13fae 6490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6491 rn = "Config6";
6492 break;
6493 case 7:
7db13fae 6494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6495 rn = "Config7";
6496 break;
9c2149c8 6497 default:
f31b035a 6498 goto cp0_unimplemented;
9c2149c8
TS
6499 }
6500 break;
6501 case 17:
6502 switch (sel) {
6503 case 0:
895c2d04 6504 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6505 rn = "LLAddr";
6506 break;
9c2149c8 6507 default:
f31b035a 6508 goto cp0_unimplemented;
9c2149c8
TS
6509 }
6510 break;
6511 case 18:
6512 switch (sel) {
fd88b6ab 6513 case 0 ... 7:
895c2d04 6514 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6515 rn = "WatchLo";
6516 break;
9c2149c8 6517 default:
f31b035a 6518 goto cp0_unimplemented;
9c2149c8
TS
6519 }
6520 break;
6521 case 19:
6522 switch (sel) {
fd88b6ab 6523 case 0 ... 7:
895c2d04 6524 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6525 rn = "WatchHi";
6526 break;
9c2149c8 6527 default:
f31b035a 6528 goto cp0_unimplemented;
9c2149c8
TS
6529 }
6530 break;
6531 case 20:
6532 switch (sel) {
6533 case 0:
d75c135e 6534 check_insn(ctx, ISA_MIPS3);
7db13fae 6535 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6536 rn = "XContext";
6537 break;
9c2149c8 6538 default:
f31b035a 6539 goto cp0_unimplemented;
9c2149c8
TS
6540 }
6541 break;
6542 case 21:
6543 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6544 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6545 switch (sel) {
6546 case 0:
7db13fae 6547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6548 rn = "Framemask";
6549 break;
9c2149c8 6550 default:
f31b035a 6551 goto cp0_unimplemented;
9c2149c8
TS
6552 }
6553 break;
6554 case 22:
d9bea114 6555 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6556 rn = "'Diagnostic"; /* implementation dependent */
6557 break;
9c2149c8
TS
6558 case 23:
6559 switch (sel) {
6560 case 0:
895c2d04 6561 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6562 rn = "Debug";
6563 break;
9c2149c8 6564 case 1:
895c2d04 6565// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6566 rn = "TraceControl";
6567// break;
9c2149c8 6568 case 2:
895c2d04 6569// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6570 rn = "TraceControl2";
6571// break;
9c2149c8 6572 case 3:
895c2d04 6573// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6574 rn = "UserTraceData";
6575// break;
9c2149c8 6576 case 4:
895c2d04 6577// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6578 rn = "TraceBPC";
6579// break;
9c2149c8 6580 default:
f31b035a 6581 goto cp0_unimplemented;
9c2149c8
TS
6582 }
6583 break;
6584 case 24:
6585 switch (sel) {
6586 case 0:
f0b3f3ae 6587 /* EJTAG support */
7db13fae 6588 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6589 rn = "DEPC";
6590 break;
9c2149c8 6591 default:
f31b035a 6592 goto cp0_unimplemented;
9c2149c8
TS
6593 }
6594 break;
6595 case 25:
6596 switch (sel) {
6597 case 0:
7db13fae 6598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6599 rn = "Performance0";
9c2149c8
TS
6600 break;
6601 case 1:
d9bea114 6602// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6603 rn = "Performance1";
6604// break;
9c2149c8 6605 case 2:
d9bea114 6606// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6607 rn = "Performance2";
6608// break;
9c2149c8 6609 case 3:
d9bea114 6610// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6611 rn = "Performance3";
6612// break;
9c2149c8 6613 case 4:
d9bea114 6614// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6615 rn = "Performance4";
6616// break;
9c2149c8 6617 case 5:
d9bea114 6618// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6619 rn = "Performance5";
6620// break;
9c2149c8 6621 case 6:
d9bea114 6622// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6623 rn = "Performance6";
6624// break;
9c2149c8 6625 case 7:
d9bea114 6626// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6627 rn = "Performance7";
6628// break;
9c2149c8 6629 default:
f31b035a 6630 goto cp0_unimplemented;
9c2149c8
TS
6631 }
6632 break;
6633 case 26:
d9bea114 6634 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6635 rn = "ECC";
6636 break;
9c2149c8
TS
6637 case 27:
6638 switch (sel) {
6639 /* ignored */
6640 case 0 ... 3:
d9bea114 6641 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6642 rn = "CacheErr";
6643 break;
9c2149c8 6644 default:
f31b035a 6645 goto cp0_unimplemented;
9c2149c8
TS
6646 }
6647 break;
6648 case 28:
6649 switch (sel) {
6650 case 0:
6651 case 2:
6652 case 4:
6653 case 6:
7db13fae 6654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6655 rn = "TagLo";
6656 break;
6657 case 1:
6658 case 3:
6659 case 5:
6660 case 7:
7db13fae 6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6662 rn = "DataLo";
6663 break;
6664 default:
f31b035a 6665 goto cp0_unimplemented;
9c2149c8
TS
6666 }
6667 break;
6668 case 29:
6669 switch (sel) {
6670 case 0:
6671 case 2:
6672 case 4:
6673 case 6:
7db13fae 6674 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6675 rn = "TagHi";
6676 break;
6677 case 1:
6678 case 3:
6679 case 5:
6680 case 7:
7db13fae 6681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6682 rn = "DataHi";
6683 break;
6684 default:
f31b035a 6685 goto cp0_unimplemented;
9c2149c8
TS
6686 }
6687 break;
6688 case 30:
6689 switch (sel) {
6690 case 0:
7db13fae 6691 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6692 rn = "ErrorEPC";
6693 break;
9c2149c8 6694 default:
f31b035a 6695 goto cp0_unimplemented;
9c2149c8
TS
6696 }
6697 break;
6698 case 31:
6699 switch (sel) {
6700 case 0:
f0b3f3ae 6701 /* EJTAG support */
7db13fae 6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6703 rn = "DESAVE";
6704 break;
e98c0d17 6705 case 2 ... 7:
f31b035a
LA
6706 CP0_CHECK(ctx->kscrexist & (1 << sel));
6707 tcg_gen_ld_tl(arg, cpu_env,
6708 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6709 rn = "KScratch";
e98c0d17 6710 break;
9c2149c8 6711 default:
f31b035a 6712 goto cp0_unimplemented;
9c2149c8
TS
6713 }
6714 break;
6715 default:
f31b035a 6716 goto cp0_unimplemented;
9c2149c8 6717 }
2abf314d 6718 (void)rn; /* avoid a compiler warning */
d12d51d5 6719 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6720 return;
6721
f31b035a 6722cp0_unimplemented:
d12d51d5 6723 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6724 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6725}
6726
d75c135e 6727static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6728{
6729 const char *rn = "invalid";
6730
e189e748 6731 if (sel != 0)
d75c135e 6732 check_insn(ctx, ISA_MIPS64);
e189e748 6733
2e70f6ef
PB
6734 if (use_icount)
6735 gen_io_start();
6736
9c2149c8
TS
6737 switch (reg) {
6738 case 0:
6739 switch (sel) {
6740 case 0:
895c2d04 6741 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6742 rn = "Index";
6743 break;
6744 case 1:
f31b035a 6745 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6746 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6747 rn = "MVPControl";
ead9360e 6748 break;
9c2149c8 6749 case 2:
f31b035a 6750 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6751 /* ignored */
9c2149c8 6752 rn = "MVPConf0";
ead9360e 6753 break;
9c2149c8 6754 case 3:
f31b035a 6755 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6756 /* ignored */
9c2149c8 6757 rn = "MVPConf1";
ead9360e 6758 break;
9c2149c8 6759 default:
f31b035a 6760 goto cp0_unimplemented;
9c2149c8
TS
6761 }
6762 break;
6763 case 1:
6764 switch (sel) {
6765 case 0:
2423f660 6766 /* ignored */
9c2149c8 6767 rn = "Random";
2423f660 6768 break;
9c2149c8 6769 case 1:
f31b035a 6770 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6771 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6772 rn = "VPEControl";
ead9360e 6773 break;
9c2149c8 6774 case 2:
f31b035a 6775 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6776 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6777 rn = "VPEConf0";
ead9360e 6778 break;
9c2149c8 6779 case 3:
f31b035a 6780 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6781 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6782 rn = "VPEConf1";
ead9360e 6783 break;
9c2149c8 6784 case 4:
f31b035a 6785 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6786 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6787 rn = "YQMask";
ead9360e 6788 break;
9c2149c8 6789 case 5:
f31b035a 6790 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6791 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6792 rn = "VPESchedule";
ead9360e 6793 break;
9c2149c8 6794 case 6:
f31b035a 6795 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6796 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6797 rn = "VPEScheFBack";
ead9360e 6798 break;
9c2149c8 6799 case 7:
f31b035a 6800 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6801 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6802 rn = "VPEOpt";
ead9360e 6803 break;
9c2149c8 6804 default:
f31b035a 6805 goto cp0_unimplemented;
9c2149c8
TS
6806 }
6807 break;
6808 case 2:
6809 switch (sel) {
6810 case 0:
7207c7f9 6811 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6812 rn = "EntryLo0";
6813 break;
9c2149c8 6814 case 1:
f31b035a 6815 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6816 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6817 rn = "TCStatus";
ead9360e 6818 break;
9c2149c8 6819 case 2:
f31b035a 6820 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6821 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6822 rn = "TCBind";
ead9360e 6823 break;
9c2149c8 6824 case 3:
f31b035a 6825 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6826 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6827 rn = "TCRestart";
ead9360e 6828 break;
9c2149c8 6829 case 4:
f31b035a 6830 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6831 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6832 rn = "TCHalt";
ead9360e 6833 break;
9c2149c8 6834 case 5:
f31b035a 6835 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6836 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6837 rn = "TCContext";
ead9360e 6838 break;
9c2149c8 6839 case 6:
f31b035a 6840 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6841 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6842 rn = "TCSchedule";
ead9360e 6843 break;
9c2149c8 6844 case 7:
f31b035a 6845 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6846 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6847 rn = "TCScheFBack";
ead9360e 6848 break;
9c2149c8 6849 default:
f31b035a 6850 goto cp0_unimplemented;
9c2149c8
TS
6851 }
6852 break;
6853 case 3:
6854 switch (sel) {
6855 case 0:
7207c7f9 6856 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6857 rn = "EntryLo1";
6858 break;
9c2149c8 6859 default:
f31b035a 6860 goto cp0_unimplemented;
876d4b07 6861 }
9c2149c8
TS
6862 break;
6863 case 4:
6864 switch (sel) {
6865 case 0:
895c2d04 6866 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6867 rn = "Context";
6868 break;
9c2149c8 6869 case 1:
895c2d04 6870// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6871 rn = "ContextConfig";
f31b035a 6872 goto cp0_unimplemented;
2423f660 6873// break;
d279279e 6874 case 2:
f31b035a
LA
6875 CP0_CHECK(ctx->ulri);
6876 tcg_gen_st_tl(arg, cpu_env,
6877 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6878 rn = "UserLocal";
d279279e 6879 break;
9c2149c8 6880 default:
f31b035a 6881 goto cp0_unimplemented;
876d4b07 6882 }
9c2149c8
TS
6883 break;
6884 case 5:
6885 switch (sel) {
6886 case 0:
895c2d04 6887 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6888 rn = "PageMask";
6889 break;
9c2149c8 6890 case 1:
d75c135e 6891 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6892 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6893 rn = "PageGrain";
6894 break;
9c2149c8 6895 default:
f31b035a 6896 goto cp0_unimplemented;
876d4b07 6897 }
9c2149c8
TS
6898 break;
6899 case 6:
6900 switch (sel) {
6901 case 0:
895c2d04 6902 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6903 rn = "Wired";
6904 break;
9c2149c8 6905 case 1:
d75c135e 6906 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6907 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6908 rn = "SRSConf0";
ead9360e 6909 break;
9c2149c8 6910 case 2:
d75c135e 6911 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6912 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6913 rn = "SRSConf1";
ead9360e 6914 break;
9c2149c8 6915 case 3:
d75c135e 6916 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6917 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6918 rn = "SRSConf2";
ead9360e 6919 break;
9c2149c8 6920 case 4:
d75c135e 6921 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6922 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6923 rn = "SRSConf3";
ead9360e 6924 break;
9c2149c8 6925 case 5:
d75c135e 6926 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6927 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6928 rn = "SRSConf4";
ead9360e 6929 break;
9c2149c8 6930 default:
f31b035a 6931 goto cp0_unimplemented;
876d4b07 6932 }
9c2149c8
TS
6933 break;
6934 case 7:
6935 switch (sel) {
6936 case 0:
d75c135e 6937 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6938 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6939 ctx->bstate = BS_STOP;
2423f660
TS
6940 rn = "HWREna";
6941 break;
9c2149c8 6942 default:
f31b035a 6943 goto cp0_unimplemented;
876d4b07 6944 }
9c2149c8
TS
6945 break;
6946 case 8:
aea14095
LA
6947 switch (sel) {
6948 case 0:
6949 /* ignored */
6950 rn = "BadVAddr";
6951 break;
6952 case 1:
6953 /* ignored */
6954 rn = "BadInstr";
6955 break;
6956 case 2:
6957 /* ignored */
6958 rn = "BadInstrP";
6959 break;
6960 default:
f31b035a 6961 goto cp0_unimplemented;
aea14095 6962 }
9c2149c8
TS
6963 break;
6964 case 9:
6965 switch (sel) {
6966 case 0:
895c2d04 6967 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6968 rn = "Count";
6969 break;
876d4b07 6970 /* 6,7 are implementation dependent */
9c2149c8 6971 default:
f31b035a 6972 goto cp0_unimplemented;
876d4b07
TS
6973 }
6974 /* Stop translation as we may have switched the execution mode */
6975 ctx->bstate = BS_STOP;
9c2149c8
TS
6976 break;
6977 case 10:
6978 switch (sel) {
6979 case 0:
895c2d04 6980 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6981 rn = "EntryHi";
6982 break;
9c2149c8 6983 default:
f31b035a 6984 goto cp0_unimplemented;
876d4b07 6985 }
9c2149c8
TS
6986 break;
6987 case 11:
6988 switch (sel) {
6989 case 0:
895c2d04 6990 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6991 rn = "Compare";
6992 break;
876d4b07 6993 /* 6,7 are implementation dependent */
9c2149c8 6994 default:
f31b035a 6995 goto cp0_unimplemented;
876d4b07 6996 }
de9a95f0
AJ
6997 /* Stop translation as we may have switched the execution mode */
6998 ctx->bstate = BS_STOP;
9c2149c8
TS
6999 break;
7000 case 12:
7001 switch (sel) {
7002 case 0:
867abc7e 7003 save_cpu_state(ctx, 1);
895c2d04 7004 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7005 /* BS_STOP isn't good enough here, hflags may have changed. */
7006 gen_save_pc(ctx->pc + 4);
7007 ctx->bstate = BS_EXCP;
2423f660
TS
7008 rn = "Status";
7009 break;
9c2149c8 7010 case 1:
d75c135e 7011 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7012 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7013 /* Stop translation as we may have switched the execution mode */
7014 ctx->bstate = BS_STOP;
2423f660
TS
7015 rn = "IntCtl";
7016 break;
9c2149c8 7017 case 2:
d75c135e 7018 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7019 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7020 /* Stop translation as we may have switched the execution mode */
7021 ctx->bstate = BS_STOP;
2423f660
TS
7022 rn = "SRSCtl";
7023 break;
9c2149c8 7024 case 3:
d75c135e 7025 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7026 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7027 /* Stop translation as we may have switched the execution mode */
7028 ctx->bstate = BS_STOP;
2423f660
TS
7029 rn = "SRSMap";
7030 break;
7031 default:
f31b035a 7032 goto cp0_unimplemented;
876d4b07 7033 }
9c2149c8
TS
7034 break;
7035 case 13:
7036 switch (sel) {
7037 case 0:
867abc7e 7038 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7039 /* Mark as an IO operation because we may trigger a software
7040 interrupt. */
7041 if (use_icount) {
7042 gen_io_start();
7043 }
895c2d04 7044 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
7045 if (use_icount) {
7046 gen_io_end();
7047 }
7048 /* Stop translation as we may have triggered an intetrupt */
7049 ctx->bstate = BS_STOP;
2423f660
TS
7050 rn = "Cause";
7051 break;
9c2149c8 7052 default:
f31b035a 7053 goto cp0_unimplemented;
876d4b07 7054 }
9c2149c8
TS
7055 break;
7056 case 14:
7057 switch (sel) {
7058 case 0:
7db13fae 7059 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7060 rn = "EPC";
7061 break;
9c2149c8 7062 default:
f31b035a 7063 goto cp0_unimplemented;
876d4b07 7064 }
9c2149c8
TS
7065 break;
7066 case 15:
7067 switch (sel) {
7068 case 0:
2423f660
TS
7069 /* ignored */
7070 rn = "PRid";
7071 break;
9c2149c8 7072 case 1:
d75c135e 7073 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7074 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7075 rn = "EBase";
7076 break;
9c2149c8 7077 default:
f31b035a 7078 goto cp0_unimplemented;
876d4b07 7079 }
9c2149c8
TS
7080 break;
7081 case 16:
7082 switch (sel) {
7083 case 0:
895c2d04 7084 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7085 rn = "Config";
2423f660
TS
7086 /* Stop translation as we may have switched the execution mode */
7087 ctx->bstate = BS_STOP;
9c2149c8
TS
7088 break;
7089 case 1:
1fc7bf6e 7090 /* ignored, read only */
9c2149c8
TS
7091 rn = "Config1";
7092 break;
7093 case 2:
895c2d04 7094 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7095 rn = "Config2";
2423f660
TS
7096 /* Stop translation as we may have switched the execution mode */
7097 ctx->bstate = BS_STOP;
9c2149c8
TS
7098 break;
7099 case 3:
2423f660 7100 /* ignored */
9c2149c8
TS
7101 rn = "Config3";
7102 break;
faf1f68b
LA
7103 case 4:
7104 /* currently ignored */
7105 rn = "Config4";
7106 break;
7107 case 5:
7108 gen_helper_mtc0_config5(cpu_env, arg);
7109 rn = "Config5";
7110 /* Stop translation as we may have switched the execution mode */
7111 ctx->bstate = BS_STOP;
7112 break;
9c2149c8
TS
7113 /* 6,7 are implementation dependent */
7114 default:
7115 rn = "Invalid config selector";
f31b035a 7116 goto cp0_unimplemented;
9c2149c8 7117 }
9c2149c8
TS
7118 break;
7119 case 17:
7120 switch (sel) {
7121 case 0:
895c2d04 7122 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7123 rn = "LLAddr";
7124 break;
9c2149c8 7125 default:
f31b035a 7126 goto cp0_unimplemented;
9c2149c8
TS
7127 }
7128 break;
7129 case 18:
7130 switch (sel) {
fd88b6ab 7131 case 0 ... 7:
895c2d04 7132 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7133 rn = "WatchLo";
7134 break;
9c2149c8 7135 default:
f31b035a 7136 goto cp0_unimplemented;
9c2149c8
TS
7137 }
7138 break;
7139 case 19:
7140 switch (sel) {
fd88b6ab 7141 case 0 ... 7:
895c2d04 7142 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7143 rn = "WatchHi";
7144 break;
9c2149c8 7145 default:
f31b035a 7146 goto cp0_unimplemented;
9c2149c8
TS
7147 }
7148 break;
7149 case 20:
7150 switch (sel) {
7151 case 0:
d75c135e 7152 check_insn(ctx, ISA_MIPS3);
895c2d04 7153 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7154 rn = "XContext";
7155 break;
9c2149c8 7156 default:
f31b035a 7157 goto cp0_unimplemented;
9c2149c8
TS
7158 }
7159 break;
7160 case 21:
7161 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7162 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7163 switch (sel) {
7164 case 0:
895c2d04 7165 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7166 rn = "Framemask";
7167 break;
9c2149c8 7168 default:
f31b035a 7169 goto cp0_unimplemented;
9c2149c8
TS
7170 }
7171 break;
7172 case 22:
7173 /* ignored */
7174 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7175 break;
9c2149c8
TS
7176 case 23:
7177 switch (sel) {
7178 case 0:
895c2d04 7179 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7180 /* BS_STOP isn't good enough here, hflags may have changed. */
7181 gen_save_pc(ctx->pc + 4);
7182 ctx->bstate = BS_EXCP;
2423f660
TS
7183 rn = "Debug";
7184 break;
9c2149c8 7185 case 1:
895c2d04 7186// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7187 /* Stop translation as we may have switched the execution mode */
7188 ctx->bstate = BS_STOP;
2423f660
TS
7189 rn = "TraceControl";
7190// break;
9c2149c8 7191 case 2:
895c2d04 7192// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7193 /* Stop translation as we may have switched the execution mode */
7194 ctx->bstate = BS_STOP;
2423f660
TS
7195 rn = "TraceControl2";
7196// break;
9c2149c8 7197 case 3:
895c2d04 7198// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7199 /* Stop translation as we may have switched the execution mode */
7200 ctx->bstate = BS_STOP;
2423f660
TS
7201 rn = "UserTraceData";
7202// break;
9c2149c8 7203 case 4:
895c2d04 7204// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7205 /* Stop translation as we may have switched the execution mode */
7206 ctx->bstate = BS_STOP;
2423f660
TS
7207 rn = "TraceBPC";
7208// break;
9c2149c8 7209 default:
f31b035a 7210 goto cp0_unimplemented;
9c2149c8 7211 }
9c2149c8
TS
7212 break;
7213 case 24:
7214 switch (sel) {
7215 case 0:
f1aa6320 7216 /* EJTAG support */
7db13fae 7217 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7218 rn = "DEPC";
7219 break;
9c2149c8 7220 default:
f31b035a 7221 goto cp0_unimplemented;
9c2149c8
TS
7222 }
7223 break;
7224 case 25:
7225 switch (sel) {
7226 case 0:
895c2d04 7227 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7228 rn = "Performance0";
7229 break;
9c2149c8 7230 case 1:
895c2d04 7231// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7232 rn = "Performance1";
7233// break;
9c2149c8 7234 case 2:
895c2d04 7235// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7236 rn = "Performance2";
7237// break;
9c2149c8 7238 case 3:
895c2d04 7239// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7240 rn = "Performance3";
7241// break;
9c2149c8 7242 case 4:
895c2d04 7243// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7244 rn = "Performance4";
7245// break;
9c2149c8 7246 case 5:
895c2d04 7247// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7248 rn = "Performance5";
7249// break;
9c2149c8 7250 case 6:
895c2d04 7251// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7252 rn = "Performance6";
7253// break;
9c2149c8 7254 case 7:
895c2d04 7255// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7256 rn = "Performance7";
7257// break;
9c2149c8 7258 default:
f31b035a 7259 goto cp0_unimplemented;
9c2149c8 7260 }
876d4b07 7261 break;
9c2149c8 7262 case 26:
876d4b07 7263 /* ignored */
9c2149c8 7264 rn = "ECC";
876d4b07 7265 break;
9c2149c8
TS
7266 case 27:
7267 switch (sel) {
7268 case 0 ... 3:
2423f660
TS
7269 /* ignored */
7270 rn = "CacheErr";
7271 break;
9c2149c8 7272 default:
f31b035a 7273 goto cp0_unimplemented;
9c2149c8 7274 }
876d4b07 7275 break;
9c2149c8
TS
7276 case 28:
7277 switch (sel) {
7278 case 0:
7279 case 2:
7280 case 4:
7281 case 6:
895c2d04 7282 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7283 rn = "TagLo";
7284 break;
7285 case 1:
7286 case 3:
7287 case 5:
7288 case 7:
895c2d04 7289 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7290 rn = "DataLo";
7291 break;
7292 default:
f31b035a 7293 goto cp0_unimplemented;
9c2149c8
TS
7294 }
7295 break;
7296 case 29:
7297 switch (sel) {
7298 case 0:
7299 case 2:
7300 case 4:
7301 case 6:
895c2d04 7302 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7303 rn = "TagHi";
7304 break;
7305 case 1:
7306 case 3:
7307 case 5:
7308 case 7:
895c2d04 7309 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7310 rn = "DataHi";
7311 break;
7312 default:
7313 rn = "invalid sel";
f31b035a 7314 goto cp0_unimplemented;
9c2149c8 7315 }
876d4b07 7316 break;
9c2149c8
TS
7317 case 30:
7318 switch (sel) {
7319 case 0:
7db13fae 7320 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7321 rn = "ErrorEPC";
7322 break;
9c2149c8 7323 default:
f31b035a 7324 goto cp0_unimplemented;
9c2149c8
TS
7325 }
7326 break;
7327 case 31:
7328 switch (sel) {
7329 case 0:
f1aa6320 7330 /* EJTAG support */
7db13fae 7331 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7332 rn = "DESAVE";
7333 break;
e98c0d17 7334 case 2 ... 7:
f31b035a
LA
7335 CP0_CHECK(ctx->kscrexist & (1 << sel));
7336 tcg_gen_st_tl(arg, cpu_env,
7337 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7338 rn = "KScratch";
e98c0d17 7339 break;
9c2149c8 7340 default:
f31b035a 7341 goto cp0_unimplemented;
9c2149c8 7342 }
876d4b07
TS
7343 /* Stop translation as we may have switched the execution mode */
7344 ctx->bstate = BS_STOP;
9c2149c8
TS
7345 break;
7346 default:
f31b035a 7347 goto cp0_unimplemented;
9c2149c8 7348 }
2abf314d 7349 (void)rn; /* avoid a compiler warning */
d12d51d5 7350 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7351 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
7352 if (use_icount) {
7353 gen_io_end();
7354 ctx->bstate = BS_STOP;
7355 }
9c2149c8
TS
7356 return;
7357
f31b035a 7358cp0_unimplemented:
d12d51d5 7359 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7360}
d26bc211 7361#endif /* TARGET_MIPS64 */
9c2149c8 7362
7db13fae 7363static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7364 int u, int sel, int h)
7365{
7366 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7367 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7368
7369 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7370 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7371 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7372 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7373 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7374 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7375 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7376 else if (u == 0) {
7377 switch (rt) {
5a25ce94
EI
7378 case 1:
7379 switch (sel) {
7380 case 1:
895c2d04 7381 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7382 break;
7383 case 2:
895c2d04 7384 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7385 break;
7386 default:
7387 goto die;
7388 break;
7389 }
7390 break;
ead9360e
TS
7391 case 2:
7392 switch (sel) {
7393 case 1:
895c2d04 7394 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7395 break;
7396 case 2:
895c2d04 7397 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7398 break;
7399 case 3:
895c2d04 7400 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7401 break;
7402 case 4:
895c2d04 7403 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7404 break;
7405 case 5:
895c2d04 7406 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7407 break;
7408 case 6:
895c2d04 7409 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7410 break;
7411 case 7:
895c2d04 7412 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7413 break;
7414 default:
d75c135e 7415 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7416 break;
7417 }
7418 break;
7419 case 10:
7420 switch (sel) {
7421 case 0:
895c2d04 7422 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7423 break;
7424 default:
d75c135e 7425 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7426 break;
7427 }
7428 case 12:
7429 switch (sel) {
7430 case 0:
895c2d04 7431 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7432 break;
7433 default:
d75c135e 7434 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7435 break;
7436 }
5a25ce94
EI
7437 case 13:
7438 switch (sel) {
7439 case 0:
895c2d04 7440 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7441 break;
7442 default:
7443 goto die;
7444 break;
7445 }
7446 break;
7447 case 14:
7448 switch (sel) {
7449 case 0:
895c2d04 7450 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7451 break;
7452 default:
7453 goto die;
7454 break;
7455 }
7456 break;
7457 case 15:
7458 switch (sel) {
7459 case 1:
895c2d04 7460 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7461 break;
7462 default:
7463 goto die;
7464 break;
7465 }
7466 break;
7467 case 16:
7468 switch (sel) {
7469 case 0 ... 7:
895c2d04 7470 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7471 break;
7472 default:
7473 goto die;
7474 break;
7475 }
7476 break;
ead9360e
TS
7477 case 23:
7478 switch (sel) {
7479 case 0:
895c2d04 7480 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7481 break;
7482 default:
d75c135e 7483 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7484 break;
7485 }
7486 break;
7487 default:
d75c135e 7488 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7489 }
7490 } else switch (sel) {
7491 /* GPR registers. */
7492 case 0:
895c2d04 7493 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7494 break;
7495 /* Auxiliary CPU registers */
7496 case 1:
7497 switch (rt) {
7498 case 0:
895c2d04 7499 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7500 break;
7501 case 1:
895c2d04 7502 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7503 break;
7504 case 2:
895c2d04 7505 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7506 break;
7507 case 4:
895c2d04 7508 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7509 break;
7510 case 5:
895c2d04 7511 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7512 break;
7513 case 6:
895c2d04 7514 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7515 break;
7516 case 8:
895c2d04 7517 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7518 break;
7519 case 9:
895c2d04 7520 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7521 break;
7522 case 10:
895c2d04 7523 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7524 break;
7525 case 12:
895c2d04 7526 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7527 break;
7528 case 13:
895c2d04 7529 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7530 break;
7531 case 14:
895c2d04 7532 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7533 break;
7534 case 16:
895c2d04 7535 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7536 break;
7537 default:
7538 goto die;
7539 }
7540 break;
7541 /* Floating point (COP1). */
7542 case 2:
7543 /* XXX: For now we support only a single FPU context. */
7544 if (h == 0) {
a7812ae4 7545 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7546
7547 gen_load_fpr32(fp0, rt);
7548 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7549 tcg_temp_free_i32(fp0);
ead9360e 7550 } else {
a7812ae4 7551 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7552
7f6613ce 7553 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7554 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7555 tcg_temp_free_i32(fp0);
ead9360e
TS
7556 }
7557 break;
7558 case 3:
7559 /* XXX: For now we support only a single FPU context. */
895c2d04 7560 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7561 break;
7562 /* COP2: Not implemented. */
7563 case 4:
7564 case 5:
7565 /* fall through */
7566 default:
7567 goto die;
7568 }
d12d51d5 7569 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7570 gen_store_gpr(t0, rd);
7571 tcg_temp_free(t0);
ead9360e
TS
7572 return;
7573
7574die:
1a3fd9c3 7575 tcg_temp_free(t0);
d12d51d5 7576 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7577 generate_exception(ctx, EXCP_RI);
7578}
7579
7db13fae 7580static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7581 int u, int sel, int h)
7582{
7583 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7584 TCGv t0 = tcg_temp_local_new();
ead9360e 7585
1a3fd9c3 7586 gen_load_gpr(t0, rt);
ead9360e 7587 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7588 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7589 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7590 /* NOP */ ;
7591 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7592 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7593 /* NOP */ ;
7594 else if (u == 0) {
7595 switch (rd) {
5a25ce94
EI
7596 case 1:
7597 switch (sel) {
7598 case 1:
895c2d04 7599 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7600 break;
7601 case 2:
895c2d04 7602 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7603 break;
7604 default:
7605 goto die;
7606 break;
7607 }
7608 break;
ead9360e
TS
7609 case 2:
7610 switch (sel) {
7611 case 1:
895c2d04 7612 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7613 break;
7614 case 2:
895c2d04 7615 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7616 break;
7617 case 3:
895c2d04 7618 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7619 break;
7620 case 4:
895c2d04 7621 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7622 break;
7623 case 5:
895c2d04 7624 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7625 break;
7626 case 6:
895c2d04 7627 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7628 break;
7629 case 7:
895c2d04 7630 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7631 break;
7632 default:
d75c135e 7633 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7634 break;
7635 }
7636 break;
7637 case 10:
7638 switch (sel) {
7639 case 0:
895c2d04 7640 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7641 break;
7642 default:
d75c135e 7643 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7644 break;
7645 }
7646 case 12:
7647 switch (sel) {
7648 case 0:
895c2d04 7649 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7650 break;
7651 default:
d75c135e 7652 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7653 break;
7654 }
5a25ce94
EI
7655 case 13:
7656 switch (sel) {
7657 case 0:
895c2d04 7658 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7659 break;
7660 default:
7661 goto die;
7662 break;
7663 }
7664 break;
7665 case 15:
7666 switch (sel) {
7667 case 1:
895c2d04 7668 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7669 break;
7670 default:
7671 goto die;
7672 break;
7673 }
7674 break;
ead9360e
TS
7675 case 23:
7676 switch (sel) {
7677 case 0:
895c2d04 7678 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7679 break;
7680 default:
d75c135e 7681 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7682 break;
7683 }
7684 break;
7685 default:
d75c135e 7686 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7687 }
7688 } else switch (sel) {
7689 /* GPR registers. */
7690 case 0:
895c2d04 7691 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7692 break;
7693 /* Auxiliary CPU registers */
7694 case 1:
7695 switch (rd) {
7696 case 0:
895c2d04 7697 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7698 break;
7699 case 1:
895c2d04 7700 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7701 break;
7702 case 2:
895c2d04 7703 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7704 break;
7705 case 4:
895c2d04 7706 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7707 break;
7708 case 5:
895c2d04 7709 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7710 break;
7711 case 6:
895c2d04 7712 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7713 break;
7714 case 8:
895c2d04 7715 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7716 break;
7717 case 9:
895c2d04 7718 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7719 break;
7720 case 10:
895c2d04 7721 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7722 break;
7723 case 12:
895c2d04 7724 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7725 break;
7726 case 13:
895c2d04 7727 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7728 break;
7729 case 14:
895c2d04 7730 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7731 break;
7732 case 16:
895c2d04 7733 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7734 break;
7735 default:
7736 goto die;
7737 }
7738 break;
7739 /* Floating point (COP1). */
7740 case 2:
7741 /* XXX: For now we support only a single FPU context. */
7742 if (h == 0) {
a7812ae4 7743 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7744
7745 tcg_gen_trunc_tl_i32(fp0, t0);
7746 gen_store_fpr32(fp0, rd);
a7812ae4 7747 tcg_temp_free_i32(fp0);
ead9360e 7748 } else {
a7812ae4 7749 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7750
7751 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7752 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7753 tcg_temp_free_i32(fp0);
ead9360e
TS
7754 }
7755 break;
7756 case 3:
7757 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7758 save_cpu_state(ctx, 1);
736d120a
PJ
7759 {
7760 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7761
7762 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7763 tcg_temp_free_i32(fs_tmp);
7764 }
4cf8a45f
YK
7765 /* Stop translation as we may have changed hflags */
7766 ctx->bstate = BS_STOP;
ead9360e
TS
7767 break;
7768 /* COP2: Not implemented. */
7769 case 4:
7770 case 5:
7771 /* fall through */
7772 default:
7773 goto die;
7774 }
d12d51d5 7775 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7776 tcg_temp_free(t0);
ead9360e
TS
7777 return;
7778
7779die:
1a3fd9c3 7780 tcg_temp_free(t0);
d12d51d5 7781 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7782 generate_exception(ctx, EXCP_RI);
7783}
7784
7db13fae 7785static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7786{
287c4b84 7787 const char *opn = "ldst";
6af0bf9c 7788
2e15497c 7789 check_cp0_enabled(ctx);
6af0bf9c
FB
7790 switch (opc) {
7791 case OPC_MFC0:
7792 if (rt == 0) {
ead9360e 7793 /* Treat as NOP. */
6af0bf9c
FB
7794 return;
7795 }
d75c135e 7796 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7797 opn = "mfc0";
7798 break;
7799 case OPC_MTC0:
1a3fd9c3 7800 {
1fc7bf6e 7801 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7802
7803 gen_load_gpr(t0, rt);
d75c135e 7804 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7805 tcg_temp_free(t0);
7806 }
6af0bf9c
FB
7807 opn = "mtc0";
7808 break;
d26bc211 7809#if defined(TARGET_MIPS64)
9c2149c8 7810 case OPC_DMFC0:
d75c135e 7811 check_insn(ctx, ISA_MIPS3);
9c2149c8 7812 if (rt == 0) {
ead9360e 7813 /* Treat as NOP. */
9c2149c8
TS
7814 return;
7815 }
d75c135e 7816 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7817 opn = "dmfc0";
7818 break;
7819 case OPC_DMTC0:
d75c135e 7820 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7821 {
1fc7bf6e 7822 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7823
7824 gen_load_gpr(t0, rt);
d75c135e 7825 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7826 tcg_temp_free(t0);
7827 }
9c2149c8
TS
7828 opn = "dmtc0";
7829 break;
534ce69f 7830#endif
ead9360e 7831 case OPC_MFTR:
d75c135e 7832 check_insn(ctx, ASE_MT);
ead9360e
TS
7833 if (rd == 0) {
7834 /* Treat as NOP. */
7835 return;
7836 }
6c5c1e20 7837 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7838 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7839 opn = "mftr";
7840 break;
7841 case OPC_MTTR:
d75c135e 7842 check_insn(ctx, ASE_MT);
6c5c1e20 7843 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7844 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7845 opn = "mttr";
7846 break;
6af0bf9c 7847 case OPC_TLBWI:
6af0bf9c 7848 opn = "tlbwi";
c01fccd2 7849 if (!env->tlb->helper_tlbwi)
29929e34 7850 goto die;
895c2d04 7851 gen_helper_tlbwi(cpu_env);
6af0bf9c 7852 break;
9456c2fb
LA
7853 case OPC_TLBINV:
7854 opn = "tlbinv";
7855 if (ctx->ie >= 2) {
7856 if (!env->tlb->helper_tlbinv) {
7857 goto die;
7858 }
7859 gen_helper_tlbinv(cpu_env);
7860 } /* treat as nop if TLBINV not supported */
7861 break;
7862 case OPC_TLBINVF:
7863 opn = "tlbinvf";
7864 if (ctx->ie >= 2) {
7865 if (!env->tlb->helper_tlbinvf) {
7866 goto die;
7867 }
7868 gen_helper_tlbinvf(cpu_env);
7869 } /* treat as nop if TLBINV not supported */
7870 break;
6af0bf9c 7871 case OPC_TLBWR:
6af0bf9c 7872 opn = "tlbwr";
c01fccd2 7873 if (!env->tlb->helper_tlbwr)
29929e34 7874 goto die;
895c2d04 7875 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7876 break;
7877 case OPC_TLBP:
6af0bf9c 7878 opn = "tlbp";
c01fccd2 7879 if (!env->tlb->helper_tlbp)
29929e34 7880 goto die;
895c2d04 7881 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7882 break;
7883 case OPC_TLBR:
6af0bf9c 7884 opn = "tlbr";
c01fccd2 7885 if (!env->tlb->helper_tlbr)
29929e34 7886 goto die;
895c2d04 7887 gen_helper_tlbr(cpu_env);
6af0bf9c 7888 break;
6af0bf9c
FB
7889 case OPC_ERET:
7890 opn = "eret";
d75c135e 7891 check_insn(ctx, ISA_MIPS2);
339cd2a8
LA
7892 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7893 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7894 MIPS_DEBUG("CTI in delay / forbidden slot");
7895 goto die;
7896 }
895c2d04 7897 gen_helper_eret(cpu_env);
6af0bf9c
FB
7898 ctx->bstate = BS_EXCP;
7899 break;
7900 case OPC_DERET:
7901 opn = "deret";
d75c135e 7902 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7903 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7904 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7905 MIPS_DEBUG("CTI in delay / forbidden slot");
7906 goto die;
7907 }
6af0bf9c 7908 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7909 MIPS_INVAL(opn);
6af0bf9c
FB
7910 generate_exception(ctx, EXCP_RI);
7911 } else {
895c2d04 7912 gen_helper_deret(cpu_env);
6af0bf9c
FB
7913 ctx->bstate = BS_EXCP;
7914 }
7915 break;
4ad40f36
FB
7916 case OPC_WAIT:
7917 opn = "wait";
d75c135e 7918 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7919 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7920 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7921 MIPS_DEBUG("CTI in delay / forbidden slot");
7922 goto die;
7923 }
4ad40f36
FB
7924 /* If we get an exception, we want to restart at next instruction */
7925 ctx->pc += 4;
7926 save_cpu_state(ctx, 1);
7927 ctx->pc -= 4;
895c2d04 7928 gen_helper_wait(cpu_env);
4ad40f36
FB
7929 ctx->bstate = BS_EXCP;
7930 break;
6af0bf9c 7931 default:
29929e34 7932 die:
923617a3 7933 MIPS_INVAL(opn);
6af0bf9c
FB
7934 generate_exception(ctx, EXCP_RI);
7935 return;
7936 }
2abf314d 7937 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7938 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7939}
f1aa6320 7940#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7941
6ea83fed 7942/* CP1 Branches (before delay slot) */
d75c135e
AJ
7943static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7944 int32_t cc, int32_t offset)
6ea83fed
FB
7945{
7946 target_ulong btarget;
923617a3 7947 const char *opn = "cp1 cond branch";
a7812ae4 7948 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7949
339cd2a8
LA
7950 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7951 MIPS_DEBUG("CTI in delay / forbidden slot");
7952 generate_exception(ctx, EXCP_RI);
7953 goto out;
7954 }
7955
e189e748 7956 if (cc != 0)
d75c135e 7957 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7958
6ea83fed
FB
7959 btarget = ctx->pc + 4 + offset;
7960
7a387fff
TS
7961 switch (op) {
7962 case OPC_BC1F:
d94536f4
AJ
7963 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7964 tcg_gen_not_i32(t0, t0);
7965 tcg_gen_andi_i32(t0, t0, 1);
7966 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7967 opn = "bc1f";
6ea83fed 7968 goto not_likely;
7a387fff 7969 case OPC_BC1FL:
d94536f4
AJ
7970 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7971 tcg_gen_not_i32(t0, t0);
7972 tcg_gen_andi_i32(t0, t0, 1);
7973 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7974 opn = "bc1fl";
6ea83fed 7975 goto likely;
7a387fff 7976 case OPC_BC1T:
d94536f4
AJ
7977 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7978 tcg_gen_andi_i32(t0, t0, 1);
7979 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7980 opn = "bc1t";
5a5012ec 7981 goto not_likely;
7a387fff 7982 case OPC_BC1TL:
d94536f4
AJ
7983 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7984 tcg_gen_andi_i32(t0, t0, 1);
7985 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7986 opn = "bc1tl";
6ea83fed
FB
7987 likely:
7988 ctx->hflags |= MIPS_HFLAG_BL;
7989 break;
5a5012ec 7990 case OPC_BC1FANY2:
a16336e4 7991 {
d94536f4
AJ
7992 TCGv_i32 t1 = tcg_temp_new_i32();
7993 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7994 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7995 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7996 tcg_temp_free_i32(t1);
d94536f4
AJ
7997 tcg_gen_andi_i32(t0, t0, 1);
7998 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7999 }
fd4a04eb 8000 opn = "bc1any2f";
5a5012ec
TS
8001 goto not_likely;
8002 case OPC_BC1TANY2:
a16336e4 8003 {
d94536f4
AJ
8004 TCGv_i32 t1 = tcg_temp_new_i32();
8005 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8006 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8007 tcg_gen_or_i32(t0, t0, t1);
8008 tcg_temp_free_i32(t1);
8009 tcg_gen_andi_i32(t0, t0, 1);
8010 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8011 }
fd4a04eb 8012 opn = "bc1any2t";
5a5012ec
TS
8013 goto not_likely;
8014 case OPC_BC1FANY4:
a16336e4 8015 {
d94536f4
AJ
8016 TCGv_i32 t1 = tcg_temp_new_i32();
8017 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8018 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8019 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8020 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8021 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8022 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8023 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8024 tcg_temp_free_i32(t1);
d94536f4
AJ
8025 tcg_gen_andi_i32(t0, t0, 1);
8026 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8027 }
fd4a04eb 8028 opn = "bc1any4f";
5a5012ec
TS
8029 goto not_likely;
8030 case OPC_BC1TANY4:
a16336e4 8031 {
d94536f4
AJ
8032 TCGv_i32 t1 = tcg_temp_new_i32();
8033 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8034 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8035 tcg_gen_or_i32(t0, t0, t1);
8036 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8037 tcg_gen_or_i32(t0, t0, t1);
8038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8039 tcg_gen_or_i32(t0, t0, t1);
8040 tcg_temp_free_i32(t1);
8041 tcg_gen_andi_i32(t0, t0, 1);
8042 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8043 }
fd4a04eb 8044 opn = "bc1any4t";
5a5012ec
TS
8045 not_likely:
8046 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8047 break;
8048 default:
923617a3 8049 MIPS_INVAL(opn);
e397ee33 8050 generate_exception (ctx, EXCP_RI);
6c5c1e20 8051 goto out;
6ea83fed 8052 }
2abf314d 8053 (void)opn; /* avoid a compiler warning */
923617a3 8054 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8055 ctx->hflags, btarget);
8056 ctx->btarget = btarget;
b231c103 8057 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8058 out:
a7812ae4 8059 tcg_temp_free_i32(t0);
6ea83fed
FB
8060}
8061
31837be3
YK
8062/* R6 CP1 Branches */
8063static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8064 int32_t ft, int32_t offset)
8065{
8066 target_ulong btarget;
8067 const char *opn = "cp1 cond branch";
8068 TCGv_i64 t0 = tcg_temp_new_i64();
8069
8070 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8071#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8072 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8073 "\n", ctx->pc);
31837be3
YK
8074#endif
8075 generate_exception(ctx, EXCP_RI);
8076 goto out;
8077 }
8078
8079 gen_load_fpr64(ctx, t0, ft);
8080 tcg_gen_andi_i64(t0, t0, 1);
8081
8082 btarget = addr_add(ctx, ctx->pc + 4, offset);
8083
8084 switch (op) {
8085 case OPC_BC1EQZ:
8086 tcg_gen_xori_i64(t0, t0, 1);
8087 opn = "bc1eqz";
8088 ctx->hflags |= MIPS_HFLAG_BC;
8089 break;
8090 case OPC_BC1NEZ:
8091 /* t0 already set */
8092 opn = "bc1nez";
8093 ctx->hflags |= MIPS_HFLAG_BC;
8094 break;
8095 default:
8096 MIPS_INVAL(opn);
8097 generate_exception(ctx, EXCP_RI);
8098 goto out;
8099 }
8100
8101 tcg_gen_trunc_i64_tl(bcond, t0);
8102
8103 (void)opn; /* avoid a compiler warning */
8104 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8105 ctx->hflags, btarget);
8106 ctx->btarget = btarget;
8107
8108out:
8109 tcg_temp_free_i64(t0);
8110}
8111
6af0bf9c 8112/* Coprocessor 1 (FPU) */
5a5012ec 8113
5a5012ec
TS
8114#define FOP(func, fmt) (((fmt) << 21) | (func))
8115
bf4120ad
NF
8116enum fopcode {
8117 OPC_ADD_S = FOP(0, FMT_S),
8118 OPC_SUB_S = FOP(1, FMT_S),
8119 OPC_MUL_S = FOP(2, FMT_S),
8120 OPC_DIV_S = FOP(3, FMT_S),
8121 OPC_SQRT_S = FOP(4, FMT_S),
8122 OPC_ABS_S = FOP(5, FMT_S),
8123 OPC_MOV_S = FOP(6, FMT_S),
8124 OPC_NEG_S = FOP(7, FMT_S),
8125 OPC_ROUND_L_S = FOP(8, FMT_S),
8126 OPC_TRUNC_L_S = FOP(9, FMT_S),
8127 OPC_CEIL_L_S = FOP(10, FMT_S),
8128 OPC_FLOOR_L_S = FOP(11, FMT_S),
8129 OPC_ROUND_W_S = FOP(12, FMT_S),
8130 OPC_TRUNC_W_S = FOP(13, FMT_S),
8131 OPC_CEIL_W_S = FOP(14, FMT_S),
8132 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8133 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8134 OPC_MOVCF_S = FOP(17, FMT_S),
8135 OPC_MOVZ_S = FOP(18, FMT_S),
8136 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8137 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8138 OPC_RECIP_S = FOP(21, FMT_S),
8139 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8140 OPC_SELNEZ_S = FOP(23, FMT_S),
8141 OPC_MADDF_S = FOP(24, FMT_S),
8142 OPC_MSUBF_S = FOP(25, FMT_S),
8143 OPC_RINT_S = FOP(26, FMT_S),
8144 OPC_CLASS_S = FOP(27, FMT_S),
8145 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8146 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8147 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8148 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8149 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8150 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8151 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8152 OPC_RSQRT2_S = FOP(31, FMT_S),
8153 OPC_CVT_D_S = FOP(33, FMT_S),
8154 OPC_CVT_W_S = FOP(36, FMT_S),
8155 OPC_CVT_L_S = FOP(37, FMT_S),
8156 OPC_CVT_PS_S = FOP(38, FMT_S),
8157 OPC_CMP_F_S = FOP (48, FMT_S),
8158 OPC_CMP_UN_S = FOP (49, FMT_S),
8159 OPC_CMP_EQ_S = FOP (50, FMT_S),
8160 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8161 OPC_CMP_OLT_S = FOP (52, FMT_S),
8162 OPC_CMP_ULT_S = FOP (53, FMT_S),
8163 OPC_CMP_OLE_S = FOP (54, FMT_S),
8164 OPC_CMP_ULE_S = FOP (55, FMT_S),
8165 OPC_CMP_SF_S = FOP (56, FMT_S),
8166 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8167 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8168 OPC_CMP_NGL_S = FOP (59, FMT_S),
8169 OPC_CMP_LT_S = FOP (60, FMT_S),
8170 OPC_CMP_NGE_S = FOP (61, FMT_S),
8171 OPC_CMP_LE_S = FOP (62, FMT_S),
8172 OPC_CMP_NGT_S = FOP (63, FMT_S),
8173
8174 OPC_ADD_D = FOP(0, FMT_D),
8175 OPC_SUB_D = FOP(1, FMT_D),
8176 OPC_MUL_D = FOP(2, FMT_D),
8177 OPC_DIV_D = FOP(3, FMT_D),
8178 OPC_SQRT_D = FOP(4, FMT_D),
8179 OPC_ABS_D = FOP(5, FMT_D),
8180 OPC_MOV_D = FOP(6, FMT_D),
8181 OPC_NEG_D = FOP(7, FMT_D),
8182 OPC_ROUND_L_D = FOP(8, FMT_D),
8183 OPC_TRUNC_L_D = FOP(9, FMT_D),
8184 OPC_CEIL_L_D = FOP(10, FMT_D),
8185 OPC_FLOOR_L_D = FOP(11, FMT_D),
8186 OPC_ROUND_W_D = FOP(12, FMT_D),
8187 OPC_TRUNC_W_D = FOP(13, FMT_D),
8188 OPC_CEIL_W_D = FOP(14, FMT_D),
8189 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8190 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8191 OPC_MOVCF_D = FOP(17, FMT_D),
8192 OPC_MOVZ_D = FOP(18, FMT_D),
8193 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8194 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8195 OPC_RECIP_D = FOP(21, FMT_D),
8196 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8197 OPC_SELNEZ_D = FOP(23, FMT_D),
8198 OPC_MADDF_D = FOP(24, FMT_D),
8199 OPC_MSUBF_D = FOP(25, FMT_D),
8200 OPC_RINT_D = FOP(26, FMT_D),
8201 OPC_CLASS_D = FOP(27, FMT_D),
8202 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8203 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8204 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8205 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8206 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8207 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8208 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8209 OPC_RSQRT2_D = FOP(31, FMT_D),
8210 OPC_CVT_S_D = FOP(32, FMT_D),
8211 OPC_CVT_W_D = FOP(36, FMT_D),
8212 OPC_CVT_L_D = FOP(37, FMT_D),
8213 OPC_CMP_F_D = FOP (48, FMT_D),
8214 OPC_CMP_UN_D = FOP (49, FMT_D),
8215 OPC_CMP_EQ_D = FOP (50, FMT_D),
8216 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8217 OPC_CMP_OLT_D = FOP (52, FMT_D),
8218 OPC_CMP_ULT_D = FOP (53, FMT_D),
8219 OPC_CMP_OLE_D = FOP (54, FMT_D),
8220 OPC_CMP_ULE_D = FOP (55, FMT_D),
8221 OPC_CMP_SF_D = FOP (56, FMT_D),
8222 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8223 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8224 OPC_CMP_NGL_D = FOP (59, FMT_D),
8225 OPC_CMP_LT_D = FOP (60, FMT_D),
8226 OPC_CMP_NGE_D = FOP (61, FMT_D),
8227 OPC_CMP_LE_D = FOP (62, FMT_D),
8228 OPC_CMP_NGT_D = FOP (63, FMT_D),
8229
8230 OPC_CVT_S_W = FOP(32, FMT_W),
8231 OPC_CVT_D_W = FOP(33, FMT_W),
8232 OPC_CVT_S_L = FOP(32, FMT_L),
8233 OPC_CVT_D_L = FOP(33, FMT_L),
8234 OPC_CVT_PS_PW = FOP(38, FMT_W),
8235
8236 OPC_ADD_PS = FOP(0, FMT_PS),
8237 OPC_SUB_PS = FOP(1, FMT_PS),
8238 OPC_MUL_PS = FOP(2, FMT_PS),
8239 OPC_DIV_PS = FOP(3, FMT_PS),
8240 OPC_ABS_PS = FOP(5, FMT_PS),
8241 OPC_MOV_PS = FOP(6, FMT_PS),
8242 OPC_NEG_PS = FOP(7, FMT_PS),
8243 OPC_MOVCF_PS = FOP(17, FMT_PS),
8244 OPC_MOVZ_PS = FOP(18, FMT_PS),
8245 OPC_MOVN_PS = FOP(19, FMT_PS),
8246 OPC_ADDR_PS = FOP(24, FMT_PS),
8247 OPC_MULR_PS = FOP(26, FMT_PS),
8248 OPC_RECIP2_PS = FOP(28, FMT_PS),
8249 OPC_RECIP1_PS = FOP(29, FMT_PS),
8250 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8251 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8252
8253 OPC_CVT_S_PU = FOP(32, FMT_PS),
8254 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8255 OPC_CVT_S_PL = FOP(40, FMT_PS),
8256 OPC_PLL_PS = FOP(44, FMT_PS),
8257 OPC_PLU_PS = FOP(45, FMT_PS),
8258 OPC_PUL_PS = FOP(46, FMT_PS),
8259 OPC_PUU_PS = FOP(47, FMT_PS),
8260 OPC_CMP_F_PS = FOP (48, FMT_PS),
8261 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8262 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8263 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8264 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8265 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8266 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8267 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8268 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8269 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8270 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8271 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8272 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8273 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8274 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8275 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8276};
8277
3f493883
YK
8278enum r6_f_cmp_op {
8279 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8280 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8281 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8282 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8283 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8284 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8285 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8286 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8287 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8288 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8289 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8290 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8291 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8292 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8293 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8294 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8295 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8296 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8297 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8298 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8299 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8300 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8301
8302 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8303 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8304 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8305 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8306 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8307 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8308 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8309 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8310 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8311 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8312 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8313 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8314 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8315 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8316 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8317 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8318 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8319 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8320 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8321 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8322 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8323 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8324};
7a387fff 8325static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8326{
923617a3 8327 const char *opn = "cp1 move";
72c3a3ee 8328 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8329
8330 switch (opc) {
8331 case OPC_MFC1:
b6d96bed 8332 {
a7812ae4 8333 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8334
8335 gen_load_fpr32(fp0, fs);
8336 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8337 tcg_temp_free_i32(fp0);
6958549d 8338 }
6c5c1e20 8339 gen_store_gpr(t0, rt);
6ea83fed
FB
8340 opn = "mfc1";
8341 break;
8342 case OPC_MTC1:
6c5c1e20 8343 gen_load_gpr(t0, rt);
b6d96bed 8344 {
a7812ae4 8345 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8346
8347 tcg_gen_trunc_tl_i32(fp0, t0);
8348 gen_store_fpr32(fp0, fs);
a7812ae4 8349 tcg_temp_free_i32(fp0);
6958549d 8350 }
6ea83fed
FB
8351 opn = "mtc1";
8352 break;
8353 case OPC_CFC1:
895c2d04 8354 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8355 gen_store_gpr(t0, rt);
6ea83fed
FB
8356 opn = "cfc1";
8357 break;
8358 case OPC_CTC1:
6c5c1e20 8359 gen_load_gpr(t0, rt);
4cf8a45f 8360 save_cpu_state(ctx, 1);
736d120a
PJ
8361 {
8362 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8363
8364 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8365 tcg_temp_free_i32(fs_tmp);
8366 }
4cf8a45f
YK
8367 /* Stop translation as we may have changed hflags */
8368 ctx->bstate = BS_STOP;
6ea83fed
FB
8369 opn = "ctc1";
8370 break;
72c3a3ee 8371#if defined(TARGET_MIPS64)
9c2149c8 8372 case OPC_DMFC1:
72c3a3ee 8373 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8374 gen_store_gpr(t0, rt);
5a5012ec
TS
8375 opn = "dmfc1";
8376 break;
9c2149c8 8377 case OPC_DMTC1:
6c5c1e20 8378 gen_load_gpr(t0, rt);
72c3a3ee 8379 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8380 opn = "dmtc1";
8381 break;
72c3a3ee 8382#endif
5a5012ec 8383 case OPC_MFHC1:
b6d96bed 8384 {
a7812ae4 8385 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8386
7f6613ce 8387 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8388 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8389 tcg_temp_free_i32(fp0);
6958549d 8390 }
6c5c1e20 8391 gen_store_gpr(t0, rt);
5a5012ec
TS
8392 opn = "mfhc1";
8393 break;
8394 case OPC_MTHC1:
6c5c1e20 8395 gen_load_gpr(t0, rt);
b6d96bed 8396 {
a7812ae4 8397 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8398
8399 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8400 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8401 tcg_temp_free_i32(fp0);
6958549d 8402 }
5a5012ec
TS
8403 opn = "mthc1";
8404 break;
6ea83fed 8405 default:
923617a3 8406 MIPS_INVAL(opn);
e397ee33 8407 generate_exception (ctx, EXCP_RI);
6c5c1e20 8408 goto out;
6ea83fed 8409 }
2abf314d 8410 (void)opn; /* avoid a compiler warning */
6ea83fed 8411 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8412
8413 out:
8414 tcg_temp_free(t0);
6ea83fed
FB
8415}
8416
5a5012ec
TS
8417static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8418{
af58f9ca 8419 int l1;
e214b9bb 8420 TCGCond cond;
af58f9ca
AJ
8421 TCGv_i32 t0;
8422
8423 if (rd == 0) {
8424 /* Treat as NOP. */
8425 return;
8426 }
6ea83fed 8427
e214b9bb 8428 if (tf)
e214b9bb 8429 cond = TCG_COND_EQ;
27848470
TS
8430 else
8431 cond = TCG_COND_NE;
8432
af58f9ca
AJ
8433 l1 = gen_new_label();
8434 t0 = tcg_temp_new_i32();
fa31af0e 8435 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8436 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8437 tcg_temp_free_i32(t0);
af58f9ca
AJ
8438 if (rs == 0) {
8439 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8440 } else {
8441 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8442 }
e214b9bb 8443 gen_set_label(l1);
5a5012ec
TS
8444}
8445
b6d96bed 8446static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8447{
a16336e4 8448 int cond;
cbc37b28 8449 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8450 int l1 = gen_new_label();
8451
a16336e4
TS
8452 if (tf)
8453 cond = TCG_COND_EQ;
8454 else
8455 cond = TCG_COND_NE;
8456
fa31af0e 8457 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8458 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8459 gen_load_fpr32(t0, fs);
8460 gen_store_fpr32(t0, fd);
a16336e4 8461 gen_set_label(l1);
cbc37b28 8462 tcg_temp_free_i32(t0);
5a5012ec 8463}
a16336e4 8464
b6d96bed 8465static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8466{
a16336e4 8467 int cond;
cbc37b28
AJ
8468 TCGv_i32 t0 = tcg_temp_new_i32();
8469 TCGv_i64 fp0;
a16336e4
TS
8470 int l1 = gen_new_label();
8471
a16336e4
TS
8472 if (tf)
8473 cond = TCG_COND_EQ;
8474 else
8475 cond = TCG_COND_NE;
8476
fa31af0e 8477 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8478 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8479 tcg_temp_free_i32(t0);
11f94258 8480 fp0 = tcg_temp_new_i64();
9bf3eb2c 8481 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8482 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8483 tcg_temp_free_i64(fp0);
cbc37b28 8484 gen_set_label(l1);
a16336e4
TS
8485}
8486
7f6613ce
PJ
8487static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8488 int cc, int tf)
a16336e4
TS
8489{
8490 int cond;
cbc37b28 8491 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8492 int l1 = gen_new_label();
8493 int l2 = gen_new_label();
8494
8495 if (tf)
8496 cond = TCG_COND_EQ;
8497 else
8498 cond = TCG_COND_NE;
8499
fa31af0e 8500 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8501 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8502 gen_load_fpr32(t0, fs);
8503 gen_store_fpr32(t0, fd);
a16336e4 8504 gen_set_label(l1);
9bf3eb2c 8505
fa31af0e 8506 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8507 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8508 gen_load_fpr32h(ctx, t0, fs);
8509 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8510 tcg_temp_free_i32(t0);
a16336e4 8511 gen_set_label(l2);
a16336e4
TS
8512}
8513
e7f16abb
LA
8514static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8515 int fs)
8516{
8517 TCGv_i32 t1 = tcg_const_i32(0);
8518 TCGv_i32 fp0 = tcg_temp_new_i32();
8519 TCGv_i32 fp1 = tcg_temp_new_i32();
8520 TCGv_i32 fp2 = tcg_temp_new_i32();
8521 gen_load_fpr32(fp0, fd);
8522 gen_load_fpr32(fp1, ft);
8523 gen_load_fpr32(fp2, fs);
8524
8525 switch (op1) {
8526 case OPC_SEL_S:
8527 tcg_gen_andi_i32(fp0, fp0, 1);
8528 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8529 break;
8530 case OPC_SELEQZ_S:
8531 tcg_gen_andi_i32(fp1, fp1, 1);
8532 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8533 break;
8534 case OPC_SELNEZ_S:
8535 tcg_gen_andi_i32(fp1, fp1, 1);
8536 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8537 break;
8538 default:
8539 MIPS_INVAL("gen_sel_s");
8540 generate_exception (ctx, EXCP_RI);
8541 break;
8542 }
8543
8544 gen_store_fpr32(fp0, fd);
8545 tcg_temp_free_i32(fp2);
8546 tcg_temp_free_i32(fp1);
8547 tcg_temp_free_i32(fp0);
8548 tcg_temp_free_i32(t1);
8549}
8550
8551static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8552 int fs)
8553{
8554 TCGv_i64 t1 = tcg_const_i64(0);
8555 TCGv_i64 fp0 = tcg_temp_new_i64();
8556 TCGv_i64 fp1 = tcg_temp_new_i64();
8557 TCGv_i64 fp2 = tcg_temp_new_i64();
8558 gen_load_fpr64(ctx, fp0, fd);
8559 gen_load_fpr64(ctx, fp1, ft);
8560 gen_load_fpr64(ctx, fp2, fs);
8561
8562 switch (op1) {
8563 case OPC_SEL_D:
8564 tcg_gen_andi_i64(fp0, fp0, 1);
8565 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8566 break;
8567 case OPC_SELEQZ_D:
8568 tcg_gen_andi_i64(fp1, fp1, 1);
8569 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8570 break;
8571 case OPC_SELNEZ_D:
8572 tcg_gen_andi_i64(fp1, fp1, 1);
8573 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8574 break;
8575 default:
8576 MIPS_INVAL("gen_sel_d");
8577 generate_exception (ctx, EXCP_RI);
8578 break;
8579 }
8580
8581 gen_store_fpr64(ctx, fp0, fd);
8582 tcg_temp_free_i64(fp2);
8583 tcg_temp_free_i64(fp1);
8584 tcg_temp_free_i64(fp0);
8585 tcg_temp_free_i64(t1);
8586}
6ea83fed 8587
bf4120ad 8588static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8589 int ft, int fs, int fd, int cc)
6ea83fed 8590{
923617a3 8591 const char *opn = "farith";
6ea83fed
FB
8592 const char *condnames[] = {
8593 "c.f",
8594 "c.un",
8595 "c.eq",
8596 "c.ueq",
8597 "c.olt",
8598 "c.ult",
8599 "c.ole",
8600 "c.ule",
8601 "c.sf",
8602 "c.ngle",
8603 "c.seq",
8604 "c.ngl",
8605 "c.lt",
8606 "c.nge",
8607 "c.le",
8608 "c.ngt",
8609 };
5a1e8ffb
TS
8610 const char *condnames_abs[] = {
8611 "cabs.f",
8612 "cabs.un",
8613 "cabs.eq",
8614 "cabs.ueq",
8615 "cabs.olt",
8616 "cabs.ult",
8617 "cabs.ole",
8618 "cabs.ule",
8619 "cabs.sf",
8620 "cabs.ngle",
8621 "cabs.seq",
8622 "cabs.ngl",
8623 "cabs.lt",
8624 "cabs.nge",
8625 "cabs.le",
8626 "cabs.ngt",
8627 };
8628 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8629 uint32_t func = ctx->opcode & 0x3f;
8630
bf4120ad
NF
8631 switch (op1) {
8632 case OPC_ADD_S:
b6d96bed 8633 {
a7812ae4
PB
8634 TCGv_i32 fp0 = tcg_temp_new_i32();
8635 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8636
8637 gen_load_fpr32(fp0, fs);
8638 gen_load_fpr32(fp1, ft);
895c2d04 8639 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8640 tcg_temp_free_i32(fp1);
b6d96bed 8641 gen_store_fpr32(fp0, fd);
a7812ae4 8642 tcg_temp_free_i32(fp0);
b6d96bed 8643 }
5a5012ec 8644 opn = "add.s";
5a1e8ffb 8645 optype = BINOP;
5a5012ec 8646 break;
bf4120ad 8647 case OPC_SUB_S:
b6d96bed 8648 {
a7812ae4
PB
8649 TCGv_i32 fp0 = tcg_temp_new_i32();
8650 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8651
8652 gen_load_fpr32(fp0, fs);
8653 gen_load_fpr32(fp1, ft);
895c2d04 8654 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8655 tcg_temp_free_i32(fp1);
b6d96bed 8656 gen_store_fpr32(fp0, fd);
a7812ae4 8657 tcg_temp_free_i32(fp0);
b6d96bed 8658 }
5a5012ec 8659 opn = "sub.s";
5a1e8ffb 8660 optype = BINOP;
5a5012ec 8661 break;
bf4120ad 8662 case OPC_MUL_S:
b6d96bed 8663 {
a7812ae4
PB
8664 TCGv_i32 fp0 = tcg_temp_new_i32();
8665 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8666
8667 gen_load_fpr32(fp0, fs);
8668 gen_load_fpr32(fp1, ft);
895c2d04 8669 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8670 tcg_temp_free_i32(fp1);
b6d96bed 8671 gen_store_fpr32(fp0, fd);
a7812ae4 8672 tcg_temp_free_i32(fp0);
b6d96bed 8673 }
5a5012ec 8674 opn = "mul.s";
5a1e8ffb 8675 optype = BINOP;
5a5012ec 8676 break;
bf4120ad 8677 case OPC_DIV_S:
b6d96bed 8678 {
a7812ae4
PB
8679 TCGv_i32 fp0 = tcg_temp_new_i32();
8680 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8681
8682 gen_load_fpr32(fp0, fs);
8683 gen_load_fpr32(fp1, ft);
895c2d04 8684 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8685 tcg_temp_free_i32(fp1);
b6d96bed 8686 gen_store_fpr32(fp0, fd);
a7812ae4 8687 tcg_temp_free_i32(fp0);
b6d96bed 8688 }
5a5012ec 8689 opn = "div.s";
5a1e8ffb 8690 optype = BINOP;
5a5012ec 8691 break;
bf4120ad 8692 case OPC_SQRT_S:
b6d96bed 8693 {
a7812ae4 8694 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8695
8696 gen_load_fpr32(fp0, fs);
895c2d04 8697 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8698 gen_store_fpr32(fp0, fd);
a7812ae4 8699 tcg_temp_free_i32(fp0);
b6d96bed 8700 }
5a5012ec
TS
8701 opn = "sqrt.s";
8702 break;
bf4120ad 8703 case OPC_ABS_S:
b6d96bed 8704 {
a7812ae4 8705 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8706
8707 gen_load_fpr32(fp0, fs);
a7812ae4 8708 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8709 gen_store_fpr32(fp0, fd);
a7812ae4 8710 tcg_temp_free_i32(fp0);
b6d96bed 8711 }
5a5012ec
TS
8712 opn = "abs.s";
8713 break;
bf4120ad 8714 case OPC_MOV_S:
b6d96bed 8715 {
a7812ae4 8716 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8717
8718 gen_load_fpr32(fp0, fs);
8719 gen_store_fpr32(fp0, fd);
a7812ae4 8720 tcg_temp_free_i32(fp0);
b6d96bed 8721 }
5a5012ec
TS
8722 opn = "mov.s";
8723 break;
bf4120ad 8724 case OPC_NEG_S:
b6d96bed 8725 {
a7812ae4 8726 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8727
8728 gen_load_fpr32(fp0, fs);
a7812ae4 8729 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8730 gen_store_fpr32(fp0, fd);
a7812ae4 8731 tcg_temp_free_i32(fp0);
b6d96bed 8732 }
5a5012ec
TS
8733 opn = "neg.s";
8734 break;
bf4120ad 8735 case OPC_ROUND_L_S:
5e755519 8736 check_cp1_64bitmode(ctx);
b6d96bed 8737 {
a7812ae4
PB
8738 TCGv_i32 fp32 = tcg_temp_new_i32();
8739 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8740
8741 gen_load_fpr32(fp32, fs);
895c2d04 8742 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8743 tcg_temp_free_i32(fp32);
b6d96bed 8744 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8745 tcg_temp_free_i64(fp64);
b6d96bed 8746 }
5a5012ec
TS
8747 opn = "round.l.s";
8748 break;
bf4120ad 8749 case OPC_TRUNC_L_S:
5e755519 8750 check_cp1_64bitmode(ctx);
b6d96bed 8751 {
a7812ae4
PB
8752 TCGv_i32 fp32 = tcg_temp_new_i32();
8753 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8754
8755 gen_load_fpr32(fp32, fs);
895c2d04 8756 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8757 tcg_temp_free_i32(fp32);
b6d96bed 8758 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8759 tcg_temp_free_i64(fp64);
b6d96bed 8760 }
5a5012ec
TS
8761 opn = "trunc.l.s";
8762 break;
bf4120ad 8763 case OPC_CEIL_L_S:
5e755519 8764 check_cp1_64bitmode(ctx);
b6d96bed 8765 {
a7812ae4
PB
8766 TCGv_i32 fp32 = tcg_temp_new_i32();
8767 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8768
8769 gen_load_fpr32(fp32, fs);
895c2d04 8770 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8771 tcg_temp_free_i32(fp32);
b6d96bed 8772 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8773 tcg_temp_free_i64(fp64);
b6d96bed 8774 }
5a5012ec
TS
8775 opn = "ceil.l.s";
8776 break;
bf4120ad 8777 case OPC_FLOOR_L_S:
5e755519 8778 check_cp1_64bitmode(ctx);
b6d96bed 8779 {
a7812ae4
PB
8780 TCGv_i32 fp32 = tcg_temp_new_i32();
8781 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8782
8783 gen_load_fpr32(fp32, fs);
895c2d04 8784 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8785 tcg_temp_free_i32(fp32);
b6d96bed 8786 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8787 tcg_temp_free_i64(fp64);
b6d96bed 8788 }
5a5012ec
TS
8789 opn = "floor.l.s";
8790 break;
bf4120ad 8791 case OPC_ROUND_W_S:
b6d96bed 8792 {
a7812ae4 8793 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8794
8795 gen_load_fpr32(fp0, fs);
895c2d04 8796 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8797 gen_store_fpr32(fp0, fd);
a7812ae4 8798 tcg_temp_free_i32(fp0);
b6d96bed 8799 }
5a5012ec
TS
8800 opn = "round.w.s";
8801 break;
bf4120ad 8802 case OPC_TRUNC_W_S:
b6d96bed 8803 {
a7812ae4 8804 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8805
8806 gen_load_fpr32(fp0, fs);
895c2d04 8807 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8808 gen_store_fpr32(fp0, fd);
a7812ae4 8809 tcg_temp_free_i32(fp0);
b6d96bed 8810 }
5a5012ec
TS
8811 opn = "trunc.w.s";
8812 break;
bf4120ad 8813 case OPC_CEIL_W_S:
b6d96bed 8814 {
a7812ae4 8815 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8816
8817 gen_load_fpr32(fp0, fs);
895c2d04 8818 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8819 gen_store_fpr32(fp0, fd);
a7812ae4 8820 tcg_temp_free_i32(fp0);
b6d96bed 8821 }
5a5012ec
TS
8822 opn = "ceil.w.s";
8823 break;
bf4120ad 8824 case OPC_FLOOR_W_S:
b6d96bed 8825 {
a7812ae4 8826 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8827
8828 gen_load_fpr32(fp0, fs);
895c2d04 8829 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8830 gen_store_fpr32(fp0, fd);
a7812ae4 8831 tcg_temp_free_i32(fp0);
b6d96bed 8832 }
5a5012ec
TS
8833 opn = "floor.w.s";
8834 break;
e7f16abb
LA
8835 case OPC_SEL_S:
8836 check_insn(ctx, ISA_MIPS32R6);
8837 gen_sel_s(ctx, op1, fd, ft, fs);
8838 opn = "sel.s";
8839 break;
8840 case OPC_SELEQZ_S:
8841 check_insn(ctx, ISA_MIPS32R6);
8842 gen_sel_s(ctx, op1, fd, ft, fs);
8843 opn = "seleqz.s";
8844 break;
8845 case OPC_SELNEZ_S:
8846 check_insn(ctx, ISA_MIPS32R6);
8847 gen_sel_s(ctx, op1, fd, ft, fs);
8848 opn = "selnez.s";
8849 break;
bf4120ad 8850 case OPC_MOVCF_S:
fecd2646 8851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8852 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8853 opn = "movcf.s";
8854 break;
bf4120ad 8855 case OPC_MOVZ_S:
fecd2646 8856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8857 {
8858 int l1 = gen_new_label();
c9297f4d 8859 TCGv_i32 fp0;
a16336e4 8860
c9297f4d
AJ
8861 if (ft != 0) {
8862 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8863 }
8864 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8865 gen_load_fpr32(fp0, fs);
8866 gen_store_fpr32(fp0, fd);
a7812ae4 8867 tcg_temp_free_i32(fp0);
a16336e4
TS
8868 gen_set_label(l1);
8869 }
5a5012ec
TS
8870 opn = "movz.s";
8871 break;
bf4120ad 8872 case OPC_MOVN_S:
fecd2646 8873 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8874 {
8875 int l1 = gen_new_label();
c9297f4d
AJ
8876 TCGv_i32 fp0;
8877
8878 if (ft != 0) {
8879 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8880 fp0 = tcg_temp_new_i32();
8881 gen_load_fpr32(fp0, fs);
8882 gen_store_fpr32(fp0, fd);
8883 tcg_temp_free_i32(fp0);
8884 gen_set_label(l1);
8885 }
a16336e4 8886 }
5a5012ec
TS
8887 opn = "movn.s";
8888 break;
bf4120ad 8889 case OPC_RECIP_S:
b8aa4598 8890 check_cop1x(ctx);
b6d96bed 8891 {
a7812ae4 8892 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8893
8894 gen_load_fpr32(fp0, fs);
895c2d04 8895 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8896 gen_store_fpr32(fp0, fd);
a7812ae4 8897 tcg_temp_free_i32(fp0);
b6d96bed 8898 }
57fa1fb3
TS
8899 opn = "recip.s";
8900 break;
bf4120ad 8901 case OPC_RSQRT_S:
b8aa4598 8902 check_cop1x(ctx);
b6d96bed 8903 {
a7812ae4 8904 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8905
8906 gen_load_fpr32(fp0, fs);
895c2d04 8907 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8908 gen_store_fpr32(fp0, fd);
a7812ae4 8909 tcg_temp_free_i32(fp0);
b6d96bed 8910 }
57fa1fb3
TS
8911 opn = "rsqrt.s";
8912 break;
e7f16abb
LA
8913 case OPC_MADDF_S:
8914 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8915 {
a7812ae4
PB
8916 TCGv_i32 fp0 = tcg_temp_new_i32();
8917 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8918 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8919 gen_load_fpr32(fp0, fs);
d22d7289 8920 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8921 gen_load_fpr32(fp2, fd);
8922 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8923 gen_store_fpr32(fp2, fd);
8924 tcg_temp_free_i32(fp2);
a7812ae4 8925 tcg_temp_free_i32(fp1);
a7812ae4 8926 tcg_temp_free_i32(fp0);
e7f16abb 8927 opn = "maddf.s";
b6d96bed 8928 }
57fa1fb3 8929 break;
e7f16abb
LA
8930 case OPC_MSUBF_S:
8931 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8932 {
a7812ae4 8933 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8934 TCGv_i32 fp1 = tcg_temp_new_i32();
8935 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8936 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8937 gen_load_fpr32(fp1, ft);
8938 gen_load_fpr32(fp2, fd);
8939 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8940 gen_store_fpr32(fp2, fd);
8941 tcg_temp_free_i32(fp2);
8942 tcg_temp_free_i32(fp1);
a7812ae4 8943 tcg_temp_free_i32(fp0);
e7f16abb 8944 opn = "msubf.s";
b6d96bed 8945 }
57fa1fb3 8946 break;
e7f16abb
LA
8947 case OPC_RINT_S:
8948 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8949 {
a7812ae4 8950 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8951 gen_load_fpr32(fp0, fs);
e7f16abb 8952 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8953 gen_store_fpr32(fp0, fd);
a7812ae4 8954 tcg_temp_free_i32(fp0);
e7f16abb 8955 opn = "rint.s";
b6d96bed 8956 }
57fa1fb3 8957 break;
e7f16abb
LA
8958 case OPC_CLASS_S:
8959 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8960 {
e7f16abb
LA
8961 TCGv_i32 fp0 = tcg_temp_new_i32();
8962 gen_load_fpr32(fp0, fs);
8963 gen_helper_float_class_s(fp0, fp0);
8964 gen_store_fpr32(fp0, fd);
8965 tcg_temp_free_i32(fp0);
8966 opn = "class.s";
8967 }
8968 break;
8969 case OPC_MIN_S: /* OPC_RECIP2_S */
8970 if (ctx->insn_flags & ISA_MIPS32R6) {
8971 /* OPC_MIN_S */
a7812ae4
PB
8972 TCGv_i32 fp0 = tcg_temp_new_i32();
8973 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8974 TCGv_i32 fp2 = tcg_temp_new_i32();
8975 gen_load_fpr32(fp0, fs);
8976 gen_load_fpr32(fp1, ft);
8977 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8978 gen_store_fpr32(fp2, fd);
8979 tcg_temp_free_i32(fp2);
8980 tcg_temp_free_i32(fp1);
8981 tcg_temp_free_i32(fp0);
8982 opn = "min.s";
8983 } else {
8984 /* OPC_RECIP2_S */
8985 check_cp1_64bitmode(ctx);
8986 {
8987 TCGv_i32 fp0 = tcg_temp_new_i32();
8988 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8989
e7f16abb
LA
8990 gen_load_fpr32(fp0, fs);
8991 gen_load_fpr32(fp1, ft);
8992 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8993 tcg_temp_free_i32(fp1);
8994 gen_store_fpr32(fp0, fd);
8995 tcg_temp_free_i32(fp0);
8996 }
8997 opn = "recip2.s";
8998 }
8999 break;
9000 case OPC_MINA_S: /* OPC_RECIP1_S */
9001 if (ctx->insn_flags & ISA_MIPS32R6) {
9002 /* OPC_MINA_S */
9003 TCGv_i32 fp0 = tcg_temp_new_i32();
9004 TCGv_i32 fp1 = tcg_temp_new_i32();
9005 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9006 gen_load_fpr32(fp0, fs);
9007 gen_load_fpr32(fp1, ft);
e7f16abb
LA
9008 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9009 gen_store_fpr32(fp2, fd);
9010 tcg_temp_free_i32(fp2);
9011 tcg_temp_free_i32(fp1);
9012 tcg_temp_free_i32(fp0);
9013 opn = "mina.s";
9014 } else {
9015 /* OPC_RECIP1_S */
9016 check_cp1_64bitmode(ctx);
9017 {
9018 TCGv_i32 fp0 = tcg_temp_new_i32();
9019
9020 gen_load_fpr32(fp0, fs);
9021 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9022 gen_store_fpr32(fp0, fd);
9023 tcg_temp_free_i32(fp0);
9024 }
9025 opn = "recip1.s";
9026 }
9027 break;
9028 case OPC_MAX_S: /* OPC_RSQRT1_S */
9029 if (ctx->insn_flags & ISA_MIPS32R6) {
9030 /* OPC_MAX_S */
9031 TCGv_i32 fp0 = tcg_temp_new_i32();
9032 TCGv_i32 fp1 = tcg_temp_new_i32();
9033 gen_load_fpr32(fp0, fs);
9034 gen_load_fpr32(fp1, ft);
9035 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9036 gen_store_fpr32(fp1, fd);
9037 tcg_temp_free_i32(fp1);
9038 tcg_temp_free_i32(fp0);
9039 opn = "max.s";
9040 } else {
9041 /* OPC_RSQRT1_S */
9042 check_cp1_64bitmode(ctx);
9043 {
9044 TCGv_i32 fp0 = tcg_temp_new_i32();
9045
9046 gen_load_fpr32(fp0, fs);
9047 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9048 gen_store_fpr32(fp0, fd);
9049 tcg_temp_free_i32(fp0);
9050 }
9051 opn = "rsqrt1.s";
9052 }
9053 break;
9054 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9055 if (ctx->insn_flags & ISA_MIPS32R6) {
9056 /* OPC_MAXA_S */
9057 TCGv_i32 fp0 = tcg_temp_new_i32();
9058 TCGv_i32 fp1 = tcg_temp_new_i32();
9059 gen_load_fpr32(fp0, fs);
9060 gen_load_fpr32(fp1, ft);
9061 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9062 gen_store_fpr32(fp1, fd);
a7812ae4 9063 tcg_temp_free_i32(fp1);
a7812ae4 9064 tcg_temp_free_i32(fp0);
e7f16abb
LA
9065 opn = "maxa.s";
9066 } else {
9067 /* OPC_RSQRT2_S */
9068 check_cp1_64bitmode(ctx);
9069 {
9070 TCGv_i32 fp0 = tcg_temp_new_i32();
9071 TCGv_i32 fp1 = tcg_temp_new_i32();
9072
9073 gen_load_fpr32(fp0, fs);
9074 gen_load_fpr32(fp1, ft);
9075 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9076 tcg_temp_free_i32(fp1);
9077 gen_store_fpr32(fp0, fd);
9078 tcg_temp_free_i32(fp0);
9079 }
9080 opn = "rsqrt2.s";
b6d96bed 9081 }
57fa1fb3 9082 break;
bf4120ad 9083 case OPC_CVT_D_S:
5e755519 9084 check_cp1_registers(ctx, fd);
b6d96bed 9085 {
a7812ae4
PB
9086 TCGv_i32 fp32 = tcg_temp_new_i32();
9087 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9088
9089 gen_load_fpr32(fp32, fs);
895c2d04 9090 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9091 tcg_temp_free_i32(fp32);
b6d96bed 9092 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9093 tcg_temp_free_i64(fp64);
b6d96bed 9094 }
5a5012ec
TS
9095 opn = "cvt.d.s";
9096 break;
bf4120ad 9097 case OPC_CVT_W_S:
b6d96bed 9098 {
a7812ae4 9099 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9100
9101 gen_load_fpr32(fp0, fs);
895c2d04 9102 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 9103 gen_store_fpr32(fp0, fd);
a7812ae4 9104 tcg_temp_free_i32(fp0);
b6d96bed 9105 }
5a5012ec
TS
9106 opn = "cvt.w.s";
9107 break;
bf4120ad 9108 case OPC_CVT_L_S:
5e755519 9109 check_cp1_64bitmode(ctx);
b6d96bed 9110 {
a7812ae4
PB
9111 TCGv_i32 fp32 = tcg_temp_new_i32();
9112 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9113
9114 gen_load_fpr32(fp32, fs);
895c2d04 9115 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9116 tcg_temp_free_i32(fp32);
b6d96bed 9117 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9118 tcg_temp_free_i64(fp64);
b6d96bed 9119 }
5a5012ec
TS
9120 opn = "cvt.l.s";
9121 break;
bf4120ad 9122 case OPC_CVT_PS_S:
fecd2646 9123 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9124 check_cp1_64bitmode(ctx);
b6d96bed 9125 {
a7812ae4
PB
9126 TCGv_i64 fp64 = tcg_temp_new_i64();
9127 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9128 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
9129
9130 gen_load_fpr32(fp32_0, fs);
9131 gen_load_fpr32(fp32_1, ft);
13d24f49 9132 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9133 tcg_temp_free_i32(fp32_1);
9134 tcg_temp_free_i32(fp32_0);
36aa55dc 9135 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9136 tcg_temp_free_i64(fp64);
b6d96bed 9137 }
5a5012ec
TS
9138 opn = "cvt.ps.s";
9139 break;
bf4120ad
NF
9140 case OPC_CMP_F_S:
9141 case OPC_CMP_UN_S:
9142 case OPC_CMP_EQ_S:
9143 case OPC_CMP_UEQ_S:
9144 case OPC_CMP_OLT_S:
9145 case OPC_CMP_ULT_S:
9146 case OPC_CMP_OLE_S:
9147 case OPC_CMP_ULE_S:
9148 case OPC_CMP_SF_S:
9149 case OPC_CMP_NGLE_S:
9150 case OPC_CMP_SEQ_S:
9151 case OPC_CMP_NGL_S:
9152 case OPC_CMP_LT_S:
9153 case OPC_CMP_NGE_S:
9154 case OPC_CMP_LE_S:
9155 case OPC_CMP_NGT_S:
fecd2646 9156 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9157 if (ctx->opcode & (1 << 6)) {
9158 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9159 opn = condnames_abs[func-48];
9160 } else {
9161 gen_cmp_s(ctx, func-48, ft, fs, cc);
9162 opn = condnames[func-48];
5a1e8ffb 9163 }
5a5012ec 9164 break;
bf4120ad 9165 case OPC_ADD_D:
5e755519 9166 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9167 {
a7812ae4
PB
9168 TCGv_i64 fp0 = tcg_temp_new_i64();
9169 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9170
9171 gen_load_fpr64(ctx, fp0, fs);
9172 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9173 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9174 tcg_temp_free_i64(fp1);
b6d96bed 9175 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9176 tcg_temp_free_i64(fp0);
b6d96bed 9177 }
6ea83fed 9178 opn = "add.d";
5a1e8ffb 9179 optype = BINOP;
6ea83fed 9180 break;
bf4120ad 9181 case OPC_SUB_D:
5e755519 9182 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9183 {
a7812ae4
PB
9184 TCGv_i64 fp0 = tcg_temp_new_i64();
9185 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9186
9187 gen_load_fpr64(ctx, fp0, fs);
9188 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9189 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9190 tcg_temp_free_i64(fp1);
b6d96bed 9191 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9192 tcg_temp_free_i64(fp0);
b6d96bed 9193 }
6ea83fed 9194 opn = "sub.d";
5a1e8ffb 9195 optype = BINOP;
6ea83fed 9196 break;
bf4120ad 9197 case OPC_MUL_D:
5e755519 9198 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9199 {
a7812ae4
PB
9200 TCGv_i64 fp0 = tcg_temp_new_i64();
9201 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9202
9203 gen_load_fpr64(ctx, fp0, fs);
9204 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9205 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9206 tcg_temp_free_i64(fp1);
b6d96bed 9207 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9208 tcg_temp_free_i64(fp0);
b6d96bed 9209 }
6ea83fed 9210 opn = "mul.d";
5a1e8ffb 9211 optype = BINOP;
6ea83fed 9212 break;
bf4120ad 9213 case OPC_DIV_D:
5e755519 9214 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9215 {
a7812ae4
PB
9216 TCGv_i64 fp0 = tcg_temp_new_i64();
9217 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9218
9219 gen_load_fpr64(ctx, fp0, fs);
9220 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9221 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9222 tcg_temp_free_i64(fp1);
b6d96bed 9223 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9224 tcg_temp_free_i64(fp0);
b6d96bed 9225 }
6ea83fed 9226 opn = "div.d";
5a1e8ffb 9227 optype = BINOP;
6ea83fed 9228 break;
bf4120ad 9229 case OPC_SQRT_D:
5e755519 9230 check_cp1_registers(ctx, fs | fd);
b6d96bed 9231 {
a7812ae4 9232 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9233
9234 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9235 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9236 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9237 tcg_temp_free_i64(fp0);
b6d96bed 9238 }
6ea83fed
FB
9239 opn = "sqrt.d";
9240 break;
bf4120ad 9241 case OPC_ABS_D:
5e755519 9242 check_cp1_registers(ctx, fs | fd);
b6d96bed 9243 {
a7812ae4 9244 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9245
9246 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9247 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9248 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9249 tcg_temp_free_i64(fp0);
b6d96bed 9250 }
6ea83fed
FB
9251 opn = "abs.d";
9252 break;
bf4120ad 9253 case OPC_MOV_D:
5e755519 9254 check_cp1_registers(ctx, fs | fd);
b6d96bed 9255 {
a7812ae4 9256 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9257
9258 gen_load_fpr64(ctx, fp0, fs);
9259 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9260 tcg_temp_free_i64(fp0);
b6d96bed 9261 }
6ea83fed
FB
9262 opn = "mov.d";
9263 break;
bf4120ad 9264 case OPC_NEG_D:
5e755519 9265 check_cp1_registers(ctx, fs | fd);
b6d96bed 9266 {
a7812ae4 9267 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9268
9269 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9270 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9271 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9272 tcg_temp_free_i64(fp0);
b6d96bed 9273 }
6ea83fed
FB
9274 opn = "neg.d";
9275 break;
bf4120ad 9276 case OPC_ROUND_L_D:
5e755519 9277 check_cp1_64bitmode(ctx);
b6d96bed 9278 {
a7812ae4 9279 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9280
9281 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9282 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9283 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9284 tcg_temp_free_i64(fp0);
b6d96bed 9285 }
5a5012ec
TS
9286 opn = "round.l.d";
9287 break;
bf4120ad 9288 case OPC_TRUNC_L_D:
5e755519 9289 check_cp1_64bitmode(ctx);
b6d96bed 9290 {
a7812ae4 9291 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9292
9293 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9294 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9295 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9296 tcg_temp_free_i64(fp0);
b6d96bed 9297 }
5a5012ec
TS
9298 opn = "trunc.l.d";
9299 break;
bf4120ad 9300 case OPC_CEIL_L_D:
5e755519 9301 check_cp1_64bitmode(ctx);
b6d96bed 9302 {
a7812ae4 9303 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9304
9305 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9306 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9307 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i64(fp0);
b6d96bed 9309 }
5a5012ec
TS
9310 opn = "ceil.l.d";
9311 break;
bf4120ad 9312 case OPC_FLOOR_L_D:
5e755519 9313 check_cp1_64bitmode(ctx);
b6d96bed 9314 {
a7812ae4 9315 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9316
9317 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9318 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9319 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9320 tcg_temp_free_i64(fp0);
b6d96bed 9321 }
5a5012ec
TS
9322 opn = "floor.l.d";
9323 break;
bf4120ad 9324 case OPC_ROUND_W_D:
5e755519 9325 check_cp1_registers(ctx, fs);
b6d96bed 9326 {
a7812ae4
PB
9327 TCGv_i32 fp32 = tcg_temp_new_i32();
9328 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9329
9330 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9331 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9332 tcg_temp_free_i64(fp64);
b6d96bed 9333 gen_store_fpr32(fp32, fd);
a7812ae4 9334 tcg_temp_free_i32(fp32);
b6d96bed 9335 }
6ea83fed
FB
9336 opn = "round.w.d";
9337 break;
bf4120ad 9338 case OPC_TRUNC_W_D:
5e755519 9339 check_cp1_registers(ctx, fs);
b6d96bed 9340 {
a7812ae4
PB
9341 TCGv_i32 fp32 = tcg_temp_new_i32();
9342 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9343
9344 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9345 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9346 tcg_temp_free_i64(fp64);
b6d96bed 9347 gen_store_fpr32(fp32, fd);
a7812ae4 9348 tcg_temp_free_i32(fp32);
b6d96bed 9349 }
6ea83fed
FB
9350 opn = "trunc.w.d";
9351 break;
bf4120ad 9352 case OPC_CEIL_W_D:
5e755519 9353 check_cp1_registers(ctx, fs);
b6d96bed 9354 {
a7812ae4
PB
9355 TCGv_i32 fp32 = tcg_temp_new_i32();
9356 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9357
9358 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9359 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9360 tcg_temp_free_i64(fp64);
b6d96bed 9361 gen_store_fpr32(fp32, fd);
a7812ae4 9362 tcg_temp_free_i32(fp32);
b6d96bed 9363 }
6ea83fed
FB
9364 opn = "ceil.w.d";
9365 break;
bf4120ad 9366 case OPC_FLOOR_W_D:
5e755519 9367 check_cp1_registers(ctx, fs);
b6d96bed 9368 {
a7812ae4
PB
9369 TCGv_i32 fp32 = tcg_temp_new_i32();
9370 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9371
9372 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9373 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9374 tcg_temp_free_i64(fp64);
b6d96bed 9375 gen_store_fpr32(fp32, fd);
a7812ae4 9376 tcg_temp_free_i32(fp32);
b6d96bed 9377 }
7a387fff 9378 opn = "floor.w.d";
6ea83fed 9379 break;
e7f16abb
LA
9380 case OPC_SEL_D:
9381 check_insn(ctx, ISA_MIPS32R6);
9382 gen_sel_d(ctx, op1, fd, ft, fs);
9383 opn = "sel.d";
9384 break;
9385 case OPC_SELEQZ_D:
9386 check_insn(ctx, ISA_MIPS32R6);
9387 gen_sel_d(ctx, op1, fd, ft, fs);
9388 opn = "seleqz.d";
9389 break;
9390 case OPC_SELNEZ_D:
9391 check_insn(ctx, ISA_MIPS32R6);
9392 gen_sel_d(ctx, op1, fd, ft, fs);
9393 opn = "selnez.d";
9394 break;
bf4120ad 9395 case OPC_MOVCF_D:
fecd2646 9396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9397 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9398 opn = "movcf.d";
dd016883 9399 break;
bf4120ad 9400 case OPC_MOVZ_D:
fecd2646 9401 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9402 {
9403 int l1 = gen_new_label();
c9297f4d 9404 TCGv_i64 fp0;
a16336e4 9405
c9297f4d
AJ
9406 if (ft != 0) {
9407 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9408 }
9409 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9410 gen_load_fpr64(ctx, fp0, fs);
9411 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9412 tcg_temp_free_i64(fp0);
a16336e4
TS
9413 gen_set_label(l1);
9414 }
5a5012ec
TS
9415 opn = "movz.d";
9416 break;
bf4120ad 9417 case OPC_MOVN_D:
fecd2646 9418 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9419 {
9420 int l1 = gen_new_label();
c9297f4d
AJ
9421 TCGv_i64 fp0;
9422
9423 if (ft != 0) {
9424 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9425 fp0 = tcg_temp_new_i64();
9426 gen_load_fpr64(ctx, fp0, fs);
9427 gen_store_fpr64(ctx, fp0, fd);
9428 tcg_temp_free_i64(fp0);
9429 gen_set_label(l1);
9430 }
a16336e4 9431 }
5a5012ec 9432 opn = "movn.d";
6ea83fed 9433 break;
bf4120ad 9434 case OPC_RECIP_D:
b8aa4598 9435 check_cp1_64bitmode(ctx);
b6d96bed 9436 {
a7812ae4 9437 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9438
9439 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9440 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9441 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9442 tcg_temp_free_i64(fp0);
b6d96bed 9443 }
57fa1fb3
TS
9444 opn = "recip.d";
9445 break;
bf4120ad 9446 case OPC_RSQRT_D:
b8aa4598 9447 check_cp1_64bitmode(ctx);
b6d96bed 9448 {
a7812ae4 9449 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9450
9451 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9452 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9453 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9454 tcg_temp_free_i64(fp0);
b6d96bed 9455 }
57fa1fb3
TS
9456 opn = "rsqrt.d";
9457 break;
e7f16abb
LA
9458 case OPC_MADDF_D:
9459 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9460 {
a7812ae4
PB
9461 TCGv_i64 fp0 = tcg_temp_new_i64();
9462 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9463 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9464 gen_load_fpr64(ctx, fp0, fs);
9465 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9466 gen_load_fpr64(ctx, fp2, fd);
9467 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9468 gen_store_fpr64(ctx, fp2, fd);
9469 tcg_temp_free_i64(fp2);
a7812ae4 9470 tcg_temp_free_i64(fp1);
a7812ae4 9471 tcg_temp_free_i64(fp0);
e7f16abb 9472 opn = "maddf.d";
b6d96bed 9473 }
57fa1fb3 9474 break;
e7f16abb
LA
9475 case OPC_MSUBF_D:
9476 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9477 {
a7812ae4 9478 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9479 TCGv_i64 fp1 = tcg_temp_new_i64();
9480 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9481 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9482 gen_load_fpr64(ctx, fp1, ft);
9483 gen_load_fpr64(ctx, fp2, fd);
9484 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9485 gen_store_fpr64(ctx, fp2, fd);
9486 tcg_temp_free_i64(fp2);
9487 tcg_temp_free_i64(fp1);
a7812ae4 9488 tcg_temp_free_i64(fp0);
e7f16abb 9489 opn = "msubf.d";
b6d96bed 9490 }
57fa1fb3 9491 break;
e7f16abb
LA
9492 case OPC_RINT_D:
9493 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9494 {
a7812ae4 9495 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9496 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9497 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9498 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9499 tcg_temp_free_i64(fp0);
e7f16abb 9500 opn = "rint.d";
b6d96bed 9501 }
57fa1fb3 9502 break;
e7f16abb
LA
9503 case OPC_CLASS_D:
9504 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9505 {
e7f16abb
LA
9506 TCGv_i64 fp0 = tcg_temp_new_i64();
9507 gen_load_fpr64(ctx, fp0, fs);
9508 gen_helper_float_class_d(fp0, fp0);
9509 gen_store_fpr64(ctx, fp0, fd);
9510 tcg_temp_free_i64(fp0);
9511 opn = "class.d";
9512 }
9513 break;
9514 case OPC_MIN_D: /* OPC_RECIP2_D */
9515 if (ctx->insn_flags & ISA_MIPS32R6) {
9516 /* OPC_MIN_D */
a7812ae4
PB
9517 TCGv_i64 fp0 = tcg_temp_new_i64();
9518 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9519 gen_load_fpr64(ctx, fp0, fs);
9520 gen_load_fpr64(ctx, fp1, ft);
9521 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9522 gen_store_fpr64(ctx, fp1, fd);
9523 tcg_temp_free_i64(fp1);
9524 tcg_temp_free_i64(fp0);
9525 opn = "min.d";
9526 } else {
9527 /* OPC_RECIP2_D */
9528 check_cp1_64bitmode(ctx);
9529 {
9530 TCGv_i64 fp0 = tcg_temp_new_i64();
9531 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9532
e7f16abb
LA
9533 gen_load_fpr64(ctx, fp0, fs);
9534 gen_load_fpr64(ctx, fp1, ft);
9535 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9536 tcg_temp_free_i64(fp1);
9537 gen_store_fpr64(ctx, fp0, fd);
9538 tcg_temp_free_i64(fp0);
9539 }
9540 opn = "recip2.d";
9541 }
9542 break;
9543 case OPC_MINA_D: /* OPC_RECIP1_D */
9544 if (ctx->insn_flags & ISA_MIPS32R6) {
9545 /* OPC_MINA_D */
9546 TCGv_i64 fp0 = tcg_temp_new_i64();
9547 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9548 gen_load_fpr64(ctx, fp0, fs);
9549 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9550 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9551 gen_store_fpr64(ctx, fp1, fd);
9552 tcg_temp_free_i64(fp1);
9553 tcg_temp_free_i64(fp0);
9554 opn = "mina.d";
9555 } else {
9556 /* OPC_RECIP1_D */
9557 check_cp1_64bitmode(ctx);
9558 {
9559 TCGv_i64 fp0 = tcg_temp_new_i64();
9560
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9563 gen_store_fpr64(ctx, fp0, fd);
9564 tcg_temp_free_i64(fp0);
9565 }
9566 opn = "recip1.d";
9567 }
9568 break;
9569 case OPC_MAX_D: /* OPC_RSQRT1_D */
9570 if (ctx->insn_flags & ISA_MIPS32R6) {
9571 /* OPC_MAX_D */
9572 TCGv_i64 fp0 = tcg_temp_new_i64();
9573 TCGv_i64 fp1 = tcg_temp_new_i64();
9574 gen_load_fpr64(ctx, fp0, fs);
9575 gen_load_fpr64(ctx, fp1, ft);
9576 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9577 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9578 tcg_temp_free_i64(fp1);
a7812ae4 9579 tcg_temp_free_i64(fp0);
e7f16abb
LA
9580 opn = "max.d";
9581 } else {
9582 /* OPC_RSQRT1_D */
9583 check_cp1_64bitmode(ctx);
9584 {
9585 TCGv_i64 fp0 = tcg_temp_new_i64();
9586
9587 gen_load_fpr64(ctx, fp0, fs);
9588 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9589 gen_store_fpr64(ctx, fp0, fd);
9590 tcg_temp_free_i64(fp0);
9591 }
9592 opn = "rsqrt1.d";
9593 }
9594 break;
9595 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9596 if (ctx->insn_flags & ISA_MIPS32R6) {
9597 /* OPC_MAXA_D */
9598 TCGv_i64 fp0 = tcg_temp_new_i64();
9599 TCGv_i64 fp1 = tcg_temp_new_i64();
9600 gen_load_fpr64(ctx, fp0, fs);
9601 gen_load_fpr64(ctx, fp1, ft);
9602 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9603 gen_store_fpr64(ctx, fp1, fd);
9604 tcg_temp_free_i64(fp1);
9605 tcg_temp_free_i64(fp0);
9606 opn = "maxa.d";
9607 } else {
9608 /* OPC_RSQRT2_D */
9609 check_cp1_64bitmode(ctx);
9610 {
9611 TCGv_i64 fp0 = tcg_temp_new_i64();
9612 TCGv_i64 fp1 = tcg_temp_new_i64();
9613
9614 gen_load_fpr64(ctx, fp0, fs);
9615 gen_load_fpr64(ctx, fp1, ft);
9616 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9617 tcg_temp_free_i64(fp1);
9618 gen_store_fpr64(ctx, fp0, fd);
9619 tcg_temp_free_i64(fp0);
9620 }
9621 opn = "rsqrt2.d";
b6d96bed 9622 }
57fa1fb3 9623 break;
bf4120ad
NF
9624 case OPC_CMP_F_D:
9625 case OPC_CMP_UN_D:
9626 case OPC_CMP_EQ_D:
9627 case OPC_CMP_UEQ_D:
9628 case OPC_CMP_OLT_D:
9629 case OPC_CMP_ULT_D:
9630 case OPC_CMP_OLE_D:
9631 case OPC_CMP_ULE_D:
9632 case OPC_CMP_SF_D:
9633 case OPC_CMP_NGLE_D:
9634 case OPC_CMP_SEQ_D:
9635 case OPC_CMP_NGL_D:
9636 case OPC_CMP_LT_D:
9637 case OPC_CMP_NGE_D:
9638 case OPC_CMP_LE_D:
9639 case OPC_CMP_NGT_D:
fecd2646 9640 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9641 if (ctx->opcode & (1 << 6)) {
9642 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9643 opn = condnames_abs[func-48];
9644 } else {
9645 gen_cmp_d(ctx, func-48, ft, fs, cc);
9646 opn = condnames[func-48];
5a1e8ffb 9647 }
6ea83fed 9648 break;
bf4120ad 9649 case OPC_CVT_S_D:
5e755519 9650 check_cp1_registers(ctx, fs);
b6d96bed 9651 {
a7812ae4
PB
9652 TCGv_i32 fp32 = tcg_temp_new_i32();
9653 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9654
9655 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9656 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9657 tcg_temp_free_i64(fp64);
b6d96bed 9658 gen_store_fpr32(fp32, fd);
a7812ae4 9659 tcg_temp_free_i32(fp32);
b6d96bed 9660 }
5a5012ec
TS
9661 opn = "cvt.s.d";
9662 break;
bf4120ad 9663 case OPC_CVT_W_D:
5e755519 9664 check_cp1_registers(ctx, fs);
b6d96bed 9665 {
a7812ae4
PB
9666 TCGv_i32 fp32 = tcg_temp_new_i32();
9667 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9668
9669 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9670 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9671 tcg_temp_free_i64(fp64);
b6d96bed 9672 gen_store_fpr32(fp32, fd);
a7812ae4 9673 tcg_temp_free_i32(fp32);
b6d96bed 9674 }
5a5012ec
TS
9675 opn = "cvt.w.d";
9676 break;
bf4120ad 9677 case OPC_CVT_L_D:
5e755519 9678 check_cp1_64bitmode(ctx);
b6d96bed 9679 {
a7812ae4 9680 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9681
9682 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9683 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9684 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9685 tcg_temp_free_i64(fp0);
b6d96bed 9686 }
5a5012ec
TS
9687 opn = "cvt.l.d";
9688 break;
bf4120ad 9689 case OPC_CVT_S_W:
b6d96bed 9690 {
a7812ae4 9691 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9692
9693 gen_load_fpr32(fp0, fs);
895c2d04 9694 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9695 gen_store_fpr32(fp0, fd);
a7812ae4 9696 tcg_temp_free_i32(fp0);
b6d96bed 9697 }
5a5012ec 9698 opn = "cvt.s.w";
6ea83fed 9699 break;
bf4120ad 9700 case OPC_CVT_D_W:
5e755519 9701 check_cp1_registers(ctx, fd);
b6d96bed 9702 {
a7812ae4
PB
9703 TCGv_i32 fp32 = tcg_temp_new_i32();
9704 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9705
9706 gen_load_fpr32(fp32, fs);
895c2d04 9707 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9708 tcg_temp_free_i32(fp32);
b6d96bed 9709 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9710 tcg_temp_free_i64(fp64);
b6d96bed 9711 }
5a5012ec
TS
9712 opn = "cvt.d.w";
9713 break;
bf4120ad 9714 case OPC_CVT_S_L:
5e755519 9715 check_cp1_64bitmode(ctx);
b6d96bed 9716 {
a7812ae4
PB
9717 TCGv_i32 fp32 = tcg_temp_new_i32();
9718 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9719
9720 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9721 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9722 tcg_temp_free_i64(fp64);
b6d96bed 9723 gen_store_fpr32(fp32, fd);
a7812ae4 9724 tcg_temp_free_i32(fp32);
b6d96bed 9725 }
5a5012ec
TS
9726 opn = "cvt.s.l";
9727 break;
bf4120ad 9728 case OPC_CVT_D_L:
5e755519 9729 check_cp1_64bitmode(ctx);
b6d96bed 9730 {
a7812ae4 9731 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9732
9733 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9734 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9735 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9736 tcg_temp_free_i64(fp0);
b6d96bed 9737 }
5a5012ec
TS
9738 opn = "cvt.d.l";
9739 break;
bf4120ad 9740 case OPC_CVT_PS_PW:
fecd2646 9741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9742 check_cp1_64bitmode(ctx);
b6d96bed 9743 {
a7812ae4 9744 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9745
9746 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9747 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9749 tcg_temp_free_i64(fp0);
b6d96bed 9750 }
5a5012ec
TS
9751 opn = "cvt.ps.pw";
9752 break;
bf4120ad 9753 case OPC_ADD_PS:
5e755519 9754 check_cp1_64bitmode(ctx);
b6d96bed 9755 {
a7812ae4
PB
9756 TCGv_i64 fp0 = tcg_temp_new_i64();
9757 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9758
9759 gen_load_fpr64(ctx, fp0, fs);
9760 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9761 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9762 tcg_temp_free_i64(fp1);
b6d96bed 9763 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9764 tcg_temp_free_i64(fp0);
b6d96bed 9765 }
5a5012ec 9766 opn = "add.ps";
6ea83fed 9767 break;
bf4120ad 9768 case OPC_SUB_PS:
5e755519 9769 check_cp1_64bitmode(ctx);
b6d96bed 9770 {
a7812ae4
PB
9771 TCGv_i64 fp0 = tcg_temp_new_i64();
9772 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9773
9774 gen_load_fpr64(ctx, fp0, fs);
9775 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9776 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9777 tcg_temp_free_i64(fp1);
b6d96bed 9778 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9779 tcg_temp_free_i64(fp0);
b6d96bed 9780 }
5a5012ec 9781 opn = "sub.ps";
6ea83fed 9782 break;
bf4120ad 9783 case OPC_MUL_PS:
5e755519 9784 check_cp1_64bitmode(ctx);
b6d96bed 9785 {
a7812ae4
PB
9786 TCGv_i64 fp0 = tcg_temp_new_i64();
9787 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9788
9789 gen_load_fpr64(ctx, fp0, fs);
9790 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9791 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9792 tcg_temp_free_i64(fp1);
b6d96bed 9793 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9794 tcg_temp_free_i64(fp0);
b6d96bed 9795 }
5a5012ec 9796 opn = "mul.ps";
6ea83fed 9797 break;
bf4120ad 9798 case OPC_ABS_PS:
5e755519 9799 check_cp1_64bitmode(ctx);
b6d96bed 9800 {
a7812ae4 9801 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9802
9803 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9804 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9805 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9806 tcg_temp_free_i64(fp0);
b6d96bed 9807 }
5a5012ec 9808 opn = "abs.ps";
6ea83fed 9809 break;
bf4120ad 9810 case OPC_MOV_PS:
5e755519 9811 check_cp1_64bitmode(ctx);
b6d96bed 9812 {
a7812ae4 9813 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9814
9815 gen_load_fpr64(ctx, fp0, fs);
9816 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9817 tcg_temp_free_i64(fp0);
b6d96bed 9818 }
5a5012ec 9819 opn = "mov.ps";
6ea83fed 9820 break;
bf4120ad 9821 case OPC_NEG_PS:
5e755519 9822 check_cp1_64bitmode(ctx);
b6d96bed 9823 {
a7812ae4 9824 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9825
9826 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9827 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9828 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9829 tcg_temp_free_i64(fp0);
b6d96bed 9830 }
5a5012ec 9831 opn = "neg.ps";
6ea83fed 9832 break;
bf4120ad 9833 case OPC_MOVCF_PS:
5e755519 9834 check_cp1_64bitmode(ctx);
7f6613ce 9835 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9836 opn = "movcf.ps";
6ea83fed 9837 break;
bf4120ad 9838 case OPC_MOVZ_PS:
5e755519 9839 check_cp1_64bitmode(ctx);
a16336e4
TS
9840 {
9841 int l1 = gen_new_label();
30a3848b 9842 TCGv_i64 fp0;
a16336e4 9843
c9297f4d
AJ
9844 if (ft != 0)
9845 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9846 fp0 = tcg_temp_new_i64();
9847 gen_load_fpr64(ctx, fp0, fs);
9848 gen_store_fpr64(ctx, fp0, fd);
9849 tcg_temp_free_i64(fp0);
a16336e4
TS
9850 gen_set_label(l1);
9851 }
5a5012ec 9852 opn = "movz.ps";
6ea83fed 9853 break;
bf4120ad 9854 case OPC_MOVN_PS:
5e755519 9855 check_cp1_64bitmode(ctx);
a16336e4
TS
9856 {
9857 int l1 = gen_new_label();
30a3848b 9858 TCGv_i64 fp0;
c9297f4d
AJ
9859
9860 if (ft != 0) {
9861 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9862 fp0 = tcg_temp_new_i64();
9863 gen_load_fpr64(ctx, fp0, fs);
9864 gen_store_fpr64(ctx, fp0, fd);
9865 tcg_temp_free_i64(fp0);
9866 gen_set_label(l1);
9867 }
a16336e4 9868 }
5a5012ec 9869 opn = "movn.ps";
6ea83fed 9870 break;
bf4120ad 9871 case OPC_ADDR_PS:
5e755519 9872 check_cp1_64bitmode(ctx);
b6d96bed 9873 {
a7812ae4
PB
9874 TCGv_i64 fp0 = tcg_temp_new_i64();
9875 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9876
9877 gen_load_fpr64(ctx, fp0, ft);
9878 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9879 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9880 tcg_temp_free_i64(fp1);
b6d96bed 9881 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9882 tcg_temp_free_i64(fp0);
b6d96bed 9883 }
fbcc6828
TS
9884 opn = "addr.ps";
9885 break;
bf4120ad 9886 case OPC_MULR_PS:
5e755519 9887 check_cp1_64bitmode(ctx);
b6d96bed 9888 {
a7812ae4
PB
9889 TCGv_i64 fp0 = tcg_temp_new_i64();
9890 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9891
9892 gen_load_fpr64(ctx, fp0, ft);
9893 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9894 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9895 tcg_temp_free_i64(fp1);
b6d96bed 9896 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9897 tcg_temp_free_i64(fp0);
b6d96bed 9898 }
57fa1fb3
TS
9899 opn = "mulr.ps";
9900 break;
bf4120ad 9901 case OPC_RECIP2_PS:
5e755519 9902 check_cp1_64bitmode(ctx);
b6d96bed 9903 {
a7812ae4
PB
9904 TCGv_i64 fp0 = tcg_temp_new_i64();
9905 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9906
9907 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9908 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9909 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9910 tcg_temp_free_i64(fp1);
b6d96bed 9911 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9912 tcg_temp_free_i64(fp0);
b6d96bed 9913 }
57fa1fb3
TS
9914 opn = "recip2.ps";
9915 break;
bf4120ad 9916 case OPC_RECIP1_PS:
5e755519 9917 check_cp1_64bitmode(ctx);
b6d96bed 9918 {
a7812ae4 9919 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9920
9921 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9922 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9923 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9924 tcg_temp_free_i64(fp0);
b6d96bed 9925 }
57fa1fb3
TS
9926 opn = "recip1.ps";
9927 break;
bf4120ad 9928 case OPC_RSQRT1_PS:
5e755519 9929 check_cp1_64bitmode(ctx);
b6d96bed 9930 {
a7812ae4 9931 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9932
9933 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9934 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9935 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9936 tcg_temp_free_i64(fp0);
b6d96bed 9937 }
57fa1fb3
TS
9938 opn = "rsqrt1.ps";
9939 break;
bf4120ad 9940 case OPC_RSQRT2_PS:
5e755519 9941 check_cp1_64bitmode(ctx);
b6d96bed 9942 {
a7812ae4
PB
9943 TCGv_i64 fp0 = tcg_temp_new_i64();
9944 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9945
9946 gen_load_fpr64(ctx, fp0, fs);
9947 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9948 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9949 tcg_temp_free_i64(fp1);
b6d96bed 9950 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9951 tcg_temp_free_i64(fp0);
b6d96bed 9952 }
57fa1fb3
TS
9953 opn = "rsqrt2.ps";
9954 break;
bf4120ad 9955 case OPC_CVT_S_PU:
5e755519 9956 check_cp1_64bitmode(ctx);
b6d96bed 9957 {
a7812ae4 9958 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9959
7f6613ce 9960 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9961 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9962 gen_store_fpr32(fp0, fd);
a7812ae4 9963 tcg_temp_free_i32(fp0);
b6d96bed 9964 }
5a5012ec 9965 opn = "cvt.s.pu";
dd016883 9966 break;
bf4120ad 9967 case OPC_CVT_PW_PS:
5e755519 9968 check_cp1_64bitmode(ctx);
b6d96bed 9969 {
a7812ae4 9970 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9971
9972 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9973 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9974 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9975 tcg_temp_free_i64(fp0);
b6d96bed 9976 }
5a5012ec 9977 opn = "cvt.pw.ps";
6ea83fed 9978 break;
bf4120ad 9979 case OPC_CVT_S_PL:
5e755519 9980 check_cp1_64bitmode(ctx);
b6d96bed 9981 {
a7812ae4 9982 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9983
9984 gen_load_fpr32(fp0, fs);
895c2d04 9985 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 9986 gen_store_fpr32(fp0, fd);
a7812ae4 9987 tcg_temp_free_i32(fp0);
b6d96bed 9988 }
5a5012ec 9989 opn = "cvt.s.pl";
6ea83fed 9990 break;
bf4120ad 9991 case OPC_PLL_PS:
5e755519 9992 check_cp1_64bitmode(ctx);
b6d96bed 9993 {
a7812ae4
PB
9994 TCGv_i32 fp0 = tcg_temp_new_i32();
9995 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9996
9997 gen_load_fpr32(fp0, fs);
9998 gen_load_fpr32(fp1, ft);
7f6613ce 9999 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 10000 gen_store_fpr32(fp1, fd);
a7812ae4
PB
10001 tcg_temp_free_i32(fp0);
10002 tcg_temp_free_i32(fp1);
b6d96bed 10003 }
5a5012ec 10004 opn = "pll.ps";
6ea83fed 10005 break;
bf4120ad 10006 case OPC_PLU_PS:
5e755519 10007 check_cp1_64bitmode(ctx);
b6d96bed 10008 {
a7812ae4
PB
10009 TCGv_i32 fp0 = tcg_temp_new_i32();
10010 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
10011
10012 gen_load_fpr32(fp0, fs);
7f6613ce 10013 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10014 gen_store_fpr32(fp1, fd);
7f6613ce 10015 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10016 tcg_temp_free_i32(fp0);
10017 tcg_temp_free_i32(fp1);
b6d96bed 10018 }
5a5012ec
TS
10019 opn = "plu.ps";
10020 break;
bf4120ad 10021 case OPC_PUL_PS:
5e755519 10022 check_cp1_64bitmode(ctx);
b6d96bed 10023 {
a7812ae4
PB
10024 TCGv_i32 fp0 = tcg_temp_new_i32();
10025 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10026
7f6613ce 10027 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
10028 gen_load_fpr32(fp1, ft);
10029 gen_store_fpr32(fp1, fd);
7f6613ce 10030 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10031 tcg_temp_free_i32(fp0);
10032 tcg_temp_free_i32(fp1);
b6d96bed 10033 }
5a5012ec
TS
10034 opn = "pul.ps";
10035 break;
bf4120ad 10036 case OPC_PUU_PS:
5e755519 10037 check_cp1_64bitmode(ctx);
b6d96bed 10038 {
a7812ae4
PB
10039 TCGv_i32 fp0 = tcg_temp_new_i32();
10040 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10041
7f6613ce
PJ
10042 gen_load_fpr32h(ctx, fp0, fs);
10043 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10044 gen_store_fpr32(fp1, fd);
7f6613ce 10045 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10046 tcg_temp_free_i32(fp0);
10047 tcg_temp_free_i32(fp1);
b6d96bed 10048 }
5a5012ec
TS
10049 opn = "puu.ps";
10050 break;
bf4120ad
NF
10051 case OPC_CMP_F_PS:
10052 case OPC_CMP_UN_PS:
10053 case OPC_CMP_EQ_PS:
10054 case OPC_CMP_UEQ_PS:
10055 case OPC_CMP_OLT_PS:
10056 case OPC_CMP_ULT_PS:
10057 case OPC_CMP_OLE_PS:
10058 case OPC_CMP_ULE_PS:
10059 case OPC_CMP_SF_PS:
10060 case OPC_CMP_NGLE_PS:
10061 case OPC_CMP_SEQ_PS:
10062 case OPC_CMP_NGL_PS:
10063 case OPC_CMP_LT_PS:
10064 case OPC_CMP_NGE_PS:
10065 case OPC_CMP_LE_PS:
10066 case OPC_CMP_NGT_PS:
8153667c
NF
10067 if (ctx->opcode & (1 << 6)) {
10068 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10069 opn = condnames_abs[func-48];
10070 } else {
10071 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10072 opn = condnames[func-48];
5a1e8ffb 10073 }
6ea83fed 10074 break;
5a5012ec 10075 default:
923617a3 10076 MIPS_INVAL(opn);
e397ee33 10077 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10078 return;
10079 }
2abf314d 10080 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10081 switch (optype) {
10082 case BINOP:
6ea83fed 10083 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10084 break;
10085 case CMPOP:
10086 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10087 break;
10088 default:
6ea83fed 10089 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10090 break;
10091 }
6ea83fed 10092}
6af0bf9c 10093
5a5012ec 10094/* Coprocessor 3 (FPU) */
5e755519
TS
10095static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10096 int fd, int fs, int base, int index)
7a387fff 10097{
923617a3 10098 const char *opn = "extended float load/store";
93b12ccc 10099 int store = 0;
4e2474d6 10100 TCGv t0 = tcg_temp_new();
7a387fff 10101
93b12ccc 10102 if (base == 0) {
6c5c1e20 10103 gen_load_gpr(t0, index);
93b12ccc 10104 } else if (index == 0) {
6c5c1e20 10105 gen_load_gpr(t0, base);
93b12ccc 10106 } else {
05168674 10107 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10108 }
5a5012ec 10109 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10110 memory access. */
5a5012ec
TS
10111 switch (opc) {
10112 case OPC_LWXC1:
8c0ab41f 10113 check_cop1x(ctx);
b6d96bed 10114 {
a7812ae4 10115 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10116
5f68f5ae 10117 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10118 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 10119 gen_store_fpr32(fp0, fd);
a7812ae4 10120 tcg_temp_free_i32(fp0);
b6d96bed 10121 }
5a5012ec
TS
10122 opn = "lwxc1";
10123 break;
10124 case OPC_LDXC1:
8c0ab41f
AJ
10125 check_cop1x(ctx);
10126 check_cp1_registers(ctx, fd);
b6d96bed 10127 {
a7812ae4 10128 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10129 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10130 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10131 tcg_temp_free_i64(fp0);
b6d96bed 10132 }
5a5012ec
TS
10133 opn = "ldxc1";
10134 break;
10135 case OPC_LUXC1:
8c0ab41f 10136 check_cp1_64bitmode(ctx);
6c5c1e20 10137 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10138 {
a7812ae4 10139 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10140
5f68f5ae 10141 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10142 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10143 tcg_temp_free_i64(fp0);
b6d96bed 10144 }
5a5012ec
TS
10145 opn = "luxc1";
10146 break;
10147 case OPC_SWXC1:
8c0ab41f 10148 check_cop1x(ctx);
b6d96bed 10149 {
a7812ae4 10150 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10151 gen_load_fpr32(fp0, fs);
5f68f5ae 10152 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10153 tcg_temp_free_i32(fp0);
b6d96bed 10154 }
5a5012ec 10155 opn = "swxc1";
93b12ccc 10156 store = 1;
5a5012ec
TS
10157 break;
10158 case OPC_SDXC1:
8c0ab41f
AJ
10159 check_cop1x(ctx);
10160 check_cp1_registers(ctx, fs);
b6d96bed 10161 {
a7812ae4 10162 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10163 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10164 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10165 tcg_temp_free_i64(fp0);
b6d96bed 10166 }
5a5012ec 10167 opn = "sdxc1";
93b12ccc 10168 store = 1;
5a5012ec
TS
10169 break;
10170 case OPC_SUXC1:
8c0ab41f 10171 check_cp1_64bitmode(ctx);
6c5c1e20 10172 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10173 {
a7812ae4 10174 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10175 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10176 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10177 tcg_temp_free_i64(fp0);
b6d96bed 10178 }
5a5012ec 10179 opn = "suxc1";
93b12ccc 10180 store = 1;
5a5012ec 10181 break;
5a5012ec 10182 }
6c5c1e20 10183 tcg_temp_free(t0);
2abf314d 10184 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10185 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10186 regnames[index], regnames[base]);
5a5012ec
TS
10187}
10188
5e755519
TS
10189static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10190 int fd, int fr, int fs, int ft)
5a5012ec 10191{
923617a3 10192 const char *opn = "flt3_arith";
5a5012ec 10193
5a5012ec
TS
10194 switch (opc) {
10195 case OPC_ALNV_PS:
b8aa4598 10196 check_cp1_64bitmode(ctx);
a16336e4 10197 {
a7812ae4 10198 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10199 TCGv_i32 fp = tcg_temp_new_i32();
10200 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
10201 int l1 = gen_new_label();
10202 int l2 = gen_new_label();
10203
6c5c1e20
TS
10204 gen_load_gpr(t0, fr);
10205 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10206
10207 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 10208 gen_load_fpr32(fp, fs);
7f6613ce 10209 gen_load_fpr32h(ctx, fph, fs);
c905fdac 10210 gen_store_fpr32(fp, fd);
7f6613ce 10211 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10212 tcg_gen_br(l2);
10213 gen_set_label(l1);
6c5c1e20
TS
10214 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10215 tcg_temp_free(t0);
a16336e4 10216#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 10217 gen_load_fpr32(fp, fs);
7f6613ce
PJ
10218 gen_load_fpr32h(ctx, fph, ft);
10219 gen_store_fpr32h(ctx, fp, fd);
c905fdac 10220 gen_store_fpr32(fph, fd);
a16336e4 10221#else
7f6613ce 10222 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
10223 gen_load_fpr32(fp, ft);
10224 gen_store_fpr32(fph, fd);
7f6613ce 10225 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10226#endif
10227 gen_set_label(l2);
c905fdac
AJ
10228 tcg_temp_free_i32(fp);
10229 tcg_temp_free_i32(fph);
a16336e4 10230 }
5a5012ec
TS
10231 opn = "alnv.ps";
10232 break;
10233 case OPC_MADD_S:
b8aa4598 10234 check_cop1x(ctx);
b6d96bed 10235 {
a7812ae4
PB
10236 TCGv_i32 fp0 = tcg_temp_new_i32();
10237 TCGv_i32 fp1 = tcg_temp_new_i32();
10238 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10239
10240 gen_load_fpr32(fp0, fs);
10241 gen_load_fpr32(fp1, ft);
10242 gen_load_fpr32(fp2, fr);
b3d6cd44 10243 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10244 tcg_temp_free_i32(fp0);
10245 tcg_temp_free_i32(fp1);
b6d96bed 10246 gen_store_fpr32(fp2, fd);
a7812ae4 10247 tcg_temp_free_i32(fp2);
b6d96bed 10248 }
5a5012ec
TS
10249 opn = "madd.s";
10250 break;
10251 case OPC_MADD_D:
b8aa4598
TS
10252 check_cop1x(ctx);
10253 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10254 {
a7812ae4
PB
10255 TCGv_i64 fp0 = tcg_temp_new_i64();
10256 TCGv_i64 fp1 = tcg_temp_new_i64();
10257 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10258
10259 gen_load_fpr64(ctx, fp0, fs);
10260 gen_load_fpr64(ctx, fp1, ft);
10261 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10262 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10263 tcg_temp_free_i64(fp0);
10264 tcg_temp_free_i64(fp1);
b6d96bed 10265 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10266 tcg_temp_free_i64(fp2);
b6d96bed 10267 }
5a5012ec
TS
10268 opn = "madd.d";
10269 break;
10270 case OPC_MADD_PS:
b8aa4598 10271 check_cp1_64bitmode(ctx);
b6d96bed 10272 {
a7812ae4
PB
10273 TCGv_i64 fp0 = tcg_temp_new_i64();
10274 TCGv_i64 fp1 = tcg_temp_new_i64();
10275 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10276
10277 gen_load_fpr64(ctx, fp0, fs);
10278 gen_load_fpr64(ctx, fp1, ft);
10279 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10280 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10281 tcg_temp_free_i64(fp0);
10282 tcg_temp_free_i64(fp1);
b6d96bed 10283 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10284 tcg_temp_free_i64(fp2);
b6d96bed 10285 }
5a5012ec
TS
10286 opn = "madd.ps";
10287 break;
10288 case OPC_MSUB_S:
b8aa4598 10289 check_cop1x(ctx);
b6d96bed 10290 {
a7812ae4
PB
10291 TCGv_i32 fp0 = tcg_temp_new_i32();
10292 TCGv_i32 fp1 = tcg_temp_new_i32();
10293 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10294
10295 gen_load_fpr32(fp0, fs);
10296 gen_load_fpr32(fp1, ft);
10297 gen_load_fpr32(fp2, fr);
b3d6cd44 10298 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10299 tcg_temp_free_i32(fp0);
10300 tcg_temp_free_i32(fp1);
b6d96bed 10301 gen_store_fpr32(fp2, fd);
a7812ae4 10302 tcg_temp_free_i32(fp2);
b6d96bed 10303 }
5a5012ec
TS
10304 opn = "msub.s";
10305 break;
10306 case OPC_MSUB_D:
b8aa4598
TS
10307 check_cop1x(ctx);
10308 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10309 {
a7812ae4
PB
10310 TCGv_i64 fp0 = tcg_temp_new_i64();
10311 TCGv_i64 fp1 = tcg_temp_new_i64();
10312 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10313
10314 gen_load_fpr64(ctx, fp0, fs);
10315 gen_load_fpr64(ctx, fp1, ft);
10316 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10317 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10318 tcg_temp_free_i64(fp0);
10319 tcg_temp_free_i64(fp1);
b6d96bed 10320 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10321 tcg_temp_free_i64(fp2);
b6d96bed 10322 }
5a5012ec
TS
10323 opn = "msub.d";
10324 break;
10325 case OPC_MSUB_PS:
b8aa4598 10326 check_cp1_64bitmode(ctx);
b6d96bed 10327 {
a7812ae4
PB
10328 TCGv_i64 fp0 = tcg_temp_new_i64();
10329 TCGv_i64 fp1 = tcg_temp_new_i64();
10330 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10331
10332 gen_load_fpr64(ctx, fp0, fs);
10333 gen_load_fpr64(ctx, fp1, ft);
10334 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10335 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10336 tcg_temp_free_i64(fp0);
10337 tcg_temp_free_i64(fp1);
b6d96bed 10338 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10339 tcg_temp_free_i64(fp2);
b6d96bed 10340 }
5a5012ec
TS
10341 opn = "msub.ps";
10342 break;
10343 case OPC_NMADD_S:
b8aa4598 10344 check_cop1x(ctx);
b6d96bed 10345 {
a7812ae4
PB
10346 TCGv_i32 fp0 = tcg_temp_new_i32();
10347 TCGv_i32 fp1 = tcg_temp_new_i32();
10348 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10349
10350 gen_load_fpr32(fp0, fs);
10351 gen_load_fpr32(fp1, ft);
10352 gen_load_fpr32(fp2, fr);
b3d6cd44 10353 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10354 tcg_temp_free_i32(fp0);
10355 tcg_temp_free_i32(fp1);
b6d96bed 10356 gen_store_fpr32(fp2, fd);
a7812ae4 10357 tcg_temp_free_i32(fp2);
b6d96bed 10358 }
5a5012ec
TS
10359 opn = "nmadd.s";
10360 break;
10361 case OPC_NMADD_D:
b8aa4598
TS
10362 check_cop1x(ctx);
10363 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10364 {
a7812ae4
PB
10365 TCGv_i64 fp0 = tcg_temp_new_i64();
10366 TCGv_i64 fp1 = tcg_temp_new_i64();
10367 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10368
10369 gen_load_fpr64(ctx, fp0, fs);
10370 gen_load_fpr64(ctx, fp1, ft);
10371 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10372 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10373 tcg_temp_free_i64(fp0);
10374 tcg_temp_free_i64(fp1);
b6d96bed 10375 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10376 tcg_temp_free_i64(fp2);
b6d96bed 10377 }
5a5012ec
TS
10378 opn = "nmadd.d";
10379 break;
10380 case OPC_NMADD_PS:
b8aa4598 10381 check_cp1_64bitmode(ctx);
b6d96bed 10382 {
a7812ae4
PB
10383 TCGv_i64 fp0 = tcg_temp_new_i64();
10384 TCGv_i64 fp1 = tcg_temp_new_i64();
10385 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10386
10387 gen_load_fpr64(ctx, fp0, fs);
10388 gen_load_fpr64(ctx, fp1, ft);
10389 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10390 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10391 tcg_temp_free_i64(fp0);
10392 tcg_temp_free_i64(fp1);
b6d96bed 10393 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10394 tcg_temp_free_i64(fp2);
b6d96bed 10395 }
5a5012ec
TS
10396 opn = "nmadd.ps";
10397 break;
10398 case OPC_NMSUB_S:
b8aa4598 10399 check_cop1x(ctx);
b6d96bed 10400 {
a7812ae4
PB
10401 TCGv_i32 fp0 = tcg_temp_new_i32();
10402 TCGv_i32 fp1 = tcg_temp_new_i32();
10403 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10404
10405 gen_load_fpr32(fp0, fs);
10406 gen_load_fpr32(fp1, ft);
10407 gen_load_fpr32(fp2, fr);
b3d6cd44 10408 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10409 tcg_temp_free_i32(fp0);
10410 tcg_temp_free_i32(fp1);
b6d96bed 10411 gen_store_fpr32(fp2, fd);
a7812ae4 10412 tcg_temp_free_i32(fp2);
b6d96bed 10413 }
5a5012ec
TS
10414 opn = "nmsub.s";
10415 break;
10416 case OPC_NMSUB_D:
b8aa4598
TS
10417 check_cop1x(ctx);
10418 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10419 {
a7812ae4
PB
10420 TCGv_i64 fp0 = tcg_temp_new_i64();
10421 TCGv_i64 fp1 = tcg_temp_new_i64();
10422 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10423
10424 gen_load_fpr64(ctx, fp0, fs);
10425 gen_load_fpr64(ctx, fp1, ft);
10426 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10427 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10428 tcg_temp_free_i64(fp0);
10429 tcg_temp_free_i64(fp1);
b6d96bed 10430 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10431 tcg_temp_free_i64(fp2);
b6d96bed 10432 }
5a5012ec
TS
10433 opn = "nmsub.d";
10434 break;
10435 case OPC_NMSUB_PS:
b8aa4598 10436 check_cp1_64bitmode(ctx);
b6d96bed 10437 {
a7812ae4
PB
10438 TCGv_i64 fp0 = tcg_temp_new_i64();
10439 TCGv_i64 fp1 = tcg_temp_new_i64();
10440 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10441
10442 gen_load_fpr64(ctx, fp0, fs);
10443 gen_load_fpr64(ctx, fp1, ft);
10444 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10445 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10446 tcg_temp_free_i64(fp0);
10447 tcg_temp_free_i64(fp1);
b6d96bed 10448 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10449 tcg_temp_free_i64(fp2);
b6d96bed 10450 }
5a5012ec
TS
10451 opn = "nmsub.ps";
10452 break;
923617a3
TS
10453 default:
10454 MIPS_INVAL(opn);
5a5012ec
TS
10455 generate_exception (ctx, EXCP_RI);
10456 return;
10457 }
2abf314d 10458 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10459 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10460 fregnames[fs], fregnames[ft]);
7a387fff
TS
10461}
10462
d75c135e 10463static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10464{
10465 TCGv t0;
10466
b3167288
RH
10467#if !defined(CONFIG_USER_ONLY)
10468 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10469 Therefore only check the ISA in system mode. */
d75c135e 10470 check_insn(ctx, ISA_MIPS32R2);
b3167288 10471#endif
26ebe468
NF
10472 t0 = tcg_temp_new();
10473
10474 switch (rd) {
10475 case 0:
10476 save_cpu_state(ctx, 1);
895c2d04 10477 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10478 gen_store_gpr(t0, rt);
10479 break;
10480 case 1:
10481 save_cpu_state(ctx, 1);
895c2d04 10482 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10483 gen_store_gpr(t0, rt);
10484 break;
10485 case 2:
10486 save_cpu_state(ctx, 1);
895c2d04 10487 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10488 gen_store_gpr(t0, rt);
10489 break;
10490 case 3:
10491 save_cpu_state(ctx, 1);
895c2d04 10492 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10493 gen_store_gpr(t0, rt);
10494 break;
10495 case 29:
10496#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10497 tcg_gen_ld_tl(t0, cpu_env,
10498 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10499 gen_store_gpr(t0, rt);
10500 break;
10501#else
d279279e
PJ
10502 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10503 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10504 tcg_gen_ld_tl(t0, cpu_env,
10505 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10506 gen_store_gpr(t0, rt);
10507 } else {
10508 generate_exception(ctx, EXCP_RI);
10509 }
10510 break;
26ebe468
NF
10511#endif
10512 default: /* Invalid */
10513 MIPS_INVAL("rdhwr");
10514 generate_exception(ctx, EXCP_RI);
10515 break;
10516 }
10517 tcg_temp_free(t0);
10518}
10519
31837be3 10520static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10521{
10522 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10523 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
10524 /* Branches completion */
10525 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10526 ctx->bstate = BS_BRANCH;
10527 save_cpu_state(ctx, 0);
10528 /* FIXME: Need to clear can_do_io. */
364d4831 10529 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10530 case MIPS_HFLAG_FBNSLOT:
10531 MIPS_DEBUG("forbidden slot");
10532 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10533 break;
c9602061
NF
10534 case MIPS_HFLAG_B:
10535 /* unconditional branch */
10536 MIPS_DEBUG("unconditional branch");
364d4831
NF
10537 if (proc_hflags & MIPS_HFLAG_BX) {
10538 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10539 }
c9602061
NF
10540 gen_goto_tb(ctx, 0, ctx->btarget);
10541 break;
10542 case MIPS_HFLAG_BL:
10543 /* blikely taken case */
10544 MIPS_DEBUG("blikely branch taken");
10545 gen_goto_tb(ctx, 0, ctx->btarget);
10546 break;
10547 case MIPS_HFLAG_BC:
10548 /* Conditional branch */
10549 MIPS_DEBUG("conditional branch");
10550 {
10551 int l1 = gen_new_label();
10552
10553 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10554 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10555 gen_set_label(l1);
10556 gen_goto_tb(ctx, 0, ctx->btarget);
10557 }
10558 break;
10559 case MIPS_HFLAG_BR:
10560 /* unconditional branch to register */
10561 MIPS_DEBUG("branch to register");
d75c135e 10562 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10563 TCGv t0 = tcg_temp_new();
10564 TCGv_i32 t1 = tcg_temp_new_i32();
10565
10566 tcg_gen_andi_tl(t0, btarget, 0x1);
10567 tcg_gen_trunc_tl_i32(t1, t0);
10568 tcg_temp_free(t0);
10569 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10570 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10571 tcg_gen_or_i32(hflags, hflags, t1);
10572 tcg_temp_free_i32(t1);
10573
10574 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10575 } else {
10576 tcg_gen_mov_tl(cpu_PC, btarget);
10577 }
c9602061
NF
10578 if (ctx->singlestep_enabled) {
10579 save_cpu_state(ctx, 0);
895c2d04 10580 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10581 }
10582 tcg_gen_exit_tb(0);
10583 break;
10584 default:
10585 MIPS_DEBUG("unknown branch");
10586 break;
10587 }
10588 }
10589}
10590
7a387fff 10591/* ISA extensions (ASEs) */
6af0bf9c 10592/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10593
10594/* MIPS16 major opcodes */
10595enum {
10596 M16_OPC_ADDIUSP = 0x00,
10597 M16_OPC_ADDIUPC = 0x01,
10598 M16_OPC_B = 0x02,
10599 M16_OPC_JAL = 0x03,
10600 M16_OPC_BEQZ = 0x04,
10601 M16_OPC_BNEQZ = 0x05,
10602 M16_OPC_SHIFT = 0x06,
10603 M16_OPC_LD = 0x07,
10604 M16_OPC_RRIA = 0x08,
10605 M16_OPC_ADDIU8 = 0x09,
10606 M16_OPC_SLTI = 0x0a,
10607 M16_OPC_SLTIU = 0x0b,
10608 M16_OPC_I8 = 0x0c,
10609 M16_OPC_LI = 0x0d,
10610 M16_OPC_CMPI = 0x0e,
10611 M16_OPC_SD = 0x0f,
10612 M16_OPC_LB = 0x10,
10613 M16_OPC_LH = 0x11,
10614 M16_OPC_LWSP = 0x12,
10615 M16_OPC_LW = 0x13,
10616 M16_OPC_LBU = 0x14,
10617 M16_OPC_LHU = 0x15,
10618 M16_OPC_LWPC = 0x16,
10619 M16_OPC_LWU = 0x17,
10620 M16_OPC_SB = 0x18,
10621 M16_OPC_SH = 0x19,
10622 M16_OPC_SWSP = 0x1a,
10623 M16_OPC_SW = 0x1b,
10624 M16_OPC_RRR = 0x1c,
10625 M16_OPC_RR = 0x1d,
10626 M16_OPC_EXTEND = 0x1e,
10627 M16_OPC_I64 = 0x1f
10628};
10629
10630/* I8 funct field */
10631enum {
10632 I8_BTEQZ = 0x0,
10633 I8_BTNEZ = 0x1,
10634 I8_SWRASP = 0x2,
10635 I8_ADJSP = 0x3,
10636 I8_SVRS = 0x4,
10637 I8_MOV32R = 0x5,
10638 I8_MOVR32 = 0x7
10639};
10640
10641/* RRR f field */
10642enum {
10643 RRR_DADDU = 0x0,
10644 RRR_ADDU = 0x1,
10645 RRR_DSUBU = 0x2,
10646 RRR_SUBU = 0x3
10647};
10648
10649/* RR funct field */
10650enum {
10651 RR_JR = 0x00,
10652 RR_SDBBP = 0x01,
10653 RR_SLT = 0x02,
10654 RR_SLTU = 0x03,
10655 RR_SLLV = 0x04,
10656 RR_BREAK = 0x05,
10657 RR_SRLV = 0x06,
10658 RR_SRAV = 0x07,
10659 RR_DSRL = 0x08,
10660 RR_CMP = 0x0a,
10661 RR_NEG = 0x0b,
10662 RR_AND = 0x0c,
10663 RR_OR = 0x0d,
10664 RR_XOR = 0x0e,
10665 RR_NOT = 0x0f,
10666 RR_MFHI = 0x10,
10667 RR_CNVT = 0x11,
10668 RR_MFLO = 0x12,
10669 RR_DSRA = 0x13,
10670 RR_DSLLV = 0x14,
10671 RR_DSRLV = 0x16,
10672 RR_DSRAV = 0x17,
10673 RR_MULT = 0x18,
10674 RR_MULTU = 0x19,
10675 RR_DIV = 0x1a,
10676 RR_DIVU = 0x1b,
10677 RR_DMULT = 0x1c,
10678 RR_DMULTU = 0x1d,
10679 RR_DDIV = 0x1e,
10680 RR_DDIVU = 0x1f
10681};
10682
10683/* I64 funct field */
10684enum {
10685 I64_LDSP = 0x0,
10686 I64_SDSP = 0x1,
10687 I64_SDRASP = 0x2,
10688 I64_DADJSP = 0x3,
10689 I64_LDPC = 0x4,
364d4831 10690 I64_DADDIU5 = 0x5,
6ea219d0
NF
10691 I64_DADDIUPC = 0x6,
10692 I64_DADDIUSP = 0x7
10693};
10694
10695/* RR ry field for CNVT */
10696enum {
10697 RR_RY_CNVT_ZEB = 0x0,
10698 RR_RY_CNVT_ZEH = 0x1,
10699 RR_RY_CNVT_ZEW = 0x2,
10700 RR_RY_CNVT_SEB = 0x4,
10701 RR_RY_CNVT_SEH = 0x5,
10702 RR_RY_CNVT_SEW = 0x6,
10703};
10704
364d4831
NF
10705static int xlat (int r)
10706{
10707 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10708
10709 return map[r];
10710}
10711
10712static void gen_mips16_save (DisasContext *ctx,
10713 int xsregs, int aregs,
10714 int do_ra, int do_s0, int do_s1,
10715 int framesize)
10716{
10717 TCGv t0 = tcg_temp_new();
10718 TCGv t1 = tcg_temp_new();
10719 int args, astatic;
10720
10721 switch (aregs) {
10722 case 0:
10723 case 1:
10724 case 2:
10725 case 3:
10726 case 11:
10727 args = 0;
10728 break;
10729 case 4:
10730 case 5:
10731 case 6:
10732 case 7:
10733 args = 1;
10734 break;
10735 case 8:
10736 case 9:
10737 case 10:
10738 args = 2;
10739 break;
10740 case 12:
10741 case 13:
10742 args = 3;
10743 break;
10744 case 14:
10745 args = 4;
10746 break;
10747 default:
10748 generate_exception(ctx, EXCP_RI);
10749 return;
10750 }
10751
10752 switch (args) {
10753 case 4:
10754 gen_base_offset_addr(ctx, t0, 29, 12);
10755 gen_load_gpr(t1, 7);
5f68f5ae 10756 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10757 /* Fall through */
10758 case 3:
10759 gen_base_offset_addr(ctx, t0, 29, 8);
10760 gen_load_gpr(t1, 6);
5f68f5ae 10761 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10762 /* Fall through */
10763 case 2:
10764 gen_base_offset_addr(ctx, t0, 29, 4);
10765 gen_load_gpr(t1, 5);
5f68f5ae 10766 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10767 /* Fall through */
10768 case 1:
10769 gen_base_offset_addr(ctx, t0, 29, 0);
10770 gen_load_gpr(t1, 4);
5f68f5ae 10771 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10772 }
10773
10774 gen_load_gpr(t0, 29);
10775
5f68f5ae
AJ
10776#define DECR_AND_STORE(reg) do { \
10777 tcg_gen_subi_tl(t0, t0, 4); \
10778 gen_load_gpr(t1, reg); \
10779 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10780 } while (0)
10781
10782 if (do_ra) {
10783 DECR_AND_STORE(31);
10784 }
10785
10786 switch (xsregs) {
10787 case 7:
10788 DECR_AND_STORE(30);
10789 /* Fall through */
10790 case 6:
10791 DECR_AND_STORE(23);
10792 /* Fall through */
10793 case 5:
10794 DECR_AND_STORE(22);
10795 /* Fall through */
10796 case 4:
10797 DECR_AND_STORE(21);
10798 /* Fall through */
10799 case 3:
10800 DECR_AND_STORE(20);
10801 /* Fall through */
10802 case 2:
10803 DECR_AND_STORE(19);
10804 /* Fall through */
10805 case 1:
10806 DECR_AND_STORE(18);
10807 }
10808
10809 if (do_s1) {
10810 DECR_AND_STORE(17);
10811 }
10812 if (do_s0) {
10813 DECR_AND_STORE(16);
10814 }
10815
10816 switch (aregs) {
10817 case 0:
10818 case 4:
10819 case 8:
10820 case 12:
10821 case 14:
10822 astatic = 0;
10823 break;
10824 case 1:
10825 case 5:
10826 case 9:
10827 case 13:
10828 astatic = 1;
10829 break;
10830 case 2:
10831 case 6:
10832 case 10:
10833 astatic = 2;
10834 break;
10835 case 3:
10836 case 7:
10837 astatic = 3;
10838 break;
10839 case 11:
10840 astatic = 4;
10841 break;
10842 default:
10843 generate_exception(ctx, EXCP_RI);
10844 return;
10845 }
10846
10847 if (astatic > 0) {
10848 DECR_AND_STORE(7);
10849 if (astatic > 1) {
10850 DECR_AND_STORE(6);
10851 if (astatic > 2) {
10852 DECR_AND_STORE(5);
10853 if (astatic > 3) {
10854 DECR_AND_STORE(4);
10855 }
10856 }
10857 }
10858 }
10859#undef DECR_AND_STORE
10860
10861 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10862 tcg_temp_free(t0);
10863 tcg_temp_free(t1);
10864}
10865
10866static void gen_mips16_restore (DisasContext *ctx,
10867 int xsregs, int aregs,
10868 int do_ra, int do_s0, int do_s1,
10869 int framesize)
10870{
10871 int astatic;
10872 TCGv t0 = tcg_temp_new();
10873 TCGv t1 = tcg_temp_new();
10874
10875 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10876
5f68f5ae
AJ
10877#define DECR_AND_LOAD(reg) do { \
10878 tcg_gen_subi_tl(t0, t0, 4); \
10879 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10880 gen_store_gpr(t1, reg); \
364d4831
NF
10881 } while (0)
10882
10883 if (do_ra) {
10884 DECR_AND_LOAD(31);
10885 }
10886
10887 switch (xsregs) {
10888 case 7:
10889 DECR_AND_LOAD(30);
10890 /* Fall through */
10891 case 6:
10892 DECR_AND_LOAD(23);
10893 /* Fall through */
10894 case 5:
10895 DECR_AND_LOAD(22);
10896 /* Fall through */
10897 case 4:
10898 DECR_AND_LOAD(21);
10899 /* Fall through */
10900 case 3:
10901 DECR_AND_LOAD(20);
10902 /* Fall through */
10903 case 2:
10904 DECR_AND_LOAD(19);
10905 /* Fall through */
10906 case 1:
10907 DECR_AND_LOAD(18);
10908 }
10909
10910 if (do_s1) {
10911 DECR_AND_LOAD(17);
10912 }
10913 if (do_s0) {
10914 DECR_AND_LOAD(16);
10915 }
10916
10917 switch (aregs) {
10918 case 0:
10919 case 4:
10920 case 8:
10921 case 12:
10922 case 14:
10923 astatic = 0;
10924 break;
10925 case 1:
10926 case 5:
10927 case 9:
10928 case 13:
10929 astatic = 1;
10930 break;
10931 case 2:
10932 case 6:
10933 case 10:
10934 astatic = 2;
10935 break;
10936 case 3:
10937 case 7:
10938 astatic = 3;
10939 break;
10940 case 11:
10941 astatic = 4;
10942 break;
10943 default:
10944 generate_exception(ctx, EXCP_RI);
10945 return;
10946 }
10947
10948 if (astatic > 0) {
10949 DECR_AND_LOAD(7);
10950 if (astatic > 1) {
10951 DECR_AND_LOAD(6);
10952 if (astatic > 2) {
10953 DECR_AND_LOAD(5);
10954 if (astatic > 3) {
10955 DECR_AND_LOAD(4);
10956 }
10957 }
10958 }
10959 }
10960#undef DECR_AND_LOAD
10961
10962 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10963 tcg_temp_free(t0);
10964 tcg_temp_free(t1);
10965}
10966
10967static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10968 int is_64_bit, int extended)
10969{
10970 TCGv t0;
10971
10972 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10973 generate_exception(ctx, EXCP_RI);
10974 return;
10975 }
10976
10977 t0 = tcg_temp_new();
10978
10979 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10980 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10981 if (!is_64_bit) {
10982 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10983 }
10984
10985 tcg_temp_free(t0);
10986}
10987
10988#if defined(TARGET_MIPS64)
d75c135e 10989static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
10990 int ry, int funct, int16_t offset,
10991 int extended)
10992{
10993 switch (funct) {
10994 case I64_LDSP:
10995 check_mips_64(ctx);
10996 offset = extended ? offset : offset << 3;
d75c135e 10997 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
10998 break;
10999 case I64_SDSP:
11000 check_mips_64(ctx);
11001 offset = extended ? offset : offset << 3;
5c13fdfd 11002 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11003 break;
11004 case I64_SDRASP:
11005 check_mips_64(ctx);
11006 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11007 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11008 break;
11009 case I64_DADJSP:
11010 check_mips_64(ctx);
11011 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11012 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11013 break;
11014 case I64_LDPC:
11015 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11016 generate_exception(ctx, EXCP_RI);
11017 } else {
11018 offset = extended ? offset : offset << 3;
d75c135e 11019 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11020 }
11021 break;
11022 case I64_DADDIU5:
11023 check_mips_64(ctx);
11024 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11025 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11026 break;
11027 case I64_DADDIUPC:
11028 check_mips_64(ctx);
11029 offset = extended ? offset : offset << 2;
11030 gen_addiupc(ctx, ry, offset, 1, extended);
11031 break;
11032 case I64_DADDIUSP:
11033 check_mips_64(ctx);
11034 offset = extended ? offset : offset << 2;
d75c135e 11035 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11036 break;
11037 }
11038}
11039#endif
11040
240ce26a 11041static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11042{
895c2d04 11043 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11044 int op, rx, ry, funct, sa;
11045 int16_t imm, offset;
11046
11047 ctx->opcode = (ctx->opcode << 16) | extend;
11048 op = (ctx->opcode >> 11) & 0x1f;
11049 sa = (ctx->opcode >> 22) & 0x1f;
11050 funct = (ctx->opcode >> 8) & 0x7;
11051 rx = xlat((ctx->opcode >> 8) & 0x7);
11052 ry = xlat((ctx->opcode >> 5) & 0x7);
11053 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11054 | ((ctx->opcode >> 21) & 0x3f) << 5
11055 | (ctx->opcode & 0x1f));
11056
11057 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11058 counterparts. */
11059 switch (op) {
11060 case M16_OPC_ADDIUSP:
d75c135e 11061 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11062 break;
11063 case M16_OPC_ADDIUPC:
11064 gen_addiupc(ctx, rx, imm, 0, 1);
11065 break;
11066 case M16_OPC_B:
b231c103 11067 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11068 /* No delay slot, so just process as a normal instruction */
11069 break;
11070 case M16_OPC_BEQZ:
b231c103 11071 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11072 /* No delay slot, so just process as a normal instruction */
11073 break;
11074 case M16_OPC_BNEQZ:
b231c103 11075 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11076 /* No delay slot, so just process as a normal instruction */
11077 break;
11078 case M16_OPC_SHIFT:
11079 switch (ctx->opcode & 0x3) {
11080 case 0x0:
d75c135e 11081 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11082 break;
11083 case 0x1:
11084#if defined(TARGET_MIPS64)
11085 check_mips_64(ctx);
d75c135e 11086 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11087#else
11088 generate_exception(ctx, EXCP_RI);
11089#endif
11090 break;
11091 case 0x2:
d75c135e 11092 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11093 break;
11094 case 0x3:
d75c135e 11095 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11096 break;
11097 }
11098 break;
11099#if defined(TARGET_MIPS64)
11100 case M16_OPC_LD:
11101 check_mips_64(ctx);
d75c135e 11102 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11103 break;
11104#endif
11105 case M16_OPC_RRIA:
11106 imm = ctx->opcode & 0xf;
11107 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11108 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11109 imm = (int16_t) (imm << 1) >> 1;
11110 if ((ctx->opcode >> 4) & 0x1) {
11111#if defined(TARGET_MIPS64)
11112 check_mips_64(ctx);
d75c135e 11113 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11114#else
11115 generate_exception(ctx, EXCP_RI);
11116#endif
11117 } else {
d75c135e 11118 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11119 }
11120 break;
11121 case M16_OPC_ADDIU8:
d75c135e 11122 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11123 break;
11124 case M16_OPC_SLTI:
d75c135e 11125 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11126 break;
11127 case M16_OPC_SLTIU:
d75c135e 11128 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11129 break;
11130 case M16_OPC_I8:
11131 switch (funct) {
11132 case I8_BTEQZ:
b231c103 11133 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11134 break;
11135 case I8_BTNEZ:
b231c103 11136 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11137 break;
11138 case I8_SWRASP:
5c13fdfd 11139 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11140 break;
11141 case I8_ADJSP:
d75c135e 11142 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11143 break;
11144 case I8_SVRS:
11145 {
11146 int xsregs = (ctx->opcode >> 24) & 0x7;
11147 int aregs = (ctx->opcode >> 16) & 0xf;
11148 int do_ra = (ctx->opcode >> 6) & 0x1;
11149 int do_s0 = (ctx->opcode >> 5) & 0x1;
11150 int do_s1 = (ctx->opcode >> 4) & 0x1;
11151 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11152 | (ctx->opcode & 0xf)) << 3;
11153
11154 if (ctx->opcode & (1 << 7)) {
11155 gen_mips16_save(ctx, xsregs, aregs,
11156 do_ra, do_s0, do_s1,
11157 framesize);
11158 } else {
11159 gen_mips16_restore(ctx, xsregs, aregs,
11160 do_ra, do_s0, do_s1,
11161 framesize);
11162 }
11163 }
11164 break;
11165 default:
11166 generate_exception(ctx, EXCP_RI);
11167 break;
11168 }
11169 break;
11170 case M16_OPC_LI:
11171 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11172 break;
11173 case M16_OPC_CMPI:
11174 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11175 break;
11176#if defined(TARGET_MIPS64)
11177 case M16_OPC_SD:
5c13fdfd 11178 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11179 break;
11180#endif
11181 case M16_OPC_LB:
d75c135e 11182 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11183 break;
11184 case M16_OPC_LH:
d75c135e 11185 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11186 break;
11187 case M16_OPC_LWSP:
d75c135e 11188 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11189 break;
11190 case M16_OPC_LW:
d75c135e 11191 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11192 break;
11193 case M16_OPC_LBU:
d75c135e 11194 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11195 break;
11196 case M16_OPC_LHU:
d75c135e 11197 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11198 break;
11199 case M16_OPC_LWPC:
d75c135e 11200 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11201 break;
11202#if defined(TARGET_MIPS64)
11203 case M16_OPC_LWU:
d75c135e 11204 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11205 break;
11206#endif
11207 case M16_OPC_SB:
5c13fdfd 11208 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11209 break;
11210 case M16_OPC_SH:
5c13fdfd 11211 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11212 break;
11213 case M16_OPC_SWSP:
5c13fdfd 11214 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11215 break;
11216 case M16_OPC_SW:
5c13fdfd 11217 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11218 break;
11219#if defined(TARGET_MIPS64)
11220 case M16_OPC_I64:
d75c135e 11221 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11222 break;
11223#endif
11224 default:
11225 generate_exception(ctx, EXCP_RI);
11226 break;
11227 }
11228
11229 return 4;
11230}
11231
240ce26a 11232static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11233{
11234 int rx, ry;
11235 int sa;
11236 int op, cnvt_op, op1, offset;
11237 int funct;
11238 int n_bytes;
11239
11240 op = (ctx->opcode >> 11) & 0x1f;
11241 sa = (ctx->opcode >> 2) & 0x7;
11242 sa = sa == 0 ? 8 : sa;
11243 rx = xlat((ctx->opcode >> 8) & 0x7);
11244 cnvt_op = (ctx->opcode >> 5) & 0x7;
11245 ry = xlat((ctx->opcode >> 5) & 0x7);
11246 op1 = offset = ctx->opcode & 0x1f;
11247
11248 n_bytes = 2;
11249
11250 switch (op) {
11251 case M16_OPC_ADDIUSP:
11252 {
11253 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11254
d75c135e 11255 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11256 }
11257 break;
11258 case M16_OPC_ADDIUPC:
11259 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11260 break;
11261 case M16_OPC_B:
11262 offset = (ctx->opcode & 0x7ff) << 1;
11263 offset = (int16_t)(offset << 4) >> 4;
b231c103 11264 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11265 /* No delay slot, so just process as a normal instruction */
11266 break;
11267 case M16_OPC_JAL:
895c2d04 11268 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11269 offset = (((ctx->opcode & 0x1f) << 21)
11270 | ((ctx->opcode >> 5) & 0x1f) << 16
11271 | offset) << 2;
b231c103
YK
11272 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11273 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11274 n_bytes = 4;
364d4831
NF
11275 break;
11276 case M16_OPC_BEQZ:
b231c103
YK
11277 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11278 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11279 /* No delay slot, so just process as a normal instruction */
11280 break;
11281 case M16_OPC_BNEQZ:
b231c103
YK
11282 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11283 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11284 /* No delay slot, so just process as a normal instruction */
11285 break;
11286 case M16_OPC_SHIFT:
11287 switch (ctx->opcode & 0x3) {
11288 case 0x0:
d75c135e 11289 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11290 break;
11291 case 0x1:
11292#if defined(TARGET_MIPS64)
11293 check_mips_64(ctx);
d75c135e 11294 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11295#else
11296 generate_exception(ctx, EXCP_RI);
11297#endif
11298 break;
11299 case 0x2:
d75c135e 11300 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11301 break;
11302 case 0x3:
d75c135e 11303 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11304 break;
11305 }
11306 break;
11307#if defined(TARGET_MIPS64)
11308 case M16_OPC_LD:
11309 check_mips_64(ctx);
d75c135e 11310 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11311 break;
11312#endif
11313 case M16_OPC_RRIA:
11314 {
11315 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11316
11317 if ((ctx->opcode >> 4) & 1) {
11318#if defined(TARGET_MIPS64)
11319 check_mips_64(ctx);
d75c135e 11320 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11321#else
11322 generate_exception(ctx, EXCP_RI);
11323#endif
11324 } else {
d75c135e 11325 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11326 }
11327 }
11328 break;
11329 case M16_OPC_ADDIU8:
11330 {
11331 int16_t imm = (int8_t) ctx->opcode;
11332
d75c135e 11333 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11334 }
11335 break;
11336 case M16_OPC_SLTI:
11337 {
11338 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11339 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11340 }
11341 break;
11342 case M16_OPC_SLTIU:
11343 {
11344 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11345 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11346 }
11347 break;
11348 case M16_OPC_I8:
11349 {
11350 int reg32;
11351
11352 funct = (ctx->opcode >> 8) & 0x7;
11353 switch (funct) {
11354 case I8_BTEQZ:
11355 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11356 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11357 break;
11358 case I8_BTNEZ:
11359 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11360 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11361 break;
11362 case I8_SWRASP:
5c13fdfd 11363 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11364 break;
11365 case I8_ADJSP:
d75c135e 11366 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11367 ((int8_t)ctx->opcode) << 3);
11368 break;
11369 case I8_SVRS:
11370 {
11371 int do_ra = ctx->opcode & (1 << 6);
11372 int do_s0 = ctx->opcode & (1 << 5);
11373 int do_s1 = ctx->opcode & (1 << 4);
11374 int framesize = ctx->opcode & 0xf;
11375
11376 if (framesize == 0) {
11377 framesize = 128;
11378 } else {
11379 framesize = framesize << 3;
11380 }
11381
11382 if (ctx->opcode & (1 << 7)) {
11383 gen_mips16_save(ctx, 0, 0,
11384 do_ra, do_s0, do_s1, framesize);
11385 } else {
11386 gen_mips16_restore(ctx, 0, 0,
11387 do_ra, do_s0, do_s1, framesize);
11388 }
11389 }
11390 break;
11391 case I8_MOV32R:
11392 {
11393 int rz = xlat(ctx->opcode & 0x7);
11394
11395 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11396 ((ctx->opcode >> 5) & 0x7);
d75c135e 11397 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11398 }
11399 break;
11400 case I8_MOVR32:
11401 reg32 = ctx->opcode & 0x1f;
d75c135e 11402 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11403 break;
11404 default:
11405 generate_exception(ctx, EXCP_RI);
11406 break;
11407 }
11408 }
11409 break;
11410 case M16_OPC_LI:
11411 {
11412 int16_t imm = (uint8_t) ctx->opcode;
11413
d75c135e 11414 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11415 }
11416 break;
11417 case M16_OPC_CMPI:
11418 {
11419 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11420 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11421 }
11422 break;
11423#if defined(TARGET_MIPS64)
11424 case M16_OPC_SD:
11425 check_mips_64(ctx);
5c13fdfd 11426 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11427 break;
11428#endif
11429 case M16_OPC_LB:
d75c135e 11430 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11431 break;
11432 case M16_OPC_LH:
d75c135e 11433 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11434 break;
11435 case M16_OPC_LWSP:
d75c135e 11436 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11437 break;
11438 case M16_OPC_LW:
d75c135e 11439 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11440 break;
11441 case M16_OPC_LBU:
d75c135e 11442 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11443 break;
11444 case M16_OPC_LHU:
d75c135e 11445 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11446 break;
11447 case M16_OPC_LWPC:
d75c135e 11448 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11449 break;
11450#if defined (TARGET_MIPS64)
11451 case M16_OPC_LWU:
11452 check_mips_64(ctx);
d75c135e 11453 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11454 break;
11455#endif
11456 case M16_OPC_SB:
5c13fdfd 11457 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11458 break;
11459 case M16_OPC_SH:
5c13fdfd 11460 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11461 break;
11462 case M16_OPC_SWSP:
5c13fdfd 11463 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11464 break;
11465 case M16_OPC_SW:
5c13fdfd 11466 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11467 break;
11468 case M16_OPC_RRR:
11469 {
11470 int rz = xlat((ctx->opcode >> 2) & 0x7);
11471 int mips32_op;
11472
11473 switch (ctx->opcode & 0x3) {
11474 case RRR_ADDU:
11475 mips32_op = OPC_ADDU;
11476 break;
11477 case RRR_SUBU:
11478 mips32_op = OPC_SUBU;
11479 break;
11480#if defined(TARGET_MIPS64)
11481 case RRR_DADDU:
11482 mips32_op = OPC_DADDU;
11483 check_mips_64(ctx);
11484 break;
11485 case RRR_DSUBU:
11486 mips32_op = OPC_DSUBU;
11487 check_mips_64(ctx);
11488 break;
11489#endif
11490 default:
11491 generate_exception(ctx, EXCP_RI);
11492 goto done;
11493 }
11494
d75c135e 11495 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11496 done:
11497 ;
11498 }
11499 break;
11500 case M16_OPC_RR:
11501 switch (op1) {
11502 case RR_JR:
11503 {
11504 int nd = (ctx->opcode >> 7) & 0x1;
11505 int link = (ctx->opcode >> 6) & 0x1;
11506 int ra = (ctx->opcode >> 5) & 0x1;
11507
11508 if (link) {
b231c103 11509 op = OPC_JALR;
364d4831
NF
11510 } else {
11511 op = OPC_JR;
11512 }
11513
b231c103
YK
11514 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11515 (nd ? 0 : 2));
364d4831
NF
11516 }
11517 break;
11518 case RR_SDBBP:
11519 /* XXX: not clear which exception should be raised
11520 * when in debug mode...
11521 */
d75c135e 11522 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11523 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11524 generate_exception(ctx, EXCP_DBp);
11525 } else {
11526 generate_exception(ctx, EXCP_DBp);
11527 }
11528 break;
11529 case RR_SLT:
d75c135e 11530 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11531 break;
11532 case RR_SLTU:
d75c135e 11533 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11534 break;
11535 case RR_BREAK:
11536 generate_exception(ctx, EXCP_BREAK);
11537 break;
11538 case RR_SLLV:
d75c135e 11539 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11540 break;
11541 case RR_SRLV:
d75c135e 11542 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11543 break;
11544 case RR_SRAV:
d75c135e 11545 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11546 break;
11547#if defined (TARGET_MIPS64)
11548 case RR_DSRL:
11549 check_mips_64(ctx);
d75c135e 11550 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11551 break;
11552#endif
11553 case RR_CMP:
d75c135e 11554 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11555 break;
11556 case RR_NEG:
d75c135e 11557 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11558 break;
11559 case RR_AND:
d75c135e 11560 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11561 break;
11562 case RR_OR:
d75c135e 11563 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11564 break;
11565 case RR_XOR:
d75c135e 11566 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11567 break;
11568 case RR_NOT:
d75c135e 11569 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11570 break;
11571 case RR_MFHI:
26135ead 11572 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11573 break;
11574 case RR_CNVT:
11575 switch (cnvt_op) {
11576 case RR_RY_CNVT_ZEB:
11577 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11578 break;
11579 case RR_RY_CNVT_ZEH:
11580 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11581 break;
11582 case RR_RY_CNVT_SEB:
11583 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11584 break;
11585 case RR_RY_CNVT_SEH:
11586 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11587 break;
11588#if defined (TARGET_MIPS64)
11589 case RR_RY_CNVT_ZEW:
11590 check_mips_64(ctx);
11591 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11592 break;
11593 case RR_RY_CNVT_SEW:
11594 check_mips_64(ctx);
11595 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11596 break;
11597#endif
11598 default:
11599 generate_exception(ctx, EXCP_RI);
11600 break;
11601 }
11602 break;
11603 case RR_MFLO:
26135ead 11604 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11605 break;
11606#if defined (TARGET_MIPS64)
11607 case RR_DSRA:
11608 check_mips_64(ctx);
d75c135e 11609 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11610 break;
11611 case RR_DSLLV:
11612 check_mips_64(ctx);
d75c135e 11613 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11614 break;
11615 case RR_DSRLV:
11616 check_mips_64(ctx);
d75c135e 11617 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11618 break;
11619 case RR_DSRAV:
11620 check_mips_64(ctx);
d75c135e 11621 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11622 break;
11623#endif
11624 case RR_MULT:
26135ead 11625 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11626 break;
11627 case RR_MULTU:
26135ead 11628 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11629 break;
11630 case RR_DIV:
26135ead 11631 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11632 break;
11633 case RR_DIVU:
26135ead 11634 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11635 break;
11636#if defined (TARGET_MIPS64)
11637 case RR_DMULT:
11638 check_mips_64(ctx);
26135ead 11639 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11640 break;
11641 case RR_DMULTU:
11642 check_mips_64(ctx);
26135ead 11643 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11644 break;
11645 case RR_DDIV:
11646 check_mips_64(ctx);
26135ead 11647 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11648 break;
11649 case RR_DDIVU:
11650 check_mips_64(ctx);
26135ead 11651 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11652 break;
11653#endif
11654 default:
11655 generate_exception(ctx, EXCP_RI);
11656 break;
11657 }
11658 break;
11659 case M16_OPC_EXTEND:
240ce26a 11660 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11661 n_bytes = 4;
11662 break;
11663#if defined(TARGET_MIPS64)
11664 case M16_OPC_I64:
11665 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11666 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11667 break;
11668#endif
11669 default:
11670 generate_exception(ctx, EXCP_RI);
11671 break;
11672 }
11673
11674 return n_bytes;
11675}
11676
211da992 11677/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11678
211da992
CWR
11679/*
11680 * microMIPS32/microMIPS64 major opcodes
11681 *
11682 * 1. MIPS Architecture for Programmers Volume II-B:
11683 * The microMIPS32 Instruction Set (Revision 3.05)
11684 *
11685 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11686 *
11687 * 2. MIPS Architecture For Programmers Volume II-A:
11688 * The MIPS64 Instruction Set (Revision 3.51)
11689 */
6af0bf9c 11690
3c824109
NF
11691enum {
11692 POOL32A = 0x00,
11693 POOL16A = 0x01,
11694 LBU16 = 0x02,
11695 MOVE16 = 0x03,
11696 ADDI32 = 0x04,
11697 LBU32 = 0x05,
11698 SB32 = 0x06,
11699 LB32 = 0x07,
11700
11701 POOL32B = 0x08,
11702 POOL16B = 0x09,
11703 LHU16 = 0x0a,
11704 ANDI16 = 0x0b,
11705 ADDIU32 = 0x0c,
11706 LHU32 = 0x0d,
11707 SH32 = 0x0e,
11708 LH32 = 0x0f,
11709
11710 POOL32I = 0x10,
11711 POOL16C = 0x11,
11712 LWSP16 = 0x12,
11713 POOL16D = 0x13,
11714 ORI32 = 0x14,
11715 POOL32F = 0x15,
211da992
CWR
11716 POOL32S = 0x16, /* MIPS64 */
11717 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11718
211da992 11719 /* 0x1f is reserved */
3c824109
NF
11720 POOL32C = 0x18,
11721 LWGP16 = 0x19,
11722 LW16 = 0x1a,
11723 POOL16E = 0x1b,
11724 XORI32 = 0x1c,
11725 JALS32 = 0x1d,
11726 ADDIUPC = 0x1e,
3c824109
NF
11727
11728 /* 0x20 is reserved */
11729 RES_20 = 0x20,
11730 POOL16F = 0x21,
11731 SB16 = 0x22,
11732 BEQZ16 = 0x23,
11733 SLTI32 = 0x24,
11734 BEQ32 = 0x25,
11735 SWC132 = 0x26,
11736 LWC132 = 0x27,
11737
11738 /* 0x28 and 0x29 are reserved */
11739 RES_28 = 0x28,
11740 RES_29 = 0x29,
11741 SH16 = 0x2a,
11742 BNEZ16 = 0x2b,
11743 SLTIU32 = 0x2c,
11744 BNE32 = 0x2d,
11745 SDC132 = 0x2e,
11746 LDC132 = 0x2f,
11747
11748 /* 0x30 and 0x31 are reserved */
11749 RES_30 = 0x30,
11750 RES_31 = 0x31,
11751 SWSP16 = 0x32,
11752 B16 = 0x33,
11753 ANDI32 = 0x34,
11754 J32 = 0x35,
211da992
CWR
11755 SD32 = 0x36, /* MIPS64 */
11756 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11757
11758 /* 0x38 and 0x39 are reserved */
11759 RES_38 = 0x38,
11760 RES_39 = 0x39,
11761 SW16 = 0x3a,
11762 LI16 = 0x3b,
11763 JALX32 = 0x3c,
11764 JAL32 = 0x3d,
11765 SW32 = 0x3e,
11766 LW32 = 0x3f
11767};
11768
11769/* POOL32A encoding of minor opcode field */
11770
11771enum {
11772 /* These opcodes are distinguished only by bits 9..6; those bits are
11773 * what are recorded below. */
11774 SLL32 = 0x0,
11775 SRL32 = 0x1,
11776 SRA = 0x2,
11777 ROTR = 0x3,
11778
11779 SLLV = 0x0,
11780 SRLV = 0x1,
11781 SRAV = 0x2,
11782 ROTRV = 0x3,
11783 ADD = 0x4,
11784 ADDU32 = 0x5,
11785 SUB = 0x6,
11786 SUBU32 = 0x7,
11787 MUL = 0x8,
11788 AND = 0x9,
11789 OR32 = 0xa,
11790 NOR = 0xb,
11791 XOR32 = 0xc,
11792 SLT = 0xd,
11793 SLTU = 0xe,
11794
11795 MOVN = 0x0,
11796 MOVZ = 0x1,
11797 LWXS = 0x4,
11798
11799 /* The following can be distinguished by their lower 6 bits. */
11800 INS = 0x0c,
11801 EXT = 0x2c,
11802 POOL32AXF = 0x3c
11803};
11804
11805/* POOL32AXF encoding of minor opcode field extension */
11806
d132c79f
CWR
11807/*
11808 * 1. MIPS Architecture for Programmers Volume II-B:
11809 * The microMIPS32 Instruction Set (Revision 3.05)
11810 *
11811 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11812 *
11813 * 2. MIPS Architecture for Programmers VolumeIV-e:
11814 * The MIPS DSP Application-Specific Extension
11815 * to the microMIPS32 Architecture (Revision 2.34)
11816 *
11817 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11818 */
11819
3c824109
NF
11820enum {
11821 /* bits 11..6 */
11822 TEQ = 0x00,
11823 TGE = 0x08,
11824 TGEU = 0x10,
11825 TLT = 0x20,
11826 TLTU = 0x28,
11827 TNE = 0x30,
11828
11829 MFC0 = 0x03,
11830 MTC0 = 0x0b,
11831
d132c79f
CWR
11832 /* begin of microMIPS32 DSP */
11833
3c824109
NF
11834 /* bits 13..12 for 0x01 */
11835 MFHI_ACC = 0x0,
11836 MFLO_ACC = 0x1,
11837 MTHI_ACC = 0x2,
11838 MTLO_ACC = 0x3,
11839
11840 /* bits 13..12 for 0x2a */
11841 MADD_ACC = 0x0,
11842 MADDU_ACC = 0x1,
11843 MSUB_ACC = 0x2,
11844 MSUBU_ACC = 0x3,
11845
11846 /* bits 13..12 for 0x32 */
11847 MULT_ACC = 0x0,
6801038b 11848 MULTU_ACC = 0x1,
3c824109 11849
d132c79f
CWR
11850 /* end of microMIPS32 DSP */
11851
3c824109
NF
11852 /* bits 15..12 for 0x2c */
11853 SEB = 0x2,
11854 SEH = 0x3,
11855 CLO = 0x4,
11856 CLZ = 0x5,
11857 RDHWR = 0x6,
11858 WSBH = 0x7,
11859 MULT = 0x8,
11860 MULTU = 0x9,
11861 DIV = 0xa,
11862 DIVU = 0xb,
11863 MADD = 0xc,
11864 MADDU = 0xd,
11865 MSUB = 0xe,
11866 MSUBU = 0xf,
11867
11868 /* bits 15..12 for 0x34 */
11869 MFC2 = 0x4,
11870 MTC2 = 0x5,
11871 MFHC2 = 0x8,
11872 MTHC2 = 0x9,
11873 CFC2 = 0xc,
11874 CTC2 = 0xd,
11875
11876 /* bits 15..12 for 0x3c */
11877 JALR = 0x0,
11878 JR = 0x0, /* alias */
11879 JALR_HB = 0x1,
11880 JALRS = 0x4,
11881 JALRS_HB = 0x5,
11882
11883 /* bits 15..12 for 0x05 */
11884 RDPGPR = 0xe,
11885 WRPGPR = 0xf,
11886
11887 /* bits 15..12 for 0x0d */
11888 TLBP = 0x0,
11889 TLBR = 0x1,
11890 TLBWI = 0x2,
11891 TLBWR = 0x3,
11892 WAIT = 0x9,
11893 IRET = 0xd,
11894 DERET = 0xe,
11895 ERET = 0xf,
11896
11897 /* bits 15..12 for 0x15 */
11898 DMT = 0x0,
11899 DVPE = 0x1,
11900 EMT = 0x2,
11901 EVPE = 0x3,
11902
11903 /* bits 15..12 for 0x1d */
11904 DI = 0x4,
11905 EI = 0x5,
11906
11907 /* bits 15..12 for 0x2d */
11908 SYNC = 0x6,
11909 SYSCALL = 0x8,
11910 SDBBP = 0xd,
11911
11912 /* bits 15..12 for 0x35 */
11913 MFHI32 = 0x0,
11914 MFLO32 = 0x1,
11915 MTHI32 = 0x2,
11916 MTLO32 = 0x3,
11917};
11918
11919/* POOL32B encoding of minor opcode field (bits 15..12) */
11920
11921enum {
11922 LWC2 = 0x0,
11923 LWP = 0x1,
11924 LDP = 0x4,
11925 LWM32 = 0x5,
11926 CACHE = 0x6,
11927 LDM = 0x7,
11928 SWC2 = 0x8,
11929 SWP = 0x9,
11930 SDP = 0xc,
11931 SWM32 = 0xd,
11932 SDM = 0xf
11933};
11934
11935/* POOL32C encoding of minor opcode field (bits 15..12) */
11936
11937enum {
11938 LWL = 0x0,
11939 SWL = 0x8,
11940 LWR = 0x1,
11941 SWR = 0x9,
11942 PREF = 0x2,
11943 /* 0xa is reserved */
11944 LL = 0x3,
11945 SC = 0xb,
11946 LDL = 0x4,
11947 SDL = 0xc,
11948 LDR = 0x5,
11949 SDR = 0xd,
11950 /* 0x6 is reserved */
11951 LWU = 0xe,
11952 LLD = 0x7,
11953 SCD = 0xf
11954};
11955
11956/* POOL32F encoding of minor opcode field (bits 5..0) */
11957
11958enum {
11959 /* These are the bit 7..6 values */
11960 ADD_FMT = 0x0,
11961 MOVN_FMT = 0x0,
11962
11963 SUB_FMT = 0x1,
11964 MOVZ_FMT = 0x1,
11965
11966 MUL_FMT = 0x2,
11967
11968 DIV_FMT = 0x3,
11969
11970 /* These are the bit 8..6 values */
11971 RSQRT2_FMT = 0x0,
11972 MOVF_FMT = 0x0,
11973
11974 LWXC1 = 0x1,
11975 MOVT_FMT = 0x1,
11976
11977 PLL_PS = 0x2,
11978 SWXC1 = 0x2,
11979
11980 PLU_PS = 0x3,
11981 LDXC1 = 0x3,
11982
11983 PUL_PS = 0x4,
11984 SDXC1 = 0x4,
11985 RECIP2_FMT = 0x4,
11986
11987 PUU_PS = 0x5,
11988 LUXC1 = 0x5,
11989
11990 CVT_PS_S = 0x6,
11991 SUXC1 = 0x6,
11992 ADDR_PS = 0x6,
11993 PREFX = 0x6,
11994
11995 MULR_PS = 0x7,
11996
11997 MADD_S = 0x01,
11998 MADD_D = 0x09,
11999 MADD_PS = 0x11,
12000 ALNV_PS = 0x19,
12001 MSUB_S = 0x21,
12002 MSUB_D = 0x29,
12003 MSUB_PS = 0x31,
12004
12005 NMADD_S = 0x02,
12006 NMADD_D = 0x0a,
12007 NMADD_PS = 0x12,
12008 NMSUB_S = 0x22,
12009 NMSUB_D = 0x2a,
12010 NMSUB_PS = 0x32,
12011
12012 POOL32FXF = 0x3b,
12013
12014 CABS_COND_FMT = 0x1c, /* MIPS3D */
12015 C_COND_FMT = 0x3c
12016};
12017
12018/* POOL32Fxf encoding of minor opcode extension field */
12019
12020enum {
12021 CVT_L = 0x04,
12022 RSQRT_FMT = 0x08,
12023 FLOOR_L = 0x0c,
12024 CVT_PW_PS = 0x1c,
12025 CVT_W = 0x24,
12026 SQRT_FMT = 0x28,
12027 FLOOR_W = 0x2c,
12028 CVT_PS_PW = 0x3c,
12029 CFC1 = 0x40,
12030 RECIP_FMT = 0x48,
12031 CEIL_L = 0x4c,
12032 CTC1 = 0x60,
12033 CEIL_W = 0x6c,
12034 MFC1 = 0x80,
12035 CVT_S_PL = 0x84,
12036 TRUNC_L = 0x8c,
12037 MTC1 = 0xa0,
12038 CVT_S_PU = 0xa4,
12039 TRUNC_W = 0xac,
12040 MFHC1 = 0xc0,
12041 ROUND_L = 0xcc,
12042 MTHC1 = 0xe0,
12043 ROUND_W = 0xec,
12044
12045 MOV_FMT = 0x01,
12046 MOVF = 0x05,
12047 ABS_FMT = 0x0d,
12048 RSQRT1_FMT = 0x1d,
12049 MOVT = 0x25,
12050 NEG_FMT = 0x2d,
12051 CVT_D = 0x4d,
12052 RECIP1_FMT = 0x5d,
12053 CVT_S = 0x6d
12054};
12055
12056/* POOL32I encoding of minor opcode field (bits 25..21) */
12057
12058enum {
12059 BLTZ = 0x00,
12060 BLTZAL = 0x01,
12061 BGEZ = 0x02,
12062 BGEZAL = 0x03,
12063 BLEZ = 0x04,
12064 BNEZC = 0x05,
12065 BGTZ = 0x06,
12066 BEQZC = 0x07,
12067 TLTI = 0x08,
12068 TGEI = 0x09,
12069 TLTIU = 0x0a,
12070 TGEIU = 0x0b,
12071 TNEI = 0x0c,
12072 LUI = 0x0d,
12073 TEQI = 0x0e,
12074 SYNCI = 0x10,
12075 BLTZALS = 0x11,
12076 BGEZALS = 0x13,
12077 BC2F = 0x14,
12078 BC2T = 0x15,
12079 BPOSGE64 = 0x1a,
12080 BPOSGE32 = 0x1b,
12081 /* These overlap and are distinguished by bit16 of the instruction */
12082 BC1F = 0x1c,
12083 BC1T = 0x1d,
12084 BC1ANY2F = 0x1c,
12085 BC1ANY2T = 0x1d,
12086 BC1ANY4F = 0x1e,
12087 BC1ANY4T = 0x1f
12088};
12089
12090/* POOL16A encoding of minor opcode field */
12091
12092enum {
12093 ADDU16 = 0x0,
12094 SUBU16 = 0x1
12095};
12096
12097/* POOL16B encoding of minor opcode field */
12098
12099enum {
12100 SLL16 = 0x0,
12101 SRL16 = 0x1
12102};
12103
12104/* POOL16C encoding of minor opcode field */
12105
12106enum {
12107 NOT16 = 0x00,
12108 XOR16 = 0x04,
12109 AND16 = 0x08,
12110 OR16 = 0x0c,
12111 LWM16 = 0x10,
12112 SWM16 = 0x14,
12113 JR16 = 0x18,
12114 JRC16 = 0x1a,
12115 JALR16 = 0x1c,
12116 JALR16S = 0x1e,
12117 MFHI16 = 0x20,
12118 MFLO16 = 0x24,
12119 BREAK16 = 0x28,
12120 SDBBP16 = 0x2c,
12121 JRADDIUSP = 0x30
12122};
12123
12124/* POOL16D encoding of minor opcode field */
12125
12126enum {
12127 ADDIUS5 = 0x0,
12128 ADDIUSP = 0x1
12129};
12130
12131/* POOL16E encoding of minor opcode field */
12132
12133enum {
12134 ADDIUR2 = 0x0,
12135 ADDIUR1SP = 0x1
12136};
12137
12138static int mmreg (int r)
12139{
12140 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12141
12142 return map[r];
12143}
12144
12145/* Used for 16-bit store instructions. */
12146static int mmreg2 (int r)
12147{
12148 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12149
12150 return map[r];
12151}
12152
12153#define uMIPS_RD(op) ((op >> 7) & 0x7)
12154#define uMIPS_RS(op) ((op >> 4) & 0x7)
12155#define uMIPS_RS2(op) uMIPS_RS(op)
12156#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12157#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12158#define uMIPS_RS5(op) (op & 0x1f)
12159
12160/* Signed immediate */
12161#define SIMM(op, start, width) \
12162 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12163 << (32-width)) \
12164 >> (32-width))
12165/* Zero-extended immediate */
12166#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12167
d75c135e 12168static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12169{
12170 int rd = mmreg(uMIPS_RD(ctx->opcode));
12171
d75c135e 12172 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12173}
12174
d75c135e 12175static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12176{
12177 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12178 int rd = mmreg(uMIPS_RD(ctx->opcode));
12179 int rs = mmreg(uMIPS_RS(ctx->opcode));
12180
d75c135e 12181 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12182}
12183
d75c135e 12184static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12185{
12186 int encoded = ZIMM(ctx->opcode, 1, 9);
12187 int decoded;
12188
12189 if (encoded <= 1) {
12190 decoded = 256 + encoded;
12191 } else if (encoded <= 255) {
12192 decoded = encoded;
12193 } else if (encoded <= 509) {
12194 decoded = encoded - 512;
12195 } else {
12196 decoded = encoded - 768;
12197 }
12198
d75c135e 12199 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12200}
12201
d75c135e 12202static void gen_addius5(DisasContext *ctx)
3c824109
NF
12203{
12204 int imm = SIMM(ctx->opcode, 1, 4);
12205 int rd = (ctx->opcode >> 5) & 0x1f;
12206
d75c135e 12207 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12208}
12209
d75c135e 12210static void gen_andi16(DisasContext *ctx)
3c824109
NF
12211{
12212 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12213 31, 32, 63, 64, 255, 32768, 65535 };
12214 int rd = mmreg(uMIPS_RD(ctx->opcode));
12215 int rs = mmreg(uMIPS_RS(ctx->opcode));
12216 int encoded = ZIMM(ctx->opcode, 0, 4);
12217
d75c135e 12218 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12219}
12220
12221static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12222 int base, int16_t offset)
12223{
e1050a76 12224 const char *opn = "ldst_multiple";
3c824109
NF
12225 TCGv t0, t1;
12226 TCGv_i32 t2;
12227
12228 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12229 generate_exception(ctx, EXCP_RI);
12230 return;
12231 }
12232
12233 t0 = tcg_temp_new();
12234
12235 gen_base_offset_addr(ctx, t0, base, offset);
12236
12237 t1 = tcg_const_tl(reglist);
12238 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12239
3c824109
NF
12240 save_cpu_state(ctx, 1);
12241 switch (opc) {
12242 case LWM32:
895c2d04 12243 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12244 opn = "lwm";
3c824109
NF
12245 break;
12246 case SWM32:
895c2d04 12247 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12248 opn = "swm";
3c824109
NF
12249 break;
12250#ifdef TARGET_MIPS64
12251 case LDM:
895c2d04 12252 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12253 opn = "ldm";
3c824109
NF
12254 break;
12255 case SDM:
895c2d04 12256 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12257 opn = "sdm";
3c824109 12258 break;
6af0bf9c 12259#endif
3c824109 12260 }
e1050a76 12261 (void)opn;
3c824109
NF
12262 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12263 tcg_temp_free(t0);
33087598 12264 tcg_temp_free(t1);
3c824109
NF
12265 tcg_temp_free_i32(t2);
12266}
6af0bf9c 12267
3c824109 12268
240ce26a 12269static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12270{
3c824109
NF
12271 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12272 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12273
3c824109
NF
12274 switch (((ctx->opcode) >> 4) & 0x3f) {
12275 case NOT16 + 0:
12276 case NOT16 + 1:
12277 case NOT16 + 2:
12278 case NOT16 + 3:
d75c135e 12279 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12280 break;
12281 case XOR16 + 0:
12282 case XOR16 + 1:
12283 case XOR16 + 2:
12284 case XOR16 + 3:
d75c135e 12285 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12286 break;
12287 case AND16 + 0:
12288 case AND16 + 1:
12289 case AND16 + 2:
12290 case AND16 + 3:
d75c135e 12291 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12292 break;
12293 case OR16 + 0:
12294 case OR16 + 1:
12295 case OR16 + 2:
12296 case OR16 + 3:
d75c135e 12297 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12298 break;
12299 case LWM16 + 0:
12300 case LWM16 + 1:
12301 case LWM16 + 2:
12302 case LWM16 + 3:
12303 {
12304 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12305 int offset = ZIMM(ctx->opcode, 0, 4);
12306
12307 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12308 29, offset << 2);
12309 }
12310 break;
12311 case SWM16 + 0:
12312 case SWM16 + 1:
12313 case SWM16 + 2:
12314 case SWM16 + 3:
12315 {
12316 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12317 int offset = ZIMM(ctx->opcode, 0, 4);
12318
12319 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12320 29, offset << 2);
12321 }
12322 break;
12323 case JR16 + 0:
12324 case JR16 + 1:
12325 {
12326 int reg = ctx->opcode & 0x1f;
12327
b231c103 12328 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12329 }
3c824109
NF
12330 break;
12331 case JRC16 + 0:
12332 case JRC16 + 1:
12333 {
12334 int reg = ctx->opcode & 0x1f;
b231c103 12335 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12336 /* Let normal delay slot handling in our caller take us
12337 to the branch target. */
12338 }
12339 break;
12340 case JALR16 + 0:
12341 case JALR16 + 1:
b231c103
YK
12342 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12343 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12344 break;
3c824109
NF
12345 case JALR16S + 0:
12346 case JALR16S + 1:
b231c103
YK
12347 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12348 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12349 break;
12350 case MFHI16 + 0:
12351 case MFHI16 + 1:
26135ead 12352 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12353 break;
12354 case MFLO16 + 0:
12355 case MFLO16 + 1:
26135ead 12356 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12357 break;
12358 case BREAK16:
12359 generate_exception(ctx, EXCP_BREAK);
12360 break;
12361 case SDBBP16:
12362 /* XXX: not clear which exception should be raised
12363 * when in debug mode...
12364 */
d75c135e 12365 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12366 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12367 generate_exception(ctx, EXCP_DBp);
12368 } else {
12369 generate_exception(ctx, EXCP_DBp);
12370 }
12371 break;
12372 case JRADDIUSP + 0:
12373 case JRADDIUSP + 1:
12374 {
12375 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12376 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12377 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12378 /* Let normal delay slot handling in our caller take us
12379 to the branch target. */
12380 }
12381 break;
12382 default:
12383 generate_exception(ctx, EXCP_RI);
12384 break;
12385 }
12386}
12387
12388static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12389{
12390 TCGv t0 = tcg_temp_new();
12391 TCGv t1 = tcg_temp_new();
12392
12393 gen_load_gpr(t0, base);
12394
12395 if (index != 0) {
12396 gen_load_gpr(t1, index);
12397 tcg_gen_shli_tl(t1, t1, 2);
12398 gen_op_addr_add(ctx, t0, t1, t0);
12399 }
12400
5f68f5ae 12401 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12402 gen_store_gpr(t1, rd);
12403
12404 tcg_temp_free(t0);
12405 tcg_temp_free(t1);
12406}
12407
12408static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12409 int base, int16_t offset)
12410{
12411 const char *opn = "ldst_pair";
12412 TCGv t0, t1;
12413
36c6711b 12414 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12415 generate_exception(ctx, EXCP_RI);
d796321b
FB
12416 return;
12417 }
12418
3c824109
NF
12419 t0 = tcg_temp_new();
12420 t1 = tcg_temp_new();
8e9ade68 12421
3c824109
NF
12422 gen_base_offset_addr(ctx, t0, base, offset);
12423
12424 switch (opc) {
12425 case LWP:
36c6711b
EJ
12426 if (rd == base) {
12427 generate_exception(ctx, EXCP_RI);
12428 return;
12429 }
5f68f5ae 12430 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12431 gen_store_gpr(t1, rd);
12432 tcg_gen_movi_tl(t1, 4);
12433 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12434 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12435 gen_store_gpr(t1, rd+1);
12436 opn = "lwp";
12437 break;
12438 case SWP:
3c824109 12439 gen_load_gpr(t1, rd);
5f68f5ae 12440 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12441 tcg_gen_movi_tl(t1, 4);
12442 gen_op_addr_add(ctx, t0, t0, t1);
12443 gen_load_gpr(t1, rd+1);
5f68f5ae 12444 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12445 opn = "swp";
12446 break;
12447#ifdef TARGET_MIPS64
12448 case LDP:
36c6711b
EJ
12449 if (rd == base) {
12450 generate_exception(ctx, EXCP_RI);
12451 return;
12452 }
5f68f5ae 12453 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12454 gen_store_gpr(t1, rd);
12455 tcg_gen_movi_tl(t1, 8);
12456 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12457 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12458 gen_store_gpr(t1, rd+1);
12459 opn = "ldp";
12460 break;
12461 case SDP:
3c824109 12462 gen_load_gpr(t1, rd);
5f68f5ae 12463 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12464 tcg_gen_movi_tl(t1, 8);
12465 gen_op_addr_add(ctx, t0, t0, t1);
12466 gen_load_gpr(t1, rd+1);
5f68f5ae 12467 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12468 opn = "sdp";
12469 break;
12470#endif
6af0bf9c 12471 }
2abf314d 12472 (void)opn; /* avoid a compiler warning */
3c824109
NF
12473 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12474 tcg_temp_free(t0);
12475 tcg_temp_free(t1);
12476}
618b0fe9 12477
240ce26a 12478static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12479{
12480 int extension = (ctx->opcode >> 6) & 0x3f;
12481 int minor = (ctx->opcode >> 12) & 0xf;
12482 uint32_t mips32_op;
12483
12484 switch (extension) {
12485 case TEQ:
12486 mips32_op = OPC_TEQ;
12487 goto do_trap;
12488 case TGE:
12489 mips32_op = OPC_TGE;
12490 goto do_trap;
12491 case TGEU:
12492 mips32_op = OPC_TGEU;
12493 goto do_trap;
12494 case TLT:
12495 mips32_op = OPC_TLT;
12496 goto do_trap;
12497 case TLTU:
12498 mips32_op = OPC_TLTU;
12499 goto do_trap;
12500 case TNE:
12501 mips32_op = OPC_TNE;
12502 do_trap:
12503 gen_trap(ctx, mips32_op, rs, rt, -1);
12504 break;
12505#ifndef CONFIG_USER_ONLY
12506 case MFC0:
12507 case MFC0 + 32:
2e15497c 12508 check_cp0_enabled(ctx);
3c824109
NF
12509 if (rt == 0) {
12510 /* Treat as NOP. */
12511 break;
12512 }
d75c135e 12513 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12514 break;
12515 case MTC0:
12516 case MTC0 + 32:
2e15497c 12517 check_cp0_enabled(ctx);
3c824109
NF
12518 {
12519 TCGv t0 = tcg_temp_new();
618b0fe9 12520
3c824109 12521 gen_load_gpr(t0, rt);
d75c135e 12522 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12523 tcg_temp_free(t0);
12524 }
12525 break;
12526#endif
a1fc6246
LA
12527 case 0x2a:
12528 switch (minor & 3) {
12529 case MADD_ACC:
12530 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12531 break;
12532 case MADDU_ACC:
12533 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12534 break;
12535 case MSUB_ACC:
12536 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12537 break;
12538 case MSUBU_ACC:
12539 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12540 break;
12541 default:
12542 goto pool32axf_invalid;
12543 }
12544 break;
12545 case 0x32:
12546 switch (minor & 3) {
12547 case MULT_ACC:
12548 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12549 break;
12550 case MULTU_ACC:
12551 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12552 break;
12553 default:
12554 goto pool32axf_invalid;
12555 }
12556 break;
3c824109
NF
12557 case 0x2c:
12558 switch (minor) {
12559 case SEB:
12560 gen_bshfl(ctx, OPC_SEB, rs, rt);
12561 break;
12562 case SEH:
12563 gen_bshfl(ctx, OPC_SEH, rs, rt);
12564 break;
12565 case CLO:
12566 mips32_op = OPC_CLO;
12567 goto do_cl;
12568 case CLZ:
12569 mips32_op = OPC_CLZ;
12570 do_cl:
d75c135e 12571 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12572 gen_cl(ctx, mips32_op, rt, rs);
12573 break;
12574 case RDHWR:
d75c135e 12575 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12576 break;
12577 case WSBH:
12578 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12579 break;
12580 case MULT:
12581 mips32_op = OPC_MULT;
26135ead 12582 goto do_mul;
3c824109
NF
12583 case MULTU:
12584 mips32_op = OPC_MULTU;
26135ead 12585 goto do_mul;
3c824109
NF
12586 case DIV:
12587 mips32_op = OPC_DIV;
26135ead 12588 goto do_div;
3c824109
NF
12589 case DIVU:
12590 mips32_op = OPC_DIVU;
26135ead
RS
12591 goto do_div;
12592 do_div:
12593 check_insn(ctx, ISA_MIPS32);
12594 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12595 break;
3c824109
NF
12596 case MADD:
12597 mips32_op = OPC_MADD;
26135ead 12598 goto do_mul;
3c824109
NF
12599 case MADDU:
12600 mips32_op = OPC_MADDU;
26135ead 12601 goto do_mul;
3c824109
NF
12602 case MSUB:
12603 mips32_op = OPC_MSUB;
26135ead 12604 goto do_mul;
3c824109
NF
12605 case MSUBU:
12606 mips32_op = OPC_MSUBU;
26135ead 12607 do_mul:
d75c135e 12608 check_insn(ctx, ISA_MIPS32);
a1fc6246 12609 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12610 break;
12611 default:
12612 goto pool32axf_invalid;
12613 }
12614 break;
12615 case 0x34:
12616 switch (minor) {
12617 case MFC2:
12618 case MTC2:
12619 case MFHC2:
12620 case MTHC2:
12621 case CFC2:
12622 case CTC2:
12623 generate_exception_err(ctx, EXCP_CpU, 2);
12624 break;
12625 default:
12626 goto pool32axf_invalid;
12627 }
12628 break;
12629 case 0x3c:
12630 switch (minor) {
12631 case JALR:
12632 case JALR_HB:
b231c103
YK
12633 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12634 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12635 break;
12636 case JALRS:
12637 case JALRS_HB:
b231c103
YK
12638 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12639 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12640 break;
12641 default:
12642 goto pool32axf_invalid;
12643 }
12644 break;
12645 case 0x05:
12646 switch (minor) {
12647 case RDPGPR:
2e15497c 12648 check_cp0_enabled(ctx);
d75c135e 12649 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12650 gen_load_srsgpr(rt, rs);
12651 break;
12652 case WRPGPR:
2e15497c 12653 check_cp0_enabled(ctx);
d75c135e 12654 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12655 gen_store_srsgpr(rt, rs);
12656 break;
12657 default:
12658 goto pool32axf_invalid;
12659 }
12660 break;
12661#ifndef CONFIG_USER_ONLY
12662 case 0x0d:
12663 switch (minor) {
12664 case TLBP:
12665 mips32_op = OPC_TLBP;
12666 goto do_cp0;
12667 case TLBR:
12668 mips32_op = OPC_TLBR;
12669 goto do_cp0;
12670 case TLBWI:
12671 mips32_op = OPC_TLBWI;
12672 goto do_cp0;
12673 case TLBWR:
12674 mips32_op = OPC_TLBWR;
12675 goto do_cp0;
12676 case WAIT:
12677 mips32_op = OPC_WAIT;
12678 goto do_cp0;
12679 case DERET:
12680 mips32_op = OPC_DERET;
12681 goto do_cp0;
12682 case ERET:
12683 mips32_op = OPC_ERET;
12684 do_cp0:
12685 gen_cp0(env, ctx, mips32_op, rt, rs);
12686 break;
12687 default:
12688 goto pool32axf_invalid;
12689 }
12690 break;
12691 case 0x1d:
12692 switch (minor) {
12693 case DI:
2e15497c 12694 check_cp0_enabled(ctx);
3c824109
NF
12695 {
12696 TCGv t0 = tcg_temp_new();
12697
12698 save_cpu_state(ctx, 1);
895c2d04 12699 gen_helper_di(t0, cpu_env);
3c824109
NF
12700 gen_store_gpr(t0, rs);
12701 /* Stop translation as we may have switched the execution mode */
12702 ctx->bstate = BS_STOP;
12703 tcg_temp_free(t0);
12704 }
12705 break;
12706 case EI:
2e15497c 12707 check_cp0_enabled(ctx);
3c824109
NF
12708 {
12709 TCGv t0 = tcg_temp_new();
12710
12711 save_cpu_state(ctx, 1);
895c2d04 12712 gen_helper_ei(t0, cpu_env);
3c824109
NF
12713 gen_store_gpr(t0, rs);
12714 /* Stop translation as we may have switched the execution mode */
12715 ctx->bstate = BS_STOP;
12716 tcg_temp_free(t0);
12717 }
12718 break;
12719 default:
12720 goto pool32axf_invalid;
12721 }
12722 break;
12723#endif
12724 case 0x2d:
12725 switch (minor) {
12726 case SYNC:
12727 /* NOP */
12728 break;
12729 case SYSCALL:
12730 generate_exception(ctx, EXCP_SYSCALL);
12731 ctx->bstate = BS_STOP;
12732 break;
12733 case SDBBP:
d75c135e 12734 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12735 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12736 generate_exception(ctx, EXCP_DBp);
12737 } else {
12738 generate_exception(ctx, EXCP_DBp);
12739 }
12740 break;
12741 default:
12742 goto pool32axf_invalid;
12743 }
12744 break;
a1fc6246 12745 case 0x01:
26135ead 12746 switch (minor & 3) {
a1fc6246 12747 case MFHI_ACC:
26135ead 12748 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12749 break;
a1fc6246 12750 case MFLO_ACC:
26135ead 12751 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12752 break;
a1fc6246 12753 case MTHI_ACC:
26135ead 12754 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12755 break;
a1fc6246 12756 case MTLO_ACC:
26135ead 12757 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12758 break;
12759 default:
12760 goto pool32axf_invalid;
12761 }
12762 break;
a1fc6246
LA
12763 case 0x35:
12764 switch (minor) {
12765 case MFHI32:
12766 gen_HILO(ctx, OPC_MFHI, 0, rs);
12767 break;
12768 case MFLO32:
12769 gen_HILO(ctx, OPC_MFLO, 0, rs);
12770 break;
12771 case MTHI32:
12772 gen_HILO(ctx, OPC_MTHI, 0, rs);
12773 break;
12774 case MTLO32:
12775 gen_HILO(ctx, OPC_MTLO, 0, rs);
12776 break;
12777 default:
12778 goto pool32axf_invalid;
12779 }
12780 break;
3c824109
NF
12781 default:
12782 pool32axf_invalid:
12783 MIPS_INVAL("pool32axf");
12784 generate_exception(ctx, EXCP_RI);
12785 break;
12786 }
12787}
12788
12789/* Values for microMIPS fmt field. Variable-width, depending on which
12790 formats the instruction supports. */
12791
12792enum {
12793 FMT_SD_S = 0,
12794 FMT_SD_D = 1,
12795
12796 FMT_SDPS_S = 0,
12797 FMT_SDPS_D = 1,
12798 FMT_SDPS_PS = 2,
12799
12800 FMT_SWL_S = 0,
12801 FMT_SWL_W = 1,
12802 FMT_SWL_L = 2,
12803
12804 FMT_DWL_D = 0,
12805 FMT_DWL_W = 1,
12806 FMT_DWL_L = 2
12807};
12808
d75c135e 12809static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12810{
12811 int extension = (ctx->opcode >> 6) & 0x3ff;
12812 uint32_t mips32_op;
12813
12814#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12815#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12816#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12817
12818 switch (extension) {
12819 case FLOAT_1BIT_FMT(CFC1, 0):
12820 mips32_op = OPC_CFC1;
12821 goto do_cp1;
12822 case FLOAT_1BIT_FMT(CTC1, 0):
12823 mips32_op = OPC_CTC1;
12824 goto do_cp1;
12825 case FLOAT_1BIT_FMT(MFC1, 0):
12826 mips32_op = OPC_MFC1;
12827 goto do_cp1;
12828 case FLOAT_1BIT_FMT(MTC1, 0):
12829 mips32_op = OPC_MTC1;
12830 goto do_cp1;
12831 case FLOAT_1BIT_FMT(MFHC1, 0):
12832 mips32_op = OPC_MFHC1;
12833 goto do_cp1;
12834 case FLOAT_1BIT_FMT(MTHC1, 0):
12835 mips32_op = OPC_MTHC1;
12836 do_cp1:
12837 gen_cp1(ctx, mips32_op, rt, rs);
12838 break;
12839
12840 /* Reciprocal square root */
12841 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12842 mips32_op = OPC_RSQRT_S;
12843 goto do_unaryfp;
12844 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12845 mips32_op = OPC_RSQRT_D;
12846 goto do_unaryfp;
12847
12848 /* Square root */
12849 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12850 mips32_op = OPC_SQRT_S;
12851 goto do_unaryfp;
12852 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12853 mips32_op = OPC_SQRT_D;
12854 goto do_unaryfp;
12855
12856 /* Reciprocal */
12857 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12858 mips32_op = OPC_RECIP_S;
12859 goto do_unaryfp;
12860 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12861 mips32_op = OPC_RECIP_D;
12862 goto do_unaryfp;
12863
12864 /* Floor */
12865 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12866 mips32_op = OPC_FLOOR_L_S;
12867 goto do_unaryfp;
12868 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12869 mips32_op = OPC_FLOOR_L_D;
12870 goto do_unaryfp;
12871 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12872 mips32_op = OPC_FLOOR_W_S;
12873 goto do_unaryfp;
12874 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12875 mips32_op = OPC_FLOOR_W_D;
12876 goto do_unaryfp;
12877
12878 /* Ceiling */
12879 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12880 mips32_op = OPC_CEIL_L_S;
12881 goto do_unaryfp;
12882 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12883 mips32_op = OPC_CEIL_L_D;
12884 goto do_unaryfp;
12885 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12886 mips32_op = OPC_CEIL_W_S;
12887 goto do_unaryfp;
12888 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12889 mips32_op = OPC_CEIL_W_D;
12890 goto do_unaryfp;
12891
12892 /* Truncation */
12893 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12894 mips32_op = OPC_TRUNC_L_S;
12895 goto do_unaryfp;
12896 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12897 mips32_op = OPC_TRUNC_L_D;
12898 goto do_unaryfp;
12899 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12900 mips32_op = OPC_TRUNC_W_S;
12901 goto do_unaryfp;
12902 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12903 mips32_op = OPC_TRUNC_W_D;
12904 goto do_unaryfp;
12905
12906 /* Round */
12907 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12908 mips32_op = OPC_ROUND_L_S;
12909 goto do_unaryfp;
12910 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12911 mips32_op = OPC_ROUND_L_D;
12912 goto do_unaryfp;
12913 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12914 mips32_op = OPC_ROUND_W_S;
12915 goto do_unaryfp;
12916 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12917 mips32_op = OPC_ROUND_W_D;
12918 goto do_unaryfp;
12919
12920 /* Integer to floating-point conversion */
12921 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12922 mips32_op = OPC_CVT_L_S;
12923 goto do_unaryfp;
12924 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12925 mips32_op = OPC_CVT_L_D;
12926 goto do_unaryfp;
12927 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12928 mips32_op = OPC_CVT_W_S;
12929 goto do_unaryfp;
12930 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12931 mips32_op = OPC_CVT_W_D;
12932 goto do_unaryfp;
12933
12934 /* Paired-foo conversions */
12935 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12936 mips32_op = OPC_CVT_S_PL;
12937 goto do_unaryfp;
12938 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12939 mips32_op = OPC_CVT_S_PU;
12940 goto do_unaryfp;
12941 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12942 mips32_op = OPC_CVT_PW_PS;
12943 goto do_unaryfp;
12944 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12945 mips32_op = OPC_CVT_PS_PW;
12946 goto do_unaryfp;
12947
12948 /* Floating-point moves */
12949 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
12950 mips32_op = OPC_MOV_S;
12951 goto do_unaryfp;
12952 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
12953 mips32_op = OPC_MOV_D;
12954 goto do_unaryfp;
12955 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
12956 mips32_op = OPC_MOV_PS;
12957 goto do_unaryfp;
12958
12959 /* Absolute value */
12960 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
12961 mips32_op = OPC_ABS_S;
12962 goto do_unaryfp;
12963 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
12964 mips32_op = OPC_ABS_D;
12965 goto do_unaryfp;
12966 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
12967 mips32_op = OPC_ABS_PS;
12968 goto do_unaryfp;
12969
12970 /* Negation */
12971 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
12972 mips32_op = OPC_NEG_S;
12973 goto do_unaryfp;
12974 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
12975 mips32_op = OPC_NEG_D;
12976 goto do_unaryfp;
12977 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
12978 mips32_op = OPC_NEG_PS;
12979 goto do_unaryfp;
12980
12981 /* Reciprocal square root step */
12982 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
12983 mips32_op = OPC_RSQRT1_S;
12984 goto do_unaryfp;
12985 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
12986 mips32_op = OPC_RSQRT1_D;
12987 goto do_unaryfp;
12988 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
12989 mips32_op = OPC_RSQRT1_PS;
12990 goto do_unaryfp;
12991
12992 /* Reciprocal step */
12993 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
12994 mips32_op = OPC_RECIP1_S;
12995 goto do_unaryfp;
12996 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
12997 mips32_op = OPC_RECIP1_S;
12998 goto do_unaryfp;
12999 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13000 mips32_op = OPC_RECIP1_PS;
13001 goto do_unaryfp;
13002
13003 /* Conversions from double */
13004 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13005 mips32_op = OPC_CVT_D_S;
13006 goto do_unaryfp;
13007 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13008 mips32_op = OPC_CVT_D_W;
13009 goto do_unaryfp;
13010 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13011 mips32_op = OPC_CVT_D_L;
13012 goto do_unaryfp;
13013
13014 /* Conversions from single */
13015 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13016 mips32_op = OPC_CVT_S_D;
13017 goto do_unaryfp;
13018 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13019 mips32_op = OPC_CVT_S_W;
13020 goto do_unaryfp;
13021 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13022 mips32_op = OPC_CVT_S_L;
13023 do_unaryfp:
13024 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13025 break;
13026
13027 /* Conditional moves on floating-point codes */
13028 case COND_FLOAT_MOV(MOVT, 0):
13029 case COND_FLOAT_MOV(MOVT, 1):
13030 case COND_FLOAT_MOV(MOVT, 2):
13031 case COND_FLOAT_MOV(MOVT, 3):
13032 case COND_FLOAT_MOV(MOVT, 4):
13033 case COND_FLOAT_MOV(MOVT, 5):
13034 case COND_FLOAT_MOV(MOVT, 6):
13035 case COND_FLOAT_MOV(MOVT, 7):
13036 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13037 break;
13038 case COND_FLOAT_MOV(MOVF, 0):
13039 case COND_FLOAT_MOV(MOVF, 1):
13040 case COND_FLOAT_MOV(MOVF, 2):
13041 case COND_FLOAT_MOV(MOVF, 3):
13042 case COND_FLOAT_MOV(MOVF, 4):
13043 case COND_FLOAT_MOV(MOVF, 5):
13044 case COND_FLOAT_MOV(MOVF, 6):
13045 case COND_FLOAT_MOV(MOVF, 7):
13046 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13047 break;
13048 default:
13049 MIPS_INVAL("pool32fxf");
13050 generate_exception(ctx, EXCP_RI);
13051 break;
13052 }
13053}
13054
7db13fae 13055static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13056 uint16_t insn_hw1)
3c824109
NF
13057{
13058 int32_t offset;
13059 uint16_t insn;
13060 int rt, rs, rd, rr;
13061 int16_t imm;
13062 uint32_t op, minor, mips32_op;
13063 uint32_t cond, fmt, cc;
13064
895c2d04 13065 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13066 ctx->opcode = (ctx->opcode << 16) | insn;
13067
13068 rt = (ctx->opcode >> 21) & 0x1f;
13069 rs = (ctx->opcode >> 16) & 0x1f;
13070 rd = (ctx->opcode >> 11) & 0x1f;
13071 rr = (ctx->opcode >> 6) & 0x1f;
13072 imm = (int16_t) ctx->opcode;
13073
13074 op = (ctx->opcode >> 26) & 0x3f;
13075 switch (op) {
13076 case POOL32A:
13077 minor = ctx->opcode & 0x3f;
13078 switch (minor) {
13079 case 0x00:
13080 minor = (ctx->opcode >> 6) & 0xf;
13081 switch (minor) {
13082 case SLL32:
13083 mips32_op = OPC_SLL;
13084 goto do_shifti;
13085 case SRA:
13086 mips32_op = OPC_SRA;
13087 goto do_shifti;
13088 case SRL32:
13089 mips32_op = OPC_SRL;
13090 goto do_shifti;
13091 case ROTR:
13092 mips32_op = OPC_ROTR;
13093 do_shifti:
d75c135e 13094 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13095 break;
13096 default:
13097 goto pool32a_invalid;
13098 }
13099 break;
13100 case 0x10:
13101 minor = (ctx->opcode >> 6) & 0xf;
13102 switch (minor) {
13103 /* Arithmetic */
13104 case ADD:
13105 mips32_op = OPC_ADD;
13106 goto do_arith;
13107 case ADDU32:
13108 mips32_op = OPC_ADDU;
13109 goto do_arith;
13110 case SUB:
13111 mips32_op = OPC_SUB;
13112 goto do_arith;
13113 case SUBU32:
13114 mips32_op = OPC_SUBU;
13115 goto do_arith;
13116 case MUL:
13117 mips32_op = OPC_MUL;
13118 do_arith:
d75c135e 13119 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13120 break;
13121 /* Shifts */
13122 case SLLV:
13123 mips32_op = OPC_SLLV;
13124 goto do_shift;
13125 case SRLV:
13126 mips32_op = OPC_SRLV;
13127 goto do_shift;
13128 case SRAV:
13129 mips32_op = OPC_SRAV;
13130 goto do_shift;
13131 case ROTRV:
13132 mips32_op = OPC_ROTRV;
13133 do_shift:
d75c135e 13134 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13135 break;
13136 /* Logical operations */
13137 case AND:
13138 mips32_op = OPC_AND;
13139 goto do_logic;
13140 case OR32:
13141 mips32_op = OPC_OR;
13142 goto do_logic;
13143 case NOR:
13144 mips32_op = OPC_NOR;
13145 goto do_logic;
13146 case XOR32:
13147 mips32_op = OPC_XOR;
13148 do_logic:
d75c135e 13149 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13150 break;
13151 /* Set less than */
13152 case SLT:
13153 mips32_op = OPC_SLT;
13154 goto do_slt;
13155 case SLTU:
13156 mips32_op = OPC_SLTU;
13157 do_slt:
d75c135e 13158 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13159 break;
13160 default:
13161 goto pool32a_invalid;
13162 }
13163 break;
13164 case 0x18:
13165 minor = (ctx->opcode >> 6) & 0xf;
13166 switch (minor) {
13167 /* Conditional moves */
13168 case MOVN:
13169 mips32_op = OPC_MOVN;
13170 goto do_cmov;
13171 case MOVZ:
13172 mips32_op = OPC_MOVZ;
13173 do_cmov:
d75c135e 13174 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13175 break;
13176 case LWXS:
13177 gen_ldxs(ctx, rs, rt, rd);
13178 break;
13179 default:
13180 goto pool32a_invalid;
13181 }
13182 break;
13183 case INS:
13184 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13185 return;
13186 case EXT:
13187 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13188 return;
13189 case POOL32AXF:
240ce26a 13190 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13191 break;
13192 case 0x07:
13193 generate_exception(ctx, EXCP_BREAK);
13194 break;
13195 default:
13196 pool32a_invalid:
13197 MIPS_INVAL("pool32a");
13198 generate_exception(ctx, EXCP_RI);
13199 break;
13200 }
13201 break;
13202 case POOL32B:
13203 minor = (ctx->opcode >> 12) & 0xf;
13204 switch (minor) {
13205 case CACHE:
2e15497c 13206 check_cp0_enabled(ctx);
3c824109
NF
13207 /* Treat as no-op. */
13208 break;
13209 case LWC2:
13210 case SWC2:
13211 /* COP2: Not implemented. */
13212 generate_exception_err(ctx, EXCP_CpU, 2);
13213 break;
13214 case LWP:
13215 case SWP:
13216#ifdef TARGET_MIPS64
13217 case LDP:
13218 case SDP:
13219#endif
13220 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13221 break;
13222 case LWM32:
13223 case SWM32:
13224#ifdef TARGET_MIPS64
13225 case LDM:
13226 case SDM:
13227#endif
13228 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13229 break;
13230 default:
13231 MIPS_INVAL("pool32b");
13232 generate_exception(ctx, EXCP_RI);
13233 break;
13234 }
13235 break;
13236 case POOL32F:
5ab5c041 13237 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13238 minor = ctx->opcode & 0x3f;
13239 check_cp1_enabled(ctx);
13240 switch (minor) {
13241 case ALNV_PS:
13242 mips32_op = OPC_ALNV_PS;
13243 goto do_madd;
13244 case MADD_S:
13245 mips32_op = OPC_MADD_S;
13246 goto do_madd;
13247 case MADD_D:
13248 mips32_op = OPC_MADD_D;
13249 goto do_madd;
13250 case MADD_PS:
13251 mips32_op = OPC_MADD_PS;
13252 goto do_madd;
13253 case MSUB_S:
13254 mips32_op = OPC_MSUB_S;
13255 goto do_madd;
13256 case MSUB_D:
13257 mips32_op = OPC_MSUB_D;
13258 goto do_madd;
13259 case MSUB_PS:
13260 mips32_op = OPC_MSUB_PS;
13261 goto do_madd;
13262 case NMADD_S:
13263 mips32_op = OPC_NMADD_S;
13264 goto do_madd;
13265 case NMADD_D:
13266 mips32_op = OPC_NMADD_D;
13267 goto do_madd;
13268 case NMADD_PS:
13269 mips32_op = OPC_NMADD_PS;
13270 goto do_madd;
13271 case NMSUB_S:
13272 mips32_op = OPC_NMSUB_S;
13273 goto do_madd;
13274 case NMSUB_D:
13275 mips32_op = OPC_NMSUB_D;
13276 goto do_madd;
13277 case NMSUB_PS:
13278 mips32_op = OPC_NMSUB_PS;
13279 do_madd:
13280 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13281 break;
13282 case CABS_COND_FMT:
13283 cond = (ctx->opcode >> 6) & 0xf;
13284 cc = (ctx->opcode >> 13) & 0x7;
13285 fmt = (ctx->opcode >> 10) & 0x3;
13286 switch (fmt) {
13287 case 0x0:
13288 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13289 break;
13290 case 0x1:
13291 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13292 break;
13293 case 0x2:
13294 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13295 break;
13296 default:
13297 goto pool32f_invalid;
13298 }
13299 break;
13300 case C_COND_FMT:
13301 cond = (ctx->opcode >> 6) & 0xf;
13302 cc = (ctx->opcode >> 13) & 0x7;
13303 fmt = (ctx->opcode >> 10) & 0x3;
13304 switch (fmt) {
13305 case 0x0:
13306 gen_cmp_s(ctx, cond, rt, rs, cc);
13307 break;
13308 case 0x1:
13309 gen_cmp_d(ctx, cond, rt, rs, cc);
13310 break;
13311 case 0x2:
13312 gen_cmp_ps(ctx, cond, rt, rs, cc);
13313 break;
13314 default:
13315 goto pool32f_invalid;
13316 }
13317 break;
13318 case POOL32FXF:
d75c135e 13319 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13320 break;
13321 case 0x00:
13322 /* PLL foo */
13323 switch ((ctx->opcode >> 6) & 0x7) {
13324 case PLL_PS:
13325 mips32_op = OPC_PLL_PS;
13326 goto do_ps;
13327 case PLU_PS:
13328 mips32_op = OPC_PLU_PS;
13329 goto do_ps;
13330 case PUL_PS:
13331 mips32_op = OPC_PUL_PS;
13332 goto do_ps;
13333 case PUU_PS:
13334 mips32_op = OPC_PUU_PS;
13335 goto do_ps;
13336 case CVT_PS_S:
13337 mips32_op = OPC_CVT_PS_S;
13338 do_ps:
13339 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13340 break;
13341 default:
13342 goto pool32f_invalid;
13343 }
13344 break;
13345 case 0x08:
13346 /* [LS][WDU]XC1 */
13347 switch ((ctx->opcode >> 6) & 0x7) {
13348 case LWXC1:
13349 mips32_op = OPC_LWXC1;
13350 goto do_ldst_cp1;
13351 case SWXC1:
13352 mips32_op = OPC_SWXC1;
13353 goto do_ldst_cp1;
13354 case LDXC1:
13355 mips32_op = OPC_LDXC1;
13356 goto do_ldst_cp1;
13357 case SDXC1:
13358 mips32_op = OPC_SDXC1;
13359 goto do_ldst_cp1;
13360 case LUXC1:
13361 mips32_op = OPC_LUXC1;
13362 goto do_ldst_cp1;
13363 case SUXC1:
13364 mips32_op = OPC_SUXC1;
13365 do_ldst_cp1:
13366 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13367 break;
13368 default:
13369 goto pool32f_invalid;
13370 }
13371 break;
13372 case 0x18:
13373 /* 3D insns */
13374 fmt = (ctx->opcode >> 9) & 0x3;
13375 switch ((ctx->opcode >> 6) & 0x7) {
13376 case RSQRT2_FMT:
13377 switch (fmt) {
13378 case FMT_SDPS_S:
13379 mips32_op = OPC_RSQRT2_S;
13380 goto do_3d;
13381 case FMT_SDPS_D:
13382 mips32_op = OPC_RSQRT2_D;
13383 goto do_3d;
13384 case FMT_SDPS_PS:
13385 mips32_op = OPC_RSQRT2_PS;
13386 goto do_3d;
13387 default:
13388 goto pool32f_invalid;
13389 }
13390 break;
13391 case RECIP2_FMT:
13392 switch (fmt) {
13393 case FMT_SDPS_S:
13394 mips32_op = OPC_RECIP2_S;
13395 goto do_3d;
13396 case FMT_SDPS_D:
13397 mips32_op = OPC_RECIP2_D;
13398 goto do_3d;
13399 case FMT_SDPS_PS:
13400 mips32_op = OPC_RECIP2_PS;
13401 goto do_3d;
13402 default:
13403 goto pool32f_invalid;
13404 }
13405 break;
13406 case ADDR_PS:
13407 mips32_op = OPC_ADDR_PS;
13408 goto do_3d;
13409 case MULR_PS:
13410 mips32_op = OPC_MULR_PS;
13411 do_3d:
13412 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13413 break;
13414 default:
13415 goto pool32f_invalid;
13416 }
13417 break;
13418 case 0x20:
13419 /* MOV[FT].fmt and PREFX */
13420 cc = (ctx->opcode >> 13) & 0x7;
13421 fmt = (ctx->opcode >> 9) & 0x3;
13422 switch ((ctx->opcode >> 6) & 0x7) {
13423 case MOVF_FMT:
13424 switch (fmt) {
13425 case FMT_SDPS_S:
13426 gen_movcf_s(rs, rt, cc, 0);
13427 break;
13428 case FMT_SDPS_D:
13429 gen_movcf_d(ctx, rs, rt, cc, 0);
13430 break;
13431 case FMT_SDPS_PS:
7f6613ce 13432 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13433 break;
13434 default:
13435 goto pool32f_invalid;
13436 }
13437 break;
13438 case MOVT_FMT:
13439 switch (fmt) {
13440 case FMT_SDPS_S:
13441 gen_movcf_s(rs, rt, cc, 1);
13442 break;
13443 case FMT_SDPS_D:
13444 gen_movcf_d(ctx, rs, rt, cc, 1);
13445 break;
13446 case FMT_SDPS_PS:
7f6613ce 13447 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13448 break;
13449 default:
13450 goto pool32f_invalid;
13451 }
13452 break;
13453 case PREFX:
13454 break;
13455 default:
13456 goto pool32f_invalid;
13457 }
13458 break;
13459#define FINSN_3ARG_SDPS(prfx) \
13460 switch ((ctx->opcode >> 8) & 0x3) { \
13461 case FMT_SDPS_S: \
13462 mips32_op = OPC_##prfx##_S; \
13463 goto do_fpop; \
13464 case FMT_SDPS_D: \
13465 mips32_op = OPC_##prfx##_D; \
13466 goto do_fpop; \
13467 case FMT_SDPS_PS: \
13468 mips32_op = OPC_##prfx##_PS; \
13469 goto do_fpop; \
13470 default: \
13471 goto pool32f_invalid; \
13472 }
13473 case 0x30:
13474 /* regular FP ops */
13475 switch ((ctx->opcode >> 6) & 0x3) {
13476 case ADD_FMT:
13477 FINSN_3ARG_SDPS(ADD);
13478 break;
13479 case SUB_FMT:
13480 FINSN_3ARG_SDPS(SUB);
13481 break;
13482 case MUL_FMT:
13483 FINSN_3ARG_SDPS(MUL);
13484 break;
13485 case DIV_FMT:
13486 fmt = (ctx->opcode >> 8) & 0x3;
13487 if (fmt == 1) {
13488 mips32_op = OPC_DIV_D;
13489 } else if (fmt == 0) {
13490 mips32_op = OPC_DIV_S;
13491 } else {
13492 goto pool32f_invalid;
13493 }
13494 goto do_fpop;
13495 default:
13496 goto pool32f_invalid;
13497 }
13498 break;
13499 case 0x38:
13500 /* cmovs */
13501 switch ((ctx->opcode >> 6) & 0x3) {
13502 case MOVN_FMT:
13503 FINSN_3ARG_SDPS(MOVN);
13504 break;
13505 case MOVZ_FMT:
13506 FINSN_3ARG_SDPS(MOVZ);
13507 break;
13508 default:
13509 goto pool32f_invalid;
13510 }
13511 break;
13512 do_fpop:
13513 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13514 break;
13515 default:
13516 pool32f_invalid:
13517 MIPS_INVAL("pool32f");
13518 generate_exception(ctx, EXCP_RI);
13519 break;
13520 }
13521 } else {
13522 generate_exception_err(ctx, EXCP_CpU, 1);
13523 }
13524 break;
13525 case POOL32I:
13526 minor = (ctx->opcode >> 21) & 0x1f;
13527 switch (minor) {
13528 case BLTZ:
b231c103
YK
13529 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13530 break;
3c824109 13531 case BLTZAL:
b231c103
YK
13532 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13533 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13534 break;
3c824109 13535 case BLTZALS:
b231c103
YK
13536 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13537 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13538 break;
3c824109 13539 case BGEZ:
b231c103
YK
13540 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13541 break;
3c824109 13542 case BGEZAL:
b231c103
YK
13543 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13544 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13545 break;
3c824109 13546 case BGEZALS:
b231c103
YK
13547 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13548 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13549 break;
3c824109 13550 case BLEZ:
b231c103
YK
13551 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13552 break;
3c824109 13553 case BGTZ:
b231c103 13554 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13555 break;
13556
13557 /* Traps */
13558 case TLTI:
13559 mips32_op = OPC_TLTI;
13560 goto do_trapi;
13561 case TGEI:
13562 mips32_op = OPC_TGEI;
13563 goto do_trapi;
13564 case TLTIU:
13565 mips32_op = OPC_TLTIU;
13566 goto do_trapi;
13567 case TGEIU:
13568 mips32_op = OPC_TGEIU;
13569 goto do_trapi;
13570 case TNEI:
13571 mips32_op = OPC_TNEI;
13572 goto do_trapi;
13573 case TEQI:
13574 mips32_op = OPC_TEQI;
13575 do_trapi:
13576 gen_trap(ctx, mips32_op, rs, -1, imm);
13577 break;
13578
13579 case BNEZC:
13580 case BEQZC:
13581 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13582 4, rs, 0, imm << 1, 0);
3c824109
NF
13583 /* Compact branches don't have a delay slot, so just let
13584 the normal delay slot handling take us to the branch
13585 target. */
13586 break;
13587 case LUI:
d75c135e 13588 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
13589 break;
13590 case SYNCI:
a83bddd6
DZ
13591 /* Break the TB to be able to sync copied instructions
13592 immediately */
13593 ctx->bstate = BS_STOP;
3c824109
NF
13594 break;
13595 case BC2F:
13596 case BC2T:
13597 /* COP2: Not implemented. */
13598 generate_exception_err(ctx, EXCP_CpU, 2);
13599 break;
13600 case BC1F:
13601 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13602 goto do_cp1branch;
13603 case BC1T:
13604 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13605 goto do_cp1branch;
13606 case BC1ANY4F:
13607 mips32_op = OPC_BC1FANY4;
13608 goto do_cp1mips3d;
13609 case BC1ANY4T:
13610 mips32_op = OPC_BC1TANY4;
13611 do_cp1mips3d:
13612 check_cop1x(ctx);
d75c135e 13613 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13614 /* Fall through */
13615 do_cp1branch:
d75c135e 13616 gen_compute_branch1(ctx, mips32_op,
3c824109 13617 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
13618 break;
13619 case BPOSGE64:
13620 case BPOSGE32:
13621 /* MIPS DSP: not implemented */
13622 /* Fall through */
13623 default:
13624 MIPS_INVAL("pool32i");
13625 generate_exception(ctx, EXCP_RI);
13626 break;
13627 }
13628 break;
13629 case POOL32C:
13630 minor = (ctx->opcode >> 12) & 0xf;
13631 switch (minor) {
13632 case LWL:
13633 mips32_op = OPC_LWL;
5c13fdfd 13634 goto do_ld_lr;
3c824109
NF
13635 case SWL:
13636 mips32_op = OPC_SWL;
5c13fdfd 13637 goto do_st_lr;
3c824109
NF
13638 case LWR:
13639 mips32_op = OPC_LWR;
5c13fdfd 13640 goto do_ld_lr;
3c824109
NF
13641 case SWR:
13642 mips32_op = OPC_SWR;
5c13fdfd 13643 goto do_st_lr;
3c824109
NF
13644#if defined(TARGET_MIPS64)
13645 case LDL:
13646 mips32_op = OPC_LDL;
5c13fdfd 13647 goto do_ld_lr;
3c824109
NF
13648 case SDL:
13649 mips32_op = OPC_SDL;
5c13fdfd 13650 goto do_st_lr;
3c824109
NF
13651 case LDR:
13652 mips32_op = OPC_LDR;
5c13fdfd 13653 goto do_ld_lr;
3c824109
NF
13654 case SDR:
13655 mips32_op = OPC_SDR;
5c13fdfd 13656 goto do_st_lr;
3c824109
NF
13657 case LWU:
13658 mips32_op = OPC_LWU;
5c13fdfd 13659 goto do_ld_lr;
3c824109
NF
13660 case LLD:
13661 mips32_op = OPC_LLD;
5c13fdfd 13662 goto do_ld_lr;
3c824109
NF
13663#endif
13664 case LL:
13665 mips32_op = OPC_LL;
5c13fdfd
AJ
13666 goto do_ld_lr;
13667 do_ld_lr:
d75c135e 13668 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13669 break;
13670 do_st_lr:
13671 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13672 break;
13673 case SC:
13674 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13675 break;
13676#if defined(TARGET_MIPS64)
13677 case SCD:
13678 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13679 break;
13680#endif
13681 case PREF:
13682 /* Treat as no-op */
13683 break;
13684 default:
13685 MIPS_INVAL("pool32c");
13686 generate_exception(ctx, EXCP_RI);
13687 break;
13688 }
13689 break;
13690 case ADDI32:
13691 mips32_op = OPC_ADDI;
13692 goto do_addi;
13693 case ADDIU32:
13694 mips32_op = OPC_ADDIU;
13695 do_addi:
d75c135e 13696 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13697 break;
13698
13699 /* Logical operations */
13700 case ORI32:
13701 mips32_op = OPC_ORI;
13702 goto do_logici;
13703 case XORI32:
13704 mips32_op = OPC_XORI;
13705 goto do_logici;
13706 case ANDI32:
13707 mips32_op = OPC_ANDI;
13708 do_logici:
d75c135e 13709 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13710 break;
13711
13712 /* Set less than immediate */
13713 case SLTI32:
13714 mips32_op = OPC_SLTI;
13715 goto do_slti;
13716 case SLTIU32:
13717 mips32_op = OPC_SLTIU;
13718 do_slti:
d75c135e 13719 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13720 break;
13721 case JALX32:
13722 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13723 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13724 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13725 break;
13726 case JALS32:
13727 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13728 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13729 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13730 break;
13731 case BEQ32:
b231c103 13732 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13733 break;
13734 case BNE32:
b231c103 13735 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13736 break;
13737 case J32:
13738 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13739 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13740 break;
13741 case JAL32:
13742 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13743 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13744 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13745 break;
13746 /* Floating point (COP1) */
13747 case LWC132:
13748 mips32_op = OPC_LWC1;
13749 goto do_cop1;
13750 case LDC132:
13751 mips32_op = OPC_LDC1;
13752 goto do_cop1;
13753 case SWC132:
13754 mips32_op = OPC_SWC1;
13755 goto do_cop1;
13756 case SDC132:
13757 mips32_op = OPC_SDC1;
13758 do_cop1:
5ab5c041 13759 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13760 break;
13761 case ADDIUPC:
13762 {
13763 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13764 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13765
13766 gen_addiupc(ctx, reg, offset, 0, 0);
13767 }
13768 break;
13769 /* Loads and stores */
13770 case LB32:
13771 mips32_op = OPC_LB;
5c13fdfd 13772 goto do_ld;
3c824109
NF
13773 case LBU32:
13774 mips32_op = OPC_LBU;
5c13fdfd 13775 goto do_ld;
3c824109
NF
13776 case LH32:
13777 mips32_op = OPC_LH;
5c13fdfd 13778 goto do_ld;
3c824109
NF
13779 case LHU32:
13780 mips32_op = OPC_LHU;
5c13fdfd 13781 goto do_ld;
3c824109
NF
13782 case LW32:
13783 mips32_op = OPC_LW;
5c13fdfd 13784 goto do_ld;
3c824109
NF
13785#ifdef TARGET_MIPS64
13786 case LD32:
13787 mips32_op = OPC_LD;
5c13fdfd 13788 goto do_ld;
3c824109
NF
13789 case SD32:
13790 mips32_op = OPC_SD;
5c13fdfd 13791 goto do_st;
3c824109
NF
13792#endif
13793 case SB32:
13794 mips32_op = OPC_SB;
5c13fdfd 13795 goto do_st;
3c824109
NF
13796 case SH32:
13797 mips32_op = OPC_SH;
5c13fdfd 13798 goto do_st;
3c824109
NF
13799 case SW32:
13800 mips32_op = OPC_SW;
5c13fdfd
AJ
13801 goto do_st;
13802 do_ld:
d75c135e 13803 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13804 break;
13805 do_st:
13806 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13807 break;
13808 default:
13809 generate_exception(ctx, EXCP_RI);
13810 break;
13811 }
13812}
13813
240ce26a 13814static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13815{
13816 uint32_t op;
13817
13818 /* make sure instructions are on a halfword boundary */
13819 if (ctx->pc & 0x1) {
13820 env->CP0_BadVAddr = ctx->pc;
13821 generate_exception(ctx, EXCP_AdEL);
13822 ctx->bstate = BS_STOP;
13823 return 2;
13824 }
13825
13826 op = (ctx->opcode >> 10) & 0x3f;
13827 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13828 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13829 switch (op & 0x7) { /* MSB-3..MSB-5 */
13830 case 0:
13831 /* POOL32A, POOL32B, POOL32I, POOL32C */
13832 case 4:
13833 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13834 case 5:
13835 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13836 case 6:
13837 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13838 case 7:
13839 /* LB32, LH32, LWC132, LDC132, LW32 */
13840 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13841 generate_exception(ctx, EXCP_RI);
13842 /* Just stop translation; the user is confused. */
13843 ctx->bstate = BS_STOP;
13844 return 2;
13845 }
13846 break;
b231c103
YK
13847 case 1:
13848 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13849 case 2:
13850 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13851 case 3:
13852 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13853 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13854 generate_exception(ctx, EXCP_RI);
13855 /* Just stop translation; the user is confused. */
13856 ctx->bstate = BS_STOP;
13857 return 2;
13858 }
13859 break;
3c824109
NF
13860 }
13861 }
b231c103 13862
3c824109
NF
13863 switch (op) {
13864 case POOL16A:
13865 {
13866 int rd = mmreg(uMIPS_RD(ctx->opcode));
13867 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13868 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13869 uint32_t opc = 0;
13870
13871 switch (ctx->opcode & 0x1) {
13872 case ADDU16:
13873 opc = OPC_ADDU;
13874 break;
13875 case SUBU16:
13876 opc = OPC_SUBU;
13877 break;
13878 }
13879
d75c135e 13880 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13881 }
13882 break;
13883 case POOL16B:
13884 {
13885 int rd = mmreg(uMIPS_RD(ctx->opcode));
13886 int rs = mmreg(uMIPS_RS(ctx->opcode));
13887 int amount = (ctx->opcode >> 1) & 0x7;
13888 uint32_t opc = 0;
13889 amount = amount == 0 ? 8 : amount;
13890
13891 switch (ctx->opcode & 0x1) {
13892 case SLL16:
13893 opc = OPC_SLL;
13894 break;
13895 case SRL16:
13896 opc = OPC_SRL;
13897 break;
13898 }
13899
d75c135e 13900 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
13901 }
13902 break;
13903 case POOL16C:
240ce26a 13904 gen_pool16c_insn(ctx);
3c824109
NF
13905 break;
13906 case LWGP16:
13907 {
13908 int rd = mmreg(uMIPS_RD(ctx->opcode));
13909 int rb = 28; /* GP */
13910 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13911
d75c135e 13912 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13913 }
13914 break;
13915 case POOL16F:
13916 if (ctx->opcode & 1) {
13917 generate_exception(ctx, EXCP_RI);
13918 } else {
13919 /* MOVEP */
13920 int enc_dest = uMIPS_RD(ctx->opcode);
13921 int enc_rt = uMIPS_RS2(ctx->opcode);
13922 int enc_rs = uMIPS_RS1(ctx->opcode);
13923 int rd, rs, re, rt;
13924 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13925 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13926 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13927
13928 rd = rd_enc[enc_dest];
13929 re = re_enc[enc_dest];
13930 rs = rs_rt_enc[enc_rs];
13931 rt = rs_rt_enc[enc_rt];
13932
d75c135e
AJ
13933 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13934 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
13935 }
13936 break;
13937 case LBU16:
13938 {
13939 int rd = mmreg(uMIPS_RD(ctx->opcode));
13940 int rb = mmreg(uMIPS_RS(ctx->opcode));
13941 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13942 offset = (offset == 0xf ? -1 : offset);
13943
d75c135e 13944 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
13945 }
13946 break;
13947 case LHU16:
13948 {
13949 int rd = mmreg(uMIPS_RD(ctx->opcode));
13950 int rb = mmreg(uMIPS_RS(ctx->opcode));
13951 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13952
d75c135e 13953 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
13954 }
13955 break;
13956 case LWSP16:
13957 {
13958 int rd = (ctx->opcode >> 5) & 0x1f;
13959 int rb = 29; /* SP */
13960 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13961
d75c135e 13962 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13963 }
13964 break;
13965 case LW16:
13966 {
13967 int rd = mmreg(uMIPS_RD(ctx->opcode));
13968 int rb = mmreg(uMIPS_RS(ctx->opcode));
13969 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13970
d75c135e 13971 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13972 }
13973 break;
13974 case SB16:
13975 {
13976 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13977 int rb = mmreg(uMIPS_RS(ctx->opcode));
13978 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13979
5c13fdfd 13980 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
13981 }
13982 break;
13983 case SH16:
13984 {
13985 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13986 int rb = mmreg(uMIPS_RS(ctx->opcode));
13987 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13988
5c13fdfd 13989 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
13990 }
13991 break;
13992 case SWSP16:
13993 {
13994 int rd = (ctx->opcode >> 5) & 0x1f;
13995 int rb = 29; /* SP */
13996 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13997
5c13fdfd 13998 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13999 }
14000 break;
14001 case SW16:
14002 {
14003 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14004 int rb = mmreg(uMIPS_RS(ctx->opcode));
14005 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14006
5c13fdfd 14007 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14008 }
14009 break;
14010 case MOVE16:
14011 {
14012 int rd = uMIPS_RD5(ctx->opcode);
14013 int rs = uMIPS_RS5(ctx->opcode);
14014
d75c135e 14015 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
14016 }
14017 break;
14018 case ANDI16:
d75c135e 14019 gen_andi16(ctx);
3c824109
NF
14020 break;
14021 case POOL16D:
14022 switch (ctx->opcode & 0x1) {
14023 case ADDIUS5:
d75c135e 14024 gen_addius5(ctx);
3c824109
NF
14025 break;
14026 case ADDIUSP:
d75c135e 14027 gen_addiusp(ctx);
3c824109
NF
14028 break;
14029 }
14030 break;
14031 case POOL16E:
14032 switch (ctx->opcode & 0x1) {
14033 case ADDIUR2:
d75c135e 14034 gen_addiur2(ctx);
3c824109
NF
14035 break;
14036 case ADDIUR1SP:
d75c135e 14037 gen_addiur1sp(ctx);
3c824109
NF
14038 break;
14039 }
14040 break;
14041 case B16:
14042 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14043 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14044 break;
14045 case BNEZ16:
14046 case BEQZ16:
14047 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14048 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14049 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14050 break;
14051 case LI16:
14052 {
14053 int reg = mmreg(uMIPS_RD(ctx->opcode));
14054 int imm = ZIMM(ctx->opcode, 0, 7);
14055
14056 imm = (imm == 0x7f ? -1 : imm);
14057 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14058 }
14059 break;
14060 case RES_20:
14061 case RES_28:
14062 case RES_29:
14063 case RES_30:
14064 case RES_31:
14065 case RES_38:
14066 case RES_39:
14067 generate_exception(ctx, EXCP_RI);
14068 break;
14069 default:
240ce26a 14070 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14071 return 4;
14072 }
14073
14074 return 2;
14075}
14076
14077/* SmartMIPS extension to MIPS32 */
14078
14079#if defined(TARGET_MIPS64)
14080
14081/* MDMX extension to MIPS64 */
14082
14083#endif
14084
9b1a1d68 14085/* MIPSDSP functions. */
d75c135e 14086static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14087 int rd, int base, int offset)
14088{
14089 const char *opn = "ldx";
14090 TCGv t0;
14091
9b1a1d68
JL
14092 check_dsp(ctx);
14093 t0 = tcg_temp_new();
14094
14095 if (base == 0) {
14096 gen_load_gpr(t0, offset);
14097 } else if (offset == 0) {
14098 gen_load_gpr(t0, base);
14099 } else {
14100 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14101 }
14102
9b1a1d68
JL
14103 switch (opc) {
14104 case OPC_LBUX:
5f68f5ae 14105 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14106 gen_store_gpr(t0, rd);
14107 opn = "lbux";
14108 break;
14109 case OPC_LHX:
5f68f5ae 14110 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14111 gen_store_gpr(t0, rd);
14112 opn = "lhx";
14113 break;
14114 case OPC_LWX:
5f68f5ae 14115 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14116 gen_store_gpr(t0, rd);
14117 opn = "lwx";
14118 break;
14119#if defined(TARGET_MIPS64)
14120 case OPC_LDX:
5f68f5ae 14121 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14122 gen_store_gpr(t0, rd);
14123 opn = "ldx";
14124 break;
14125#endif
14126 }
14127 (void)opn; /* avoid a compiler warning */
14128 MIPS_DEBUG("%s %s, %s(%s)", opn,
14129 regnames[rd], regnames[offset], regnames[base]);
14130 tcg_temp_free(t0);
14131}
14132
461c08df
JL
14133static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14134 int ret, int v1, int v2)
14135{
14136 const char *opn = "mipsdsp arith";
14137 TCGv v1_t;
14138 TCGv v2_t;
14139
14140 if (ret == 0) {
14141 /* Treat as NOP. */
14142 MIPS_DEBUG("NOP");
14143 return;
14144 }
14145
14146 v1_t = tcg_temp_new();
14147 v2_t = tcg_temp_new();
14148
14149 gen_load_gpr(v1_t, v1);
14150 gen_load_gpr(v2_t, v2);
14151
14152 switch (op1) {
14153 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14154 case OPC_MULT_G_2E:
14155 check_dspr2(ctx);
14156 switch (op2) {
14157 case OPC_ADDUH_QB:
14158 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14159 break;
14160 case OPC_ADDUH_R_QB:
14161 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14162 break;
14163 case OPC_ADDQH_PH:
14164 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14165 break;
14166 case OPC_ADDQH_R_PH:
14167 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14168 break;
14169 case OPC_ADDQH_W:
14170 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14171 break;
14172 case OPC_ADDQH_R_W:
14173 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14174 break;
14175 case OPC_SUBUH_QB:
14176 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14177 break;
14178 case OPC_SUBUH_R_QB:
14179 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14180 break;
14181 case OPC_SUBQH_PH:
14182 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14183 break;
14184 case OPC_SUBQH_R_PH:
14185 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14186 break;
14187 case OPC_SUBQH_W:
14188 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14189 break;
14190 case OPC_SUBQH_R_W:
14191 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14192 break;
14193 }
14194 break;
14195 case OPC_ABSQ_S_PH_DSP:
14196 switch (op2) {
14197 case OPC_ABSQ_S_QB:
14198 check_dspr2(ctx);
14199 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14200 break;
14201 case OPC_ABSQ_S_PH:
14202 check_dsp(ctx);
14203 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14204 break;
14205 case OPC_ABSQ_S_W:
14206 check_dsp(ctx);
14207 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14208 break;
14209 case OPC_PRECEQ_W_PHL:
14210 check_dsp(ctx);
14211 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14212 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14213 break;
14214 case OPC_PRECEQ_W_PHR:
14215 check_dsp(ctx);
14216 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14217 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14218 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14219 break;
14220 case OPC_PRECEQU_PH_QBL:
14221 check_dsp(ctx);
14222 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14223 break;
14224 case OPC_PRECEQU_PH_QBR:
14225 check_dsp(ctx);
14226 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14227 break;
14228 case OPC_PRECEQU_PH_QBLA:
14229 check_dsp(ctx);
14230 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14231 break;
14232 case OPC_PRECEQU_PH_QBRA:
14233 check_dsp(ctx);
14234 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14235 break;
14236 case OPC_PRECEU_PH_QBL:
14237 check_dsp(ctx);
14238 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14239 break;
14240 case OPC_PRECEU_PH_QBR:
14241 check_dsp(ctx);
14242 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14243 break;
14244 case OPC_PRECEU_PH_QBLA:
14245 check_dsp(ctx);
14246 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14247 break;
14248 case OPC_PRECEU_PH_QBRA:
14249 check_dsp(ctx);
14250 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14251 break;
14252 }
14253 break;
14254 case OPC_ADDU_QB_DSP:
14255 switch (op2) {
14256 case OPC_ADDQ_PH:
14257 check_dsp(ctx);
14258 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14259 break;
14260 case OPC_ADDQ_S_PH:
14261 check_dsp(ctx);
14262 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14263 break;
14264 case OPC_ADDQ_S_W:
14265 check_dsp(ctx);
14266 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14267 break;
14268 case OPC_ADDU_QB:
14269 check_dsp(ctx);
14270 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14271 break;
14272 case OPC_ADDU_S_QB:
14273 check_dsp(ctx);
14274 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14275 break;
14276 case OPC_ADDU_PH:
14277 check_dspr2(ctx);
14278 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14279 break;
14280 case OPC_ADDU_S_PH:
14281 check_dspr2(ctx);
14282 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14283 break;
14284 case OPC_SUBQ_PH:
14285 check_dsp(ctx);
14286 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14287 break;
14288 case OPC_SUBQ_S_PH:
14289 check_dsp(ctx);
14290 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14291 break;
14292 case OPC_SUBQ_S_W:
14293 check_dsp(ctx);
14294 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14295 break;
14296 case OPC_SUBU_QB:
14297 check_dsp(ctx);
14298 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14299 break;
14300 case OPC_SUBU_S_QB:
14301 check_dsp(ctx);
14302 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14303 break;
14304 case OPC_SUBU_PH:
14305 check_dspr2(ctx);
14306 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14307 break;
14308 case OPC_SUBU_S_PH:
14309 check_dspr2(ctx);
14310 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14311 break;
14312 case OPC_ADDSC:
14313 check_dsp(ctx);
14314 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14315 break;
14316 case OPC_ADDWC:
14317 check_dsp(ctx);
14318 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14319 break;
14320 case OPC_MODSUB:
14321 check_dsp(ctx);
14322 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14323 break;
14324 case OPC_RADDU_W_QB:
14325 check_dsp(ctx);
14326 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14327 break;
14328 }
14329 break;
14330 case OPC_CMPU_EQ_QB_DSP:
14331 switch (op2) {
14332 case OPC_PRECR_QB_PH:
14333 check_dspr2(ctx);
14334 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14335 break;
14336 case OPC_PRECRQ_QB_PH:
14337 check_dsp(ctx);
14338 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14339 break;
14340 case OPC_PRECR_SRA_PH_W:
14341 check_dspr2(ctx);
14342 {
14343 TCGv_i32 sa_t = tcg_const_i32(v2);
14344 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14345 cpu_gpr[ret]);
14346 tcg_temp_free_i32(sa_t);
14347 break;
14348 }
14349 case OPC_PRECR_SRA_R_PH_W:
14350 check_dspr2(ctx);
14351 {
14352 TCGv_i32 sa_t = tcg_const_i32(v2);
14353 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14354 cpu_gpr[ret]);
14355 tcg_temp_free_i32(sa_t);
14356 break;
14357 }
14358 case OPC_PRECRQ_PH_W:
14359 check_dsp(ctx);
14360 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14361 break;
14362 case OPC_PRECRQ_RS_PH_W:
14363 check_dsp(ctx);
14364 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14365 break;
14366 case OPC_PRECRQU_S_QB_PH:
14367 check_dsp(ctx);
14368 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14369 break;
14370 }
14371 break;
14372#ifdef TARGET_MIPS64
14373 case OPC_ABSQ_S_QH_DSP:
14374 switch (op2) {
14375 case OPC_PRECEQ_L_PWL:
14376 check_dsp(ctx);
14377 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14378 break;
14379 case OPC_PRECEQ_L_PWR:
14380 check_dsp(ctx);
14381 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14382 break;
14383 case OPC_PRECEQ_PW_QHL:
14384 check_dsp(ctx);
14385 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14386 break;
14387 case OPC_PRECEQ_PW_QHR:
14388 check_dsp(ctx);
14389 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14390 break;
14391 case OPC_PRECEQ_PW_QHLA:
14392 check_dsp(ctx);
14393 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14394 break;
14395 case OPC_PRECEQ_PW_QHRA:
14396 check_dsp(ctx);
14397 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14398 break;
14399 case OPC_PRECEQU_QH_OBL:
14400 check_dsp(ctx);
14401 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14402 break;
14403 case OPC_PRECEQU_QH_OBR:
14404 check_dsp(ctx);
14405 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14406 break;
14407 case OPC_PRECEQU_QH_OBLA:
14408 check_dsp(ctx);
14409 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14410 break;
14411 case OPC_PRECEQU_QH_OBRA:
14412 check_dsp(ctx);
14413 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14414 break;
14415 case OPC_PRECEU_QH_OBL:
14416 check_dsp(ctx);
14417 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14418 break;
14419 case OPC_PRECEU_QH_OBR:
14420 check_dsp(ctx);
14421 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14422 break;
14423 case OPC_PRECEU_QH_OBLA:
14424 check_dsp(ctx);
14425 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14426 break;
14427 case OPC_PRECEU_QH_OBRA:
14428 check_dsp(ctx);
14429 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14430 break;
14431 case OPC_ABSQ_S_OB:
14432 check_dspr2(ctx);
14433 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14434 break;
14435 case OPC_ABSQ_S_PW:
14436 check_dsp(ctx);
14437 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14438 break;
14439 case OPC_ABSQ_S_QH:
14440 check_dsp(ctx);
14441 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14442 break;
14443 }
14444 break;
14445 case OPC_ADDU_OB_DSP:
14446 switch (op2) {
14447 case OPC_RADDU_L_OB:
14448 check_dsp(ctx);
14449 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14450 break;
14451 case OPC_SUBQ_PW:
14452 check_dsp(ctx);
14453 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14454 break;
14455 case OPC_SUBQ_S_PW:
14456 check_dsp(ctx);
14457 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14458 break;
14459 case OPC_SUBQ_QH:
14460 check_dsp(ctx);
14461 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14462 break;
14463 case OPC_SUBQ_S_QH:
14464 check_dsp(ctx);
14465 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14466 break;
14467 case OPC_SUBU_OB:
14468 check_dsp(ctx);
14469 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14470 break;
14471 case OPC_SUBU_S_OB:
14472 check_dsp(ctx);
14473 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14474 break;
14475 case OPC_SUBU_QH:
14476 check_dspr2(ctx);
14477 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14478 break;
14479 case OPC_SUBU_S_QH:
14480 check_dspr2(ctx);
14481 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14482 break;
14483 case OPC_SUBUH_OB:
14484 check_dspr2(ctx);
14485 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14486 break;
14487 case OPC_SUBUH_R_OB:
14488 check_dspr2(ctx);
14489 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14490 break;
14491 case OPC_ADDQ_PW:
14492 check_dsp(ctx);
14493 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14494 break;
14495 case OPC_ADDQ_S_PW:
14496 check_dsp(ctx);
14497 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14498 break;
14499 case OPC_ADDQ_QH:
14500 check_dsp(ctx);
14501 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14502 break;
14503 case OPC_ADDQ_S_QH:
14504 check_dsp(ctx);
14505 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14506 break;
14507 case OPC_ADDU_OB:
14508 check_dsp(ctx);
14509 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14510 break;
14511 case OPC_ADDU_S_OB:
14512 check_dsp(ctx);
14513 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14514 break;
14515 case OPC_ADDU_QH:
14516 check_dspr2(ctx);
14517 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14518 break;
14519 case OPC_ADDU_S_QH:
14520 check_dspr2(ctx);
14521 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14522 break;
14523 case OPC_ADDUH_OB:
14524 check_dspr2(ctx);
14525 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14526 break;
14527 case OPC_ADDUH_R_OB:
14528 check_dspr2(ctx);
14529 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14530 break;
14531 }
14532 break;
14533 case OPC_CMPU_EQ_OB_DSP:
14534 switch (op2) {
14535 case OPC_PRECR_OB_QH:
14536 check_dspr2(ctx);
14537 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14538 break;
14539 case OPC_PRECR_SRA_QH_PW:
14540 check_dspr2(ctx);
14541 {
14542 TCGv_i32 ret_t = tcg_const_i32(ret);
14543 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14544 tcg_temp_free_i32(ret_t);
14545 break;
14546 }
14547 case OPC_PRECR_SRA_R_QH_PW:
14548 check_dspr2(ctx);
14549 {
14550 TCGv_i32 sa_v = tcg_const_i32(ret);
14551 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14552 tcg_temp_free_i32(sa_v);
14553 break;
14554 }
14555 case OPC_PRECRQ_OB_QH:
14556 check_dsp(ctx);
14557 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14558 break;
14559 case OPC_PRECRQ_PW_L:
14560 check_dsp(ctx);
14561 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14562 break;
14563 case OPC_PRECRQ_QH_PW:
14564 check_dsp(ctx);
14565 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14566 break;
14567 case OPC_PRECRQ_RS_QH_PW:
14568 check_dsp(ctx);
14569 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14570 break;
14571 case OPC_PRECRQU_S_OB_QH:
14572 check_dsp(ctx);
14573 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14574 break;
14575 }
14576 break;
14577#endif
14578 }
14579
14580 tcg_temp_free(v1_t);
14581 tcg_temp_free(v2_t);
14582
14583 (void)opn; /* avoid a compiler warning */
14584 MIPS_DEBUG("%s", opn);
14585}
9b1a1d68 14586
77c5fa8b
JL
14587static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14588 int ret, int v1, int v2)
14589{
14590 uint32_t op2;
14591 const char *opn = "mipsdsp shift";
14592 TCGv t0;
14593 TCGv v1_t;
14594 TCGv v2_t;
14595
14596 if (ret == 0) {
14597 /* Treat as NOP. */
14598 MIPS_DEBUG("NOP");
14599 return;
14600 }
14601
14602 t0 = tcg_temp_new();
14603 v1_t = tcg_temp_new();
14604 v2_t = tcg_temp_new();
14605
14606 tcg_gen_movi_tl(t0, v1);
14607 gen_load_gpr(v1_t, v1);
14608 gen_load_gpr(v2_t, v2);
14609
14610 switch (opc) {
14611 case OPC_SHLL_QB_DSP:
14612 {
14613 op2 = MASK_SHLL_QB(ctx->opcode);
14614 switch (op2) {
14615 case OPC_SHLL_QB:
14616 check_dsp(ctx);
14617 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14618 break;
14619 case OPC_SHLLV_QB:
14620 check_dsp(ctx);
14621 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14622 break;
14623 case OPC_SHLL_PH:
14624 check_dsp(ctx);
14625 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14626 break;
14627 case OPC_SHLLV_PH:
14628 check_dsp(ctx);
14629 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14630 break;
14631 case OPC_SHLL_S_PH:
14632 check_dsp(ctx);
14633 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14634 break;
14635 case OPC_SHLLV_S_PH:
14636 check_dsp(ctx);
14637 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14638 break;
14639 case OPC_SHLL_S_W:
14640 check_dsp(ctx);
14641 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14642 break;
14643 case OPC_SHLLV_S_W:
14644 check_dsp(ctx);
14645 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14646 break;
14647 case OPC_SHRL_QB:
14648 check_dsp(ctx);
14649 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14650 break;
14651 case OPC_SHRLV_QB:
14652 check_dsp(ctx);
14653 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14654 break;
14655 case OPC_SHRL_PH:
14656 check_dspr2(ctx);
14657 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14658 break;
14659 case OPC_SHRLV_PH:
14660 check_dspr2(ctx);
14661 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14662 break;
14663 case OPC_SHRA_QB:
14664 check_dspr2(ctx);
14665 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14666 break;
14667 case OPC_SHRA_R_QB:
14668 check_dspr2(ctx);
14669 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14670 break;
14671 case OPC_SHRAV_QB:
14672 check_dspr2(ctx);
14673 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14674 break;
14675 case OPC_SHRAV_R_QB:
14676 check_dspr2(ctx);
14677 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14678 break;
14679 case OPC_SHRA_PH:
14680 check_dsp(ctx);
14681 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14682 break;
14683 case OPC_SHRA_R_PH:
14684 check_dsp(ctx);
14685 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14686 break;
14687 case OPC_SHRAV_PH:
14688 check_dsp(ctx);
14689 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14690 break;
14691 case OPC_SHRAV_R_PH:
14692 check_dsp(ctx);
14693 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14694 break;
14695 case OPC_SHRA_R_W:
14696 check_dsp(ctx);
14697 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14698 break;
14699 case OPC_SHRAV_R_W:
14700 check_dsp(ctx);
14701 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14702 break;
14703 default: /* Invalid */
14704 MIPS_INVAL("MASK SHLL.QB");
14705 generate_exception(ctx, EXCP_RI);
14706 break;
14707 }
14708 break;
14709 }
14710#ifdef TARGET_MIPS64
14711 case OPC_SHLL_OB_DSP:
14712 op2 = MASK_SHLL_OB(ctx->opcode);
14713 switch (op2) {
14714 case OPC_SHLL_PW:
14715 check_dsp(ctx);
14716 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14717 break;
14718 case OPC_SHLLV_PW:
14719 check_dsp(ctx);
14720 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14721 break;
14722 case OPC_SHLL_S_PW:
14723 check_dsp(ctx);
14724 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14725 break;
14726 case OPC_SHLLV_S_PW:
14727 check_dsp(ctx);
14728 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14729 break;
14730 case OPC_SHLL_OB:
14731 check_dsp(ctx);
14732 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14733 break;
14734 case OPC_SHLLV_OB:
14735 check_dsp(ctx);
14736 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14737 break;
14738 case OPC_SHLL_QH:
14739 check_dsp(ctx);
14740 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14741 break;
14742 case OPC_SHLLV_QH:
14743 check_dsp(ctx);
14744 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14745 break;
14746 case OPC_SHLL_S_QH:
14747 check_dsp(ctx);
14748 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14749 break;
14750 case OPC_SHLLV_S_QH:
14751 check_dsp(ctx);
14752 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14753 break;
14754 case OPC_SHRA_OB:
14755 check_dspr2(ctx);
14756 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14757 break;
14758 case OPC_SHRAV_OB:
14759 check_dspr2(ctx);
14760 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14761 break;
14762 case OPC_SHRA_R_OB:
14763 check_dspr2(ctx);
14764 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14765 break;
14766 case OPC_SHRAV_R_OB:
14767 check_dspr2(ctx);
14768 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14769 break;
14770 case OPC_SHRA_PW:
14771 check_dsp(ctx);
14772 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14773 break;
14774 case OPC_SHRAV_PW:
14775 check_dsp(ctx);
14776 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14777 break;
14778 case OPC_SHRA_R_PW:
14779 check_dsp(ctx);
14780 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14781 break;
14782 case OPC_SHRAV_R_PW:
14783 check_dsp(ctx);
14784 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14785 break;
14786 case OPC_SHRA_QH:
14787 check_dsp(ctx);
14788 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14789 break;
14790 case OPC_SHRAV_QH:
14791 check_dsp(ctx);
14792 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14793 break;
14794 case OPC_SHRA_R_QH:
14795 check_dsp(ctx);
14796 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14797 break;
14798 case OPC_SHRAV_R_QH:
14799 check_dsp(ctx);
14800 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14801 break;
14802 case OPC_SHRL_OB:
14803 check_dsp(ctx);
14804 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14805 break;
14806 case OPC_SHRLV_OB:
14807 check_dsp(ctx);
14808 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14809 break;
14810 case OPC_SHRL_QH:
14811 check_dspr2(ctx);
14812 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14813 break;
14814 case OPC_SHRLV_QH:
14815 check_dspr2(ctx);
14816 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14817 break;
14818 default: /* Invalid */
14819 MIPS_INVAL("MASK SHLL.OB");
14820 generate_exception(ctx, EXCP_RI);
14821 break;
14822 }
14823 break;
14824#endif
14825 }
14826
14827 tcg_temp_free(t0);
14828 tcg_temp_free(v1_t);
14829 tcg_temp_free(v2_t);
14830 (void)opn; /* avoid a compiler warning */
14831 MIPS_DEBUG("%s", opn);
14832}
14833
a22260ae
JL
14834static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14835 int ret, int v1, int v2, int check_ret)
14836{
14837 const char *opn = "mipsdsp multiply";
14838 TCGv_i32 t0;
14839 TCGv v1_t;
14840 TCGv v2_t;
14841
14842 if ((ret == 0) && (check_ret == 1)) {
14843 /* Treat as NOP. */
14844 MIPS_DEBUG("NOP");
14845 return;
14846 }
14847
14848 t0 = tcg_temp_new_i32();
14849 v1_t = tcg_temp_new();
14850 v2_t = tcg_temp_new();
14851
14852 tcg_gen_movi_i32(t0, ret);
14853 gen_load_gpr(v1_t, v1);
14854 gen_load_gpr(v2_t, v2);
14855
14856 switch (op1) {
14857 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14858 * the same mask and op1. */
14859 case OPC_MULT_G_2E:
639eadb9 14860 check_dspr2(ctx);
a22260ae
JL
14861 switch (op2) {
14862 case OPC_MUL_PH:
14863 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14864 break;
14865 case OPC_MUL_S_PH:
14866 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14867 break;
14868 case OPC_MULQ_S_W:
14869 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14870 break;
14871 case OPC_MULQ_RS_W:
14872 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14873 break;
14874 }
14875 break;
14876 case OPC_DPA_W_PH_DSP:
14877 switch (op2) {
14878 case OPC_DPAU_H_QBL:
14879 check_dsp(ctx);
14880 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14881 break;
14882 case OPC_DPAU_H_QBR:
14883 check_dsp(ctx);
14884 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14885 break;
14886 case OPC_DPSU_H_QBL:
14887 check_dsp(ctx);
14888 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14889 break;
14890 case OPC_DPSU_H_QBR:
14891 check_dsp(ctx);
14892 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14893 break;
14894 case OPC_DPA_W_PH:
14895 check_dspr2(ctx);
14896 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14897 break;
14898 case OPC_DPAX_W_PH:
14899 check_dspr2(ctx);
14900 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14901 break;
14902 case OPC_DPAQ_S_W_PH:
14903 check_dsp(ctx);
14904 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14905 break;
14906 case OPC_DPAQX_S_W_PH:
14907 check_dspr2(ctx);
14908 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14909 break;
14910 case OPC_DPAQX_SA_W_PH:
14911 check_dspr2(ctx);
14912 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14913 break;
14914 case OPC_DPS_W_PH:
14915 check_dspr2(ctx);
14916 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14917 break;
14918 case OPC_DPSX_W_PH:
14919 check_dspr2(ctx);
14920 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
14921 break;
14922 case OPC_DPSQ_S_W_PH:
14923 check_dsp(ctx);
14924 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14925 break;
14926 case OPC_DPSQX_S_W_PH:
14927 check_dspr2(ctx);
14928 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14929 break;
14930 case OPC_DPSQX_SA_W_PH:
14931 check_dspr2(ctx);
14932 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14933 break;
14934 case OPC_MULSAQ_S_W_PH:
14935 check_dsp(ctx);
14936 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14937 break;
14938 case OPC_DPAQ_SA_L_W:
14939 check_dsp(ctx);
14940 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14941 break;
14942 case OPC_DPSQ_SA_L_W:
14943 check_dsp(ctx);
14944 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14945 break;
14946 case OPC_MAQ_S_W_PHL:
14947 check_dsp(ctx);
14948 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
14949 break;
14950 case OPC_MAQ_S_W_PHR:
14951 check_dsp(ctx);
14952 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
14953 break;
14954 case OPC_MAQ_SA_W_PHL:
14955 check_dsp(ctx);
14956 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
14957 break;
14958 case OPC_MAQ_SA_W_PHR:
14959 check_dsp(ctx);
14960 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
14961 break;
14962 case OPC_MULSA_W_PH:
14963 check_dspr2(ctx);
14964 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
14965 break;
14966 }
14967 break;
14968#ifdef TARGET_MIPS64
14969 case OPC_DPAQ_W_QH_DSP:
14970 {
14971 int ac = ret & 0x03;
14972 tcg_gen_movi_i32(t0, ac);
14973
14974 switch (op2) {
14975 case OPC_DMADD:
14976 check_dsp(ctx);
14977 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
14978 break;
14979 case OPC_DMADDU:
14980 check_dsp(ctx);
14981 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
14982 break;
14983 case OPC_DMSUB:
14984 check_dsp(ctx);
14985 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
14986 break;
14987 case OPC_DMSUBU:
14988 check_dsp(ctx);
14989 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
14990 break;
14991 case OPC_DPA_W_QH:
14992 check_dspr2(ctx);
14993 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
14994 break;
14995 case OPC_DPAQ_S_W_QH:
14996 check_dsp(ctx);
14997 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14998 break;
14999 case OPC_DPAQ_SA_L_PW:
15000 check_dsp(ctx);
15001 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15002 break;
15003 case OPC_DPAU_H_OBL:
15004 check_dsp(ctx);
15005 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15006 break;
15007 case OPC_DPAU_H_OBR:
15008 check_dsp(ctx);
15009 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15010 break;
15011 case OPC_DPS_W_QH:
15012 check_dspr2(ctx);
15013 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15014 break;
15015 case OPC_DPSQ_S_W_QH:
15016 check_dsp(ctx);
15017 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15018 break;
15019 case OPC_DPSQ_SA_L_PW:
15020 check_dsp(ctx);
15021 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15022 break;
15023 case OPC_DPSU_H_OBL:
15024 check_dsp(ctx);
15025 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15026 break;
15027 case OPC_DPSU_H_OBR:
15028 check_dsp(ctx);
15029 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15030 break;
15031 case OPC_MAQ_S_L_PWL:
15032 check_dsp(ctx);
15033 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15034 break;
15035 case OPC_MAQ_S_L_PWR:
15036 check_dsp(ctx);
15037 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15038 break;
15039 case OPC_MAQ_S_W_QHLL:
15040 check_dsp(ctx);
15041 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15042 break;
15043 case OPC_MAQ_SA_W_QHLL:
15044 check_dsp(ctx);
15045 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15046 break;
15047 case OPC_MAQ_S_W_QHLR:
15048 check_dsp(ctx);
15049 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15050 break;
15051 case OPC_MAQ_SA_W_QHLR:
15052 check_dsp(ctx);
15053 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15054 break;
15055 case OPC_MAQ_S_W_QHRL:
15056 check_dsp(ctx);
15057 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15058 break;
15059 case OPC_MAQ_SA_W_QHRL:
15060 check_dsp(ctx);
15061 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15062 break;
15063 case OPC_MAQ_S_W_QHRR:
15064 check_dsp(ctx);
15065 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15066 break;
15067 case OPC_MAQ_SA_W_QHRR:
15068 check_dsp(ctx);
15069 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15070 break;
15071 case OPC_MULSAQ_S_L_PW:
15072 check_dsp(ctx);
15073 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15074 break;
15075 case OPC_MULSAQ_S_W_QH:
15076 check_dsp(ctx);
15077 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15078 break;
15079 }
15080 }
15081 break;
15082#endif
15083 case OPC_ADDU_QB_DSP:
15084 switch (op2) {
15085 case OPC_MULEU_S_PH_QBL:
15086 check_dsp(ctx);
15087 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15088 break;
15089 case OPC_MULEU_S_PH_QBR:
15090 check_dsp(ctx);
15091 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15092 break;
15093 case OPC_MULQ_RS_PH:
15094 check_dsp(ctx);
15095 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15096 break;
15097 case OPC_MULEQ_S_W_PHL:
15098 check_dsp(ctx);
15099 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15100 break;
15101 case OPC_MULEQ_S_W_PHR:
15102 check_dsp(ctx);
15103 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15104 break;
15105 case OPC_MULQ_S_PH:
15106 check_dspr2(ctx);
15107 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15108 break;
15109 }
15110 break;
15111#ifdef TARGET_MIPS64
15112 case OPC_ADDU_OB_DSP:
15113 switch (op2) {
15114 case OPC_MULEQ_S_PW_QHL:
15115 check_dsp(ctx);
15116 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15117 break;
15118 case OPC_MULEQ_S_PW_QHR:
15119 check_dsp(ctx);
15120 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15121 break;
15122 case OPC_MULEU_S_QH_OBL:
15123 check_dsp(ctx);
15124 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15125 break;
15126 case OPC_MULEU_S_QH_OBR:
15127 check_dsp(ctx);
15128 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15129 break;
15130 case OPC_MULQ_RS_QH:
15131 check_dsp(ctx);
15132 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15133 break;
15134 }
15135 break;
15136#endif
15137 }
15138
15139 tcg_temp_free_i32(t0);
15140 tcg_temp_free(v1_t);
15141 tcg_temp_free(v2_t);
15142
15143 (void)opn; /* avoid a compiler warning */
15144 MIPS_DEBUG("%s", opn);
15145
15146}
15147
d75c135e 15148static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15149 int ret, int val)
15150{
15151 const char *opn = "mipsdsp Bit/ Manipulation";
15152 int16_t imm;
15153 TCGv t0;
15154 TCGv val_t;
15155
15156 if (ret == 0) {
15157 /* Treat as NOP. */
15158 MIPS_DEBUG("NOP");
15159 return;
15160 }
15161
15162 t0 = tcg_temp_new();
15163 val_t = tcg_temp_new();
15164 gen_load_gpr(val_t, val);
15165
15166 switch (op1) {
15167 case OPC_ABSQ_S_PH_DSP:
15168 switch (op2) {
15169 case OPC_BITREV:
15170 check_dsp(ctx);
15171 gen_helper_bitrev(cpu_gpr[ret], val_t);
15172 break;
15173 case OPC_REPL_QB:
15174 check_dsp(ctx);
15175 {
15176 target_long result;
15177 imm = (ctx->opcode >> 16) & 0xFF;
15178 result = (uint32_t)imm << 24 |
15179 (uint32_t)imm << 16 |
15180 (uint32_t)imm << 8 |
15181 (uint32_t)imm;
15182 result = (int32_t)result;
15183 tcg_gen_movi_tl(cpu_gpr[ret], result);
15184 }
15185 break;
15186 case OPC_REPLV_QB:
15187 check_dsp(ctx);
15188 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15189 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15190 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15191 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15192 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15193 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15194 break;
15195 case OPC_REPL_PH:
15196 check_dsp(ctx);
15197 {
15198 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15199 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15200 tcg_gen_movi_tl(cpu_gpr[ret], \
15201 (target_long)((int32_t)imm << 16 | \
c4aaba92 15202 (uint16_t)imm));
1cb6686c
JL
15203 }
15204 break;
15205 case OPC_REPLV_PH:
15206 check_dsp(ctx);
15207 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15208 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15209 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15210 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15211 break;
15212 }
15213 break;
15214#ifdef TARGET_MIPS64
15215 case OPC_ABSQ_S_QH_DSP:
15216 switch (op2) {
15217 case OPC_REPL_OB:
15218 check_dsp(ctx);
15219 {
15220 target_long temp;
15221
15222 imm = (ctx->opcode >> 16) & 0xFF;
15223 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15224 temp = (temp << 16) | temp;
15225 temp = (temp << 32) | temp;
15226 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15227 break;
15228 }
15229 case OPC_REPL_PW:
15230 check_dsp(ctx);
15231 {
15232 target_long temp;
15233
15234 imm = (ctx->opcode >> 16) & 0x03FF;
15235 imm = (int16_t)(imm << 6) >> 6;
15236 temp = ((target_long)imm << 32) \
15237 | ((target_long)imm & 0xFFFFFFFF);
15238 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15239 break;
15240 }
15241 case OPC_REPL_QH:
15242 check_dsp(ctx);
15243 {
15244 target_long temp;
15245
15246 imm = (ctx->opcode >> 16) & 0x03FF;
15247 imm = (int16_t)(imm << 6) >> 6;
15248
15249 temp = ((uint64_t)(uint16_t)imm << 48) |
15250 ((uint64_t)(uint16_t)imm << 32) |
15251 ((uint64_t)(uint16_t)imm << 16) |
15252 (uint64_t)(uint16_t)imm;
15253 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15254 break;
15255 }
15256 case OPC_REPLV_OB:
15257 check_dsp(ctx);
15258 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15259 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15260 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15261 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15262 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15263 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15264 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15265 break;
15266 case OPC_REPLV_PW:
15267 check_dsp(ctx);
15268 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15269 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15270 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15271 break;
15272 case OPC_REPLV_QH:
15273 check_dsp(ctx);
15274 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15275 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15276 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15277 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15278 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15279 break;
15280 }
15281 break;
15282#endif
15283 }
15284 tcg_temp_free(t0);
15285 tcg_temp_free(val_t);
15286
15287 (void)opn; /* avoid a compiler warning */
15288 MIPS_DEBUG("%s", opn);
15289}
15290
26690560
JL
15291static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15292 uint32_t op1, uint32_t op2,
15293 int ret, int v1, int v2, int check_ret)
15294{
15295 const char *opn = "mipsdsp add compare pick";
26690560
JL
15296 TCGv t1;
15297 TCGv v1_t;
15298 TCGv v2_t;
15299
15300 if ((ret == 0) && (check_ret == 1)) {
15301 /* Treat as NOP. */
15302 MIPS_DEBUG("NOP");
15303 return;
15304 }
15305
26690560
JL
15306 t1 = tcg_temp_new();
15307 v1_t = tcg_temp_new();
15308 v2_t = tcg_temp_new();
15309
15310 gen_load_gpr(v1_t, v1);
15311 gen_load_gpr(v2_t, v2);
15312
15313 switch (op1) {
26690560
JL
15314 case OPC_CMPU_EQ_QB_DSP:
15315 switch (op2) {
15316 case OPC_CMPU_EQ_QB:
15317 check_dsp(ctx);
15318 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15319 break;
15320 case OPC_CMPU_LT_QB:
15321 check_dsp(ctx);
15322 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15323 break;
15324 case OPC_CMPU_LE_QB:
15325 check_dsp(ctx);
15326 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15327 break;
15328 case OPC_CMPGU_EQ_QB:
15329 check_dsp(ctx);
15330 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15331 break;
15332 case OPC_CMPGU_LT_QB:
15333 check_dsp(ctx);
15334 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15335 break;
15336 case OPC_CMPGU_LE_QB:
15337 check_dsp(ctx);
15338 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15339 break;
15340 case OPC_CMPGDU_EQ_QB:
15341 check_dspr2(ctx);
15342 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15343 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15344 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15345 tcg_gen_shli_tl(t1, t1, 24);
15346 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15347 break;
15348 case OPC_CMPGDU_LT_QB:
15349 check_dspr2(ctx);
15350 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15351 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15352 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15353 tcg_gen_shli_tl(t1, t1, 24);
15354 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15355 break;
15356 case OPC_CMPGDU_LE_QB:
15357 check_dspr2(ctx);
15358 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15359 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15360 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15361 tcg_gen_shli_tl(t1, t1, 24);
15362 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15363 break;
15364 case OPC_CMP_EQ_PH:
15365 check_dsp(ctx);
15366 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15367 break;
15368 case OPC_CMP_LT_PH:
15369 check_dsp(ctx);
15370 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15371 break;
15372 case OPC_CMP_LE_PH:
15373 check_dsp(ctx);
15374 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15375 break;
15376 case OPC_PICK_QB:
15377 check_dsp(ctx);
15378 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15379 break;
15380 case OPC_PICK_PH:
15381 check_dsp(ctx);
15382 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15383 break;
15384 case OPC_PACKRL_PH:
15385 check_dsp(ctx);
15386 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15387 break;
15388 }
15389 break;
15390#ifdef TARGET_MIPS64
15391 case OPC_CMPU_EQ_OB_DSP:
15392 switch (op2) {
15393 case OPC_CMP_EQ_PW:
15394 check_dsp(ctx);
15395 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15396 break;
15397 case OPC_CMP_LT_PW:
15398 check_dsp(ctx);
15399 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15400 break;
15401 case OPC_CMP_LE_PW:
15402 check_dsp(ctx);
15403 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15404 break;
15405 case OPC_CMP_EQ_QH:
15406 check_dsp(ctx);
15407 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15408 break;
15409 case OPC_CMP_LT_QH:
15410 check_dsp(ctx);
15411 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15412 break;
15413 case OPC_CMP_LE_QH:
15414 check_dsp(ctx);
15415 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15416 break;
15417 case OPC_CMPGDU_EQ_OB:
15418 check_dspr2(ctx);
15419 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15420 break;
15421 case OPC_CMPGDU_LT_OB:
15422 check_dspr2(ctx);
15423 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15424 break;
15425 case OPC_CMPGDU_LE_OB:
15426 check_dspr2(ctx);
15427 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15428 break;
15429 case OPC_CMPGU_EQ_OB:
15430 check_dsp(ctx);
15431 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15432 break;
15433 case OPC_CMPGU_LT_OB:
15434 check_dsp(ctx);
15435 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15436 break;
15437 case OPC_CMPGU_LE_OB:
15438 check_dsp(ctx);
15439 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15440 break;
15441 case OPC_CMPU_EQ_OB:
15442 check_dsp(ctx);
15443 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15444 break;
15445 case OPC_CMPU_LT_OB:
15446 check_dsp(ctx);
15447 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15448 break;
15449 case OPC_CMPU_LE_OB:
15450 check_dsp(ctx);
15451 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15452 break;
15453 case OPC_PACKRL_PW:
15454 check_dsp(ctx);
15455 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15456 break;
15457 case OPC_PICK_OB:
15458 check_dsp(ctx);
15459 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15460 break;
15461 case OPC_PICK_PW:
15462 check_dsp(ctx);
15463 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15464 break;
15465 case OPC_PICK_QH:
15466 check_dsp(ctx);
15467 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15468 break;
15469 }
15470 break;
df6126a7
AJ
15471#endif
15472 }
15473
15474 tcg_temp_free(t1);
15475 tcg_temp_free(v1_t);
15476 tcg_temp_free(v2_t);
15477
15478 (void)opn; /* avoid a compiler warning */
15479 MIPS_DEBUG("%s", opn);
15480}
15481
15482static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15483 uint32_t op1, int rt, int rs, int sa)
15484{
15485 const char *opn = "mipsdsp append/dappend";
15486 TCGv t0;
15487
15488 check_dspr2(ctx);
15489
15490 if (rt == 0) {
15491 /* Treat as NOP. */
15492 MIPS_DEBUG("NOP");
15493 return;
15494 }
15495
15496 t0 = tcg_temp_new();
15497 gen_load_gpr(t0, rs);
15498
15499 switch (op1) {
15500 case OPC_APPEND_DSP:
15501 switch (MASK_APPEND(ctx->opcode)) {
15502 case OPC_APPEND:
15503 if (sa != 0) {
15504 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15505 }
15506 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15507 break;
15508 case OPC_PREPEND:
15509 if (sa != 0) {
15510 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15511 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15512 tcg_gen_shli_tl(t0, t0, 32 - sa);
15513 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15514 }
15515 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15516 break;
15517 case OPC_BALIGN:
15518 sa &= 3;
15519 if (sa != 0 && sa != 2) {
15520 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15521 tcg_gen_ext32u_tl(t0, t0);
15522 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15523 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15524 }
15525 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15526 break;
15527 default: /* Invalid */
15528 MIPS_INVAL("MASK APPEND");
15529 generate_exception(ctx, EXCP_RI);
15530 break;
15531 }
15532 break;
15533#ifdef TARGET_MIPS64
26690560 15534 case OPC_DAPPEND_DSP:
df6126a7 15535 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15536 case OPC_DAPPEND:
df6126a7
AJ
15537 if (sa != 0) {
15538 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15539 }
26690560
JL
15540 break;
15541 case OPC_PREPENDD:
df6126a7
AJ
15542 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15543 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15544 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15545 break;
15546 case OPC_PREPENDW:
df6126a7
AJ
15547 if (sa != 0) {
15548 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15549 tcg_gen_shli_tl(t0, t0, 64 - sa);
15550 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15551 }
26690560
JL
15552 break;
15553 case OPC_DBALIGN:
df6126a7
AJ
15554 sa &= 7;
15555 if (sa != 0 && sa != 2 && sa != 4) {
15556 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15557 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15558 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15559 }
26690560
JL
15560 break;
15561 default: /* Invalid */
15562 MIPS_INVAL("MASK DAPPEND");
15563 generate_exception(ctx, EXCP_RI);
15564 break;
15565 }
15566 break;
15567#endif
15568 }
df6126a7 15569 tcg_temp_free(t0);
26690560
JL
15570 (void)opn; /* avoid a compiler warning */
15571 MIPS_DEBUG("%s", opn);
15572}
15573
b53371ed
JL
15574static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15575 int ret, int v1, int v2, int check_ret)
15576
15577{
15578 const char *opn = "mipsdsp accumulator";
15579 TCGv t0;
15580 TCGv t1;
15581 TCGv v1_t;
15582 TCGv v2_t;
15583 int16_t imm;
15584
15585 if ((ret == 0) && (check_ret == 1)) {
15586 /* Treat as NOP. */
15587 MIPS_DEBUG("NOP");
15588 return;
15589 }
15590
15591 t0 = tcg_temp_new();
15592 t1 = tcg_temp_new();
15593 v1_t = tcg_temp_new();
15594 v2_t = tcg_temp_new();
15595
15596 gen_load_gpr(v1_t, v1);
15597 gen_load_gpr(v2_t, v2);
15598
15599 switch (op1) {
15600 case OPC_EXTR_W_DSP:
15601 check_dsp(ctx);
15602 switch (op2) {
15603 case OPC_EXTR_W:
15604 tcg_gen_movi_tl(t0, v2);
15605 tcg_gen_movi_tl(t1, v1);
15606 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15607 break;
15608 case OPC_EXTR_R_W:
15609 tcg_gen_movi_tl(t0, v2);
15610 tcg_gen_movi_tl(t1, v1);
15611 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15612 break;
15613 case OPC_EXTR_RS_W:
15614 tcg_gen_movi_tl(t0, v2);
15615 tcg_gen_movi_tl(t1, v1);
15616 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15617 break;
15618 case OPC_EXTR_S_H:
15619 tcg_gen_movi_tl(t0, v2);
15620 tcg_gen_movi_tl(t1, v1);
15621 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15622 break;
15623 case OPC_EXTRV_S_H:
15624 tcg_gen_movi_tl(t0, v2);
15625 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15626 break;
15627 case OPC_EXTRV_W:
15628 tcg_gen_movi_tl(t0, v2);
15629 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15630 break;
15631 case OPC_EXTRV_R_W:
15632 tcg_gen_movi_tl(t0, v2);
15633 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15634 break;
15635 case OPC_EXTRV_RS_W:
15636 tcg_gen_movi_tl(t0, v2);
15637 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15638 break;
15639 case OPC_EXTP:
15640 tcg_gen_movi_tl(t0, v2);
15641 tcg_gen_movi_tl(t1, v1);
15642 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15643 break;
15644 case OPC_EXTPV:
15645 tcg_gen_movi_tl(t0, v2);
15646 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15647 break;
15648 case OPC_EXTPDP:
15649 tcg_gen_movi_tl(t0, v2);
15650 tcg_gen_movi_tl(t1, v1);
15651 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15652 break;
15653 case OPC_EXTPDPV:
15654 tcg_gen_movi_tl(t0, v2);
15655 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15656 break;
15657 case OPC_SHILO:
15658 imm = (ctx->opcode >> 20) & 0x3F;
15659 tcg_gen_movi_tl(t0, ret);
15660 tcg_gen_movi_tl(t1, imm);
15661 gen_helper_shilo(t0, t1, cpu_env);
15662 break;
15663 case OPC_SHILOV:
15664 tcg_gen_movi_tl(t0, ret);
15665 gen_helper_shilo(t0, v1_t, cpu_env);
15666 break;
15667 case OPC_MTHLIP:
15668 tcg_gen_movi_tl(t0, ret);
15669 gen_helper_mthlip(t0, v1_t, cpu_env);
15670 break;
15671 case OPC_WRDSP:
15672 imm = (ctx->opcode >> 11) & 0x3FF;
15673 tcg_gen_movi_tl(t0, imm);
15674 gen_helper_wrdsp(v1_t, t0, cpu_env);
15675 break;
15676 case OPC_RDDSP:
15677 imm = (ctx->opcode >> 16) & 0x03FF;
15678 tcg_gen_movi_tl(t0, imm);
15679 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15680 break;
15681 }
15682 break;
15683#ifdef TARGET_MIPS64
15684 case OPC_DEXTR_W_DSP:
15685 check_dsp(ctx);
15686 switch (op2) {
15687 case OPC_DMTHLIP:
15688 tcg_gen_movi_tl(t0, ret);
15689 gen_helper_dmthlip(v1_t, t0, cpu_env);
15690 break;
15691 case OPC_DSHILO:
15692 {
15693 int shift = (ctx->opcode >> 19) & 0x7F;
15694 int ac = (ctx->opcode >> 11) & 0x03;
15695 tcg_gen_movi_tl(t0, shift);
15696 tcg_gen_movi_tl(t1, ac);
15697 gen_helper_dshilo(t0, t1, cpu_env);
15698 break;
15699 }
15700 case OPC_DSHILOV:
15701 {
15702 int ac = (ctx->opcode >> 11) & 0x03;
15703 tcg_gen_movi_tl(t0, ac);
15704 gen_helper_dshilo(v1_t, t0, cpu_env);
15705 break;
15706 }
15707 case OPC_DEXTP:
15708 tcg_gen_movi_tl(t0, v2);
15709 tcg_gen_movi_tl(t1, v1);
15710
15711 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15712 break;
15713 case OPC_DEXTPV:
15714 tcg_gen_movi_tl(t0, v2);
15715 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15716 break;
15717 case OPC_DEXTPDP:
15718 tcg_gen_movi_tl(t0, v2);
15719 tcg_gen_movi_tl(t1, v1);
15720 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15721 break;
15722 case OPC_DEXTPDPV:
15723 tcg_gen_movi_tl(t0, v2);
15724 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15725 break;
15726 case OPC_DEXTR_L:
15727 tcg_gen_movi_tl(t0, v2);
15728 tcg_gen_movi_tl(t1, v1);
15729 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15730 break;
15731 case OPC_DEXTR_R_L:
15732 tcg_gen_movi_tl(t0, v2);
15733 tcg_gen_movi_tl(t1, v1);
15734 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15735 break;
15736 case OPC_DEXTR_RS_L:
15737 tcg_gen_movi_tl(t0, v2);
15738 tcg_gen_movi_tl(t1, v1);
15739 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15740 break;
15741 case OPC_DEXTR_W:
15742 tcg_gen_movi_tl(t0, v2);
15743 tcg_gen_movi_tl(t1, v1);
15744 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15745 break;
15746 case OPC_DEXTR_R_W:
15747 tcg_gen_movi_tl(t0, v2);
15748 tcg_gen_movi_tl(t1, v1);
15749 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15750 break;
15751 case OPC_DEXTR_RS_W:
15752 tcg_gen_movi_tl(t0, v2);
15753 tcg_gen_movi_tl(t1, v1);
15754 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15755 break;
15756 case OPC_DEXTR_S_H:
15757 tcg_gen_movi_tl(t0, v2);
15758 tcg_gen_movi_tl(t1, v1);
15759 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15760 break;
15761 case OPC_DEXTRV_S_H:
15762 tcg_gen_movi_tl(t0, v2);
15763 tcg_gen_movi_tl(t1, v1);
15764 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15765 break;
15766 case OPC_DEXTRV_L:
15767 tcg_gen_movi_tl(t0, v2);
15768 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15769 break;
15770 case OPC_DEXTRV_R_L:
15771 tcg_gen_movi_tl(t0, v2);
15772 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15773 break;
15774 case OPC_DEXTRV_RS_L:
15775 tcg_gen_movi_tl(t0, v2);
15776 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15777 break;
15778 case OPC_DEXTRV_W:
15779 tcg_gen_movi_tl(t0, v2);
15780 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15781 break;
15782 case OPC_DEXTRV_R_W:
15783 tcg_gen_movi_tl(t0, v2);
15784 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15785 break;
15786 case OPC_DEXTRV_RS_W:
15787 tcg_gen_movi_tl(t0, v2);
15788 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15789 break;
15790 }
15791 break;
15792#endif
15793 }
15794
15795 tcg_temp_free(t0);
15796 tcg_temp_free(t1);
15797 tcg_temp_free(v1_t);
15798 tcg_temp_free(v2_t);
15799
15800 (void)opn; /* avoid a compiler warning */
15801 MIPS_DEBUG("%s", opn);
15802}
15803
9b1a1d68
JL
15804/* End MIPSDSP functions. */
15805
31837be3
YK
15806/* Compact Branches */
15807static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15808 int rs, int rt, int32_t offset)
15809{
15810 int bcond_compute = 0;
15811 TCGv t0 = tcg_temp_new();
15812 TCGv t1 = tcg_temp_new();
15813
15814 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15815#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15816 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15817 "\n", ctx->pc);
31837be3
YK
15818#endif
15819 generate_exception(ctx, EXCP_RI);
15820 goto out;
15821 }
15822
15823 /* Load needed operands and calculate btarget */
15824 switch (opc) {
15825 /* compact branch */
15826 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15827 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15828 gen_load_gpr(t0, rs);
15829 gen_load_gpr(t1, rt);
15830 bcond_compute = 1;
15831 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15832 if (rs <= rt && rs == 0) {
15833 /* OPC_BEQZALC, OPC_BNEZALC */
15834 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15835 }
15836 break;
15837 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15838 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15839 gen_load_gpr(t0, rs);
15840 gen_load_gpr(t1, rt);
15841 bcond_compute = 1;
15842 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15843 break;
15844 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15845 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15846 if (rs == 0 || rs == rt) {
15847 /* OPC_BLEZALC, OPC_BGEZALC */
15848 /* OPC_BGTZALC, OPC_BLTZALC */
15849 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15850 }
15851 gen_load_gpr(t0, rs);
15852 gen_load_gpr(t1, rt);
15853 bcond_compute = 1;
15854 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15855 break;
15856 case OPC_BC:
15857 case OPC_BALC:
15858 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15859 break;
15860 case OPC_BEQZC:
15861 case OPC_BNEZC:
15862 if (rs != 0) {
15863 /* OPC_BEQZC, OPC_BNEZC */
15864 gen_load_gpr(t0, rs);
15865 bcond_compute = 1;
15866 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15867 } else {
15868 /* OPC_JIC, OPC_JIALC */
15869 TCGv tbase = tcg_temp_new();
15870 TCGv toffset = tcg_temp_new();
15871
15872 gen_load_gpr(tbase, rt);
15873 tcg_gen_movi_tl(toffset, offset);
15874 gen_op_addr_add(ctx, btarget, tbase, toffset);
15875 tcg_temp_free(tbase);
15876 tcg_temp_free(toffset);
15877 }
15878 break;
15879 default:
15880 MIPS_INVAL("Compact branch/jump");
15881 generate_exception(ctx, EXCP_RI);
15882 goto out;
15883 }
15884
15885 if (bcond_compute == 0) {
15886 /* Uncoditional compact branch */
15887 switch (opc) {
15888 case OPC_JIALC:
15889 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15890 /* Fallthrough */
15891 case OPC_JIC:
15892 ctx->hflags |= MIPS_HFLAG_BR;
15893 break;
15894 case OPC_BALC:
15895 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15896 /* Fallthrough */
15897 case OPC_BC:
15898 ctx->hflags |= MIPS_HFLAG_B;
15899 break;
15900 default:
15901 MIPS_INVAL("Compact branch/jump");
15902 generate_exception(ctx, EXCP_RI);
15903 goto out;
15904 }
15905
15906 /* Generating branch here as compact branches don't have delay slot */
15907 gen_branch(ctx, 4);
15908 } else {
15909 /* Conditional compact branch */
339cd2a8 15910 int fs = gen_new_label();
31837be3
YK
15911 save_cpu_state(ctx, 0);
15912
15913 switch (opc) {
15914 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15915 if (rs == 0 && rt != 0) {
15916 /* OPC_BLEZALC */
339cd2a8 15917 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
15918 } else if (rs != 0 && rt != 0 && rs == rt) {
15919 /* OPC_BGEZALC */
339cd2a8 15920 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
15921 } else {
15922 /* OPC_BGEUC */
339cd2a8 15923 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
15924 }
15925 break;
15926 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15927 if (rs == 0 && rt != 0) {
15928 /* OPC_BGTZALC */
339cd2a8 15929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
15930 } else if (rs != 0 && rt != 0 && rs == rt) {
15931 /* OPC_BLTZALC */
339cd2a8 15932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
15933 } else {
15934 /* OPC_BLTUC */
339cd2a8 15935 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
15936 }
15937 break;
15938 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15939 if (rs == 0 && rt != 0) {
15940 /* OPC_BLEZC */
339cd2a8 15941 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
15942 } else if (rs != 0 && rt != 0 && rs == rt) {
15943 /* OPC_BGEZC */
339cd2a8 15944 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
15945 } else {
15946 /* OPC_BGEC */
339cd2a8 15947 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
15948 }
15949 break;
15950 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15951 if (rs == 0 && rt != 0) {
15952 /* OPC_BGTZC */
339cd2a8 15953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
15954 } else if (rs != 0 && rt != 0 && rs == rt) {
15955 /* OPC_BLTZC */
339cd2a8 15956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
15957 } else {
15958 /* OPC_BLTC */
339cd2a8 15959 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
15960 }
15961 break;
15962 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15963 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15964 if (rs >= rt) {
15965 /* OPC_BOVC, OPC_BNVC */
15966 TCGv t2 = tcg_temp_new();
15967 TCGv t3 = tcg_temp_new();
15968 TCGv t4 = tcg_temp_new();
15969 TCGv input_overflow = tcg_temp_new();
15970
15971 gen_load_gpr(t0, rs);
15972 gen_load_gpr(t1, rt);
15973 tcg_gen_ext32s_tl(t2, t0);
15974 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
15975 tcg_gen_ext32s_tl(t3, t1);
15976 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
15977 tcg_gen_or_tl(input_overflow, input_overflow, t4);
15978
15979 tcg_gen_add_tl(t4, t2, t3);
15980 tcg_gen_ext32s_tl(t4, t4);
15981 tcg_gen_xor_tl(t2, t2, t3);
15982 tcg_gen_xor_tl(t3, t4, t3);
15983 tcg_gen_andc_tl(t2, t3, t2);
15984 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
15985 tcg_gen_or_tl(t4, t4, input_overflow);
15986 if (opc == OPC_BOVC) {
15987 /* OPC_BOVC */
339cd2a8 15988 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
15989 } else {
15990 /* OPC_BNVC */
339cd2a8 15991 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
15992 }
15993 tcg_temp_free(input_overflow);
15994 tcg_temp_free(t4);
15995 tcg_temp_free(t3);
15996 tcg_temp_free(t2);
15997 } else if (rs < rt && rs == 0) {
15998 /* OPC_BEQZALC, OPC_BNEZALC */
15999 if (opc == OPC_BEQZALC) {
16000 /* OPC_BEQZALC */
339cd2a8 16001 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
16002 } else {
16003 /* OPC_BNEZALC */
339cd2a8 16004 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
16005 }
16006 } else {
16007 /* OPC_BEQC, OPC_BNEC */
16008 if (opc == OPC_BEQC) {
16009 /* OPC_BEQC */
339cd2a8 16010 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
16011 } else {
16012 /* OPC_BNEC */
339cd2a8 16013 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
16014 }
16015 }
16016 break;
16017 case OPC_BEQZC:
339cd2a8 16018 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
16019 break;
16020 case OPC_BNEZC:
339cd2a8 16021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16022 break;
16023 default:
16024 MIPS_INVAL("Compact conditional branch/jump");
16025 generate_exception(ctx, EXCP_RI);
16026 goto out;
16027 }
16028
16029 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16030 gen_goto_tb(ctx, 1, ctx->btarget);
16031 gen_set_label(fs);
16032
16033 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16034 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16035 }
16036
16037out:
16038 tcg_temp_free(t0);
16039 tcg_temp_free(t1);
16040}
16041
10dc65db
LA
16042static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16043{
4267d3e6 16044 int rs, rt, rd, sa;
b42ee5e1 16045 uint32_t op1, op2;
10dc65db
LA
16046
16047 rs = (ctx->opcode >> 21) & 0x1f;
16048 rt = (ctx->opcode >> 16) & 0x1f;
16049 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16050 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16051
16052 op1 = MASK_SPECIAL(ctx->opcode);
16053 switch (op1) {
d4ea6acd
LA
16054 case OPC_LSA:
16055 if (rd != 0) {
16056 int imm2 = extract32(ctx->opcode, 6, 3);
16057 TCGv t0 = tcg_temp_new();
16058 TCGv t1 = tcg_temp_new();
16059 gen_load_gpr(t0, rs);
16060 gen_load_gpr(t1, rt);
16061 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16062 tcg_gen_add_tl(t0, t0, t1);
16063 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16064 tcg_temp_free(t1);
16065 tcg_temp_free(t0);
16066 }
16067 break;
b42ee5e1
LA
16068 case OPC_MULT ... OPC_DIVU:
16069 op2 = MASK_R6_MULDIV(ctx->opcode);
16070 switch (op2) {
16071 case R6_OPC_MUL:
16072 case R6_OPC_MUH:
16073 case R6_OPC_MULU:
16074 case R6_OPC_MUHU:
16075 case R6_OPC_DIV:
16076 case R6_OPC_MOD:
16077 case R6_OPC_DIVU:
16078 case R6_OPC_MODU:
16079 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16080 break;
16081 default:
16082 MIPS_INVAL("special_r6 muldiv");
16083 generate_exception(ctx, EXCP_RI);
16084 break;
16085 }
16086 break;
10dc65db
LA
16087 case OPC_SELEQZ:
16088 case OPC_SELNEZ:
16089 gen_cond_move(ctx, op1, rd, rs, rt);
16090 break;
4267d3e6
LA
16091 case R6_OPC_CLO:
16092 case R6_OPC_CLZ:
16093 if (rt == 0 && sa == 1) {
16094 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16095 We need additionally to check other fields */
16096 gen_cl(ctx, op1, rd, rs);
16097 } else {
16098 generate_exception(ctx, EXCP_RI);
16099 }
16100 break;
16101 case R6_OPC_SDBBP:
faf1f68b
LA
16102 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16103 generate_exception(ctx, EXCP_RI);
16104 } else {
16105 generate_exception(ctx, EXCP_DBp);
16106 }
4267d3e6 16107 break;
b42ee5e1 16108#if defined(TARGET_MIPS64)
d4ea6acd
LA
16109 case OPC_DLSA:
16110 check_mips_64(ctx);
16111 if (rd != 0) {
16112 int imm2 = extract32(ctx->opcode, 6, 3);
16113 TCGv t0 = tcg_temp_new();
16114 TCGv t1 = tcg_temp_new();
16115 gen_load_gpr(t0, rs);
16116 gen_load_gpr(t1, rt);
16117 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16118 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16119 tcg_temp_free(t1);
16120 tcg_temp_free(t0);
16121 }
16122 break;
4267d3e6
LA
16123 case R6_OPC_DCLO:
16124 case R6_OPC_DCLZ:
16125 if (rt == 0 && sa == 1) {
16126 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16127 We need additionally to check other fields */
16128 check_mips_64(ctx);
16129 gen_cl(ctx, op1, rd, rs);
16130 } else {
16131 generate_exception(ctx, EXCP_RI);
16132 }
16133 break;
b42ee5e1
LA
16134 case OPC_DMULT ... OPC_DDIVU:
16135 op2 = MASK_R6_MULDIV(ctx->opcode);
16136 switch (op2) {
16137 case R6_OPC_DMUL:
16138 case R6_OPC_DMUH:
16139 case R6_OPC_DMULU:
16140 case R6_OPC_DMUHU:
16141 case R6_OPC_DDIV:
16142 case R6_OPC_DMOD:
16143 case R6_OPC_DDIVU:
16144 case R6_OPC_DMODU:
16145 check_mips_64(ctx);
16146 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16147 break;
16148 default:
16149 MIPS_INVAL("special_r6 muldiv");
16150 generate_exception(ctx, EXCP_RI);
16151 break;
16152 }
16153 break;
16154#endif
10dc65db
LA
16155 default: /* Invalid */
16156 MIPS_INVAL("special_r6");
16157 generate_exception(ctx, EXCP_RI);
16158 break;
16159 }
16160}
16161
16162static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16163{
b42ee5e1 16164 int rs, rt, rd, sa;
10dc65db
LA
16165 uint32_t op1;
16166
16167 rs = (ctx->opcode >> 21) & 0x1f;
16168 rt = (ctx->opcode >> 16) & 0x1f;
16169 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16170 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16171
16172 op1 = MASK_SPECIAL(ctx->opcode);
16173 switch (op1) {
16174 case OPC_MOVN: /* Conditional move */
16175 case OPC_MOVZ:
16176 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16177 INSN_LOONGSON2E | INSN_LOONGSON2F);
16178 gen_cond_move(ctx, op1, rd, rs, rt);
16179 break;
16180 case OPC_MFHI: /* Move from HI/LO */
16181 case OPC_MFLO:
16182 gen_HILO(ctx, op1, rs & 3, rd);
16183 break;
16184 case OPC_MTHI:
16185 case OPC_MTLO: /* Move to HI/LO */
16186 gen_HILO(ctx, op1, rd & 3, rs);
16187 break;
16188 case OPC_MOVCI:
16189 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16190 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16191 check_cp1_enabled(ctx);
16192 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16193 (ctx->opcode >> 16) & 1);
16194 } else {
16195 generate_exception_err(ctx, EXCP_CpU, 1);
16196 }
16197 break;
b42ee5e1
LA
16198 case OPC_MULT:
16199 case OPC_MULTU:
16200 if (sa) {
16201 check_insn(ctx, INSN_VR54XX);
16202 op1 = MASK_MUL_VR54XX(ctx->opcode);
16203 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16204 } else {
16205 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16206 }
16207 break;
16208 case OPC_DIV:
16209 case OPC_DIVU:
16210 gen_muldiv(ctx, op1, 0, rs, rt);
16211 break;
16212#if defined(TARGET_MIPS64)
16213 case OPC_DMULT ... OPC_DDIVU:
16214 check_insn(ctx, ISA_MIPS3);
16215 check_mips_64(ctx);
16216 gen_muldiv(ctx, op1, 0, rs, rt);
16217 break;
16218#endif
0aefa333 16219 case OPC_JR:
b231c103 16220 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16221 break;
4267d3e6
LA
16222 case OPC_SPIM:
16223#ifdef MIPS_STRICT_STANDARD
16224 MIPS_INVAL("SPIM");
16225 generate_exception(ctx, EXCP_RI);
16226#else
16227 /* Implemented as RI exception for now. */
16228 MIPS_INVAL("spim (unofficial)");
16229 generate_exception(ctx, EXCP_RI);
16230#endif
16231 break;
10dc65db
LA
16232 default: /* Invalid */
16233 MIPS_INVAL("special_legacy");
16234 generate_exception(ctx, EXCP_RI);
16235 break;
16236 }
16237}
16238
099e5b4d 16239static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16240{
3c824109 16241 int rs, rt, rd, sa;
099e5b4d 16242 uint32_t op1;
3c824109 16243
3c824109
NF
16244 rs = (ctx->opcode >> 21) & 0x1f;
16245 rt = (ctx->opcode >> 16) & 0x1f;
16246 rd = (ctx->opcode >> 11) & 0x1f;
16247 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16248
16249 op1 = MASK_SPECIAL(ctx->opcode);
16250 switch (op1) {
16251 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16252 if (sa == 5 && rd == 0 &&
16253 rs == 0 && rt == 0) { /* PAUSE */
16254 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16255 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16256 MIPS_DEBUG("CTI in delay / forbidden slot");
16257 generate_exception(ctx, EXCP_RI);
16258 break;
16259 }
16260 }
16261 /* Fallthrough */
099e5b4d
LA
16262 case OPC_SRA:
16263 gen_shift_imm(ctx, op1, rd, rt, sa);
16264 break;
16265 case OPC_SRL:
16266 switch ((ctx->opcode >> 21) & 0x1f) {
16267 case 1:
16268 /* rotr is decoded as srl on non-R2 CPUs */
16269 if (ctx->insn_flags & ISA_MIPS32R2) {
16270 op1 = OPC_ROTR;
ea63e2c3 16271 }
099e5b4d
LA
16272 /* Fallthrough */
16273 case 0:
16274 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16275 break;
099e5b4d
LA
16276 default:
16277 generate_exception(ctx, EXCP_RI);
ea63e2c3 16278 break;
099e5b4d
LA
16279 }
16280 break;
099e5b4d
LA
16281 case OPC_ADD ... OPC_SUBU:
16282 gen_arith(ctx, op1, rd, rs, rt);
16283 break;
16284 case OPC_SLLV: /* Shifts */
16285 case OPC_SRAV:
16286 gen_shift(ctx, op1, rd, rs, rt);
16287 break;
16288 case OPC_SRLV:
16289 switch ((ctx->opcode >> 6) & 0x1f) {
16290 case 1:
16291 /* rotrv is decoded as srlv on non-R2 CPUs */
16292 if (ctx->insn_flags & ISA_MIPS32R2) {
16293 op1 = OPC_ROTRV;
26135ead 16294 }
099e5b4d
LA
16295 /* Fallthrough */
16296 case 0:
16297 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16298 break;
099e5b4d
LA
16299 default:
16300 generate_exception(ctx, EXCP_RI);
6af0bf9c 16301 break;
099e5b4d
LA
16302 }
16303 break;
16304 case OPC_SLT: /* Set on less than */
16305 case OPC_SLTU:
16306 gen_slt(ctx, op1, rd, rs, rt);
16307 break;
16308 case OPC_AND: /* Logic*/
16309 case OPC_OR:
16310 case OPC_NOR:
16311 case OPC_XOR:
16312 gen_logic(ctx, op1, rd, rs, rt);
16313 break;
0aefa333 16314 case OPC_JALR:
b231c103 16315 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16316 break;
16317 case OPC_TGE ... OPC_TEQ: /* Traps */
16318 case OPC_TNE:
16319 gen_trap(ctx, op1, rs, rt, -1);
16320 break;
d4ea6acd
LA
16321 case OPC_LSA: /* OPC_PMON */
16322 if (ctx->insn_flags & ISA_MIPS32R6) {
16323 decode_opc_special_r6(env, ctx);
16324 } else {
16325 /* Pmon entry point, also R4010 selsl */
b48cfdff 16326#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16327 MIPS_INVAL("PMON / selsl");
16328 generate_exception(ctx, EXCP_RI);
b48cfdff 16329#else
d4ea6acd 16330 gen_helper_0e0i(pmon, sa);
b48cfdff 16331#endif
d4ea6acd 16332 }
099e5b4d
LA
16333 break;
16334 case OPC_SYSCALL:
16335 generate_exception(ctx, EXCP_SYSCALL);
16336 ctx->bstate = BS_STOP;
16337 break;
16338 case OPC_BREAK:
16339 generate_exception(ctx, EXCP_BREAK);
16340 break;
099e5b4d
LA
16341 case OPC_SYNC:
16342 /* Treat as NOP. */
16343 break;
4ad40f36 16344
d26bc211 16345#if defined(TARGET_MIPS64)
099e5b4d
LA
16346 /* MIPS64 specific opcodes */
16347 case OPC_DSLL:
16348 case OPC_DSRA:
16349 case OPC_DSLL32:
16350 case OPC_DSRA32:
16351 check_insn(ctx, ISA_MIPS3);
16352 check_mips_64(ctx);
16353 gen_shift_imm(ctx, op1, rd, rt, sa);
16354 break;
16355 case OPC_DSRL:
16356 switch ((ctx->opcode >> 21) & 0x1f) {
16357 case 1:
16358 /* drotr is decoded as dsrl on non-R2 CPUs */
16359 if (ctx->insn_flags & ISA_MIPS32R2) {
16360 op1 = OPC_DROTR;
ea63e2c3 16361 }
099e5b4d
LA
16362 /* Fallthrough */
16363 case 0:
d75c135e 16364 check_insn(ctx, ISA_MIPS3);
e189e748 16365 check_mips_64(ctx);
099e5b4d 16366 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16367 break;
099e5b4d
LA
16368 default:
16369 generate_exception(ctx, EXCP_RI);
460f00c4 16370 break;
099e5b4d
LA
16371 }
16372 break;
16373 case OPC_DSRL32:
16374 switch ((ctx->opcode >> 21) & 0x1f) {
16375 case 1:
16376 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16377 if (ctx->insn_flags & ISA_MIPS32R2) {
16378 op1 = OPC_DROTR32;
ea63e2c3 16379 }
099e5b4d
LA
16380 /* Fallthrough */
16381 case 0:
d75c135e 16382 check_insn(ctx, ISA_MIPS3);
e189e748 16383 check_mips_64(ctx);
099e5b4d 16384 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16385 break;
099e5b4d 16386 default:
6af0bf9c
FB
16387 generate_exception(ctx, EXCP_RI);
16388 break;
16389 }
16390 break;
099e5b4d
LA
16391 case OPC_DADD ... OPC_DSUBU:
16392 check_insn(ctx, ISA_MIPS3);
16393 check_mips_64(ctx);
16394 gen_arith(ctx, op1, rd, rs, rt);
16395 break;
16396 case OPC_DSLLV:
16397 case OPC_DSRAV:
16398 check_insn(ctx, ISA_MIPS3);
16399 check_mips_64(ctx);
16400 gen_shift(ctx, op1, rd, rs, rt);
16401 break;
16402 case OPC_DSRLV:
16403 switch ((ctx->opcode >> 6) & 0x1f) {
16404 case 1:
16405 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16406 if (ctx->insn_flags & ISA_MIPS32R2) {
16407 op1 = OPC_DROTRV;
6af0bf9c 16408 }
099e5b4d
LA
16409 /* Fallthrough */
16410 case 0:
16411 check_insn(ctx, ISA_MIPS3);
e189e748 16412 check_mips_64(ctx);
099e5b4d 16413 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16414 break;
099e5b4d 16415 default:
6af0bf9c
FB
16416 generate_exception(ctx, EXCP_RI);
16417 break;
16418 }
16419 break;
099e5b4d 16420#endif
10dc65db
LA
16421 default:
16422 if (ctx->insn_flags & ISA_MIPS32R6) {
16423 decode_opc_special_r6(env, ctx);
16424 } else {
16425 decode_opc_special_legacy(env, ctx);
16426 }
16427 }
16428}
16429
10dc65db 16430static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16431{
16432 int rs, rt, rd;
16433 uint32_t op1;
6c5c1e20 16434
4267d3e6
LA
16435 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16436
099e5b4d
LA
16437 rs = (ctx->opcode >> 21) & 0x1f;
16438 rt = (ctx->opcode >> 16) & 0x1f;
16439 rd = (ctx->opcode >> 11) & 0x1f;
16440
16441 op1 = MASK_SPECIAL2(ctx->opcode);
16442 switch (op1) {
16443 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16444 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16445 check_insn(ctx, ISA_MIPS32);
16446 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16447 break;
16448 case OPC_MUL:
099e5b4d
LA
16449 gen_arith(ctx, op1, rd, rs, rt);
16450 break;
fac5a073
LA
16451 case OPC_DIV_G_2F:
16452 case OPC_DIVU_G_2F:
16453 case OPC_MULT_G_2F:
16454 case OPC_MULTU_G_2F:
16455 case OPC_MOD_G_2F:
16456 case OPC_MODU_G_2F:
16457 check_insn(ctx, INSN_LOONGSON2F);
16458 gen_loongson_integer(ctx, op1, rd, rs, rt);
16459 break;
099e5b4d
LA
16460 case OPC_CLO:
16461 case OPC_CLZ:
16462 check_insn(ctx, ISA_MIPS32);
16463 gen_cl(ctx, op1, rd, rs);
16464 break;
16465 case OPC_SDBBP:
16466 /* XXX: not clear which exception should be raised
16467 * when in debug mode...
16468 */
16469 check_insn(ctx, ISA_MIPS32);
16470 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16471 generate_exception(ctx, EXCP_DBp);
16472 } else {
16473 generate_exception(ctx, EXCP_DBp);
16474 }
16475 /* Treat as NOP. */
16476 break;
9b1a1d68 16477#if defined(TARGET_MIPS64)
099e5b4d
LA
16478 case OPC_DCLO:
16479 case OPC_DCLZ:
16480 check_insn(ctx, ISA_MIPS64);
16481 check_mips_64(ctx);
16482 gen_cl(ctx, op1, rd, rs);
16483 break;
4267d3e6
LA
16484 case OPC_DMULT_G_2F:
16485 case OPC_DMULTU_G_2F:
16486 case OPC_DDIV_G_2F:
16487 case OPC_DDIVU_G_2F:
16488 case OPC_DMOD_G_2F:
16489 case OPC_DMODU_G_2F:
16490 check_insn(ctx, INSN_LOONGSON2F);
16491 gen_loongson_integer(ctx, op1, rd, rs, rt);
16492 break;
10dc65db 16493#endif
4267d3e6
LA
16494 default: /* Invalid */
16495 MIPS_INVAL("special2_legacy");
16496 generate_exception(ctx, EXCP_RI);
16497 break;
10dc65db
LA
16498 }
16499}
16500
16501static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16502{
15eacb9b
YK
16503 int rs, rt, rd, sa;
16504 uint32_t op1, op2;
10dc65db
LA
16505 int16_t imm;
16506
16507 rs = (ctx->opcode >> 21) & 0x1f;
16508 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16509 rd = (ctx->opcode >> 11) & 0x1f;
16510 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16511 imm = (int16_t)ctx->opcode >> 7;
16512
16513 op1 = MASK_SPECIAL3(ctx->opcode);
16514 switch (op1) {
bf7910c6
LA
16515 case R6_OPC_PREF:
16516 if (rt >= 24) {
16517 /* hint codes 24-31 are reserved and signal RI */
16518 generate_exception(ctx, EXCP_RI);
16519 }
16520 /* Treat as NOP. */
16521 break;
16522 case R6_OPC_CACHE:
16523 /* Treat as NOP. */
16524 break;
10dc65db
LA
16525 case R6_OPC_SC:
16526 gen_st_cond(ctx, op1, rt, rs, imm);
16527 break;
16528 case R6_OPC_LL:
16529 gen_ld(ctx, op1, rt, rs, imm);
16530 break;
15eacb9b
YK
16531 case OPC_BSHFL:
16532 {
16533 if (rd == 0) {
16534 /* Treat as NOP. */
16535 break;
16536 }
16537 TCGv t0 = tcg_temp_new();
16538 gen_load_gpr(t0, rt);
16539
16540 op2 = MASK_BSHFL(ctx->opcode);
16541 switch (op2) {
16542 case OPC_ALIGN ... OPC_ALIGN_END:
16543 sa &= 3;
16544 if (sa == 0) {
16545 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16546 } else {
16547 TCGv t1 = tcg_temp_new();
16548 TCGv_i64 t2 = tcg_temp_new_i64();
16549 gen_load_gpr(t1, rs);
16550 tcg_gen_concat_tl_i64(t2, t1, t0);
16551 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16552#if defined(TARGET_MIPS64)
16553 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16554#else
16555 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16556#endif
16557 tcg_temp_free_i64(t2);
16558 tcg_temp_free(t1);
16559 }
16560 break;
16561 case OPC_BITSWAP:
16562 gen_helper_bitswap(cpu_gpr[rd], t0);
16563 break;
16564 }
16565 tcg_temp_free(t0);
16566 }
16567 break;
bf7910c6
LA
16568#if defined(TARGET_MIPS64)
16569 case R6_OPC_SCD:
16570 gen_st_cond(ctx, op1, rt, rs, imm);
16571 break;
16572 case R6_OPC_LLD:
16573 gen_ld(ctx, op1, rt, rs, imm);
16574 break;
15eacb9b
YK
16575 case OPC_DBSHFL:
16576 check_mips_64(ctx);
16577 {
16578 if (rd == 0) {
16579 /* Treat as NOP. */
16580 break;
16581 }
16582 TCGv t0 = tcg_temp_new();
16583 gen_load_gpr(t0, rt);
16584
16585 op2 = MASK_DBSHFL(ctx->opcode);
16586 switch (op2) {
16587 case OPC_DALIGN ... OPC_DALIGN_END:
16588 sa &= 7;
16589 if (sa == 0) {
16590 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16591 } else {
16592 TCGv t1 = tcg_temp_new();
16593 gen_load_gpr(t1, rs);
16594 tcg_gen_shli_tl(t0, t0, 8 * sa);
16595 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16596 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16597 tcg_temp_free(t1);
16598 }
16599 break;
16600 case OPC_DBITSWAP:
16601 gen_helper_dbitswap(cpu_gpr[rd], t0);
16602 break;
16603 }
16604 tcg_temp_free(t0);
16605 }
16606 break;
bf7910c6 16607#endif
10dc65db
LA
16608 default: /* Invalid */
16609 MIPS_INVAL("special3_r6");
16610 generate_exception(ctx, EXCP_RI);
16611 break;
16612 }
16613}
16614
16615static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16616{
fac5a073 16617 int rs, rt, rd;
099e5b4d 16618 uint32_t op1, op2;
099e5b4d
LA
16619
16620 rs = (ctx->opcode >> 21) & 0x1f;
16621 rt = (ctx->opcode >> 16) & 0x1f;
16622 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16623
16624 op1 = MASK_SPECIAL3(ctx->opcode);
16625 switch (op1) {
099e5b4d
LA
16626 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16627 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16628 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16629 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16630 * the same mask and op1. */
16631 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16632 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16633 switch (op2) {
099e5b4d
LA
16634 case OPC_ADDUH_QB:
16635 case OPC_ADDUH_R_QB:
16636 case OPC_ADDQH_PH:
16637 case OPC_ADDQH_R_PH:
16638 case OPC_ADDQH_W:
16639 case OPC_ADDQH_R_W:
16640 case OPC_SUBUH_QB:
16641 case OPC_SUBUH_R_QB:
16642 case OPC_SUBQH_PH:
16643 case OPC_SUBQH_R_PH:
16644 case OPC_SUBQH_W:
16645 case OPC_SUBQH_R_W:
461c08df
JL
16646 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16647 break;
099e5b4d
LA
16648 case OPC_MUL_PH:
16649 case OPC_MUL_S_PH:
16650 case OPC_MULQ_S_W:
16651 case OPC_MULQ_RS_W:
16652 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16653 break;
461c08df 16654 default:
099e5b4d 16655 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16656 generate_exception(ctx, EXCP_RI);
16657 break;
16658 }
099e5b4d
LA
16659 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16660 gen_loongson_integer(ctx, op1, rd, rs, rt);
16661 } else {
16662 generate_exception(ctx, EXCP_RI);
16663 }
16664 break;
16665 case OPC_LX_DSP:
16666 op2 = MASK_LX(ctx->opcode);
16667 switch (op2) {
16668#if defined(TARGET_MIPS64)
16669 case OPC_LDX:
16670#endif
16671 case OPC_LBUX:
16672 case OPC_LHX:
16673 case OPC_LWX:
16674 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16675 break;
16676 default: /* Invalid */
16677 MIPS_INVAL("MASK LX");
16678 generate_exception(ctx, EXCP_RI);
16679 break;
16680 }
16681 break;
16682 case OPC_ABSQ_S_PH_DSP:
16683 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16684 switch (op2) {
16685 case OPC_ABSQ_S_QB:
16686 case OPC_ABSQ_S_PH:
16687 case OPC_ABSQ_S_W:
16688 case OPC_PRECEQ_W_PHL:
16689 case OPC_PRECEQ_W_PHR:
16690 case OPC_PRECEQU_PH_QBL:
16691 case OPC_PRECEQU_PH_QBR:
16692 case OPC_PRECEQU_PH_QBLA:
16693 case OPC_PRECEQU_PH_QBRA:
16694 case OPC_PRECEU_PH_QBL:
16695 case OPC_PRECEU_PH_QBR:
16696 case OPC_PRECEU_PH_QBLA:
16697 case OPC_PRECEU_PH_QBRA:
16698 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16699 break;
16700 case OPC_BITREV:
16701 case OPC_REPL_QB:
16702 case OPC_REPLV_QB:
16703 case OPC_REPL_PH:
16704 case OPC_REPLV_PH:
16705 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16706 break;
16707 default:
16708 MIPS_INVAL("MASK ABSQ_S.PH");
16709 generate_exception(ctx, EXCP_RI);
16710 break;
16711 }
16712 break;
16713 case OPC_ADDU_QB_DSP:
16714 op2 = MASK_ADDU_QB(ctx->opcode);
16715 switch (op2) {
16716 case OPC_ADDQ_PH:
16717 case OPC_ADDQ_S_PH:
16718 case OPC_ADDQ_S_W:
16719 case OPC_ADDU_QB:
16720 case OPC_ADDU_S_QB:
16721 case OPC_ADDU_PH:
16722 case OPC_ADDU_S_PH:
16723 case OPC_SUBQ_PH:
16724 case OPC_SUBQ_S_PH:
16725 case OPC_SUBQ_S_W:
16726 case OPC_SUBU_QB:
16727 case OPC_SUBU_S_QB:
16728 case OPC_SUBU_PH:
16729 case OPC_SUBU_S_PH:
16730 case OPC_ADDSC:
16731 case OPC_ADDWC:
16732 case OPC_MODSUB:
16733 case OPC_RADDU_W_QB:
16734 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16735 break;
16736 case OPC_MULEU_S_PH_QBL:
16737 case OPC_MULEU_S_PH_QBR:
16738 case OPC_MULQ_RS_PH:
16739 case OPC_MULEQ_S_W_PHL:
16740 case OPC_MULEQ_S_W_PHR:
16741 case OPC_MULQ_S_PH:
16742 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16743 break;
16744 default: /* Invalid */
16745 MIPS_INVAL("MASK ADDU.QB");
16746 generate_exception(ctx, EXCP_RI);
461c08df 16747 break;
461c08df 16748
099e5b4d
LA
16749 }
16750 break;
16751 case OPC_CMPU_EQ_QB_DSP:
16752 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16753 switch (op2) {
16754 case OPC_PRECR_SRA_PH_W:
16755 case OPC_PRECR_SRA_R_PH_W:
16756 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16757 break;
099e5b4d
LA
16758 case OPC_PRECR_QB_PH:
16759 case OPC_PRECRQ_QB_PH:
16760 case OPC_PRECRQ_PH_W:
16761 case OPC_PRECRQ_RS_PH_W:
16762 case OPC_PRECRQU_S_QB_PH:
16763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16764 break;
099e5b4d
LA
16765 case OPC_CMPU_EQ_QB:
16766 case OPC_CMPU_LT_QB:
16767 case OPC_CMPU_LE_QB:
16768 case OPC_CMP_EQ_PH:
16769 case OPC_CMP_LT_PH:
16770 case OPC_CMP_LE_PH:
16771 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16772 break;
099e5b4d
LA
16773 case OPC_CMPGU_EQ_QB:
16774 case OPC_CMPGU_LT_QB:
16775 case OPC_CMPGU_LE_QB:
16776 case OPC_CMPGDU_EQ_QB:
16777 case OPC_CMPGDU_LT_QB:
16778 case OPC_CMPGDU_LE_QB:
16779 case OPC_PICK_QB:
16780 case OPC_PICK_PH:
16781 case OPC_PACKRL_PH:
16782 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16783 break;
16784 default: /* Invalid */
16785 MIPS_INVAL("MASK CMPU.EQ.QB");
16786 generate_exception(ctx, EXCP_RI);
16787 break;
16788 }
16789 break;
16790 case OPC_SHLL_QB_DSP:
16791 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16792 break;
16793 case OPC_DPA_W_PH_DSP:
16794 op2 = MASK_DPA_W_PH(ctx->opcode);
16795 switch (op2) {
16796 case OPC_DPAU_H_QBL:
16797 case OPC_DPAU_H_QBR:
16798 case OPC_DPSU_H_QBL:
16799 case OPC_DPSU_H_QBR:
16800 case OPC_DPA_W_PH:
16801 case OPC_DPAX_W_PH:
16802 case OPC_DPAQ_S_W_PH:
16803 case OPC_DPAQX_S_W_PH:
16804 case OPC_DPAQX_SA_W_PH:
16805 case OPC_DPS_W_PH:
16806 case OPC_DPSX_W_PH:
16807 case OPC_DPSQ_S_W_PH:
16808 case OPC_DPSQX_S_W_PH:
16809 case OPC_DPSQX_SA_W_PH:
16810 case OPC_MULSAQ_S_W_PH:
16811 case OPC_DPAQ_SA_L_W:
16812 case OPC_DPSQ_SA_L_W:
16813 case OPC_MAQ_S_W_PHL:
16814 case OPC_MAQ_S_W_PHR:
16815 case OPC_MAQ_SA_W_PHL:
16816 case OPC_MAQ_SA_W_PHR:
16817 case OPC_MULSA_W_PH:
16818 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16819 break;
16820 default: /* Invalid */
16821 MIPS_INVAL("MASK DPAW.PH");
16822 generate_exception(ctx, EXCP_RI);
16823 break;
16824 }
16825 break;
16826 case OPC_INSV_DSP:
16827 op2 = MASK_INSV(ctx->opcode);
16828 switch (op2) {
16829 case OPC_INSV:
16830 check_dsp(ctx);
16831 {
16832 TCGv t0, t1;
16833
16834 if (rt == 0) {
16835 MIPS_DEBUG("NOP");
16836 break;
16837 }
16838
16839 t0 = tcg_temp_new();
16840 t1 = tcg_temp_new();
16841
16842 gen_load_gpr(t0, rt);
16843 gen_load_gpr(t1, rs);
16844
16845 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16846
16847 tcg_temp_free(t0);
16848 tcg_temp_free(t1);
a22260ae
JL
16849 break;
16850 }
099e5b4d
LA
16851 default: /* Invalid */
16852 MIPS_INVAL("MASK INSV");
16853 generate_exception(ctx, EXCP_RI);
16854 break;
16855 }
16856 break;
16857 case OPC_APPEND_DSP:
16858 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16859 break;
16860 case OPC_EXTR_W_DSP:
16861 op2 = MASK_EXTR_W(ctx->opcode);
16862 switch (op2) {
16863 case OPC_EXTR_W:
16864 case OPC_EXTR_R_W:
16865 case OPC_EXTR_RS_W:
16866 case OPC_EXTR_S_H:
16867 case OPC_EXTRV_S_H:
16868 case OPC_EXTRV_W:
16869 case OPC_EXTRV_R_W:
16870 case OPC_EXTRV_RS_W:
16871 case OPC_EXTP:
16872 case OPC_EXTPV:
16873 case OPC_EXTPDP:
16874 case OPC_EXTPDPV:
16875 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16876 break;
16877 case OPC_RDDSP:
16878 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16879 break;
16880 case OPC_SHILO:
16881 case OPC_SHILOV:
16882 case OPC_MTHLIP:
16883 case OPC_WRDSP:
16884 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16885 break;
16886 default: /* Invalid */
16887 MIPS_INVAL("MASK EXTR.W");
16888 generate_exception(ctx, EXCP_RI);
16889 break;
16890 }
16891 break;
099e5b4d 16892#if defined(TARGET_MIPS64)
fac5a073
LA
16893 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16894 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16895 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16896 check_insn(ctx, INSN_LOONGSON2E);
16897 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 16898 break;
099e5b4d
LA
16899 case OPC_ABSQ_S_QH_DSP:
16900 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16901 switch (op2) {
16902 case OPC_PRECEQ_L_PWL:
16903 case OPC_PRECEQ_L_PWR:
16904 case OPC_PRECEQ_PW_QHL:
16905 case OPC_PRECEQ_PW_QHR:
16906 case OPC_PRECEQ_PW_QHLA:
16907 case OPC_PRECEQ_PW_QHRA:
16908 case OPC_PRECEQU_QH_OBL:
16909 case OPC_PRECEQU_QH_OBR:
16910 case OPC_PRECEQU_QH_OBLA:
16911 case OPC_PRECEQU_QH_OBRA:
16912 case OPC_PRECEU_QH_OBL:
16913 case OPC_PRECEU_QH_OBR:
16914 case OPC_PRECEU_QH_OBLA:
16915 case OPC_PRECEU_QH_OBRA:
16916 case OPC_ABSQ_S_OB:
16917 case OPC_ABSQ_S_PW:
16918 case OPC_ABSQ_S_QH:
16919 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16920 break;
16921 case OPC_REPL_OB:
16922 case OPC_REPL_PW:
16923 case OPC_REPL_QH:
16924 case OPC_REPLV_OB:
16925 case OPC_REPLV_PW:
16926 case OPC_REPLV_QH:
16927 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16928 break;
16929 default: /* Invalid */
16930 MIPS_INVAL("MASK ABSQ_S.QH");
16931 generate_exception(ctx, EXCP_RI);
16932 break;
16933 }
16934 break;
16935 case OPC_ADDU_OB_DSP:
16936 op2 = MASK_ADDU_OB(ctx->opcode);
16937 switch (op2) {
16938 case OPC_RADDU_L_OB:
16939 case OPC_SUBQ_PW:
16940 case OPC_SUBQ_S_PW:
16941 case OPC_SUBQ_QH:
16942 case OPC_SUBQ_S_QH:
16943 case OPC_SUBU_OB:
16944 case OPC_SUBU_S_OB:
16945 case OPC_SUBU_QH:
16946 case OPC_SUBU_S_QH:
16947 case OPC_SUBUH_OB:
16948 case OPC_SUBUH_R_OB:
16949 case OPC_ADDQ_PW:
16950 case OPC_ADDQ_S_PW:
16951 case OPC_ADDQ_QH:
16952 case OPC_ADDQ_S_QH:
16953 case OPC_ADDU_OB:
16954 case OPC_ADDU_S_OB:
16955 case OPC_ADDU_QH:
16956 case OPC_ADDU_S_QH:
16957 case OPC_ADDUH_OB:
16958 case OPC_ADDUH_R_OB:
16959 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 16960 break;
099e5b4d
LA
16961 case OPC_MULEQ_S_PW_QHL:
16962 case OPC_MULEQ_S_PW_QHR:
16963 case OPC_MULEU_S_QH_OBL:
16964 case OPC_MULEU_S_QH_OBR:
16965 case OPC_MULQ_RS_QH:
16966 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16967 break;
099e5b4d
LA
16968 default: /* Invalid */
16969 MIPS_INVAL("MASK ADDU.OB");
16970 generate_exception(ctx, EXCP_RI);
26690560 16971 break;
099e5b4d
LA
16972 }
16973 break;
16974 case OPC_CMPU_EQ_OB_DSP:
16975 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
16976 switch (op2) {
16977 case OPC_PRECR_SRA_QH_PW:
16978 case OPC_PRECR_SRA_R_QH_PW:
16979 /* Return value is rt. */
16980 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 16981 break;
099e5b4d
LA
16982 case OPC_PRECR_OB_QH:
16983 case OPC_PRECRQ_OB_QH:
16984 case OPC_PRECRQ_PW_L:
16985 case OPC_PRECRQ_QH_PW:
16986 case OPC_PRECRQ_RS_QH_PW:
16987 case OPC_PRECRQU_S_OB_QH:
16988 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 16989 break;
099e5b4d
LA
16990 case OPC_CMPU_EQ_OB:
16991 case OPC_CMPU_LT_OB:
16992 case OPC_CMPU_LE_OB:
16993 case OPC_CMP_EQ_QH:
16994 case OPC_CMP_LT_QH:
16995 case OPC_CMP_LE_QH:
16996 case OPC_CMP_EQ_PW:
16997 case OPC_CMP_LT_PW:
16998 case OPC_CMP_LE_PW:
16999 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17000 break;
099e5b4d
LA
17001 case OPC_CMPGDU_EQ_OB:
17002 case OPC_CMPGDU_LT_OB:
17003 case OPC_CMPGDU_LE_OB:
17004 case OPC_CMPGU_EQ_OB:
17005 case OPC_CMPGU_LT_OB:
17006 case OPC_CMPGU_LE_OB:
17007 case OPC_PACKRL_PW:
17008 case OPC_PICK_OB:
17009 case OPC_PICK_PW:
17010 case OPC_PICK_QH:
17011 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17012 break;
099e5b4d
LA
17013 default: /* Invalid */
17014 MIPS_INVAL("MASK CMPU_EQ.OB");
17015 generate_exception(ctx, EXCP_RI);
161f85e6 17016 break;
099e5b4d
LA
17017 }
17018 break;
17019 case OPC_DAPPEND_DSP:
17020 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17021 break;
17022 case OPC_DEXTR_W_DSP:
17023 op2 = MASK_DEXTR_W(ctx->opcode);
17024 switch (op2) {
17025 case OPC_DEXTP:
17026 case OPC_DEXTPDP:
17027 case OPC_DEXTPDPV:
17028 case OPC_DEXTPV:
17029 case OPC_DEXTR_L:
17030 case OPC_DEXTR_R_L:
17031 case OPC_DEXTR_RS_L:
17032 case OPC_DEXTR_W:
17033 case OPC_DEXTR_R_W:
17034 case OPC_DEXTR_RS_W:
17035 case OPC_DEXTR_S_H:
17036 case OPC_DEXTRV_L:
17037 case OPC_DEXTRV_R_L:
17038 case OPC_DEXTRV_RS_L:
17039 case OPC_DEXTRV_S_H:
17040 case OPC_DEXTRV_W:
17041 case OPC_DEXTRV_R_W:
17042 case OPC_DEXTRV_RS_W:
17043 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17044 break;
099e5b4d
LA
17045 case OPC_DMTHLIP:
17046 case OPC_DSHILO:
17047 case OPC_DSHILOV:
17048 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17049 break;
099e5b4d
LA
17050 default: /* Invalid */
17051 MIPS_INVAL("MASK EXTR.W");
17052 generate_exception(ctx, EXCP_RI);
461c08df 17053 break;
099e5b4d
LA
17054 }
17055 break;
17056 case OPC_DPAQ_W_QH_DSP:
17057 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17058 switch (op2) {
17059 case OPC_DPAU_H_OBL:
17060 case OPC_DPAU_H_OBR:
17061 case OPC_DPSU_H_OBL:
17062 case OPC_DPSU_H_OBR:
17063 case OPC_DPA_W_QH:
17064 case OPC_DPAQ_S_W_QH:
17065 case OPC_DPS_W_QH:
17066 case OPC_DPSQ_S_W_QH:
17067 case OPC_MULSAQ_S_W_QH:
17068 case OPC_DPAQ_SA_L_PW:
17069 case OPC_DPSQ_SA_L_PW:
17070 case OPC_MULSAQ_S_L_PW:
17071 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17072 break;
17073 case OPC_MAQ_S_W_QHLL:
17074 case OPC_MAQ_S_W_QHLR:
17075 case OPC_MAQ_S_W_QHRL:
17076 case OPC_MAQ_S_W_QHRR:
17077 case OPC_MAQ_SA_W_QHLL:
17078 case OPC_MAQ_SA_W_QHLR:
17079 case OPC_MAQ_SA_W_QHRL:
17080 case OPC_MAQ_SA_W_QHRR:
17081 case OPC_MAQ_S_L_PWL:
17082 case OPC_MAQ_S_L_PWR:
17083 case OPC_DMADD:
17084 case OPC_DMADDU:
17085 case OPC_DMSUB:
17086 case OPC_DMSUBU:
17087 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17088 break;
099e5b4d
LA
17089 default: /* Invalid */
17090 MIPS_INVAL("MASK DPAQ.W.QH");
17091 generate_exception(ctx, EXCP_RI);
b53371ed 17092 break;
099e5b4d
LA
17093 }
17094 break;
17095 case OPC_DINSV_DSP:
17096 op2 = MASK_INSV(ctx->opcode);
17097 switch (op2) {
17098 case OPC_DINSV:
17099 {
17100 TCGv t0, t1;
17101
17102 if (rt == 0) {
17103 MIPS_DEBUG("NOP");
a22260ae
JL
17104 break;
17105 }
099e5b4d 17106 check_dsp(ctx);
1cb6686c 17107
099e5b4d
LA
17108 t0 = tcg_temp_new();
17109 t1 = tcg_temp_new();
1cb6686c 17110
099e5b4d
LA
17111 gen_load_gpr(t0, rt);
17112 gen_load_gpr(t1, rs);
1cb6686c 17113
099e5b4d 17114 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17115
099e5b4d
LA
17116 tcg_temp_free(t0);
17117 tcg_temp_free(t1);
77c5fa8b 17118 break;
099e5b4d 17119 }
7a387fff 17120 default: /* Invalid */
099e5b4d 17121 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17122 generate_exception(ctx, EXCP_RI);
17123 break;
17124 }
17125 break;
099e5b4d
LA
17126 case OPC_SHLL_OB_DSP:
17127 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17128 break;
17129#endif
fac5a073
LA
17130 default: /* Invalid */
17131 MIPS_INVAL("special3_legacy");
17132 generate_exception(ctx, EXCP_RI);
17133 break;
17134 }
17135}
17136
17137static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17138{
17139 int rs, rt, rd, sa;
17140 uint32_t op1, op2;
17141
17142 rs = (ctx->opcode >> 21) & 0x1f;
17143 rt = (ctx->opcode >> 16) & 0x1f;
17144 rd = (ctx->opcode >> 11) & 0x1f;
17145 sa = (ctx->opcode >> 6) & 0x1f;
17146
17147 op1 = MASK_SPECIAL3(ctx->opcode);
17148 switch (op1) {
17149 case OPC_EXT:
17150 case OPC_INS:
17151 check_insn(ctx, ISA_MIPS32R2);
17152 gen_bitops(ctx, op1, rt, rs, sa, rd);
17153 break;
17154 case OPC_BSHFL:
fac5a073 17155 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17156 switch (op2) {
17157 case OPC_ALIGN ... OPC_ALIGN_END:
17158 case OPC_BITSWAP:
17159 check_insn(ctx, ISA_MIPS32R6);
17160 decode_opc_special3_r6(env, ctx);
17161 break;
17162 default:
17163 check_insn(ctx, ISA_MIPS32R2);
17164 gen_bshfl(ctx, op2, rt, rd);
17165 break;
17166 }
fac5a073
LA
17167 break;
17168#if defined(TARGET_MIPS64)
17169 case OPC_DEXTM ... OPC_DEXT:
17170 case OPC_DINSM ... OPC_DINS:
17171 check_insn(ctx, ISA_MIPS64R2);
17172 check_mips_64(ctx);
17173 gen_bitops(ctx, op1, rt, rs, sa, rd);
17174 break;
17175 case OPC_DBSHFL:
fac5a073 17176 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17177 switch (op2) {
17178 case OPC_DALIGN ... OPC_DALIGN_END:
17179 case OPC_DBITSWAP:
17180 check_insn(ctx, ISA_MIPS32R6);
17181 decode_opc_special3_r6(env, ctx);
17182 break;
17183 default:
17184 check_insn(ctx, ISA_MIPS64R2);
17185 check_mips_64(ctx);
17186 op2 = MASK_DBSHFL(ctx->opcode);
17187 gen_bshfl(ctx, op2, rt, rd);
17188 break;
17189 }
fac5a073
LA
17190 break;
17191#endif
17192 case OPC_RDHWR:
17193 gen_rdhwr(ctx, rt, rd);
17194 break;
17195 case OPC_FORK:
17196 check_insn(ctx, ASE_MT);
17197 {
17198 TCGv t0 = tcg_temp_new();
17199 TCGv t1 = tcg_temp_new();
17200
17201 gen_load_gpr(t0, rt);
17202 gen_load_gpr(t1, rs);
17203 gen_helper_fork(t0, t1);
17204 tcg_temp_free(t0);
17205 tcg_temp_free(t1);
17206 }
17207 break;
17208 case OPC_YIELD:
17209 check_insn(ctx, ASE_MT);
17210 {
17211 TCGv t0 = tcg_temp_new();
17212
17213 save_cpu_state(ctx, 1);
17214 gen_load_gpr(t0, rs);
17215 gen_helper_yield(t0, cpu_env, t0);
17216 gen_store_gpr(t0, rd);
17217 tcg_temp_free(t0);
17218 }
17219 break;
10dc65db
LA
17220 default:
17221 if (ctx->insn_flags & ISA_MIPS32R6) {
17222 decode_opc_special3_r6(env, ctx);
17223 } else {
17224 decode_opc_special3_legacy(env, ctx);
17225 }
099e5b4d
LA
17226 }
17227}
17228
863f264d
YK
17229/* MIPS SIMD Architecture (MSA) */
17230static inline int check_msa_access(DisasContext *ctx)
17231{
17232 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17233 !(ctx->hflags & MIPS_HFLAG_F64))) {
17234 generate_exception(ctx, EXCP_RI);
17235 return 0;
17236 }
17237
17238 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17239 if (ctx->insn_flags & ASE_MSA) {
17240 generate_exception(ctx, EXCP_MSADIS);
17241 return 0;
17242 } else {
17243 generate_exception(ctx, EXCP_RI);
17244 return 0;
17245 }
17246 }
17247 return 1;
17248}
17249
5692c6e1
YK
17250static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17251{
17252 /* generates tcg ops to check if any element is 0 */
17253 /* Note this function only works with MSA_WRLEN = 128 */
17254 uint64_t eval_zero_or_big = 0;
17255 uint64_t eval_big = 0;
17256 TCGv_i64 t0 = tcg_temp_new_i64();
17257 TCGv_i64 t1 = tcg_temp_new_i64();
17258 switch (df) {
17259 case DF_BYTE:
17260 eval_zero_or_big = 0x0101010101010101ULL;
17261 eval_big = 0x8080808080808080ULL;
17262 break;
17263 case DF_HALF:
17264 eval_zero_or_big = 0x0001000100010001ULL;
17265 eval_big = 0x8000800080008000ULL;
17266 break;
17267 case DF_WORD:
17268 eval_zero_or_big = 0x0000000100000001ULL;
17269 eval_big = 0x8000000080000000ULL;
17270 break;
17271 case DF_DOUBLE:
17272 eval_zero_or_big = 0x0000000000000001ULL;
17273 eval_big = 0x8000000000000000ULL;
17274 break;
17275 }
17276 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17277 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17278 tcg_gen_andi_i64(t0, t0, eval_big);
17279 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17280 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17281 tcg_gen_andi_i64(t1, t1, eval_big);
17282 tcg_gen_or_i64(t0, t0, t1);
17283 /* if all bits are zero then all elements are not zero */
17284 /* if some bit is non-zero then some element is zero */
17285 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17286 tcg_gen_trunc_i64_tl(tresult, t0);
17287 tcg_temp_free_i64(t0);
17288 tcg_temp_free_i64(t1);
17289}
17290
17291static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17292{
17293 uint8_t df = (ctx->opcode >> 21) & 0x3;
17294 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17295 int64_t s16 = (int16_t)ctx->opcode;
17296
17297 check_msa_access(ctx);
17298
17299 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17300 MIPS_DEBUG("CTI in delay / forbidden slot");
17301 generate_exception(ctx, EXCP_RI);
17302 return;
17303 }
17304 switch (op1) {
17305 case OPC_BZ_V:
17306 case OPC_BNZ_V:
17307 {
17308 TCGv_i64 t0 = tcg_temp_new_i64();
17309 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17310 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17311 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17312 tcg_gen_trunc_i64_tl(bcond, t0);
17313 tcg_temp_free_i64(t0);
17314 }
17315 break;
17316 case OPC_BZ_B:
17317 case OPC_BZ_H:
17318 case OPC_BZ_W:
17319 case OPC_BZ_D:
17320 gen_check_zero_element(bcond, df, wt);
17321 break;
17322 case OPC_BNZ_B:
17323 case OPC_BNZ_H:
17324 case OPC_BNZ_W:
17325 case OPC_BNZ_D:
17326 gen_check_zero_element(bcond, df, wt);
17327 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17328 break;
17329 }
17330
17331 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17332
17333 ctx->hflags |= MIPS_HFLAG_BC;
17334 ctx->hflags |= MIPS_HFLAG_BDS32;
17335}
17336
4c789546
YK
17337static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17338{
17339#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17340 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17341 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17342 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17343
17344 TCGv_i32 twd = tcg_const_i32(wd);
17345 TCGv_i32 tws = tcg_const_i32(ws);
17346 TCGv_i32 ti8 = tcg_const_i32(i8);
17347
17348 switch (MASK_MSA_I8(ctx->opcode)) {
17349 case OPC_ANDI_B:
17350 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17351 break;
17352 case OPC_ORI_B:
17353 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17354 break;
17355 case OPC_NORI_B:
17356 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17357 break;
17358 case OPC_XORI_B:
17359 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17360 break;
17361 case OPC_BMNZI_B:
17362 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17363 break;
17364 case OPC_BMZI_B:
17365 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17366 break;
17367 case OPC_BSELI_B:
17368 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17369 break;
17370 case OPC_SHF_B:
17371 case OPC_SHF_H:
17372 case OPC_SHF_W:
17373 {
17374 uint8_t df = (ctx->opcode >> 24) & 0x3;
17375 if (df == DF_DOUBLE) {
17376 generate_exception(ctx, EXCP_RI);
17377 } else {
17378 TCGv_i32 tdf = tcg_const_i32(df);
17379 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17380 tcg_temp_free_i32(tdf);
17381 }
17382 }
17383 break;
17384 default:
17385 MIPS_INVAL("MSA instruction");
17386 generate_exception(ctx, EXCP_RI);
17387 break;
17388 }
17389
17390 tcg_temp_free_i32(twd);
17391 tcg_temp_free_i32(tws);
17392 tcg_temp_free_i32(ti8);
17393}
17394
80e71591
YK
17395static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17396{
17397#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17398 uint8_t df = (ctx->opcode >> 21) & 0x3;
17399 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17400 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17401 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17402 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17403
17404 TCGv_i32 tdf = tcg_const_i32(df);
17405 TCGv_i32 twd = tcg_const_i32(wd);
17406 TCGv_i32 tws = tcg_const_i32(ws);
17407 TCGv_i32 timm = tcg_temp_new_i32();
17408 tcg_gen_movi_i32(timm, u5);
17409
17410 switch (MASK_MSA_I5(ctx->opcode)) {
17411 case OPC_ADDVI_df:
17412 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17413 break;
17414 case OPC_SUBVI_df:
17415 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17416 break;
17417 case OPC_MAXI_S_df:
17418 tcg_gen_movi_i32(timm, s5);
17419 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17420 break;
17421 case OPC_MAXI_U_df:
17422 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17423 break;
17424 case OPC_MINI_S_df:
17425 tcg_gen_movi_i32(timm, s5);
17426 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17427 break;
17428 case OPC_MINI_U_df:
17429 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17430 break;
17431 case OPC_CEQI_df:
17432 tcg_gen_movi_i32(timm, s5);
17433 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17434 break;
17435 case OPC_CLTI_S_df:
17436 tcg_gen_movi_i32(timm, s5);
17437 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17438 break;
17439 case OPC_CLTI_U_df:
17440 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17441 break;
17442 case OPC_CLEI_S_df:
17443 tcg_gen_movi_i32(timm, s5);
17444 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17445 break;
17446 case OPC_CLEI_U_df:
17447 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17448 break;
17449 case OPC_LDI_df:
17450 {
17451 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17452 tcg_gen_movi_i32(timm, s10);
17453 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17454 }
17455 break;
17456 default:
17457 MIPS_INVAL("MSA instruction");
17458 generate_exception(ctx, EXCP_RI);
17459 break;
17460 }
17461
17462 tcg_temp_free_i32(tdf);
17463 tcg_temp_free_i32(twd);
17464 tcg_temp_free_i32(tws);
17465 tcg_temp_free_i32(timm);
17466}
17467
d4cf28de
YK
17468static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17469{
17470#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17471 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17472 uint32_t df = 0, m = 0;
17473 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17474 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17475
17476 TCGv_i32 tdf;
17477 TCGv_i32 tm;
17478 TCGv_i32 twd;
17479 TCGv_i32 tws;
17480
17481 if ((dfm & 0x40) == 0x00) {
17482 m = dfm & 0x3f;
17483 df = DF_DOUBLE;
17484 } else if ((dfm & 0x60) == 0x40) {
17485 m = dfm & 0x1f;
17486 df = DF_WORD;
17487 } else if ((dfm & 0x70) == 0x60) {
17488 m = dfm & 0x0f;
17489 df = DF_HALF;
17490 } else if ((dfm & 0x78) == 0x70) {
17491 m = dfm & 0x7;
17492 df = DF_BYTE;
17493 } else {
17494 generate_exception(ctx, EXCP_RI);
17495 return;
17496 }
17497
17498 tdf = tcg_const_i32(df);
17499 tm = tcg_const_i32(m);
17500 twd = tcg_const_i32(wd);
17501 tws = tcg_const_i32(ws);
17502
17503 switch (MASK_MSA_BIT(ctx->opcode)) {
17504 case OPC_SLLI_df:
17505 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17506 break;
17507 case OPC_SRAI_df:
17508 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17509 break;
17510 case OPC_SRLI_df:
17511 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17512 break;
17513 case OPC_BCLRI_df:
17514 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17515 break;
17516 case OPC_BSETI_df:
17517 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17518 break;
17519 case OPC_BNEGI_df:
17520 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17521 break;
17522 case OPC_BINSLI_df:
17523 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17524 break;
17525 case OPC_BINSRI_df:
17526 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17527 break;
17528 case OPC_SAT_S_df:
17529 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17530 break;
17531 case OPC_SAT_U_df:
17532 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17533 break;
17534 case OPC_SRARI_df:
17535 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17536 break;
17537 case OPC_SRLRI_df:
17538 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17539 break;
17540 default:
17541 MIPS_INVAL("MSA instruction");
17542 generate_exception(ctx, EXCP_RI);
17543 break;
17544 }
17545
17546 tcg_temp_free_i32(tdf);
17547 tcg_temp_free_i32(tm);
17548 tcg_temp_free_i32(twd);
17549 tcg_temp_free_i32(tws);
17550}
17551
28f99f08
YK
17552static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17553{
17554#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17555 uint8_t df = (ctx->opcode >> 21) & 0x3;
17556 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17557 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17558 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17559
17560 TCGv_i32 tdf = tcg_const_i32(df);
17561 TCGv_i32 twd = tcg_const_i32(wd);
17562 TCGv_i32 tws = tcg_const_i32(ws);
17563 TCGv_i32 twt = tcg_const_i32(wt);
17564
17565 switch (MASK_MSA_3R(ctx->opcode)) {
17566 case OPC_SLL_df:
17567 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17568 break;
17569 case OPC_ADDV_df:
17570 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17571 break;
17572 case OPC_CEQ_df:
17573 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17574 break;
17575 case OPC_ADD_A_df:
17576 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17577 break;
17578 case OPC_SUBS_S_df:
17579 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17580 break;
17581 case OPC_MULV_df:
17582 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17583 break;
17584 case OPC_SLD_df:
17585 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17586 break;
17587 case OPC_VSHF_df:
17588 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17589 break;
17590 case OPC_SRA_df:
17591 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17592 break;
17593 case OPC_SUBV_df:
17594 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17595 break;
17596 case OPC_ADDS_A_df:
17597 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17598 break;
17599 case OPC_SUBS_U_df:
17600 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17601 break;
17602 case OPC_MADDV_df:
17603 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17604 break;
17605 case OPC_SPLAT_df:
17606 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17607 break;
17608 case OPC_SRAR_df:
17609 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17610 break;
17611 case OPC_SRL_df:
17612 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17613 break;
17614 case OPC_MAX_S_df:
17615 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17616 break;
17617 case OPC_CLT_S_df:
17618 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17619 break;
17620 case OPC_ADDS_S_df:
17621 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17622 break;
17623 case OPC_SUBSUS_U_df:
17624 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17625 break;
17626 case OPC_MSUBV_df:
17627 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17628 break;
17629 case OPC_PCKEV_df:
17630 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17631 break;
17632 case OPC_SRLR_df:
17633 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17634 break;
17635 case OPC_BCLR_df:
17636 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17637 break;
17638 case OPC_MAX_U_df:
17639 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17640 break;
17641 case OPC_CLT_U_df:
17642 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17643 break;
17644 case OPC_ADDS_U_df:
17645 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17646 break;
17647 case OPC_SUBSUU_S_df:
17648 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17649 break;
17650 case OPC_PCKOD_df:
17651 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17652 break;
17653 case OPC_BSET_df:
17654 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17655 break;
17656 case OPC_MIN_S_df:
17657 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17658 break;
17659 case OPC_CLE_S_df:
17660 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17661 break;
17662 case OPC_AVE_S_df:
17663 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17664 break;
17665 case OPC_ASUB_S_df:
17666 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17667 break;
17668 case OPC_DIV_S_df:
17669 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17670 break;
17671 case OPC_ILVL_df:
17672 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17673 break;
17674 case OPC_BNEG_df:
17675 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17676 break;
17677 case OPC_MIN_U_df:
17678 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17679 break;
17680 case OPC_CLE_U_df:
17681 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17682 break;
17683 case OPC_AVE_U_df:
17684 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17685 break;
17686 case OPC_ASUB_U_df:
17687 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17688 break;
17689 case OPC_DIV_U_df:
17690 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17691 break;
17692 case OPC_ILVR_df:
17693 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17694 break;
17695 case OPC_BINSL_df:
17696 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17697 break;
17698 case OPC_MAX_A_df:
17699 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17700 break;
17701 case OPC_AVER_S_df:
17702 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17703 break;
17704 case OPC_MOD_S_df:
17705 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17706 break;
17707 case OPC_ILVEV_df:
17708 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17709 break;
17710 case OPC_BINSR_df:
17711 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17712 break;
17713 case OPC_MIN_A_df:
17714 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17715 break;
17716 case OPC_AVER_U_df:
17717 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17718 break;
17719 case OPC_MOD_U_df:
17720 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17721 break;
17722 case OPC_ILVOD_df:
17723 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17724 break;
17725
17726 case OPC_DOTP_S_df:
17727 case OPC_DOTP_U_df:
17728 case OPC_DPADD_S_df:
17729 case OPC_DPADD_U_df:
17730 case OPC_DPSUB_S_df:
17731 case OPC_HADD_S_df:
17732 case OPC_DPSUB_U_df:
17733 case OPC_HADD_U_df:
17734 case OPC_HSUB_S_df:
17735 case OPC_HSUB_U_df:
17736 if (df == DF_BYTE) {
17737 generate_exception(ctx, EXCP_RI);
17738 }
17739 switch (MASK_MSA_3R(ctx->opcode)) {
17740 case OPC_DOTP_S_df:
17741 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17742 break;
17743 case OPC_DOTP_U_df:
17744 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17745 break;
17746 case OPC_DPADD_S_df:
17747 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17748 break;
17749 case OPC_DPADD_U_df:
17750 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17751 break;
17752 case OPC_DPSUB_S_df:
17753 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17754 break;
17755 case OPC_HADD_S_df:
17756 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17757 break;
17758 case OPC_DPSUB_U_df:
17759 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17760 break;
17761 case OPC_HADD_U_df:
17762 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17763 break;
17764 case OPC_HSUB_S_df:
17765 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17766 break;
17767 case OPC_HSUB_U_df:
17768 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17769 break;
17770 }
17771 break;
17772 default:
17773 MIPS_INVAL("MSA instruction");
17774 generate_exception(ctx, EXCP_RI);
17775 break;
17776 }
17777 tcg_temp_free_i32(twd);
17778 tcg_temp_free_i32(tws);
17779 tcg_temp_free_i32(twt);
17780 tcg_temp_free_i32(tdf);
17781}
17782
1e608ec1
YK
17783static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17784{
17785#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17786 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17787 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17788 TCGv telm = tcg_temp_new();
17789 TCGv_i32 tsr = tcg_const_i32(source);
17790 TCGv_i32 tdt = tcg_const_i32(dest);
17791
17792 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17793 case OPC_CTCMSA:
17794 gen_load_gpr(telm, source);
17795 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17796 break;
17797 case OPC_CFCMSA:
17798 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17799 gen_store_gpr(telm, dest);
17800 break;
17801 case OPC_MOVE_V:
17802 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17803 break;
17804 default:
17805 MIPS_INVAL("MSA instruction");
17806 generate_exception(ctx, EXCP_RI);
17807 break;
17808 }
17809
17810 tcg_temp_free(telm);
17811 tcg_temp_free_i32(tdt);
17812 tcg_temp_free_i32(tsr);
17813}
17814
17815static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17816 uint32_t n)
17817{
17818#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17819 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17820 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17821
17822 TCGv_i32 tws = tcg_const_i32(ws);
17823 TCGv_i32 twd = tcg_const_i32(wd);
17824 TCGv_i32 tn = tcg_const_i32(n);
17825 TCGv_i32 tdf = tcg_const_i32(df);
17826
17827 switch (MASK_MSA_ELM(ctx->opcode)) {
17828 case OPC_SLDI_df:
17829 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17830 break;
17831 case OPC_SPLATI_df:
17832 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17833 break;
17834 case OPC_INSVE_df:
17835 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17836 break;
17837 case OPC_COPY_S_df:
17838 case OPC_COPY_U_df:
17839 case OPC_INSERT_df:
17840#if !defined(TARGET_MIPS64)
17841 /* Double format valid only for MIPS64 */
17842 if (df == DF_DOUBLE) {
17843 generate_exception(ctx, EXCP_RI);
17844 break;
17845 }
17846#endif
17847 switch (MASK_MSA_ELM(ctx->opcode)) {
17848 case OPC_COPY_S_df:
17849 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
17850 break;
17851 case OPC_COPY_U_df:
17852 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
17853 break;
17854 case OPC_INSERT_df:
17855 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
17856 break;
17857 }
17858 break;
17859 default:
17860 MIPS_INVAL("MSA instruction");
17861 generate_exception(ctx, EXCP_RI);
17862 }
17863 tcg_temp_free_i32(twd);
17864 tcg_temp_free_i32(tws);
17865 tcg_temp_free_i32(tn);
17866 tcg_temp_free_i32(tdf);
17867}
17868
17869static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
17870{
17871 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
17872 uint32_t df = 0, n = 0;
17873
17874 if ((dfn & 0x30) == 0x00) {
17875 n = dfn & 0x0f;
17876 df = DF_BYTE;
17877 } else if ((dfn & 0x38) == 0x20) {
17878 n = dfn & 0x07;
17879 df = DF_HALF;
17880 } else if ((dfn & 0x3c) == 0x30) {
17881 n = dfn & 0x03;
17882 df = DF_WORD;
17883 } else if ((dfn & 0x3e) == 0x38) {
17884 n = dfn & 0x01;
17885 df = DF_DOUBLE;
17886 } else if (dfn == 0x3E) {
17887 /* CTCMSA, CFCMSA, MOVE.V */
17888 gen_msa_elm_3e(env, ctx);
17889 return;
17890 } else {
17891 generate_exception(ctx, EXCP_RI);
17892 return;
17893 }
17894
17895 gen_msa_elm_df(env, ctx, df, n);
17896}
17897
7d05b9c8
YK
17898static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
17899{
17900#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17901 uint8_t df = (ctx->opcode >> 21) & 0x1;
17902 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17903 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17904 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17905
17906 TCGv_i32 twd = tcg_const_i32(wd);
17907 TCGv_i32 tws = tcg_const_i32(ws);
17908 TCGv_i32 twt = tcg_const_i32(wt);
17909 TCGv_i32 tdf = tcg_temp_new_i32();
17910
17911 /* adjust df value for floating-point instruction */
17912 tcg_gen_movi_i32(tdf, df + 2);
17913
17914 switch (MASK_MSA_3RF(ctx->opcode)) {
17915 case OPC_FCAF_df:
17916 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
17917 break;
17918 case OPC_FADD_df:
17919 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
17920 break;
17921 case OPC_FCUN_df:
17922 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
17923 break;
17924 case OPC_FSUB_df:
17925 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
17926 break;
17927 case OPC_FCOR_df:
17928 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
17929 break;
17930 case OPC_FCEQ_df:
17931 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
17932 break;
17933 case OPC_FMUL_df:
17934 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
17935 break;
17936 case OPC_FCUNE_df:
17937 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
17938 break;
17939 case OPC_FCUEQ_df:
17940 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
17941 break;
17942 case OPC_FDIV_df:
17943 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
17944 break;
17945 case OPC_FCNE_df:
17946 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
17947 break;
17948 case OPC_FCLT_df:
17949 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
17950 break;
17951 case OPC_FMADD_df:
17952 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
17953 break;
17954 case OPC_MUL_Q_df:
17955 tcg_gen_movi_i32(tdf, df + 1);
17956 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
17957 break;
17958 case OPC_FCULT_df:
17959 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
17960 break;
17961 case OPC_FMSUB_df:
17962 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
17963 break;
17964 case OPC_MADD_Q_df:
17965 tcg_gen_movi_i32(tdf, df + 1);
17966 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
17967 break;
17968 case OPC_FCLE_df:
17969 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
17970 break;
17971 case OPC_MSUB_Q_df:
17972 tcg_gen_movi_i32(tdf, df + 1);
17973 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
17974 break;
17975 case OPC_FCULE_df:
17976 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
17977 break;
17978 case OPC_FEXP2_df:
17979 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
17980 break;
17981 case OPC_FSAF_df:
17982 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
17983 break;
17984 case OPC_FEXDO_df:
17985 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
17986 break;
17987 case OPC_FSUN_df:
17988 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
17989 break;
17990 case OPC_FSOR_df:
17991 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
17992 break;
17993 case OPC_FSEQ_df:
17994 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
17995 break;
17996 case OPC_FTQ_df:
17997 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
17998 break;
17999 case OPC_FSUNE_df:
18000 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18001 break;
18002 case OPC_FSUEQ_df:
18003 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18004 break;
18005 case OPC_FSNE_df:
18006 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18007 break;
18008 case OPC_FSLT_df:
18009 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18010 break;
18011 case OPC_FMIN_df:
18012 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18013 break;
18014 case OPC_MULR_Q_df:
18015 tcg_gen_movi_i32(tdf, df + 1);
18016 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18017 break;
18018 case OPC_FSULT_df:
18019 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18020 break;
18021 case OPC_FMIN_A_df:
18022 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18023 break;
18024 case OPC_MADDR_Q_df:
18025 tcg_gen_movi_i32(tdf, df + 1);
18026 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18027 break;
18028 case OPC_FSLE_df:
18029 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18030 break;
18031 case OPC_FMAX_df:
18032 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18033 break;
18034 case OPC_MSUBR_Q_df:
18035 tcg_gen_movi_i32(tdf, df + 1);
18036 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18037 break;
18038 case OPC_FSULE_df:
18039 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18040 break;
18041 case OPC_FMAX_A_df:
18042 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18043 break;
18044 default:
18045 MIPS_INVAL("MSA instruction");
18046 generate_exception(ctx, EXCP_RI);
18047 break;
18048 }
18049
18050 tcg_temp_free_i32(twd);
18051 tcg_temp_free_i32(tws);
18052 tcg_temp_free_i32(twt);
18053 tcg_temp_free_i32(tdf);
18054}
18055
4c789546
YK
18056static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18057{
18058 uint32_t opcode = ctx->opcode;
18059 check_insn(ctx, ASE_MSA);
18060 check_msa_access(ctx);
18061
18062 switch (MASK_MSA_MINOR(opcode)) {
18063 case OPC_MSA_I8_00:
18064 case OPC_MSA_I8_01:
18065 case OPC_MSA_I8_02:
18066 gen_msa_i8(env, ctx);
18067 break;
80e71591
YK
18068 case OPC_MSA_I5_06:
18069 case OPC_MSA_I5_07:
18070 gen_msa_i5(env, ctx);
18071 break;
d4cf28de
YK
18072 case OPC_MSA_BIT_09:
18073 case OPC_MSA_BIT_0A:
18074 gen_msa_bit(env, ctx);
18075 break;
28f99f08
YK
18076 case OPC_MSA_3R_0D:
18077 case OPC_MSA_3R_0E:
18078 case OPC_MSA_3R_0F:
18079 case OPC_MSA_3R_10:
18080 case OPC_MSA_3R_11:
18081 case OPC_MSA_3R_12:
18082 case OPC_MSA_3R_13:
18083 case OPC_MSA_3R_14:
18084 case OPC_MSA_3R_15:
18085 gen_msa_3r(env, ctx);
18086 break;
1e608ec1
YK
18087 case OPC_MSA_ELM:
18088 gen_msa_elm(env, ctx);
18089 break;
7d05b9c8
YK
18090 case OPC_MSA_3RF_1A:
18091 case OPC_MSA_3RF_1B:
18092 case OPC_MSA_3RF_1C:
18093 gen_msa_3rf(env, ctx);
18094 break;
4c789546
YK
18095 default:
18096 MIPS_INVAL("MSA instruction");
18097 generate_exception(ctx, EXCP_RI);
18098 break;
18099 }
18100
18101}
18102
099e5b4d
LA
18103static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
18104{
18105 int32_t offset;
18106 int rs, rt, rd, sa;
18107 uint32_t op, op1;
18108 int16_t imm;
18109
18110 /* make sure instructions are on a word boundary */
18111 if (ctx->pc & 0x3) {
18112 env->CP0_BadVAddr = ctx->pc;
aea14095 18113 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
18114 return;
18115 }
18116
18117 /* Handle blikely not taken case */
18118 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18119 int l1 = gen_new_label();
18120
18121 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18122 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18123 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18124 gen_goto_tb(ctx, 1, ctx->pc + 4);
18125 gen_set_label(l1);
18126 }
18127
18128 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18129 tcg_gen_debug_insn_start(ctx->pc);
18130 }
18131
18132 op = MASK_OP_MAJOR(ctx->opcode);
18133 rs = (ctx->opcode >> 21) & 0x1f;
18134 rt = (ctx->opcode >> 16) & 0x1f;
18135 rd = (ctx->opcode >> 11) & 0x1f;
18136 sa = (ctx->opcode >> 6) & 0x1f;
18137 imm = (int16_t)ctx->opcode;
18138 switch (op) {
18139 case OPC_SPECIAL:
18140 decode_opc_special(env, ctx);
18141 break;
18142 case OPC_SPECIAL2:
4267d3e6 18143 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18144 break;
18145 case OPC_SPECIAL3:
18146 decode_opc_special3(env, ctx);
18147 break;
7a387fff
TS
18148 case OPC_REGIMM:
18149 op1 = MASK_REGIMM(ctx->opcode);
18150 switch (op1) {
fecd2646
LA
18151 case OPC_BLTZL: /* REGIMM branches */
18152 case OPC_BGEZL:
18153 case OPC_BLTZALL:
18154 case OPC_BGEZALL:
18155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18156 case OPC_BLTZ:
18157 case OPC_BGEZ:
b231c103 18158 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18159 break;
fecd2646
LA
18160 case OPC_BLTZAL:
18161 case OPC_BGEZAL:
0aefa333
YK
18162 if (ctx->insn_flags & ISA_MIPS32R6) {
18163 if (rs == 0) {
18164 /* OPC_NAL, OPC_BAL */
b231c103 18165 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18166 } else {
18167 generate_exception(ctx, EXCP_RI);
18168 }
18169 } else {
b231c103 18170 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18171 }
c9602061 18172 break;
7a387fff
TS
18173 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18174 case OPC_TNEI:
fecd2646 18175 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18176 gen_trap(ctx, op1, rs, -1, imm);
18177 break;
18178 case OPC_SYNCI:
d75c135e 18179 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18180 /* Break the TB to be able to sync copied instructions
18181 immediately */
18182 ctx->bstate = BS_STOP;
6af0bf9c 18183 break;
e45a93e2
JL
18184 case OPC_BPOSGE32: /* MIPS DSP branch */
18185#if defined(TARGET_MIPS64)
18186 case OPC_BPOSGE64:
18187#endif
18188 check_dsp(ctx);
b231c103 18189 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18190 break;
d4ea6acd
LA
18191#if defined(TARGET_MIPS64)
18192 case OPC_DAHI:
18193 check_insn(ctx, ISA_MIPS32R6);
18194 check_mips_64(ctx);
18195 if (rs != 0) {
18196 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18197 }
18198 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18199 break;
18200 case OPC_DATI:
18201 check_insn(ctx, ISA_MIPS32R6);
18202 check_mips_64(ctx);
18203 if (rs != 0) {
18204 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18205 }
18206 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18207 break;
18208#endif
6af0bf9c 18209 default: /* Invalid */
923617a3 18210 MIPS_INVAL("regimm");
6af0bf9c
FB
18211 generate_exception(ctx, EXCP_RI);
18212 break;
18213 }
18214 break;
7a387fff 18215 case OPC_CP0:
387a8fe5 18216 check_cp0_enabled(ctx);
7a387fff 18217 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18218 switch (op1) {
7a387fff
TS
18219 case OPC_MFC0:
18220 case OPC_MTC0:
ead9360e
TS
18221 case OPC_MFTR:
18222 case OPC_MTTR:
d26bc211 18223#if defined(TARGET_MIPS64)
7a387fff
TS
18224 case OPC_DMFC0:
18225 case OPC_DMTC0:
18226#endif
f1aa6320 18227#ifndef CONFIG_USER_ONLY
932e71cd 18228 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 18229#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18230 break;
18231 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 18232#ifndef CONFIG_USER_ONLY
932e71cd 18233 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 18234#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18235 break;
18236 case OPC_MFMC0:
8706c382 18237#ifndef CONFIG_USER_ONLY
932e71cd 18238 {
099e5b4d 18239 uint32_t op2;
35fbce2c 18240 TCGv t0 = tcg_temp_new();
6c5c1e20 18241
0eaef5aa 18242 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
18243 switch (op2) {
18244 case OPC_DMT:
d75c135e 18245 check_insn(ctx, ASE_MT);
9ed5726c 18246 gen_helper_dmt(t0);
35fbce2c 18247 gen_store_gpr(t0, rt);
6c5c1e20
TS
18248 break;
18249 case OPC_EMT:
d75c135e 18250 check_insn(ctx, ASE_MT);
9ed5726c 18251 gen_helper_emt(t0);
35fbce2c 18252 gen_store_gpr(t0, rt);
da80682b 18253 break;
6c5c1e20 18254 case OPC_DVPE:
d75c135e 18255 check_insn(ctx, ASE_MT);
895c2d04 18256 gen_helper_dvpe(t0, cpu_env);
35fbce2c 18257 gen_store_gpr(t0, rt);
6c5c1e20
TS
18258 break;
18259 case OPC_EVPE:
d75c135e 18260 check_insn(ctx, ASE_MT);
895c2d04 18261 gen_helper_evpe(t0, cpu_env);
35fbce2c 18262 gen_store_gpr(t0, rt);
6c5c1e20
TS
18263 break;
18264 case OPC_DI:
d75c135e 18265 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18266 save_cpu_state(ctx, 1);
895c2d04 18267 gen_helper_di(t0, cpu_env);
35fbce2c 18268 gen_store_gpr(t0, rt);
6c5c1e20
TS
18269 /* Stop translation as we may have switched the execution mode */
18270 ctx->bstate = BS_STOP;
18271 break;
18272 case OPC_EI:
d75c135e 18273 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18274 save_cpu_state(ctx, 1);
895c2d04 18275 gen_helper_ei(t0, cpu_env);
35fbce2c 18276 gen_store_gpr(t0, rt);
6c5c1e20
TS
18277 /* Stop translation as we may have switched the execution mode */
18278 ctx->bstate = BS_STOP;
18279 break;
18280 default: /* Invalid */
18281 MIPS_INVAL("mfmc0");
18282 generate_exception(ctx, EXCP_RI);
18283 break;
18284 }
6c5c1e20 18285 tcg_temp_free(t0);
7a387fff 18286 }
0eaef5aa 18287#endif /* !CONFIG_USER_ONLY */
6af0bf9c 18288 break;
7a387fff 18289 case OPC_RDPGPR:
d75c135e 18290 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18291 gen_load_srsgpr(rt, rd);
ead9360e 18292 break;
7a387fff 18293 case OPC_WRPGPR:
d75c135e 18294 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18295 gen_store_srsgpr(rt, rd);
38121543 18296 break;
6af0bf9c 18297 default:
923617a3 18298 MIPS_INVAL("cp0");
7a387fff 18299 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
18300 break;
18301 }
18302 break;
31837be3
YK
18303 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18304 if (ctx->insn_flags & ISA_MIPS32R6) {
18305 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18306 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18307 } else {
18308 /* OPC_ADDI */
18309 /* Arithmetic with immediate opcode */
18310 gen_arith_imm(ctx, op, rt, rs, imm);
18311 }
18312 break;
324d9e32 18313 case OPC_ADDIU:
d75c135e 18314 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18315 break;
324d9e32
AJ
18316 case OPC_SLTI: /* Set on less than with immediate opcode */
18317 case OPC_SLTIU:
d75c135e 18318 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
18319 break;
18320 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 18321 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
18322 case OPC_ORI:
18323 case OPC_XORI:
d75c135e 18324 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 18325 break;
7a387fff
TS
18326 case OPC_J ... OPC_JAL: /* Jump */
18327 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18328 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 18329 break;
31837be3
YK
18330 /* Branch */
18331 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18332 if (ctx->insn_flags & ISA_MIPS32R6) {
18333 if (rt == 0) {
18334 generate_exception(ctx, EXCP_RI);
18335 break;
18336 }
18337 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18338 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18339 } else {
18340 /* OPC_BLEZL */
b231c103 18341 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18342 }
18343 break;
18344 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18345 if (ctx->insn_flags & ISA_MIPS32R6) {
18346 if (rt == 0) {
18347 generate_exception(ctx, EXCP_RI);
18348 break;
18349 }
18350 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18351 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18352 } else {
18353 /* OPC_BGTZL */
b231c103 18354 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18355 }
18356 break;
18357 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18358 if (rt == 0) {
18359 /* OPC_BLEZ */
b231c103 18360 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18361 } else {
18362 check_insn(ctx, ISA_MIPS32R6);
18363 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18364 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18365 }
18366 break;
18367 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18368 if (rt == 0) {
18369 /* OPC_BGTZ */
b231c103 18370 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18371 } else {
18372 check_insn(ctx, ISA_MIPS32R6);
18373 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18374 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18375 }
18376 break;
18377 case OPC_BEQL:
18378 case OPC_BNEL:
fecd2646 18379 check_insn_opc_removed(ctx, ISA_MIPS32R6);
31837be3
YK
18380 case OPC_BEQ:
18381 case OPC_BNE:
b231c103 18382 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 18383 break;
fecd2646
LA
18384 case OPC_LWL: /* Load and stores */
18385 case OPC_LWR:
4368b29a 18386 case OPC_LL:
fecd2646
LA
18387 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18388 case OPC_LB ... OPC_LH:
18389 case OPC_LW ... OPC_LHU:
d75c135e 18390 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 18391 break;
fecd2646 18392 case OPC_SWL:
7a387fff 18393 case OPC_SWR:
fecd2646
LA
18394 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18395 case OPC_SB ... OPC_SH:
18396 case OPC_SW:
5c13fdfd 18397 gen_st(ctx, op, rt, rs, imm);
7a387fff 18398 break;
d66c7132 18399 case OPC_SC:
4368b29a 18400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
18401 gen_st_cond(ctx, op, rt, rs, imm);
18402 break;
7a387fff 18403 case OPC_CACHE:
bf7910c6 18404 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 18405 check_cp0_enabled(ctx);
d75c135e 18406 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 18407 /* Treat as NOP. */
34ae7b51 18408 break;
7a387fff 18409 case OPC_PREF:
bf7910c6 18410 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18411 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 18412 /* Treat as NOP. */
6af0bf9c 18413 break;
4ad40f36 18414
923617a3 18415 /* Floating point (COP1). */
7a387fff
TS
18416 case OPC_LWC1:
18417 case OPC_LDC1:
18418 case OPC_SWC1:
18419 case OPC_SDC1:
5ab5c041 18420 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
18421 break;
18422
7a387fff 18423 case OPC_CP1:
5692c6e1
YK
18424 op1 = MASK_CP1(ctx->opcode);
18425
18426 switch (op1) {
18427 case OPC_MFHC1:
18428 case OPC_MTHC1:
5e755519 18429 check_cp1_enabled(ctx);
5692c6e1
YK
18430 check_insn(ctx, ISA_MIPS32R2);
18431 case OPC_MFC1:
18432 case OPC_CFC1:
18433 case OPC_MTC1:
18434 case OPC_CTC1:
18435 check_cp1_enabled(ctx);
18436 gen_cp1(ctx, op1, rt, rd);
18437 break;
d26bc211 18438#if defined(TARGET_MIPS64)
5692c6e1
YK
18439 case OPC_DMFC1:
18440 case OPC_DMTC1:
18441 check_cp1_enabled(ctx);
18442 check_insn(ctx, ISA_MIPS3);
18443 gen_cp1(ctx, op1, rt, rd);
18444 break;
e189e748 18445#endif
5692c6e1
YK
18446 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18447 check_cp1_enabled(ctx);
18448 if (ctx->insn_flags & ISA_MIPS32R6) {
18449 /* OPC_BC1EQZ */
31837be3
YK
18450 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18451 rt, imm << 2);
5692c6e1
YK
18452 } else {
18453 /* OPC_BC1ANY2 */
b8aa4598 18454 check_cop1x(ctx);
d75c135e 18455 check_insn(ctx, ASE_MIPS3D);
d75c135e 18456 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 18457 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
18458 }
18459 break;
18460 case OPC_BC1NEZ:
18461 check_cp1_enabled(ctx);
18462 check_insn(ctx, ISA_MIPS32R6);
18463 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18464 rt, imm << 2);
18465 break;
18466 case OPC_BC1ANY4:
18467 check_cp1_enabled(ctx);
18468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18469 check_cop1x(ctx);
18470 check_insn(ctx, ASE_MIPS3D);
18471 /* fall through */
18472 case OPC_BC1:
18473 check_cp1_enabled(ctx);
18474 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18475 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18476 (rt >> 2) & 0x7, imm << 2);
18477 break;
18478 case OPC_PS_FMT:
18479 check_cp1_enabled(ctx);
18480 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18481 case OPC_S_FMT:
18482 case OPC_D_FMT:
18483 check_cp1_enabled(ctx);
18484 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18485 (imm >> 8) & 0x7);
18486 break;
18487 case OPC_W_FMT:
18488 case OPC_L_FMT:
18489 {
18490 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18491 check_cp1_enabled(ctx);
18492 if (ctx->insn_flags & ISA_MIPS32R6) {
18493 switch (r6_op) {
18494 case R6_OPC_CMP_AF_S:
18495 case R6_OPC_CMP_UN_S:
18496 case R6_OPC_CMP_EQ_S:
18497 case R6_OPC_CMP_UEQ_S:
18498 case R6_OPC_CMP_LT_S:
18499 case R6_OPC_CMP_ULT_S:
18500 case R6_OPC_CMP_LE_S:
18501 case R6_OPC_CMP_ULE_S:
18502 case R6_OPC_CMP_SAF_S:
18503 case R6_OPC_CMP_SUN_S:
18504 case R6_OPC_CMP_SEQ_S:
18505 case R6_OPC_CMP_SEUQ_S:
18506 case R6_OPC_CMP_SLT_S:
18507 case R6_OPC_CMP_SULT_S:
18508 case R6_OPC_CMP_SLE_S:
18509 case R6_OPC_CMP_SULE_S:
18510 case R6_OPC_CMP_OR_S:
18511 case R6_OPC_CMP_UNE_S:
18512 case R6_OPC_CMP_NE_S:
18513 case R6_OPC_CMP_SOR_S:
18514 case R6_OPC_CMP_SUNE_S:
18515 case R6_OPC_CMP_SNE_S:
18516 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18517 break;
18518 case R6_OPC_CMP_AF_D:
18519 case R6_OPC_CMP_UN_D:
18520 case R6_OPC_CMP_EQ_D:
18521 case R6_OPC_CMP_UEQ_D:
18522 case R6_OPC_CMP_LT_D:
18523 case R6_OPC_CMP_ULT_D:
18524 case R6_OPC_CMP_LE_D:
18525 case R6_OPC_CMP_ULE_D:
18526 case R6_OPC_CMP_SAF_D:
18527 case R6_OPC_CMP_SUN_D:
18528 case R6_OPC_CMP_SEQ_D:
18529 case R6_OPC_CMP_SEUQ_D:
18530 case R6_OPC_CMP_SLT_D:
18531 case R6_OPC_CMP_SULT_D:
18532 case R6_OPC_CMP_SLE_D:
18533 case R6_OPC_CMP_SULE_D:
18534 case R6_OPC_CMP_OR_D:
18535 case R6_OPC_CMP_UNE_D:
18536 case R6_OPC_CMP_NE_D:
18537 case R6_OPC_CMP_SOR_D:
18538 case R6_OPC_CMP_SUNE_D:
18539 case R6_OPC_CMP_SNE_D:
18540 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18541 break;
18542 default:
3f493883
YK
18543 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18544 (imm >> 8) & 0x7);
5692c6e1 18545 break;
3f493883 18546 }
5692c6e1
YK
18547 } else {
18548 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18549 (imm >> 8) & 0x7);
36d23958 18550 }
5692c6e1
YK
18551 break;
18552 }
18553 case OPC_BZ_V:
18554 case OPC_BNZ_V:
18555 case OPC_BZ_B:
18556 case OPC_BZ_H:
18557 case OPC_BZ_W:
18558 case OPC_BZ_D:
18559 case OPC_BNZ_B:
18560 case OPC_BNZ_H:
18561 case OPC_BNZ_W:
18562 case OPC_BNZ_D:
18563 check_insn(ctx, ASE_MSA);
18564 gen_msa_branch(env, ctx, op1);
18565 break;
18566 default:
18567 MIPS_INVAL("cp1");
18568 generate_exception(ctx, EXCP_RI);
18569 break;
6ea83fed 18570 }
4ad40f36
FB
18571 break;
18572
31837be3
YK
18573 /* Compact branches [R6] and COP2 [non-R6] */
18574 case OPC_BC: /* OPC_LWC2 */
18575 case OPC_BALC: /* OPC_SWC2 */
18576 if (ctx->insn_flags & ISA_MIPS32R6) {
18577 /* OPC_BC, OPC_BALC */
18578 gen_compute_compact_branch(ctx, op, 0, 0,
18579 sextract32(ctx->opcode << 2, 0, 28));
18580 } else {
18581 /* OPC_LWC2, OPC_SWC2 */
18582 /* COP2: Not implemented. */
18583 generate_exception_err(ctx, EXCP_CpU, 2);
18584 }
18585 break;
18586 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18587 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
18588 if (ctx->insn_flags & ISA_MIPS32R6) {
18589 if (rs != 0) {
18590 /* OPC_BEQZC, OPC_BNEZC */
18591 gen_compute_compact_branch(ctx, op, rs, 0,
18592 sextract32(ctx->opcode << 2, 0, 23));
18593 } else {
18594 /* OPC_JIC, OPC_JIALC */
18595 gen_compute_compact_branch(ctx, op, 0, rt, imm);
18596 }
18597 } else {
18598 /* OPC_LWC2, OPC_SWC2 */
18599 /* COP2: Not implemented. */
18600 generate_exception_err(ctx, EXCP_CpU, 2);
18601 }
4ad40f36 18602 break;
bd277fa1 18603 case OPC_CP2:
d75c135e 18604 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
18605 /* Note that these instructions use different fields. */
18606 gen_loongson_multimedia(ctx, sa, rd, rt);
18607 break;
4ad40f36 18608
7a387fff 18609 case OPC_CP3:
fecd2646 18610 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 18611 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 18612 check_cp1_enabled(ctx);
36d23958
TS
18613 op1 = MASK_CP3(ctx->opcode);
18614 switch (op1) {
5a5012ec
TS
18615 case OPC_LWXC1:
18616 case OPC_LDXC1:
18617 case OPC_LUXC1:
18618 case OPC_SWXC1:
18619 case OPC_SDXC1:
18620 case OPC_SUXC1:
93b12ccc 18621 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 18622 break;
e0c84da7 18623 case OPC_PREFX:
ead9360e 18624 /* Treat as NOP. */
e0c84da7 18625 break;
5a5012ec
TS
18626 case OPC_ALNV_PS:
18627 case OPC_MADD_S:
18628 case OPC_MADD_D:
18629 case OPC_MADD_PS:
18630 case OPC_MSUB_S:
18631 case OPC_MSUB_D:
18632 case OPC_MSUB_PS:
18633 case OPC_NMADD_S:
18634 case OPC_NMADD_D:
18635 case OPC_NMADD_PS:
18636 case OPC_NMSUB_S:
18637 case OPC_NMSUB_D:
18638 case OPC_NMSUB_PS:
18639 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
18640 break;
36d23958 18641 default:
923617a3 18642 MIPS_INVAL("cp3");
e397ee33 18643 generate_exception (ctx, EXCP_RI);
36d23958
TS
18644 break;
18645 }
18646 } else {
e397ee33 18647 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 18648 }
4ad40f36
FB
18649 break;
18650
d26bc211 18651#if defined(TARGET_MIPS64)
7a387fff 18652 /* MIPS64 opcodes */
7a387fff 18653 case OPC_LDL ... OPC_LDR:
bf7910c6 18654 case OPC_LLD:
fecd2646
LA
18655 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18656 case OPC_LWU:
7a387fff 18657 case OPC_LD:
d75c135e 18658 check_insn(ctx, ISA_MIPS3);
5c13fdfd 18659 check_mips_64(ctx);
d75c135e 18660 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
18661 break;
18662 case OPC_SDL ... OPC_SDR:
fecd2646 18663 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 18664 case OPC_SD:
d75c135e 18665 check_insn(ctx, ISA_MIPS3);
e189e748 18666 check_mips_64(ctx);
5c13fdfd 18667 gen_st(ctx, op, rt, rs, imm);
7a387fff 18668 break;
d66c7132 18669 case OPC_SCD:
bf7910c6 18670 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18671 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
18672 check_mips_64(ctx);
18673 gen_st_cond(ctx, op, rt, rs, imm);
18674 break;
31837be3
YK
18675 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
18676 if (ctx->insn_flags & ISA_MIPS32R6) {
18677 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
18678 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18679 } else {
18680 /* OPC_DADDI */
18681 check_insn(ctx, ISA_MIPS3);
18682 check_mips_64(ctx);
18683 gen_arith_imm(ctx, op, rt, rs, imm);
18684 }
18685 break;
324d9e32 18686 case OPC_DADDIU:
d75c135e 18687 check_insn(ctx, ISA_MIPS3);
e189e748 18688 check_mips_64(ctx);
d75c135e 18689 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18690 break;
31837be3
YK
18691#else
18692 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
18693 if (ctx->insn_flags & ISA_MIPS32R6) {
18694 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18695 } else {
18696 MIPS_INVAL("major opcode");
18697 generate_exception(ctx, EXCP_RI);
18698 }
18699 break;
6af0bf9c 18700#endif
d4ea6acd
LA
18701 case OPC_DAUI: /* OPC_JALX */
18702 if (ctx->insn_flags & ISA_MIPS32R6) {
18703#if defined(TARGET_MIPS64)
18704 /* OPC_DAUI */
18705 check_mips_64(ctx);
18706 if (rt != 0) {
18707 TCGv t0 = tcg_temp_new();
18708 gen_load_gpr(t0, rs);
18709 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
18710 tcg_temp_free(t0);
18711 }
18712 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
18713#else
18714 generate_exception(ctx, EXCP_RI);
18715 MIPS_INVAL("major opcode");
18716#endif
18717 } else {
18718 /* OPC_JALX */
18719 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
18720 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18721 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 18722 }
364d4831 18723 break;
4c789546 18724 case OPC_MSA: /* OPC_MDMX */
7a387fff 18725 /* MDMX: Not implemented. */
4c789546 18726 gen_msa(env, ctx);
d4ea6acd
LA
18727 break;
18728 case OPC_PCREL:
18729 check_insn(ctx, ISA_MIPS32R6);
18730 gen_pcrel(ctx, rs, imm);
18731 break;
6af0bf9c 18732 default: /* Invalid */
923617a3 18733 MIPS_INVAL("major opcode");
6af0bf9c
FB
18734 generate_exception(ctx, EXCP_RI);
18735 break;
18736 }
6af0bf9c
FB
18737}
18738
2cfc5f17 18739static inline void
6429db34
AF
18740gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
18741 bool search_pc)
6af0bf9c 18742{
ed2803da 18743 CPUState *cs = CPU(cpu);
6429db34 18744 CPUMIPSState *env = &cpu->env;
278d0702 18745 DisasContext ctx;
6af0bf9c
FB
18746 target_ulong pc_start;
18747 uint16_t *gen_opc_end;
a1d1bb31 18748 CPUBreakpoint *bp;
6af0bf9c 18749 int j, lj = -1;
2e70f6ef
PB
18750 int num_insns;
18751 int max_insns;
c9602061 18752 int insn_bytes;
339cd2a8 18753 int is_slot;
6af0bf9c 18754
93fcfe39
AL
18755 if (search_pc)
18756 qemu_log("search pc %d\n", search_pc);
4ad40f36 18757
6af0bf9c 18758 pc_start = tb->pc;
92414b31 18759 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 18760 ctx.pc = pc_start;
4ad40f36 18761 ctx.saved_pc = -1;
ed2803da 18762 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 18763 ctx.insn_flags = env->insn_flags;
5ab5c041 18764 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
18765 ctx.tb = tb;
18766 ctx.bstate = BS_NONE;
e98c0d17 18767 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 18768 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 18769 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
18770 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
18771 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 18772 /* Restore delay slot state from the tb context. */
c068688b 18773 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 18774 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 18775 restore_cpu_state(env, &ctx);
932e71cd 18776#ifdef CONFIG_USER_ONLY
0eaef5aa 18777 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 18778#else
0eaef5aa 18779 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 18780#endif
2e70f6ef
PB
18781 num_insns = 0;
18782 max_insns = tb->cflags & CF_COUNT_MASK;
18783 if (max_insns == 0)
18784 max_insns = CF_COUNT_MASK;
d12d51d5 18785 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 18786 gen_tb_start();
faf7aaa9 18787 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
18788 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
18789 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 18790 if (bp->pc == ctx.pc) {
278d0702 18791 save_cpu_state(&ctx, 1);
4ad40f36 18792 ctx.bstate = BS_BRANCH;
895c2d04 18793 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
18794 /* Include the breakpoint location or the tb won't
18795 * be flushed when it must be. */
18796 ctx.pc += 4;
4ad40f36
FB
18797 goto done_generating;
18798 }
18799 }
18800 }
18801
6af0bf9c 18802 if (search_pc) {
92414b31 18803 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
18804 if (lj < j) {
18805 lj++;
18806 while (lj < j)
ab1103de 18807 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 18808 }
25983cad 18809 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 18810 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 18811 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 18812 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 18813 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 18814 }
2e70f6ef
PB
18815 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
18816 gen_io_start();
c9602061 18817
339cd2a8 18818 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 18819 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 18820 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 18821 insn_bytes = 4;
240ce26a 18822 decode_opc(env, &ctx);
d75c135e 18823 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 18824 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 18825 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 18826 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 18827 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 18828 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
18829 } else {
18830 generate_exception(&ctx, EXCP_RI);
3c824109 18831 ctx.bstate = BS_STOP;
c9602061
NF
18832 break;
18833 }
31837be3 18834
b231c103 18835 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
18836 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
18837 MIPS_HFLAG_FBNSLOT))) {
18838 /* force to generate branch as there is neither delay nor
18839 forbidden slot */
18840 is_slot = 1;
b231c103
YK
18841 }
18842 }
339cd2a8 18843 if (is_slot) {
31837be3 18844 gen_branch(&ctx, insn_bytes);
c9602061
NF
18845 }
18846 ctx.pc += insn_bytes;
18847
2e70f6ef 18848 num_insns++;
4ad40f36 18849
7b270ef2
NF
18850 /* Execute a branch and its delay slot as a single instruction.
18851 This is what GDB expects and is consistent with what the
18852 hardware does (e.g. if a delay slot instruction faults, the
18853 reported PC is the PC of the branch). */
ed2803da 18854 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 18855 break;
ed2803da 18856 }
4ad40f36 18857
6af0bf9c
FB
18858 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
18859 break;
4ad40f36 18860
efd7f486 18861 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 18862 break;
efd7f486 18863 }
faf7aaa9 18864
2e70f6ef
PB
18865 if (num_insns >= max_insns)
18866 break;
1b530a6d
AJ
18867
18868 if (singlestep)
18869 break;
6af0bf9c 18870 }
ed2803da 18871 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 18872 gen_io_end();
ed2803da
AF
18873 }
18874 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 18875 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 18876 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 18877 } else {
6958549d 18878 switch (ctx.bstate) {
16c00cb2 18879 case BS_STOP:
df1561e2
TS
18880 gen_goto_tb(&ctx, 0, ctx.pc);
18881 break;
16c00cb2 18882 case BS_NONE:
278d0702 18883 save_cpu_state(&ctx, 0);
16c00cb2
TS
18884 gen_goto_tb(&ctx, 0, ctx.pc);
18885 break;
5a5012ec 18886 case BS_EXCP:
57fec1fe 18887 tcg_gen_exit_tb(0);
16c00cb2 18888 break;
5a5012ec
TS
18889 case BS_BRANCH:
18890 default:
18891 break;
6958549d 18892 }
6af0bf9c 18893 }
4ad40f36 18894done_generating:
806f352d 18895 gen_tb_end(tb, num_insns);
efd7f486 18896 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 18897 if (search_pc) {
92414b31 18898 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
18899 lj++;
18900 while (lj <= j)
ab1103de 18901 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
18902 } else {
18903 tb->size = ctx.pc - pc_start;
2e70f6ef 18904 tb->icount = num_insns;
6af0bf9c
FB
18905 }
18906#ifdef DEBUG_DISAS
d12d51d5 18907 LOG_DISAS("\n");
8fec2b8c 18908 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 18909 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 18910 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 18911 qemu_log("\n");
6af0bf9c
FB
18912 }
18913#endif
6af0bf9c
FB
18914}
18915
7db13fae 18916void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 18917{
6429db34 18918 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
18919}
18920
7db13fae 18921void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 18922{
6429db34 18923 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
18924}
18925
7db13fae 18926static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 18927 int flags)
6ea83fed
FB
18928{
18929 int i;
5e755519 18930 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 18931
2a5612e6
SW
18932#define printfpr(fp) \
18933 do { \
18934 if (is_fpu64) \
18935 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18936 " fd:%13g fs:%13g psu: %13g\n", \
18937 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
18938 (double)(fp)->fd, \
18939 (double)(fp)->fs[FP_ENDIAN_IDX], \
18940 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
18941 else { \
18942 fpr_t tmp; \
18943 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
18944 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
18945 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18946 " fd:%13g fs:%13g psu:%13g\n", \
18947 tmp.w[FP_ENDIAN_IDX], tmp.d, \
18948 (double)tmp.fd, \
18949 (double)tmp.fs[FP_ENDIAN_IDX], \
18950 (double)tmp.fs[!FP_ENDIAN_IDX]); \
18951 } \
6ea83fed
FB
18952 } while(0)
18953
5a5012ec 18954
9a78eead
SW
18955 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
18956 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 18957 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
18958 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
18959 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 18960 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
18961 }
18962
18963#undef printfpr
18964}
18965
d26bc211 18966#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 18967/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 18968 sign-extended values on 64bit machines. */
c570fd16
TS
18969
18970#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
18971
8706c382 18972static void
7db13fae 18973cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 18974 fprintf_function cpu_fprintf,
8706c382 18975 int flags)
c570fd16
TS
18976{
18977 int i;
18978
b5dc7732
TS
18979 if (!SIGN_EXT_P(env->active_tc.PC))
18980 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
18981 if (!SIGN_EXT_P(env->active_tc.HI[0]))
18982 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
18983 if (!SIGN_EXT_P(env->active_tc.LO[0]))
18984 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 18985 if (!SIGN_EXT_P(env->btarget))
3594c774 18986 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
18987
18988 for (i = 0; i < 32; i++) {
b5dc7732
TS
18989 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
18990 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
18991 }
18992
18993 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 18994 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
18995 if (!SIGN_EXT_P(env->lladdr))
18996 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
18997}
18998#endif
18999
878096ee
AF
19000void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19001 int flags)
6af0bf9c 19002{
878096ee
AF
19003 MIPSCPU *cpu = MIPS_CPU(cs);
19004 CPUMIPSState *env = &cpu->env;
6af0bf9c 19005 int i;
3b46e624 19006
a7200c9f
SW
19007 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19008 " LO=0x" TARGET_FMT_lx " ds %04x "
19009 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19010 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19011 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19012 for (i = 0; i < 32; i++) {
19013 if ((i & 3) == 0)
19014 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19015 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19016 if ((i & 3) == 3)
19017 cpu_fprintf(f, "\n");
19018 }
568b600d 19019
3594c774 19020 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19021 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 19022 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 19023 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 19024 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19025 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 19026#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
19027 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19028#endif
6af0bf9c
FB
19029}
19030
78ce64f4 19031void mips_tcg_init(void)
39454628 19032{
f01be154 19033 int i;
39454628
TS
19034 static int inited;
19035
19036 /* Initialize various static tables. */
19037 if (inited)
6958549d 19038 return;
39454628 19039
a7812ae4 19040 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19041 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19042 for (i = 1; i < 32; i++)
a7812ae4 19043 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19044 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19045 regnames[i]);
d73ee8a2
RH
19046
19047 for (i = 0; i < 32; i++) {
19048 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
19049 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
19050 }
19051
863f264d
YK
19052 for (i = 0; i < 32; i++) {
19053 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19054 msa_wr_d[i * 2] =
19055 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
19056 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19057 msa_wr_d[i * 2 + 1] =
19058 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19059 }
19060
a7812ae4 19061 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19062 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19063 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19064 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19065 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19066 regnames_HI[i]);
a7812ae4 19067 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19068 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19069 regnames_LO[i]);
4b2eb8d2 19070 }
a7812ae4 19071 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19072 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19073 "DSPControl");
1ba74fb8 19074 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19075 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19076 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19077 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19078 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19079 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19080
a7812ae4 19081 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19082 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19083 "fcr0");
19084 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19085 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19086 "fcr31");
39454628
TS
19087
19088 inited = 1;
19089}
19090
aaed909a
FB
19091#include "translate_init.c"
19092
30bf942d 19093MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19094{
0f71a709 19095 MIPSCPU *cpu;
6af0bf9c 19096 CPUMIPSState *env;
c227f099 19097 const mips_def_t *def;
6af0bf9c 19098
aaed909a
FB
19099 def = cpu_mips_find_by_name(cpu_model);
19100 if (!def)
19101 return NULL;
0f71a709
AF
19102 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19103 env = &cpu->env;
aaed909a
FB
19104 env->cpu_model = def;
19105
51cc2e78
BS
19106#ifndef CONFIG_USER_ONLY
19107 mmu_init(env, def);
19108#endif
19109 fpu_init(env, def);
19110 mvp_init(env, def);
c1caf1d9
AF
19111
19112 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19113
30bf942d 19114 return cpu;
6ae81775
TS
19115}
19116
1bba0dc9 19117void cpu_state_reset(CPUMIPSState *env)
6ae81775 19118{
55e5c285
AF
19119 MIPSCPU *cpu = mips_env_get_cpu(env);
19120 CPUState *cs = CPU(cpu);
6ae81775 19121
51cc2e78
BS
19122 /* Reset registers to their default values */
19123 env->CP0_PRid = env->cpu_model->CP0_PRid;
19124 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19125#ifdef TARGET_WORDS_BIGENDIAN
19126 env->CP0_Config0 |= (1 << CP0C0_BE);
19127#endif
19128 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19129 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19130 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19131 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19132 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19133 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19134 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19135 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19136 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19137 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19138 << env->cpu_model->CP0_LLAddr_shift;
19139 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19140 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19141 env->CCRes = env->cpu_model->CCRes;
19142 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19143 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19144 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19145 env->current_tc = 0;
19146 env->SEGBITS = env->cpu_model->SEGBITS;
19147 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19148#if defined(TARGET_MIPS64)
19149 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19150 env->SEGMask |= 3ULL << 62;
19151 }
19152#endif
19153 env->PABITS = env->cpu_model->PABITS;
19154 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19155 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19156 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19157 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19158 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19159 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19160 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19161 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19162 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19163 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19164 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19165 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19166 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19167 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19168 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19169 env->insn_flags = env->cpu_model->insn_flags;
19170
0eaef5aa 19171#if defined(CONFIG_USER_ONLY)
03e6e501 19172 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19173# ifdef TARGET_MIPS64
19174 /* Enable 64-bit register mode. */
19175 env->CP0_Status |= (1 << CP0St_PX);
19176# endif
19177# ifdef TARGET_ABI_MIPSN64
19178 /* Enable 64-bit address mode. */
19179 env->CP0_Status |= (1 << CP0St_UX);
19180# endif
94159135
MI
19181 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19182 hardware registers. */
19183 env->CP0_HWREna |= 0x0000000F;
91a75935 19184 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19185 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19186 }
6f0af304
PJ
19187 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19188 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19189 }
4d66261f
PJ
19190# if defined(TARGET_MIPS64)
19191 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19192 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19193 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19194 env->CP0_Status |= (1 << CP0St_FR);
19195 }
4d66261f 19196# endif
932e71cd
AJ
19197#else
19198 if (env->hflags & MIPS_HFLAG_BMASK) {
19199 /* If the exception was raised from a delay slot,
19200 come back to the jump. */
19201 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 19202 } else {
932e71cd
AJ
19203 env->CP0_ErrorEPC = env->active_tc.PC;
19204 }
19205 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19206 env->CP0_Random = env->tlb->nb_tlb - 1;
19207 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19208 env->CP0_Wired = 0;
0a2672b7
JH
19209 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19210 if (kvm_enabled()) {
19211 env->CP0_EBase |= 0x40000000;
19212 } else {
19213 env->CP0_EBase |= 0x80000000;
19214 }
932e71cd
AJ
19215 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19216 /* vectored interrupts not implemented, timer on int 7,
19217 no performance counters. */
19218 env->CP0_IntCtl = 0xe0000000;
19219 {
19220 int i;
19221
19222 for (i = 0; i < 7; i++) {
19223 env->CP0_WatchLo[i] = 0;
19224 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 19225 }
932e71cd
AJ
19226 env->CP0_WatchLo[7] = 0;
19227 env->CP0_WatchHi[7] = 0;
fd88b6ab 19228 }
932e71cd
AJ
19229 /* Count register increments in debug mode, EJTAG version 1 */
19230 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 19231
4b69c7e2
JH
19232 cpu_mips_store_count(env, 1);
19233
9e56e756
EI
19234 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19235 int i;
19236
19237 /* Only TC0 on VPE 0 starts as active. */
19238 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 19239 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
19240 env->tcs[i].CP0_TCHalt = 1;
19241 }
19242 env->active_tc.CP0_TCHalt = 1;
259186a7 19243 cs->halted = 1;
9e56e756 19244
55e5c285 19245 if (cs->cpu_index == 0) {
9e56e756
EI
19246 /* VPE0 starts up enabled. */
19247 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19248 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19249
19250 /* TC0 starts up unhalted. */
259186a7 19251 cs->halted = 0;
9e56e756
EI
19252 env->active_tc.CP0_TCHalt = 0;
19253 env->tcs[0].CP0_TCHalt = 0;
19254 /* With thread 0 active. */
19255 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19256 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19257 }
19258 }
51cc2e78 19259#endif
ddc584bd
LA
19260 if ((env->insn_flags & ISA_MIPS32R6) &&
19261 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19262 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19263 env->CP0_Status |= (1 << CP0St_FR);
19264 }
19265
863f264d
YK
19266 /* MSA */
19267 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19268 msa_reset(env);
19269 }
19270
03e6e501 19271 compute_hflags(env);
27103424 19272 cs->exception_index = EXCP_NONE;
6af0bf9c 19273}
d2856f1a 19274
7db13fae 19275void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 19276{
25983cad 19277 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
19278 env->hflags &= ~MIPS_HFLAG_BMASK;
19279 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
19280 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19281 case MIPS_HFLAG_BR:
19282 break;
19283 case MIPS_HFLAG_BC:
19284 case MIPS_HFLAG_BL:
19285 case MIPS_HFLAG_B:
19286 env->btarget = gen_opc_btarget[pc_pos];
19287 break;
19288 }
d2856f1a 19289}