]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: add MSA opcode enum
[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];
aa0bf00b 1359
1a7ff922 1360static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1361static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1362
022c62cb 1363#include "exec/gen-icount.h"
2e70f6ef 1364
895c2d04 1365#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1366 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1367 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1368 tcg_temp_free_i32(helper_tmp); \
1369 } while(0)
be24bb4f 1370
895c2d04 1371#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1372 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1373 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1374 tcg_temp_free_i32(helper_tmp); \
1375 } while(0)
be24bb4f 1376
895c2d04
BS
1377#define gen_helper_1e0i(name, ret, arg1) do { \
1378 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1379 gen_helper_##name(ret, cpu_env, helper_tmp); \
1380 tcg_temp_free_i32(helper_tmp); \
1381 } while(0)
1382
1383#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1384 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1385 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1386 tcg_temp_free_i32(helper_tmp); \
1387 } while(0)
1388
1389#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1390 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1391 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1392 tcg_temp_free_i32(helper_tmp); \
1393 } while(0)
1394
1395#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1396 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1397 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1398 tcg_temp_free_i32(helper_tmp); \
1399 } while(0)
be24bb4f 1400
895c2d04 1401#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1402 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1403 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1404 tcg_temp_free_i32(helper_tmp); \
1405 } while(0)
c239529e 1406
8e9ade68
TS
1407typedef struct DisasContext {
1408 struct TranslationBlock *tb;
1409 target_ulong pc, saved_pc;
1410 uint32_t opcode;
7b270ef2 1411 int singlestep_enabled;
d75c135e 1412 int insn_flags;
5ab5c041 1413 int32_t CP0_Config1;
8e9ade68
TS
1414 /* Routine used to access memory */
1415 int mem_idx;
1416 uint32_t hflags, saved_hflags;
1417 int bstate;
1418 target_ulong btarget;
d279279e 1419 bool ulri;
e98c0d17 1420 int kscrexist;
7207c7f9 1421 bool rxi;
9456c2fb 1422 int ie;
aea14095
LA
1423 bool bi;
1424 bool bp;
8e9ade68
TS
1425} DisasContext;
1426
1427enum {
1428 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1429 * exception condition */
8e9ade68
TS
1430 BS_STOP = 1, /* We want to stop translation for any reason */
1431 BS_BRANCH = 2, /* We reached a branch condition */
1432 BS_EXCP = 3, /* We reached an exception condition */
1433};
1434
d73ee8a2
RH
1435static const char * const regnames[] = {
1436 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1437 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1438 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1439 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1440};
6af0bf9c 1441
d73ee8a2
RH
1442static const char * const regnames_HI[] = {
1443 "HI0", "HI1", "HI2", "HI3",
1444};
4b2eb8d2 1445
d73ee8a2
RH
1446static const char * const regnames_LO[] = {
1447 "LO0", "LO1", "LO2", "LO3",
1448};
4b2eb8d2 1449
d73ee8a2
RH
1450static const char * const fregnames[] = {
1451 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1452 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1453 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1454 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1455};
958fb4a9 1456
fb7729e2
RH
1457#define MIPS_DEBUG(fmt, ...) \
1458 do { \
1459 if (MIPS_DEBUG_DISAS) { \
1460 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1461 TARGET_FMT_lx ": %08x " fmt "\n", \
1462 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1463 } \
1464 } while (0)
1465
1466#define LOG_DISAS(...) \
1467 do { \
1468 if (MIPS_DEBUG_DISAS) { \
1469 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1470 } \
1471 } while (0)
958fb4a9 1472
8e9ade68 1473#define MIPS_INVAL(op) \
8e9ade68 1474 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1475 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1476
8e9ade68
TS
1477/* General purpose registers moves. */
1478static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1479{
8e9ade68
TS
1480 if (reg == 0)
1481 tcg_gen_movi_tl(t, 0);
1482 else
4b2eb8d2 1483 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1484}
1485
8e9ade68 1486static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1487{
8e9ade68 1488 if (reg != 0)
4b2eb8d2 1489 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1490}
1491
8e9ade68 1492/* Moves to/from shadow registers. */
be24bb4f 1493static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1494{
d9bea114 1495 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1496
1497 if (from == 0)
d9bea114 1498 tcg_gen_movi_tl(t0, 0);
8e9ade68 1499 else {
d9bea114 1500 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1501 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1502
7db13fae 1503 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1504 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1505 tcg_gen_andi_i32(t2, t2, 0xf);
1506 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1507 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1508 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1509
d9bea114 1510 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1511 tcg_temp_free_ptr(addr);
d9bea114 1512 tcg_temp_free_i32(t2);
8e9ade68 1513 }
d9bea114
AJ
1514 gen_store_gpr(t0, to);
1515 tcg_temp_free(t0);
aaa9128a
TS
1516}
1517
be24bb4f 1518static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1519{
be24bb4f 1520 if (to != 0) {
d9bea114
AJ
1521 TCGv t0 = tcg_temp_new();
1522 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1523 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1524
d9bea114 1525 gen_load_gpr(t0, from);
7db13fae 1526 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1527 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1528 tcg_gen_andi_i32(t2, t2, 0xf);
1529 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1530 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1531 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1532
d9bea114 1533 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1534 tcg_temp_free_ptr(addr);
d9bea114
AJ
1535 tcg_temp_free_i32(t2);
1536 tcg_temp_free(t0);
8e9ade68 1537 }
aaa9128a
TS
1538}
1539
aaa9128a 1540/* Floating point register moves. */
d73ee8a2 1541static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1542{
d73ee8a2 1543 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1544}
1545
d73ee8a2 1546static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1547{
d73ee8a2
RH
1548 TCGv_i64 t64 = tcg_temp_new_i64();
1549 tcg_gen_extu_i32_i64(t64, t);
1550 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1551 tcg_temp_free_i64(t64);
6d066274
AJ
1552}
1553
7f6613ce 1554static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1555{
7f6613ce
PJ
1556 if (ctx->hflags & MIPS_HFLAG_F64) {
1557 TCGv_i64 t64 = tcg_temp_new_i64();
1558 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1559 tcg_gen_trunc_i64_i32(t, t64);
1560 tcg_temp_free_i64(t64);
1561 } else {
1562 gen_load_fpr32(t, reg | 1);
1563 }
6d066274
AJ
1564}
1565
7f6613ce 1566static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1567{
7f6613ce
PJ
1568 if (ctx->hflags & MIPS_HFLAG_F64) {
1569 TCGv_i64 t64 = tcg_temp_new_i64();
1570 tcg_gen_extu_i32_i64(t64, t);
1571 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1572 tcg_temp_free_i64(t64);
1573 } else {
1574 gen_store_fpr32(t, reg | 1);
1575 }
aa0bf00b 1576}
6ea83fed 1577
d73ee8a2 1578static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1579{
f364515c 1580 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1581 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1582 } else {
d73ee8a2 1583 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1584 }
1585}
6ea83fed 1586
d73ee8a2 1587static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1588{
f364515c 1589 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1590 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1591 } else {
d73ee8a2
RH
1592 TCGv_i64 t0;
1593 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1594 t0 = tcg_temp_new_i64();
6d066274 1595 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1596 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1597 tcg_temp_free_i64(t0);
aa0bf00b
TS
1598 }
1599}
6ea83fed 1600
d94536f4 1601static inline int get_fp_bit (int cc)
a16336e4 1602{
d94536f4
AJ
1603 if (cc)
1604 return 24 + cc;
1605 else
1606 return 23;
a16336e4
TS
1607}
1608
30898801 1609/* Tests */
8e9ade68
TS
1610static inline void gen_save_pc(target_ulong pc)
1611{
1eb75d4a 1612 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1613}
30898801 1614
356265ae 1615static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1616{
d12d51d5 1617 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1618 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1619 gen_save_pc(ctx->pc);
6af0bf9c
FB
1620 ctx->saved_pc = ctx->pc;
1621 }
1622 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1623 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1624 ctx->saved_hflags = ctx->hflags;
364d4831 1625 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1626 case MIPS_HFLAG_BR:
5a5012ec
TS
1627 break;
1628 case MIPS_HFLAG_BC:
5a5012ec 1629 case MIPS_HFLAG_BL:
5a5012ec 1630 case MIPS_HFLAG_B:
d077b6f7 1631 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1632 break;
6af0bf9c
FB
1633 }
1634 }
1635}
1636
7db13fae 1637static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1638{
fd4a04eb 1639 ctx->saved_hflags = ctx->hflags;
364d4831 1640 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1641 case MIPS_HFLAG_BR:
fd4a04eb
TS
1642 break;
1643 case MIPS_HFLAG_BC:
1644 case MIPS_HFLAG_BL:
39454628 1645 case MIPS_HFLAG_B:
fd4a04eb 1646 ctx->btarget = env->btarget;
fd4a04eb 1647 break;
5a5012ec
TS
1648 }
1649}
1650
356265ae 1651static inline void
48d38ca5 1652generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1653{
a7812ae4
PB
1654 TCGv_i32 texcp = tcg_const_i32(excp);
1655 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1656 save_cpu_state(ctx, 1);
895c2d04 1657 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1658 tcg_temp_free_i32(terr);
1659 tcg_temp_free_i32(texcp);
aaa9128a
TS
1660}
1661
356265ae 1662static inline void
48d38ca5 1663generate_exception (DisasContext *ctx, int excp)
aaa9128a 1664{
6af0bf9c 1665 save_cpu_state(ctx, 1);
895c2d04 1666 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1667}
1668
48d38ca5 1669/* Addresses computation */
941694d0 1670static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1671{
941694d0 1672 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1673
1674#if defined(TARGET_MIPS64)
01f72885 1675 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1676 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1677 }
1678#endif
4ad40f36
FB
1679}
1680
31837be3
YK
1681/* Addresses computation (translation time) */
1682static target_long addr_add(DisasContext *ctx, target_long base,
1683 target_long offset)
1684{
1685 target_long sum = base + offset;
1686
1687#if defined(TARGET_MIPS64)
1688 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1689 sum = (int32_t)sum;
1690 }
1691#endif
1692 return sum;
1693}
1694
356265ae 1695static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1696{
fe253235 1697 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1698 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1699}
1700
356265ae 1701static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1702{
fe253235 1703 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1704 generate_exception_err(ctx, EXCP_CpU, 1);
1705}
1706
b8aa4598
TS
1707/* Verify that the processor is running with COP1X instructions enabled.
1708 This is associated with the nabla symbol in the MIPS32 and MIPS64
1709 opcode tables. */
1710
356265ae 1711static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1712{
1713 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1714 generate_exception(ctx, EXCP_RI);
1715}
1716
1717/* Verify that the processor is running with 64-bit floating-point
1718 operations enabled. */
1719
356265ae 1720static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1721{
b8aa4598 1722 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1723 generate_exception(ctx, EXCP_RI);
1724}
1725
1726/*
1727 * Verify if floating point register is valid; an operation is not defined
1728 * if bit 0 of any register specification is set and the FR bit in the
1729 * Status register equals zero, since the register numbers specify an
1730 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1731 * in the Status register equals one, both even and odd register numbers
1732 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1733 *
1734 * Multiple 64 bit wide registers can be checked by calling
1735 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1736 */
356265ae 1737static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1738{
fe253235 1739 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1740 generate_exception(ctx, EXCP_RI);
1741}
1742
853c3240
JL
1743/* Verify that the processor is running with DSP instructions enabled.
1744 This is enabled by CP0 Status register MX(24) bit.
1745 */
1746
1747static inline void check_dsp(DisasContext *ctx)
1748{
1749 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1750 if (ctx->insn_flags & ASE_DSP) {
1751 generate_exception(ctx, EXCP_DSPDIS);
1752 } else {
1753 generate_exception(ctx, EXCP_RI);
1754 }
853c3240
JL
1755 }
1756}
1757
1758static inline void check_dspr2(DisasContext *ctx)
1759{
1760 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1761 if (ctx->insn_flags & ASE_DSP) {
1762 generate_exception(ctx, EXCP_DSPDIS);
1763 } else {
1764 generate_exception(ctx, EXCP_RI);
1765 }
853c3240
JL
1766 }
1767}
1768
3a95e3a7 1769/* This code generates a "reserved instruction" exception if the
e189e748 1770 CPU does not support the instruction set corresponding to flags. */
d75c135e 1771static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1772{
d75c135e 1773 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1774 generate_exception(ctx, EXCP_RI);
d75c135e 1775 }
3a95e3a7
TS
1776}
1777
fecd2646
LA
1778/* This code generates a "reserved instruction" exception if the
1779 CPU has corresponding flag set which indicates that the instruction
1780 has been removed. */
1781static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1782{
1783 if (unlikely(ctx->insn_flags & flags)) {
1784 generate_exception(ctx, EXCP_RI);
1785 }
1786}
1787
c7986fd6 1788#ifdef TARGET_MIPS64
e189e748
TS
1789/* This code generates a "reserved instruction" exception if 64-bit
1790 instructions are not enabled. */
356265ae 1791static inline void check_mips_64(DisasContext *ctx)
e189e748 1792{
fe253235 1793 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1794 generate_exception(ctx, EXCP_RI);
1795}
c7986fd6 1796#endif
e189e748 1797
8153667c
NF
1798/* Define small wrappers for gen_load_fpr* so that we have a uniform
1799 calling interface for 32 and 64-bit FPRs. No sense in changing
1800 all callers for gen_load_fpr32 when we need the CTX parameter for
1801 this one use. */
1802#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1803#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1804#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1805static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1806 int ft, int fs, int cc) \
1807{ \
1808 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1809 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1810 switch (ifmt) { \
1811 case FMT_PS: \
1812 check_cp1_64bitmode(ctx); \
1813 break; \
1814 case FMT_D: \
1815 if (abs) { \
1816 check_cop1x(ctx); \
1817 } \
1818 check_cp1_registers(ctx, fs | ft); \
1819 break; \
1820 case FMT_S: \
1821 if (abs) { \
1822 check_cop1x(ctx); \
1823 } \
1824 break; \
1825 } \
1826 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1827 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1828 switch (n) { \
895c2d04
BS
1829 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1830 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1831 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1832 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1833 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1834 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1835 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1836 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1837 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1838 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1839 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1840 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1841 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1842 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1843 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1844 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1845 default: abort(); \
1846 } \
1847 tcg_temp_free_i##bits (fp0); \
1848 tcg_temp_free_i##bits (fp1); \
1849}
1850
1851FOP_CONDS(, 0, d, FMT_D, 64)
1852FOP_CONDS(abs, 1, d, FMT_D, 64)
1853FOP_CONDS(, 0, s, FMT_S, 32)
1854FOP_CONDS(abs, 1, s, FMT_S, 32)
1855FOP_CONDS(, 0, ps, FMT_PS, 64)
1856FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1857#undef FOP_CONDS
3f493883
YK
1858
1859#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1860static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1861 int ft, int fs, int fd) \
1862{ \
1863 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1864 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1865 switch (ifmt) { \
1866 case FMT_D: \
1867 check_cp1_registers(ctx, fs | ft | fd); \
1868 break; \
1869 } \
1870 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1871 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1872 switch (n) { \
1873 case 0: \
1874 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1875 break; \
1876 case 1: \
1877 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1878 break; \
1879 case 2: \
1880 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1881 break; \
1882 case 3: \
1883 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1884 break; \
1885 case 4: \
1886 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1887 break; \
1888 case 5: \
1889 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1890 break; \
1891 case 6: \
1892 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1893 break; \
1894 case 7: \
1895 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1896 break; \
1897 case 8: \
1898 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 9: \
1901 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 10: \
1904 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 11: \
1907 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 12: \
1910 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 13: \
1913 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 14: \
1916 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 15: \
1919 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 17: \
1922 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 18: \
1925 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 19: \
1928 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 25: \
1931 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 26: \
1934 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 27: \
1937 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 default: \
1940 abort(); \
1941 } \
1942 STORE; \
1943 tcg_temp_free_i ## bits (fp0); \
1944 tcg_temp_free_i ## bits (fp1); \
1945}
1946
1947FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1948FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1949#undef FOP_CONDNS
8153667c
NF
1950#undef gen_ldcmp_fpr32
1951#undef gen_ldcmp_fpr64
1952
958fb4a9 1953/* load/store instructions. */
e7139c44 1954#ifdef CONFIG_USER_ONLY
d9bea114 1955#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1956static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1957{ \
1958 TCGv t0 = tcg_temp_new(); \
1959 tcg_gen_mov_tl(t0, arg1); \
1960 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1961 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1962 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1963 tcg_temp_free(t0); \
aaa9128a 1964}
e7139c44
AJ
1965#else
1966#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1967static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1968{ \
895c2d04 1969 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1970}
1971#endif
aaa9128a
TS
1972OP_LD_ATOMIC(ll,ld32s);
1973#if defined(TARGET_MIPS64)
1974OP_LD_ATOMIC(lld,ld64);
1975#endif
1976#undef OP_LD_ATOMIC
1977
590bc601
PB
1978#ifdef CONFIG_USER_ONLY
1979#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1980static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1981{ \
1982 TCGv t0 = tcg_temp_new(); \
1983 int l1 = gen_new_label(); \
1984 int l2 = gen_new_label(); \
1985 \
1986 tcg_gen_andi_tl(t0, arg2, almask); \
1987 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1988 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1989 generate_exception(ctx, EXCP_AdES); \
1990 gen_set_label(l1); \
7db13fae 1991 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1992 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1993 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1994 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1995 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1996 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1997 gen_set_label(l2); \
1998 tcg_gen_movi_tl(t0, 0); \
1999 gen_store_gpr(t0, rt); \
2000 tcg_temp_free(t0); \
2001}
2002#else
2003#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2004static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2005{ \
2006 TCGv t0 = tcg_temp_new(); \
895c2d04 2007 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2008 gen_store_gpr(t0, rt); \
590bc601
PB
2009 tcg_temp_free(t0); \
2010}
2011#endif
590bc601 2012OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2013#if defined(TARGET_MIPS64)
590bc601 2014OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2015#endif
2016#undef OP_ST_ATOMIC
2017
662d7485
NF
2018static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2019 int base, int16_t offset)
2020{
2021 if (base == 0) {
2022 tcg_gen_movi_tl(addr, offset);
2023 } else if (offset == 0) {
2024 gen_load_gpr(addr, base);
2025 } else {
2026 tcg_gen_movi_tl(addr, offset);
2027 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2028 }
2029}
2030
364d4831
NF
2031static target_ulong pc_relative_pc (DisasContext *ctx)
2032{
2033 target_ulong pc = ctx->pc;
2034
2035 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2036 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2037
2038 pc -= branch_bytes;
2039 }
2040
2041 pc &= ~(target_ulong)3;
2042 return pc;
2043}
2044
5c13fdfd 2045/* Load */
d75c135e
AJ
2046static void gen_ld(DisasContext *ctx, uint32_t opc,
2047 int rt, int base, int16_t offset)
6af0bf9c 2048{
5c13fdfd 2049 const char *opn = "ld";
fc40787a 2050 TCGv t0, t1, t2;
afa88c3a 2051
d75c135e 2052 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2053 /* Loongson CPU uses a load to zero register for prefetch.
2054 We emulate it as a NOP. On other CPU we must perform the
2055 actual memory access. */
2056 MIPS_DEBUG("NOP");
2057 return;
2058 }
6af0bf9c 2059
afa88c3a 2060 t0 = tcg_temp_new();
662d7485 2061 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2062
6af0bf9c 2063 switch (opc) {
d26bc211 2064#if defined(TARGET_MIPS64)
6e473128 2065 case OPC_LWU:
5f68f5ae 2066 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 2067 gen_store_gpr(t0, rt);
6e473128
TS
2068 opn = "lwu";
2069 break;
6af0bf9c 2070 case OPC_LD:
5f68f5ae 2071 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 2072 gen_store_gpr(t0, rt);
6af0bf9c
FB
2073 opn = "ld";
2074 break;
7a387fff 2075 case OPC_LLD:
bf7910c6 2076 case R6_OPC_LLD:
b835e919 2077 save_cpu_state(ctx, 1);
5c13fdfd 2078 op_ld_lld(t0, t0, ctx);
78723684 2079 gen_store_gpr(t0, rt);
7a387fff
TS
2080 opn = "lld";
2081 break;
6af0bf9c 2082 case OPC_LDL:
3cee3050 2083 t1 = tcg_temp_new();
fc40787a
AJ
2084 tcg_gen_andi_tl(t1, t0, 7);
2085#ifndef TARGET_WORDS_BIGENDIAN
2086 tcg_gen_xori_tl(t1, t1, 7);
2087#endif
2088 tcg_gen_shli_tl(t1, t1, 3);
2089 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2090 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2091 tcg_gen_shl_tl(t0, t0, t1);
2092 tcg_gen_xori_tl(t1, t1, 63);
2093 t2 = tcg_const_tl(0x7fffffffffffffffull);
2094 tcg_gen_shr_tl(t2, t2, t1);
78723684 2095 gen_load_gpr(t1, rt);
fc40787a
AJ
2096 tcg_gen_and_tl(t1, t1, t2);
2097 tcg_temp_free(t2);
2098 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2099 tcg_temp_free(t1);
fc40787a 2100 gen_store_gpr(t0, rt);
6af0bf9c
FB
2101 opn = "ldl";
2102 break;
6af0bf9c 2103 case OPC_LDR:
3cee3050 2104 t1 = tcg_temp_new();
fc40787a
AJ
2105 tcg_gen_andi_tl(t1, t0, 7);
2106#ifdef TARGET_WORDS_BIGENDIAN
2107 tcg_gen_xori_tl(t1, t1, 7);
2108#endif
2109 tcg_gen_shli_tl(t1, t1, 3);
2110 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2111 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2112 tcg_gen_shr_tl(t0, t0, t1);
2113 tcg_gen_xori_tl(t1, t1, 63);
2114 t2 = tcg_const_tl(0xfffffffffffffffeull);
2115 tcg_gen_shl_tl(t2, t2, t1);
78723684 2116 gen_load_gpr(t1, rt);
fc40787a
AJ
2117 tcg_gen_and_tl(t1, t1, t2);
2118 tcg_temp_free(t2);
2119 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2120 tcg_temp_free(t1);
fc40787a 2121 gen_store_gpr(t0, rt);
6af0bf9c
FB
2122 opn = "ldr";
2123 break;
364d4831 2124 case OPC_LDPC:
3cee3050 2125 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2126 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2127 tcg_temp_free(t1);
5f68f5ae 2128 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2129 gen_store_gpr(t0, rt);
5c13fdfd 2130 opn = "ldpc";
364d4831 2131 break;
6af0bf9c 2132#endif
364d4831 2133 case OPC_LWPC:
3cee3050 2134 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2135 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2136 tcg_temp_free(t1);
5f68f5ae 2137 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2138 gen_store_gpr(t0, rt);
5c13fdfd 2139 opn = "lwpc";
364d4831 2140 break;
6af0bf9c 2141 case OPC_LW:
5f68f5ae 2142 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 2143 gen_store_gpr(t0, rt);
6af0bf9c
FB
2144 opn = "lw";
2145 break;
6af0bf9c 2146 case OPC_LH:
5f68f5ae 2147 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 2148 gen_store_gpr(t0, rt);
6af0bf9c
FB
2149 opn = "lh";
2150 break;
6af0bf9c 2151 case OPC_LHU:
5f68f5ae 2152 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 2153 gen_store_gpr(t0, rt);
6af0bf9c
FB
2154 opn = "lhu";
2155 break;
2156 case OPC_LB:
5f68f5ae 2157 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2158 gen_store_gpr(t0, rt);
6af0bf9c
FB
2159 opn = "lb";
2160 break;
6af0bf9c 2161 case OPC_LBU:
5f68f5ae 2162 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2163 gen_store_gpr(t0, rt);
6af0bf9c
FB
2164 opn = "lbu";
2165 break;
2166 case OPC_LWL:
3cee3050 2167 t1 = tcg_temp_new();
fc40787a
AJ
2168 tcg_gen_andi_tl(t1, t0, 3);
2169#ifndef TARGET_WORDS_BIGENDIAN
2170 tcg_gen_xori_tl(t1, t1, 3);
2171#endif
2172 tcg_gen_shli_tl(t1, t1, 3);
2173 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2175 tcg_gen_shl_tl(t0, t0, t1);
2176 tcg_gen_xori_tl(t1, t1, 31);
2177 t2 = tcg_const_tl(0x7fffffffull);
2178 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2179 gen_load_gpr(t1, rt);
fc40787a
AJ
2180 tcg_gen_and_tl(t1, t1, t2);
2181 tcg_temp_free(t2);
2182 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2183 tcg_temp_free(t1);
fc40787a
AJ
2184 tcg_gen_ext32s_tl(t0, t0);
2185 gen_store_gpr(t0, rt);
6af0bf9c
FB
2186 opn = "lwl";
2187 break;
6af0bf9c 2188 case OPC_LWR:
3cee3050 2189 t1 = tcg_temp_new();
fc40787a
AJ
2190 tcg_gen_andi_tl(t1, t0, 3);
2191#ifdef TARGET_WORDS_BIGENDIAN
2192 tcg_gen_xori_tl(t1, t1, 3);
2193#endif
2194 tcg_gen_shli_tl(t1, t1, 3);
2195 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2196 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2197 tcg_gen_shr_tl(t0, t0, t1);
2198 tcg_gen_xori_tl(t1, t1, 31);
2199 t2 = tcg_const_tl(0xfffffffeull);
2200 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2201 gen_load_gpr(t1, rt);
fc40787a
AJ
2202 tcg_gen_and_tl(t1, t1, t2);
2203 tcg_temp_free(t2);
2204 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2205 tcg_temp_free(t1);
c728154b 2206 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2207 gen_store_gpr(t0, rt);
6af0bf9c
FB
2208 opn = "lwr";
2209 break;
6af0bf9c 2210 case OPC_LL:
4368b29a 2211 case R6_OPC_LL:
e7139c44 2212 save_cpu_state(ctx, 1);
5c13fdfd 2213 op_ld_ll(t0, t0, ctx);
78723684 2214 gen_store_gpr(t0, rt);
6af0bf9c
FB
2215 opn = "ll";
2216 break;
d66c7132 2217 }
2abf314d 2218 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2219 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2220 tcg_temp_free(t0);
d66c7132
AJ
2221}
2222
5c13fdfd
AJ
2223/* Store */
2224static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2225 int base, int16_t offset)
2226{
2227 const char *opn = "st";
2228 TCGv t0 = tcg_temp_new();
2229 TCGv t1 = tcg_temp_new();
2230
2231 gen_base_offset_addr(ctx, t0, base, offset);
2232 gen_load_gpr(t1, rt);
2233 switch (opc) {
2234#if defined(TARGET_MIPS64)
2235 case OPC_SD:
5f68f5ae 2236 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
2237 opn = "sd";
2238 break;
2239 case OPC_SDL:
2240 save_cpu_state(ctx, 1);
895c2d04 2241 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2242 opn = "sdl";
2243 break;
2244 case OPC_SDR:
2245 save_cpu_state(ctx, 1);
895c2d04 2246 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2247 opn = "sdr";
2248 break;
2249#endif
2250 case OPC_SW:
5f68f5ae 2251 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2252 opn = "sw";
2253 break;
2254 case OPC_SH:
5f68f5ae 2255 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2256 opn = "sh";
2257 break;
2258 case OPC_SB:
5f68f5ae 2259 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2260 opn = "sb";
2261 break;
2262 case OPC_SWL:
2263 save_cpu_state(ctx, 1);
895c2d04 2264 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2265 opn = "swl";
2266 break;
2267 case OPC_SWR:
2268 save_cpu_state(ctx, 1);
895c2d04 2269 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2270 opn = "swr";
2271 break;
2272 }
2abf314d 2273 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2274 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2275 tcg_temp_free(t0);
2276 tcg_temp_free(t1);
2277}
2278
2279
d66c7132
AJ
2280/* Store conditional */
2281static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2282 int base, int16_t offset)
2283{
2284 const char *opn = "st_cond";
2285 TCGv t0, t1;
2286
2d2826b9 2287#ifdef CONFIG_USER_ONLY
d66c7132 2288 t0 = tcg_temp_local_new();
d66c7132 2289 t1 = tcg_temp_local_new();
2d2826b9
AJ
2290#else
2291 t0 = tcg_temp_new();
2292 t1 = tcg_temp_new();
2293#endif
2294 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2295 gen_load_gpr(t1, rt);
2296 switch (opc) {
2297#if defined(TARGET_MIPS64)
2298 case OPC_SCD:
bf7910c6 2299 case R6_OPC_SCD:
b835e919 2300 save_cpu_state(ctx, 1);
5c13fdfd 2301 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2302 opn = "scd";
2303 break;
2304#endif
6af0bf9c 2305 case OPC_SC:
4368b29a 2306 case R6_OPC_SC:
e7139c44 2307 save_cpu_state(ctx, 1);
5c13fdfd 2308 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2309 opn = "sc";
2310 break;
6af0bf9c 2311 }
2abf314d 2312 (void)opn; /* avoid a compiler warning */
6af0bf9c 2313 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2314 tcg_temp_free(t1);
d66c7132 2315 tcg_temp_free(t0);
6af0bf9c
FB
2316}
2317
6ea83fed 2318/* Load and store */
7a387fff 2319static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2320 int base, int16_t offset)
6ea83fed 2321{
923617a3 2322 const char *opn = "flt_ldst";
4e2474d6 2323 TCGv t0 = tcg_temp_new();
6ea83fed 2324
662d7485 2325 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2326 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2327 memory access. */
6ea83fed
FB
2328 switch (opc) {
2329 case OPC_LWC1:
b6d96bed 2330 {
a7812ae4 2331 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2332 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2333 gen_store_fpr32(fp0, ft);
a7812ae4 2334 tcg_temp_free_i32(fp0);
b6d96bed 2335 }
6ea83fed
FB
2336 opn = "lwc1";
2337 break;
2338 case OPC_SWC1:
b6d96bed 2339 {
a7812ae4 2340 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2341 gen_load_fpr32(fp0, ft);
5f68f5ae 2342 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2343 tcg_temp_free_i32(fp0);
b6d96bed 2344 }
6ea83fed
FB
2345 opn = "swc1";
2346 break;
2347 case OPC_LDC1:
b6d96bed 2348 {
a7812ae4 2349 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2350 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2351 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2352 tcg_temp_free_i64(fp0);
b6d96bed 2353 }
6ea83fed
FB
2354 opn = "ldc1";
2355 break;
2356 case OPC_SDC1:
b6d96bed 2357 {
a7812ae4 2358 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2359 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2360 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2361 tcg_temp_free_i64(fp0);
b6d96bed 2362 }
6ea83fed
FB
2363 opn = "sdc1";
2364 break;
2365 default:
923617a3 2366 MIPS_INVAL(opn);
e397ee33 2367 generate_exception(ctx, EXCP_RI);
78723684 2368 goto out;
6ea83fed 2369 }
2abf314d 2370 (void)opn; /* avoid a compiler warning */
6ea83fed 2371 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2372 out:
2373 tcg_temp_free(t0);
6ea83fed 2374}
6ea83fed 2375
5ab5c041
AJ
2376static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2377 int rs, int16_t imm)
26ebe468 2378{
5ab5c041 2379 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
2380 check_cp1_enabled(ctx);
2381 gen_flt_ldst(ctx, op, rt, rs, imm);
2382 } else {
2383 generate_exception_err(ctx, EXCP_CpU, 1);
2384 }
2385}
2386
6af0bf9c 2387/* Arithmetic with immediate operand */
d75c135e
AJ
2388static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2389 int rt, int rs, int16_t imm)
6af0bf9c 2390{
324d9e32 2391 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2392 const char *opn = "imm arith";
6af0bf9c 2393
7a387fff 2394 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2395 /* If no destination, treat it as a NOP.
2396 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2397 MIPS_DEBUG("NOP");
324d9e32 2398 return;
6af0bf9c
FB
2399 }
2400 switch (opc) {
2401 case OPC_ADDI:
48d38ca5 2402 {
324d9e32
AJ
2403 TCGv t0 = tcg_temp_local_new();
2404 TCGv t1 = tcg_temp_new();
2405 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2406 int l1 = gen_new_label();
2407
324d9e32
AJ
2408 gen_load_gpr(t1, rs);
2409 tcg_gen_addi_tl(t0, t1, uimm);
2410 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2411
324d9e32
AJ
2412 tcg_gen_xori_tl(t1, t1, ~uimm);
2413 tcg_gen_xori_tl(t2, t0, uimm);
2414 tcg_gen_and_tl(t1, t1, t2);
2415 tcg_temp_free(t2);
2416 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2417 tcg_temp_free(t1);
48d38ca5
TS
2418 /* operands of same sign, result different sign */
2419 generate_exception(ctx, EXCP_OVERFLOW);
2420 gen_set_label(l1);
78723684 2421 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2422 gen_store_gpr(t0, rt);
2423 tcg_temp_free(t0);
48d38ca5 2424 }
6af0bf9c
FB
2425 opn = "addi";
2426 break;
2427 case OPC_ADDIU:
324d9e32
AJ
2428 if (rs != 0) {
2429 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2430 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2431 } else {
2432 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2433 }
6af0bf9c
FB
2434 opn = "addiu";
2435 break;
d26bc211 2436#if defined(TARGET_MIPS64)
7a387fff 2437 case OPC_DADDI:
48d38ca5 2438 {
324d9e32
AJ
2439 TCGv t0 = tcg_temp_local_new();
2440 TCGv t1 = tcg_temp_new();
2441 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2442 int l1 = gen_new_label();
2443
324d9e32
AJ
2444 gen_load_gpr(t1, rs);
2445 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2446
324d9e32
AJ
2447 tcg_gen_xori_tl(t1, t1, ~uimm);
2448 tcg_gen_xori_tl(t2, t0, uimm);
2449 tcg_gen_and_tl(t1, t1, t2);
2450 tcg_temp_free(t2);
2451 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2452 tcg_temp_free(t1);
48d38ca5
TS
2453 /* operands of same sign, result different sign */
2454 generate_exception(ctx, EXCP_OVERFLOW);
2455 gen_set_label(l1);
324d9e32
AJ
2456 gen_store_gpr(t0, rt);
2457 tcg_temp_free(t0);
48d38ca5 2458 }
7a387fff
TS
2459 opn = "daddi";
2460 break;
2461 case OPC_DADDIU:
324d9e32
AJ
2462 if (rs != 0) {
2463 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2464 } else {
2465 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2466 }
7a387fff
TS
2467 opn = "daddiu";
2468 break;
2469#endif
324d9e32 2470 }
2abf314d 2471 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2472 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2473}
2474
2475/* Logic with immediate operand */
d75c135e 2476static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2477 int rt, int rs, int16_t imm)
324d9e32
AJ
2478{
2479 target_ulong uimm;
324d9e32
AJ
2480
2481 if (rt == 0) {
2482 /* If no destination, treat it as a NOP. */
2483 MIPS_DEBUG("NOP");
2484 return;
2485 }
2486 uimm = (uint16_t)imm;
2487 switch (opc) {
6af0bf9c 2488 case OPC_ANDI:
324d9e32
AJ
2489 if (likely(rs != 0))
2490 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2491 else
2492 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2493 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2494 regnames[rs], uimm);
6af0bf9c
FB
2495 break;
2496 case OPC_ORI:
324d9e32
AJ
2497 if (rs != 0)
2498 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2499 else
2500 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2501 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2502 regnames[rs], uimm);
6af0bf9c
FB
2503 break;
2504 case OPC_XORI:
324d9e32
AJ
2505 if (likely(rs != 0))
2506 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2507 else
2508 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2509 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2510 regnames[rs], uimm);
6af0bf9c
FB
2511 break;
2512 case OPC_LUI:
d4ea6acd
LA
2513 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2514 /* OPC_AUI */
2515 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2516 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2517 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2518 } else {
2519 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2520 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2521 }
7c2c3ea3
EJ
2522 break;
2523
2524 default:
2525 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2526 break;
324d9e32 2527 }
324d9e32
AJ
2528}
2529
2530/* Set on less than with immediate operand */
d75c135e 2531static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2532 int rt, int rs, int16_t imm)
324d9e32
AJ
2533{
2534 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2535 const char *opn = "imm arith";
2536 TCGv t0;
2537
2538 if (rt == 0) {
2539 /* If no destination, treat it as a NOP. */
2540 MIPS_DEBUG("NOP");
2541 return;
2542 }
2543 t0 = tcg_temp_new();
2544 gen_load_gpr(t0, rs);
2545 switch (opc) {
2546 case OPC_SLTI:
e68dd28f 2547 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2548 opn = "slti";
2549 break;
2550 case OPC_SLTIU:
e68dd28f 2551 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2552 opn = "sltiu";
2553 break;
2554 }
2abf314d 2555 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2556 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2557 tcg_temp_free(t0);
2558}
2559
2560/* Shifts with immediate operand */
d75c135e 2561static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2562 int rt, int rs, int16_t imm)
2563{
2564 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2565 const char *opn = "imm shift";
2566 TCGv t0;
2567
2568 if (rt == 0) {
2569 /* If no destination, treat it as a NOP. */
2570 MIPS_DEBUG("NOP");
2571 return;
2572 }
2573
2574 t0 = tcg_temp_new();
2575 gen_load_gpr(t0, rs);
2576 switch (opc) {
6af0bf9c 2577 case OPC_SLL:
78723684 2578 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2579 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2580 opn = "sll";
2581 break;
2582 case OPC_SRA:
324d9e32 2583 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2584 opn = "sra";
2585 break;
2586 case OPC_SRL:
ea63e2c3
NF
2587 if (uimm != 0) {
2588 tcg_gen_ext32u_tl(t0, t0);
2589 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2590 } else {
2591 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2592 }
ea63e2c3
NF
2593 opn = "srl";
2594 break;
2595 case OPC_ROTR:
2596 if (uimm != 0) {
2597 TCGv_i32 t1 = tcg_temp_new_i32();
2598
2599 tcg_gen_trunc_tl_i32(t1, t0);
2600 tcg_gen_rotri_i32(t1, t1, uimm);
2601 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2602 tcg_temp_free_i32(t1);
3399e30f
NF
2603 } else {
2604 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2605 }
2606 opn = "rotr";
7a387fff 2607 break;
d26bc211 2608#if defined(TARGET_MIPS64)
7a387fff 2609 case OPC_DSLL:
324d9e32 2610 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2611 opn = "dsll";
2612 break;
2613 case OPC_DSRA:
324d9e32 2614 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2615 opn = "dsra";
2616 break;
2617 case OPC_DSRL:
ea63e2c3
NF
2618 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2619 opn = "dsrl";
2620 break;
2621 case OPC_DROTR:
2622 if (uimm != 0) {
2623 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2624 } else {
2625 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2626 }
ea63e2c3 2627 opn = "drotr";
7a387fff
TS
2628 break;
2629 case OPC_DSLL32:
324d9e32 2630 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2631 opn = "dsll32";
2632 break;
2633 case OPC_DSRA32:
324d9e32 2634 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2635 opn = "dsra32";
2636 break;
2637 case OPC_DSRL32:
ea63e2c3
NF
2638 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2639 opn = "dsrl32";
2640 break;
2641 case OPC_DROTR32:
2642 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2643 opn = "drotr32";
6af0bf9c 2644 break;
7a387fff 2645#endif
6af0bf9c 2646 }
2abf314d 2647 (void)opn; /* avoid a compiler warning */
93b12ccc 2648 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2649 tcg_temp_free(t0);
6af0bf9c
FB
2650}
2651
2652/* Arithmetic */
d75c135e
AJ
2653static void gen_arith(DisasContext *ctx, uint32_t opc,
2654 int rd, int rs, int rt)
6af0bf9c 2655{
923617a3 2656 const char *opn = "arith";
6af0bf9c 2657
7a387fff
TS
2658 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2659 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2660 /* If no destination, treat it as a NOP.
2661 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2662 MIPS_DEBUG("NOP");
460f00c4 2663 return;
185f0762 2664 }
460f00c4 2665
6af0bf9c
FB
2666 switch (opc) {
2667 case OPC_ADD:
48d38ca5 2668 {
460f00c4
AJ
2669 TCGv t0 = tcg_temp_local_new();
2670 TCGv t1 = tcg_temp_new();
2671 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2672 int l1 = gen_new_label();
2673
460f00c4
AJ
2674 gen_load_gpr(t1, rs);
2675 gen_load_gpr(t2, rt);
2676 tcg_gen_add_tl(t0, t1, t2);
2677 tcg_gen_ext32s_tl(t0, t0);
2678 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2679 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2680 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2681 tcg_temp_free(t2);
2682 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2683 tcg_temp_free(t1);
48d38ca5
TS
2684 /* operands of same sign, result different sign */
2685 generate_exception(ctx, EXCP_OVERFLOW);
2686 gen_set_label(l1);
460f00c4
AJ
2687 gen_store_gpr(t0, rd);
2688 tcg_temp_free(t0);
48d38ca5 2689 }
6af0bf9c
FB
2690 opn = "add";
2691 break;
2692 case OPC_ADDU:
460f00c4
AJ
2693 if (rs != 0 && rt != 0) {
2694 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2695 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2696 } else if (rs == 0 && rt != 0) {
2697 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2698 } else if (rs != 0 && rt == 0) {
2699 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2700 } else {
2701 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2702 }
6af0bf9c
FB
2703 opn = "addu";
2704 break;
2705 case OPC_SUB:
48d38ca5 2706 {
460f00c4
AJ
2707 TCGv t0 = tcg_temp_local_new();
2708 TCGv t1 = tcg_temp_new();
2709 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2710 int l1 = gen_new_label();
2711
460f00c4
AJ
2712 gen_load_gpr(t1, rs);
2713 gen_load_gpr(t2, rt);
2714 tcg_gen_sub_tl(t0, t1, t2);
2715 tcg_gen_ext32s_tl(t0, t0);
2716 tcg_gen_xor_tl(t2, t1, t2);
2717 tcg_gen_xor_tl(t1, t0, t1);
2718 tcg_gen_and_tl(t1, t1, t2);
2719 tcg_temp_free(t2);
2720 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2721 tcg_temp_free(t1);
31e3104f 2722 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2723 generate_exception(ctx, EXCP_OVERFLOW);
2724 gen_set_label(l1);
460f00c4
AJ
2725 gen_store_gpr(t0, rd);
2726 tcg_temp_free(t0);
48d38ca5 2727 }
6af0bf9c
FB
2728 opn = "sub";
2729 break;
2730 case OPC_SUBU:
460f00c4
AJ
2731 if (rs != 0 && rt != 0) {
2732 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2733 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2734 } else if (rs == 0 && rt != 0) {
2735 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2736 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2737 } else if (rs != 0 && rt == 0) {
2738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2739 } else {
2740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2741 }
6af0bf9c
FB
2742 opn = "subu";
2743 break;
d26bc211 2744#if defined(TARGET_MIPS64)
7a387fff 2745 case OPC_DADD:
48d38ca5 2746 {
460f00c4
AJ
2747 TCGv t0 = tcg_temp_local_new();
2748 TCGv t1 = tcg_temp_new();
2749 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2750 int l1 = gen_new_label();
2751
460f00c4
AJ
2752 gen_load_gpr(t1, rs);
2753 gen_load_gpr(t2, rt);
2754 tcg_gen_add_tl(t0, t1, t2);
2755 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2756 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2757 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2758 tcg_temp_free(t2);
2759 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2760 tcg_temp_free(t1);
48d38ca5
TS
2761 /* operands of same sign, result different sign */
2762 generate_exception(ctx, EXCP_OVERFLOW);
2763 gen_set_label(l1);
460f00c4
AJ
2764 gen_store_gpr(t0, rd);
2765 tcg_temp_free(t0);
48d38ca5 2766 }
7a387fff
TS
2767 opn = "dadd";
2768 break;
2769 case OPC_DADDU:
460f00c4
AJ
2770 if (rs != 0 && rt != 0) {
2771 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2772 } else if (rs == 0 && rt != 0) {
2773 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2774 } else if (rs != 0 && rt == 0) {
2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2776 } else {
2777 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2778 }
7a387fff
TS
2779 opn = "daddu";
2780 break;
2781 case OPC_DSUB:
48d38ca5 2782 {
460f00c4
AJ
2783 TCGv t0 = tcg_temp_local_new();
2784 TCGv t1 = tcg_temp_new();
2785 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2786 int l1 = gen_new_label();
2787
460f00c4
AJ
2788 gen_load_gpr(t1, rs);
2789 gen_load_gpr(t2, rt);
2790 tcg_gen_sub_tl(t0, t1, t2);
2791 tcg_gen_xor_tl(t2, t1, t2);
2792 tcg_gen_xor_tl(t1, t0, t1);
2793 tcg_gen_and_tl(t1, t1, t2);
2794 tcg_temp_free(t2);
2795 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2796 tcg_temp_free(t1);
31e3104f 2797 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2798 generate_exception(ctx, EXCP_OVERFLOW);
2799 gen_set_label(l1);
460f00c4
AJ
2800 gen_store_gpr(t0, rd);
2801 tcg_temp_free(t0);
48d38ca5 2802 }
7a387fff
TS
2803 opn = "dsub";
2804 break;
2805 case OPC_DSUBU:
460f00c4
AJ
2806 if (rs != 0 && rt != 0) {
2807 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2808 } else if (rs == 0 && rt != 0) {
2809 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2810 } else if (rs != 0 && rt == 0) {
2811 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2812 } else {
2813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2814 }
7a387fff
TS
2815 opn = "dsubu";
2816 break;
2817#endif
460f00c4
AJ
2818 case OPC_MUL:
2819 if (likely(rs != 0 && rt != 0)) {
2820 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2821 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2822 } else {
2823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2824 }
2825 opn = "mul";
6af0bf9c 2826 break;
460f00c4 2827 }
2abf314d 2828 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2829 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2830}
2831
2832/* Conditional move */
d75c135e 2833static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2834 int rd, int rs, int rt)
460f00c4
AJ
2835{
2836 const char *opn = "cond move";
acf12465 2837 TCGv t0, t1, t2;
460f00c4
AJ
2838
2839 if (rd == 0) {
acf12465 2840 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2841 MIPS_DEBUG("NOP");
2842 return;
2843 }
2844
acf12465
AJ
2845 t0 = tcg_temp_new();
2846 gen_load_gpr(t0, rt);
2847 t1 = tcg_const_tl(0);
2848 t2 = tcg_temp_new();
2849 gen_load_gpr(t2, rs);
460f00c4
AJ
2850 switch (opc) {
2851 case OPC_MOVN:
acf12465 2852 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2853 opn = "movn";
6af0bf9c 2854 break;
460f00c4 2855 case OPC_MOVZ:
acf12465 2856 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2857 opn = "movz";
2858 break;
b691d9d2
LA
2859 case OPC_SELNEZ:
2860 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2861 opn = "selnez";
2862 break;
2863 case OPC_SELEQZ:
2864 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2865 opn = "seleqz";
2866 break;
460f00c4 2867 }
acf12465
AJ
2868 tcg_temp_free(t2);
2869 tcg_temp_free(t1);
2870 tcg_temp_free(t0);
460f00c4 2871
2abf314d 2872 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2873 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2874}
2875
2876/* Logic */
d75c135e 2877static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2878 int rd, int rs, int rt)
460f00c4
AJ
2879{
2880 const char *opn = "logic";
2881
2882 if (rd == 0) {
2883 /* If no destination, treat it as a NOP. */
2884 MIPS_DEBUG("NOP");
2885 return;
2886 }
2887
2888 switch (opc) {
6af0bf9c 2889 case OPC_AND:
460f00c4
AJ
2890 if (likely(rs != 0 && rt != 0)) {
2891 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2892 } else {
2893 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2894 }
6af0bf9c
FB
2895 opn = "and";
2896 break;
2897 case OPC_NOR:
460f00c4
AJ
2898 if (rs != 0 && rt != 0) {
2899 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2900 } else if (rs == 0 && rt != 0) {
2901 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2902 } else if (rs != 0 && rt == 0) {
2903 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2904 } else {
2905 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2906 }
6af0bf9c
FB
2907 opn = "nor";
2908 break;
2909 case OPC_OR:
460f00c4
AJ
2910 if (likely(rs != 0 && rt != 0)) {
2911 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2912 } else if (rs == 0 && rt != 0) {
2913 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2914 } else if (rs != 0 && rt == 0) {
2915 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2916 } else {
2917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2918 }
6af0bf9c
FB
2919 opn = "or";
2920 break;
2921 case OPC_XOR:
460f00c4
AJ
2922 if (likely(rs != 0 && rt != 0)) {
2923 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2924 } else if (rs == 0 && rt != 0) {
2925 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2926 } else if (rs != 0 && rt == 0) {
2927 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2928 } else {
2929 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2930 }
6af0bf9c
FB
2931 opn = "xor";
2932 break;
460f00c4 2933 }
2abf314d 2934 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2935 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2936}
2937
2938/* Set on lower than */
d75c135e 2939static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2940 int rd, int rs, int rt)
460f00c4
AJ
2941{
2942 const char *opn = "slt";
2943 TCGv t0, t1;
2944
2945 if (rd == 0) {
2946 /* If no destination, treat it as a NOP. */
2947 MIPS_DEBUG("NOP");
2948 return;
2949 }
2950
2951 t0 = tcg_temp_new();
2952 t1 = tcg_temp_new();
2953 gen_load_gpr(t0, rs);
2954 gen_load_gpr(t1, rt);
2955 switch (opc) {
2956 case OPC_SLT:
e68dd28f 2957 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2958 opn = "slt";
6af0bf9c 2959 break;
460f00c4 2960 case OPC_SLTU:
e68dd28f 2961 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2962 opn = "sltu";
2963 break;
2964 }
2abf314d 2965 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2966 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2967 tcg_temp_free(t0);
2968 tcg_temp_free(t1);
2969}
20c4c97c 2970
460f00c4 2971/* Shifts */
d75c135e
AJ
2972static void gen_shift(DisasContext *ctx, uint32_t opc,
2973 int rd, int rs, int rt)
460f00c4
AJ
2974{
2975 const char *opn = "shifts";
2976 TCGv t0, t1;
20c4c97c 2977
460f00c4
AJ
2978 if (rd == 0) {
2979 /* If no destination, treat it as a NOP.
2980 For add & sub, we must generate the overflow exception when needed. */
2981 MIPS_DEBUG("NOP");
2982 return;
2983 }
2984
2985 t0 = tcg_temp_new();
2986 t1 = tcg_temp_new();
2987 gen_load_gpr(t0, rs);
2988 gen_load_gpr(t1, rt);
2989 switch (opc) {
6af0bf9c 2990 case OPC_SLLV:
78723684
TS
2991 tcg_gen_andi_tl(t0, t0, 0x1f);
2992 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2993 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2994 opn = "sllv";
2995 break;
2996 case OPC_SRAV:
78723684 2997 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2998 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2999 opn = "srav";
3000 break;
3001 case OPC_SRLV:
ea63e2c3
NF
3002 tcg_gen_ext32u_tl(t1, t1);
3003 tcg_gen_andi_tl(t0, t0, 0x1f);
3004 tcg_gen_shr_tl(t0, t1, t0);
3005 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3006 opn = "srlv";
3007 break;
3008 case OPC_ROTRV:
3009 {
3010 TCGv_i32 t2 = tcg_temp_new_i32();
3011 TCGv_i32 t3 = tcg_temp_new_i32();
3012
3013 tcg_gen_trunc_tl_i32(t2, t0);
3014 tcg_gen_trunc_tl_i32(t3, t1);
3015 tcg_gen_andi_i32(t2, t2, 0x1f);
3016 tcg_gen_rotr_i32(t2, t3, t2);
3017 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3018 tcg_temp_free_i32(t2);
3019 tcg_temp_free_i32(t3);
3020 opn = "rotrv";
5a63bcb2 3021 }
7a387fff 3022 break;
d26bc211 3023#if defined(TARGET_MIPS64)
7a387fff 3024 case OPC_DSLLV:
78723684 3025 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3026 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3027 opn = "dsllv";
3028 break;
3029 case OPC_DSRAV:
78723684 3030 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3031 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3032 opn = "dsrav";
3033 break;
3034 case OPC_DSRLV:
ea63e2c3
NF
3035 tcg_gen_andi_tl(t0, t0, 0x3f);
3036 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3037 opn = "dsrlv";
3038 break;
3039 case OPC_DROTRV:
3040 tcg_gen_andi_tl(t0, t0, 0x3f);
3041 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3042 opn = "drotrv";
6af0bf9c 3043 break;
7a387fff 3044#endif
6af0bf9c 3045 }
2abf314d 3046 (void)opn; /* avoid a compiler warning */
6af0bf9c 3047 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3048 tcg_temp_free(t0);
3049 tcg_temp_free(t1);
6af0bf9c
FB
3050}
3051
3052/* Arithmetic on HI/LO registers */
26135ead 3053static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3054{
923617a3 3055 const char *opn = "hilo";
6af0bf9c
FB
3056
3057 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3058 /* Treat as NOP. */
6af0bf9c 3059 MIPS_DEBUG("NOP");
a1f6684d 3060 return;
6af0bf9c 3061 }
4133498f 3062
4133498f
JL
3063 if (acc != 0) {
3064 check_dsp(ctx);
3065 }
3066
6af0bf9c
FB
3067 switch (opc) {
3068 case OPC_MFHI:
4133498f
JL
3069#if defined(TARGET_MIPS64)
3070 if (acc != 0) {
3071 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3072 } else
3073#endif
3074 {
3075 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3076 }
6af0bf9c
FB
3077 opn = "mfhi";
3078 break;
3079 case OPC_MFLO:
4133498f
JL
3080#if defined(TARGET_MIPS64)
3081 if (acc != 0) {
3082 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3083 } else
3084#endif
3085 {
3086 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3087 }
6af0bf9c
FB
3088 opn = "mflo";
3089 break;
3090 case OPC_MTHI:
4133498f
JL
3091 if (reg != 0) {
3092#if defined(TARGET_MIPS64)
3093 if (acc != 0) {
3094 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3095 } else
3096#endif
3097 {
3098 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3099 }
3100 } else {
3101 tcg_gen_movi_tl(cpu_HI[acc], 0);
3102 }
6af0bf9c
FB
3103 opn = "mthi";
3104 break;
3105 case OPC_MTLO:
4133498f
JL
3106 if (reg != 0) {
3107#if defined(TARGET_MIPS64)
3108 if (acc != 0) {
3109 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3110 } else
3111#endif
3112 {
3113 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3114 }
3115 } else {
3116 tcg_gen_movi_tl(cpu_LO[acc], 0);
3117 }
6af0bf9c
FB
3118 opn = "mtlo";
3119 break;
6af0bf9c 3120 }
2abf314d 3121 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3122 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3123}
3124
d4ea6acd
LA
3125static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3126 TCGMemOp memop)
3127{
3128 TCGv t0 = tcg_const_tl(addr);
3129 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3130 gen_store_gpr(t0, reg);
3131 tcg_temp_free(t0);
3132}
3133
3134static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3135{
3136 target_long offset;
3137 target_long addr;
3138
3139 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3140 case OPC_ADDIUPC:
3141 if (rs != 0) {
3142 offset = sextract32(ctx->opcode << 2, 0, 21);
3143 addr = addr_add(ctx, ctx->pc, offset);
3144 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3145 }
3146 break;
3147 case R6_OPC_LWPC:
3148 offset = sextract32(ctx->opcode << 2, 0, 21);
3149 addr = addr_add(ctx, ctx->pc, offset);
3150 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3151 break;
3152#if defined(TARGET_MIPS64)
3153 case OPC_LWUPC:
3154 check_mips_64(ctx);
3155 offset = sextract32(ctx->opcode << 2, 0, 21);
3156 addr = addr_add(ctx, ctx->pc, offset);
3157 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3158 break;
3159#endif
3160 default:
3161 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3162 case OPC_AUIPC:
3163 if (rs != 0) {
3164 offset = imm << 16;
3165 addr = addr_add(ctx, ctx->pc, offset);
3166 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3167 }
3168 break;
3169 case OPC_ALUIPC:
3170 if (rs != 0) {
3171 offset = imm << 16;
3172 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3173 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3174 }
3175 break;
3176#if defined(TARGET_MIPS64)
3177 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3178 case R6_OPC_LDPC + (1 << 16):
3179 case R6_OPC_LDPC + (2 << 16):
3180 case R6_OPC_LDPC + (3 << 16):
3181 check_mips_64(ctx);
3182 offset = sextract32(ctx->opcode << 3, 0, 21);
3183 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3184 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3185 break;
3186#endif
3187 default:
3188 MIPS_INVAL("OPC_PCREL");
3189 generate_exception(ctx, EXCP_RI);
3190 break;
3191 }
3192 break;
3193 }
3194}
3195
b42ee5e1
LA
3196static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3197{
3198 const char *opn = "r6 mul/div";
3199 TCGv t0, t1;
3200
3201 if (rd == 0) {
3202 /* Treat as NOP. */
3203 MIPS_DEBUG("NOP");
3204 return;
3205 }
3206
3207 t0 = tcg_temp_new();
3208 t1 = tcg_temp_new();
3209
3210 gen_load_gpr(t0, rs);
3211 gen_load_gpr(t1, rt);
3212
3213 switch (opc) {
3214 case R6_OPC_DIV:
3215 {
3216 TCGv t2 = tcg_temp_new();
3217 TCGv t3 = tcg_temp_new();
3218 tcg_gen_ext32s_tl(t0, t0);
3219 tcg_gen_ext32s_tl(t1, t1);
3220 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3221 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3222 tcg_gen_and_tl(t2, t2, t3);
3223 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3224 tcg_gen_or_tl(t2, t2, t3);
3225 tcg_gen_movi_tl(t3, 0);
3226 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3227 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3228 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3229 tcg_temp_free(t3);
3230 tcg_temp_free(t2);
3231 }
3232 opn = "div";
3233 break;
3234 case R6_OPC_MOD:
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_rem_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 = "mod";
3253 break;
3254 case R6_OPC_DIVU:
3255 {
3256 TCGv t2 = tcg_const_tl(0);
3257 TCGv t3 = tcg_const_tl(1);
3258 tcg_gen_ext32u_tl(t0, t0);
3259 tcg_gen_ext32u_tl(t1, t1);
3260 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3261 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3262 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3263 tcg_temp_free(t3);
3264 tcg_temp_free(t2);
3265 }
3266 opn = "divu";
3267 break;
3268 case R6_OPC_MODU:
3269 {
3270 TCGv t2 = tcg_const_tl(0);
3271 TCGv t3 = tcg_const_tl(1);
3272 tcg_gen_ext32u_tl(t0, t0);
3273 tcg_gen_ext32u_tl(t1, t1);
3274 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3275 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3277 tcg_temp_free(t3);
3278 tcg_temp_free(t2);
3279 }
3280 opn = "modu";
3281 break;
3282 case R6_OPC_MUL:
3283 {
3284 TCGv_i32 t2 = tcg_temp_new_i32();
3285 TCGv_i32 t3 = tcg_temp_new_i32();
3286 tcg_gen_trunc_tl_i32(t2, t0);
3287 tcg_gen_trunc_tl_i32(t3, t1);
3288 tcg_gen_mul_i32(t2, t2, t3);
3289 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3290 tcg_temp_free_i32(t2);
3291 tcg_temp_free_i32(t3);
3292 }
3293 opn = "mul";
3294 break;
3295 case R6_OPC_MUH:
3296 {
3297 TCGv_i32 t2 = tcg_temp_new_i32();
3298 TCGv_i32 t3 = tcg_temp_new_i32();
3299 tcg_gen_trunc_tl_i32(t2, t0);
3300 tcg_gen_trunc_tl_i32(t3, t1);
3301 tcg_gen_muls2_i32(t2, t3, t2, t3);
3302 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3303 tcg_temp_free_i32(t2);
3304 tcg_temp_free_i32(t3);
3305 }
3306 opn = "muh";
3307 break;
3308 case R6_OPC_MULU:
3309 {
3310 TCGv_i32 t2 = tcg_temp_new_i32();
3311 TCGv_i32 t3 = tcg_temp_new_i32();
3312 tcg_gen_trunc_tl_i32(t2, t0);
3313 tcg_gen_trunc_tl_i32(t3, t1);
3314 tcg_gen_mul_i32(t2, t2, t3);
3315 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3316 tcg_temp_free_i32(t2);
3317 tcg_temp_free_i32(t3);
3318 }
3319 opn = "mulu";
3320 break;
3321 case R6_OPC_MUHU:
3322 {
3323 TCGv_i32 t2 = tcg_temp_new_i32();
3324 TCGv_i32 t3 = tcg_temp_new_i32();
3325 tcg_gen_trunc_tl_i32(t2, t0);
3326 tcg_gen_trunc_tl_i32(t3, t1);
3327 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3328 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3329 tcg_temp_free_i32(t2);
3330 tcg_temp_free_i32(t3);
3331 }
3332 opn = "muhu";
3333 break;
3334#if defined(TARGET_MIPS64)
3335 case R6_OPC_DDIV:
3336 {
3337 TCGv t2 = tcg_temp_new();
3338 TCGv t3 = tcg_temp_new();
3339 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3340 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3341 tcg_gen_and_tl(t2, t2, t3);
3342 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3343 tcg_gen_or_tl(t2, t2, t3);
3344 tcg_gen_movi_tl(t3, 0);
3345 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3346 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3347 tcg_temp_free(t3);
3348 tcg_temp_free(t2);
3349 }
3350 opn = "ddiv";
3351 break;
3352 case R6_OPC_DMOD:
3353 {
3354 TCGv t2 = tcg_temp_new();
3355 TCGv t3 = tcg_temp_new();
3356 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3357 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3358 tcg_gen_and_tl(t2, t2, t3);
3359 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3360 tcg_gen_or_tl(t2, t2, t3);
3361 tcg_gen_movi_tl(t3, 0);
3362 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3363 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3364 tcg_temp_free(t3);
3365 tcg_temp_free(t2);
3366 }
3367 opn = "dmod";
3368 break;
3369 case R6_OPC_DDIVU:
3370 {
3371 TCGv t2 = tcg_const_tl(0);
3372 TCGv t3 = tcg_const_tl(1);
3373 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3374 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3375 tcg_temp_free(t3);
3376 tcg_temp_free(t2);
3377 }
3378 opn = "ddivu";
3379 break;
3380 case R6_OPC_DMODU:
3381 {
3382 TCGv t2 = tcg_const_tl(0);
3383 TCGv t3 = tcg_const_tl(1);
3384 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3385 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3386 tcg_temp_free(t3);
3387 tcg_temp_free(t2);
3388 }
3389 opn = "dmodu";
3390 break;
3391 case R6_OPC_DMUL:
3392 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3393 opn = "dmul";
3394 break;
3395 case R6_OPC_DMUH:
3396 {
3397 TCGv t2 = tcg_temp_new();
3398 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3399 tcg_temp_free(t2);
3400 }
3401 opn = "dmuh";
3402 break;
3403 case R6_OPC_DMULU:
3404 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3405 opn = "dmulu";
3406 break;
3407 case R6_OPC_DMUHU:
3408 {
3409 TCGv t2 = tcg_temp_new();
3410 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3411 tcg_temp_free(t2);
3412 }
3413 opn = "dmuhu";
3414 break;
3415#endif
3416 default:
3417 MIPS_INVAL(opn);
3418 generate_exception(ctx, EXCP_RI);
3419 goto out;
3420 }
3421 (void)opn; /* avoid a compiler warning */
3422 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3423 out:
3424 tcg_temp_free(t0);
3425 tcg_temp_free(t1);
3426}
3427
26135ead
RS
3428static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3429 int acc, int rs, int rt)
6af0bf9c 3430{
923617a3 3431 const char *opn = "mul/div";
d45f89f4
AJ
3432 TCGv t0, t1;
3433
51127181
AJ
3434 t0 = tcg_temp_new();
3435 t1 = tcg_temp_new();
6af0bf9c 3436
78723684
TS
3437 gen_load_gpr(t0, rs);
3438 gen_load_gpr(t1, rt);
51127181 3439
26135ead
RS
3440 if (acc != 0) {
3441 check_dsp(ctx);
3442 }
3443
6af0bf9c
FB
3444 switch (opc) {
3445 case OPC_DIV:
48d38ca5 3446 {
51127181
AJ
3447 TCGv t2 = tcg_temp_new();
3448 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3449 tcg_gen_ext32s_tl(t0, t0);
3450 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3451 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3452 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3453 tcg_gen_and_tl(t2, t2, t3);
3454 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3455 tcg_gen_or_tl(t2, t2, t3);
3456 tcg_gen_movi_tl(t3, 0);
3457 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3458 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3459 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3460 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3461 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3462 tcg_temp_free(t3);
3463 tcg_temp_free(t2);
48d38ca5 3464 }
6af0bf9c
FB
3465 opn = "div";
3466 break;
3467 case OPC_DIVU:
48d38ca5 3468 {
51127181
AJ
3469 TCGv t2 = tcg_const_tl(0);
3470 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3471 tcg_gen_ext32u_tl(t0, t0);
3472 tcg_gen_ext32u_tl(t1, t1);
51127181 3473 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3474 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3475 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3476 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3477 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3478 tcg_temp_free(t3);
3479 tcg_temp_free(t2);
48d38ca5 3480 }
6af0bf9c
FB
3481 opn = "divu";
3482 break;
3483 case OPC_MULT:
214c465f 3484 {
ce1dd5d1
RH
3485 TCGv_i32 t2 = tcg_temp_new_i32();
3486 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3487 tcg_gen_trunc_tl_i32(t2, t0);
3488 tcg_gen_trunc_tl_i32(t3, t1);
3489 tcg_gen_muls2_i32(t2, t3, t2, t3);
3490 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3491 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3492 tcg_temp_free_i32(t2);
3493 tcg_temp_free_i32(t3);
214c465f 3494 }
6af0bf9c
FB
3495 opn = "mult";
3496 break;
3497 case OPC_MULTU:
214c465f 3498 {
ce1dd5d1
RH
3499 TCGv_i32 t2 = tcg_temp_new_i32();
3500 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3501 tcg_gen_trunc_tl_i32(t2, t0);
3502 tcg_gen_trunc_tl_i32(t3, t1);
3503 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3504 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3505 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3506 tcg_temp_free_i32(t2);
3507 tcg_temp_free_i32(t3);
214c465f 3508 }
6af0bf9c
FB
3509 opn = "multu";
3510 break;
d26bc211 3511#if defined(TARGET_MIPS64)
7a387fff 3512 case OPC_DDIV:
48d38ca5 3513 {
51127181
AJ
3514 TCGv t2 = tcg_temp_new();
3515 TCGv t3 = tcg_temp_new();
3516 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3517 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3518 tcg_gen_and_tl(t2, t2, t3);
3519 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3520 tcg_gen_or_tl(t2, t2, t3);
3521 tcg_gen_movi_tl(t3, 0);
3522 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3523 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3524 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3525 tcg_temp_free(t3);
3526 tcg_temp_free(t2);
48d38ca5 3527 }
7a387fff
TS
3528 opn = "ddiv";
3529 break;
3530 case OPC_DDIVU:
48d38ca5 3531 {
51127181
AJ
3532 TCGv t2 = tcg_const_tl(0);
3533 TCGv t3 = tcg_const_tl(1);
3534 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3535 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3536 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3537 tcg_temp_free(t3);
3538 tcg_temp_free(t2);
48d38ca5 3539 }
7a387fff
TS
3540 opn = "ddivu";
3541 break;
3542 case OPC_DMULT:
26135ead 3543 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3544 opn = "dmult";
3545 break;
3546 case OPC_DMULTU:
26135ead 3547 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3548 opn = "dmultu";
3549 break;
3550#endif
6af0bf9c 3551 case OPC_MADD:
214c465f 3552 {
d45f89f4
AJ
3553 TCGv_i64 t2 = tcg_temp_new_i64();
3554 TCGv_i64 t3 = tcg_temp_new_i64();
3555
3556 tcg_gen_ext_tl_i64(t2, t0);
3557 tcg_gen_ext_tl_i64(t3, t1);
3558 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3559 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3560 tcg_gen_add_i64(t2, t2, t3);
3561 tcg_temp_free_i64(t3);
3562 tcg_gen_trunc_i64_tl(t0, t2);
3563 tcg_gen_shri_i64(t2, t2, 32);
3564 tcg_gen_trunc_i64_tl(t1, t2);
3565 tcg_temp_free_i64(t2);
4133498f
JL
3566 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3567 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3568 }
6af0bf9c
FB
3569 opn = "madd";
3570 break;
3571 case OPC_MADDU:
4133498f 3572 {
d45f89f4
AJ
3573 TCGv_i64 t2 = tcg_temp_new_i64();
3574 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3575
78723684
TS
3576 tcg_gen_ext32u_tl(t0, t0);
3577 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3578 tcg_gen_extu_tl_i64(t2, t0);
3579 tcg_gen_extu_tl_i64(t3, t1);
3580 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3581 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3582 tcg_gen_add_i64(t2, t2, t3);
3583 tcg_temp_free_i64(t3);
3584 tcg_gen_trunc_i64_tl(t0, t2);
3585 tcg_gen_shri_i64(t2, t2, 32);
3586 tcg_gen_trunc_i64_tl(t1, t2);
3587 tcg_temp_free_i64(t2);
4133498f
JL
3588 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3589 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3590 }
6af0bf9c
FB
3591 opn = "maddu";
3592 break;
3593 case OPC_MSUB:
214c465f 3594 {
d45f89f4
AJ
3595 TCGv_i64 t2 = tcg_temp_new_i64();
3596 TCGv_i64 t3 = tcg_temp_new_i64();
3597
3598 tcg_gen_ext_tl_i64(t2, t0);
3599 tcg_gen_ext_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]);
98070ce0 3602 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
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 = "msub";
3612 break;
3613 case OPC_MSUBU:
214c465f 3614 {
d45f89f4
AJ
3615 TCGv_i64 t2 = tcg_temp_new_i64();
3616 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3617
78723684
TS
3618 tcg_gen_ext32u_tl(t0, t0);
3619 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3620 tcg_gen_extu_tl_i64(t2, t0);
3621 tcg_gen_extu_tl_i64(t3, t1);
3622 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3623 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3624 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3625 tcg_temp_free_i64(t3);
3626 tcg_gen_trunc_i64_tl(t0, t2);
3627 tcg_gen_shri_i64(t2, t2, 32);
3628 tcg_gen_trunc_i64_tl(t1, t2);
3629 tcg_temp_free_i64(t2);
4133498f
JL
3630 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3631 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3632 }
6af0bf9c
FB
3633 opn = "msubu";
3634 break;
3635 default:
923617a3 3636 MIPS_INVAL(opn);
6af0bf9c 3637 generate_exception(ctx, EXCP_RI);
78723684 3638 goto out;
6af0bf9c 3639 }
2abf314d 3640 (void)opn; /* avoid a compiler warning */
6af0bf9c 3641 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3642 out:
3643 tcg_temp_free(t0);
3644 tcg_temp_free(t1);
6af0bf9c
FB
3645}
3646
e9c71dd1
TS
3647static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3648 int rd, int rs, int rt)
3649{
3650 const char *opn = "mul vr54xx";
f157bfe1
AJ
3651 TCGv t0 = tcg_temp_new();
3652 TCGv t1 = tcg_temp_new();
e9c71dd1 3653
6c5c1e20
TS
3654 gen_load_gpr(t0, rs);
3655 gen_load_gpr(t1, rt);
e9c71dd1
TS
3656
3657 switch (opc) {
3658 case OPC_VR54XX_MULS:
895c2d04 3659 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3660 opn = "muls";
6958549d 3661 break;
e9c71dd1 3662 case OPC_VR54XX_MULSU:
895c2d04 3663 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3664 opn = "mulsu";
6958549d 3665 break;
e9c71dd1 3666 case OPC_VR54XX_MACC:
895c2d04 3667 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3668 opn = "macc";
6958549d 3669 break;
e9c71dd1 3670 case OPC_VR54XX_MACCU:
895c2d04 3671 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3672 opn = "maccu";
6958549d 3673 break;
e9c71dd1 3674 case OPC_VR54XX_MSAC:
895c2d04 3675 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3676 opn = "msac";
6958549d 3677 break;
e9c71dd1 3678 case OPC_VR54XX_MSACU:
895c2d04 3679 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3680 opn = "msacu";
6958549d 3681 break;
e9c71dd1 3682 case OPC_VR54XX_MULHI:
895c2d04 3683 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3684 opn = "mulhi";
6958549d 3685 break;
e9c71dd1 3686 case OPC_VR54XX_MULHIU:
895c2d04 3687 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3688 opn = "mulhiu";
6958549d 3689 break;
e9c71dd1 3690 case OPC_VR54XX_MULSHI:
895c2d04 3691 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3692 opn = "mulshi";
6958549d 3693 break;
e9c71dd1 3694 case OPC_VR54XX_MULSHIU:
895c2d04 3695 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3696 opn = "mulshiu";
6958549d 3697 break;
e9c71dd1 3698 case OPC_VR54XX_MACCHI:
895c2d04 3699 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3700 opn = "macchi";
6958549d 3701 break;
e9c71dd1 3702 case OPC_VR54XX_MACCHIU:
895c2d04 3703 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3704 opn = "macchiu";
6958549d 3705 break;
e9c71dd1 3706 case OPC_VR54XX_MSACHI:
895c2d04 3707 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3708 opn = "msachi";
6958549d 3709 break;
e9c71dd1 3710 case OPC_VR54XX_MSACHIU:
895c2d04 3711 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3712 opn = "msachiu";
6958549d 3713 break;
e9c71dd1
TS
3714 default:
3715 MIPS_INVAL("mul vr54xx");
3716 generate_exception(ctx, EXCP_RI);
6c5c1e20 3717 goto out;
e9c71dd1 3718 }
6c5c1e20 3719 gen_store_gpr(t0, rd);
2abf314d 3720 (void)opn; /* avoid a compiler warning */
e9c71dd1 3721 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3722
3723 out:
3724 tcg_temp_free(t0);
3725 tcg_temp_free(t1);
e9c71dd1
TS
3726}
3727
7a387fff 3728static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3729 int rd, int rs)
3730{
923617a3 3731 const char *opn = "CLx";
20e1fb52 3732 TCGv t0;
6c5c1e20 3733
6af0bf9c 3734 if (rd == 0) {
ead9360e 3735 /* Treat as NOP. */
6af0bf9c 3736 MIPS_DEBUG("NOP");
20e1fb52 3737 return;
6af0bf9c 3738 }
20e1fb52 3739 t0 = tcg_temp_new();
6c5c1e20 3740 gen_load_gpr(t0, rs);
6af0bf9c
FB
3741 switch (opc) {
3742 case OPC_CLO:
4267d3e6 3743 case R6_OPC_CLO:
20e1fb52 3744 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3745 opn = "clo";
3746 break;
3747 case OPC_CLZ:
4267d3e6 3748 case R6_OPC_CLZ:
20e1fb52 3749 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3750 opn = "clz";
3751 break;
d26bc211 3752#if defined(TARGET_MIPS64)
7a387fff 3753 case OPC_DCLO:
4267d3e6 3754 case R6_OPC_DCLO:
20e1fb52 3755 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3756 opn = "dclo";
3757 break;
3758 case OPC_DCLZ:
4267d3e6 3759 case R6_OPC_DCLZ:
20e1fb52 3760 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3761 opn = "dclz";
3762 break;
3763#endif
6af0bf9c 3764 }
2abf314d 3765 (void)opn; /* avoid a compiler warning */
6af0bf9c 3766 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3767 tcg_temp_free(t0);
6af0bf9c
FB
3768}
3769
161f85e6 3770/* Godson integer instructions */
bd277fa1
RH
3771static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3772 int rd, int rs, int rt)
161f85e6
AJ
3773{
3774 const char *opn = "loongson";
3775 TCGv t0, t1;
3776
3777 if (rd == 0) {
3778 /* Treat as NOP. */
3779 MIPS_DEBUG("NOP");
3780 return;
3781 }
3782
3783 switch (opc) {
3784 case OPC_MULT_G_2E:
3785 case OPC_MULT_G_2F:
3786 case OPC_MULTU_G_2E:
3787 case OPC_MULTU_G_2F:
3788#if defined(TARGET_MIPS64)
3789 case OPC_DMULT_G_2E:
3790 case OPC_DMULT_G_2F:
3791 case OPC_DMULTU_G_2E:
3792 case OPC_DMULTU_G_2F:
3793#endif
3794 t0 = tcg_temp_new();
3795 t1 = tcg_temp_new();
3796 break;
3797 default:
3798 t0 = tcg_temp_local_new();
3799 t1 = tcg_temp_local_new();
3800 break;
3801 }
3802
3803 gen_load_gpr(t0, rs);
3804 gen_load_gpr(t1, rt);
3805
3806 switch (opc) {
3807 case OPC_MULT_G_2E:
3808 case OPC_MULT_G_2F:
3809 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3810 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3811 opn = "mult.g";
3812 break;
3813 case OPC_MULTU_G_2E:
3814 case OPC_MULTU_G_2F:
3815 tcg_gen_ext32u_tl(t0, t0);
3816 tcg_gen_ext32u_tl(t1, t1);
3817 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3818 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3819 opn = "multu.g";
3820 break;
3821 case OPC_DIV_G_2E:
3822 case OPC_DIV_G_2F:
3823 {
3824 int l1 = gen_new_label();
3825 int l2 = gen_new_label();
3826 int l3 = gen_new_label();
3827 tcg_gen_ext32s_tl(t0, t0);
3828 tcg_gen_ext32s_tl(t1, t1);
3829 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3830 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3831 tcg_gen_br(l3);
3832 gen_set_label(l1);
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3834 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3835 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3836 tcg_gen_br(l3);
3837 gen_set_label(l2);
3838 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3839 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3840 gen_set_label(l3);
3841 }
3842 opn = "div.g";
3843 break;
3844 case OPC_DIVU_G_2E:
3845 case OPC_DIVU_G_2F:
3846 {
3847 int l1 = gen_new_label();
3848 int l2 = gen_new_label();
3849 tcg_gen_ext32u_tl(t0, t0);
3850 tcg_gen_ext32u_tl(t1, t1);
3851 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3852 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3853 tcg_gen_br(l2);
3854 gen_set_label(l1);
3855 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3856 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3857 gen_set_label(l2);
3858 }
3859 opn = "divu.g";
3860 break;
3861 case OPC_MOD_G_2E:
3862 case OPC_MOD_G_2F:
3863 {
3864 int l1 = gen_new_label();
3865 int l2 = gen_new_label();
3866 int l3 = gen_new_label();
3867 tcg_gen_ext32u_tl(t0, t0);
3868 tcg_gen_ext32u_tl(t1, t1);
3869 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3870 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3871 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3872 gen_set_label(l1);
3873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3874 tcg_gen_br(l3);
3875 gen_set_label(l2);
3876 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3877 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3878 gen_set_label(l3);
3879 }
3880 opn = "mod.g";
3881 break;
3882 case OPC_MODU_G_2E:
3883 case OPC_MODU_G_2F:
3884 {
3885 int l1 = gen_new_label();
3886 int l2 = gen_new_label();
3887 tcg_gen_ext32u_tl(t0, t0);
3888 tcg_gen_ext32u_tl(t1, t1);
3889 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3890 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3891 tcg_gen_br(l2);
3892 gen_set_label(l1);
3893 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3894 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3895 gen_set_label(l2);
3896 }
3897 opn = "modu.g";
3898 break;
3899#if defined(TARGET_MIPS64)
3900 case OPC_DMULT_G_2E:
3901 case OPC_DMULT_G_2F:
3902 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3903 opn = "dmult.g";
3904 break;
3905 case OPC_DMULTU_G_2E:
3906 case OPC_DMULTU_G_2F:
3907 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3908 opn = "dmultu.g";
3909 break;
3910 case OPC_DDIV_G_2E:
3911 case OPC_DDIV_G_2F:
3912 {
3913 int l1 = gen_new_label();
3914 int l2 = gen_new_label();
3915 int l3 = gen_new_label();
3916 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3918 tcg_gen_br(l3);
3919 gen_set_label(l1);
3920 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3921 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3922 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3923 tcg_gen_br(l3);
3924 gen_set_label(l2);
3925 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3926 gen_set_label(l3);
3927 }
3928 opn = "ddiv.g";
3929 break;
3930 case OPC_DDIVU_G_2E:
3931 case OPC_DDIVU_G_2F:
3932 {
3933 int l1 = gen_new_label();
3934 int l2 = gen_new_label();
3935 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3936 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3937 tcg_gen_br(l2);
3938 gen_set_label(l1);
3939 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3940 gen_set_label(l2);
3941 }
3942 opn = "ddivu.g";
3943 break;
3944 case OPC_DMOD_G_2E:
3945 case OPC_DMOD_G_2F:
3946 {
3947 int l1 = gen_new_label();
3948 int l2 = gen_new_label();
3949 int l3 = gen_new_label();
3950 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3951 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3952 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3953 gen_set_label(l1);
3954 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3955 tcg_gen_br(l3);
3956 gen_set_label(l2);
3957 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3958 gen_set_label(l3);
3959 }
3960 opn = "dmod.g";
3961 break;
3962 case OPC_DMODU_G_2E:
3963 case OPC_DMODU_G_2F:
3964 {
3965 int l1 = gen_new_label();
3966 int l2 = gen_new_label();
3967 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3968 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3969 tcg_gen_br(l2);
3970 gen_set_label(l1);
3971 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3972 gen_set_label(l2);
3973 }
3974 opn = "dmodu.g";
3975 break;
3976#endif
3977 }
3978
2abf314d 3979 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3980 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3981 tcg_temp_free(t0);
3982 tcg_temp_free(t1);
3983}
3984
bd277fa1
RH
3985/* Loongson multimedia instructions */
3986static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3987{
3988 const char *opn = "loongson_cp2";
3989 uint32_t opc, shift_max;
3990 TCGv_i64 t0, t1;
3991
3992 opc = MASK_LMI(ctx->opcode);
3993 switch (opc) {
3994 case OPC_ADD_CP2:
3995 case OPC_SUB_CP2:
3996 case OPC_DADD_CP2:
3997 case OPC_DSUB_CP2:
3998 t0 = tcg_temp_local_new_i64();
3999 t1 = tcg_temp_local_new_i64();
4000 break;
4001 default:
4002 t0 = tcg_temp_new_i64();
4003 t1 = tcg_temp_new_i64();
4004 break;
4005 }
4006
4007 gen_load_fpr64(ctx, t0, rs);
4008 gen_load_fpr64(ctx, t1, rt);
4009
4010#define LMI_HELPER(UP, LO) \
4011 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4012#define LMI_HELPER_1(UP, LO) \
4013 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4014#define LMI_DIRECT(UP, LO, OP) \
4015 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4016
4017 switch (opc) {
4018 LMI_HELPER(PADDSH, paddsh);
4019 LMI_HELPER(PADDUSH, paddush);
4020 LMI_HELPER(PADDH, paddh);
4021 LMI_HELPER(PADDW, paddw);
4022 LMI_HELPER(PADDSB, paddsb);
4023 LMI_HELPER(PADDUSB, paddusb);
4024 LMI_HELPER(PADDB, paddb);
4025
4026 LMI_HELPER(PSUBSH, psubsh);
4027 LMI_HELPER(PSUBUSH, psubush);
4028 LMI_HELPER(PSUBH, psubh);
4029 LMI_HELPER(PSUBW, psubw);
4030 LMI_HELPER(PSUBSB, psubsb);
4031 LMI_HELPER(PSUBUSB, psubusb);
4032 LMI_HELPER(PSUBB, psubb);
4033
4034 LMI_HELPER(PSHUFH, pshufh);
4035 LMI_HELPER(PACKSSWH, packsswh);
4036 LMI_HELPER(PACKSSHB, packsshb);
4037 LMI_HELPER(PACKUSHB, packushb);
4038
4039 LMI_HELPER(PUNPCKLHW, punpcklhw);
4040 LMI_HELPER(PUNPCKHHW, punpckhhw);
4041 LMI_HELPER(PUNPCKLBH, punpcklbh);
4042 LMI_HELPER(PUNPCKHBH, punpckhbh);
4043 LMI_HELPER(PUNPCKLWD, punpcklwd);
4044 LMI_HELPER(PUNPCKHWD, punpckhwd);
4045
4046 LMI_HELPER(PAVGH, pavgh);
4047 LMI_HELPER(PAVGB, pavgb);
4048 LMI_HELPER(PMAXSH, pmaxsh);
4049 LMI_HELPER(PMINSH, pminsh);
4050 LMI_HELPER(PMAXUB, pmaxub);
4051 LMI_HELPER(PMINUB, pminub);
4052
4053 LMI_HELPER(PCMPEQW, pcmpeqw);
4054 LMI_HELPER(PCMPGTW, pcmpgtw);
4055 LMI_HELPER(PCMPEQH, pcmpeqh);
4056 LMI_HELPER(PCMPGTH, pcmpgth);
4057 LMI_HELPER(PCMPEQB, pcmpeqb);
4058 LMI_HELPER(PCMPGTB, pcmpgtb);
4059
4060 LMI_HELPER(PSLLW, psllw);
4061 LMI_HELPER(PSLLH, psllh);
4062 LMI_HELPER(PSRLW, psrlw);
4063 LMI_HELPER(PSRLH, psrlh);
4064 LMI_HELPER(PSRAW, psraw);
4065 LMI_HELPER(PSRAH, psrah);
4066
4067 LMI_HELPER(PMULLH, pmullh);
4068 LMI_HELPER(PMULHH, pmulhh);
4069 LMI_HELPER(PMULHUH, pmulhuh);
4070 LMI_HELPER(PMADDHW, pmaddhw);
4071
4072 LMI_HELPER(PASUBUB, pasubub);
4073 LMI_HELPER_1(BIADD, biadd);
4074 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4075
4076 LMI_DIRECT(PADDD, paddd, add);
4077 LMI_DIRECT(PSUBD, psubd, sub);
4078 LMI_DIRECT(XOR_CP2, xor, xor);
4079 LMI_DIRECT(NOR_CP2, nor, nor);
4080 LMI_DIRECT(AND_CP2, and, and);
4081 LMI_DIRECT(PANDN, pandn, andc);
4082 LMI_DIRECT(OR, or, or);
4083
4084 case OPC_PINSRH_0:
4085 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4086 opn = "pinsrh_0";
4087 break;
4088 case OPC_PINSRH_1:
4089 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4090 opn = "pinsrh_1";
4091 break;
4092 case OPC_PINSRH_2:
4093 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4094 opn = "pinsrh_2";
4095 break;
4096 case OPC_PINSRH_3:
4097 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4098 opn = "pinsrh_3";
4099 break;
4100
4101 case OPC_PEXTRH:
4102 tcg_gen_andi_i64(t1, t1, 3);
4103 tcg_gen_shli_i64(t1, t1, 4);
4104 tcg_gen_shr_i64(t0, t0, t1);
4105 tcg_gen_ext16u_i64(t0, t0);
4106 opn = "pextrh";
4107 break;
4108
4109 case OPC_ADDU_CP2:
4110 tcg_gen_add_i64(t0, t0, t1);
4111 tcg_gen_ext32s_i64(t0, t0);
4112 opn = "addu";
4113 break;
4114 case OPC_SUBU_CP2:
4115 tcg_gen_sub_i64(t0, t0, t1);
4116 tcg_gen_ext32s_i64(t0, t0);
4117 opn = "addu";
4118 break;
4119
4120 case OPC_SLL_CP2:
4121 opn = "sll";
4122 shift_max = 32;
4123 goto do_shift;
4124 case OPC_SRL_CP2:
4125 opn = "srl";
4126 shift_max = 32;
4127 goto do_shift;
4128 case OPC_SRA_CP2:
4129 opn = "sra";
4130 shift_max = 32;
4131 goto do_shift;
4132 case OPC_DSLL_CP2:
4133 opn = "dsll";
4134 shift_max = 64;
4135 goto do_shift;
4136 case OPC_DSRL_CP2:
4137 opn = "dsrl";
4138 shift_max = 64;
4139 goto do_shift;
4140 case OPC_DSRA_CP2:
4141 opn = "dsra";
4142 shift_max = 64;
4143 goto do_shift;
4144 do_shift:
4145 /* Make sure shift count isn't TCG undefined behaviour. */
4146 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4147
4148 switch (opc) {
4149 case OPC_SLL_CP2:
4150 case OPC_DSLL_CP2:
4151 tcg_gen_shl_i64(t0, t0, t1);
4152 break;
4153 case OPC_SRA_CP2:
4154 case OPC_DSRA_CP2:
4155 /* Since SRA is UndefinedResult without sign-extended inputs,
4156 we can treat SRA and DSRA the same. */
4157 tcg_gen_sar_i64(t0, t0, t1);
4158 break;
4159 case OPC_SRL_CP2:
4160 /* We want to shift in zeros for SRL; zero-extend first. */
4161 tcg_gen_ext32u_i64(t0, t0);
4162 /* FALLTHRU */
4163 case OPC_DSRL_CP2:
4164 tcg_gen_shr_i64(t0, t0, t1);
4165 break;
4166 }
4167
4168 if (shift_max == 32) {
4169 tcg_gen_ext32s_i64(t0, t0);
4170 }
4171
4172 /* Shifts larger than MAX produce zero. */
4173 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4174 tcg_gen_neg_i64(t1, t1);
4175 tcg_gen_and_i64(t0, t0, t1);
4176 break;
4177
4178 case OPC_ADD_CP2:
4179 case OPC_DADD_CP2:
4180 {
4181 TCGv_i64 t2 = tcg_temp_new_i64();
4182 int lab = gen_new_label();
4183
4184 tcg_gen_mov_i64(t2, t0);
4185 tcg_gen_add_i64(t0, t1, t2);
4186 if (opc == OPC_ADD_CP2) {
4187 tcg_gen_ext32s_i64(t0, t0);
4188 }
4189 tcg_gen_xor_i64(t1, t1, t2);
4190 tcg_gen_xor_i64(t2, t2, t0);
4191 tcg_gen_andc_i64(t1, t2, t1);
4192 tcg_temp_free_i64(t2);
4193 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4194 generate_exception(ctx, EXCP_OVERFLOW);
4195 gen_set_label(lab);
4196
4197 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4198 break;
4199 }
4200
4201 case OPC_SUB_CP2:
4202 case OPC_DSUB_CP2:
4203 {
4204 TCGv_i64 t2 = tcg_temp_new_i64();
4205 int lab = gen_new_label();
4206
4207 tcg_gen_mov_i64(t2, t0);
4208 tcg_gen_sub_i64(t0, t1, t2);
4209 if (opc == OPC_SUB_CP2) {
4210 tcg_gen_ext32s_i64(t0, t0);
4211 }
4212 tcg_gen_xor_i64(t1, t1, t2);
4213 tcg_gen_xor_i64(t2, t2, t0);
4214 tcg_gen_and_i64(t1, t1, t2);
4215 tcg_temp_free_i64(t2);
4216 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4217 generate_exception(ctx, EXCP_OVERFLOW);
4218 gen_set_label(lab);
4219
4220 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4221 break;
4222 }
4223
4224 case OPC_PMULUW:
4225 tcg_gen_ext32u_i64(t0, t0);
4226 tcg_gen_ext32u_i64(t1, t1);
4227 tcg_gen_mul_i64(t0, t0, t1);
4228 opn = "pmuluw";
4229 break;
4230
4231 case OPC_SEQU_CP2:
4232 case OPC_SEQ_CP2:
4233 case OPC_SLTU_CP2:
4234 case OPC_SLT_CP2:
4235 case OPC_SLEU_CP2:
4236 case OPC_SLE_CP2:
4237 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4238 FD field is the CC field? */
4239 default:
4240 MIPS_INVAL(opn);
4241 generate_exception(ctx, EXCP_RI);
4242 return;
4243 }
4244
4245#undef LMI_HELPER
4246#undef LMI_DIRECT
4247
4248 gen_store_fpr64(ctx, t0, rd);
4249
4250 (void)opn; /* avoid a compiler warning */
4251 MIPS_DEBUG("%s %s, %s, %s", opn,
4252 fregnames[rd], fregnames[rs], fregnames[rt]);
4253 tcg_temp_free_i64(t0);
4254 tcg_temp_free_i64(t1);
4255}
4256
6af0bf9c 4257/* Traps */
7a387fff 4258static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4259 int rs, int rt, int16_t imm)
4260{
4261 int cond;
cdc0faa6 4262 TCGv t0 = tcg_temp_new();
1ba74fb8 4263 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4264
4265 cond = 0;
4266 /* Load needed operands */
4267 switch (opc) {
4268 case OPC_TEQ:
4269 case OPC_TGE:
4270 case OPC_TGEU:
4271 case OPC_TLT:
4272 case OPC_TLTU:
4273 case OPC_TNE:
4274 /* Compare two registers */
4275 if (rs != rt) {
be24bb4f
TS
4276 gen_load_gpr(t0, rs);
4277 gen_load_gpr(t1, rt);
6af0bf9c
FB
4278 cond = 1;
4279 }
179e32bb 4280 break;
6af0bf9c
FB
4281 case OPC_TEQI:
4282 case OPC_TGEI:
4283 case OPC_TGEIU:
4284 case OPC_TLTI:
4285 case OPC_TLTIU:
4286 case OPC_TNEI:
4287 /* Compare register to immediate */
4288 if (rs != 0 || imm != 0) {
be24bb4f
TS
4289 gen_load_gpr(t0, rs);
4290 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4291 cond = 1;
4292 }
4293 break;
4294 }
4295 if (cond == 0) {
4296 switch (opc) {
4297 case OPC_TEQ: /* rs == rs */
4298 case OPC_TEQI: /* r0 == 0 */
4299 case OPC_TGE: /* rs >= rs */
4300 case OPC_TGEI: /* r0 >= 0 */
4301 case OPC_TGEU: /* rs >= rs unsigned */
4302 case OPC_TGEIU: /* r0 >= 0 unsigned */
4303 /* Always trap */
cdc0faa6 4304 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4305 break;
4306 case OPC_TLT: /* rs < rs */
4307 case OPC_TLTI: /* r0 < 0 */
4308 case OPC_TLTU: /* rs < rs unsigned */
4309 case OPC_TLTIU: /* r0 < 0 unsigned */
4310 case OPC_TNE: /* rs != rs */
4311 case OPC_TNEI: /* r0 != 0 */
ead9360e 4312 /* Never trap: treat as NOP. */
cdc0faa6 4313 break;
6af0bf9c
FB
4314 }
4315 } else {
cdc0faa6
AJ
4316 int l1 = gen_new_label();
4317
6af0bf9c
FB
4318 switch (opc) {
4319 case OPC_TEQ:
4320 case OPC_TEQI:
cdc0faa6 4321 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4322 break;
4323 case OPC_TGE:
4324 case OPC_TGEI:
cdc0faa6 4325 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4326 break;
4327 case OPC_TGEU:
4328 case OPC_TGEIU:
cdc0faa6 4329 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4330 break;
4331 case OPC_TLT:
4332 case OPC_TLTI:
cdc0faa6 4333 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4334 break;
4335 case OPC_TLTU:
4336 case OPC_TLTIU:
cdc0faa6 4337 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4338 break;
4339 case OPC_TNE:
4340 case OPC_TNEI:
cdc0faa6 4341 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4342 break;
6af0bf9c 4343 }
cdc0faa6 4344 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4345 gen_set_label(l1);
4346 }
be24bb4f
TS
4347 tcg_temp_free(t0);
4348 tcg_temp_free(t1);
6af0bf9c
FB
4349}
4350
356265ae 4351static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4352{
6e256c93
FB
4353 TranslationBlock *tb;
4354 tb = ctx->tb;
7b270ef2
NF
4355 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4356 likely(!ctx->singlestep_enabled)) {
57fec1fe 4357 tcg_gen_goto_tb(n);
9b9e4393 4358 gen_save_pc(dest);
8cfd0495 4359 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4360 } else {
9b9e4393 4361 gen_save_pc(dest);
7b270ef2
NF
4362 if (ctx->singlestep_enabled) {
4363 save_cpu_state(ctx, 0);
895c2d04 4364 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4365 }
57fec1fe 4366 tcg_gen_exit_tb(0);
6e256c93 4367 }
c53be334
FB
4368}
4369
6af0bf9c 4370/* Branches (before delay slot) */
7a387fff 4371static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4372 int insn_bytes,
b231c103
YK
4373 int rs, int rt, int32_t offset,
4374 int delayslot_size)
6af0bf9c 4375{
d077b6f7 4376 target_ulong btgt = -1;
3ad4bb2d 4377 int blink = 0;
2fdbad25 4378 int bcond_compute = 0;
1ba74fb8
AJ
4379 TCGv t0 = tcg_temp_new();
4380 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4381
4382 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4383#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4384 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4385 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4386#endif
3ad4bb2d 4387 generate_exception(ctx, EXCP_RI);
6c5c1e20 4388 goto out;
3ad4bb2d 4389 }
6af0bf9c 4390
6af0bf9c
FB
4391 /* Load needed operands */
4392 switch (opc) {
4393 case OPC_BEQ:
4394 case OPC_BEQL:
4395 case OPC_BNE:
4396 case OPC_BNEL:
4397 /* Compare two registers */
4398 if (rs != rt) {
6c5c1e20
TS
4399 gen_load_gpr(t0, rs);
4400 gen_load_gpr(t1, rt);
2fdbad25 4401 bcond_compute = 1;
6af0bf9c 4402 }
7dca4ad0 4403 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4404 break;
4405 case OPC_BGEZ:
4406 case OPC_BGEZAL:
4407 case OPC_BGEZALL:
4408 case OPC_BGEZL:
4409 case OPC_BGTZ:
4410 case OPC_BGTZL:
4411 case OPC_BLEZ:
4412 case OPC_BLEZL:
4413 case OPC_BLTZ:
4414 case OPC_BLTZAL:
4415 case OPC_BLTZALL:
4416 case OPC_BLTZL:
4417 /* Compare to zero */
4418 if (rs != 0) {
6c5c1e20 4419 gen_load_gpr(t0, rs);
2fdbad25 4420 bcond_compute = 1;
6af0bf9c 4421 }
7dca4ad0 4422 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4423 break;
e45a93e2
JL
4424 case OPC_BPOSGE32:
4425#if defined(TARGET_MIPS64)
4426 case OPC_BPOSGE64:
4427 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4428#else
4429 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4430#endif
4431 bcond_compute = 1;
4432 btgt = ctx->pc + insn_bytes + offset;
4433 break;
6af0bf9c
FB
4434 case OPC_J:
4435 case OPC_JAL:
364d4831 4436 case OPC_JALX:
6af0bf9c 4437 /* Jump to immediate */
7dca4ad0 4438 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4439 break;
4440 case OPC_JR:
4441 case OPC_JALR:
4442 /* Jump to register */
7a387fff
TS
4443 if (offset != 0 && offset != 16) {
4444 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4445 others are reserved. */
923617a3 4446 MIPS_INVAL("jump hint");
6af0bf9c 4447 generate_exception(ctx, EXCP_RI);
6c5c1e20 4448 goto out;
6af0bf9c 4449 }
d077b6f7 4450 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4451 break;
4452 default:
4453 MIPS_INVAL("branch/jump");
4454 generate_exception(ctx, EXCP_RI);
6c5c1e20 4455 goto out;
6af0bf9c 4456 }
2fdbad25 4457 if (bcond_compute == 0) {
6af0bf9c
FB
4458 /* No condition to be computed */
4459 switch (opc) {
4460 case OPC_BEQ: /* rx == rx */
4461 case OPC_BEQL: /* rx == rx likely */
4462 case OPC_BGEZ: /* 0 >= 0 */
4463 case OPC_BGEZL: /* 0 >= 0 likely */
4464 case OPC_BLEZ: /* 0 <= 0 */
4465 case OPC_BLEZL: /* 0 <= 0 likely */
4466 /* Always take */
4ad40f36 4467 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4468 MIPS_DEBUG("balways");
4469 break;
4470 case OPC_BGEZAL: /* 0 >= 0 */
4471 case OPC_BGEZALL: /* 0 >= 0 likely */
4472 /* Always take and link */
4473 blink = 31;
4ad40f36 4474 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4475 MIPS_DEBUG("balways and link");
4476 break;
4477 case OPC_BNE: /* rx != rx */
4478 case OPC_BGTZ: /* 0 > 0 */
4479 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4480 /* Treat as NOP. */
6af0bf9c 4481 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4482 goto out;
eeef26cd 4483 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4484 /* Handle as an unconditional branch to get correct delay
4485 slot checking. */
4486 blink = 31;
b231c103 4487 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4488 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4489 MIPS_DEBUG("bnever and link");
3c824109 4490 break;
eeef26cd 4491 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4492 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4493 /* Skip the instruction in the delay slot */
4494 MIPS_DEBUG("bnever, link and skip");
4495 ctx->pc += 4;
6c5c1e20 4496 goto out;
6af0bf9c
FB
4497 case OPC_BNEL: /* rx != rx likely */
4498 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4499 case OPC_BLTZL: /* 0 < 0 likely */
4500 /* Skip the instruction in the delay slot */
4501 MIPS_DEBUG("bnever and skip");
9898128f 4502 ctx->pc += 4;
6c5c1e20 4503 goto out;
6af0bf9c 4504 case OPC_J:
4ad40f36 4505 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4506 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4507 break;
364d4831
NF
4508 case OPC_JALX:
4509 ctx->hflags |= MIPS_HFLAG_BX;
4510 /* Fallthrough */
6af0bf9c
FB
4511 case OPC_JAL:
4512 blink = 31;
4ad40f36 4513 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4514 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4515 break;
4516 case OPC_JR:
4ad40f36 4517 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4518 MIPS_DEBUG("jr %s", regnames[rs]);
4519 break;
4520 case OPC_JALR:
4521 blink = rt;
4ad40f36 4522 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4523 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4524 break;
4525 default:
4526 MIPS_INVAL("branch/jump");
4527 generate_exception(ctx, EXCP_RI);
6c5c1e20 4528 goto out;
6af0bf9c
FB
4529 }
4530 } else {
4531 switch (opc) {
4532 case OPC_BEQ:
e68dd28f 4533 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4534 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4535 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4536 goto not_likely;
4537 case OPC_BEQL:
e68dd28f 4538 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4539 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4540 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4541 goto likely;
4542 case OPC_BNE:
e68dd28f 4543 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4544 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4545 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4546 goto not_likely;
4547 case OPC_BNEL:
e68dd28f 4548 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4549 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4550 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4551 goto likely;
4552 case OPC_BGEZ:
e68dd28f 4553 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4554 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4555 goto not_likely;
4556 case OPC_BGEZL:
e68dd28f 4557 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4558 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4559 goto likely;
4560 case OPC_BGEZAL:
e68dd28f 4561 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4562 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4563 blink = 31;
4564 goto not_likely;
4565 case OPC_BGEZALL:
e68dd28f 4566 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4567 blink = 31;
d077b6f7 4568 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4569 goto likely;
4570 case OPC_BGTZ:
e68dd28f 4571 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4572 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4573 goto not_likely;
4574 case OPC_BGTZL:
e68dd28f 4575 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4576 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4577 goto likely;
4578 case OPC_BLEZ:
e68dd28f 4579 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4580 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4581 goto not_likely;
4582 case OPC_BLEZL:
e68dd28f 4583 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4584 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4585 goto likely;
4586 case OPC_BLTZ:
e68dd28f 4587 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4588 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4589 goto not_likely;
4590 case OPC_BLTZL:
e68dd28f 4591 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4592 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4593 goto likely;
e45a93e2
JL
4594 case OPC_BPOSGE32:
4595 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4596 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4597 goto not_likely;
4598#if defined(TARGET_MIPS64)
4599 case OPC_BPOSGE64:
4600 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4601 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4602 goto not_likely;
4603#endif
6af0bf9c 4604 case OPC_BLTZAL:
e68dd28f 4605 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4606 blink = 31;
d077b6f7 4607 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4608 not_likely:
4ad40f36 4609 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4610 break;
4611 case OPC_BLTZALL:
e68dd28f 4612 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4613 blink = 31;
d077b6f7 4614 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4615 likely:
4ad40f36 4616 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4617 break;
c53f4a62
TS
4618 default:
4619 MIPS_INVAL("conditional branch/jump");
4620 generate_exception(ctx, EXCP_RI);
6c5c1e20 4621 goto out;
6af0bf9c 4622 }
6af0bf9c 4623 }
923617a3 4624 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4625 blink, ctx->hflags, btgt);
9b9e4393 4626
d077b6f7 4627 ctx->btarget = btgt;
b231c103
YK
4628
4629 switch (delayslot_size) {
4630 case 2:
4631 ctx->hflags |= MIPS_HFLAG_BDS16;
4632 break;
4633 case 4:
4634 ctx->hflags |= MIPS_HFLAG_BDS32;
4635 break;
4636 }
4637
6af0bf9c 4638 if (blink > 0) {
b231c103 4639 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4640 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4641
364d4831 4642 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4643 }
6c5c1e20
TS
4644
4645 out:
364d4831
NF
4646 if (insn_bytes == 2)
4647 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4648 tcg_temp_free(t0);
4649 tcg_temp_free(t1);
6af0bf9c
FB
4650}
4651
7a387fff
TS
4652/* special3 bitfield operations */
4653static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4654 int rs, int lsb, int msb)
7a387fff 4655{
a7812ae4
PB
4656 TCGv t0 = tcg_temp_new();
4657 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4658
4659 gen_load_gpr(t1, rs);
7a387fff
TS
4660 switch (opc) {
4661 case OPC_EXT:
4662 if (lsb + msb > 31)
4663 goto fail;
505ad7c2
AJ
4664 tcg_gen_shri_tl(t0, t1, lsb);
4665 if (msb != 31) {
4666 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4667 } else {
4668 tcg_gen_ext32s_tl(t0, t0);
4669 }
7a387fff 4670 break;
c6d6dd7c 4671#if defined(TARGET_MIPS64)
7a387fff 4672 case OPC_DEXTM:
505ad7c2
AJ
4673 tcg_gen_shri_tl(t0, t1, lsb);
4674 if (msb != 31) {
4675 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4676 }
7a387fff
TS
4677 break;
4678 case OPC_DEXTU:
505ad7c2
AJ
4679 tcg_gen_shri_tl(t0, t1, lsb + 32);
4680 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4681 break;
4682 case OPC_DEXT:
505ad7c2
AJ
4683 tcg_gen_shri_tl(t0, t1, lsb);
4684 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4685 break;
c6d6dd7c 4686#endif
7a387fff
TS
4687 case OPC_INS:
4688 if (lsb > msb)
4689 goto fail;
6c5c1e20 4690 gen_load_gpr(t0, rt);
e0d002f1 4691 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4692 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4693 break;
c6d6dd7c 4694#if defined(TARGET_MIPS64)
7a387fff 4695 case OPC_DINSM:
6c5c1e20 4696 gen_load_gpr(t0, rt);
e0d002f1 4697 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4698 break;
4699 case OPC_DINSU:
6c5c1e20 4700 gen_load_gpr(t0, rt);
e0d002f1 4701 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4702 break;
4703 case OPC_DINS:
6c5c1e20 4704 gen_load_gpr(t0, rt);
e0d002f1 4705 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4706 break;
c6d6dd7c 4707#endif
7a387fff
TS
4708 default:
4709fail:
4710 MIPS_INVAL("bitops");
4711 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4712 tcg_temp_free(t0);
4713 tcg_temp_free(t1);
7a387fff
TS
4714 return;
4715 }
6c5c1e20
TS
4716 gen_store_gpr(t0, rt);
4717 tcg_temp_free(t0);
4718 tcg_temp_free(t1);
7a387fff
TS
4719}
4720
49bcf33c
AJ
4721static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4722{
3a55fa47 4723 TCGv t0;
49bcf33c 4724
3a55fa47
AJ
4725 if (rd == 0) {
4726 /* If no destination, treat it as a NOP. */
4727 MIPS_DEBUG("NOP");
4728 return;
4729 }
4730
4731 t0 = tcg_temp_new();
4732 gen_load_gpr(t0, rt);
49bcf33c
AJ
4733 switch (op2) {
4734 case OPC_WSBH:
3a55fa47
AJ
4735 {
4736 TCGv t1 = tcg_temp_new();
4737
4738 tcg_gen_shri_tl(t1, t0, 8);
4739 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4740 tcg_gen_shli_tl(t0, t0, 8);
4741 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4742 tcg_gen_or_tl(t0, t0, t1);
4743 tcg_temp_free(t1);
4744 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4745 }
49bcf33c
AJ
4746 break;
4747 case OPC_SEB:
3a55fa47 4748 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4749 break;
4750 case OPC_SEH:
3a55fa47 4751 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4752 break;
4753#if defined(TARGET_MIPS64)
4754 case OPC_DSBH:
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, 0x00FF00FF00FF00FFULL);
4760 tcg_gen_shli_tl(t0, t0, 8);
4761 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4762 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4763 tcg_temp_free(t1);
4764 }
49bcf33c
AJ
4765 break;
4766 case OPC_DSHD:
3a55fa47
AJ
4767 {
4768 TCGv t1 = tcg_temp_new();
4769
4770 tcg_gen_shri_tl(t1, t0, 16);
4771 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4772 tcg_gen_shli_tl(t0, t0, 16);
4773 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4774 tcg_gen_or_tl(t0, t0, t1);
4775 tcg_gen_shri_tl(t1, t0, 32);
4776 tcg_gen_shli_tl(t0, t0, 32);
4777 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4778 tcg_temp_free(t1);
4779 }
49bcf33c
AJ
4780 break;
4781#endif
4782 default:
4783 MIPS_INVAL("bsfhl");
4784 generate_exception(ctx, EXCP_RI);
4785 tcg_temp_free(t0);
49bcf33c
AJ
4786 return;
4787 }
49bcf33c 4788 tcg_temp_free(t0);
49bcf33c
AJ
4789}
4790
f1aa6320 4791#ifndef CONFIG_USER_ONLY
0eaef5aa 4792/* CP0 (MMU and control) */
d9bea114 4793static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4794{
d9bea114 4795 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4796
d9bea114
AJ
4797 tcg_gen_ld_i32(t0, cpu_env, off);
4798 tcg_gen_ext_i32_tl(arg, t0);
4799 tcg_temp_free_i32(t0);
4f57689a
TS
4800}
4801
d9bea114 4802static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4803{
d9bea114
AJ
4804 tcg_gen_ld_tl(arg, cpu_env, off);
4805 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4806}
4807
d9bea114 4808static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4809{
d9bea114 4810 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4811
d9bea114
AJ
4812 tcg_gen_trunc_tl_i32(t0, arg);
4813 tcg_gen_st_i32(t0, cpu_env, off);
4814 tcg_temp_free_i32(t0);
f1aa6320
TS
4815}
4816
d9bea114 4817static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4818{
d9bea114
AJ
4819 tcg_gen_ext32s_tl(arg, arg);
4820 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4821}
4822
e98c0d17
LA
4823static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4824{
4825 if (ctx->insn_flags & ISA_MIPS32R6) {
4826 tcg_gen_movi_tl(arg, 0);
4827 } else {
4828 tcg_gen_movi_tl(arg, ~0);
4829 }
4830}
4831
f31b035a
LA
4832#define CP0_CHECK(c) \
4833 do { \
4834 if (!(c)) { \
4835 goto cp0_unimplemented; \
4836 } \
4837 } while (0)
4838
d75c135e 4839static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4840{
7a387fff 4841 const char *rn = "invalid";
873eb012 4842
e189e748 4843 if (sel != 0)
d75c135e 4844 check_insn(ctx, ISA_MIPS32);
e189e748 4845
873eb012
TS
4846 switch (reg) {
4847 case 0:
7a387fff
TS
4848 switch (sel) {
4849 case 0:
7db13fae 4850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4851 rn = "Index";
4852 break;
4853 case 1:
f31b035a 4854 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4855 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4856 rn = "MVPControl";
ead9360e 4857 break;
7a387fff 4858 case 2:
f31b035a 4859 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4860 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4861 rn = "MVPConf0";
ead9360e 4862 break;
7a387fff 4863 case 3:
f31b035a 4864 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4865 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4866 rn = "MVPConf1";
ead9360e 4867 break;
7a387fff 4868 default:
f31b035a 4869 goto cp0_unimplemented;
7a387fff 4870 }
873eb012
TS
4871 break;
4872 case 1:
7a387fff
TS
4873 switch (sel) {
4874 case 0:
f31b035a 4875 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4876 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4877 rn = "Random";
2423f660 4878 break;
7a387fff 4879 case 1:
f31b035a 4880 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4882 rn = "VPEControl";
ead9360e 4883 break;
7a387fff 4884 case 2:
f31b035a 4885 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4886 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4887 rn = "VPEConf0";
ead9360e 4888 break;
7a387fff 4889 case 3:
f31b035a 4890 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4891 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4892 rn = "VPEConf1";
ead9360e 4893 break;
7a387fff 4894 case 4:
f31b035a 4895 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4896 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4897 rn = "YQMask";
ead9360e 4898 break;
7a387fff 4899 case 5:
f31b035a 4900 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4901 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4902 rn = "VPESchedule";
ead9360e 4903 break;
7a387fff 4904 case 6:
f31b035a 4905 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4906 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4907 rn = "VPEScheFBack";
ead9360e 4908 break;
7a387fff 4909 case 7:
f31b035a 4910 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4912 rn = "VPEOpt";
ead9360e 4913 break;
7a387fff 4914 default:
f31b035a 4915 goto cp0_unimplemented;
7a387fff 4916 }
873eb012
TS
4917 break;
4918 case 2:
7a387fff
TS
4919 switch (sel) {
4920 case 0:
7db13fae 4921 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4922#if defined(TARGET_MIPS64)
4923 if (ctx->rxi) {
4924 TCGv tmp = tcg_temp_new();
4925 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
4926 tcg_gen_shri_tl(tmp, tmp, 32);
4927 tcg_gen_or_tl(arg, arg, tmp);
4928 tcg_temp_free(tmp);
4929 }
4930#endif
d9bea114 4931 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4932 rn = "EntryLo0";
4933 break;
7a387fff 4934 case 1:
f31b035a 4935 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4936 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4937 rn = "TCStatus";
ead9360e 4938 break;
7a387fff 4939 case 2:
f31b035a 4940 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4941 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4942 rn = "TCBind";
ead9360e 4943 break;
7a387fff 4944 case 3:
f31b035a 4945 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4946 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4947 rn = "TCRestart";
ead9360e 4948 break;
7a387fff 4949 case 4:
f31b035a 4950 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4951 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4952 rn = "TCHalt";
ead9360e 4953 break;
7a387fff 4954 case 5:
f31b035a 4955 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4956 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4957 rn = "TCContext";
ead9360e 4958 break;
7a387fff 4959 case 6:
f31b035a 4960 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4961 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4962 rn = "TCSchedule";
ead9360e 4963 break;
7a387fff 4964 case 7:
f31b035a 4965 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4966 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4967 rn = "TCScheFBack";
ead9360e 4968 break;
7a387fff 4969 default:
f31b035a 4970 goto cp0_unimplemented;
7a387fff 4971 }
873eb012
TS
4972 break;
4973 case 3:
7a387fff
TS
4974 switch (sel) {
4975 case 0:
7db13fae 4976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
4977#if defined(TARGET_MIPS64)
4978 if (ctx->rxi) {
4979 TCGv tmp = tcg_temp_new();
4980 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
4981 tcg_gen_shri_tl(tmp, tmp, 32);
4982 tcg_gen_or_tl(arg, arg, tmp);
4983 tcg_temp_free(tmp);
4984 }
4985#endif
d9bea114 4986 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4987 rn = "EntryLo1";
4988 break;
7a387fff 4989 default:
f31b035a 4990 goto cp0_unimplemented;
1579a72e 4991 }
873eb012
TS
4992 break;
4993 case 4:
7a387fff
TS
4994 switch (sel) {
4995 case 0:
7db13fae 4996 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4997 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4998 rn = "Context";
4999 break;
7a387fff 5000 case 1:
d9bea114 5001// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5002 rn = "ContextConfig";
f31b035a 5003 goto cp0_unimplemented;
2423f660 5004// break;
d279279e 5005 case 2:
f31b035a
LA
5006 CP0_CHECK(ctx->ulri);
5007 tcg_gen_ld32s_tl(arg, cpu_env,
5008 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5009 rn = "UserLocal";
d279279e 5010 break;
7a387fff 5011 default:
f31b035a 5012 goto cp0_unimplemented;
1579a72e 5013 }
873eb012
TS
5014 break;
5015 case 5:
7a387fff
TS
5016 switch (sel) {
5017 case 0:
7db13fae 5018 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5019 rn = "PageMask";
5020 break;
7a387fff 5021 case 1:
d75c135e 5022 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5024 rn = "PageGrain";
5025 break;
7a387fff 5026 default:
f31b035a 5027 goto cp0_unimplemented;
1579a72e 5028 }
873eb012
TS
5029 break;
5030 case 6:
7a387fff
TS
5031 switch (sel) {
5032 case 0:
7db13fae 5033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5034 rn = "Wired";
5035 break;
7a387fff 5036 case 1:
d75c135e 5037 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5039 rn = "SRSConf0";
ead9360e 5040 break;
7a387fff 5041 case 2:
d75c135e 5042 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5044 rn = "SRSConf1";
ead9360e 5045 break;
7a387fff 5046 case 3:
d75c135e 5047 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5048 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5049 rn = "SRSConf2";
ead9360e 5050 break;
7a387fff 5051 case 4:
d75c135e 5052 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5054 rn = "SRSConf3";
ead9360e 5055 break;
7a387fff 5056 case 5:
d75c135e 5057 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5059 rn = "SRSConf4";
ead9360e 5060 break;
7a387fff 5061 default:
f31b035a 5062 goto cp0_unimplemented;
1579a72e 5063 }
873eb012 5064 break;
8c0fdd85 5065 case 7:
7a387fff
TS
5066 switch (sel) {
5067 case 0:
d75c135e 5068 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5069 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5070 rn = "HWREna";
5071 break;
7a387fff 5072 default:
f31b035a 5073 goto cp0_unimplemented;
1579a72e 5074 }
8c0fdd85 5075 break;
873eb012 5076 case 8:
7a387fff
TS
5077 switch (sel) {
5078 case 0:
7db13fae 5079 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5080 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5081 rn = "BadVAddr";
2423f660 5082 break;
aea14095 5083 case 1:
f31b035a
LA
5084 CP0_CHECK(ctx->bi);
5085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5086 rn = "BadInstr";
aea14095
LA
5087 break;
5088 case 2:
f31b035a
LA
5089 CP0_CHECK(ctx->bp);
5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5091 rn = "BadInstrP";
aea14095 5092 break;
7a387fff 5093 default:
f31b035a 5094 goto cp0_unimplemented;
aea14095 5095 }
873eb012
TS
5096 break;
5097 case 9:
7a387fff
TS
5098 switch (sel) {
5099 case 0:
2e70f6ef
PB
5100 /* Mark as an IO operation because we read the time. */
5101 if (use_icount)
5102 gen_io_start();
895c2d04 5103 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5104 if (use_icount) {
5105 gen_io_end();
2e70f6ef 5106 }
55807224
EI
5107 /* Break the TB to be able to take timer interrupts immediately
5108 after reading count. */
5109 ctx->bstate = BS_STOP;
2423f660
TS
5110 rn = "Count";
5111 break;
5112 /* 6,7 are implementation dependent */
7a387fff 5113 default:
f31b035a 5114 goto cp0_unimplemented;
2423f660 5115 }
873eb012
TS
5116 break;
5117 case 10:
7a387fff
TS
5118 switch (sel) {
5119 case 0:
7db13fae 5120 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5121 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5122 rn = "EntryHi";
5123 break;
7a387fff 5124 default:
f31b035a 5125 goto cp0_unimplemented;
1579a72e 5126 }
873eb012
TS
5127 break;
5128 case 11:
7a387fff
TS
5129 switch (sel) {
5130 case 0:
7db13fae 5131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5132 rn = "Compare";
5133 break;
5134 /* 6,7 are implementation dependent */
7a387fff 5135 default:
f31b035a 5136 goto cp0_unimplemented;
2423f660 5137 }
873eb012
TS
5138 break;
5139 case 12:
7a387fff
TS
5140 switch (sel) {
5141 case 0:
7db13fae 5142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5143 rn = "Status";
5144 break;
7a387fff 5145 case 1:
d75c135e 5146 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5148 rn = "IntCtl";
5149 break;
7a387fff 5150 case 2:
d75c135e 5151 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5153 rn = "SRSCtl";
5154 break;
7a387fff 5155 case 3:
d75c135e 5156 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5158 rn = "SRSMap";
fd88b6ab 5159 break;
7a387fff 5160 default:
f31b035a 5161 goto cp0_unimplemented;
7a387fff 5162 }
873eb012
TS
5163 break;
5164 case 13:
7a387fff
TS
5165 switch (sel) {
5166 case 0:
7db13fae 5167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5168 rn = "Cause";
5169 break;
7a387fff 5170 default:
f31b035a 5171 goto cp0_unimplemented;
7a387fff 5172 }
873eb012
TS
5173 break;
5174 case 14:
7a387fff
TS
5175 switch (sel) {
5176 case 0:
7db13fae 5177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5178 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5179 rn = "EPC";
5180 break;
7a387fff 5181 default:
f31b035a 5182 goto cp0_unimplemented;
1579a72e 5183 }
873eb012
TS
5184 break;
5185 case 15:
7a387fff
TS
5186 switch (sel) {
5187 case 0:
7db13fae 5188 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5189 rn = "PRid";
5190 break;
7a387fff 5191 case 1:
d75c135e 5192 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5194 rn = "EBase";
5195 break;
7a387fff 5196 default:
f31b035a 5197 goto cp0_unimplemented;
7a387fff 5198 }
873eb012
TS
5199 break;
5200 case 16:
5201 switch (sel) {
5202 case 0:
7db13fae 5203 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5204 rn = "Config";
5205 break;
5206 case 1:
7db13fae 5207 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5208 rn = "Config1";
5209 break;
7a387fff 5210 case 2:
7db13fae 5211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5212 rn = "Config2";
5213 break;
5214 case 3:
7db13fae 5215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5216 rn = "Config3";
5217 break;
b4160af1
PJ
5218 case 4:
5219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5220 rn = "Config4";
5221 break;
b4dd99a3
PJ
5222 case 5:
5223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5224 rn = "Config5";
5225 break;
e397ee33
TS
5226 /* 6,7 are implementation dependent */
5227 case 6:
7db13fae 5228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5229 rn = "Config6";
5230 break;
5231 case 7:
7db13fae 5232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5233 rn = "Config7";
5234 break;
873eb012 5235 default:
f31b035a 5236 goto cp0_unimplemented;
873eb012
TS
5237 }
5238 break;
5239 case 17:
7a387fff
TS
5240 switch (sel) {
5241 case 0:
895c2d04 5242 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5243 rn = "LLAddr";
5244 break;
7a387fff 5245 default:
f31b035a 5246 goto cp0_unimplemented;
7a387fff 5247 }
873eb012
TS
5248 break;
5249 case 18:
7a387fff 5250 switch (sel) {
fd88b6ab 5251 case 0 ... 7:
895c2d04 5252 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5253 rn = "WatchLo";
5254 break;
7a387fff 5255 default:
f31b035a 5256 goto cp0_unimplemented;
7a387fff 5257 }
873eb012
TS
5258 break;
5259 case 19:
7a387fff 5260 switch (sel) {
fd88b6ab 5261 case 0 ...7:
895c2d04 5262 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5263 rn = "WatchHi";
5264 break;
7a387fff 5265 default:
f31b035a 5266 goto cp0_unimplemented;
7a387fff 5267 }
873eb012 5268 break;
8c0fdd85 5269 case 20:
7a387fff
TS
5270 switch (sel) {
5271 case 0:
d26bc211 5272#if defined(TARGET_MIPS64)
d75c135e 5273 check_insn(ctx, ISA_MIPS3);
7db13fae 5274 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5275 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5276 rn = "XContext";
5277 break;
703eaf37 5278#endif
7a387fff 5279 default:
f31b035a 5280 goto cp0_unimplemented;
7a387fff 5281 }
8c0fdd85
TS
5282 break;
5283 case 21:
7a387fff 5284 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5285 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5286 switch (sel) {
5287 case 0:
7db13fae 5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5289 rn = "Framemask";
5290 break;
7a387fff 5291 default:
f31b035a 5292 goto cp0_unimplemented;
7a387fff 5293 }
8c0fdd85
TS
5294 break;
5295 case 22:
d9bea114 5296 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5297 rn = "'Diagnostic"; /* implementation dependent */
5298 break;
873eb012 5299 case 23:
7a387fff
TS
5300 switch (sel) {
5301 case 0:
895c2d04 5302 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5303 rn = "Debug";
5304 break;
7a387fff 5305 case 1:
d9bea114 5306// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5307 rn = "TraceControl";
5308// break;
7a387fff 5309 case 2:
d9bea114 5310// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5311 rn = "TraceControl2";
5312// break;
7a387fff 5313 case 3:
d9bea114 5314// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5315 rn = "UserTraceData";
5316// break;
7a387fff 5317 case 4:
d9bea114 5318// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5319 rn = "TraceBPC";
5320// break;
7a387fff 5321 default:
f31b035a 5322 goto cp0_unimplemented;
7a387fff 5323 }
873eb012
TS
5324 break;
5325 case 24:
7a387fff
TS
5326 switch (sel) {
5327 case 0:
f0b3f3ae 5328 /* EJTAG support */
7db13fae 5329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5330 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5331 rn = "DEPC";
5332 break;
7a387fff 5333 default:
f31b035a 5334 goto cp0_unimplemented;
7a387fff 5335 }
873eb012 5336 break;
8c0fdd85 5337 case 25:
7a387fff
TS
5338 switch (sel) {
5339 case 0:
7db13fae 5340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5341 rn = "Performance0";
7a387fff
TS
5342 break;
5343 case 1:
d9bea114 5344// gen_helper_mfc0_performance1(arg);
2423f660
TS
5345 rn = "Performance1";
5346// break;
7a387fff 5347 case 2:
d9bea114 5348// gen_helper_mfc0_performance2(arg);
2423f660
TS
5349 rn = "Performance2";
5350// break;
7a387fff 5351 case 3:
d9bea114 5352// gen_helper_mfc0_performance3(arg);
2423f660
TS
5353 rn = "Performance3";
5354// break;
7a387fff 5355 case 4:
d9bea114 5356// gen_helper_mfc0_performance4(arg);
2423f660
TS
5357 rn = "Performance4";
5358// break;
7a387fff 5359 case 5:
d9bea114 5360// gen_helper_mfc0_performance5(arg);
2423f660
TS
5361 rn = "Performance5";
5362// break;
7a387fff 5363 case 6:
d9bea114 5364// gen_helper_mfc0_performance6(arg);
2423f660
TS
5365 rn = "Performance6";
5366// break;
7a387fff 5367 case 7:
d9bea114 5368// gen_helper_mfc0_performance7(arg);
2423f660
TS
5369 rn = "Performance7";
5370// break;
7a387fff 5371 default:
f31b035a 5372 goto cp0_unimplemented;
7a387fff 5373 }
8c0fdd85
TS
5374 break;
5375 case 26:
d9bea114 5376 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5377 rn = "ECC";
5378 break;
8c0fdd85 5379 case 27:
7a387fff 5380 switch (sel) {
7a387fff 5381 case 0 ... 3:
d9bea114 5382 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5383 rn = "CacheErr";
5384 break;
7a387fff 5385 default:
f31b035a 5386 goto cp0_unimplemented;
7a387fff 5387 }
8c0fdd85 5388 break;
873eb012
TS
5389 case 28:
5390 switch (sel) {
5391 case 0:
7a387fff
TS
5392 case 2:
5393 case 4:
5394 case 6:
7db13fae 5395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5396 rn = "TagLo";
5397 break;
5398 case 1:
7a387fff
TS
5399 case 3:
5400 case 5:
5401 case 7:
7db13fae 5402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5403 rn = "DataLo";
5404 break;
5405 default:
f31b035a 5406 goto cp0_unimplemented;
873eb012
TS
5407 }
5408 break;
8c0fdd85 5409 case 29:
7a387fff
TS
5410 switch (sel) {
5411 case 0:
5412 case 2:
5413 case 4:
5414 case 6:
7db13fae 5415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5416 rn = "TagHi";
5417 break;
5418 case 1:
5419 case 3:
5420 case 5:
5421 case 7:
7db13fae 5422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5423 rn = "DataHi";
5424 break;
5425 default:
f31b035a 5426 goto cp0_unimplemented;
7a387fff 5427 }
8c0fdd85 5428 break;
873eb012 5429 case 30:
7a387fff
TS
5430 switch (sel) {
5431 case 0:
7db13fae 5432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5433 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5434 rn = "ErrorEPC";
5435 break;
7a387fff 5436 default:
f31b035a 5437 goto cp0_unimplemented;
7a387fff 5438 }
873eb012
TS
5439 break;
5440 case 31:
7a387fff
TS
5441 switch (sel) {
5442 case 0:
f0b3f3ae 5443 /* EJTAG support */
7db13fae 5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5445 rn = "DESAVE";
5446 break;
e98c0d17 5447 case 2 ... 7:
f31b035a
LA
5448 CP0_CHECK(ctx->kscrexist & (1 << sel));
5449 tcg_gen_ld_tl(arg, cpu_env,
5450 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5451 tcg_gen_ext32s_tl(arg, arg);
5452 rn = "KScratch";
e98c0d17 5453 break;
7a387fff 5454 default:
f31b035a 5455 goto cp0_unimplemented;
7a387fff 5456 }
873eb012
TS
5457 break;
5458 default:
f31b035a 5459 goto cp0_unimplemented;
873eb012 5460 }
2abf314d 5461 (void)rn; /* avoid a compiler warning */
d12d51d5 5462 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5463 return;
5464
f31b035a 5465cp0_unimplemented:
d12d51d5 5466 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5467 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5468}
5469
d75c135e 5470static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5471{
7a387fff
TS
5472 const char *rn = "invalid";
5473
e189e748 5474 if (sel != 0)
d75c135e 5475 check_insn(ctx, ISA_MIPS32);
e189e748 5476
2e70f6ef
PB
5477 if (use_icount)
5478 gen_io_start();
5479
8c0fdd85
TS
5480 switch (reg) {
5481 case 0:
7a387fff
TS
5482 switch (sel) {
5483 case 0:
895c2d04 5484 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5485 rn = "Index";
5486 break;
5487 case 1:
f31b035a 5488 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5489 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5490 rn = "MVPControl";
ead9360e 5491 break;
7a387fff 5492 case 2:
f31b035a 5493 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5494 /* ignored */
7a387fff 5495 rn = "MVPConf0";
ead9360e 5496 break;
7a387fff 5497 case 3:
f31b035a 5498 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5499 /* ignored */
7a387fff 5500 rn = "MVPConf1";
ead9360e 5501 break;
7a387fff 5502 default:
f31b035a 5503 goto cp0_unimplemented;
7a387fff 5504 }
8c0fdd85
TS
5505 break;
5506 case 1:
7a387fff
TS
5507 switch (sel) {
5508 case 0:
2423f660 5509 /* ignored */
7a387fff 5510 rn = "Random";
2423f660 5511 break;
7a387fff 5512 case 1:
f31b035a 5513 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5514 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5515 rn = "VPEControl";
ead9360e 5516 break;
7a387fff 5517 case 2:
f31b035a 5518 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5519 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5520 rn = "VPEConf0";
ead9360e 5521 break;
7a387fff 5522 case 3:
f31b035a 5523 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5524 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5525 rn = "VPEConf1";
ead9360e 5526 break;
7a387fff 5527 case 4:
f31b035a 5528 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5529 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5530 rn = "YQMask";
ead9360e 5531 break;
7a387fff 5532 case 5:
f31b035a 5533 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5534 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5535 rn = "VPESchedule";
ead9360e 5536 break;
7a387fff 5537 case 6:
f31b035a 5538 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5539 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5540 rn = "VPEScheFBack";
ead9360e 5541 break;
7a387fff 5542 case 7:
f31b035a 5543 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5544 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5545 rn = "VPEOpt";
ead9360e 5546 break;
7a387fff 5547 default:
f31b035a 5548 goto cp0_unimplemented;
7a387fff 5549 }
8c0fdd85
TS
5550 break;
5551 case 2:
7a387fff
TS
5552 switch (sel) {
5553 case 0:
895c2d04 5554 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5555 rn = "EntryLo0";
5556 break;
7a387fff 5557 case 1:
f31b035a 5558 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5559 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5560 rn = "TCStatus";
ead9360e 5561 break;
7a387fff 5562 case 2:
f31b035a 5563 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5564 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5565 rn = "TCBind";
ead9360e 5566 break;
7a387fff 5567 case 3:
f31b035a 5568 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5569 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5570 rn = "TCRestart";
ead9360e 5571 break;
7a387fff 5572 case 4:
f31b035a 5573 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5574 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5575 rn = "TCHalt";
ead9360e 5576 break;
7a387fff 5577 case 5:
f31b035a 5578 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5579 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5580 rn = "TCContext";
ead9360e 5581 break;
7a387fff 5582 case 6:
f31b035a 5583 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5584 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5585 rn = "TCSchedule";
ead9360e 5586 break;
7a387fff 5587 case 7:
f31b035a 5588 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5589 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5590 rn = "TCScheFBack";
ead9360e 5591 break;
7a387fff 5592 default:
f31b035a 5593 goto cp0_unimplemented;
7a387fff 5594 }
8c0fdd85
TS
5595 break;
5596 case 3:
7a387fff
TS
5597 switch (sel) {
5598 case 0:
895c2d04 5599 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5600 rn = "EntryLo1";
5601 break;
7a387fff 5602 default:
f31b035a 5603 goto cp0_unimplemented;
876d4b07 5604 }
8c0fdd85
TS
5605 break;
5606 case 4:
7a387fff
TS
5607 switch (sel) {
5608 case 0:
895c2d04 5609 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5610 rn = "Context";
5611 break;
7a387fff 5612 case 1:
895c2d04 5613// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5614 rn = "ContextConfig";
f31b035a 5615 goto cp0_unimplemented;
2423f660 5616// break;
d279279e 5617 case 2:
f31b035a
LA
5618 CP0_CHECK(ctx->ulri);
5619 tcg_gen_st_tl(arg, cpu_env,
5620 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5621 rn = "UserLocal";
d279279e 5622 break;
7a387fff 5623 default:
f31b035a 5624 goto cp0_unimplemented;
876d4b07 5625 }
8c0fdd85
TS
5626 break;
5627 case 5:
7a387fff
TS
5628 switch (sel) {
5629 case 0:
895c2d04 5630 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5631 rn = "PageMask";
5632 break;
7a387fff 5633 case 1:
d75c135e 5634 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5635 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5636 rn = "PageGrain";
5637 break;
7a387fff 5638 default:
f31b035a 5639 goto cp0_unimplemented;
876d4b07 5640 }
8c0fdd85
TS
5641 break;
5642 case 6:
7a387fff
TS
5643 switch (sel) {
5644 case 0:
895c2d04 5645 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5646 rn = "Wired";
5647 break;
7a387fff 5648 case 1:
d75c135e 5649 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5650 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5651 rn = "SRSConf0";
ead9360e 5652 break;
7a387fff 5653 case 2:
d75c135e 5654 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5655 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5656 rn = "SRSConf1";
ead9360e 5657 break;
7a387fff 5658 case 3:
d75c135e 5659 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5660 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5661 rn = "SRSConf2";
ead9360e 5662 break;
7a387fff 5663 case 4:
d75c135e 5664 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5665 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5666 rn = "SRSConf3";
ead9360e 5667 break;
7a387fff 5668 case 5:
d75c135e 5669 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5670 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5671 rn = "SRSConf4";
ead9360e 5672 break;
7a387fff 5673 default:
f31b035a 5674 goto cp0_unimplemented;
876d4b07 5675 }
8c0fdd85
TS
5676 break;
5677 case 7:
7a387fff
TS
5678 switch (sel) {
5679 case 0:
d75c135e 5680 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5681 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5682 ctx->bstate = BS_STOP;
2423f660
TS
5683 rn = "HWREna";
5684 break;
7a387fff 5685 default:
f31b035a 5686 goto cp0_unimplemented;
876d4b07 5687 }
8c0fdd85
TS
5688 break;
5689 case 8:
aea14095
LA
5690 switch (sel) {
5691 case 0:
5692 /* ignored */
5693 rn = "BadVAddr";
5694 break;
5695 case 1:
5696 /* ignored */
5697 rn = "BadInstr";
5698 break;
5699 case 2:
5700 /* ignored */
5701 rn = "BadInstrP";
5702 break;
5703 default:
f31b035a 5704 goto cp0_unimplemented;
aea14095 5705 }
8c0fdd85
TS
5706 break;
5707 case 9:
7a387fff
TS
5708 switch (sel) {
5709 case 0:
895c2d04 5710 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5711 rn = "Count";
5712 break;
876d4b07 5713 /* 6,7 are implementation dependent */
7a387fff 5714 default:
f31b035a 5715 goto cp0_unimplemented;
876d4b07 5716 }
8c0fdd85
TS
5717 break;
5718 case 10:
7a387fff
TS
5719 switch (sel) {
5720 case 0:
895c2d04 5721 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5722 rn = "EntryHi";
5723 break;
7a387fff 5724 default:
f31b035a 5725 goto cp0_unimplemented;
876d4b07 5726 }
8c0fdd85
TS
5727 break;
5728 case 11:
7a387fff
TS
5729 switch (sel) {
5730 case 0:
895c2d04 5731 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5732 rn = "Compare";
5733 break;
5734 /* 6,7 are implementation dependent */
7a387fff 5735 default:
f31b035a 5736 goto cp0_unimplemented;
876d4b07 5737 }
8c0fdd85
TS
5738 break;
5739 case 12:
7a387fff
TS
5740 switch (sel) {
5741 case 0:
867abc7e 5742 save_cpu_state(ctx, 1);
895c2d04 5743 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5744 /* BS_STOP isn't good enough here, hflags may have changed. */
5745 gen_save_pc(ctx->pc + 4);
5746 ctx->bstate = BS_EXCP;
2423f660
TS
5747 rn = "Status";
5748 break;
7a387fff 5749 case 1:
d75c135e 5750 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5751 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5752 /* Stop translation as we may have switched the execution mode */
5753 ctx->bstate = BS_STOP;
2423f660
TS
5754 rn = "IntCtl";
5755 break;
7a387fff 5756 case 2:
d75c135e 5757 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5758 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5759 /* Stop translation as we may have switched the execution mode */
5760 ctx->bstate = BS_STOP;
2423f660
TS
5761 rn = "SRSCtl";
5762 break;
7a387fff 5763 case 3:
d75c135e 5764 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5765 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5766 /* Stop translation as we may have switched the execution mode */
5767 ctx->bstate = BS_STOP;
2423f660 5768 rn = "SRSMap";
fd88b6ab 5769 break;
7a387fff 5770 default:
f31b035a 5771 goto cp0_unimplemented;
876d4b07 5772 }
8c0fdd85
TS
5773 break;
5774 case 13:
7a387fff
TS
5775 switch (sel) {
5776 case 0:
867abc7e 5777 save_cpu_state(ctx, 1);
895c2d04 5778 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5779 rn = "Cause";
5780 break;
7a387fff 5781 default:
f31b035a 5782 goto cp0_unimplemented;
876d4b07 5783 }
8c0fdd85
TS
5784 break;
5785 case 14:
7a387fff
TS
5786 switch (sel) {
5787 case 0:
7db13fae 5788 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5789 rn = "EPC";
5790 break;
7a387fff 5791 default:
f31b035a 5792 goto cp0_unimplemented;
876d4b07 5793 }
8c0fdd85
TS
5794 break;
5795 case 15:
7a387fff
TS
5796 switch (sel) {
5797 case 0:
2423f660
TS
5798 /* ignored */
5799 rn = "PRid";
5800 break;
7a387fff 5801 case 1:
d75c135e 5802 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5803 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5804 rn = "EBase";
5805 break;
7a387fff 5806 default:
f31b035a 5807 goto cp0_unimplemented;
1579a72e 5808 }
8c0fdd85
TS
5809 break;
5810 case 16:
5811 switch (sel) {
5812 case 0:
895c2d04 5813 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5814 rn = "Config";
2423f660
TS
5815 /* Stop translation as we may have switched the execution mode */
5816 ctx->bstate = BS_STOP;
7a387fff
TS
5817 break;
5818 case 1:
e397ee33 5819 /* ignored, read only */
7a387fff
TS
5820 rn = "Config1";
5821 break;
5822 case 2:
895c2d04 5823 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5824 rn = "Config2";
2423f660
TS
5825 /* Stop translation as we may have switched the execution mode */
5826 ctx->bstate = BS_STOP;
8c0fdd85 5827 break;
7a387fff 5828 case 3:
e397ee33 5829 /* ignored, read only */
7a387fff
TS
5830 rn = "Config3";
5831 break;
b4160af1
PJ
5832 case 4:
5833 gen_helper_mtc0_config4(cpu_env, arg);
5834 rn = "Config4";
5835 ctx->bstate = BS_STOP;
5836 break;
b4dd99a3
PJ
5837 case 5:
5838 gen_helper_mtc0_config5(cpu_env, arg);
5839 rn = "Config5";
5840 /* Stop translation as we may have switched the execution mode */
5841 ctx->bstate = BS_STOP;
5842 break;
e397ee33
TS
5843 /* 6,7 are implementation dependent */
5844 case 6:
5845 /* ignored */
5846 rn = "Config6";
5847 break;
5848 case 7:
5849 /* ignored */
5850 rn = "Config7";
5851 break;
8c0fdd85
TS
5852 default:
5853 rn = "Invalid config selector";
f31b035a 5854 goto cp0_unimplemented;
8c0fdd85
TS
5855 }
5856 break;
5857 case 17:
7a387fff
TS
5858 switch (sel) {
5859 case 0:
895c2d04 5860 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5861 rn = "LLAddr";
5862 break;
7a387fff 5863 default:
f31b035a 5864 goto cp0_unimplemented;
7a387fff 5865 }
8c0fdd85
TS
5866 break;
5867 case 18:
7a387fff 5868 switch (sel) {
fd88b6ab 5869 case 0 ... 7:
895c2d04 5870 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5871 rn = "WatchLo";
5872 break;
7a387fff 5873 default:
f31b035a 5874 goto cp0_unimplemented;
7a387fff 5875 }
8c0fdd85
TS
5876 break;
5877 case 19:
7a387fff 5878 switch (sel) {
fd88b6ab 5879 case 0 ... 7:
895c2d04 5880 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5881 rn = "WatchHi";
5882 break;
7a387fff 5883 default:
f31b035a 5884 goto cp0_unimplemented;
7a387fff 5885 }
8c0fdd85
TS
5886 break;
5887 case 20:
7a387fff
TS
5888 switch (sel) {
5889 case 0:
d26bc211 5890#if defined(TARGET_MIPS64)
d75c135e 5891 check_insn(ctx, ISA_MIPS3);
895c2d04 5892 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5893 rn = "XContext";
5894 break;
703eaf37 5895#endif
7a387fff 5896 default:
f31b035a 5897 goto cp0_unimplemented;
7a387fff 5898 }
8c0fdd85
TS
5899 break;
5900 case 21:
7a387fff 5901 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5902 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5903 switch (sel) {
5904 case 0:
895c2d04 5905 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5906 rn = "Framemask";
5907 break;
7a387fff 5908 default:
f31b035a 5909 goto cp0_unimplemented;
7a387fff
TS
5910 }
5911 break;
8c0fdd85 5912 case 22:
7a387fff
TS
5913 /* ignored */
5914 rn = "Diagnostic"; /* implementation dependent */
2423f660 5915 break;
8c0fdd85 5916 case 23:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
895c2d04 5919 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5920 /* BS_STOP isn't good enough here, hflags may have changed. */
5921 gen_save_pc(ctx->pc + 4);
5922 ctx->bstate = BS_EXCP;
2423f660
TS
5923 rn = "Debug";
5924 break;
7a387fff 5925 case 1:
895c2d04 5926// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5927 rn = "TraceControl";
8487327a
TS
5928 /* Stop translation as we may have switched the execution mode */
5929 ctx->bstate = BS_STOP;
2423f660 5930// break;
7a387fff 5931 case 2:
895c2d04 5932// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5933 rn = "TraceControl2";
8487327a
TS
5934 /* Stop translation as we may have switched the execution mode */
5935 ctx->bstate = BS_STOP;
2423f660 5936// break;
7a387fff 5937 case 3:
8487327a
TS
5938 /* Stop translation as we may have switched the execution mode */
5939 ctx->bstate = BS_STOP;
895c2d04 5940// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5941 rn = "UserTraceData";
8487327a
TS
5942 /* Stop translation as we may have switched the execution mode */
5943 ctx->bstate = BS_STOP;
2423f660 5944// break;
7a387fff 5945 case 4:
895c2d04 5946// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5947 /* Stop translation as we may have switched the execution mode */
5948 ctx->bstate = BS_STOP;
2423f660
TS
5949 rn = "TraceBPC";
5950// break;
7a387fff 5951 default:
f31b035a 5952 goto cp0_unimplemented;
7a387fff 5953 }
8c0fdd85
TS
5954 break;
5955 case 24:
7a387fff
TS
5956 switch (sel) {
5957 case 0:
f1aa6320 5958 /* EJTAG support */
7db13fae 5959 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5960 rn = "DEPC";
5961 break;
7a387fff 5962 default:
f31b035a 5963 goto cp0_unimplemented;
7a387fff 5964 }
8c0fdd85
TS
5965 break;
5966 case 25:
7a387fff
TS
5967 switch (sel) {
5968 case 0:
895c2d04 5969 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5970 rn = "Performance0";
5971 break;
7a387fff 5972 case 1:
d9bea114 5973// gen_helper_mtc0_performance1(arg);
2423f660
TS
5974 rn = "Performance1";
5975// break;
7a387fff 5976 case 2:
d9bea114 5977// gen_helper_mtc0_performance2(arg);
2423f660
TS
5978 rn = "Performance2";
5979// break;
7a387fff 5980 case 3:
d9bea114 5981// gen_helper_mtc0_performance3(arg);
2423f660
TS
5982 rn = "Performance3";
5983// break;
7a387fff 5984 case 4:
d9bea114 5985// gen_helper_mtc0_performance4(arg);
2423f660
TS
5986 rn = "Performance4";
5987// break;
7a387fff 5988 case 5:
d9bea114 5989// gen_helper_mtc0_performance5(arg);
2423f660
TS
5990 rn = "Performance5";
5991// break;
7a387fff 5992 case 6:
d9bea114 5993// gen_helper_mtc0_performance6(arg);
2423f660
TS
5994 rn = "Performance6";
5995// break;
7a387fff 5996 case 7:
d9bea114 5997// gen_helper_mtc0_performance7(arg);
2423f660
TS
5998 rn = "Performance7";
5999// break;
7a387fff 6000 default:
f31b035a 6001 goto cp0_unimplemented;
7a387fff 6002 }
8c0fdd85
TS
6003 break;
6004 case 26:
2423f660 6005 /* ignored */
8c0fdd85 6006 rn = "ECC";
2423f660 6007 break;
8c0fdd85 6008 case 27:
7a387fff
TS
6009 switch (sel) {
6010 case 0 ... 3:
2423f660
TS
6011 /* ignored */
6012 rn = "CacheErr";
6013 break;
7a387fff 6014 default:
f31b035a 6015 goto cp0_unimplemented;
7a387fff 6016 }
8c0fdd85
TS
6017 break;
6018 case 28:
6019 switch (sel) {
6020 case 0:
7a387fff
TS
6021 case 2:
6022 case 4:
6023 case 6:
895c2d04 6024 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6025 rn = "TagLo";
6026 break;
7a387fff
TS
6027 case 1:
6028 case 3:
6029 case 5:
6030 case 7:
895c2d04 6031 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6032 rn = "DataLo";
6033 break;
8c0fdd85 6034 default:
f31b035a 6035 goto cp0_unimplemented;
8c0fdd85
TS
6036 }
6037 break;
6038 case 29:
7a387fff
TS
6039 switch (sel) {
6040 case 0:
6041 case 2:
6042 case 4:
6043 case 6:
895c2d04 6044 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6045 rn = "TagHi";
6046 break;
6047 case 1:
6048 case 3:
6049 case 5:
6050 case 7:
895c2d04 6051 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6052 rn = "DataHi";
6053 break;
6054 default:
6055 rn = "invalid sel";
f31b035a 6056 goto cp0_unimplemented;
7a387fff 6057 }
8c0fdd85
TS
6058 break;
6059 case 30:
7a387fff
TS
6060 switch (sel) {
6061 case 0:
7db13fae 6062 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6063 rn = "ErrorEPC";
6064 break;
7a387fff 6065 default:
f31b035a 6066 goto cp0_unimplemented;
7a387fff 6067 }
8c0fdd85
TS
6068 break;
6069 case 31:
7a387fff
TS
6070 switch (sel) {
6071 case 0:
f1aa6320 6072 /* EJTAG support */
7db13fae 6073 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6074 rn = "DESAVE";
6075 break;
e98c0d17 6076 case 2 ... 7:
f31b035a
LA
6077 CP0_CHECK(ctx->kscrexist & (1 << sel));
6078 tcg_gen_st_tl(arg, cpu_env,
6079 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6080 rn = "KScratch";
e98c0d17 6081 break;
7a387fff 6082 default:
f31b035a 6083 goto cp0_unimplemented;
7a387fff 6084 }
2423f660
TS
6085 /* Stop translation as we may have switched the execution mode */
6086 ctx->bstate = BS_STOP;
8c0fdd85
TS
6087 break;
6088 default:
f31b035a 6089 goto cp0_unimplemented;
8c0fdd85 6090 }
2abf314d 6091 (void)rn; /* avoid a compiler warning */
d12d51d5 6092 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6093 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6094 if (use_icount) {
6095 gen_io_end();
6096 ctx->bstate = BS_STOP;
6097 }
8c0fdd85
TS
6098 return;
6099
f31b035a 6100cp0_unimplemented:
d12d51d5 6101 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6102}
6103
d26bc211 6104#if defined(TARGET_MIPS64)
d75c135e 6105static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6106{
6107 const char *rn = "invalid";
6108
e189e748 6109 if (sel != 0)
d75c135e 6110 check_insn(ctx, ISA_MIPS64);
e189e748 6111
9c2149c8
TS
6112 switch (reg) {
6113 case 0:
6114 switch (sel) {
6115 case 0:
7db13fae 6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6117 rn = "Index";
6118 break;
6119 case 1:
f31b035a 6120 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6121 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6122 rn = "MVPControl";
ead9360e 6123 break;
9c2149c8 6124 case 2:
f31b035a 6125 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6126 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6127 rn = "MVPConf0";
ead9360e 6128 break;
9c2149c8 6129 case 3:
f31b035a 6130 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6131 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6132 rn = "MVPConf1";
ead9360e 6133 break;
9c2149c8 6134 default:
f31b035a 6135 goto cp0_unimplemented;
9c2149c8
TS
6136 }
6137 break;
6138 case 1:
6139 switch (sel) {
6140 case 0:
f31b035a 6141 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6142 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6143 rn = "Random";
2423f660 6144 break;
9c2149c8 6145 case 1:
f31b035a 6146 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6148 rn = "VPEControl";
ead9360e 6149 break;
9c2149c8 6150 case 2:
f31b035a 6151 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6153 rn = "VPEConf0";
ead9360e 6154 break;
9c2149c8 6155 case 3:
f31b035a 6156 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6158 rn = "VPEConf1";
ead9360e 6159 break;
9c2149c8 6160 case 4:
f31b035a 6161 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6162 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6163 rn = "YQMask";
ead9360e 6164 break;
9c2149c8 6165 case 5:
f31b035a 6166 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6167 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6168 rn = "VPESchedule";
ead9360e 6169 break;
9c2149c8 6170 case 6:
f31b035a 6171 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6172 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6173 rn = "VPEScheFBack";
ead9360e 6174 break;
9c2149c8 6175 case 7:
f31b035a 6176 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6178 rn = "VPEOpt";
ead9360e 6179 break;
9c2149c8 6180 default:
f31b035a 6181 goto cp0_unimplemented;
9c2149c8
TS
6182 }
6183 break;
6184 case 2:
6185 switch (sel) {
6186 case 0:
7db13fae 6187 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6188 rn = "EntryLo0";
6189 break;
9c2149c8 6190 case 1:
f31b035a 6191 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6192 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6193 rn = "TCStatus";
ead9360e 6194 break;
9c2149c8 6195 case 2:
f31b035a 6196 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6197 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6198 rn = "TCBind";
ead9360e 6199 break;
9c2149c8 6200 case 3:
f31b035a 6201 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6202 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6203 rn = "TCRestart";
ead9360e 6204 break;
9c2149c8 6205 case 4:
f31b035a 6206 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6207 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6208 rn = "TCHalt";
ead9360e 6209 break;
9c2149c8 6210 case 5:
f31b035a 6211 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6212 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6213 rn = "TCContext";
ead9360e 6214 break;
9c2149c8 6215 case 6:
f31b035a 6216 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6217 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6218 rn = "TCSchedule";
ead9360e 6219 break;
9c2149c8 6220 case 7:
f31b035a 6221 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6222 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6223 rn = "TCScheFBack";
ead9360e 6224 break;
9c2149c8 6225 default:
f31b035a 6226 goto cp0_unimplemented;
9c2149c8
TS
6227 }
6228 break;
6229 case 3:
6230 switch (sel) {
6231 case 0:
7db13fae 6232 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6233 rn = "EntryLo1";
6234 break;
9c2149c8 6235 default:
f31b035a 6236 goto cp0_unimplemented;
1579a72e 6237 }
9c2149c8
TS
6238 break;
6239 case 4:
6240 switch (sel) {
6241 case 0:
7db13fae 6242 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6243 rn = "Context";
6244 break;
9c2149c8 6245 case 1:
d9bea114 6246// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6247 rn = "ContextConfig";
f31b035a 6248 goto cp0_unimplemented;
2423f660 6249// break;
d279279e 6250 case 2:
f31b035a
LA
6251 CP0_CHECK(ctx->ulri);
6252 tcg_gen_ld_tl(arg, cpu_env,
6253 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6254 rn = "UserLocal";
d279279e 6255 break;
9c2149c8 6256 default:
f31b035a 6257 goto cp0_unimplemented;
876d4b07 6258 }
9c2149c8
TS
6259 break;
6260 case 5:
6261 switch (sel) {
6262 case 0:
7db13fae 6263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6264 rn = "PageMask";
6265 break;
9c2149c8 6266 case 1:
d75c135e 6267 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6269 rn = "PageGrain";
6270 break;
9c2149c8 6271 default:
f31b035a 6272 goto cp0_unimplemented;
876d4b07 6273 }
9c2149c8
TS
6274 break;
6275 case 6:
6276 switch (sel) {
6277 case 0:
7db13fae 6278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6279 rn = "Wired";
6280 break;
9c2149c8 6281 case 1:
d75c135e 6282 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6284 rn = "SRSConf0";
ead9360e 6285 break;
9c2149c8 6286 case 2:
d75c135e 6287 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6289 rn = "SRSConf1";
ead9360e 6290 break;
9c2149c8 6291 case 3:
d75c135e 6292 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6294 rn = "SRSConf2";
ead9360e 6295 break;
9c2149c8 6296 case 4:
d75c135e 6297 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6299 rn = "SRSConf3";
ead9360e 6300 break;
9c2149c8 6301 case 5:
d75c135e 6302 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6304 rn = "SRSConf4";
ead9360e 6305 break;
9c2149c8 6306 default:
f31b035a 6307 goto cp0_unimplemented;
876d4b07 6308 }
9c2149c8
TS
6309 break;
6310 case 7:
6311 switch (sel) {
6312 case 0:
d75c135e 6313 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6315 rn = "HWREna";
6316 break;
9c2149c8 6317 default:
f31b035a 6318 goto cp0_unimplemented;
876d4b07 6319 }
9c2149c8
TS
6320 break;
6321 case 8:
6322 switch (sel) {
6323 case 0:
7db13fae 6324 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6325 rn = "BadVAddr";
2423f660 6326 break;
aea14095 6327 case 1:
f31b035a
LA
6328 CP0_CHECK(ctx->bi);
6329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6330 rn = "BadInstr";
aea14095
LA
6331 break;
6332 case 2:
f31b035a
LA
6333 CP0_CHECK(ctx->bp);
6334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6335 rn = "BadInstrP";
aea14095 6336 break;
9c2149c8 6337 default:
f31b035a 6338 goto cp0_unimplemented;
876d4b07 6339 }
9c2149c8
TS
6340 break;
6341 case 9:
6342 switch (sel) {
6343 case 0:
2e70f6ef
PB
6344 /* Mark as an IO operation because we read the time. */
6345 if (use_icount)
6346 gen_io_start();
895c2d04 6347 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
6348 if (use_icount) {
6349 gen_io_end();
2e70f6ef 6350 }
55807224
EI
6351 /* Break the TB to be able to take timer interrupts immediately
6352 after reading count. */
6353 ctx->bstate = BS_STOP;
2423f660
TS
6354 rn = "Count";
6355 break;
6356 /* 6,7 are implementation dependent */
9c2149c8 6357 default:
f31b035a 6358 goto cp0_unimplemented;
876d4b07 6359 }
9c2149c8
TS
6360 break;
6361 case 10:
6362 switch (sel) {
6363 case 0:
7db13fae 6364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6365 rn = "EntryHi";
6366 break;
9c2149c8 6367 default:
f31b035a 6368 goto cp0_unimplemented;
876d4b07 6369 }
9c2149c8
TS
6370 break;
6371 case 11:
6372 switch (sel) {
6373 case 0:
7db13fae 6374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6375 rn = "Compare";
6376 break;
876d4b07 6377 /* 6,7 are implementation dependent */
9c2149c8 6378 default:
f31b035a 6379 goto cp0_unimplemented;
876d4b07 6380 }
9c2149c8
TS
6381 break;
6382 case 12:
6383 switch (sel) {
6384 case 0:
7db13fae 6385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6386 rn = "Status";
6387 break;
9c2149c8 6388 case 1:
d75c135e 6389 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6391 rn = "IntCtl";
6392 break;
9c2149c8 6393 case 2:
d75c135e 6394 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6396 rn = "SRSCtl";
6397 break;
9c2149c8 6398 case 3:
d75c135e 6399 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6401 rn = "SRSMap";
6402 break;
9c2149c8 6403 default:
f31b035a 6404 goto cp0_unimplemented;
876d4b07 6405 }
9c2149c8
TS
6406 break;
6407 case 13:
6408 switch (sel) {
6409 case 0:
7db13fae 6410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6411 rn = "Cause";
6412 break;
9c2149c8 6413 default:
f31b035a 6414 goto cp0_unimplemented;
876d4b07 6415 }
9c2149c8
TS
6416 break;
6417 case 14:
6418 switch (sel) {
6419 case 0:
7db13fae 6420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6421 rn = "EPC";
6422 break;
9c2149c8 6423 default:
f31b035a 6424 goto cp0_unimplemented;
876d4b07 6425 }
9c2149c8
TS
6426 break;
6427 case 15:
6428 switch (sel) {
6429 case 0:
7db13fae 6430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6431 rn = "PRid";
6432 break;
9c2149c8 6433 case 1:
d75c135e 6434 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6436 rn = "EBase";
6437 break;
9c2149c8 6438 default:
f31b035a 6439 goto cp0_unimplemented;
876d4b07 6440 }
9c2149c8
TS
6441 break;
6442 case 16:
6443 switch (sel) {
6444 case 0:
7db13fae 6445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6446 rn = "Config";
6447 break;
6448 case 1:
7db13fae 6449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6450 rn = "Config1";
6451 break;
6452 case 2:
7db13fae 6453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6454 rn = "Config2";
6455 break;
6456 case 3:
7db13fae 6457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6458 rn = "Config3";
6459 break;
faf1f68b
LA
6460 case 4:
6461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6462 rn = "Config4";
6463 break;
6464 case 5:
6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6466 rn = "Config5";
6467 break;
9c2149c8 6468 /* 6,7 are implementation dependent */
f0b3f3ae 6469 case 6:
7db13fae 6470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6471 rn = "Config6";
6472 break;
6473 case 7:
7db13fae 6474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6475 rn = "Config7";
6476 break;
9c2149c8 6477 default:
f31b035a 6478 goto cp0_unimplemented;
9c2149c8
TS
6479 }
6480 break;
6481 case 17:
6482 switch (sel) {
6483 case 0:
895c2d04 6484 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6485 rn = "LLAddr";
6486 break;
9c2149c8 6487 default:
f31b035a 6488 goto cp0_unimplemented;
9c2149c8
TS
6489 }
6490 break;
6491 case 18:
6492 switch (sel) {
fd88b6ab 6493 case 0 ... 7:
895c2d04 6494 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6495 rn = "WatchLo";
6496 break;
9c2149c8 6497 default:
f31b035a 6498 goto cp0_unimplemented;
9c2149c8
TS
6499 }
6500 break;
6501 case 19:
6502 switch (sel) {
fd88b6ab 6503 case 0 ... 7:
895c2d04 6504 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6505 rn = "WatchHi";
6506 break;
9c2149c8 6507 default:
f31b035a 6508 goto cp0_unimplemented;
9c2149c8
TS
6509 }
6510 break;
6511 case 20:
6512 switch (sel) {
6513 case 0:
d75c135e 6514 check_insn(ctx, ISA_MIPS3);
7db13fae 6515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6516 rn = "XContext";
6517 break;
9c2149c8 6518 default:
f31b035a 6519 goto cp0_unimplemented;
9c2149c8
TS
6520 }
6521 break;
6522 case 21:
6523 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6524 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6525 switch (sel) {
6526 case 0:
7db13fae 6527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6528 rn = "Framemask";
6529 break;
9c2149c8 6530 default:
f31b035a 6531 goto cp0_unimplemented;
9c2149c8
TS
6532 }
6533 break;
6534 case 22:
d9bea114 6535 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6536 rn = "'Diagnostic"; /* implementation dependent */
6537 break;
9c2149c8
TS
6538 case 23:
6539 switch (sel) {
6540 case 0:
895c2d04 6541 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6542 rn = "Debug";
6543 break;
9c2149c8 6544 case 1:
895c2d04 6545// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6546 rn = "TraceControl";
6547// break;
9c2149c8 6548 case 2:
895c2d04 6549// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6550 rn = "TraceControl2";
6551// break;
9c2149c8 6552 case 3:
895c2d04 6553// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6554 rn = "UserTraceData";
6555// break;
9c2149c8 6556 case 4:
895c2d04 6557// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6558 rn = "TraceBPC";
6559// break;
9c2149c8 6560 default:
f31b035a 6561 goto cp0_unimplemented;
9c2149c8
TS
6562 }
6563 break;
6564 case 24:
6565 switch (sel) {
6566 case 0:
f0b3f3ae 6567 /* EJTAG support */
7db13fae 6568 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6569 rn = "DEPC";
6570 break;
9c2149c8 6571 default:
f31b035a 6572 goto cp0_unimplemented;
9c2149c8
TS
6573 }
6574 break;
6575 case 25:
6576 switch (sel) {
6577 case 0:
7db13fae 6578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6579 rn = "Performance0";
9c2149c8
TS
6580 break;
6581 case 1:
d9bea114 6582// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6583 rn = "Performance1";
6584// break;
9c2149c8 6585 case 2:
d9bea114 6586// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6587 rn = "Performance2";
6588// break;
9c2149c8 6589 case 3:
d9bea114 6590// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6591 rn = "Performance3";
6592// break;
9c2149c8 6593 case 4:
d9bea114 6594// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6595 rn = "Performance4";
6596// break;
9c2149c8 6597 case 5:
d9bea114 6598// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6599 rn = "Performance5";
6600// break;
9c2149c8 6601 case 6:
d9bea114 6602// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6603 rn = "Performance6";
6604// break;
9c2149c8 6605 case 7:
d9bea114 6606// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6607 rn = "Performance7";
6608// break;
9c2149c8 6609 default:
f31b035a 6610 goto cp0_unimplemented;
9c2149c8
TS
6611 }
6612 break;
6613 case 26:
d9bea114 6614 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6615 rn = "ECC";
6616 break;
9c2149c8
TS
6617 case 27:
6618 switch (sel) {
6619 /* ignored */
6620 case 0 ... 3:
d9bea114 6621 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6622 rn = "CacheErr";
6623 break;
9c2149c8 6624 default:
f31b035a 6625 goto cp0_unimplemented;
9c2149c8
TS
6626 }
6627 break;
6628 case 28:
6629 switch (sel) {
6630 case 0:
6631 case 2:
6632 case 4:
6633 case 6:
7db13fae 6634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6635 rn = "TagLo";
6636 break;
6637 case 1:
6638 case 3:
6639 case 5:
6640 case 7:
7db13fae 6641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6642 rn = "DataLo";
6643 break;
6644 default:
f31b035a 6645 goto cp0_unimplemented;
9c2149c8
TS
6646 }
6647 break;
6648 case 29:
6649 switch (sel) {
6650 case 0:
6651 case 2:
6652 case 4:
6653 case 6:
7db13fae 6654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6655 rn = "TagHi";
6656 break;
6657 case 1:
6658 case 3:
6659 case 5:
6660 case 7:
7db13fae 6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6662 rn = "DataHi";
6663 break;
6664 default:
f31b035a 6665 goto cp0_unimplemented;
9c2149c8
TS
6666 }
6667 break;
6668 case 30:
6669 switch (sel) {
6670 case 0:
7db13fae 6671 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6672 rn = "ErrorEPC";
6673 break;
9c2149c8 6674 default:
f31b035a 6675 goto cp0_unimplemented;
9c2149c8
TS
6676 }
6677 break;
6678 case 31:
6679 switch (sel) {
6680 case 0:
f0b3f3ae 6681 /* EJTAG support */
7db13fae 6682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6683 rn = "DESAVE";
6684 break;
e98c0d17 6685 case 2 ... 7:
f31b035a
LA
6686 CP0_CHECK(ctx->kscrexist & (1 << sel));
6687 tcg_gen_ld_tl(arg, cpu_env,
6688 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6689 rn = "KScratch";
e98c0d17 6690 break;
9c2149c8 6691 default:
f31b035a 6692 goto cp0_unimplemented;
9c2149c8
TS
6693 }
6694 break;
6695 default:
f31b035a 6696 goto cp0_unimplemented;
9c2149c8 6697 }
2abf314d 6698 (void)rn; /* avoid a compiler warning */
d12d51d5 6699 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6700 return;
6701
f31b035a 6702cp0_unimplemented:
d12d51d5 6703 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6704 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6705}
6706
d75c135e 6707static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6708{
6709 const char *rn = "invalid";
6710
e189e748 6711 if (sel != 0)
d75c135e 6712 check_insn(ctx, ISA_MIPS64);
e189e748 6713
2e70f6ef
PB
6714 if (use_icount)
6715 gen_io_start();
6716
9c2149c8
TS
6717 switch (reg) {
6718 case 0:
6719 switch (sel) {
6720 case 0:
895c2d04 6721 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6722 rn = "Index";
6723 break;
6724 case 1:
f31b035a 6725 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6726 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6727 rn = "MVPControl";
ead9360e 6728 break;
9c2149c8 6729 case 2:
f31b035a 6730 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6731 /* ignored */
9c2149c8 6732 rn = "MVPConf0";
ead9360e 6733 break;
9c2149c8 6734 case 3:
f31b035a 6735 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6736 /* ignored */
9c2149c8 6737 rn = "MVPConf1";
ead9360e 6738 break;
9c2149c8 6739 default:
f31b035a 6740 goto cp0_unimplemented;
9c2149c8
TS
6741 }
6742 break;
6743 case 1:
6744 switch (sel) {
6745 case 0:
2423f660 6746 /* ignored */
9c2149c8 6747 rn = "Random";
2423f660 6748 break;
9c2149c8 6749 case 1:
f31b035a 6750 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6751 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6752 rn = "VPEControl";
ead9360e 6753 break;
9c2149c8 6754 case 2:
f31b035a 6755 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6756 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6757 rn = "VPEConf0";
ead9360e 6758 break;
9c2149c8 6759 case 3:
f31b035a 6760 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6761 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6762 rn = "VPEConf1";
ead9360e 6763 break;
9c2149c8 6764 case 4:
f31b035a 6765 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6766 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6767 rn = "YQMask";
ead9360e 6768 break;
9c2149c8 6769 case 5:
f31b035a 6770 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6771 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6772 rn = "VPESchedule";
ead9360e 6773 break;
9c2149c8 6774 case 6:
f31b035a 6775 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6776 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6777 rn = "VPEScheFBack";
ead9360e 6778 break;
9c2149c8 6779 case 7:
f31b035a 6780 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6781 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6782 rn = "VPEOpt";
ead9360e 6783 break;
9c2149c8 6784 default:
f31b035a 6785 goto cp0_unimplemented;
9c2149c8
TS
6786 }
6787 break;
6788 case 2:
6789 switch (sel) {
6790 case 0:
7207c7f9 6791 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6792 rn = "EntryLo0";
6793 break;
9c2149c8 6794 case 1:
f31b035a 6795 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6796 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6797 rn = "TCStatus";
ead9360e 6798 break;
9c2149c8 6799 case 2:
f31b035a 6800 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6801 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6802 rn = "TCBind";
ead9360e 6803 break;
9c2149c8 6804 case 3:
f31b035a 6805 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6806 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6807 rn = "TCRestart";
ead9360e 6808 break;
9c2149c8 6809 case 4:
f31b035a 6810 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6811 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6812 rn = "TCHalt";
ead9360e 6813 break;
9c2149c8 6814 case 5:
f31b035a 6815 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6816 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6817 rn = "TCContext";
ead9360e 6818 break;
9c2149c8 6819 case 6:
f31b035a 6820 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6821 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6822 rn = "TCSchedule";
ead9360e 6823 break;
9c2149c8 6824 case 7:
f31b035a 6825 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6826 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6827 rn = "TCScheFBack";
ead9360e 6828 break;
9c2149c8 6829 default:
f31b035a 6830 goto cp0_unimplemented;
9c2149c8
TS
6831 }
6832 break;
6833 case 3:
6834 switch (sel) {
6835 case 0:
7207c7f9 6836 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6837 rn = "EntryLo1";
6838 break;
9c2149c8 6839 default:
f31b035a 6840 goto cp0_unimplemented;
876d4b07 6841 }
9c2149c8
TS
6842 break;
6843 case 4:
6844 switch (sel) {
6845 case 0:
895c2d04 6846 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6847 rn = "Context";
6848 break;
9c2149c8 6849 case 1:
895c2d04 6850// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6851 rn = "ContextConfig";
f31b035a 6852 goto cp0_unimplemented;
2423f660 6853// break;
d279279e 6854 case 2:
f31b035a
LA
6855 CP0_CHECK(ctx->ulri);
6856 tcg_gen_st_tl(arg, cpu_env,
6857 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6858 rn = "UserLocal";
d279279e 6859 break;
9c2149c8 6860 default:
f31b035a 6861 goto cp0_unimplemented;
876d4b07 6862 }
9c2149c8
TS
6863 break;
6864 case 5:
6865 switch (sel) {
6866 case 0:
895c2d04 6867 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6868 rn = "PageMask";
6869 break;
9c2149c8 6870 case 1:
d75c135e 6871 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6872 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6873 rn = "PageGrain";
6874 break;
9c2149c8 6875 default:
f31b035a 6876 goto cp0_unimplemented;
876d4b07 6877 }
9c2149c8
TS
6878 break;
6879 case 6:
6880 switch (sel) {
6881 case 0:
895c2d04 6882 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6883 rn = "Wired";
6884 break;
9c2149c8 6885 case 1:
d75c135e 6886 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6887 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6888 rn = "SRSConf0";
ead9360e 6889 break;
9c2149c8 6890 case 2:
d75c135e 6891 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6892 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6893 rn = "SRSConf1";
ead9360e 6894 break;
9c2149c8 6895 case 3:
d75c135e 6896 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6897 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6898 rn = "SRSConf2";
ead9360e 6899 break;
9c2149c8 6900 case 4:
d75c135e 6901 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6902 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6903 rn = "SRSConf3";
ead9360e 6904 break;
9c2149c8 6905 case 5:
d75c135e 6906 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6907 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6908 rn = "SRSConf4";
ead9360e 6909 break;
9c2149c8 6910 default:
f31b035a 6911 goto cp0_unimplemented;
876d4b07 6912 }
9c2149c8
TS
6913 break;
6914 case 7:
6915 switch (sel) {
6916 case 0:
d75c135e 6917 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6918 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6919 ctx->bstate = BS_STOP;
2423f660
TS
6920 rn = "HWREna";
6921 break;
9c2149c8 6922 default:
f31b035a 6923 goto cp0_unimplemented;
876d4b07 6924 }
9c2149c8
TS
6925 break;
6926 case 8:
aea14095
LA
6927 switch (sel) {
6928 case 0:
6929 /* ignored */
6930 rn = "BadVAddr";
6931 break;
6932 case 1:
6933 /* ignored */
6934 rn = "BadInstr";
6935 break;
6936 case 2:
6937 /* ignored */
6938 rn = "BadInstrP";
6939 break;
6940 default:
f31b035a 6941 goto cp0_unimplemented;
aea14095 6942 }
9c2149c8
TS
6943 break;
6944 case 9:
6945 switch (sel) {
6946 case 0:
895c2d04 6947 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6948 rn = "Count";
6949 break;
876d4b07 6950 /* 6,7 are implementation dependent */
9c2149c8 6951 default:
f31b035a 6952 goto cp0_unimplemented;
876d4b07
TS
6953 }
6954 /* Stop translation as we may have switched the execution mode */
6955 ctx->bstate = BS_STOP;
9c2149c8
TS
6956 break;
6957 case 10:
6958 switch (sel) {
6959 case 0:
895c2d04 6960 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6961 rn = "EntryHi";
6962 break;
9c2149c8 6963 default:
f31b035a 6964 goto cp0_unimplemented;
876d4b07 6965 }
9c2149c8
TS
6966 break;
6967 case 11:
6968 switch (sel) {
6969 case 0:
895c2d04 6970 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6971 rn = "Compare";
6972 break;
876d4b07 6973 /* 6,7 are implementation dependent */
9c2149c8 6974 default:
f31b035a 6975 goto cp0_unimplemented;
876d4b07 6976 }
de9a95f0
AJ
6977 /* Stop translation as we may have switched the execution mode */
6978 ctx->bstate = BS_STOP;
9c2149c8
TS
6979 break;
6980 case 12:
6981 switch (sel) {
6982 case 0:
867abc7e 6983 save_cpu_state(ctx, 1);
895c2d04 6984 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6985 /* BS_STOP isn't good enough here, hflags may have changed. */
6986 gen_save_pc(ctx->pc + 4);
6987 ctx->bstate = BS_EXCP;
2423f660
TS
6988 rn = "Status";
6989 break;
9c2149c8 6990 case 1:
d75c135e 6991 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6992 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6993 /* Stop translation as we may have switched the execution mode */
6994 ctx->bstate = BS_STOP;
2423f660
TS
6995 rn = "IntCtl";
6996 break;
9c2149c8 6997 case 2:
d75c135e 6998 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6999 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7000 /* Stop translation as we may have switched the execution mode */
7001 ctx->bstate = BS_STOP;
2423f660
TS
7002 rn = "SRSCtl";
7003 break;
9c2149c8 7004 case 3:
d75c135e 7005 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7006 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7007 /* Stop translation as we may have switched the execution mode */
7008 ctx->bstate = BS_STOP;
2423f660
TS
7009 rn = "SRSMap";
7010 break;
7011 default:
f31b035a 7012 goto cp0_unimplemented;
876d4b07 7013 }
9c2149c8
TS
7014 break;
7015 case 13:
7016 switch (sel) {
7017 case 0:
867abc7e 7018 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7019 /* Mark as an IO operation because we may trigger a software
7020 interrupt. */
7021 if (use_icount) {
7022 gen_io_start();
7023 }
895c2d04 7024 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
7025 if (use_icount) {
7026 gen_io_end();
7027 }
7028 /* Stop translation as we may have triggered an intetrupt */
7029 ctx->bstate = BS_STOP;
2423f660
TS
7030 rn = "Cause";
7031 break;
9c2149c8 7032 default:
f31b035a 7033 goto cp0_unimplemented;
876d4b07 7034 }
9c2149c8
TS
7035 break;
7036 case 14:
7037 switch (sel) {
7038 case 0:
7db13fae 7039 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7040 rn = "EPC";
7041 break;
9c2149c8 7042 default:
f31b035a 7043 goto cp0_unimplemented;
876d4b07 7044 }
9c2149c8
TS
7045 break;
7046 case 15:
7047 switch (sel) {
7048 case 0:
2423f660
TS
7049 /* ignored */
7050 rn = "PRid";
7051 break;
9c2149c8 7052 case 1:
d75c135e 7053 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7054 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7055 rn = "EBase";
7056 break;
9c2149c8 7057 default:
f31b035a 7058 goto cp0_unimplemented;
876d4b07 7059 }
9c2149c8
TS
7060 break;
7061 case 16:
7062 switch (sel) {
7063 case 0:
895c2d04 7064 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7065 rn = "Config";
2423f660
TS
7066 /* Stop translation as we may have switched the execution mode */
7067 ctx->bstate = BS_STOP;
9c2149c8
TS
7068 break;
7069 case 1:
1fc7bf6e 7070 /* ignored, read only */
9c2149c8
TS
7071 rn = "Config1";
7072 break;
7073 case 2:
895c2d04 7074 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7075 rn = "Config2";
2423f660
TS
7076 /* Stop translation as we may have switched the execution mode */
7077 ctx->bstate = BS_STOP;
9c2149c8
TS
7078 break;
7079 case 3:
2423f660 7080 /* ignored */
9c2149c8
TS
7081 rn = "Config3";
7082 break;
faf1f68b
LA
7083 case 4:
7084 /* currently ignored */
7085 rn = "Config4";
7086 break;
7087 case 5:
7088 gen_helper_mtc0_config5(cpu_env, arg);
7089 rn = "Config5";
7090 /* Stop translation as we may have switched the execution mode */
7091 ctx->bstate = BS_STOP;
7092 break;
9c2149c8
TS
7093 /* 6,7 are implementation dependent */
7094 default:
7095 rn = "Invalid config selector";
f31b035a 7096 goto cp0_unimplemented;
9c2149c8 7097 }
9c2149c8
TS
7098 break;
7099 case 17:
7100 switch (sel) {
7101 case 0:
895c2d04 7102 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7103 rn = "LLAddr";
7104 break;
9c2149c8 7105 default:
f31b035a 7106 goto cp0_unimplemented;
9c2149c8
TS
7107 }
7108 break;
7109 case 18:
7110 switch (sel) {
fd88b6ab 7111 case 0 ... 7:
895c2d04 7112 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7113 rn = "WatchLo";
7114 break;
9c2149c8 7115 default:
f31b035a 7116 goto cp0_unimplemented;
9c2149c8
TS
7117 }
7118 break;
7119 case 19:
7120 switch (sel) {
fd88b6ab 7121 case 0 ... 7:
895c2d04 7122 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7123 rn = "WatchHi";
7124 break;
9c2149c8 7125 default:
f31b035a 7126 goto cp0_unimplemented;
9c2149c8
TS
7127 }
7128 break;
7129 case 20:
7130 switch (sel) {
7131 case 0:
d75c135e 7132 check_insn(ctx, ISA_MIPS3);
895c2d04 7133 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7134 rn = "XContext";
7135 break;
9c2149c8 7136 default:
f31b035a 7137 goto cp0_unimplemented;
9c2149c8
TS
7138 }
7139 break;
7140 case 21:
7141 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7142 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7143 switch (sel) {
7144 case 0:
895c2d04 7145 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7146 rn = "Framemask";
7147 break;
9c2149c8 7148 default:
f31b035a 7149 goto cp0_unimplemented;
9c2149c8
TS
7150 }
7151 break;
7152 case 22:
7153 /* ignored */
7154 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7155 break;
9c2149c8
TS
7156 case 23:
7157 switch (sel) {
7158 case 0:
895c2d04 7159 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7160 /* BS_STOP isn't good enough here, hflags may have changed. */
7161 gen_save_pc(ctx->pc + 4);
7162 ctx->bstate = BS_EXCP;
2423f660
TS
7163 rn = "Debug";
7164 break;
9c2149c8 7165 case 1:
895c2d04 7166// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7167 /* Stop translation as we may have switched the execution mode */
7168 ctx->bstate = BS_STOP;
2423f660
TS
7169 rn = "TraceControl";
7170// break;
9c2149c8 7171 case 2:
895c2d04 7172// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7173 /* Stop translation as we may have switched the execution mode */
7174 ctx->bstate = BS_STOP;
2423f660
TS
7175 rn = "TraceControl2";
7176// break;
9c2149c8 7177 case 3:
895c2d04 7178// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7179 /* Stop translation as we may have switched the execution mode */
7180 ctx->bstate = BS_STOP;
2423f660
TS
7181 rn = "UserTraceData";
7182// break;
9c2149c8 7183 case 4:
895c2d04 7184// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7185 /* Stop translation as we may have switched the execution mode */
7186 ctx->bstate = BS_STOP;
2423f660
TS
7187 rn = "TraceBPC";
7188// break;
9c2149c8 7189 default:
f31b035a 7190 goto cp0_unimplemented;
9c2149c8 7191 }
9c2149c8
TS
7192 break;
7193 case 24:
7194 switch (sel) {
7195 case 0:
f1aa6320 7196 /* EJTAG support */
7db13fae 7197 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7198 rn = "DEPC";
7199 break;
9c2149c8 7200 default:
f31b035a 7201 goto cp0_unimplemented;
9c2149c8
TS
7202 }
7203 break;
7204 case 25:
7205 switch (sel) {
7206 case 0:
895c2d04 7207 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7208 rn = "Performance0";
7209 break;
9c2149c8 7210 case 1:
895c2d04 7211// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7212 rn = "Performance1";
7213// break;
9c2149c8 7214 case 2:
895c2d04 7215// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7216 rn = "Performance2";
7217// break;
9c2149c8 7218 case 3:
895c2d04 7219// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7220 rn = "Performance3";
7221// break;
9c2149c8 7222 case 4:
895c2d04 7223// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7224 rn = "Performance4";
7225// break;
9c2149c8 7226 case 5:
895c2d04 7227// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7228 rn = "Performance5";
7229// break;
9c2149c8 7230 case 6:
895c2d04 7231// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7232 rn = "Performance6";
7233// break;
9c2149c8 7234 case 7:
895c2d04 7235// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7236 rn = "Performance7";
7237// break;
9c2149c8 7238 default:
f31b035a 7239 goto cp0_unimplemented;
9c2149c8 7240 }
876d4b07 7241 break;
9c2149c8 7242 case 26:
876d4b07 7243 /* ignored */
9c2149c8 7244 rn = "ECC";
876d4b07 7245 break;
9c2149c8
TS
7246 case 27:
7247 switch (sel) {
7248 case 0 ... 3:
2423f660
TS
7249 /* ignored */
7250 rn = "CacheErr";
7251 break;
9c2149c8 7252 default:
f31b035a 7253 goto cp0_unimplemented;
9c2149c8 7254 }
876d4b07 7255 break;
9c2149c8
TS
7256 case 28:
7257 switch (sel) {
7258 case 0:
7259 case 2:
7260 case 4:
7261 case 6:
895c2d04 7262 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7263 rn = "TagLo";
7264 break;
7265 case 1:
7266 case 3:
7267 case 5:
7268 case 7:
895c2d04 7269 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7270 rn = "DataLo";
7271 break;
7272 default:
f31b035a 7273 goto cp0_unimplemented;
9c2149c8
TS
7274 }
7275 break;
7276 case 29:
7277 switch (sel) {
7278 case 0:
7279 case 2:
7280 case 4:
7281 case 6:
895c2d04 7282 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7283 rn = "TagHi";
7284 break;
7285 case 1:
7286 case 3:
7287 case 5:
7288 case 7:
895c2d04 7289 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7290 rn = "DataHi";
7291 break;
7292 default:
7293 rn = "invalid sel";
f31b035a 7294 goto cp0_unimplemented;
9c2149c8 7295 }
876d4b07 7296 break;
9c2149c8
TS
7297 case 30:
7298 switch (sel) {
7299 case 0:
7db13fae 7300 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7301 rn = "ErrorEPC";
7302 break;
9c2149c8 7303 default:
f31b035a 7304 goto cp0_unimplemented;
9c2149c8
TS
7305 }
7306 break;
7307 case 31:
7308 switch (sel) {
7309 case 0:
f1aa6320 7310 /* EJTAG support */
7db13fae 7311 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7312 rn = "DESAVE";
7313 break;
e98c0d17 7314 case 2 ... 7:
f31b035a
LA
7315 CP0_CHECK(ctx->kscrexist & (1 << sel));
7316 tcg_gen_st_tl(arg, cpu_env,
7317 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7318 rn = "KScratch";
e98c0d17 7319 break;
9c2149c8 7320 default:
f31b035a 7321 goto cp0_unimplemented;
9c2149c8 7322 }
876d4b07
TS
7323 /* Stop translation as we may have switched the execution mode */
7324 ctx->bstate = BS_STOP;
9c2149c8
TS
7325 break;
7326 default:
f31b035a 7327 goto cp0_unimplemented;
9c2149c8 7328 }
2abf314d 7329 (void)rn; /* avoid a compiler warning */
d12d51d5 7330 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7331 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
7332 if (use_icount) {
7333 gen_io_end();
7334 ctx->bstate = BS_STOP;
7335 }
9c2149c8
TS
7336 return;
7337
f31b035a 7338cp0_unimplemented:
d12d51d5 7339 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7340}
d26bc211 7341#endif /* TARGET_MIPS64 */
9c2149c8 7342
7db13fae 7343static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7344 int u, int sel, int h)
7345{
7346 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7347 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7348
7349 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7350 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7351 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7352 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7353 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7354 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7355 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7356 else if (u == 0) {
7357 switch (rt) {
5a25ce94
EI
7358 case 1:
7359 switch (sel) {
7360 case 1:
895c2d04 7361 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7362 break;
7363 case 2:
895c2d04 7364 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7365 break;
7366 default:
7367 goto die;
7368 break;
7369 }
7370 break;
ead9360e
TS
7371 case 2:
7372 switch (sel) {
7373 case 1:
895c2d04 7374 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7375 break;
7376 case 2:
895c2d04 7377 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7378 break;
7379 case 3:
895c2d04 7380 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7381 break;
7382 case 4:
895c2d04 7383 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7384 break;
7385 case 5:
895c2d04 7386 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7387 break;
7388 case 6:
895c2d04 7389 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7390 break;
7391 case 7:
895c2d04 7392 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7393 break;
7394 default:
d75c135e 7395 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7396 break;
7397 }
7398 break;
7399 case 10:
7400 switch (sel) {
7401 case 0:
895c2d04 7402 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7403 break;
7404 default:
d75c135e 7405 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7406 break;
7407 }
7408 case 12:
7409 switch (sel) {
7410 case 0:
895c2d04 7411 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7412 break;
7413 default:
d75c135e 7414 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7415 break;
7416 }
5a25ce94
EI
7417 case 13:
7418 switch (sel) {
7419 case 0:
895c2d04 7420 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7421 break;
7422 default:
7423 goto die;
7424 break;
7425 }
7426 break;
7427 case 14:
7428 switch (sel) {
7429 case 0:
895c2d04 7430 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7431 break;
7432 default:
7433 goto die;
7434 break;
7435 }
7436 break;
7437 case 15:
7438 switch (sel) {
7439 case 1:
895c2d04 7440 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7441 break;
7442 default:
7443 goto die;
7444 break;
7445 }
7446 break;
7447 case 16:
7448 switch (sel) {
7449 case 0 ... 7:
895c2d04 7450 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7451 break;
7452 default:
7453 goto die;
7454 break;
7455 }
7456 break;
ead9360e
TS
7457 case 23:
7458 switch (sel) {
7459 case 0:
895c2d04 7460 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7461 break;
7462 default:
d75c135e 7463 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7464 break;
7465 }
7466 break;
7467 default:
d75c135e 7468 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7469 }
7470 } else switch (sel) {
7471 /* GPR registers. */
7472 case 0:
895c2d04 7473 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7474 break;
7475 /* Auxiliary CPU registers */
7476 case 1:
7477 switch (rt) {
7478 case 0:
895c2d04 7479 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7480 break;
7481 case 1:
895c2d04 7482 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7483 break;
7484 case 2:
895c2d04 7485 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7486 break;
7487 case 4:
895c2d04 7488 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7489 break;
7490 case 5:
895c2d04 7491 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7492 break;
7493 case 6:
895c2d04 7494 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7495 break;
7496 case 8:
895c2d04 7497 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7498 break;
7499 case 9:
895c2d04 7500 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7501 break;
7502 case 10:
895c2d04 7503 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7504 break;
7505 case 12:
895c2d04 7506 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7507 break;
7508 case 13:
895c2d04 7509 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7510 break;
7511 case 14:
895c2d04 7512 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7513 break;
7514 case 16:
895c2d04 7515 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7516 break;
7517 default:
7518 goto die;
7519 }
7520 break;
7521 /* Floating point (COP1). */
7522 case 2:
7523 /* XXX: For now we support only a single FPU context. */
7524 if (h == 0) {
a7812ae4 7525 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7526
7527 gen_load_fpr32(fp0, rt);
7528 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7529 tcg_temp_free_i32(fp0);
ead9360e 7530 } else {
a7812ae4 7531 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7532
7f6613ce 7533 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7534 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7535 tcg_temp_free_i32(fp0);
ead9360e
TS
7536 }
7537 break;
7538 case 3:
7539 /* XXX: For now we support only a single FPU context. */
895c2d04 7540 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7541 break;
7542 /* COP2: Not implemented. */
7543 case 4:
7544 case 5:
7545 /* fall through */
7546 default:
7547 goto die;
7548 }
d12d51d5 7549 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7550 gen_store_gpr(t0, rd);
7551 tcg_temp_free(t0);
ead9360e
TS
7552 return;
7553
7554die:
1a3fd9c3 7555 tcg_temp_free(t0);
d12d51d5 7556 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7557 generate_exception(ctx, EXCP_RI);
7558}
7559
7db13fae 7560static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7561 int u, int sel, int h)
7562{
7563 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7564 TCGv t0 = tcg_temp_local_new();
ead9360e 7565
1a3fd9c3 7566 gen_load_gpr(t0, rt);
ead9360e 7567 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7568 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7569 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7570 /* NOP */ ;
7571 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7572 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7573 /* NOP */ ;
7574 else if (u == 0) {
7575 switch (rd) {
5a25ce94
EI
7576 case 1:
7577 switch (sel) {
7578 case 1:
895c2d04 7579 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7580 break;
7581 case 2:
895c2d04 7582 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7583 break;
7584 default:
7585 goto die;
7586 break;
7587 }
7588 break;
ead9360e
TS
7589 case 2:
7590 switch (sel) {
7591 case 1:
895c2d04 7592 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7593 break;
7594 case 2:
895c2d04 7595 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7596 break;
7597 case 3:
895c2d04 7598 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7599 break;
7600 case 4:
895c2d04 7601 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7602 break;
7603 case 5:
895c2d04 7604 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7605 break;
7606 case 6:
895c2d04 7607 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7608 break;
7609 case 7:
895c2d04 7610 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7611 break;
7612 default:
d75c135e 7613 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7614 break;
7615 }
7616 break;
7617 case 10:
7618 switch (sel) {
7619 case 0:
895c2d04 7620 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7621 break;
7622 default:
d75c135e 7623 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7624 break;
7625 }
7626 case 12:
7627 switch (sel) {
7628 case 0:
895c2d04 7629 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7630 break;
7631 default:
d75c135e 7632 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7633 break;
7634 }
5a25ce94
EI
7635 case 13:
7636 switch (sel) {
7637 case 0:
895c2d04 7638 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7639 break;
7640 default:
7641 goto die;
7642 break;
7643 }
7644 break;
7645 case 15:
7646 switch (sel) {
7647 case 1:
895c2d04 7648 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7649 break;
7650 default:
7651 goto die;
7652 break;
7653 }
7654 break;
ead9360e
TS
7655 case 23:
7656 switch (sel) {
7657 case 0:
895c2d04 7658 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7659 break;
7660 default:
d75c135e 7661 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7662 break;
7663 }
7664 break;
7665 default:
d75c135e 7666 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7667 }
7668 } else switch (sel) {
7669 /* GPR registers. */
7670 case 0:
895c2d04 7671 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7672 break;
7673 /* Auxiliary CPU registers */
7674 case 1:
7675 switch (rd) {
7676 case 0:
895c2d04 7677 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7678 break;
7679 case 1:
895c2d04 7680 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7681 break;
7682 case 2:
895c2d04 7683 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7684 break;
7685 case 4:
895c2d04 7686 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7687 break;
7688 case 5:
895c2d04 7689 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7690 break;
7691 case 6:
895c2d04 7692 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7693 break;
7694 case 8:
895c2d04 7695 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7696 break;
7697 case 9:
895c2d04 7698 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7699 break;
7700 case 10:
895c2d04 7701 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7702 break;
7703 case 12:
895c2d04 7704 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7705 break;
7706 case 13:
895c2d04 7707 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7708 break;
7709 case 14:
895c2d04 7710 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7711 break;
7712 case 16:
895c2d04 7713 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7714 break;
7715 default:
7716 goto die;
7717 }
7718 break;
7719 /* Floating point (COP1). */
7720 case 2:
7721 /* XXX: For now we support only a single FPU context. */
7722 if (h == 0) {
a7812ae4 7723 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7724
7725 tcg_gen_trunc_tl_i32(fp0, t0);
7726 gen_store_fpr32(fp0, rd);
a7812ae4 7727 tcg_temp_free_i32(fp0);
ead9360e 7728 } else {
a7812ae4 7729 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7730
7731 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7732 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7733 tcg_temp_free_i32(fp0);
ead9360e
TS
7734 }
7735 break;
7736 case 3:
7737 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7738 save_cpu_state(ctx, 1);
736d120a
PJ
7739 {
7740 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7741
7742 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7743 tcg_temp_free_i32(fs_tmp);
7744 }
4cf8a45f
YK
7745 /* Stop translation as we may have changed hflags */
7746 ctx->bstate = BS_STOP;
ead9360e
TS
7747 break;
7748 /* COP2: Not implemented. */
7749 case 4:
7750 case 5:
7751 /* fall through */
7752 default:
7753 goto die;
7754 }
d12d51d5 7755 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7756 tcg_temp_free(t0);
ead9360e
TS
7757 return;
7758
7759die:
1a3fd9c3 7760 tcg_temp_free(t0);
d12d51d5 7761 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7762 generate_exception(ctx, EXCP_RI);
7763}
7764
7db13fae 7765static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7766{
287c4b84 7767 const char *opn = "ldst";
6af0bf9c 7768
2e15497c 7769 check_cp0_enabled(ctx);
6af0bf9c
FB
7770 switch (opc) {
7771 case OPC_MFC0:
7772 if (rt == 0) {
ead9360e 7773 /* Treat as NOP. */
6af0bf9c
FB
7774 return;
7775 }
d75c135e 7776 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7777 opn = "mfc0";
7778 break;
7779 case OPC_MTC0:
1a3fd9c3 7780 {
1fc7bf6e 7781 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7782
7783 gen_load_gpr(t0, rt);
d75c135e 7784 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7785 tcg_temp_free(t0);
7786 }
6af0bf9c
FB
7787 opn = "mtc0";
7788 break;
d26bc211 7789#if defined(TARGET_MIPS64)
9c2149c8 7790 case OPC_DMFC0:
d75c135e 7791 check_insn(ctx, ISA_MIPS3);
9c2149c8 7792 if (rt == 0) {
ead9360e 7793 /* Treat as NOP. */
9c2149c8
TS
7794 return;
7795 }
d75c135e 7796 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7797 opn = "dmfc0";
7798 break;
7799 case OPC_DMTC0:
d75c135e 7800 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7801 {
1fc7bf6e 7802 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7803
7804 gen_load_gpr(t0, rt);
d75c135e 7805 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7806 tcg_temp_free(t0);
7807 }
9c2149c8
TS
7808 opn = "dmtc0";
7809 break;
534ce69f 7810#endif
ead9360e 7811 case OPC_MFTR:
d75c135e 7812 check_insn(ctx, ASE_MT);
ead9360e
TS
7813 if (rd == 0) {
7814 /* Treat as NOP. */
7815 return;
7816 }
6c5c1e20 7817 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7818 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7819 opn = "mftr";
7820 break;
7821 case OPC_MTTR:
d75c135e 7822 check_insn(ctx, ASE_MT);
6c5c1e20 7823 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7824 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7825 opn = "mttr";
7826 break;
6af0bf9c 7827 case OPC_TLBWI:
6af0bf9c 7828 opn = "tlbwi";
c01fccd2 7829 if (!env->tlb->helper_tlbwi)
29929e34 7830 goto die;
895c2d04 7831 gen_helper_tlbwi(cpu_env);
6af0bf9c 7832 break;
9456c2fb
LA
7833 case OPC_TLBINV:
7834 opn = "tlbinv";
7835 if (ctx->ie >= 2) {
7836 if (!env->tlb->helper_tlbinv) {
7837 goto die;
7838 }
7839 gen_helper_tlbinv(cpu_env);
7840 } /* treat as nop if TLBINV not supported */
7841 break;
7842 case OPC_TLBINVF:
7843 opn = "tlbinvf";
7844 if (ctx->ie >= 2) {
7845 if (!env->tlb->helper_tlbinvf) {
7846 goto die;
7847 }
7848 gen_helper_tlbinvf(cpu_env);
7849 } /* treat as nop if TLBINV not supported */
7850 break;
6af0bf9c 7851 case OPC_TLBWR:
6af0bf9c 7852 opn = "tlbwr";
c01fccd2 7853 if (!env->tlb->helper_tlbwr)
29929e34 7854 goto die;
895c2d04 7855 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7856 break;
7857 case OPC_TLBP:
6af0bf9c 7858 opn = "tlbp";
c01fccd2 7859 if (!env->tlb->helper_tlbp)
29929e34 7860 goto die;
895c2d04 7861 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7862 break;
7863 case OPC_TLBR:
6af0bf9c 7864 opn = "tlbr";
c01fccd2 7865 if (!env->tlb->helper_tlbr)
29929e34 7866 goto die;
895c2d04 7867 gen_helper_tlbr(cpu_env);
6af0bf9c 7868 break;
6af0bf9c
FB
7869 case OPC_ERET:
7870 opn = "eret";
d75c135e 7871 check_insn(ctx, ISA_MIPS2);
339cd2a8
LA
7872 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7873 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7874 MIPS_DEBUG("CTI in delay / forbidden slot");
7875 goto die;
7876 }
895c2d04 7877 gen_helper_eret(cpu_env);
6af0bf9c
FB
7878 ctx->bstate = BS_EXCP;
7879 break;
7880 case OPC_DERET:
7881 opn = "deret";
d75c135e 7882 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7883 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7884 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7885 MIPS_DEBUG("CTI in delay / forbidden slot");
7886 goto die;
7887 }
6af0bf9c 7888 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7889 MIPS_INVAL(opn);
6af0bf9c
FB
7890 generate_exception(ctx, EXCP_RI);
7891 } else {
895c2d04 7892 gen_helper_deret(cpu_env);
6af0bf9c
FB
7893 ctx->bstate = BS_EXCP;
7894 }
7895 break;
4ad40f36
FB
7896 case OPC_WAIT:
7897 opn = "wait";
d75c135e 7898 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7899 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7900 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7901 MIPS_DEBUG("CTI in delay / forbidden slot");
7902 goto die;
7903 }
4ad40f36
FB
7904 /* If we get an exception, we want to restart at next instruction */
7905 ctx->pc += 4;
7906 save_cpu_state(ctx, 1);
7907 ctx->pc -= 4;
895c2d04 7908 gen_helper_wait(cpu_env);
4ad40f36
FB
7909 ctx->bstate = BS_EXCP;
7910 break;
6af0bf9c 7911 default:
29929e34 7912 die:
923617a3 7913 MIPS_INVAL(opn);
6af0bf9c
FB
7914 generate_exception(ctx, EXCP_RI);
7915 return;
7916 }
2abf314d 7917 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7918 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7919}
f1aa6320 7920#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7921
6ea83fed 7922/* CP1 Branches (before delay slot) */
d75c135e
AJ
7923static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7924 int32_t cc, int32_t offset)
6ea83fed
FB
7925{
7926 target_ulong btarget;
923617a3 7927 const char *opn = "cp1 cond branch";
a7812ae4 7928 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7929
339cd2a8
LA
7930 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7931 MIPS_DEBUG("CTI in delay / forbidden slot");
7932 generate_exception(ctx, EXCP_RI);
7933 goto out;
7934 }
7935
e189e748 7936 if (cc != 0)
d75c135e 7937 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7938
6ea83fed
FB
7939 btarget = ctx->pc + 4 + offset;
7940
7a387fff
TS
7941 switch (op) {
7942 case OPC_BC1F:
d94536f4
AJ
7943 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7944 tcg_gen_not_i32(t0, t0);
7945 tcg_gen_andi_i32(t0, t0, 1);
7946 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7947 opn = "bc1f";
6ea83fed 7948 goto not_likely;
7a387fff 7949 case OPC_BC1FL:
d94536f4
AJ
7950 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7951 tcg_gen_not_i32(t0, t0);
7952 tcg_gen_andi_i32(t0, t0, 1);
7953 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7954 opn = "bc1fl";
6ea83fed 7955 goto likely;
7a387fff 7956 case OPC_BC1T:
d94536f4
AJ
7957 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7958 tcg_gen_andi_i32(t0, t0, 1);
7959 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7960 opn = "bc1t";
5a5012ec 7961 goto not_likely;
7a387fff 7962 case OPC_BC1TL:
d94536f4
AJ
7963 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7964 tcg_gen_andi_i32(t0, t0, 1);
7965 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7966 opn = "bc1tl";
6ea83fed
FB
7967 likely:
7968 ctx->hflags |= MIPS_HFLAG_BL;
7969 break;
5a5012ec 7970 case OPC_BC1FANY2:
a16336e4 7971 {
d94536f4
AJ
7972 TCGv_i32 t1 = tcg_temp_new_i32();
7973 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7974 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7975 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7976 tcg_temp_free_i32(t1);
d94536f4
AJ
7977 tcg_gen_andi_i32(t0, t0, 1);
7978 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7979 }
fd4a04eb 7980 opn = "bc1any2f";
5a5012ec
TS
7981 goto not_likely;
7982 case OPC_BC1TANY2:
a16336e4 7983 {
d94536f4
AJ
7984 TCGv_i32 t1 = tcg_temp_new_i32();
7985 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7986 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7987 tcg_gen_or_i32(t0, t0, t1);
7988 tcg_temp_free_i32(t1);
7989 tcg_gen_andi_i32(t0, t0, 1);
7990 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7991 }
fd4a04eb 7992 opn = "bc1any2t";
5a5012ec
TS
7993 goto not_likely;
7994 case OPC_BC1FANY4:
a16336e4 7995 {
d94536f4
AJ
7996 TCGv_i32 t1 = tcg_temp_new_i32();
7997 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7998 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7999 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8000 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8001 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8002 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8003 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8004 tcg_temp_free_i32(t1);
d94536f4
AJ
8005 tcg_gen_andi_i32(t0, t0, 1);
8006 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8007 }
fd4a04eb 8008 opn = "bc1any4f";
5a5012ec
TS
8009 goto not_likely;
8010 case OPC_BC1TANY4:
a16336e4 8011 {
d94536f4
AJ
8012 TCGv_i32 t1 = tcg_temp_new_i32();
8013 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8014 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8015 tcg_gen_or_i32(t0, t0, t1);
8016 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8017 tcg_gen_or_i32(t0, t0, t1);
8018 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8019 tcg_gen_or_i32(t0, t0, t1);
8020 tcg_temp_free_i32(t1);
8021 tcg_gen_andi_i32(t0, t0, 1);
8022 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8023 }
fd4a04eb 8024 opn = "bc1any4t";
5a5012ec
TS
8025 not_likely:
8026 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8027 break;
8028 default:
923617a3 8029 MIPS_INVAL(opn);
e397ee33 8030 generate_exception (ctx, EXCP_RI);
6c5c1e20 8031 goto out;
6ea83fed 8032 }
2abf314d 8033 (void)opn; /* avoid a compiler warning */
923617a3 8034 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8035 ctx->hflags, btarget);
8036 ctx->btarget = btarget;
b231c103 8037 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8038 out:
a7812ae4 8039 tcg_temp_free_i32(t0);
6ea83fed
FB
8040}
8041
31837be3
YK
8042/* R6 CP1 Branches */
8043static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8044 int32_t ft, int32_t offset)
8045{
8046 target_ulong btarget;
8047 const char *opn = "cp1 cond branch";
8048 TCGv_i64 t0 = tcg_temp_new_i64();
8049
8050 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8051#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8052 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8053 "\n", ctx->pc);
31837be3
YK
8054#endif
8055 generate_exception(ctx, EXCP_RI);
8056 goto out;
8057 }
8058
8059 gen_load_fpr64(ctx, t0, ft);
8060 tcg_gen_andi_i64(t0, t0, 1);
8061
8062 btarget = addr_add(ctx, ctx->pc + 4, offset);
8063
8064 switch (op) {
8065 case OPC_BC1EQZ:
8066 tcg_gen_xori_i64(t0, t0, 1);
8067 opn = "bc1eqz";
8068 ctx->hflags |= MIPS_HFLAG_BC;
8069 break;
8070 case OPC_BC1NEZ:
8071 /* t0 already set */
8072 opn = "bc1nez";
8073 ctx->hflags |= MIPS_HFLAG_BC;
8074 break;
8075 default:
8076 MIPS_INVAL(opn);
8077 generate_exception(ctx, EXCP_RI);
8078 goto out;
8079 }
8080
8081 tcg_gen_trunc_i64_tl(bcond, t0);
8082
8083 (void)opn; /* avoid a compiler warning */
8084 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8085 ctx->hflags, btarget);
8086 ctx->btarget = btarget;
8087
8088out:
8089 tcg_temp_free_i64(t0);
8090}
8091
6af0bf9c 8092/* Coprocessor 1 (FPU) */
5a5012ec 8093
5a5012ec
TS
8094#define FOP(func, fmt) (((fmt) << 21) | (func))
8095
bf4120ad
NF
8096enum fopcode {
8097 OPC_ADD_S = FOP(0, FMT_S),
8098 OPC_SUB_S = FOP(1, FMT_S),
8099 OPC_MUL_S = FOP(2, FMT_S),
8100 OPC_DIV_S = FOP(3, FMT_S),
8101 OPC_SQRT_S = FOP(4, FMT_S),
8102 OPC_ABS_S = FOP(5, FMT_S),
8103 OPC_MOV_S = FOP(6, FMT_S),
8104 OPC_NEG_S = FOP(7, FMT_S),
8105 OPC_ROUND_L_S = FOP(8, FMT_S),
8106 OPC_TRUNC_L_S = FOP(9, FMT_S),
8107 OPC_CEIL_L_S = FOP(10, FMT_S),
8108 OPC_FLOOR_L_S = FOP(11, FMT_S),
8109 OPC_ROUND_W_S = FOP(12, FMT_S),
8110 OPC_TRUNC_W_S = FOP(13, FMT_S),
8111 OPC_CEIL_W_S = FOP(14, FMT_S),
8112 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8113 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8114 OPC_MOVCF_S = FOP(17, FMT_S),
8115 OPC_MOVZ_S = FOP(18, FMT_S),
8116 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8117 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8118 OPC_RECIP_S = FOP(21, FMT_S),
8119 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8120 OPC_SELNEZ_S = FOP(23, FMT_S),
8121 OPC_MADDF_S = FOP(24, FMT_S),
8122 OPC_MSUBF_S = FOP(25, FMT_S),
8123 OPC_RINT_S = FOP(26, FMT_S),
8124 OPC_CLASS_S = FOP(27, FMT_S),
8125 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8126 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8127 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8128 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8129 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8130 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8131 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8132 OPC_RSQRT2_S = FOP(31, FMT_S),
8133 OPC_CVT_D_S = FOP(33, FMT_S),
8134 OPC_CVT_W_S = FOP(36, FMT_S),
8135 OPC_CVT_L_S = FOP(37, FMT_S),
8136 OPC_CVT_PS_S = FOP(38, FMT_S),
8137 OPC_CMP_F_S = FOP (48, FMT_S),
8138 OPC_CMP_UN_S = FOP (49, FMT_S),
8139 OPC_CMP_EQ_S = FOP (50, FMT_S),
8140 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8141 OPC_CMP_OLT_S = FOP (52, FMT_S),
8142 OPC_CMP_ULT_S = FOP (53, FMT_S),
8143 OPC_CMP_OLE_S = FOP (54, FMT_S),
8144 OPC_CMP_ULE_S = FOP (55, FMT_S),
8145 OPC_CMP_SF_S = FOP (56, FMT_S),
8146 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8147 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8148 OPC_CMP_NGL_S = FOP (59, FMT_S),
8149 OPC_CMP_LT_S = FOP (60, FMT_S),
8150 OPC_CMP_NGE_S = FOP (61, FMT_S),
8151 OPC_CMP_LE_S = FOP (62, FMT_S),
8152 OPC_CMP_NGT_S = FOP (63, FMT_S),
8153
8154 OPC_ADD_D = FOP(0, FMT_D),
8155 OPC_SUB_D = FOP(1, FMT_D),
8156 OPC_MUL_D = FOP(2, FMT_D),
8157 OPC_DIV_D = FOP(3, FMT_D),
8158 OPC_SQRT_D = FOP(4, FMT_D),
8159 OPC_ABS_D = FOP(5, FMT_D),
8160 OPC_MOV_D = FOP(6, FMT_D),
8161 OPC_NEG_D = FOP(7, FMT_D),
8162 OPC_ROUND_L_D = FOP(8, FMT_D),
8163 OPC_TRUNC_L_D = FOP(9, FMT_D),
8164 OPC_CEIL_L_D = FOP(10, FMT_D),
8165 OPC_FLOOR_L_D = FOP(11, FMT_D),
8166 OPC_ROUND_W_D = FOP(12, FMT_D),
8167 OPC_TRUNC_W_D = FOP(13, FMT_D),
8168 OPC_CEIL_W_D = FOP(14, FMT_D),
8169 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8170 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8171 OPC_MOVCF_D = FOP(17, FMT_D),
8172 OPC_MOVZ_D = FOP(18, FMT_D),
8173 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8174 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8175 OPC_RECIP_D = FOP(21, FMT_D),
8176 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8177 OPC_SELNEZ_D = FOP(23, FMT_D),
8178 OPC_MADDF_D = FOP(24, FMT_D),
8179 OPC_MSUBF_D = FOP(25, FMT_D),
8180 OPC_RINT_D = FOP(26, FMT_D),
8181 OPC_CLASS_D = FOP(27, FMT_D),
8182 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8183 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8184 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8185 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8186 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8187 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8188 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8189 OPC_RSQRT2_D = FOP(31, FMT_D),
8190 OPC_CVT_S_D = FOP(32, FMT_D),
8191 OPC_CVT_W_D = FOP(36, FMT_D),
8192 OPC_CVT_L_D = FOP(37, FMT_D),
8193 OPC_CMP_F_D = FOP (48, FMT_D),
8194 OPC_CMP_UN_D = FOP (49, FMT_D),
8195 OPC_CMP_EQ_D = FOP (50, FMT_D),
8196 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8197 OPC_CMP_OLT_D = FOP (52, FMT_D),
8198 OPC_CMP_ULT_D = FOP (53, FMT_D),
8199 OPC_CMP_OLE_D = FOP (54, FMT_D),
8200 OPC_CMP_ULE_D = FOP (55, FMT_D),
8201 OPC_CMP_SF_D = FOP (56, FMT_D),
8202 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8203 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8204 OPC_CMP_NGL_D = FOP (59, FMT_D),
8205 OPC_CMP_LT_D = FOP (60, FMT_D),
8206 OPC_CMP_NGE_D = FOP (61, FMT_D),
8207 OPC_CMP_LE_D = FOP (62, FMT_D),
8208 OPC_CMP_NGT_D = FOP (63, FMT_D),
8209
8210 OPC_CVT_S_W = FOP(32, FMT_W),
8211 OPC_CVT_D_W = FOP(33, FMT_W),
8212 OPC_CVT_S_L = FOP(32, FMT_L),
8213 OPC_CVT_D_L = FOP(33, FMT_L),
8214 OPC_CVT_PS_PW = FOP(38, FMT_W),
8215
8216 OPC_ADD_PS = FOP(0, FMT_PS),
8217 OPC_SUB_PS = FOP(1, FMT_PS),
8218 OPC_MUL_PS = FOP(2, FMT_PS),
8219 OPC_DIV_PS = FOP(3, FMT_PS),
8220 OPC_ABS_PS = FOP(5, FMT_PS),
8221 OPC_MOV_PS = FOP(6, FMT_PS),
8222 OPC_NEG_PS = FOP(7, FMT_PS),
8223 OPC_MOVCF_PS = FOP(17, FMT_PS),
8224 OPC_MOVZ_PS = FOP(18, FMT_PS),
8225 OPC_MOVN_PS = FOP(19, FMT_PS),
8226 OPC_ADDR_PS = FOP(24, FMT_PS),
8227 OPC_MULR_PS = FOP(26, FMT_PS),
8228 OPC_RECIP2_PS = FOP(28, FMT_PS),
8229 OPC_RECIP1_PS = FOP(29, FMT_PS),
8230 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8231 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8232
8233 OPC_CVT_S_PU = FOP(32, FMT_PS),
8234 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8235 OPC_CVT_S_PL = FOP(40, FMT_PS),
8236 OPC_PLL_PS = FOP(44, FMT_PS),
8237 OPC_PLU_PS = FOP(45, FMT_PS),
8238 OPC_PUL_PS = FOP(46, FMT_PS),
8239 OPC_PUU_PS = FOP(47, FMT_PS),
8240 OPC_CMP_F_PS = FOP (48, FMT_PS),
8241 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8242 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8243 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8244 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8245 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8246 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8247 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8248 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8249 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8250 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8251 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8252 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8253 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8254 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8255 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8256};
8257
3f493883
YK
8258enum r6_f_cmp_op {
8259 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8260 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8261 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8262 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8263 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8264 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8265 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8266 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8267 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8268 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8269 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8270 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8271 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8272 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8273 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8274 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8275 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8276 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8277 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8278 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8279 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8280 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8281
8282 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8283 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8284 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8285 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8286 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8287 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8288 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8289 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8290 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8291 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8292 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8293 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8294 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8295 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8296 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8297 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8298 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8299 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8300 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8301 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8302 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8303 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8304};
7a387fff 8305static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8306{
923617a3 8307 const char *opn = "cp1 move";
72c3a3ee 8308 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8309
8310 switch (opc) {
8311 case OPC_MFC1:
b6d96bed 8312 {
a7812ae4 8313 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8314
8315 gen_load_fpr32(fp0, fs);
8316 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8317 tcg_temp_free_i32(fp0);
6958549d 8318 }
6c5c1e20 8319 gen_store_gpr(t0, rt);
6ea83fed
FB
8320 opn = "mfc1";
8321 break;
8322 case OPC_MTC1:
6c5c1e20 8323 gen_load_gpr(t0, rt);
b6d96bed 8324 {
a7812ae4 8325 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8326
8327 tcg_gen_trunc_tl_i32(fp0, t0);
8328 gen_store_fpr32(fp0, fs);
a7812ae4 8329 tcg_temp_free_i32(fp0);
6958549d 8330 }
6ea83fed
FB
8331 opn = "mtc1";
8332 break;
8333 case OPC_CFC1:
895c2d04 8334 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8335 gen_store_gpr(t0, rt);
6ea83fed
FB
8336 opn = "cfc1";
8337 break;
8338 case OPC_CTC1:
6c5c1e20 8339 gen_load_gpr(t0, rt);
4cf8a45f 8340 save_cpu_state(ctx, 1);
736d120a
PJ
8341 {
8342 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8343
8344 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8345 tcg_temp_free_i32(fs_tmp);
8346 }
4cf8a45f
YK
8347 /* Stop translation as we may have changed hflags */
8348 ctx->bstate = BS_STOP;
6ea83fed
FB
8349 opn = "ctc1";
8350 break;
72c3a3ee 8351#if defined(TARGET_MIPS64)
9c2149c8 8352 case OPC_DMFC1:
72c3a3ee 8353 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8354 gen_store_gpr(t0, rt);
5a5012ec
TS
8355 opn = "dmfc1";
8356 break;
9c2149c8 8357 case OPC_DMTC1:
6c5c1e20 8358 gen_load_gpr(t0, rt);
72c3a3ee 8359 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8360 opn = "dmtc1";
8361 break;
72c3a3ee 8362#endif
5a5012ec 8363 case OPC_MFHC1:
b6d96bed 8364 {
a7812ae4 8365 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8366
7f6613ce 8367 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8368 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8369 tcg_temp_free_i32(fp0);
6958549d 8370 }
6c5c1e20 8371 gen_store_gpr(t0, rt);
5a5012ec
TS
8372 opn = "mfhc1";
8373 break;
8374 case OPC_MTHC1:
6c5c1e20 8375 gen_load_gpr(t0, rt);
b6d96bed 8376 {
a7812ae4 8377 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8378
8379 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8380 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8381 tcg_temp_free_i32(fp0);
6958549d 8382 }
5a5012ec
TS
8383 opn = "mthc1";
8384 break;
6ea83fed 8385 default:
923617a3 8386 MIPS_INVAL(opn);
e397ee33 8387 generate_exception (ctx, EXCP_RI);
6c5c1e20 8388 goto out;
6ea83fed 8389 }
2abf314d 8390 (void)opn; /* avoid a compiler warning */
6ea83fed 8391 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8392
8393 out:
8394 tcg_temp_free(t0);
6ea83fed
FB
8395}
8396
5a5012ec
TS
8397static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8398{
af58f9ca 8399 int l1;
e214b9bb 8400 TCGCond cond;
af58f9ca
AJ
8401 TCGv_i32 t0;
8402
8403 if (rd == 0) {
8404 /* Treat as NOP. */
8405 return;
8406 }
6ea83fed 8407
e214b9bb 8408 if (tf)
e214b9bb 8409 cond = TCG_COND_EQ;
27848470
TS
8410 else
8411 cond = TCG_COND_NE;
8412
af58f9ca
AJ
8413 l1 = gen_new_label();
8414 t0 = tcg_temp_new_i32();
fa31af0e 8415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8416 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8417 tcg_temp_free_i32(t0);
af58f9ca
AJ
8418 if (rs == 0) {
8419 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8420 } else {
8421 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8422 }
e214b9bb 8423 gen_set_label(l1);
5a5012ec
TS
8424}
8425
b6d96bed 8426static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8427{
a16336e4 8428 int cond;
cbc37b28 8429 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8430 int l1 = gen_new_label();
8431
a16336e4
TS
8432 if (tf)
8433 cond = TCG_COND_EQ;
8434 else
8435 cond = TCG_COND_NE;
8436
fa31af0e 8437 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8438 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8439 gen_load_fpr32(t0, fs);
8440 gen_store_fpr32(t0, fd);
a16336e4 8441 gen_set_label(l1);
cbc37b28 8442 tcg_temp_free_i32(t0);
5a5012ec 8443}
a16336e4 8444
b6d96bed 8445static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8446{
a16336e4 8447 int cond;
cbc37b28
AJ
8448 TCGv_i32 t0 = tcg_temp_new_i32();
8449 TCGv_i64 fp0;
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 8458 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8459 tcg_temp_free_i32(t0);
11f94258 8460 fp0 = tcg_temp_new_i64();
9bf3eb2c 8461 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8462 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8463 tcg_temp_free_i64(fp0);
cbc37b28 8464 gen_set_label(l1);
a16336e4
TS
8465}
8466
7f6613ce
PJ
8467static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8468 int cc, int tf)
a16336e4
TS
8469{
8470 int cond;
cbc37b28 8471 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8472 int l1 = gen_new_label();
8473 int l2 = gen_new_label();
8474
8475 if (tf)
8476 cond = TCG_COND_EQ;
8477 else
8478 cond = TCG_COND_NE;
8479
fa31af0e 8480 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8481 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8482 gen_load_fpr32(t0, fs);
8483 gen_store_fpr32(t0, fd);
a16336e4 8484 gen_set_label(l1);
9bf3eb2c 8485
fa31af0e 8486 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8487 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8488 gen_load_fpr32h(ctx, t0, fs);
8489 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8490 tcg_temp_free_i32(t0);
a16336e4 8491 gen_set_label(l2);
a16336e4
TS
8492}
8493
e7f16abb
LA
8494static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8495 int fs)
8496{
8497 TCGv_i32 t1 = tcg_const_i32(0);
8498 TCGv_i32 fp0 = tcg_temp_new_i32();
8499 TCGv_i32 fp1 = tcg_temp_new_i32();
8500 TCGv_i32 fp2 = tcg_temp_new_i32();
8501 gen_load_fpr32(fp0, fd);
8502 gen_load_fpr32(fp1, ft);
8503 gen_load_fpr32(fp2, fs);
8504
8505 switch (op1) {
8506 case OPC_SEL_S:
8507 tcg_gen_andi_i32(fp0, fp0, 1);
8508 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8509 break;
8510 case OPC_SELEQZ_S:
8511 tcg_gen_andi_i32(fp1, fp1, 1);
8512 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8513 break;
8514 case OPC_SELNEZ_S:
8515 tcg_gen_andi_i32(fp1, fp1, 1);
8516 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8517 break;
8518 default:
8519 MIPS_INVAL("gen_sel_s");
8520 generate_exception (ctx, EXCP_RI);
8521 break;
8522 }
8523
8524 gen_store_fpr32(fp0, fd);
8525 tcg_temp_free_i32(fp2);
8526 tcg_temp_free_i32(fp1);
8527 tcg_temp_free_i32(fp0);
8528 tcg_temp_free_i32(t1);
8529}
8530
8531static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8532 int fs)
8533{
8534 TCGv_i64 t1 = tcg_const_i64(0);
8535 TCGv_i64 fp0 = tcg_temp_new_i64();
8536 TCGv_i64 fp1 = tcg_temp_new_i64();
8537 TCGv_i64 fp2 = tcg_temp_new_i64();
8538 gen_load_fpr64(ctx, fp0, fd);
8539 gen_load_fpr64(ctx, fp1, ft);
8540 gen_load_fpr64(ctx, fp2, fs);
8541
8542 switch (op1) {
8543 case OPC_SEL_D:
8544 tcg_gen_andi_i64(fp0, fp0, 1);
8545 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8546 break;
8547 case OPC_SELEQZ_D:
8548 tcg_gen_andi_i64(fp1, fp1, 1);
8549 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8550 break;
8551 case OPC_SELNEZ_D:
8552 tcg_gen_andi_i64(fp1, fp1, 1);
8553 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8554 break;
8555 default:
8556 MIPS_INVAL("gen_sel_d");
8557 generate_exception (ctx, EXCP_RI);
8558 break;
8559 }
8560
8561 gen_store_fpr64(ctx, fp0, fd);
8562 tcg_temp_free_i64(fp2);
8563 tcg_temp_free_i64(fp1);
8564 tcg_temp_free_i64(fp0);
8565 tcg_temp_free_i64(t1);
8566}
6ea83fed 8567
bf4120ad 8568static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8569 int ft, int fs, int fd, int cc)
6ea83fed 8570{
923617a3 8571 const char *opn = "farith";
6ea83fed
FB
8572 const char *condnames[] = {
8573 "c.f",
8574 "c.un",
8575 "c.eq",
8576 "c.ueq",
8577 "c.olt",
8578 "c.ult",
8579 "c.ole",
8580 "c.ule",
8581 "c.sf",
8582 "c.ngle",
8583 "c.seq",
8584 "c.ngl",
8585 "c.lt",
8586 "c.nge",
8587 "c.le",
8588 "c.ngt",
8589 };
5a1e8ffb
TS
8590 const char *condnames_abs[] = {
8591 "cabs.f",
8592 "cabs.un",
8593 "cabs.eq",
8594 "cabs.ueq",
8595 "cabs.olt",
8596 "cabs.ult",
8597 "cabs.ole",
8598 "cabs.ule",
8599 "cabs.sf",
8600 "cabs.ngle",
8601 "cabs.seq",
8602 "cabs.ngl",
8603 "cabs.lt",
8604 "cabs.nge",
8605 "cabs.le",
8606 "cabs.ngt",
8607 };
8608 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8609 uint32_t func = ctx->opcode & 0x3f;
8610
bf4120ad
NF
8611 switch (op1) {
8612 case OPC_ADD_S:
b6d96bed 8613 {
a7812ae4
PB
8614 TCGv_i32 fp0 = tcg_temp_new_i32();
8615 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8616
8617 gen_load_fpr32(fp0, fs);
8618 gen_load_fpr32(fp1, ft);
895c2d04 8619 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8620 tcg_temp_free_i32(fp1);
b6d96bed 8621 gen_store_fpr32(fp0, fd);
a7812ae4 8622 tcg_temp_free_i32(fp0);
b6d96bed 8623 }
5a5012ec 8624 opn = "add.s";
5a1e8ffb 8625 optype = BINOP;
5a5012ec 8626 break;
bf4120ad 8627 case OPC_SUB_S:
b6d96bed 8628 {
a7812ae4
PB
8629 TCGv_i32 fp0 = tcg_temp_new_i32();
8630 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8631
8632 gen_load_fpr32(fp0, fs);
8633 gen_load_fpr32(fp1, ft);
895c2d04 8634 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8635 tcg_temp_free_i32(fp1);
b6d96bed 8636 gen_store_fpr32(fp0, fd);
a7812ae4 8637 tcg_temp_free_i32(fp0);
b6d96bed 8638 }
5a5012ec 8639 opn = "sub.s";
5a1e8ffb 8640 optype = BINOP;
5a5012ec 8641 break;
bf4120ad 8642 case OPC_MUL_S:
b6d96bed 8643 {
a7812ae4
PB
8644 TCGv_i32 fp0 = tcg_temp_new_i32();
8645 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8646
8647 gen_load_fpr32(fp0, fs);
8648 gen_load_fpr32(fp1, ft);
895c2d04 8649 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8650 tcg_temp_free_i32(fp1);
b6d96bed 8651 gen_store_fpr32(fp0, fd);
a7812ae4 8652 tcg_temp_free_i32(fp0);
b6d96bed 8653 }
5a5012ec 8654 opn = "mul.s";
5a1e8ffb 8655 optype = BINOP;
5a5012ec 8656 break;
bf4120ad 8657 case OPC_DIV_S:
b6d96bed 8658 {
a7812ae4
PB
8659 TCGv_i32 fp0 = tcg_temp_new_i32();
8660 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8661
8662 gen_load_fpr32(fp0, fs);
8663 gen_load_fpr32(fp1, ft);
895c2d04 8664 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8665 tcg_temp_free_i32(fp1);
b6d96bed 8666 gen_store_fpr32(fp0, fd);
a7812ae4 8667 tcg_temp_free_i32(fp0);
b6d96bed 8668 }
5a5012ec 8669 opn = "div.s";
5a1e8ffb 8670 optype = BINOP;
5a5012ec 8671 break;
bf4120ad 8672 case OPC_SQRT_S:
b6d96bed 8673 {
a7812ae4 8674 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8675
8676 gen_load_fpr32(fp0, fs);
895c2d04 8677 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8678 gen_store_fpr32(fp0, fd);
a7812ae4 8679 tcg_temp_free_i32(fp0);
b6d96bed 8680 }
5a5012ec
TS
8681 opn = "sqrt.s";
8682 break;
bf4120ad 8683 case OPC_ABS_S:
b6d96bed 8684 {
a7812ae4 8685 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8686
8687 gen_load_fpr32(fp0, fs);
a7812ae4 8688 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8689 gen_store_fpr32(fp0, fd);
a7812ae4 8690 tcg_temp_free_i32(fp0);
b6d96bed 8691 }
5a5012ec
TS
8692 opn = "abs.s";
8693 break;
bf4120ad 8694 case OPC_MOV_S:
b6d96bed 8695 {
a7812ae4 8696 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8697
8698 gen_load_fpr32(fp0, fs);
8699 gen_store_fpr32(fp0, fd);
a7812ae4 8700 tcg_temp_free_i32(fp0);
b6d96bed 8701 }
5a5012ec
TS
8702 opn = "mov.s";
8703 break;
bf4120ad 8704 case OPC_NEG_S:
b6d96bed 8705 {
a7812ae4 8706 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8707
8708 gen_load_fpr32(fp0, fs);
a7812ae4 8709 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8710 gen_store_fpr32(fp0, fd);
a7812ae4 8711 tcg_temp_free_i32(fp0);
b6d96bed 8712 }
5a5012ec
TS
8713 opn = "neg.s";
8714 break;
bf4120ad 8715 case OPC_ROUND_L_S:
5e755519 8716 check_cp1_64bitmode(ctx);
b6d96bed 8717 {
a7812ae4
PB
8718 TCGv_i32 fp32 = tcg_temp_new_i32();
8719 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8720
8721 gen_load_fpr32(fp32, fs);
895c2d04 8722 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8723 tcg_temp_free_i32(fp32);
b6d96bed 8724 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8725 tcg_temp_free_i64(fp64);
b6d96bed 8726 }
5a5012ec
TS
8727 opn = "round.l.s";
8728 break;
bf4120ad 8729 case OPC_TRUNC_L_S:
5e755519 8730 check_cp1_64bitmode(ctx);
b6d96bed 8731 {
a7812ae4
PB
8732 TCGv_i32 fp32 = tcg_temp_new_i32();
8733 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8734
8735 gen_load_fpr32(fp32, fs);
895c2d04 8736 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8737 tcg_temp_free_i32(fp32);
b6d96bed 8738 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8739 tcg_temp_free_i64(fp64);
b6d96bed 8740 }
5a5012ec
TS
8741 opn = "trunc.l.s";
8742 break;
bf4120ad 8743 case OPC_CEIL_L_S:
5e755519 8744 check_cp1_64bitmode(ctx);
b6d96bed 8745 {
a7812ae4
PB
8746 TCGv_i32 fp32 = tcg_temp_new_i32();
8747 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8748
8749 gen_load_fpr32(fp32, fs);
895c2d04 8750 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8751 tcg_temp_free_i32(fp32);
b6d96bed 8752 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8753 tcg_temp_free_i64(fp64);
b6d96bed 8754 }
5a5012ec
TS
8755 opn = "ceil.l.s";
8756 break;
bf4120ad 8757 case OPC_FLOOR_L_S:
5e755519 8758 check_cp1_64bitmode(ctx);
b6d96bed 8759 {
a7812ae4
PB
8760 TCGv_i32 fp32 = tcg_temp_new_i32();
8761 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8762
8763 gen_load_fpr32(fp32, fs);
895c2d04 8764 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8765 tcg_temp_free_i32(fp32);
b6d96bed 8766 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8767 tcg_temp_free_i64(fp64);
b6d96bed 8768 }
5a5012ec
TS
8769 opn = "floor.l.s";
8770 break;
bf4120ad 8771 case OPC_ROUND_W_S:
b6d96bed 8772 {
a7812ae4 8773 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8774
8775 gen_load_fpr32(fp0, fs);
895c2d04 8776 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8777 gen_store_fpr32(fp0, fd);
a7812ae4 8778 tcg_temp_free_i32(fp0);
b6d96bed 8779 }
5a5012ec
TS
8780 opn = "round.w.s";
8781 break;
bf4120ad 8782 case OPC_TRUNC_W_S:
b6d96bed 8783 {
a7812ae4 8784 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8785
8786 gen_load_fpr32(fp0, fs);
895c2d04 8787 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8788 gen_store_fpr32(fp0, fd);
a7812ae4 8789 tcg_temp_free_i32(fp0);
b6d96bed 8790 }
5a5012ec
TS
8791 opn = "trunc.w.s";
8792 break;
bf4120ad 8793 case OPC_CEIL_W_S:
b6d96bed 8794 {
a7812ae4 8795 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8796
8797 gen_load_fpr32(fp0, fs);
895c2d04 8798 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8799 gen_store_fpr32(fp0, fd);
a7812ae4 8800 tcg_temp_free_i32(fp0);
b6d96bed 8801 }
5a5012ec
TS
8802 opn = "ceil.w.s";
8803 break;
bf4120ad 8804 case OPC_FLOOR_W_S:
b6d96bed 8805 {
a7812ae4 8806 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8807
8808 gen_load_fpr32(fp0, fs);
895c2d04 8809 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8810 gen_store_fpr32(fp0, fd);
a7812ae4 8811 tcg_temp_free_i32(fp0);
b6d96bed 8812 }
5a5012ec
TS
8813 opn = "floor.w.s";
8814 break;
e7f16abb
LA
8815 case OPC_SEL_S:
8816 check_insn(ctx, ISA_MIPS32R6);
8817 gen_sel_s(ctx, op1, fd, ft, fs);
8818 opn = "sel.s";
8819 break;
8820 case OPC_SELEQZ_S:
8821 check_insn(ctx, ISA_MIPS32R6);
8822 gen_sel_s(ctx, op1, fd, ft, fs);
8823 opn = "seleqz.s";
8824 break;
8825 case OPC_SELNEZ_S:
8826 check_insn(ctx, ISA_MIPS32R6);
8827 gen_sel_s(ctx, op1, fd, ft, fs);
8828 opn = "selnez.s";
8829 break;
bf4120ad 8830 case OPC_MOVCF_S:
fecd2646 8831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8832 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8833 opn = "movcf.s";
8834 break;
bf4120ad 8835 case OPC_MOVZ_S:
fecd2646 8836 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8837 {
8838 int l1 = gen_new_label();
c9297f4d 8839 TCGv_i32 fp0;
a16336e4 8840
c9297f4d
AJ
8841 if (ft != 0) {
8842 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8843 }
8844 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8845 gen_load_fpr32(fp0, fs);
8846 gen_store_fpr32(fp0, fd);
a7812ae4 8847 tcg_temp_free_i32(fp0);
a16336e4
TS
8848 gen_set_label(l1);
8849 }
5a5012ec
TS
8850 opn = "movz.s";
8851 break;
bf4120ad 8852 case OPC_MOVN_S:
fecd2646 8853 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8854 {
8855 int l1 = gen_new_label();
c9297f4d
AJ
8856 TCGv_i32 fp0;
8857
8858 if (ft != 0) {
8859 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8860 fp0 = tcg_temp_new_i32();
8861 gen_load_fpr32(fp0, fs);
8862 gen_store_fpr32(fp0, fd);
8863 tcg_temp_free_i32(fp0);
8864 gen_set_label(l1);
8865 }
a16336e4 8866 }
5a5012ec
TS
8867 opn = "movn.s";
8868 break;
bf4120ad 8869 case OPC_RECIP_S:
b8aa4598 8870 check_cop1x(ctx);
b6d96bed 8871 {
a7812ae4 8872 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8873
8874 gen_load_fpr32(fp0, fs);
895c2d04 8875 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8876 gen_store_fpr32(fp0, fd);
a7812ae4 8877 tcg_temp_free_i32(fp0);
b6d96bed 8878 }
57fa1fb3
TS
8879 opn = "recip.s";
8880 break;
bf4120ad 8881 case OPC_RSQRT_S:
b8aa4598 8882 check_cop1x(ctx);
b6d96bed 8883 {
a7812ae4 8884 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8885
8886 gen_load_fpr32(fp0, fs);
895c2d04 8887 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8888 gen_store_fpr32(fp0, fd);
a7812ae4 8889 tcg_temp_free_i32(fp0);
b6d96bed 8890 }
57fa1fb3
TS
8891 opn = "rsqrt.s";
8892 break;
e7f16abb
LA
8893 case OPC_MADDF_S:
8894 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8895 {
a7812ae4
PB
8896 TCGv_i32 fp0 = tcg_temp_new_i32();
8897 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8898 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8899 gen_load_fpr32(fp0, fs);
d22d7289 8900 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8901 gen_load_fpr32(fp2, fd);
8902 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8903 gen_store_fpr32(fp2, fd);
8904 tcg_temp_free_i32(fp2);
a7812ae4 8905 tcg_temp_free_i32(fp1);
a7812ae4 8906 tcg_temp_free_i32(fp0);
e7f16abb 8907 opn = "maddf.s";
b6d96bed 8908 }
57fa1fb3 8909 break;
e7f16abb
LA
8910 case OPC_MSUBF_S:
8911 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8912 {
a7812ae4 8913 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8914 TCGv_i32 fp1 = tcg_temp_new_i32();
8915 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8916 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8917 gen_load_fpr32(fp1, ft);
8918 gen_load_fpr32(fp2, fd);
8919 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8920 gen_store_fpr32(fp2, fd);
8921 tcg_temp_free_i32(fp2);
8922 tcg_temp_free_i32(fp1);
a7812ae4 8923 tcg_temp_free_i32(fp0);
e7f16abb 8924 opn = "msubf.s";
b6d96bed 8925 }
57fa1fb3 8926 break;
e7f16abb
LA
8927 case OPC_RINT_S:
8928 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8929 {
a7812ae4 8930 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8931 gen_load_fpr32(fp0, fs);
e7f16abb 8932 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8933 gen_store_fpr32(fp0, fd);
a7812ae4 8934 tcg_temp_free_i32(fp0);
e7f16abb 8935 opn = "rint.s";
b6d96bed 8936 }
57fa1fb3 8937 break;
e7f16abb
LA
8938 case OPC_CLASS_S:
8939 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8940 {
e7f16abb
LA
8941 TCGv_i32 fp0 = tcg_temp_new_i32();
8942 gen_load_fpr32(fp0, fs);
8943 gen_helper_float_class_s(fp0, fp0);
8944 gen_store_fpr32(fp0, fd);
8945 tcg_temp_free_i32(fp0);
8946 opn = "class.s";
8947 }
8948 break;
8949 case OPC_MIN_S: /* OPC_RECIP2_S */
8950 if (ctx->insn_flags & ISA_MIPS32R6) {
8951 /* OPC_MIN_S */
a7812ae4
PB
8952 TCGv_i32 fp0 = tcg_temp_new_i32();
8953 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8954 TCGv_i32 fp2 = tcg_temp_new_i32();
8955 gen_load_fpr32(fp0, fs);
8956 gen_load_fpr32(fp1, ft);
8957 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8958 gen_store_fpr32(fp2, fd);
8959 tcg_temp_free_i32(fp2);
8960 tcg_temp_free_i32(fp1);
8961 tcg_temp_free_i32(fp0);
8962 opn = "min.s";
8963 } else {
8964 /* OPC_RECIP2_S */
8965 check_cp1_64bitmode(ctx);
8966 {
8967 TCGv_i32 fp0 = tcg_temp_new_i32();
8968 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8969
e7f16abb
LA
8970 gen_load_fpr32(fp0, fs);
8971 gen_load_fpr32(fp1, ft);
8972 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8973 tcg_temp_free_i32(fp1);
8974 gen_store_fpr32(fp0, fd);
8975 tcg_temp_free_i32(fp0);
8976 }
8977 opn = "recip2.s";
8978 }
8979 break;
8980 case OPC_MINA_S: /* OPC_RECIP1_S */
8981 if (ctx->insn_flags & ISA_MIPS32R6) {
8982 /* OPC_MINA_S */
8983 TCGv_i32 fp0 = tcg_temp_new_i32();
8984 TCGv_i32 fp1 = tcg_temp_new_i32();
8985 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8986 gen_load_fpr32(fp0, fs);
8987 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8988 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
8989 gen_store_fpr32(fp2, fd);
8990 tcg_temp_free_i32(fp2);
8991 tcg_temp_free_i32(fp1);
8992 tcg_temp_free_i32(fp0);
8993 opn = "mina.s";
8994 } else {
8995 /* OPC_RECIP1_S */
8996 check_cp1_64bitmode(ctx);
8997 {
8998 TCGv_i32 fp0 = tcg_temp_new_i32();
8999
9000 gen_load_fpr32(fp0, fs);
9001 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9002 gen_store_fpr32(fp0, fd);
9003 tcg_temp_free_i32(fp0);
9004 }
9005 opn = "recip1.s";
9006 }
9007 break;
9008 case OPC_MAX_S: /* OPC_RSQRT1_S */
9009 if (ctx->insn_flags & ISA_MIPS32R6) {
9010 /* OPC_MAX_S */
9011 TCGv_i32 fp0 = tcg_temp_new_i32();
9012 TCGv_i32 fp1 = tcg_temp_new_i32();
9013 gen_load_fpr32(fp0, fs);
9014 gen_load_fpr32(fp1, ft);
9015 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9016 gen_store_fpr32(fp1, fd);
9017 tcg_temp_free_i32(fp1);
9018 tcg_temp_free_i32(fp0);
9019 opn = "max.s";
9020 } else {
9021 /* OPC_RSQRT1_S */
9022 check_cp1_64bitmode(ctx);
9023 {
9024 TCGv_i32 fp0 = tcg_temp_new_i32();
9025
9026 gen_load_fpr32(fp0, fs);
9027 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9028 gen_store_fpr32(fp0, fd);
9029 tcg_temp_free_i32(fp0);
9030 }
9031 opn = "rsqrt1.s";
9032 }
9033 break;
9034 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9035 if (ctx->insn_flags & ISA_MIPS32R6) {
9036 /* OPC_MAXA_S */
9037 TCGv_i32 fp0 = tcg_temp_new_i32();
9038 TCGv_i32 fp1 = tcg_temp_new_i32();
9039 gen_load_fpr32(fp0, fs);
9040 gen_load_fpr32(fp1, ft);
9041 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9042 gen_store_fpr32(fp1, fd);
a7812ae4 9043 tcg_temp_free_i32(fp1);
a7812ae4 9044 tcg_temp_free_i32(fp0);
e7f16abb
LA
9045 opn = "maxa.s";
9046 } else {
9047 /* OPC_RSQRT2_S */
9048 check_cp1_64bitmode(ctx);
9049 {
9050 TCGv_i32 fp0 = tcg_temp_new_i32();
9051 TCGv_i32 fp1 = tcg_temp_new_i32();
9052
9053 gen_load_fpr32(fp0, fs);
9054 gen_load_fpr32(fp1, ft);
9055 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9056 tcg_temp_free_i32(fp1);
9057 gen_store_fpr32(fp0, fd);
9058 tcg_temp_free_i32(fp0);
9059 }
9060 opn = "rsqrt2.s";
b6d96bed 9061 }
57fa1fb3 9062 break;
bf4120ad 9063 case OPC_CVT_D_S:
5e755519 9064 check_cp1_registers(ctx, fd);
b6d96bed 9065 {
a7812ae4
PB
9066 TCGv_i32 fp32 = tcg_temp_new_i32();
9067 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9068
9069 gen_load_fpr32(fp32, fs);
895c2d04 9070 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9071 tcg_temp_free_i32(fp32);
b6d96bed 9072 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9073 tcg_temp_free_i64(fp64);
b6d96bed 9074 }
5a5012ec
TS
9075 opn = "cvt.d.s";
9076 break;
bf4120ad 9077 case OPC_CVT_W_S:
b6d96bed 9078 {
a7812ae4 9079 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9080
9081 gen_load_fpr32(fp0, fs);
895c2d04 9082 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 9083 gen_store_fpr32(fp0, fd);
a7812ae4 9084 tcg_temp_free_i32(fp0);
b6d96bed 9085 }
5a5012ec
TS
9086 opn = "cvt.w.s";
9087 break;
bf4120ad 9088 case OPC_CVT_L_S:
5e755519 9089 check_cp1_64bitmode(ctx);
b6d96bed 9090 {
a7812ae4
PB
9091 TCGv_i32 fp32 = tcg_temp_new_i32();
9092 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9093
9094 gen_load_fpr32(fp32, fs);
895c2d04 9095 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9096 tcg_temp_free_i32(fp32);
b6d96bed 9097 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9098 tcg_temp_free_i64(fp64);
b6d96bed 9099 }
5a5012ec
TS
9100 opn = "cvt.l.s";
9101 break;
bf4120ad 9102 case OPC_CVT_PS_S:
fecd2646 9103 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9104 check_cp1_64bitmode(ctx);
b6d96bed 9105 {
a7812ae4
PB
9106 TCGv_i64 fp64 = tcg_temp_new_i64();
9107 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9108 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
9109
9110 gen_load_fpr32(fp32_0, fs);
9111 gen_load_fpr32(fp32_1, ft);
13d24f49 9112 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9113 tcg_temp_free_i32(fp32_1);
9114 tcg_temp_free_i32(fp32_0);
36aa55dc 9115 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9116 tcg_temp_free_i64(fp64);
b6d96bed 9117 }
5a5012ec
TS
9118 opn = "cvt.ps.s";
9119 break;
bf4120ad
NF
9120 case OPC_CMP_F_S:
9121 case OPC_CMP_UN_S:
9122 case OPC_CMP_EQ_S:
9123 case OPC_CMP_UEQ_S:
9124 case OPC_CMP_OLT_S:
9125 case OPC_CMP_ULT_S:
9126 case OPC_CMP_OLE_S:
9127 case OPC_CMP_ULE_S:
9128 case OPC_CMP_SF_S:
9129 case OPC_CMP_NGLE_S:
9130 case OPC_CMP_SEQ_S:
9131 case OPC_CMP_NGL_S:
9132 case OPC_CMP_LT_S:
9133 case OPC_CMP_NGE_S:
9134 case OPC_CMP_LE_S:
9135 case OPC_CMP_NGT_S:
fecd2646 9136 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9137 if (ctx->opcode & (1 << 6)) {
9138 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9139 opn = condnames_abs[func-48];
9140 } else {
9141 gen_cmp_s(ctx, func-48, ft, fs, cc);
9142 opn = condnames[func-48];
5a1e8ffb 9143 }
5a5012ec 9144 break;
bf4120ad 9145 case OPC_ADD_D:
5e755519 9146 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9147 {
a7812ae4
PB
9148 TCGv_i64 fp0 = tcg_temp_new_i64();
9149 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9150
9151 gen_load_fpr64(ctx, fp0, fs);
9152 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9153 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9154 tcg_temp_free_i64(fp1);
b6d96bed 9155 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9156 tcg_temp_free_i64(fp0);
b6d96bed 9157 }
6ea83fed 9158 opn = "add.d";
5a1e8ffb 9159 optype = BINOP;
6ea83fed 9160 break;
bf4120ad 9161 case OPC_SUB_D:
5e755519 9162 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9163 {
a7812ae4
PB
9164 TCGv_i64 fp0 = tcg_temp_new_i64();
9165 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9166
9167 gen_load_fpr64(ctx, fp0, fs);
9168 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9169 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9170 tcg_temp_free_i64(fp1);
b6d96bed 9171 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9172 tcg_temp_free_i64(fp0);
b6d96bed 9173 }
6ea83fed 9174 opn = "sub.d";
5a1e8ffb 9175 optype = BINOP;
6ea83fed 9176 break;
bf4120ad 9177 case OPC_MUL_D:
5e755519 9178 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9179 {
a7812ae4
PB
9180 TCGv_i64 fp0 = tcg_temp_new_i64();
9181 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9182
9183 gen_load_fpr64(ctx, fp0, fs);
9184 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9185 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9186 tcg_temp_free_i64(fp1);
b6d96bed 9187 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9188 tcg_temp_free_i64(fp0);
b6d96bed 9189 }
6ea83fed 9190 opn = "mul.d";
5a1e8ffb 9191 optype = BINOP;
6ea83fed 9192 break;
bf4120ad 9193 case OPC_DIV_D:
5e755519 9194 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9195 {
a7812ae4
PB
9196 TCGv_i64 fp0 = tcg_temp_new_i64();
9197 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9198
9199 gen_load_fpr64(ctx, fp0, fs);
9200 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9201 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9202 tcg_temp_free_i64(fp1);
b6d96bed 9203 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9204 tcg_temp_free_i64(fp0);
b6d96bed 9205 }
6ea83fed 9206 opn = "div.d";
5a1e8ffb 9207 optype = BINOP;
6ea83fed 9208 break;
bf4120ad 9209 case OPC_SQRT_D:
5e755519 9210 check_cp1_registers(ctx, fs | fd);
b6d96bed 9211 {
a7812ae4 9212 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9213
9214 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9215 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9216 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9217 tcg_temp_free_i64(fp0);
b6d96bed 9218 }
6ea83fed
FB
9219 opn = "sqrt.d";
9220 break;
bf4120ad 9221 case OPC_ABS_D:
5e755519 9222 check_cp1_registers(ctx, fs | fd);
b6d96bed 9223 {
a7812ae4 9224 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9225
9226 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9227 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9228 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9229 tcg_temp_free_i64(fp0);
b6d96bed 9230 }
6ea83fed
FB
9231 opn = "abs.d";
9232 break;
bf4120ad 9233 case OPC_MOV_D:
5e755519 9234 check_cp1_registers(ctx, fs | fd);
b6d96bed 9235 {
a7812ae4 9236 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9237
9238 gen_load_fpr64(ctx, fp0, fs);
9239 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9240 tcg_temp_free_i64(fp0);
b6d96bed 9241 }
6ea83fed
FB
9242 opn = "mov.d";
9243 break;
bf4120ad 9244 case OPC_NEG_D:
5e755519 9245 check_cp1_registers(ctx, fs | fd);
b6d96bed 9246 {
a7812ae4 9247 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9248
9249 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9250 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9251 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9252 tcg_temp_free_i64(fp0);
b6d96bed 9253 }
6ea83fed
FB
9254 opn = "neg.d";
9255 break;
bf4120ad 9256 case OPC_ROUND_L_D:
5e755519 9257 check_cp1_64bitmode(ctx);
b6d96bed 9258 {
a7812ae4 9259 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9260
9261 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9262 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9263 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9264 tcg_temp_free_i64(fp0);
b6d96bed 9265 }
5a5012ec
TS
9266 opn = "round.l.d";
9267 break;
bf4120ad 9268 case OPC_TRUNC_L_D:
5e755519 9269 check_cp1_64bitmode(ctx);
b6d96bed 9270 {
a7812ae4 9271 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9272
9273 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9274 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9275 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9276 tcg_temp_free_i64(fp0);
b6d96bed 9277 }
5a5012ec
TS
9278 opn = "trunc.l.d";
9279 break;
bf4120ad 9280 case OPC_CEIL_L_D:
5e755519 9281 check_cp1_64bitmode(ctx);
b6d96bed 9282 {
a7812ae4 9283 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9284
9285 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9286 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9287 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9288 tcg_temp_free_i64(fp0);
b6d96bed 9289 }
5a5012ec
TS
9290 opn = "ceil.l.d";
9291 break;
bf4120ad 9292 case OPC_FLOOR_L_D:
5e755519 9293 check_cp1_64bitmode(ctx);
b6d96bed 9294 {
a7812ae4 9295 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9296
9297 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9298 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9299 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9300 tcg_temp_free_i64(fp0);
b6d96bed 9301 }
5a5012ec
TS
9302 opn = "floor.l.d";
9303 break;
bf4120ad 9304 case OPC_ROUND_W_D:
5e755519 9305 check_cp1_registers(ctx, fs);
b6d96bed 9306 {
a7812ae4
PB
9307 TCGv_i32 fp32 = tcg_temp_new_i32();
9308 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9309
9310 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9311 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9312 tcg_temp_free_i64(fp64);
b6d96bed 9313 gen_store_fpr32(fp32, fd);
a7812ae4 9314 tcg_temp_free_i32(fp32);
b6d96bed 9315 }
6ea83fed
FB
9316 opn = "round.w.d";
9317 break;
bf4120ad 9318 case OPC_TRUNC_W_D:
5e755519 9319 check_cp1_registers(ctx, fs);
b6d96bed 9320 {
a7812ae4
PB
9321 TCGv_i32 fp32 = tcg_temp_new_i32();
9322 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9323
9324 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9325 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9326 tcg_temp_free_i64(fp64);
b6d96bed 9327 gen_store_fpr32(fp32, fd);
a7812ae4 9328 tcg_temp_free_i32(fp32);
b6d96bed 9329 }
6ea83fed
FB
9330 opn = "trunc.w.d";
9331 break;
bf4120ad 9332 case OPC_CEIL_W_D:
5e755519 9333 check_cp1_registers(ctx, fs);
b6d96bed 9334 {
a7812ae4
PB
9335 TCGv_i32 fp32 = tcg_temp_new_i32();
9336 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9337
9338 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9339 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9340 tcg_temp_free_i64(fp64);
b6d96bed 9341 gen_store_fpr32(fp32, fd);
a7812ae4 9342 tcg_temp_free_i32(fp32);
b6d96bed 9343 }
6ea83fed
FB
9344 opn = "ceil.w.d";
9345 break;
bf4120ad 9346 case OPC_FLOOR_W_D:
5e755519 9347 check_cp1_registers(ctx, fs);
b6d96bed 9348 {
a7812ae4
PB
9349 TCGv_i32 fp32 = tcg_temp_new_i32();
9350 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9351
9352 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9353 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9354 tcg_temp_free_i64(fp64);
b6d96bed 9355 gen_store_fpr32(fp32, fd);
a7812ae4 9356 tcg_temp_free_i32(fp32);
b6d96bed 9357 }
7a387fff 9358 opn = "floor.w.d";
6ea83fed 9359 break;
e7f16abb
LA
9360 case OPC_SEL_D:
9361 check_insn(ctx, ISA_MIPS32R6);
9362 gen_sel_d(ctx, op1, fd, ft, fs);
9363 opn = "sel.d";
9364 break;
9365 case OPC_SELEQZ_D:
9366 check_insn(ctx, ISA_MIPS32R6);
9367 gen_sel_d(ctx, op1, fd, ft, fs);
9368 opn = "seleqz.d";
9369 break;
9370 case OPC_SELNEZ_D:
9371 check_insn(ctx, ISA_MIPS32R6);
9372 gen_sel_d(ctx, op1, fd, ft, fs);
9373 opn = "selnez.d";
9374 break;
bf4120ad 9375 case OPC_MOVCF_D:
fecd2646 9376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9377 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9378 opn = "movcf.d";
dd016883 9379 break;
bf4120ad 9380 case OPC_MOVZ_D:
fecd2646 9381 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9382 {
9383 int l1 = gen_new_label();
c9297f4d 9384 TCGv_i64 fp0;
a16336e4 9385
c9297f4d
AJ
9386 if (ft != 0) {
9387 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9388 }
9389 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9390 gen_load_fpr64(ctx, fp0, fs);
9391 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9392 tcg_temp_free_i64(fp0);
a16336e4
TS
9393 gen_set_label(l1);
9394 }
5a5012ec
TS
9395 opn = "movz.d";
9396 break;
bf4120ad 9397 case OPC_MOVN_D:
fecd2646 9398 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9399 {
9400 int l1 = gen_new_label();
c9297f4d
AJ
9401 TCGv_i64 fp0;
9402
9403 if (ft != 0) {
9404 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9405 fp0 = tcg_temp_new_i64();
9406 gen_load_fpr64(ctx, fp0, fs);
9407 gen_store_fpr64(ctx, fp0, fd);
9408 tcg_temp_free_i64(fp0);
9409 gen_set_label(l1);
9410 }
a16336e4 9411 }
5a5012ec 9412 opn = "movn.d";
6ea83fed 9413 break;
bf4120ad 9414 case OPC_RECIP_D:
b8aa4598 9415 check_cp1_64bitmode(ctx);
b6d96bed 9416 {
a7812ae4 9417 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9418
9419 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9420 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9421 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9422 tcg_temp_free_i64(fp0);
b6d96bed 9423 }
57fa1fb3
TS
9424 opn = "recip.d";
9425 break;
bf4120ad 9426 case OPC_RSQRT_D:
b8aa4598 9427 check_cp1_64bitmode(ctx);
b6d96bed 9428 {
a7812ae4 9429 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9430
9431 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9432 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9433 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9434 tcg_temp_free_i64(fp0);
b6d96bed 9435 }
57fa1fb3
TS
9436 opn = "rsqrt.d";
9437 break;
e7f16abb
LA
9438 case OPC_MADDF_D:
9439 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9440 {
a7812ae4
PB
9441 TCGv_i64 fp0 = tcg_temp_new_i64();
9442 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9443 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9444 gen_load_fpr64(ctx, fp0, fs);
9445 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9446 gen_load_fpr64(ctx, fp2, fd);
9447 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9448 gen_store_fpr64(ctx, fp2, fd);
9449 tcg_temp_free_i64(fp2);
a7812ae4 9450 tcg_temp_free_i64(fp1);
a7812ae4 9451 tcg_temp_free_i64(fp0);
e7f16abb 9452 opn = "maddf.d";
b6d96bed 9453 }
57fa1fb3 9454 break;
e7f16abb
LA
9455 case OPC_MSUBF_D:
9456 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9457 {
a7812ae4 9458 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9459 TCGv_i64 fp1 = tcg_temp_new_i64();
9460 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9461 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9462 gen_load_fpr64(ctx, fp1, ft);
9463 gen_load_fpr64(ctx, fp2, fd);
9464 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9465 gen_store_fpr64(ctx, fp2, fd);
9466 tcg_temp_free_i64(fp2);
9467 tcg_temp_free_i64(fp1);
a7812ae4 9468 tcg_temp_free_i64(fp0);
e7f16abb 9469 opn = "msubf.d";
b6d96bed 9470 }
57fa1fb3 9471 break;
e7f16abb
LA
9472 case OPC_RINT_D:
9473 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9474 {
a7812ae4 9475 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9476 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9477 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9478 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9479 tcg_temp_free_i64(fp0);
e7f16abb 9480 opn = "rint.d";
b6d96bed 9481 }
57fa1fb3 9482 break;
e7f16abb
LA
9483 case OPC_CLASS_D:
9484 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9485 {
e7f16abb
LA
9486 TCGv_i64 fp0 = tcg_temp_new_i64();
9487 gen_load_fpr64(ctx, fp0, fs);
9488 gen_helper_float_class_d(fp0, fp0);
9489 gen_store_fpr64(ctx, fp0, fd);
9490 tcg_temp_free_i64(fp0);
9491 opn = "class.d";
9492 }
9493 break;
9494 case OPC_MIN_D: /* OPC_RECIP2_D */
9495 if (ctx->insn_flags & ISA_MIPS32R6) {
9496 /* OPC_MIN_D */
a7812ae4
PB
9497 TCGv_i64 fp0 = tcg_temp_new_i64();
9498 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9499 gen_load_fpr64(ctx, fp0, fs);
9500 gen_load_fpr64(ctx, fp1, ft);
9501 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9502 gen_store_fpr64(ctx, fp1, fd);
9503 tcg_temp_free_i64(fp1);
9504 tcg_temp_free_i64(fp0);
9505 opn = "min.d";
9506 } else {
9507 /* OPC_RECIP2_D */
9508 check_cp1_64bitmode(ctx);
9509 {
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9512
e7f16abb
LA
9513 gen_load_fpr64(ctx, fp0, fs);
9514 gen_load_fpr64(ctx, fp1, ft);
9515 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9516 tcg_temp_free_i64(fp1);
9517 gen_store_fpr64(ctx, fp0, fd);
9518 tcg_temp_free_i64(fp0);
9519 }
9520 opn = "recip2.d";
9521 }
9522 break;
9523 case OPC_MINA_D: /* OPC_RECIP1_D */
9524 if (ctx->insn_flags & ISA_MIPS32R6) {
9525 /* OPC_MINA_D */
9526 TCGv_i64 fp0 = tcg_temp_new_i64();
9527 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9528 gen_load_fpr64(ctx, fp0, fs);
9529 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9530 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9531 gen_store_fpr64(ctx, fp1, fd);
9532 tcg_temp_free_i64(fp1);
9533 tcg_temp_free_i64(fp0);
9534 opn = "mina.d";
9535 } else {
9536 /* OPC_RECIP1_D */
9537 check_cp1_64bitmode(ctx);
9538 {
9539 TCGv_i64 fp0 = tcg_temp_new_i64();
9540
9541 gen_load_fpr64(ctx, fp0, fs);
9542 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9543 gen_store_fpr64(ctx, fp0, fd);
9544 tcg_temp_free_i64(fp0);
9545 }
9546 opn = "recip1.d";
9547 }
9548 break;
9549 case OPC_MAX_D: /* OPC_RSQRT1_D */
9550 if (ctx->insn_flags & ISA_MIPS32R6) {
9551 /* OPC_MAX_D */
9552 TCGv_i64 fp0 = tcg_temp_new_i64();
9553 TCGv_i64 fp1 = tcg_temp_new_i64();
9554 gen_load_fpr64(ctx, fp0, fs);
9555 gen_load_fpr64(ctx, fp1, ft);
9556 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9557 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9558 tcg_temp_free_i64(fp1);
a7812ae4 9559 tcg_temp_free_i64(fp0);
e7f16abb
LA
9560 opn = "max.d";
9561 } else {
9562 /* OPC_RSQRT1_D */
9563 check_cp1_64bitmode(ctx);
9564 {
9565 TCGv_i64 fp0 = tcg_temp_new_i64();
9566
9567 gen_load_fpr64(ctx, fp0, fs);
9568 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9569 gen_store_fpr64(ctx, fp0, fd);
9570 tcg_temp_free_i64(fp0);
9571 }
9572 opn = "rsqrt1.d";
9573 }
9574 break;
9575 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9576 if (ctx->insn_flags & ISA_MIPS32R6) {
9577 /* OPC_MAXA_D */
9578 TCGv_i64 fp0 = tcg_temp_new_i64();
9579 TCGv_i64 fp1 = tcg_temp_new_i64();
9580 gen_load_fpr64(ctx, fp0, fs);
9581 gen_load_fpr64(ctx, fp1, ft);
9582 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9583 gen_store_fpr64(ctx, fp1, fd);
9584 tcg_temp_free_i64(fp1);
9585 tcg_temp_free_i64(fp0);
9586 opn = "maxa.d";
9587 } else {
9588 /* OPC_RSQRT2_D */
9589 check_cp1_64bitmode(ctx);
9590 {
9591 TCGv_i64 fp0 = tcg_temp_new_i64();
9592 TCGv_i64 fp1 = tcg_temp_new_i64();
9593
9594 gen_load_fpr64(ctx, fp0, fs);
9595 gen_load_fpr64(ctx, fp1, ft);
9596 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9597 tcg_temp_free_i64(fp1);
9598 gen_store_fpr64(ctx, fp0, fd);
9599 tcg_temp_free_i64(fp0);
9600 }
9601 opn = "rsqrt2.d";
b6d96bed 9602 }
57fa1fb3 9603 break;
bf4120ad
NF
9604 case OPC_CMP_F_D:
9605 case OPC_CMP_UN_D:
9606 case OPC_CMP_EQ_D:
9607 case OPC_CMP_UEQ_D:
9608 case OPC_CMP_OLT_D:
9609 case OPC_CMP_ULT_D:
9610 case OPC_CMP_OLE_D:
9611 case OPC_CMP_ULE_D:
9612 case OPC_CMP_SF_D:
9613 case OPC_CMP_NGLE_D:
9614 case OPC_CMP_SEQ_D:
9615 case OPC_CMP_NGL_D:
9616 case OPC_CMP_LT_D:
9617 case OPC_CMP_NGE_D:
9618 case OPC_CMP_LE_D:
9619 case OPC_CMP_NGT_D:
fecd2646 9620 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9621 if (ctx->opcode & (1 << 6)) {
9622 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9623 opn = condnames_abs[func-48];
9624 } else {
9625 gen_cmp_d(ctx, func-48, ft, fs, cc);
9626 opn = condnames[func-48];
5a1e8ffb 9627 }
6ea83fed 9628 break;
bf4120ad 9629 case OPC_CVT_S_D:
5e755519 9630 check_cp1_registers(ctx, fs);
b6d96bed 9631 {
a7812ae4
PB
9632 TCGv_i32 fp32 = tcg_temp_new_i32();
9633 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9634
9635 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9636 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9637 tcg_temp_free_i64(fp64);
b6d96bed 9638 gen_store_fpr32(fp32, fd);
a7812ae4 9639 tcg_temp_free_i32(fp32);
b6d96bed 9640 }
5a5012ec
TS
9641 opn = "cvt.s.d";
9642 break;
bf4120ad 9643 case OPC_CVT_W_D:
5e755519 9644 check_cp1_registers(ctx, fs);
b6d96bed 9645 {
a7812ae4
PB
9646 TCGv_i32 fp32 = tcg_temp_new_i32();
9647 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9648
9649 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9650 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9651 tcg_temp_free_i64(fp64);
b6d96bed 9652 gen_store_fpr32(fp32, fd);
a7812ae4 9653 tcg_temp_free_i32(fp32);
b6d96bed 9654 }
5a5012ec
TS
9655 opn = "cvt.w.d";
9656 break;
bf4120ad 9657 case OPC_CVT_L_D:
5e755519 9658 check_cp1_64bitmode(ctx);
b6d96bed 9659 {
a7812ae4 9660 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9661
9662 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9663 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9664 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9665 tcg_temp_free_i64(fp0);
b6d96bed 9666 }
5a5012ec
TS
9667 opn = "cvt.l.d";
9668 break;
bf4120ad 9669 case OPC_CVT_S_W:
b6d96bed 9670 {
a7812ae4 9671 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9672
9673 gen_load_fpr32(fp0, fs);
895c2d04 9674 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9675 gen_store_fpr32(fp0, fd);
a7812ae4 9676 tcg_temp_free_i32(fp0);
b6d96bed 9677 }
5a5012ec 9678 opn = "cvt.s.w";
6ea83fed 9679 break;
bf4120ad 9680 case OPC_CVT_D_W:
5e755519 9681 check_cp1_registers(ctx, fd);
b6d96bed 9682 {
a7812ae4
PB
9683 TCGv_i32 fp32 = tcg_temp_new_i32();
9684 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9685
9686 gen_load_fpr32(fp32, fs);
895c2d04 9687 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9688 tcg_temp_free_i32(fp32);
b6d96bed 9689 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9690 tcg_temp_free_i64(fp64);
b6d96bed 9691 }
5a5012ec
TS
9692 opn = "cvt.d.w";
9693 break;
bf4120ad 9694 case OPC_CVT_S_L:
5e755519 9695 check_cp1_64bitmode(ctx);
b6d96bed 9696 {
a7812ae4
PB
9697 TCGv_i32 fp32 = tcg_temp_new_i32();
9698 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9699
9700 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9701 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9702 tcg_temp_free_i64(fp64);
b6d96bed 9703 gen_store_fpr32(fp32, fd);
a7812ae4 9704 tcg_temp_free_i32(fp32);
b6d96bed 9705 }
5a5012ec
TS
9706 opn = "cvt.s.l";
9707 break;
bf4120ad 9708 case OPC_CVT_D_L:
5e755519 9709 check_cp1_64bitmode(ctx);
b6d96bed 9710 {
a7812ae4 9711 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9712
9713 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9714 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9715 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9716 tcg_temp_free_i64(fp0);
b6d96bed 9717 }
5a5012ec
TS
9718 opn = "cvt.d.l";
9719 break;
bf4120ad 9720 case OPC_CVT_PS_PW:
fecd2646 9721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9722 check_cp1_64bitmode(ctx);
b6d96bed 9723 {
a7812ae4 9724 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9725
9726 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9727 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9728 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9729 tcg_temp_free_i64(fp0);
b6d96bed 9730 }
5a5012ec
TS
9731 opn = "cvt.ps.pw";
9732 break;
bf4120ad 9733 case OPC_ADD_PS:
5e755519 9734 check_cp1_64bitmode(ctx);
b6d96bed 9735 {
a7812ae4
PB
9736 TCGv_i64 fp0 = tcg_temp_new_i64();
9737 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9738
9739 gen_load_fpr64(ctx, fp0, fs);
9740 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9741 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9742 tcg_temp_free_i64(fp1);
b6d96bed 9743 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9744 tcg_temp_free_i64(fp0);
b6d96bed 9745 }
5a5012ec 9746 opn = "add.ps";
6ea83fed 9747 break;
bf4120ad 9748 case OPC_SUB_PS:
5e755519 9749 check_cp1_64bitmode(ctx);
b6d96bed 9750 {
a7812ae4
PB
9751 TCGv_i64 fp0 = tcg_temp_new_i64();
9752 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9753
9754 gen_load_fpr64(ctx, fp0, fs);
9755 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9756 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9757 tcg_temp_free_i64(fp1);
b6d96bed 9758 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9759 tcg_temp_free_i64(fp0);
b6d96bed 9760 }
5a5012ec 9761 opn = "sub.ps";
6ea83fed 9762 break;
bf4120ad 9763 case OPC_MUL_PS:
5e755519 9764 check_cp1_64bitmode(ctx);
b6d96bed 9765 {
a7812ae4
PB
9766 TCGv_i64 fp0 = tcg_temp_new_i64();
9767 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9768
9769 gen_load_fpr64(ctx, fp0, fs);
9770 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9771 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9772 tcg_temp_free_i64(fp1);
b6d96bed 9773 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9774 tcg_temp_free_i64(fp0);
b6d96bed 9775 }
5a5012ec 9776 opn = "mul.ps";
6ea83fed 9777 break;
bf4120ad 9778 case OPC_ABS_PS:
5e755519 9779 check_cp1_64bitmode(ctx);
b6d96bed 9780 {
a7812ae4 9781 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9782
9783 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9784 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9785 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9786 tcg_temp_free_i64(fp0);
b6d96bed 9787 }
5a5012ec 9788 opn = "abs.ps";
6ea83fed 9789 break;
bf4120ad 9790 case OPC_MOV_PS:
5e755519 9791 check_cp1_64bitmode(ctx);
b6d96bed 9792 {
a7812ae4 9793 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9794
9795 gen_load_fpr64(ctx, fp0, fs);
9796 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9797 tcg_temp_free_i64(fp0);
b6d96bed 9798 }
5a5012ec 9799 opn = "mov.ps";
6ea83fed 9800 break;
bf4120ad 9801 case OPC_NEG_PS:
5e755519 9802 check_cp1_64bitmode(ctx);
b6d96bed 9803 {
a7812ae4 9804 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9805
9806 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9807 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9808 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9809 tcg_temp_free_i64(fp0);
b6d96bed 9810 }
5a5012ec 9811 opn = "neg.ps";
6ea83fed 9812 break;
bf4120ad 9813 case OPC_MOVCF_PS:
5e755519 9814 check_cp1_64bitmode(ctx);
7f6613ce 9815 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9816 opn = "movcf.ps";
6ea83fed 9817 break;
bf4120ad 9818 case OPC_MOVZ_PS:
5e755519 9819 check_cp1_64bitmode(ctx);
a16336e4
TS
9820 {
9821 int l1 = gen_new_label();
30a3848b 9822 TCGv_i64 fp0;
a16336e4 9823
c9297f4d
AJ
9824 if (ft != 0)
9825 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9826 fp0 = tcg_temp_new_i64();
9827 gen_load_fpr64(ctx, fp0, fs);
9828 gen_store_fpr64(ctx, fp0, fd);
9829 tcg_temp_free_i64(fp0);
a16336e4
TS
9830 gen_set_label(l1);
9831 }
5a5012ec 9832 opn = "movz.ps";
6ea83fed 9833 break;
bf4120ad 9834 case OPC_MOVN_PS:
5e755519 9835 check_cp1_64bitmode(ctx);
a16336e4
TS
9836 {
9837 int l1 = gen_new_label();
30a3848b 9838 TCGv_i64 fp0;
c9297f4d
AJ
9839
9840 if (ft != 0) {
9841 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9842 fp0 = tcg_temp_new_i64();
9843 gen_load_fpr64(ctx, fp0, fs);
9844 gen_store_fpr64(ctx, fp0, fd);
9845 tcg_temp_free_i64(fp0);
9846 gen_set_label(l1);
9847 }
a16336e4 9848 }
5a5012ec 9849 opn = "movn.ps";
6ea83fed 9850 break;
bf4120ad 9851 case OPC_ADDR_PS:
5e755519 9852 check_cp1_64bitmode(ctx);
b6d96bed 9853 {
a7812ae4
PB
9854 TCGv_i64 fp0 = tcg_temp_new_i64();
9855 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9856
9857 gen_load_fpr64(ctx, fp0, ft);
9858 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9859 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9860 tcg_temp_free_i64(fp1);
b6d96bed 9861 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9862 tcg_temp_free_i64(fp0);
b6d96bed 9863 }
fbcc6828
TS
9864 opn = "addr.ps";
9865 break;
bf4120ad 9866 case OPC_MULR_PS:
5e755519 9867 check_cp1_64bitmode(ctx);
b6d96bed 9868 {
a7812ae4
PB
9869 TCGv_i64 fp0 = tcg_temp_new_i64();
9870 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9871
9872 gen_load_fpr64(ctx, fp0, ft);
9873 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9874 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9875 tcg_temp_free_i64(fp1);
b6d96bed 9876 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9877 tcg_temp_free_i64(fp0);
b6d96bed 9878 }
57fa1fb3
TS
9879 opn = "mulr.ps";
9880 break;
bf4120ad 9881 case OPC_RECIP2_PS:
5e755519 9882 check_cp1_64bitmode(ctx);
b6d96bed 9883 {
a7812ae4
PB
9884 TCGv_i64 fp0 = tcg_temp_new_i64();
9885 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9886
9887 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9888 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9889 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9890 tcg_temp_free_i64(fp1);
b6d96bed 9891 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9892 tcg_temp_free_i64(fp0);
b6d96bed 9893 }
57fa1fb3
TS
9894 opn = "recip2.ps";
9895 break;
bf4120ad 9896 case OPC_RECIP1_PS:
5e755519 9897 check_cp1_64bitmode(ctx);
b6d96bed 9898 {
a7812ae4 9899 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9900
9901 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9902 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9903 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9904 tcg_temp_free_i64(fp0);
b6d96bed 9905 }
57fa1fb3
TS
9906 opn = "recip1.ps";
9907 break;
bf4120ad 9908 case OPC_RSQRT1_PS:
5e755519 9909 check_cp1_64bitmode(ctx);
b6d96bed 9910 {
a7812ae4 9911 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9912
9913 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9914 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9915 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9916 tcg_temp_free_i64(fp0);
b6d96bed 9917 }
57fa1fb3
TS
9918 opn = "rsqrt1.ps";
9919 break;
bf4120ad 9920 case OPC_RSQRT2_PS:
5e755519 9921 check_cp1_64bitmode(ctx);
b6d96bed 9922 {
a7812ae4
PB
9923 TCGv_i64 fp0 = tcg_temp_new_i64();
9924 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9925
9926 gen_load_fpr64(ctx, fp0, fs);
9927 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9928 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9929 tcg_temp_free_i64(fp1);
b6d96bed 9930 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9931 tcg_temp_free_i64(fp0);
b6d96bed 9932 }
57fa1fb3
TS
9933 opn = "rsqrt2.ps";
9934 break;
bf4120ad 9935 case OPC_CVT_S_PU:
5e755519 9936 check_cp1_64bitmode(ctx);
b6d96bed 9937 {
a7812ae4 9938 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9939
7f6613ce 9940 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9941 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9942 gen_store_fpr32(fp0, fd);
a7812ae4 9943 tcg_temp_free_i32(fp0);
b6d96bed 9944 }
5a5012ec 9945 opn = "cvt.s.pu";
dd016883 9946 break;
bf4120ad 9947 case OPC_CVT_PW_PS:
5e755519 9948 check_cp1_64bitmode(ctx);
b6d96bed 9949 {
a7812ae4 9950 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9951
9952 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9953 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9954 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9955 tcg_temp_free_i64(fp0);
b6d96bed 9956 }
5a5012ec 9957 opn = "cvt.pw.ps";
6ea83fed 9958 break;
bf4120ad 9959 case OPC_CVT_S_PL:
5e755519 9960 check_cp1_64bitmode(ctx);
b6d96bed 9961 {
a7812ae4 9962 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9963
9964 gen_load_fpr32(fp0, fs);
895c2d04 9965 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 9966 gen_store_fpr32(fp0, fd);
a7812ae4 9967 tcg_temp_free_i32(fp0);
b6d96bed 9968 }
5a5012ec 9969 opn = "cvt.s.pl";
6ea83fed 9970 break;
bf4120ad 9971 case OPC_PLL_PS:
5e755519 9972 check_cp1_64bitmode(ctx);
b6d96bed 9973 {
a7812ae4
PB
9974 TCGv_i32 fp0 = tcg_temp_new_i32();
9975 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9976
9977 gen_load_fpr32(fp0, fs);
9978 gen_load_fpr32(fp1, ft);
7f6613ce 9979 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 9980 gen_store_fpr32(fp1, fd);
a7812ae4
PB
9981 tcg_temp_free_i32(fp0);
9982 tcg_temp_free_i32(fp1);
b6d96bed 9983 }
5a5012ec 9984 opn = "pll.ps";
6ea83fed 9985 break;
bf4120ad 9986 case OPC_PLU_PS:
5e755519 9987 check_cp1_64bitmode(ctx);
b6d96bed 9988 {
a7812ae4
PB
9989 TCGv_i32 fp0 = tcg_temp_new_i32();
9990 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9991
9992 gen_load_fpr32(fp0, fs);
7f6613ce 9993 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 9994 gen_store_fpr32(fp1, fd);
7f6613ce 9995 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9996 tcg_temp_free_i32(fp0);
9997 tcg_temp_free_i32(fp1);
b6d96bed 9998 }
5a5012ec
TS
9999 opn = "plu.ps";
10000 break;
bf4120ad 10001 case OPC_PUL_PS:
5e755519 10002 check_cp1_64bitmode(ctx);
b6d96bed 10003 {
a7812ae4
PB
10004 TCGv_i32 fp0 = tcg_temp_new_i32();
10005 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10006
7f6613ce 10007 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
10008 gen_load_fpr32(fp1, ft);
10009 gen_store_fpr32(fp1, fd);
7f6613ce 10010 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10011 tcg_temp_free_i32(fp0);
10012 tcg_temp_free_i32(fp1);
b6d96bed 10013 }
5a5012ec
TS
10014 opn = "pul.ps";
10015 break;
bf4120ad 10016 case OPC_PUU_PS:
5e755519 10017 check_cp1_64bitmode(ctx);
b6d96bed 10018 {
a7812ae4
PB
10019 TCGv_i32 fp0 = tcg_temp_new_i32();
10020 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10021
7f6613ce
PJ
10022 gen_load_fpr32h(ctx, fp0, fs);
10023 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10024 gen_store_fpr32(fp1, fd);
7f6613ce 10025 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10026 tcg_temp_free_i32(fp0);
10027 tcg_temp_free_i32(fp1);
b6d96bed 10028 }
5a5012ec
TS
10029 opn = "puu.ps";
10030 break;
bf4120ad
NF
10031 case OPC_CMP_F_PS:
10032 case OPC_CMP_UN_PS:
10033 case OPC_CMP_EQ_PS:
10034 case OPC_CMP_UEQ_PS:
10035 case OPC_CMP_OLT_PS:
10036 case OPC_CMP_ULT_PS:
10037 case OPC_CMP_OLE_PS:
10038 case OPC_CMP_ULE_PS:
10039 case OPC_CMP_SF_PS:
10040 case OPC_CMP_NGLE_PS:
10041 case OPC_CMP_SEQ_PS:
10042 case OPC_CMP_NGL_PS:
10043 case OPC_CMP_LT_PS:
10044 case OPC_CMP_NGE_PS:
10045 case OPC_CMP_LE_PS:
10046 case OPC_CMP_NGT_PS:
8153667c
NF
10047 if (ctx->opcode & (1 << 6)) {
10048 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10049 opn = condnames_abs[func-48];
10050 } else {
10051 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10052 opn = condnames[func-48];
5a1e8ffb 10053 }
6ea83fed 10054 break;
5a5012ec 10055 default:
923617a3 10056 MIPS_INVAL(opn);
e397ee33 10057 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10058 return;
10059 }
2abf314d 10060 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10061 switch (optype) {
10062 case BINOP:
6ea83fed 10063 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10064 break;
10065 case CMPOP:
10066 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10067 break;
10068 default:
6ea83fed 10069 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10070 break;
10071 }
6ea83fed 10072}
6af0bf9c 10073
5a5012ec 10074/* Coprocessor 3 (FPU) */
5e755519
TS
10075static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10076 int fd, int fs, int base, int index)
7a387fff 10077{
923617a3 10078 const char *opn = "extended float load/store";
93b12ccc 10079 int store = 0;
4e2474d6 10080 TCGv t0 = tcg_temp_new();
7a387fff 10081
93b12ccc 10082 if (base == 0) {
6c5c1e20 10083 gen_load_gpr(t0, index);
93b12ccc 10084 } else if (index == 0) {
6c5c1e20 10085 gen_load_gpr(t0, base);
93b12ccc 10086 } else {
05168674 10087 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10088 }
5a5012ec 10089 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10090 memory access. */
5a5012ec
TS
10091 switch (opc) {
10092 case OPC_LWXC1:
8c0ab41f 10093 check_cop1x(ctx);
b6d96bed 10094 {
a7812ae4 10095 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10096
5f68f5ae 10097 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10098 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 10099 gen_store_fpr32(fp0, fd);
a7812ae4 10100 tcg_temp_free_i32(fp0);
b6d96bed 10101 }
5a5012ec
TS
10102 opn = "lwxc1";
10103 break;
10104 case OPC_LDXC1:
8c0ab41f
AJ
10105 check_cop1x(ctx);
10106 check_cp1_registers(ctx, fd);
b6d96bed 10107 {
a7812ae4 10108 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10109 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10110 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10111 tcg_temp_free_i64(fp0);
b6d96bed 10112 }
5a5012ec
TS
10113 opn = "ldxc1";
10114 break;
10115 case OPC_LUXC1:
8c0ab41f 10116 check_cp1_64bitmode(ctx);
6c5c1e20 10117 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10118 {
a7812ae4 10119 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10120
5f68f5ae 10121 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10122 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10123 tcg_temp_free_i64(fp0);
b6d96bed 10124 }
5a5012ec
TS
10125 opn = "luxc1";
10126 break;
10127 case OPC_SWXC1:
8c0ab41f 10128 check_cop1x(ctx);
b6d96bed 10129 {
a7812ae4 10130 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10131 gen_load_fpr32(fp0, fs);
5f68f5ae 10132 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10133 tcg_temp_free_i32(fp0);
b6d96bed 10134 }
5a5012ec 10135 opn = "swxc1";
93b12ccc 10136 store = 1;
5a5012ec
TS
10137 break;
10138 case OPC_SDXC1:
8c0ab41f
AJ
10139 check_cop1x(ctx);
10140 check_cp1_registers(ctx, fs);
b6d96bed 10141 {
a7812ae4 10142 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10143 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10144 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10145 tcg_temp_free_i64(fp0);
b6d96bed 10146 }
5a5012ec 10147 opn = "sdxc1";
93b12ccc 10148 store = 1;
5a5012ec
TS
10149 break;
10150 case OPC_SUXC1:
8c0ab41f 10151 check_cp1_64bitmode(ctx);
6c5c1e20 10152 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10153 {
a7812ae4 10154 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10155 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10156 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10157 tcg_temp_free_i64(fp0);
b6d96bed 10158 }
5a5012ec 10159 opn = "suxc1";
93b12ccc 10160 store = 1;
5a5012ec 10161 break;
5a5012ec 10162 }
6c5c1e20 10163 tcg_temp_free(t0);
2abf314d 10164 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10165 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10166 regnames[index], regnames[base]);
5a5012ec
TS
10167}
10168
5e755519
TS
10169static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10170 int fd, int fr, int fs, int ft)
5a5012ec 10171{
923617a3 10172 const char *opn = "flt3_arith";
5a5012ec 10173
5a5012ec
TS
10174 switch (opc) {
10175 case OPC_ALNV_PS:
b8aa4598 10176 check_cp1_64bitmode(ctx);
a16336e4 10177 {
a7812ae4 10178 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10179 TCGv_i32 fp = tcg_temp_new_i32();
10180 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
10181 int l1 = gen_new_label();
10182 int l2 = gen_new_label();
10183
6c5c1e20
TS
10184 gen_load_gpr(t0, fr);
10185 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10186
10187 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 10188 gen_load_fpr32(fp, fs);
7f6613ce 10189 gen_load_fpr32h(ctx, fph, fs);
c905fdac 10190 gen_store_fpr32(fp, fd);
7f6613ce 10191 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10192 tcg_gen_br(l2);
10193 gen_set_label(l1);
6c5c1e20
TS
10194 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10195 tcg_temp_free(t0);
a16336e4 10196#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 10197 gen_load_fpr32(fp, fs);
7f6613ce
PJ
10198 gen_load_fpr32h(ctx, fph, ft);
10199 gen_store_fpr32h(ctx, fp, fd);
c905fdac 10200 gen_store_fpr32(fph, fd);
a16336e4 10201#else
7f6613ce 10202 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
10203 gen_load_fpr32(fp, ft);
10204 gen_store_fpr32(fph, fd);
7f6613ce 10205 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10206#endif
10207 gen_set_label(l2);
c905fdac
AJ
10208 tcg_temp_free_i32(fp);
10209 tcg_temp_free_i32(fph);
a16336e4 10210 }
5a5012ec
TS
10211 opn = "alnv.ps";
10212 break;
10213 case OPC_MADD_S:
b8aa4598 10214 check_cop1x(ctx);
b6d96bed 10215 {
a7812ae4
PB
10216 TCGv_i32 fp0 = tcg_temp_new_i32();
10217 TCGv_i32 fp1 = tcg_temp_new_i32();
10218 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10219
10220 gen_load_fpr32(fp0, fs);
10221 gen_load_fpr32(fp1, ft);
10222 gen_load_fpr32(fp2, fr);
b3d6cd44 10223 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10224 tcg_temp_free_i32(fp0);
10225 tcg_temp_free_i32(fp1);
b6d96bed 10226 gen_store_fpr32(fp2, fd);
a7812ae4 10227 tcg_temp_free_i32(fp2);
b6d96bed 10228 }
5a5012ec
TS
10229 opn = "madd.s";
10230 break;
10231 case OPC_MADD_D:
b8aa4598
TS
10232 check_cop1x(ctx);
10233 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10234 {
a7812ae4
PB
10235 TCGv_i64 fp0 = tcg_temp_new_i64();
10236 TCGv_i64 fp1 = tcg_temp_new_i64();
10237 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10238
10239 gen_load_fpr64(ctx, fp0, fs);
10240 gen_load_fpr64(ctx, fp1, ft);
10241 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10242 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10243 tcg_temp_free_i64(fp0);
10244 tcg_temp_free_i64(fp1);
b6d96bed 10245 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10246 tcg_temp_free_i64(fp2);
b6d96bed 10247 }
5a5012ec
TS
10248 opn = "madd.d";
10249 break;
10250 case OPC_MADD_PS:
b8aa4598 10251 check_cp1_64bitmode(ctx);
b6d96bed 10252 {
a7812ae4
PB
10253 TCGv_i64 fp0 = tcg_temp_new_i64();
10254 TCGv_i64 fp1 = tcg_temp_new_i64();
10255 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10256
10257 gen_load_fpr64(ctx, fp0, fs);
10258 gen_load_fpr64(ctx, fp1, ft);
10259 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10260 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10261 tcg_temp_free_i64(fp0);
10262 tcg_temp_free_i64(fp1);
b6d96bed 10263 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10264 tcg_temp_free_i64(fp2);
b6d96bed 10265 }
5a5012ec
TS
10266 opn = "madd.ps";
10267 break;
10268 case OPC_MSUB_S:
b8aa4598 10269 check_cop1x(ctx);
b6d96bed 10270 {
a7812ae4
PB
10271 TCGv_i32 fp0 = tcg_temp_new_i32();
10272 TCGv_i32 fp1 = tcg_temp_new_i32();
10273 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10274
10275 gen_load_fpr32(fp0, fs);
10276 gen_load_fpr32(fp1, ft);
10277 gen_load_fpr32(fp2, fr);
b3d6cd44 10278 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10279 tcg_temp_free_i32(fp0);
10280 tcg_temp_free_i32(fp1);
b6d96bed 10281 gen_store_fpr32(fp2, fd);
a7812ae4 10282 tcg_temp_free_i32(fp2);
b6d96bed 10283 }
5a5012ec
TS
10284 opn = "msub.s";
10285 break;
10286 case OPC_MSUB_D:
b8aa4598
TS
10287 check_cop1x(ctx);
10288 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10289 {
a7812ae4
PB
10290 TCGv_i64 fp0 = tcg_temp_new_i64();
10291 TCGv_i64 fp1 = tcg_temp_new_i64();
10292 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10293
10294 gen_load_fpr64(ctx, fp0, fs);
10295 gen_load_fpr64(ctx, fp1, ft);
10296 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10297 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10298 tcg_temp_free_i64(fp0);
10299 tcg_temp_free_i64(fp1);
b6d96bed 10300 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10301 tcg_temp_free_i64(fp2);
b6d96bed 10302 }
5a5012ec
TS
10303 opn = "msub.d";
10304 break;
10305 case OPC_MSUB_PS:
b8aa4598 10306 check_cp1_64bitmode(ctx);
b6d96bed 10307 {
a7812ae4
PB
10308 TCGv_i64 fp0 = tcg_temp_new_i64();
10309 TCGv_i64 fp1 = tcg_temp_new_i64();
10310 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10311
10312 gen_load_fpr64(ctx, fp0, fs);
10313 gen_load_fpr64(ctx, fp1, ft);
10314 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10315 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10316 tcg_temp_free_i64(fp0);
10317 tcg_temp_free_i64(fp1);
b6d96bed 10318 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10319 tcg_temp_free_i64(fp2);
b6d96bed 10320 }
5a5012ec
TS
10321 opn = "msub.ps";
10322 break;
10323 case OPC_NMADD_S:
b8aa4598 10324 check_cop1x(ctx);
b6d96bed 10325 {
a7812ae4
PB
10326 TCGv_i32 fp0 = tcg_temp_new_i32();
10327 TCGv_i32 fp1 = tcg_temp_new_i32();
10328 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10329
10330 gen_load_fpr32(fp0, fs);
10331 gen_load_fpr32(fp1, ft);
10332 gen_load_fpr32(fp2, fr);
b3d6cd44 10333 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10334 tcg_temp_free_i32(fp0);
10335 tcg_temp_free_i32(fp1);
b6d96bed 10336 gen_store_fpr32(fp2, fd);
a7812ae4 10337 tcg_temp_free_i32(fp2);
b6d96bed 10338 }
5a5012ec
TS
10339 opn = "nmadd.s";
10340 break;
10341 case OPC_NMADD_D:
b8aa4598
TS
10342 check_cop1x(ctx);
10343 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10344 {
a7812ae4
PB
10345 TCGv_i64 fp0 = tcg_temp_new_i64();
10346 TCGv_i64 fp1 = tcg_temp_new_i64();
10347 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10348
10349 gen_load_fpr64(ctx, fp0, fs);
10350 gen_load_fpr64(ctx, fp1, ft);
10351 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10352 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10353 tcg_temp_free_i64(fp0);
10354 tcg_temp_free_i64(fp1);
b6d96bed 10355 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10356 tcg_temp_free_i64(fp2);
b6d96bed 10357 }
5a5012ec
TS
10358 opn = "nmadd.d";
10359 break;
10360 case OPC_NMADD_PS:
b8aa4598 10361 check_cp1_64bitmode(ctx);
b6d96bed 10362 {
a7812ae4
PB
10363 TCGv_i64 fp0 = tcg_temp_new_i64();
10364 TCGv_i64 fp1 = tcg_temp_new_i64();
10365 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10366
10367 gen_load_fpr64(ctx, fp0, fs);
10368 gen_load_fpr64(ctx, fp1, ft);
10369 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10370 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10371 tcg_temp_free_i64(fp0);
10372 tcg_temp_free_i64(fp1);
b6d96bed 10373 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10374 tcg_temp_free_i64(fp2);
b6d96bed 10375 }
5a5012ec
TS
10376 opn = "nmadd.ps";
10377 break;
10378 case OPC_NMSUB_S:
b8aa4598 10379 check_cop1x(ctx);
b6d96bed 10380 {
a7812ae4
PB
10381 TCGv_i32 fp0 = tcg_temp_new_i32();
10382 TCGv_i32 fp1 = tcg_temp_new_i32();
10383 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10384
10385 gen_load_fpr32(fp0, fs);
10386 gen_load_fpr32(fp1, ft);
10387 gen_load_fpr32(fp2, fr);
b3d6cd44 10388 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10389 tcg_temp_free_i32(fp0);
10390 tcg_temp_free_i32(fp1);
b6d96bed 10391 gen_store_fpr32(fp2, fd);
a7812ae4 10392 tcg_temp_free_i32(fp2);
b6d96bed 10393 }
5a5012ec
TS
10394 opn = "nmsub.s";
10395 break;
10396 case OPC_NMSUB_D:
b8aa4598
TS
10397 check_cop1x(ctx);
10398 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10399 {
a7812ae4
PB
10400 TCGv_i64 fp0 = tcg_temp_new_i64();
10401 TCGv_i64 fp1 = tcg_temp_new_i64();
10402 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10403
10404 gen_load_fpr64(ctx, fp0, fs);
10405 gen_load_fpr64(ctx, fp1, ft);
10406 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10407 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10408 tcg_temp_free_i64(fp0);
10409 tcg_temp_free_i64(fp1);
b6d96bed 10410 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10411 tcg_temp_free_i64(fp2);
b6d96bed 10412 }
5a5012ec
TS
10413 opn = "nmsub.d";
10414 break;
10415 case OPC_NMSUB_PS:
b8aa4598 10416 check_cp1_64bitmode(ctx);
b6d96bed 10417 {
a7812ae4
PB
10418 TCGv_i64 fp0 = tcg_temp_new_i64();
10419 TCGv_i64 fp1 = tcg_temp_new_i64();
10420 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10421
10422 gen_load_fpr64(ctx, fp0, fs);
10423 gen_load_fpr64(ctx, fp1, ft);
10424 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10425 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10426 tcg_temp_free_i64(fp0);
10427 tcg_temp_free_i64(fp1);
b6d96bed 10428 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10429 tcg_temp_free_i64(fp2);
b6d96bed 10430 }
5a5012ec
TS
10431 opn = "nmsub.ps";
10432 break;
923617a3
TS
10433 default:
10434 MIPS_INVAL(opn);
5a5012ec
TS
10435 generate_exception (ctx, EXCP_RI);
10436 return;
10437 }
2abf314d 10438 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10439 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10440 fregnames[fs], fregnames[ft]);
7a387fff
TS
10441}
10442
d75c135e 10443static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10444{
10445 TCGv t0;
10446
b3167288
RH
10447#if !defined(CONFIG_USER_ONLY)
10448 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10449 Therefore only check the ISA in system mode. */
d75c135e 10450 check_insn(ctx, ISA_MIPS32R2);
b3167288 10451#endif
26ebe468
NF
10452 t0 = tcg_temp_new();
10453
10454 switch (rd) {
10455 case 0:
10456 save_cpu_state(ctx, 1);
895c2d04 10457 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10458 gen_store_gpr(t0, rt);
10459 break;
10460 case 1:
10461 save_cpu_state(ctx, 1);
895c2d04 10462 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10463 gen_store_gpr(t0, rt);
10464 break;
10465 case 2:
10466 save_cpu_state(ctx, 1);
895c2d04 10467 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10468 gen_store_gpr(t0, rt);
10469 break;
10470 case 3:
10471 save_cpu_state(ctx, 1);
895c2d04 10472 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10473 gen_store_gpr(t0, rt);
10474 break;
10475 case 29:
10476#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10477 tcg_gen_ld_tl(t0, cpu_env,
10478 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10479 gen_store_gpr(t0, rt);
10480 break;
10481#else
d279279e
PJ
10482 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10483 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10484 tcg_gen_ld_tl(t0, cpu_env,
10485 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10486 gen_store_gpr(t0, rt);
10487 } else {
10488 generate_exception(ctx, EXCP_RI);
10489 }
10490 break;
26ebe468
NF
10491#endif
10492 default: /* Invalid */
10493 MIPS_INVAL("rdhwr");
10494 generate_exception(ctx, EXCP_RI);
10495 break;
10496 }
10497 tcg_temp_free(t0);
10498}
10499
31837be3 10500static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10501{
10502 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10503 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
10504 /* Branches completion */
10505 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10506 ctx->bstate = BS_BRANCH;
10507 save_cpu_state(ctx, 0);
10508 /* FIXME: Need to clear can_do_io. */
364d4831 10509 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10510 case MIPS_HFLAG_FBNSLOT:
10511 MIPS_DEBUG("forbidden slot");
10512 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10513 break;
c9602061
NF
10514 case MIPS_HFLAG_B:
10515 /* unconditional branch */
10516 MIPS_DEBUG("unconditional branch");
364d4831
NF
10517 if (proc_hflags & MIPS_HFLAG_BX) {
10518 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10519 }
c9602061
NF
10520 gen_goto_tb(ctx, 0, ctx->btarget);
10521 break;
10522 case MIPS_HFLAG_BL:
10523 /* blikely taken case */
10524 MIPS_DEBUG("blikely branch taken");
10525 gen_goto_tb(ctx, 0, ctx->btarget);
10526 break;
10527 case MIPS_HFLAG_BC:
10528 /* Conditional branch */
10529 MIPS_DEBUG("conditional branch");
10530 {
10531 int l1 = gen_new_label();
10532
10533 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10534 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10535 gen_set_label(l1);
10536 gen_goto_tb(ctx, 0, ctx->btarget);
10537 }
10538 break;
10539 case MIPS_HFLAG_BR:
10540 /* unconditional branch to register */
10541 MIPS_DEBUG("branch to register");
d75c135e 10542 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10543 TCGv t0 = tcg_temp_new();
10544 TCGv_i32 t1 = tcg_temp_new_i32();
10545
10546 tcg_gen_andi_tl(t0, btarget, 0x1);
10547 tcg_gen_trunc_tl_i32(t1, t0);
10548 tcg_temp_free(t0);
10549 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10550 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10551 tcg_gen_or_i32(hflags, hflags, t1);
10552 tcg_temp_free_i32(t1);
10553
10554 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10555 } else {
10556 tcg_gen_mov_tl(cpu_PC, btarget);
10557 }
c9602061
NF
10558 if (ctx->singlestep_enabled) {
10559 save_cpu_state(ctx, 0);
895c2d04 10560 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10561 }
10562 tcg_gen_exit_tb(0);
10563 break;
10564 default:
10565 MIPS_DEBUG("unknown branch");
10566 break;
10567 }
10568 }
10569}
10570
7a387fff 10571/* ISA extensions (ASEs) */
6af0bf9c 10572/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10573
10574/* MIPS16 major opcodes */
10575enum {
10576 M16_OPC_ADDIUSP = 0x00,
10577 M16_OPC_ADDIUPC = 0x01,
10578 M16_OPC_B = 0x02,
10579 M16_OPC_JAL = 0x03,
10580 M16_OPC_BEQZ = 0x04,
10581 M16_OPC_BNEQZ = 0x05,
10582 M16_OPC_SHIFT = 0x06,
10583 M16_OPC_LD = 0x07,
10584 M16_OPC_RRIA = 0x08,
10585 M16_OPC_ADDIU8 = 0x09,
10586 M16_OPC_SLTI = 0x0a,
10587 M16_OPC_SLTIU = 0x0b,
10588 M16_OPC_I8 = 0x0c,
10589 M16_OPC_LI = 0x0d,
10590 M16_OPC_CMPI = 0x0e,
10591 M16_OPC_SD = 0x0f,
10592 M16_OPC_LB = 0x10,
10593 M16_OPC_LH = 0x11,
10594 M16_OPC_LWSP = 0x12,
10595 M16_OPC_LW = 0x13,
10596 M16_OPC_LBU = 0x14,
10597 M16_OPC_LHU = 0x15,
10598 M16_OPC_LWPC = 0x16,
10599 M16_OPC_LWU = 0x17,
10600 M16_OPC_SB = 0x18,
10601 M16_OPC_SH = 0x19,
10602 M16_OPC_SWSP = 0x1a,
10603 M16_OPC_SW = 0x1b,
10604 M16_OPC_RRR = 0x1c,
10605 M16_OPC_RR = 0x1d,
10606 M16_OPC_EXTEND = 0x1e,
10607 M16_OPC_I64 = 0x1f
10608};
10609
10610/* I8 funct field */
10611enum {
10612 I8_BTEQZ = 0x0,
10613 I8_BTNEZ = 0x1,
10614 I8_SWRASP = 0x2,
10615 I8_ADJSP = 0x3,
10616 I8_SVRS = 0x4,
10617 I8_MOV32R = 0x5,
10618 I8_MOVR32 = 0x7
10619};
10620
10621/* RRR f field */
10622enum {
10623 RRR_DADDU = 0x0,
10624 RRR_ADDU = 0x1,
10625 RRR_DSUBU = 0x2,
10626 RRR_SUBU = 0x3
10627};
10628
10629/* RR funct field */
10630enum {
10631 RR_JR = 0x00,
10632 RR_SDBBP = 0x01,
10633 RR_SLT = 0x02,
10634 RR_SLTU = 0x03,
10635 RR_SLLV = 0x04,
10636 RR_BREAK = 0x05,
10637 RR_SRLV = 0x06,
10638 RR_SRAV = 0x07,
10639 RR_DSRL = 0x08,
10640 RR_CMP = 0x0a,
10641 RR_NEG = 0x0b,
10642 RR_AND = 0x0c,
10643 RR_OR = 0x0d,
10644 RR_XOR = 0x0e,
10645 RR_NOT = 0x0f,
10646 RR_MFHI = 0x10,
10647 RR_CNVT = 0x11,
10648 RR_MFLO = 0x12,
10649 RR_DSRA = 0x13,
10650 RR_DSLLV = 0x14,
10651 RR_DSRLV = 0x16,
10652 RR_DSRAV = 0x17,
10653 RR_MULT = 0x18,
10654 RR_MULTU = 0x19,
10655 RR_DIV = 0x1a,
10656 RR_DIVU = 0x1b,
10657 RR_DMULT = 0x1c,
10658 RR_DMULTU = 0x1d,
10659 RR_DDIV = 0x1e,
10660 RR_DDIVU = 0x1f
10661};
10662
10663/* I64 funct field */
10664enum {
10665 I64_LDSP = 0x0,
10666 I64_SDSP = 0x1,
10667 I64_SDRASP = 0x2,
10668 I64_DADJSP = 0x3,
10669 I64_LDPC = 0x4,
364d4831 10670 I64_DADDIU5 = 0x5,
6ea219d0
NF
10671 I64_DADDIUPC = 0x6,
10672 I64_DADDIUSP = 0x7
10673};
10674
10675/* RR ry field for CNVT */
10676enum {
10677 RR_RY_CNVT_ZEB = 0x0,
10678 RR_RY_CNVT_ZEH = 0x1,
10679 RR_RY_CNVT_ZEW = 0x2,
10680 RR_RY_CNVT_SEB = 0x4,
10681 RR_RY_CNVT_SEH = 0x5,
10682 RR_RY_CNVT_SEW = 0x6,
10683};
10684
364d4831
NF
10685static int xlat (int r)
10686{
10687 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10688
10689 return map[r];
10690}
10691
10692static void gen_mips16_save (DisasContext *ctx,
10693 int xsregs, int aregs,
10694 int do_ra, int do_s0, int do_s1,
10695 int framesize)
10696{
10697 TCGv t0 = tcg_temp_new();
10698 TCGv t1 = tcg_temp_new();
10699 int args, astatic;
10700
10701 switch (aregs) {
10702 case 0:
10703 case 1:
10704 case 2:
10705 case 3:
10706 case 11:
10707 args = 0;
10708 break;
10709 case 4:
10710 case 5:
10711 case 6:
10712 case 7:
10713 args = 1;
10714 break;
10715 case 8:
10716 case 9:
10717 case 10:
10718 args = 2;
10719 break;
10720 case 12:
10721 case 13:
10722 args = 3;
10723 break;
10724 case 14:
10725 args = 4;
10726 break;
10727 default:
10728 generate_exception(ctx, EXCP_RI);
10729 return;
10730 }
10731
10732 switch (args) {
10733 case 4:
10734 gen_base_offset_addr(ctx, t0, 29, 12);
10735 gen_load_gpr(t1, 7);
5f68f5ae 10736 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10737 /* Fall through */
10738 case 3:
10739 gen_base_offset_addr(ctx, t0, 29, 8);
10740 gen_load_gpr(t1, 6);
5f68f5ae 10741 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10742 /* Fall through */
10743 case 2:
10744 gen_base_offset_addr(ctx, t0, 29, 4);
10745 gen_load_gpr(t1, 5);
5f68f5ae 10746 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10747 /* Fall through */
10748 case 1:
10749 gen_base_offset_addr(ctx, t0, 29, 0);
10750 gen_load_gpr(t1, 4);
5f68f5ae 10751 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10752 }
10753
10754 gen_load_gpr(t0, 29);
10755
5f68f5ae
AJ
10756#define DECR_AND_STORE(reg) do { \
10757 tcg_gen_subi_tl(t0, t0, 4); \
10758 gen_load_gpr(t1, reg); \
10759 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10760 } while (0)
10761
10762 if (do_ra) {
10763 DECR_AND_STORE(31);
10764 }
10765
10766 switch (xsregs) {
10767 case 7:
10768 DECR_AND_STORE(30);
10769 /* Fall through */
10770 case 6:
10771 DECR_AND_STORE(23);
10772 /* Fall through */
10773 case 5:
10774 DECR_AND_STORE(22);
10775 /* Fall through */
10776 case 4:
10777 DECR_AND_STORE(21);
10778 /* Fall through */
10779 case 3:
10780 DECR_AND_STORE(20);
10781 /* Fall through */
10782 case 2:
10783 DECR_AND_STORE(19);
10784 /* Fall through */
10785 case 1:
10786 DECR_AND_STORE(18);
10787 }
10788
10789 if (do_s1) {
10790 DECR_AND_STORE(17);
10791 }
10792 if (do_s0) {
10793 DECR_AND_STORE(16);
10794 }
10795
10796 switch (aregs) {
10797 case 0:
10798 case 4:
10799 case 8:
10800 case 12:
10801 case 14:
10802 astatic = 0;
10803 break;
10804 case 1:
10805 case 5:
10806 case 9:
10807 case 13:
10808 astatic = 1;
10809 break;
10810 case 2:
10811 case 6:
10812 case 10:
10813 astatic = 2;
10814 break;
10815 case 3:
10816 case 7:
10817 astatic = 3;
10818 break;
10819 case 11:
10820 astatic = 4;
10821 break;
10822 default:
10823 generate_exception(ctx, EXCP_RI);
10824 return;
10825 }
10826
10827 if (astatic > 0) {
10828 DECR_AND_STORE(7);
10829 if (astatic > 1) {
10830 DECR_AND_STORE(6);
10831 if (astatic > 2) {
10832 DECR_AND_STORE(5);
10833 if (astatic > 3) {
10834 DECR_AND_STORE(4);
10835 }
10836 }
10837 }
10838 }
10839#undef DECR_AND_STORE
10840
10841 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10842 tcg_temp_free(t0);
10843 tcg_temp_free(t1);
10844}
10845
10846static void gen_mips16_restore (DisasContext *ctx,
10847 int xsregs, int aregs,
10848 int do_ra, int do_s0, int do_s1,
10849 int framesize)
10850{
10851 int astatic;
10852 TCGv t0 = tcg_temp_new();
10853 TCGv t1 = tcg_temp_new();
10854
10855 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10856
5f68f5ae
AJ
10857#define DECR_AND_LOAD(reg) do { \
10858 tcg_gen_subi_tl(t0, t0, 4); \
10859 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10860 gen_store_gpr(t1, reg); \
364d4831
NF
10861 } while (0)
10862
10863 if (do_ra) {
10864 DECR_AND_LOAD(31);
10865 }
10866
10867 switch (xsregs) {
10868 case 7:
10869 DECR_AND_LOAD(30);
10870 /* Fall through */
10871 case 6:
10872 DECR_AND_LOAD(23);
10873 /* Fall through */
10874 case 5:
10875 DECR_AND_LOAD(22);
10876 /* Fall through */
10877 case 4:
10878 DECR_AND_LOAD(21);
10879 /* Fall through */
10880 case 3:
10881 DECR_AND_LOAD(20);
10882 /* Fall through */
10883 case 2:
10884 DECR_AND_LOAD(19);
10885 /* Fall through */
10886 case 1:
10887 DECR_AND_LOAD(18);
10888 }
10889
10890 if (do_s1) {
10891 DECR_AND_LOAD(17);
10892 }
10893 if (do_s0) {
10894 DECR_AND_LOAD(16);
10895 }
10896
10897 switch (aregs) {
10898 case 0:
10899 case 4:
10900 case 8:
10901 case 12:
10902 case 14:
10903 astatic = 0;
10904 break;
10905 case 1:
10906 case 5:
10907 case 9:
10908 case 13:
10909 astatic = 1;
10910 break;
10911 case 2:
10912 case 6:
10913 case 10:
10914 astatic = 2;
10915 break;
10916 case 3:
10917 case 7:
10918 astatic = 3;
10919 break;
10920 case 11:
10921 astatic = 4;
10922 break;
10923 default:
10924 generate_exception(ctx, EXCP_RI);
10925 return;
10926 }
10927
10928 if (astatic > 0) {
10929 DECR_AND_LOAD(7);
10930 if (astatic > 1) {
10931 DECR_AND_LOAD(6);
10932 if (astatic > 2) {
10933 DECR_AND_LOAD(5);
10934 if (astatic > 3) {
10935 DECR_AND_LOAD(4);
10936 }
10937 }
10938 }
10939 }
10940#undef DECR_AND_LOAD
10941
10942 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10943 tcg_temp_free(t0);
10944 tcg_temp_free(t1);
10945}
10946
10947static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10948 int is_64_bit, int extended)
10949{
10950 TCGv t0;
10951
10952 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10953 generate_exception(ctx, EXCP_RI);
10954 return;
10955 }
10956
10957 t0 = tcg_temp_new();
10958
10959 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10960 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10961 if (!is_64_bit) {
10962 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10963 }
10964
10965 tcg_temp_free(t0);
10966}
10967
10968#if defined(TARGET_MIPS64)
d75c135e 10969static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
10970 int ry, int funct, int16_t offset,
10971 int extended)
10972{
10973 switch (funct) {
10974 case I64_LDSP:
10975 check_mips_64(ctx);
10976 offset = extended ? offset : offset << 3;
d75c135e 10977 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
10978 break;
10979 case I64_SDSP:
10980 check_mips_64(ctx);
10981 offset = extended ? offset : offset << 3;
5c13fdfd 10982 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
10983 break;
10984 case I64_SDRASP:
10985 check_mips_64(ctx);
10986 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 10987 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
10988 break;
10989 case I64_DADJSP:
10990 check_mips_64(ctx);
10991 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 10992 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
10993 break;
10994 case I64_LDPC:
10995 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10996 generate_exception(ctx, EXCP_RI);
10997 } else {
10998 offset = extended ? offset : offset << 3;
d75c135e 10999 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11000 }
11001 break;
11002 case I64_DADDIU5:
11003 check_mips_64(ctx);
11004 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11005 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11006 break;
11007 case I64_DADDIUPC:
11008 check_mips_64(ctx);
11009 offset = extended ? offset : offset << 2;
11010 gen_addiupc(ctx, ry, offset, 1, extended);
11011 break;
11012 case I64_DADDIUSP:
11013 check_mips_64(ctx);
11014 offset = extended ? offset : offset << 2;
d75c135e 11015 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11016 break;
11017 }
11018}
11019#endif
11020
240ce26a 11021static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11022{
895c2d04 11023 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11024 int op, rx, ry, funct, sa;
11025 int16_t imm, offset;
11026
11027 ctx->opcode = (ctx->opcode << 16) | extend;
11028 op = (ctx->opcode >> 11) & 0x1f;
11029 sa = (ctx->opcode >> 22) & 0x1f;
11030 funct = (ctx->opcode >> 8) & 0x7;
11031 rx = xlat((ctx->opcode >> 8) & 0x7);
11032 ry = xlat((ctx->opcode >> 5) & 0x7);
11033 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11034 | ((ctx->opcode >> 21) & 0x3f) << 5
11035 | (ctx->opcode & 0x1f));
11036
11037 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11038 counterparts. */
11039 switch (op) {
11040 case M16_OPC_ADDIUSP:
d75c135e 11041 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11042 break;
11043 case M16_OPC_ADDIUPC:
11044 gen_addiupc(ctx, rx, imm, 0, 1);
11045 break;
11046 case M16_OPC_B:
b231c103 11047 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11048 /* No delay slot, so just process as a normal instruction */
11049 break;
11050 case M16_OPC_BEQZ:
b231c103 11051 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11052 /* No delay slot, so just process as a normal instruction */
11053 break;
11054 case M16_OPC_BNEQZ:
b231c103 11055 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11056 /* No delay slot, so just process as a normal instruction */
11057 break;
11058 case M16_OPC_SHIFT:
11059 switch (ctx->opcode & 0x3) {
11060 case 0x0:
d75c135e 11061 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11062 break;
11063 case 0x1:
11064#if defined(TARGET_MIPS64)
11065 check_mips_64(ctx);
d75c135e 11066 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11067#else
11068 generate_exception(ctx, EXCP_RI);
11069#endif
11070 break;
11071 case 0x2:
d75c135e 11072 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11073 break;
11074 case 0x3:
d75c135e 11075 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11076 break;
11077 }
11078 break;
11079#if defined(TARGET_MIPS64)
11080 case M16_OPC_LD:
11081 check_mips_64(ctx);
d75c135e 11082 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11083 break;
11084#endif
11085 case M16_OPC_RRIA:
11086 imm = ctx->opcode & 0xf;
11087 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11088 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11089 imm = (int16_t) (imm << 1) >> 1;
11090 if ((ctx->opcode >> 4) & 0x1) {
11091#if defined(TARGET_MIPS64)
11092 check_mips_64(ctx);
d75c135e 11093 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11094#else
11095 generate_exception(ctx, EXCP_RI);
11096#endif
11097 } else {
d75c135e 11098 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11099 }
11100 break;
11101 case M16_OPC_ADDIU8:
d75c135e 11102 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11103 break;
11104 case M16_OPC_SLTI:
d75c135e 11105 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11106 break;
11107 case M16_OPC_SLTIU:
d75c135e 11108 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11109 break;
11110 case M16_OPC_I8:
11111 switch (funct) {
11112 case I8_BTEQZ:
b231c103 11113 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11114 break;
11115 case I8_BTNEZ:
b231c103 11116 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11117 break;
11118 case I8_SWRASP:
5c13fdfd 11119 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11120 break;
11121 case I8_ADJSP:
d75c135e 11122 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11123 break;
11124 case I8_SVRS:
11125 {
11126 int xsregs = (ctx->opcode >> 24) & 0x7;
11127 int aregs = (ctx->opcode >> 16) & 0xf;
11128 int do_ra = (ctx->opcode >> 6) & 0x1;
11129 int do_s0 = (ctx->opcode >> 5) & 0x1;
11130 int do_s1 = (ctx->opcode >> 4) & 0x1;
11131 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11132 | (ctx->opcode & 0xf)) << 3;
11133
11134 if (ctx->opcode & (1 << 7)) {
11135 gen_mips16_save(ctx, xsregs, aregs,
11136 do_ra, do_s0, do_s1,
11137 framesize);
11138 } else {
11139 gen_mips16_restore(ctx, xsregs, aregs,
11140 do_ra, do_s0, do_s1,
11141 framesize);
11142 }
11143 }
11144 break;
11145 default:
11146 generate_exception(ctx, EXCP_RI);
11147 break;
11148 }
11149 break;
11150 case M16_OPC_LI:
11151 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11152 break;
11153 case M16_OPC_CMPI:
11154 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11155 break;
11156#if defined(TARGET_MIPS64)
11157 case M16_OPC_SD:
5c13fdfd 11158 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11159 break;
11160#endif
11161 case M16_OPC_LB:
d75c135e 11162 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11163 break;
11164 case M16_OPC_LH:
d75c135e 11165 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11166 break;
11167 case M16_OPC_LWSP:
d75c135e 11168 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11169 break;
11170 case M16_OPC_LW:
d75c135e 11171 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11172 break;
11173 case M16_OPC_LBU:
d75c135e 11174 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11175 break;
11176 case M16_OPC_LHU:
d75c135e 11177 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11178 break;
11179 case M16_OPC_LWPC:
d75c135e 11180 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11181 break;
11182#if defined(TARGET_MIPS64)
11183 case M16_OPC_LWU:
d75c135e 11184 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11185 break;
11186#endif
11187 case M16_OPC_SB:
5c13fdfd 11188 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11189 break;
11190 case M16_OPC_SH:
5c13fdfd 11191 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11192 break;
11193 case M16_OPC_SWSP:
5c13fdfd 11194 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11195 break;
11196 case M16_OPC_SW:
5c13fdfd 11197 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11198 break;
11199#if defined(TARGET_MIPS64)
11200 case M16_OPC_I64:
d75c135e 11201 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11202 break;
11203#endif
11204 default:
11205 generate_exception(ctx, EXCP_RI);
11206 break;
11207 }
11208
11209 return 4;
11210}
11211
240ce26a 11212static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11213{
11214 int rx, ry;
11215 int sa;
11216 int op, cnvt_op, op1, offset;
11217 int funct;
11218 int n_bytes;
11219
11220 op = (ctx->opcode >> 11) & 0x1f;
11221 sa = (ctx->opcode >> 2) & 0x7;
11222 sa = sa == 0 ? 8 : sa;
11223 rx = xlat((ctx->opcode >> 8) & 0x7);
11224 cnvt_op = (ctx->opcode >> 5) & 0x7;
11225 ry = xlat((ctx->opcode >> 5) & 0x7);
11226 op1 = offset = ctx->opcode & 0x1f;
11227
11228 n_bytes = 2;
11229
11230 switch (op) {
11231 case M16_OPC_ADDIUSP:
11232 {
11233 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11234
d75c135e 11235 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11236 }
11237 break;
11238 case M16_OPC_ADDIUPC:
11239 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11240 break;
11241 case M16_OPC_B:
11242 offset = (ctx->opcode & 0x7ff) << 1;
11243 offset = (int16_t)(offset << 4) >> 4;
b231c103 11244 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11245 /* No delay slot, so just process as a normal instruction */
11246 break;
11247 case M16_OPC_JAL:
895c2d04 11248 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11249 offset = (((ctx->opcode & 0x1f) << 21)
11250 | ((ctx->opcode >> 5) & 0x1f) << 16
11251 | offset) << 2;
b231c103
YK
11252 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11253 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11254 n_bytes = 4;
364d4831
NF
11255 break;
11256 case M16_OPC_BEQZ:
b231c103
YK
11257 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11258 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11259 /* No delay slot, so just process as a normal instruction */
11260 break;
11261 case M16_OPC_BNEQZ:
b231c103
YK
11262 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11263 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11264 /* No delay slot, so just process as a normal instruction */
11265 break;
11266 case M16_OPC_SHIFT:
11267 switch (ctx->opcode & 0x3) {
11268 case 0x0:
d75c135e 11269 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11270 break;
11271 case 0x1:
11272#if defined(TARGET_MIPS64)
11273 check_mips_64(ctx);
d75c135e 11274 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11275#else
11276 generate_exception(ctx, EXCP_RI);
11277#endif
11278 break;
11279 case 0x2:
d75c135e 11280 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11281 break;
11282 case 0x3:
d75c135e 11283 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11284 break;
11285 }
11286 break;
11287#if defined(TARGET_MIPS64)
11288 case M16_OPC_LD:
11289 check_mips_64(ctx);
d75c135e 11290 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11291 break;
11292#endif
11293 case M16_OPC_RRIA:
11294 {
11295 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11296
11297 if ((ctx->opcode >> 4) & 1) {
11298#if defined(TARGET_MIPS64)
11299 check_mips_64(ctx);
d75c135e 11300 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11301#else
11302 generate_exception(ctx, EXCP_RI);
11303#endif
11304 } else {
d75c135e 11305 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11306 }
11307 }
11308 break;
11309 case M16_OPC_ADDIU8:
11310 {
11311 int16_t imm = (int8_t) ctx->opcode;
11312
d75c135e 11313 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11314 }
11315 break;
11316 case M16_OPC_SLTI:
11317 {
11318 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11319 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11320 }
11321 break;
11322 case M16_OPC_SLTIU:
11323 {
11324 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11325 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11326 }
11327 break;
11328 case M16_OPC_I8:
11329 {
11330 int reg32;
11331
11332 funct = (ctx->opcode >> 8) & 0x7;
11333 switch (funct) {
11334 case I8_BTEQZ:
11335 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11336 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11337 break;
11338 case I8_BTNEZ:
11339 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11340 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11341 break;
11342 case I8_SWRASP:
5c13fdfd 11343 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11344 break;
11345 case I8_ADJSP:
d75c135e 11346 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11347 ((int8_t)ctx->opcode) << 3);
11348 break;
11349 case I8_SVRS:
11350 {
11351 int do_ra = ctx->opcode & (1 << 6);
11352 int do_s0 = ctx->opcode & (1 << 5);
11353 int do_s1 = ctx->opcode & (1 << 4);
11354 int framesize = ctx->opcode & 0xf;
11355
11356 if (framesize == 0) {
11357 framesize = 128;
11358 } else {
11359 framesize = framesize << 3;
11360 }
11361
11362 if (ctx->opcode & (1 << 7)) {
11363 gen_mips16_save(ctx, 0, 0,
11364 do_ra, do_s0, do_s1, framesize);
11365 } else {
11366 gen_mips16_restore(ctx, 0, 0,
11367 do_ra, do_s0, do_s1, framesize);
11368 }
11369 }
11370 break;
11371 case I8_MOV32R:
11372 {
11373 int rz = xlat(ctx->opcode & 0x7);
11374
11375 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11376 ((ctx->opcode >> 5) & 0x7);
d75c135e 11377 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11378 }
11379 break;
11380 case I8_MOVR32:
11381 reg32 = ctx->opcode & 0x1f;
d75c135e 11382 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11383 break;
11384 default:
11385 generate_exception(ctx, EXCP_RI);
11386 break;
11387 }
11388 }
11389 break;
11390 case M16_OPC_LI:
11391 {
11392 int16_t imm = (uint8_t) ctx->opcode;
11393
d75c135e 11394 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11395 }
11396 break;
11397 case M16_OPC_CMPI:
11398 {
11399 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11400 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11401 }
11402 break;
11403#if defined(TARGET_MIPS64)
11404 case M16_OPC_SD:
11405 check_mips_64(ctx);
5c13fdfd 11406 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11407 break;
11408#endif
11409 case M16_OPC_LB:
d75c135e 11410 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11411 break;
11412 case M16_OPC_LH:
d75c135e 11413 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11414 break;
11415 case M16_OPC_LWSP:
d75c135e 11416 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11417 break;
11418 case M16_OPC_LW:
d75c135e 11419 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11420 break;
11421 case M16_OPC_LBU:
d75c135e 11422 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11423 break;
11424 case M16_OPC_LHU:
d75c135e 11425 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11426 break;
11427 case M16_OPC_LWPC:
d75c135e 11428 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11429 break;
11430#if defined (TARGET_MIPS64)
11431 case M16_OPC_LWU:
11432 check_mips_64(ctx);
d75c135e 11433 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11434 break;
11435#endif
11436 case M16_OPC_SB:
5c13fdfd 11437 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11438 break;
11439 case M16_OPC_SH:
5c13fdfd 11440 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11441 break;
11442 case M16_OPC_SWSP:
5c13fdfd 11443 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11444 break;
11445 case M16_OPC_SW:
5c13fdfd 11446 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11447 break;
11448 case M16_OPC_RRR:
11449 {
11450 int rz = xlat((ctx->opcode >> 2) & 0x7);
11451 int mips32_op;
11452
11453 switch (ctx->opcode & 0x3) {
11454 case RRR_ADDU:
11455 mips32_op = OPC_ADDU;
11456 break;
11457 case RRR_SUBU:
11458 mips32_op = OPC_SUBU;
11459 break;
11460#if defined(TARGET_MIPS64)
11461 case RRR_DADDU:
11462 mips32_op = OPC_DADDU;
11463 check_mips_64(ctx);
11464 break;
11465 case RRR_DSUBU:
11466 mips32_op = OPC_DSUBU;
11467 check_mips_64(ctx);
11468 break;
11469#endif
11470 default:
11471 generate_exception(ctx, EXCP_RI);
11472 goto done;
11473 }
11474
d75c135e 11475 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11476 done:
11477 ;
11478 }
11479 break;
11480 case M16_OPC_RR:
11481 switch (op1) {
11482 case RR_JR:
11483 {
11484 int nd = (ctx->opcode >> 7) & 0x1;
11485 int link = (ctx->opcode >> 6) & 0x1;
11486 int ra = (ctx->opcode >> 5) & 0x1;
11487
11488 if (link) {
b231c103 11489 op = OPC_JALR;
364d4831
NF
11490 } else {
11491 op = OPC_JR;
11492 }
11493
b231c103
YK
11494 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11495 (nd ? 0 : 2));
364d4831
NF
11496 }
11497 break;
11498 case RR_SDBBP:
11499 /* XXX: not clear which exception should be raised
11500 * when in debug mode...
11501 */
d75c135e 11502 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11503 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11504 generate_exception(ctx, EXCP_DBp);
11505 } else {
11506 generate_exception(ctx, EXCP_DBp);
11507 }
11508 break;
11509 case RR_SLT:
d75c135e 11510 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11511 break;
11512 case RR_SLTU:
d75c135e 11513 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11514 break;
11515 case RR_BREAK:
11516 generate_exception(ctx, EXCP_BREAK);
11517 break;
11518 case RR_SLLV:
d75c135e 11519 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11520 break;
11521 case RR_SRLV:
d75c135e 11522 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11523 break;
11524 case RR_SRAV:
d75c135e 11525 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11526 break;
11527#if defined (TARGET_MIPS64)
11528 case RR_DSRL:
11529 check_mips_64(ctx);
d75c135e 11530 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11531 break;
11532#endif
11533 case RR_CMP:
d75c135e 11534 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11535 break;
11536 case RR_NEG:
d75c135e 11537 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11538 break;
11539 case RR_AND:
d75c135e 11540 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11541 break;
11542 case RR_OR:
d75c135e 11543 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11544 break;
11545 case RR_XOR:
d75c135e 11546 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11547 break;
11548 case RR_NOT:
d75c135e 11549 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11550 break;
11551 case RR_MFHI:
26135ead 11552 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11553 break;
11554 case RR_CNVT:
11555 switch (cnvt_op) {
11556 case RR_RY_CNVT_ZEB:
11557 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11558 break;
11559 case RR_RY_CNVT_ZEH:
11560 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11561 break;
11562 case RR_RY_CNVT_SEB:
11563 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11564 break;
11565 case RR_RY_CNVT_SEH:
11566 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11567 break;
11568#if defined (TARGET_MIPS64)
11569 case RR_RY_CNVT_ZEW:
11570 check_mips_64(ctx);
11571 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11572 break;
11573 case RR_RY_CNVT_SEW:
11574 check_mips_64(ctx);
11575 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11576 break;
11577#endif
11578 default:
11579 generate_exception(ctx, EXCP_RI);
11580 break;
11581 }
11582 break;
11583 case RR_MFLO:
26135ead 11584 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11585 break;
11586#if defined (TARGET_MIPS64)
11587 case RR_DSRA:
11588 check_mips_64(ctx);
d75c135e 11589 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11590 break;
11591 case RR_DSLLV:
11592 check_mips_64(ctx);
d75c135e 11593 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11594 break;
11595 case RR_DSRLV:
11596 check_mips_64(ctx);
d75c135e 11597 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11598 break;
11599 case RR_DSRAV:
11600 check_mips_64(ctx);
d75c135e 11601 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11602 break;
11603#endif
11604 case RR_MULT:
26135ead 11605 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11606 break;
11607 case RR_MULTU:
26135ead 11608 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11609 break;
11610 case RR_DIV:
26135ead 11611 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11612 break;
11613 case RR_DIVU:
26135ead 11614 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11615 break;
11616#if defined (TARGET_MIPS64)
11617 case RR_DMULT:
11618 check_mips_64(ctx);
26135ead 11619 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11620 break;
11621 case RR_DMULTU:
11622 check_mips_64(ctx);
26135ead 11623 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11624 break;
11625 case RR_DDIV:
11626 check_mips_64(ctx);
26135ead 11627 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11628 break;
11629 case RR_DDIVU:
11630 check_mips_64(ctx);
26135ead 11631 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11632 break;
11633#endif
11634 default:
11635 generate_exception(ctx, EXCP_RI);
11636 break;
11637 }
11638 break;
11639 case M16_OPC_EXTEND:
240ce26a 11640 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11641 n_bytes = 4;
11642 break;
11643#if defined(TARGET_MIPS64)
11644 case M16_OPC_I64:
11645 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11646 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11647 break;
11648#endif
11649 default:
11650 generate_exception(ctx, EXCP_RI);
11651 break;
11652 }
11653
11654 return n_bytes;
11655}
11656
211da992 11657/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11658
211da992
CWR
11659/*
11660 * microMIPS32/microMIPS64 major opcodes
11661 *
11662 * 1. MIPS Architecture for Programmers Volume II-B:
11663 * The microMIPS32 Instruction Set (Revision 3.05)
11664 *
11665 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11666 *
11667 * 2. MIPS Architecture For Programmers Volume II-A:
11668 * The MIPS64 Instruction Set (Revision 3.51)
11669 */
6af0bf9c 11670
3c824109
NF
11671enum {
11672 POOL32A = 0x00,
11673 POOL16A = 0x01,
11674 LBU16 = 0x02,
11675 MOVE16 = 0x03,
11676 ADDI32 = 0x04,
11677 LBU32 = 0x05,
11678 SB32 = 0x06,
11679 LB32 = 0x07,
11680
11681 POOL32B = 0x08,
11682 POOL16B = 0x09,
11683 LHU16 = 0x0a,
11684 ANDI16 = 0x0b,
11685 ADDIU32 = 0x0c,
11686 LHU32 = 0x0d,
11687 SH32 = 0x0e,
11688 LH32 = 0x0f,
11689
11690 POOL32I = 0x10,
11691 POOL16C = 0x11,
11692 LWSP16 = 0x12,
11693 POOL16D = 0x13,
11694 ORI32 = 0x14,
11695 POOL32F = 0x15,
211da992
CWR
11696 POOL32S = 0x16, /* MIPS64 */
11697 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11698
211da992 11699 /* 0x1f is reserved */
3c824109
NF
11700 POOL32C = 0x18,
11701 LWGP16 = 0x19,
11702 LW16 = 0x1a,
11703 POOL16E = 0x1b,
11704 XORI32 = 0x1c,
11705 JALS32 = 0x1d,
11706 ADDIUPC = 0x1e,
3c824109
NF
11707
11708 /* 0x20 is reserved */
11709 RES_20 = 0x20,
11710 POOL16F = 0x21,
11711 SB16 = 0x22,
11712 BEQZ16 = 0x23,
11713 SLTI32 = 0x24,
11714 BEQ32 = 0x25,
11715 SWC132 = 0x26,
11716 LWC132 = 0x27,
11717
11718 /* 0x28 and 0x29 are reserved */
11719 RES_28 = 0x28,
11720 RES_29 = 0x29,
11721 SH16 = 0x2a,
11722 BNEZ16 = 0x2b,
11723 SLTIU32 = 0x2c,
11724 BNE32 = 0x2d,
11725 SDC132 = 0x2e,
11726 LDC132 = 0x2f,
11727
11728 /* 0x30 and 0x31 are reserved */
11729 RES_30 = 0x30,
11730 RES_31 = 0x31,
11731 SWSP16 = 0x32,
11732 B16 = 0x33,
11733 ANDI32 = 0x34,
11734 J32 = 0x35,
211da992
CWR
11735 SD32 = 0x36, /* MIPS64 */
11736 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11737
11738 /* 0x38 and 0x39 are reserved */
11739 RES_38 = 0x38,
11740 RES_39 = 0x39,
11741 SW16 = 0x3a,
11742 LI16 = 0x3b,
11743 JALX32 = 0x3c,
11744 JAL32 = 0x3d,
11745 SW32 = 0x3e,
11746 LW32 = 0x3f
11747};
11748
11749/* POOL32A encoding of minor opcode field */
11750
11751enum {
11752 /* These opcodes are distinguished only by bits 9..6; those bits are
11753 * what are recorded below. */
11754 SLL32 = 0x0,
11755 SRL32 = 0x1,
11756 SRA = 0x2,
11757 ROTR = 0x3,
11758
11759 SLLV = 0x0,
11760 SRLV = 0x1,
11761 SRAV = 0x2,
11762 ROTRV = 0x3,
11763 ADD = 0x4,
11764 ADDU32 = 0x5,
11765 SUB = 0x6,
11766 SUBU32 = 0x7,
11767 MUL = 0x8,
11768 AND = 0x9,
11769 OR32 = 0xa,
11770 NOR = 0xb,
11771 XOR32 = 0xc,
11772 SLT = 0xd,
11773 SLTU = 0xe,
11774
11775 MOVN = 0x0,
11776 MOVZ = 0x1,
11777 LWXS = 0x4,
11778
11779 /* The following can be distinguished by their lower 6 bits. */
11780 INS = 0x0c,
11781 EXT = 0x2c,
11782 POOL32AXF = 0x3c
11783};
11784
11785/* POOL32AXF encoding of minor opcode field extension */
11786
d132c79f
CWR
11787/*
11788 * 1. MIPS Architecture for Programmers Volume II-B:
11789 * The microMIPS32 Instruction Set (Revision 3.05)
11790 *
11791 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11792 *
11793 * 2. MIPS Architecture for Programmers VolumeIV-e:
11794 * The MIPS DSP Application-Specific Extension
11795 * to the microMIPS32 Architecture (Revision 2.34)
11796 *
11797 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11798 */
11799
3c824109
NF
11800enum {
11801 /* bits 11..6 */
11802 TEQ = 0x00,
11803 TGE = 0x08,
11804 TGEU = 0x10,
11805 TLT = 0x20,
11806 TLTU = 0x28,
11807 TNE = 0x30,
11808
11809 MFC0 = 0x03,
11810 MTC0 = 0x0b,
11811
d132c79f
CWR
11812 /* begin of microMIPS32 DSP */
11813
3c824109
NF
11814 /* bits 13..12 for 0x01 */
11815 MFHI_ACC = 0x0,
11816 MFLO_ACC = 0x1,
11817 MTHI_ACC = 0x2,
11818 MTLO_ACC = 0x3,
11819
11820 /* bits 13..12 for 0x2a */
11821 MADD_ACC = 0x0,
11822 MADDU_ACC = 0x1,
11823 MSUB_ACC = 0x2,
11824 MSUBU_ACC = 0x3,
11825
11826 /* bits 13..12 for 0x32 */
11827 MULT_ACC = 0x0,
6801038b 11828 MULTU_ACC = 0x1,
3c824109 11829
d132c79f
CWR
11830 /* end of microMIPS32 DSP */
11831
3c824109
NF
11832 /* bits 15..12 for 0x2c */
11833 SEB = 0x2,
11834 SEH = 0x3,
11835 CLO = 0x4,
11836 CLZ = 0x5,
11837 RDHWR = 0x6,
11838 WSBH = 0x7,
11839 MULT = 0x8,
11840 MULTU = 0x9,
11841 DIV = 0xa,
11842 DIVU = 0xb,
11843 MADD = 0xc,
11844 MADDU = 0xd,
11845 MSUB = 0xe,
11846 MSUBU = 0xf,
11847
11848 /* bits 15..12 for 0x34 */
11849 MFC2 = 0x4,
11850 MTC2 = 0x5,
11851 MFHC2 = 0x8,
11852 MTHC2 = 0x9,
11853 CFC2 = 0xc,
11854 CTC2 = 0xd,
11855
11856 /* bits 15..12 for 0x3c */
11857 JALR = 0x0,
11858 JR = 0x0, /* alias */
11859 JALR_HB = 0x1,
11860 JALRS = 0x4,
11861 JALRS_HB = 0x5,
11862
11863 /* bits 15..12 for 0x05 */
11864 RDPGPR = 0xe,
11865 WRPGPR = 0xf,
11866
11867 /* bits 15..12 for 0x0d */
11868 TLBP = 0x0,
11869 TLBR = 0x1,
11870 TLBWI = 0x2,
11871 TLBWR = 0x3,
11872 WAIT = 0x9,
11873 IRET = 0xd,
11874 DERET = 0xe,
11875 ERET = 0xf,
11876
11877 /* bits 15..12 for 0x15 */
11878 DMT = 0x0,
11879 DVPE = 0x1,
11880 EMT = 0x2,
11881 EVPE = 0x3,
11882
11883 /* bits 15..12 for 0x1d */
11884 DI = 0x4,
11885 EI = 0x5,
11886
11887 /* bits 15..12 for 0x2d */
11888 SYNC = 0x6,
11889 SYSCALL = 0x8,
11890 SDBBP = 0xd,
11891
11892 /* bits 15..12 for 0x35 */
11893 MFHI32 = 0x0,
11894 MFLO32 = 0x1,
11895 MTHI32 = 0x2,
11896 MTLO32 = 0x3,
11897};
11898
11899/* POOL32B encoding of minor opcode field (bits 15..12) */
11900
11901enum {
11902 LWC2 = 0x0,
11903 LWP = 0x1,
11904 LDP = 0x4,
11905 LWM32 = 0x5,
11906 CACHE = 0x6,
11907 LDM = 0x7,
11908 SWC2 = 0x8,
11909 SWP = 0x9,
11910 SDP = 0xc,
11911 SWM32 = 0xd,
11912 SDM = 0xf
11913};
11914
11915/* POOL32C encoding of minor opcode field (bits 15..12) */
11916
11917enum {
11918 LWL = 0x0,
11919 SWL = 0x8,
11920 LWR = 0x1,
11921 SWR = 0x9,
11922 PREF = 0x2,
11923 /* 0xa is reserved */
11924 LL = 0x3,
11925 SC = 0xb,
11926 LDL = 0x4,
11927 SDL = 0xc,
11928 LDR = 0x5,
11929 SDR = 0xd,
11930 /* 0x6 is reserved */
11931 LWU = 0xe,
11932 LLD = 0x7,
11933 SCD = 0xf
11934};
11935
11936/* POOL32F encoding of minor opcode field (bits 5..0) */
11937
11938enum {
11939 /* These are the bit 7..6 values */
11940 ADD_FMT = 0x0,
11941 MOVN_FMT = 0x0,
11942
11943 SUB_FMT = 0x1,
11944 MOVZ_FMT = 0x1,
11945
11946 MUL_FMT = 0x2,
11947
11948 DIV_FMT = 0x3,
11949
11950 /* These are the bit 8..6 values */
11951 RSQRT2_FMT = 0x0,
11952 MOVF_FMT = 0x0,
11953
11954 LWXC1 = 0x1,
11955 MOVT_FMT = 0x1,
11956
11957 PLL_PS = 0x2,
11958 SWXC1 = 0x2,
11959
11960 PLU_PS = 0x3,
11961 LDXC1 = 0x3,
11962
11963 PUL_PS = 0x4,
11964 SDXC1 = 0x4,
11965 RECIP2_FMT = 0x4,
11966
11967 PUU_PS = 0x5,
11968 LUXC1 = 0x5,
11969
11970 CVT_PS_S = 0x6,
11971 SUXC1 = 0x6,
11972 ADDR_PS = 0x6,
11973 PREFX = 0x6,
11974
11975 MULR_PS = 0x7,
11976
11977 MADD_S = 0x01,
11978 MADD_D = 0x09,
11979 MADD_PS = 0x11,
11980 ALNV_PS = 0x19,
11981 MSUB_S = 0x21,
11982 MSUB_D = 0x29,
11983 MSUB_PS = 0x31,
11984
11985 NMADD_S = 0x02,
11986 NMADD_D = 0x0a,
11987 NMADD_PS = 0x12,
11988 NMSUB_S = 0x22,
11989 NMSUB_D = 0x2a,
11990 NMSUB_PS = 0x32,
11991
11992 POOL32FXF = 0x3b,
11993
11994 CABS_COND_FMT = 0x1c, /* MIPS3D */
11995 C_COND_FMT = 0x3c
11996};
11997
11998/* POOL32Fxf encoding of minor opcode extension field */
11999
12000enum {
12001 CVT_L = 0x04,
12002 RSQRT_FMT = 0x08,
12003 FLOOR_L = 0x0c,
12004 CVT_PW_PS = 0x1c,
12005 CVT_W = 0x24,
12006 SQRT_FMT = 0x28,
12007 FLOOR_W = 0x2c,
12008 CVT_PS_PW = 0x3c,
12009 CFC1 = 0x40,
12010 RECIP_FMT = 0x48,
12011 CEIL_L = 0x4c,
12012 CTC1 = 0x60,
12013 CEIL_W = 0x6c,
12014 MFC1 = 0x80,
12015 CVT_S_PL = 0x84,
12016 TRUNC_L = 0x8c,
12017 MTC1 = 0xa0,
12018 CVT_S_PU = 0xa4,
12019 TRUNC_W = 0xac,
12020 MFHC1 = 0xc0,
12021 ROUND_L = 0xcc,
12022 MTHC1 = 0xe0,
12023 ROUND_W = 0xec,
12024
12025 MOV_FMT = 0x01,
12026 MOVF = 0x05,
12027 ABS_FMT = 0x0d,
12028 RSQRT1_FMT = 0x1d,
12029 MOVT = 0x25,
12030 NEG_FMT = 0x2d,
12031 CVT_D = 0x4d,
12032 RECIP1_FMT = 0x5d,
12033 CVT_S = 0x6d
12034};
12035
12036/* POOL32I encoding of minor opcode field (bits 25..21) */
12037
12038enum {
12039 BLTZ = 0x00,
12040 BLTZAL = 0x01,
12041 BGEZ = 0x02,
12042 BGEZAL = 0x03,
12043 BLEZ = 0x04,
12044 BNEZC = 0x05,
12045 BGTZ = 0x06,
12046 BEQZC = 0x07,
12047 TLTI = 0x08,
12048 TGEI = 0x09,
12049 TLTIU = 0x0a,
12050 TGEIU = 0x0b,
12051 TNEI = 0x0c,
12052 LUI = 0x0d,
12053 TEQI = 0x0e,
12054 SYNCI = 0x10,
12055 BLTZALS = 0x11,
12056 BGEZALS = 0x13,
12057 BC2F = 0x14,
12058 BC2T = 0x15,
12059 BPOSGE64 = 0x1a,
12060 BPOSGE32 = 0x1b,
12061 /* These overlap and are distinguished by bit16 of the instruction */
12062 BC1F = 0x1c,
12063 BC1T = 0x1d,
12064 BC1ANY2F = 0x1c,
12065 BC1ANY2T = 0x1d,
12066 BC1ANY4F = 0x1e,
12067 BC1ANY4T = 0x1f
12068};
12069
12070/* POOL16A encoding of minor opcode field */
12071
12072enum {
12073 ADDU16 = 0x0,
12074 SUBU16 = 0x1
12075};
12076
12077/* POOL16B encoding of minor opcode field */
12078
12079enum {
12080 SLL16 = 0x0,
12081 SRL16 = 0x1
12082};
12083
12084/* POOL16C encoding of minor opcode field */
12085
12086enum {
12087 NOT16 = 0x00,
12088 XOR16 = 0x04,
12089 AND16 = 0x08,
12090 OR16 = 0x0c,
12091 LWM16 = 0x10,
12092 SWM16 = 0x14,
12093 JR16 = 0x18,
12094 JRC16 = 0x1a,
12095 JALR16 = 0x1c,
12096 JALR16S = 0x1e,
12097 MFHI16 = 0x20,
12098 MFLO16 = 0x24,
12099 BREAK16 = 0x28,
12100 SDBBP16 = 0x2c,
12101 JRADDIUSP = 0x30
12102};
12103
12104/* POOL16D encoding of minor opcode field */
12105
12106enum {
12107 ADDIUS5 = 0x0,
12108 ADDIUSP = 0x1
12109};
12110
12111/* POOL16E encoding of minor opcode field */
12112
12113enum {
12114 ADDIUR2 = 0x0,
12115 ADDIUR1SP = 0x1
12116};
12117
12118static int mmreg (int r)
12119{
12120 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12121
12122 return map[r];
12123}
12124
12125/* Used for 16-bit store instructions. */
12126static int mmreg2 (int r)
12127{
12128 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12129
12130 return map[r];
12131}
12132
12133#define uMIPS_RD(op) ((op >> 7) & 0x7)
12134#define uMIPS_RS(op) ((op >> 4) & 0x7)
12135#define uMIPS_RS2(op) uMIPS_RS(op)
12136#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12137#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12138#define uMIPS_RS5(op) (op & 0x1f)
12139
12140/* Signed immediate */
12141#define SIMM(op, start, width) \
12142 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12143 << (32-width)) \
12144 >> (32-width))
12145/* Zero-extended immediate */
12146#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12147
d75c135e 12148static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12149{
12150 int rd = mmreg(uMIPS_RD(ctx->opcode));
12151
d75c135e 12152 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12153}
12154
d75c135e 12155static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12156{
12157 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12158 int rd = mmreg(uMIPS_RD(ctx->opcode));
12159 int rs = mmreg(uMIPS_RS(ctx->opcode));
12160
d75c135e 12161 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12162}
12163
d75c135e 12164static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12165{
12166 int encoded = ZIMM(ctx->opcode, 1, 9);
12167 int decoded;
12168
12169 if (encoded <= 1) {
12170 decoded = 256 + encoded;
12171 } else if (encoded <= 255) {
12172 decoded = encoded;
12173 } else if (encoded <= 509) {
12174 decoded = encoded - 512;
12175 } else {
12176 decoded = encoded - 768;
12177 }
12178
d75c135e 12179 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12180}
12181
d75c135e 12182static void gen_addius5(DisasContext *ctx)
3c824109
NF
12183{
12184 int imm = SIMM(ctx->opcode, 1, 4);
12185 int rd = (ctx->opcode >> 5) & 0x1f;
12186
d75c135e 12187 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12188}
12189
d75c135e 12190static void gen_andi16(DisasContext *ctx)
3c824109
NF
12191{
12192 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12193 31, 32, 63, 64, 255, 32768, 65535 };
12194 int rd = mmreg(uMIPS_RD(ctx->opcode));
12195 int rs = mmreg(uMIPS_RS(ctx->opcode));
12196 int encoded = ZIMM(ctx->opcode, 0, 4);
12197
d75c135e 12198 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12199}
12200
12201static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12202 int base, int16_t offset)
12203{
e1050a76 12204 const char *opn = "ldst_multiple";
3c824109
NF
12205 TCGv t0, t1;
12206 TCGv_i32 t2;
12207
12208 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12209 generate_exception(ctx, EXCP_RI);
12210 return;
12211 }
12212
12213 t0 = tcg_temp_new();
12214
12215 gen_base_offset_addr(ctx, t0, base, offset);
12216
12217 t1 = tcg_const_tl(reglist);
12218 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12219
3c824109
NF
12220 save_cpu_state(ctx, 1);
12221 switch (opc) {
12222 case LWM32:
895c2d04 12223 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12224 opn = "lwm";
3c824109
NF
12225 break;
12226 case SWM32:
895c2d04 12227 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12228 opn = "swm";
3c824109
NF
12229 break;
12230#ifdef TARGET_MIPS64
12231 case LDM:
895c2d04 12232 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12233 opn = "ldm";
3c824109
NF
12234 break;
12235 case SDM:
895c2d04 12236 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12237 opn = "sdm";
3c824109 12238 break;
6af0bf9c 12239#endif
3c824109 12240 }
e1050a76 12241 (void)opn;
3c824109
NF
12242 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12243 tcg_temp_free(t0);
33087598 12244 tcg_temp_free(t1);
3c824109
NF
12245 tcg_temp_free_i32(t2);
12246}
6af0bf9c 12247
3c824109 12248
240ce26a 12249static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12250{
3c824109
NF
12251 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12252 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12253
3c824109
NF
12254 switch (((ctx->opcode) >> 4) & 0x3f) {
12255 case NOT16 + 0:
12256 case NOT16 + 1:
12257 case NOT16 + 2:
12258 case NOT16 + 3:
d75c135e 12259 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12260 break;
12261 case XOR16 + 0:
12262 case XOR16 + 1:
12263 case XOR16 + 2:
12264 case XOR16 + 3:
d75c135e 12265 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12266 break;
12267 case AND16 + 0:
12268 case AND16 + 1:
12269 case AND16 + 2:
12270 case AND16 + 3:
d75c135e 12271 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12272 break;
12273 case OR16 + 0:
12274 case OR16 + 1:
12275 case OR16 + 2:
12276 case OR16 + 3:
d75c135e 12277 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12278 break;
12279 case LWM16 + 0:
12280 case LWM16 + 1:
12281 case LWM16 + 2:
12282 case LWM16 + 3:
12283 {
12284 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12285 int offset = ZIMM(ctx->opcode, 0, 4);
12286
12287 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12288 29, offset << 2);
12289 }
12290 break;
12291 case SWM16 + 0:
12292 case SWM16 + 1:
12293 case SWM16 + 2:
12294 case SWM16 + 3:
12295 {
12296 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12297 int offset = ZIMM(ctx->opcode, 0, 4);
12298
12299 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12300 29, offset << 2);
12301 }
12302 break;
12303 case JR16 + 0:
12304 case JR16 + 1:
12305 {
12306 int reg = ctx->opcode & 0x1f;
12307
b231c103 12308 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12309 }
3c824109
NF
12310 break;
12311 case JRC16 + 0:
12312 case JRC16 + 1:
12313 {
12314 int reg = ctx->opcode & 0x1f;
b231c103 12315 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12316 /* Let normal delay slot handling in our caller take us
12317 to the branch target. */
12318 }
12319 break;
12320 case JALR16 + 0:
12321 case JALR16 + 1:
b231c103
YK
12322 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12323 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12324 break;
3c824109
NF
12325 case JALR16S + 0:
12326 case JALR16S + 1:
b231c103
YK
12327 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12328 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12329 break;
12330 case MFHI16 + 0:
12331 case MFHI16 + 1:
26135ead 12332 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12333 break;
12334 case MFLO16 + 0:
12335 case MFLO16 + 1:
26135ead 12336 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12337 break;
12338 case BREAK16:
12339 generate_exception(ctx, EXCP_BREAK);
12340 break;
12341 case SDBBP16:
12342 /* XXX: not clear which exception should be raised
12343 * when in debug mode...
12344 */
d75c135e 12345 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12346 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12347 generate_exception(ctx, EXCP_DBp);
12348 } else {
12349 generate_exception(ctx, EXCP_DBp);
12350 }
12351 break;
12352 case JRADDIUSP + 0:
12353 case JRADDIUSP + 1:
12354 {
12355 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12356 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12357 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12358 /* Let normal delay slot handling in our caller take us
12359 to the branch target. */
12360 }
12361 break;
12362 default:
12363 generate_exception(ctx, EXCP_RI);
12364 break;
12365 }
12366}
12367
12368static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12369{
12370 TCGv t0 = tcg_temp_new();
12371 TCGv t1 = tcg_temp_new();
12372
12373 gen_load_gpr(t0, base);
12374
12375 if (index != 0) {
12376 gen_load_gpr(t1, index);
12377 tcg_gen_shli_tl(t1, t1, 2);
12378 gen_op_addr_add(ctx, t0, t1, t0);
12379 }
12380
5f68f5ae 12381 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12382 gen_store_gpr(t1, rd);
12383
12384 tcg_temp_free(t0);
12385 tcg_temp_free(t1);
12386}
12387
12388static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12389 int base, int16_t offset)
12390{
12391 const char *opn = "ldst_pair";
12392 TCGv t0, t1;
12393
36c6711b 12394 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12395 generate_exception(ctx, EXCP_RI);
d796321b
FB
12396 return;
12397 }
12398
3c824109
NF
12399 t0 = tcg_temp_new();
12400 t1 = tcg_temp_new();
8e9ade68 12401
3c824109
NF
12402 gen_base_offset_addr(ctx, t0, base, offset);
12403
12404 switch (opc) {
12405 case LWP:
36c6711b
EJ
12406 if (rd == base) {
12407 generate_exception(ctx, EXCP_RI);
12408 return;
12409 }
5f68f5ae 12410 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12411 gen_store_gpr(t1, rd);
12412 tcg_gen_movi_tl(t1, 4);
12413 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12414 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12415 gen_store_gpr(t1, rd+1);
12416 opn = "lwp";
12417 break;
12418 case SWP:
3c824109 12419 gen_load_gpr(t1, rd);
5f68f5ae 12420 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12421 tcg_gen_movi_tl(t1, 4);
12422 gen_op_addr_add(ctx, t0, t0, t1);
12423 gen_load_gpr(t1, rd+1);
5f68f5ae 12424 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12425 opn = "swp";
12426 break;
12427#ifdef TARGET_MIPS64
12428 case LDP:
36c6711b
EJ
12429 if (rd == base) {
12430 generate_exception(ctx, EXCP_RI);
12431 return;
12432 }
5f68f5ae 12433 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12434 gen_store_gpr(t1, rd);
12435 tcg_gen_movi_tl(t1, 8);
12436 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12437 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12438 gen_store_gpr(t1, rd+1);
12439 opn = "ldp";
12440 break;
12441 case SDP:
3c824109 12442 gen_load_gpr(t1, rd);
5f68f5ae 12443 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12444 tcg_gen_movi_tl(t1, 8);
12445 gen_op_addr_add(ctx, t0, t0, t1);
12446 gen_load_gpr(t1, rd+1);
5f68f5ae 12447 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12448 opn = "sdp";
12449 break;
12450#endif
6af0bf9c 12451 }
2abf314d 12452 (void)opn; /* avoid a compiler warning */
3c824109
NF
12453 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12454 tcg_temp_free(t0);
12455 tcg_temp_free(t1);
12456}
618b0fe9 12457
240ce26a 12458static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12459{
12460 int extension = (ctx->opcode >> 6) & 0x3f;
12461 int minor = (ctx->opcode >> 12) & 0xf;
12462 uint32_t mips32_op;
12463
12464 switch (extension) {
12465 case TEQ:
12466 mips32_op = OPC_TEQ;
12467 goto do_trap;
12468 case TGE:
12469 mips32_op = OPC_TGE;
12470 goto do_trap;
12471 case TGEU:
12472 mips32_op = OPC_TGEU;
12473 goto do_trap;
12474 case TLT:
12475 mips32_op = OPC_TLT;
12476 goto do_trap;
12477 case TLTU:
12478 mips32_op = OPC_TLTU;
12479 goto do_trap;
12480 case TNE:
12481 mips32_op = OPC_TNE;
12482 do_trap:
12483 gen_trap(ctx, mips32_op, rs, rt, -1);
12484 break;
12485#ifndef CONFIG_USER_ONLY
12486 case MFC0:
12487 case MFC0 + 32:
2e15497c 12488 check_cp0_enabled(ctx);
3c824109
NF
12489 if (rt == 0) {
12490 /* Treat as NOP. */
12491 break;
12492 }
d75c135e 12493 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12494 break;
12495 case MTC0:
12496 case MTC0 + 32:
2e15497c 12497 check_cp0_enabled(ctx);
3c824109
NF
12498 {
12499 TCGv t0 = tcg_temp_new();
618b0fe9 12500
3c824109 12501 gen_load_gpr(t0, rt);
d75c135e 12502 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12503 tcg_temp_free(t0);
12504 }
12505 break;
12506#endif
a1fc6246
LA
12507 case 0x2a:
12508 switch (minor & 3) {
12509 case MADD_ACC:
12510 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12511 break;
12512 case MADDU_ACC:
12513 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12514 break;
12515 case MSUB_ACC:
12516 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12517 break;
12518 case MSUBU_ACC:
12519 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12520 break;
12521 default:
12522 goto pool32axf_invalid;
12523 }
12524 break;
12525 case 0x32:
12526 switch (minor & 3) {
12527 case MULT_ACC:
12528 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12529 break;
12530 case MULTU_ACC:
12531 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12532 break;
12533 default:
12534 goto pool32axf_invalid;
12535 }
12536 break;
3c824109
NF
12537 case 0x2c:
12538 switch (minor) {
12539 case SEB:
12540 gen_bshfl(ctx, OPC_SEB, rs, rt);
12541 break;
12542 case SEH:
12543 gen_bshfl(ctx, OPC_SEH, rs, rt);
12544 break;
12545 case CLO:
12546 mips32_op = OPC_CLO;
12547 goto do_cl;
12548 case CLZ:
12549 mips32_op = OPC_CLZ;
12550 do_cl:
d75c135e 12551 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12552 gen_cl(ctx, mips32_op, rt, rs);
12553 break;
12554 case RDHWR:
d75c135e 12555 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12556 break;
12557 case WSBH:
12558 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12559 break;
12560 case MULT:
12561 mips32_op = OPC_MULT;
26135ead 12562 goto do_mul;
3c824109
NF
12563 case MULTU:
12564 mips32_op = OPC_MULTU;
26135ead 12565 goto do_mul;
3c824109
NF
12566 case DIV:
12567 mips32_op = OPC_DIV;
26135ead 12568 goto do_div;
3c824109
NF
12569 case DIVU:
12570 mips32_op = OPC_DIVU;
26135ead
RS
12571 goto do_div;
12572 do_div:
12573 check_insn(ctx, ISA_MIPS32);
12574 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12575 break;
3c824109
NF
12576 case MADD:
12577 mips32_op = OPC_MADD;
26135ead 12578 goto do_mul;
3c824109
NF
12579 case MADDU:
12580 mips32_op = OPC_MADDU;
26135ead 12581 goto do_mul;
3c824109
NF
12582 case MSUB:
12583 mips32_op = OPC_MSUB;
26135ead 12584 goto do_mul;
3c824109
NF
12585 case MSUBU:
12586 mips32_op = OPC_MSUBU;
26135ead 12587 do_mul:
d75c135e 12588 check_insn(ctx, ISA_MIPS32);
a1fc6246 12589 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12590 break;
12591 default:
12592 goto pool32axf_invalid;
12593 }
12594 break;
12595 case 0x34:
12596 switch (minor) {
12597 case MFC2:
12598 case MTC2:
12599 case MFHC2:
12600 case MTHC2:
12601 case CFC2:
12602 case CTC2:
12603 generate_exception_err(ctx, EXCP_CpU, 2);
12604 break;
12605 default:
12606 goto pool32axf_invalid;
12607 }
12608 break;
12609 case 0x3c:
12610 switch (minor) {
12611 case JALR:
12612 case JALR_HB:
b231c103
YK
12613 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12614 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12615 break;
12616 case JALRS:
12617 case JALRS_HB:
b231c103
YK
12618 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12619 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12620 break;
12621 default:
12622 goto pool32axf_invalid;
12623 }
12624 break;
12625 case 0x05:
12626 switch (minor) {
12627 case RDPGPR:
2e15497c 12628 check_cp0_enabled(ctx);
d75c135e 12629 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12630 gen_load_srsgpr(rt, rs);
12631 break;
12632 case WRPGPR:
2e15497c 12633 check_cp0_enabled(ctx);
d75c135e 12634 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12635 gen_store_srsgpr(rt, rs);
12636 break;
12637 default:
12638 goto pool32axf_invalid;
12639 }
12640 break;
12641#ifndef CONFIG_USER_ONLY
12642 case 0x0d:
12643 switch (minor) {
12644 case TLBP:
12645 mips32_op = OPC_TLBP;
12646 goto do_cp0;
12647 case TLBR:
12648 mips32_op = OPC_TLBR;
12649 goto do_cp0;
12650 case TLBWI:
12651 mips32_op = OPC_TLBWI;
12652 goto do_cp0;
12653 case TLBWR:
12654 mips32_op = OPC_TLBWR;
12655 goto do_cp0;
12656 case WAIT:
12657 mips32_op = OPC_WAIT;
12658 goto do_cp0;
12659 case DERET:
12660 mips32_op = OPC_DERET;
12661 goto do_cp0;
12662 case ERET:
12663 mips32_op = OPC_ERET;
12664 do_cp0:
12665 gen_cp0(env, ctx, mips32_op, rt, rs);
12666 break;
12667 default:
12668 goto pool32axf_invalid;
12669 }
12670 break;
12671 case 0x1d:
12672 switch (minor) {
12673 case DI:
2e15497c 12674 check_cp0_enabled(ctx);
3c824109
NF
12675 {
12676 TCGv t0 = tcg_temp_new();
12677
12678 save_cpu_state(ctx, 1);
895c2d04 12679 gen_helper_di(t0, cpu_env);
3c824109
NF
12680 gen_store_gpr(t0, rs);
12681 /* Stop translation as we may have switched the execution mode */
12682 ctx->bstate = BS_STOP;
12683 tcg_temp_free(t0);
12684 }
12685 break;
12686 case EI:
2e15497c 12687 check_cp0_enabled(ctx);
3c824109
NF
12688 {
12689 TCGv t0 = tcg_temp_new();
12690
12691 save_cpu_state(ctx, 1);
895c2d04 12692 gen_helper_ei(t0, cpu_env);
3c824109
NF
12693 gen_store_gpr(t0, rs);
12694 /* Stop translation as we may have switched the execution mode */
12695 ctx->bstate = BS_STOP;
12696 tcg_temp_free(t0);
12697 }
12698 break;
12699 default:
12700 goto pool32axf_invalid;
12701 }
12702 break;
12703#endif
12704 case 0x2d:
12705 switch (minor) {
12706 case SYNC:
12707 /* NOP */
12708 break;
12709 case SYSCALL:
12710 generate_exception(ctx, EXCP_SYSCALL);
12711 ctx->bstate = BS_STOP;
12712 break;
12713 case SDBBP:
d75c135e 12714 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12715 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12716 generate_exception(ctx, EXCP_DBp);
12717 } else {
12718 generate_exception(ctx, EXCP_DBp);
12719 }
12720 break;
12721 default:
12722 goto pool32axf_invalid;
12723 }
12724 break;
a1fc6246 12725 case 0x01:
26135ead 12726 switch (minor & 3) {
a1fc6246 12727 case MFHI_ACC:
26135ead 12728 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12729 break;
a1fc6246 12730 case MFLO_ACC:
26135ead 12731 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12732 break;
a1fc6246 12733 case MTHI_ACC:
26135ead 12734 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12735 break;
a1fc6246 12736 case MTLO_ACC:
26135ead 12737 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12738 break;
12739 default:
12740 goto pool32axf_invalid;
12741 }
12742 break;
a1fc6246
LA
12743 case 0x35:
12744 switch (minor) {
12745 case MFHI32:
12746 gen_HILO(ctx, OPC_MFHI, 0, rs);
12747 break;
12748 case MFLO32:
12749 gen_HILO(ctx, OPC_MFLO, 0, rs);
12750 break;
12751 case MTHI32:
12752 gen_HILO(ctx, OPC_MTHI, 0, rs);
12753 break;
12754 case MTLO32:
12755 gen_HILO(ctx, OPC_MTLO, 0, rs);
12756 break;
12757 default:
12758 goto pool32axf_invalid;
12759 }
12760 break;
3c824109
NF
12761 default:
12762 pool32axf_invalid:
12763 MIPS_INVAL("pool32axf");
12764 generate_exception(ctx, EXCP_RI);
12765 break;
12766 }
12767}
12768
12769/* Values for microMIPS fmt field. Variable-width, depending on which
12770 formats the instruction supports. */
12771
12772enum {
12773 FMT_SD_S = 0,
12774 FMT_SD_D = 1,
12775
12776 FMT_SDPS_S = 0,
12777 FMT_SDPS_D = 1,
12778 FMT_SDPS_PS = 2,
12779
12780 FMT_SWL_S = 0,
12781 FMT_SWL_W = 1,
12782 FMT_SWL_L = 2,
12783
12784 FMT_DWL_D = 0,
12785 FMT_DWL_W = 1,
12786 FMT_DWL_L = 2
12787};
12788
d75c135e 12789static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12790{
12791 int extension = (ctx->opcode >> 6) & 0x3ff;
12792 uint32_t mips32_op;
12793
12794#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12795#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12796#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12797
12798 switch (extension) {
12799 case FLOAT_1BIT_FMT(CFC1, 0):
12800 mips32_op = OPC_CFC1;
12801 goto do_cp1;
12802 case FLOAT_1BIT_FMT(CTC1, 0):
12803 mips32_op = OPC_CTC1;
12804 goto do_cp1;
12805 case FLOAT_1BIT_FMT(MFC1, 0):
12806 mips32_op = OPC_MFC1;
12807 goto do_cp1;
12808 case FLOAT_1BIT_FMT(MTC1, 0):
12809 mips32_op = OPC_MTC1;
12810 goto do_cp1;
12811 case FLOAT_1BIT_FMT(MFHC1, 0):
12812 mips32_op = OPC_MFHC1;
12813 goto do_cp1;
12814 case FLOAT_1BIT_FMT(MTHC1, 0):
12815 mips32_op = OPC_MTHC1;
12816 do_cp1:
12817 gen_cp1(ctx, mips32_op, rt, rs);
12818 break;
12819
12820 /* Reciprocal square root */
12821 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12822 mips32_op = OPC_RSQRT_S;
12823 goto do_unaryfp;
12824 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12825 mips32_op = OPC_RSQRT_D;
12826 goto do_unaryfp;
12827
12828 /* Square root */
12829 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12830 mips32_op = OPC_SQRT_S;
12831 goto do_unaryfp;
12832 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12833 mips32_op = OPC_SQRT_D;
12834 goto do_unaryfp;
12835
12836 /* Reciprocal */
12837 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12838 mips32_op = OPC_RECIP_S;
12839 goto do_unaryfp;
12840 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12841 mips32_op = OPC_RECIP_D;
12842 goto do_unaryfp;
12843
12844 /* Floor */
12845 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12846 mips32_op = OPC_FLOOR_L_S;
12847 goto do_unaryfp;
12848 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12849 mips32_op = OPC_FLOOR_L_D;
12850 goto do_unaryfp;
12851 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12852 mips32_op = OPC_FLOOR_W_S;
12853 goto do_unaryfp;
12854 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12855 mips32_op = OPC_FLOOR_W_D;
12856 goto do_unaryfp;
12857
12858 /* Ceiling */
12859 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12860 mips32_op = OPC_CEIL_L_S;
12861 goto do_unaryfp;
12862 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12863 mips32_op = OPC_CEIL_L_D;
12864 goto do_unaryfp;
12865 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12866 mips32_op = OPC_CEIL_W_S;
12867 goto do_unaryfp;
12868 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12869 mips32_op = OPC_CEIL_W_D;
12870 goto do_unaryfp;
12871
12872 /* Truncation */
12873 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12874 mips32_op = OPC_TRUNC_L_S;
12875 goto do_unaryfp;
12876 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12877 mips32_op = OPC_TRUNC_L_D;
12878 goto do_unaryfp;
12879 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12880 mips32_op = OPC_TRUNC_W_S;
12881 goto do_unaryfp;
12882 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12883 mips32_op = OPC_TRUNC_W_D;
12884 goto do_unaryfp;
12885
12886 /* Round */
12887 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12888 mips32_op = OPC_ROUND_L_S;
12889 goto do_unaryfp;
12890 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12891 mips32_op = OPC_ROUND_L_D;
12892 goto do_unaryfp;
12893 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12894 mips32_op = OPC_ROUND_W_S;
12895 goto do_unaryfp;
12896 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12897 mips32_op = OPC_ROUND_W_D;
12898 goto do_unaryfp;
12899
12900 /* Integer to floating-point conversion */
12901 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12902 mips32_op = OPC_CVT_L_S;
12903 goto do_unaryfp;
12904 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12905 mips32_op = OPC_CVT_L_D;
12906 goto do_unaryfp;
12907 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12908 mips32_op = OPC_CVT_W_S;
12909 goto do_unaryfp;
12910 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12911 mips32_op = OPC_CVT_W_D;
12912 goto do_unaryfp;
12913
12914 /* Paired-foo conversions */
12915 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12916 mips32_op = OPC_CVT_S_PL;
12917 goto do_unaryfp;
12918 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12919 mips32_op = OPC_CVT_S_PU;
12920 goto do_unaryfp;
12921 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12922 mips32_op = OPC_CVT_PW_PS;
12923 goto do_unaryfp;
12924 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12925 mips32_op = OPC_CVT_PS_PW;
12926 goto do_unaryfp;
12927
12928 /* Floating-point moves */
12929 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
12930 mips32_op = OPC_MOV_S;
12931 goto do_unaryfp;
12932 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
12933 mips32_op = OPC_MOV_D;
12934 goto do_unaryfp;
12935 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
12936 mips32_op = OPC_MOV_PS;
12937 goto do_unaryfp;
12938
12939 /* Absolute value */
12940 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
12941 mips32_op = OPC_ABS_S;
12942 goto do_unaryfp;
12943 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
12944 mips32_op = OPC_ABS_D;
12945 goto do_unaryfp;
12946 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
12947 mips32_op = OPC_ABS_PS;
12948 goto do_unaryfp;
12949
12950 /* Negation */
12951 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
12952 mips32_op = OPC_NEG_S;
12953 goto do_unaryfp;
12954 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
12955 mips32_op = OPC_NEG_D;
12956 goto do_unaryfp;
12957 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
12958 mips32_op = OPC_NEG_PS;
12959 goto do_unaryfp;
12960
12961 /* Reciprocal square root step */
12962 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
12963 mips32_op = OPC_RSQRT1_S;
12964 goto do_unaryfp;
12965 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
12966 mips32_op = OPC_RSQRT1_D;
12967 goto do_unaryfp;
12968 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
12969 mips32_op = OPC_RSQRT1_PS;
12970 goto do_unaryfp;
12971
12972 /* Reciprocal step */
12973 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
12974 mips32_op = OPC_RECIP1_S;
12975 goto do_unaryfp;
12976 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
12977 mips32_op = OPC_RECIP1_S;
12978 goto do_unaryfp;
12979 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
12980 mips32_op = OPC_RECIP1_PS;
12981 goto do_unaryfp;
12982
12983 /* Conversions from double */
12984 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
12985 mips32_op = OPC_CVT_D_S;
12986 goto do_unaryfp;
12987 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
12988 mips32_op = OPC_CVT_D_W;
12989 goto do_unaryfp;
12990 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
12991 mips32_op = OPC_CVT_D_L;
12992 goto do_unaryfp;
12993
12994 /* Conversions from single */
12995 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
12996 mips32_op = OPC_CVT_S_D;
12997 goto do_unaryfp;
12998 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
12999 mips32_op = OPC_CVT_S_W;
13000 goto do_unaryfp;
13001 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13002 mips32_op = OPC_CVT_S_L;
13003 do_unaryfp:
13004 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13005 break;
13006
13007 /* Conditional moves on floating-point codes */
13008 case COND_FLOAT_MOV(MOVT, 0):
13009 case COND_FLOAT_MOV(MOVT, 1):
13010 case COND_FLOAT_MOV(MOVT, 2):
13011 case COND_FLOAT_MOV(MOVT, 3):
13012 case COND_FLOAT_MOV(MOVT, 4):
13013 case COND_FLOAT_MOV(MOVT, 5):
13014 case COND_FLOAT_MOV(MOVT, 6):
13015 case COND_FLOAT_MOV(MOVT, 7):
13016 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13017 break;
13018 case COND_FLOAT_MOV(MOVF, 0):
13019 case COND_FLOAT_MOV(MOVF, 1):
13020 case COND_FLOAT_MOV(MOVF, 2):
13021 case COND_FLOAT_MOV(MOVF, 3):
13022 case COND_FLOAT_MOV(MOVF, 4):
13023 case COND_FLOAT_MOV(MOVF, 5):
13024 case COND_FLOAT_MOV(MOVF, 6):
13025 case COND_FLOAT_MOV(MOVF, 7):
13026 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13027 break;
13028 default:
13029 MIPS_INVAL("pool32fxf");
13030 generate_exception(ctx, EXCP_RI);
13031 break;
13032 }
13033}
13034
7db13fae 13035static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13036 uint16_t insn_hw1)
3c824109
NF
13037{
13038 int32_t offset;
13039 uint16_t insn;
13040 int rt, rs, rd, rr;
13041 int16_t imm;
13042 uint32_t op, minor, mips32_op;
13043 uint32_t cond, fmt, cc;
13044
895c2d04 13045 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13046 ctx->opcode = (ctx->opcode << 16) | insn;
13047
13048 rt = (ctx->opcode >> 21) & 0x1f;
13049 rs = (ctx->opcode >> 16) & 0x1f;
13050 rd = (ctx->opcode >> 11) & 0x1f;
13051 rr = (ctx->opcode >> 6) & 0x1f;
13052 imm = (int16_t) ctx->opcode;
13053
13054 op = (ctx->opcode >> 26) & 0x3f;
13055 switch (op) {
13056 case POOL32A:
13057 minor = ctx->opcode & 0x3f;
13058 switch (minor) {
13059 case 0x00:
13060 minor = (ctx->opcode >> 6) & 0xf;
13061 switch (minor) {
13062 case SLL32:
13063 mips32_op = OPC_SLL;
13064 goto do_shifti;
13065 case SRA:
13066 mips32_op = OPC_SRA;
13067 goto do_shifti;
13068 case SRL32:
13069 mips32_op = OPC_SRL;
13070 goto do_shifti;
13071 case ROTR:
13072 mips32_op = OPC_ROTR;
13073 do_shifti:
d75c135e 13074 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13075 break;
13076 default:
13077 goto pool32a_invalid;
13078 }
13079 break;
13080 case 0x10:
13081 minor = (ctx->opcode >> 6) & 0xf;
13082 switch (minor) {
13083 /* Arithmetic */
13084 case ADD:
13085 mips32_op = OPC_ADD;
13086 goto do_arith;
13087 case ADDU32:
13088 mips32_op = OPC_ADDU;
13089 goto do_arith;
13090 case SUB:
13091 mips32_op = OPC_SUB;
13092 goto do_arith;
13093 case SUBU32:
13094 mips32_op = OPC_SUBU;
13095 goto do_arith;
13096 case MUL:
13097 mips32_op = OPC_MUL;
13098 do_arith:
d75c135e 13099 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13100 break;
13101 /* Shifts */
13102 case SLLV:
13103 mips32_op = OPC_SLLV;
13104 goto do_shift;
13105 case SRLV:
13106 mips32_op = OPC_SRLV;
13107 goto do_shift;
13108 case SRAV:
13109 mips32_op = OPC_SRAV;
13110 goto do_shift;
13111 case ROTRV:
13112 mips32_op = OPC_ROTRV;
13113 do_shift:
d75c135e 13114 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13115 break;
13116 /* Logical operations */
13117 case AND:
13118 mips32_op = OPC_AND;
13119 goto do_logic;
13120 case OR32:
13121 mips32_op = OPC_OR;
13122 goto do_logic;
13123 case NOR:
13124 mips32_op = OPC_NOR;
13125 goto do_logic;
13126 case XOR32:
13127 mips32_op = OPC_XOR;
13128 do_logic:
d75c135e 13129 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13130 break;
13131 /* Set less than */
13132 case SLT:
13133 mips32_op = OPC_SLT;
13134 goto do_slt;
13135 case SLTU:
13136 mips32_op = OPC_SLTU;
13137 do_slt:
d75c135e 13138 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13139 break;
13140 default:
13141 goto pool32a_invalid;
13142 }
13143 break;
13144 case 0x18:
13145 minor = (ctx->opcode >> 6) & 0xf;
13146 switch (minor) {
13147 /* Conditional moves */
13148 case MOVN:
13149 mips32_op = OPC_MOVN;
13150 goto do_cmov;
13151 case MOVZ:
13152 mips32_op = OPC_MOVZ;
13153 do_cmov:
d75c135e 13154 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13155 break;
13156 case LWXS:
13157 gen_ldxs(ctx, rs, rt, rd);
13158 break;
13159 default:
13160 goto pool32a_invalid;
13161 }
13162 break;
13163 case INS:
13164 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13165 return;
13166 case EXT:
13167 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13168 return;
13169 case POOL32AXF:
240ce26a 13170 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13171 break;
13172 case 0x07:
13173 generate_exception(ctx, EXCP_BREAK);
13174 break;
13175 default:
13176 pool32a_invalid:
13177 MIPS_INVAL("pool32a");
13178 generate_exception(ctx, EXCP_RI);
13179 break;
13180 }
13181 break;
13182 case POOL32B:
13183 minor = (ctx->opcode >> 12) & 0xf;
13184 switch (minor) {
13185 case CACHE:
2e15497c 13186 check_cp0_enabled(ctx);
3c824109
NF
13187 /* Treat as no-op. */
13188 break;
13189 case LWC2:
13190 case SWC2:
13191 /* COP2: Not implemented. */
13192 generate_exception_err(ctx, EXCP_CpU, 2);
13193 break;
13194 case LWP:
13195 case SWP:
13196#ifdef TARGET_MIPS64
13197 case LDP:
13198 case SDP:
13199#endif
13200 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13201 break;
13202 case LWM32:
13203 case SWM32:
13204#ifdef TARGET_MIPS64
13205 case LDM:
13206 case SDM:
13207#endif
13208 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13209 break;
13210 default:
13211 MIPS_INVAL("pool32b");
13212 generate_exception(ctx, EXCP_RI);
13213 break;
13214 }
13215 break;
13216 case POOL32F:
5ab5c041 13217 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13218 minor = ctx->opcode & 0x3f;
13219 check_cp1_enabled(ctx);
13220 switch (minor) {
13221 case ALNV_PS:
13222 mips32_op = OPC_ALNV_PS;
13223 goto do_madd;
13224 case MADD_S:
13225 mips32_op = OPC_MADD_S;
13226 goto do_madd;
13227 case MADD_D:
13228 mips32_op = OPC_MADD_D;
13229 goto do_madd;
13230 case MADD_PS:
13231 mips32_op = OPC_MADD_PS;
13232 goto do_madd;
13233 case MSUB_S:
13234 mips32_op = OPC_MSUB_S;
13235 goto do_madd;
13236 case MSUB_D:
13237 mips32_op = OPC_MSUB_D;
13238 goto do_madd;
13239 case MSUB_PS:
13240 mips32_op = OPC_MSUB_PS;
13241 goto do_madd;
13242 case NMADD_S:
13243 mips32_op = OPC_NMADD_S;
13244 goto do_madd;
13245 case NMADD_D:
13246 mips32_op = OPC_NMADD_D;
13247 goto do_madd;
13248 case NMADD_PS:
13249 mips32_op = OPC_NMADD_PS;
13250 goto do_madd;
13251 case NMSUB_S:
13252 mips32_op = OPC_NMSUB_S;
13253 goto do_madd;
13254 case NMSUB_D:
13255 mips32_op = OPC_NMSUB_D;
13256 goto do_madd;
13257 case NMSUB_PS:
13258 mips32_op = OPC_NMSUB_PS;
13259 do_madd:
13260 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13261 break;
13262 case CABS_COND_FMT:
13263 cond = (ctx->opcode >> 6) & 0xf;
13264 cc = (ctx->opcode >> 13) & 0x7;
13265 fmt = (ctx->opcode >> 10) & 0x3;
13266 switch (fmt) {
13267 case 0x0:
13268 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13269 break;
13270 case 0x1:
13271 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13272 break;
13273 case 0x2:
13274 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13275 break;
13276 default:
13277 goto pool32f_invalid;
13278 }
13279 break;
13280 case C_COND_FMT:
13281 cond = (ctx->opcode >> 6) & 0xf;
13282 cc = (ctx->opcode >> 13) & 0x7;
13283 fmt = (ctx->opcode >> 10) & 0x3;
13284 switch (fmt) {
13285 case 0x0:
13286 gen_cmp_s(ctx, cond, rt, rs, cc);
13287 break;
13288 case 0x1:
13289 gen_cmp_d(ctx, cond, rt, rs, cc);
13290 break;
13291 case 0x2:
13292 gen_cmp_ps(ctx, cond, rt, rs, cc);
13293 break;
13294 default:
13295 goto pool32f_invalid;
13296 }
13297 break;
13298 case POOL32FXF:
d75c135e 13299 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13300 break;
13301 case 0x00:
13302 /* PLL foo */
13303 switch ((ctx->opcode >> 6) & 0x7) {
13304 case PLL_PS:
13305 mips32_op = OPC_PLL_PS;
13306 goto do_ps;
13307 case PLU_PS:
13308 mips32_op = OPC_PLU_PS;
13309 goto do_ps;
13310 case PUL_PS:
13311 mips32_op = OPC_PUL_PS;
13312 goto do_ps;
13313 case PUU_PS:
13314 mips32_op = OPC_PUU_PS;
13315 goto do_ps;
13316 case CVT_PS_S:
13317 mips32_op = OPC_CVT_PS_S;
13318 do_ps:
13319 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13320 break;
13321 default:
13322 goto pool32f_invalid;
13323 }
13324 break;
13325 case 0x08:
13326 /* [LS][WDU]XC1 */
13327 switch ((ctx->opcode >> 6) & 0x7) {
13328 case LWXC1:
13329 mips32_op = OPC_LWXC1;
13330 goto do_ldst_cp1;
13331 case SWXC1:
13332 mips32_op = OPC_SWXC1;
13333 goto do_ldst_cp1;
13334 case LDXC1:
13335 mips32_op = OPC_LDXC1;
13336 goto do_ldst_cp1;
13337 case SDXC1:
13338 mips32_op = OPC_SDXC1;
13339 goto do_ldst_cp1;
13340 case LUXC1:
13341 mips32_op = OPC_LUXC1;
13342 goto do_ldst_cp1;
13343 case SUXC1:
13344 mips32_op = OPC_SUXC1;
13345 do_ldst_cp1:
13346 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13347 break;
13348 default:
13349 goto pool32f_invalid;
13350 }
13351 break;
13352 case 0x18:
13353 /* 3D insns */
13354 fmt = (ctx->opcode >> 9) & 0x3;
13355 switch ((ctx->opcode >> 6) & 0x7) {
13356 case RSQRT2_FMT:
13357 switch (fmt) {
13358 case FMT_SDPS_S:
13359 mips32_op = OPC_RSQRT2_S;
13360 goto do_3d;
13361 case FMT_SDPS_D:
13362 mips32_op = OPC_RSQRT2_D;
13363 goto do_3d;
13364 case FMT_SDPS_PS:
13365 mips32_op = OPC_RSQRT2_PS;
13366 goto do_3d;
13367 default:
13368 goto pool32f_invalid;
13369 }
13370 break;
13371 case RECIP2_FMT:
13372 switch (fmt) {
13373 case FMT_SDPS_S:
13374 mips32_op = OPC_RECIP2_S;
13375 goto do_3d;
13376 case FMT_SDPS_D:
13377 mips32_op = OPC_RECIP2_D;
13378 goto do_3d;
13379 case FMT_SDPS_PS:
13380 mips32_op = OPC_RECIP2_PS;
13381 goto do_3d;
13382 default:
13383 goto pool32f_invalid;
13384 }
13385 break;
13386 case ADDR_PS:
13387 mips32_op = OPC_ADDR_PS;
13388 goto do_3d;
13389 case MULR_PS:
13390 mips32_op = OPC_MULR_PS;
13391 do_3d:
13392 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13393 break;
13394 default:
13395 goto pool32f_invalid;
13396 }
13397 break;
13398 case 0x20:
13399 /* MOV[FT].fmt and PREFX */
13400 cc = (ctx->opcode >> 13) & 0x7;
13401 fmt = (ctx->opcode >> 9) & 0x3;
13402 switch ((ctx->opcode >> 6) & 0x7) {
13403 case MOVF_FMT:
13404 switch (fmt) {
13405 case FMT_SDPS_S:
13406 gen_movcf_s(rs, rt, cc, 0);
13407 break;
13408 case FMT_SDPS_D:
13409 gen_movcf_d(ctx, rs, rt, cc, 0);
13410 break;
13411 case FMT_SDPS_PS:
7f6613ce 13412 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13413 break;
13414 default:
13415 goto pool32f_invalid;
13416 }
13417 break;
13418 case MOVT_FMT:
13419 switch (fmt) {
13420 case FMT_SDPS_S:
13421 gen_movcf_s(rs, rt, cc, 1);
13422 break;
13423 case FMT_SDPS_D:
13424 gen_movcf_d(ctx, rs, rt, cc, 1);
13425 break;
13426 case FMT_SDPS_PS:
7f6613ce 13427 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13428 break;
13429 default:
13430 goto pool32f_invalid;
13431 }
13432 break;
13433 case PREFX:
13434 break;
13435 default:
13436 goto pool32f_invalid;
13437 }
13438 break;
13439#define FINSN_3ARG_SDPS(prfx) \
13440 switch ((ctx->opcode >> 8) & 0x3) { \
13441 case FMT_SDPS_S: \
13442 mips32_op = OPC_##prfx##_S; \
13443 goto do_fpop; \
13444 case FMT_SDPS_D: \
13445 mips32_op = OPC_##prfx##_D; \
13446 goto do_fpop; \
13447 case FMT_SDPS_PS: \
13448 mips32_op = OPC_##prfx##_PS; \
13449 goto do_fpop; \
13450 default: \
13451 goto pool32f_invalid; \
13452 }
13453 case 0x30:
13454 /* regular FP ops */
13455 switch ((ctx->opcode >> 6) & 0x3) {
13456 case ADD_FMT:
13457 FINSN_3ARG_SDPS(ADD);
13458 break;
13459 case SUB_FMT:
13460 FINSN_3ARG_SDPS(SUB);
13461 break;
13462 case MUL_FMT:
13463 FINSN_3ARG_SDPS(MUL);
13464 break;
13465 case DIV_FMT:
13466 fmt = (ctx->opcode >> 8) & 0x3;
13467 if (fmt == 1) {
13468 mips32_op = OPC_DIV_D;
13469 } else if (fmt == 0) {
13470 mips32_op = OPC_DIV_S;
13471 } else {
13472 goto pool32f_invalid;
13473 }
13474 goto do_fpop;
13475 default:
13476 goto pool32f_invalid;
13477 }
13478 break;
13479 case 0x38:
13480 /* cmovs */
13481 switch ((ctx->opcode >> 6) & 0x3) {
13482 case MOVN_FMT:
13483 FINSN_3ARG_SDPS(MOVN);
13484 break;
13485 case MOVZ_FMT:
13486 FINSN_3ARG_SDPS(MOVZ);
13487 break;
13488 default:
13489 goto pool32f_invalid;
13490 }
13491 break;
13492 do_fpop:
13493 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13494 break;
13495 default:
13496 pool32f_invalid:
13497 MIPS_INVAL("pool32f");
13498 generate_exception(ctx, EXCP_RI);
13499 break;
13500 }
13501 } else {
13502 generate_exception_err(ctx, EXCP_CpU, 1);
13503 }
13504 break;
13505 case POOL32I:
13506 minor = (ctx->opcode >> 21) & 0x1f;
13507 switch (minor) {
13508 case BLTZ:
b231c103
YK
13509 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13510 break;
3c824109 13511 case BLTZAL:
b231c103
YK
13512 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13513 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13514 break;
3c824109 13515 case BLTZALS:
b231c103
YK
13516 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13517 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13518 break;
3c824109 13519 case BGEZ:
b231c103
YK
13520 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13521 break;
3c824109 13522 case BGEZAL:
b231c103
YK
13523 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13524 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13525 break;
3c824109 13526 case BGEZALS:
b231c103
YK
13527 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13528 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13529 break;
3c824109 13530 case BLEZ:
b231c103
YK
13531 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13532 break;
3c824109 13533 case BGTZ:
b231c103 13534 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13535 break;
13536
13537 /* Traps */
13538 case TLTI:
13539 mips32_op = OPC_TLTI;
13540 goto do_trapi;
13541 case TGEI:
13542 mips32_op = OPC_TGEI;
13543 goto do_trapi;
13544 case TLTIU:
13545 mips32_op = OPC_TLTIU;
13546 goto do_trapi;
13547 case TGEIU:
13548 mips32_op = OPC_TGEIU;
13549 goto do_trapi;
13550 case TNEI:
13551 mips32_op = OPC_TNEI;
13552 goto do_trapi;
13553 case TEQI:
13554 mips32_op = OPC_TEQI;
13555 do_trapi:
13556 gen_trap(ctx, mips32_op, rs, -1, imm);
13557 break;
13558
13559 case BNEZC:
13560 case BEQZC:
13561 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13562 4, rs, 0, imm << 1, 0);
3c824109
NF
13563 /* Compact branches don't have a delay slot, so just let
13564 the normal delay slot handling take us to the branch
13565 target. */
13566 break;
13567 case LUI:
d75c135e 13568 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
13569 break;
13570 case SYNCI:
a83bddd6
DZ
13571 /* Break the TB to be able to sync copied instructions
13572 immediately */
13573 ctx->bstate = BS_STOP;
3c824109
NF
13574 break;
13575 case BC2F:
13576 case BC2T:
13577 /* COP2: Not implemented. */
13578 generate_exception_err(ctx, EXCP_CpU, 2);
13579 break;
13580 case BC1F:
13581 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13582 goto do_cp1branch;
13583 case BC1T:
13584 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13585 goto do_cp1branch;
13586 case BC1ANY4F:
13587 mips32_op = OPC_BC1FANY4;
13588 goto do_cp1mips3d;
13589 case BC1ANY4T:
13590 mips32_op = OPC_BC1TANY4;
13591 do_cp1mips3d:
13592 check_cop1x(ctx);
d75c135e 13593 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13594 /* Fall through */
13595 do_cp1branch:
d75c135e 13596 gen_compute_branch1(ctx, mips32_op,
3c824109 13597 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
13598 break;
13599 case BPOSGE64:
13600 case BPOSGE32:
13601 /* MIPS DSP: not implemented */
13602 /* Fall through */
13603 default:
13604 MIPS_INVAL("pool32i");
13605 generate_exception(ctx, EXCP_RI);
13606 break;
13607 }
13608 break;
13609 case POOL32C:
13610 minor = (ctx->opcode >> 12) & 0xf;
13611 switch (minor) {
13612 case LWL:
13613 mips32_op = OPC_LWL;
5c13fdfd 13614 goto do_ld_lr;
3c824109
NF
13615 case SWL:
13616 mips32_op = OPC_SWL;
5c13fdfd 13617 goto do_st_lr;
3c824109
NF
13618 case LWR:
13619 mips32_op = OPC_LWR;
5c13fdfd 13620 goto do_ld_lr;
3c824109
NF
13621 case SWR:
13622 mips32_op = OPC_SWR;
5c13fdfd 13623 goto do_st_lr;
3c824109
NF
13624#if defined(TARGET_MIPS64)
13625 case LDL:
13626 mips32_op = OPC_LDL;
5c13fdfd 13627 goto do_ld_lr;
3c824109
NF
13628 case SDL:
13629 mips32_op = OPC_SDL;
5c13fdfd 13630 goto do_st_lr;
3c824109
NF
13631 case LDR:
13632 mips32_op = OPC_LDR;
5c13fdfd 13633 goto do_ld_lr;
3c824109
NF
13634 case SDR:
13635 mips32_op = OPC_SDR;
5c13fdfd 13636 goto do_st_lr;
3c824109
NF
13637 case LWU:
13638 mips32_op = OPC_LWU;
5c13fdfd 13639 goto do_ld_lr;
3c824109
NF
13640 case LLD:
13641 mips32_op = OPC_LLD;
5c13fdfd 13642 goto do_ld_lr;
3c824109
NF
13643#endif
13644 case LL:
13645 mips32_op = OPC_LL;
5c13fdfd
AJ
13646 goto do_ld_lr;
13647 do_ld_lr:
d75c135e 13648 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13649 break;
13650 do_st_lr:
13651 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13652 break;
13653 case SC:
13654 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13655 break;
13656#if defined(TARGET_MIPS64)
13657 case SCD:
13658 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13659 break;
13660#endif
13661 case PREF:
13662 /* Treat as no-op */
13663 break;
13664 default:
13665 MIPS_INVAL("pool32c");
13666 generate_exception(ctx, EXCP_RI);
13667 break;
13668 }
13669 break;
13670 case ADDI32:
13671 mips32_op = OPC_ADDI;
13672 goto do_addi;
13673 case ADDIU32:
13674 mips32_op = OPC_ADDIU;
13675 do_addi:
d75c135e 13676 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13677 break;
13678
13679 /* Logical operations */
13680 case ORI32:
13681 mips32_op = OPC_ORI;
13682 goto do_logici;
13683 case XORI32:
13684 mips32_op = OPC_XORI;
13685 goto do_logici;
13686 case ANDI32:
13687 mips32_op = OPC_ANDI;
13688 do_logici:
d75c135e 13689 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13690 break;
13691
13692 /* Set less than immediate */
13693 case SLTI32:
13694 mips32_op = OPC_SLTI;
13695 goto do_slti;
13696 case SLTIU32:
13697 mips32_op = OPC_SLTIU;
13698 do_slti:
d75c135e 13699 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13700 break;
13701 case JALX32:
13702 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13703 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13704 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13705 break;
13706 case JALS32:
13707 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13708 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13709 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13710 break;
13711 case BEQ32:
b231c103 13712 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13713 break;
13714 case BNE32:
b231c103 13715 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13716 break;
13717 case J32:
13718 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13719 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13720 break;
13721 case JAL32:
13722 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13723 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13724 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13725 break;
13726 /* Floating point (COP1) */
13727 case LWC132:
13728 mips32_op = OPC_LWC1;
13729 goto do_cop1;
13730 case LDC132:
13731 mips32_op = OPC_LDC1;
13732 goto do_cop1;
13733 case SWC132:
13734 mips32_op = OPC_SWC1;
13735 goto do_cop1;
13736 case SDC132:
13737 mips32_op = OPC_SDC1;
13738 do_cop1:
5ab5c041 13739 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13740 break;
13741 case ADDIUPC:
13742 {
13743 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13744 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13745
13746 gen_addiupc(ctx, reg, offset, 0, 0);
13747 }
13748 break;
13749 /* Loads and stores */
13750 case LB32:
13751 mips32_op = OPC_LB;
5c13fdfd 13752 goto do_ld;
3c824109
NF
13753 case LBU32:
13754 mips32_op = OPC_LBU;
5c13fdfd 13755 goto do_ld;
3c824109
NF
13756 case LH32:
13757 mips32_op = OPC_LH;
5c13fdfd 13758 goto do_ld;
3c824109
NF
13759 case LHU32:
13760 mips32_op = OPC_LHU;
5c13fdfd 13761 goto do_ld;
3c824109
NF
13762 case LW32:
13763 mips32_op = OPC_LW;
5c13fdfd 13764 goto do_ld;
3c824109
NF
13765#ifdef TARGET_MIPS64
13766 case LD32:
13767 mips32_op = OPC_LD;
5c13fdfd 13768 goto do_ld;
3c824109
NF
13769 case SD32:
13770 mips32_op = OPC_SD;
5c13fdfd 13771 goto do_st;
3c824109
NF
13772#endif
13773 case SB32:
13774 mips32_op = OPC_SB;
5c13fdfd 13775 goto do_st;
3c824109
NF
13776 case SH32:
13777 mips32_op = OPC_SH;
5c13fdfd 13778 goto do_st;
3c824109
NF
13779 case SW32:
13780 mips32_op = OPC_SW;
5c13fdfd
AJ
13781 goto do_st;
13782 do_ld:
d75c135e 13783 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13784 break;
13785 do_st:
13786 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13787 break;
13788 default:
13789 generate_exception(ctx, EXCP_RI);
13790 break;
13791 }
13792}
13793
240ce26a 13794static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13795{
13796 uint32_t op;
13797
13798 /* make sure instructions are on a halfword boundary */
13799 if (ctx->pc & 0x1) {
13800 env->CP0_BadVAddr = ctx->pc;
13801 generate_exception(ctx, EXCP_AdEL);
13802 ctx->bstate = BS_STOP;
13803 return 2;
13804 }
13805
13806 op = (ctx->opcode >> 10) & 0x3f;
13807 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13808 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13809 switch (op & 0x7) { /* MSB-3..MSB-5 */
13810 case 0:
13811 /* POOL32A, POOL32B, POOL32I, POOL32C */
13812 case 4:
13813 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13814 case 5:
13815 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13816 case 6:
13817 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13818 case 7:
13819 /* LB32, LH32, LWC132, LDC132, LW32 */
13820 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13821 generate_exception(ctx, EXCP_RI);
13822 /* Just stop translation; the user is confused. */
13823 ctx->bstate = BS_STOP;
13824 return 2;
13825 }
13826 break;
b231c103
YK
13827 case 1:
13828 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13829 case 2:
13830 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13831 case 3:
13832 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13833 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13834 generate_exception(ctx, EXCP_RI);
13835 /* Just stop translation; the user is confused. */
13836 ctx->bstate = BS_STOP;
13837 return 2;
13838 }
13839 break;
3c824109
NF
13840 }
13841 }
b231c103 13842
3c824109
NF
13843 switch (op) {
13844 case POOL16A:
13845 {
13846 int rd = mmreg(uMIPS_RD(ctx->opcode));
13847 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13848 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13849 uint32_t opc = 0;
13850
13851 switch (ctx->opcode & 0x1) {
13852 case ADDU16:
13853 opc = OPC_ADDU;
13854 break;
13855 case SUBU16:
13856 opc = OPC_SUBU;
13857 break;
13858 }
13859
d75c135e 13860 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13861 }
13862 break;
13863 case POOL16B:
13864 {
13865 int rd = mmreg(uMIPS_RD(ctx->opcode));
13866 int rs = mmreg(uMIPS_RS(ctx->opcode));
13867 int amount = (ctx->opcode >> 1) & 0x7;
13868 uint32_t opc = 0;
13869 amount = amount == 0 ? 8 : amount;
13870
13871 switch (ctx->opcode & 0x1) {
13872 case SLL16:
13873 opc = OPC_SLL;
13874 break;
13875 case SRL16:
13876 opc = OPC_SRL;
13877 break;
13878 }
13879
d75c135e 13880 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
13881 }
13882 break;
13883 case POOL16C:
240ce26a 13884 gen_pool16c_insn(ctx);
3c824109
NF
13885 break;
13886 case LWGP16:
13887 {
13888 int rd = mmreg(uMIPS_RD(ctx->opcode));
13889 int rb = 28; /* GP */
13890 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13891
d75c135e 13892 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13893 }
13894 break;
13895 case POOL16F:
13896 if (ctx->opcode & 1) {
13897 generate_exception(ctx, EXCP_RI);
13898 } else {
13899 /* MOVEP */
13900 int enc_dest = uMIPS_RD(ctx->opcode);
13901 int enc_rt = uMIPS_RS2(ctx->opcode);
13902 int enc_rs = uMIPS_RS1(ctx->opcode);
13903 int rd, rs, re, rt;
13904 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13905 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13906 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13907
13908 rd = rd_enc[enc_dest];
13909 re = re_enc[enc_dest];
13910 rs = rs_rt_enc[enc_rs];
13911 rt = rs_rt_enc[enc_rt];
13912
d75c135e
AJ
13913 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13914 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
13915 }
13916 break;
13917 case LBU16:
13918 {
13919 int rd = mmreg(uMIPS_RD(ctx->opcode));
13920 int rb = mmreg(uMIPS_RS(ctx->opcode));
13921 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13922 offset = (offset == 0xf ? -1 : offset);
13923
d75c135e 13924 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
13925 }
13926 break;
13927 case LHU16:
13928 {
13929 int rd = mmreg(uMIPS_RD(ctx->opcode));
13930 int rb = mmreg(uMIPS_RS(ctx->opcode));
13931 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13932
d75c135e 13933 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
13934 }
13935 break;
13936 case LWSP16:
13937 {
13938 int rd = (ctx->opcode >> 5) & 0x1f;
13939 int rb = 29; /* SP */
13940 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13941
d75c135e 13942 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13943 }
13944 break;
13945 case LW16:
13946 {
13947 int rd = mmreg(uMIPS_RD(ctx->opcode));
13948 int rb = mmreg(uMIPS_RS(ctx->opcode));
13949 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13950
d75c135e 13951 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13952 }
13953 break;
13954 case SB16:
13955 {
13956 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13957 int rb = mmreg(uMIPS_RS(ctx->opcode));
13958 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13959
5c13fdfd 13960 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
13961 }
13962 break;
13963 case SH16:
13964 {
13965 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13966 int rb = mmreg(uMIPS_RS(ctx->opcode));
13967 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13968
5c13fdfd 13969 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
13970 }
13971 break;
13972 case SWSP16:
13973 {
13974 int rd = (ctx->opcode >> 5) & 0x1f;
13975 int rb = 29; /* SP */
13976 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13977
5c13fdfd 13978 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13979 }
13980 break;
13981 case SW16:
13982 {
13983 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13984 int rb = mmreg(uMIPS_RS(ctx->opcode));
13985 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13986
5c13fdfd 13987 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13988 }
13989 break;
13990 case MOVE16:
13991 {
13992 int rd = uMIPS_RD5(ctx->opcode);
13993 int rs = uMIPS_RS5(ctx->opcode);
13994
d75c135e 13995 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
13996 }
13997 break;
13998 case ANDI16:
d75c135e 13999 gen_andi16(ctx);
3c824109
NF
14000 break;
14001 case POOL16D:
14002 switch (ctx->opcode & 0x1) {
14003 case ADDIUS5:
d75c135e 14004 gen_addius5(ctx);
3c824109
NF
14005 break;
14006 case ADDIUSP:
d75c135e 14007 gen_addiusp(ctx);
3c824109
NF
14008 break;
14009 }
14010 break;
14011 case POOL16E:
14012 switch (ctx->opcode & 0x1) {
14013 case ADDIUR2:
d75c135e 14014 gen_addiur2(ctx);
3c824109
NF
14015 break;
14016 case ADDIUR1SP:
d75c135e 14017 gen_addiur1sp(ctx);
3c824109
NF
14018 break;
14019 }
14020 break;
14021 case B16:
14022 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14023 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14024 break;
14025 case BNEZ16:
14026 case BEQZ16:
14027 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14028 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14029 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14030 break;
14031 case LI16:
14032 {
14033 int reg = mmreg(uMIPS_RD(ctx->opcode));
14034 int imm = ZIMM(ctx->opcode, 0, 7);
14035
14036 imm = (imm == 0x7f ? -1 : imm);
14037 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14038 }
14039 break;
14040 case RES_20:
14041 case RES_28:
14042 case RES_29:
14043 case RES_30:
14044 case RES_31:
14045 case RES_38:
14046 case RES_39:
14047 generate_exception(ctx, EXCP_RI);
14048 break;
14049 default:
240ce26a 14050 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14051 return 4;
14052 }
14053
14054 return 2;
14055}
14056
14057/* SmartMIPS extension to MIPS32 */
14058
14059#if defined(TARGET_MIPS64)
14060
14061/* MDMX extension to MIPS64 */
14062
14063#endif
14064
9b1a1d68 14065/* MIPSDSP functions. */
d75c135e 14066static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14067 int rd, int base, int offset)
14068{
14069 const char *opn = "ldx";
14070 TCGv t0;
14071
9b1a1d68
JL
14072 check_dsp(ctx);
14073 t0 = tcg_temp_new();
14074
14075 if (base == 0) {
14076 gen_load_gpr(t0, offset);
14077 } else if (offset == 0) {
14078 gen_load_gpr(t0, base);
14079 } else {
14080 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14081 }
14082
9b1a1d68
JL
14083 switch (opc) {
14084 case OPC_LBUX:
5f68f5ae 14085 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14086 gen_store_gpr(t0, rd);
14087 opn = "lbux";
14088 break;
14089 case OPC_LHX:
5f68f5ae 14090 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14091 gen_store_gpr(t0, rd);
14092 opn = "lhx";
14093 break;
14094 case OPC_LWX:
5f68f5ae 14095 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14096 gen_store_gpr(t0, rd);
14097 opn = "lwx";
14098 break;
14099#if defined(TARGET_MIPS64)
14100 case OPC_LDX:
5f68f5ae 14101 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14102 gen_store_gpr(t0, rd);
14103 opn = "ldx";
14104 break;
14105#endif
14106 }
14107 (void)opn; /* avoid a compiler warning */
14108 MIPS_DEBUG("%s %s, %s(%s)", opn,
14109 regnames[rd], regnames[offset], regnames[base]);
14110 tcg_temp_free(t0);
14111}
14112
461c08df
JL
14113static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14114 int ret, int v1, int v2)
14115{
14116 const char *opn = "mipsdsp arith";
14117 TCGv v1_t;
14118 TCGv v2_t;
14119
14120 if (ret == 0) {
14121 /* Treat as NOP. */
14122 MIPS_DEBUG("NOP");
14123 return;
14124 }
14125
14126 v1_t = tcg_temp_new();
14127 v2_t = tcg_temp_new();
14128
14129 gen_load_gpr(v1_t, v1);
14130 gen_load_gpr(v2_t, v2);
14131
14132 switch (op1) {
14133 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14134 case OPC_MULT_G_2E:
14135 check_dspr2(ctx);
14136 switch (op2) {
14137 case OPC_ADDUH_QB:
14138 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14139 break;
14140 case OPC_ADDUH_R_QB:
14141 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14142 break;
14143 case OPC_ADDQH_PH:
14144 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14145 break;
14146 case OPC_ADDQH_R_PH:
14147 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14148 break;
14149 case OPC_ADDQH_W:
14150 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14151 break;
14152 case OPC_ADDQH_R_W:
14153 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14154 break;
14155 case OPC_SUBUH_QB:
14156 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14157 break;
14158 case OPC_SUBUH_R_QB:
14159 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14160 break;
14161 case OPC_SUBQH_PH:
14162 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14163 break;
14164 case OPC_SUBQH_R_PH:
14165 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14166 break;
14167 case OPC_SUBQH_W:
14168 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14169 break;
14170 case OPC_SUBQH_R_W:
14171 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14172 break;
14173 }
14174 break;
14175 case OPC_ABSQ_S_PH_DSP:
14176 switch (op2) {
14177 case OPC_ABSQ_S_QB:
14178 check_dspr2(ctx);
14179 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14180 break;
14181 case OPC_ABSQ_S_PH:
14182 check_dsp(ctx);
14183 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14184 break;
14185 case OPC_ABSQ_S_W:
14186 check_dsp(ctx);
14187 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14188 break;
14189 case OPC_PRECEQ_W_PHL:
14190 check_dsp(ctx);
14191 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14192 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14193 break;
14194 case OPC_PRECEQ_W_PHR:
14195 check_dsp(ctx);
14196 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14197 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14198 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14199 break;
14200 case OPC_PRECEQU_PH_QBL:
14201 check_dsp(ctx);
14202 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14203 break;
14204 case OPC_PRECEQU_PH_QBR:
14205 check_dsp(ctx);
14206 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14207 break;
14208 case OPC_PRECEQU_PH_QBLA:
14209 check_dsp(ctx);
14210 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14211 break;
14212 case OPC_PRECEQU_PH_QBRA:
14213 check_dsp(ctx);
14214 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14215 break;
14216 case OPC_PRECEU_PH_QBL:
14217 check_dsp(ctx);
14218 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14219 break;
14220 case OPC_PRECEU_PH_QBR:
14221 check_dsp(ctx);
14222 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14223 break;
14224 case OPC_PRECEU_PH_QBLA:
14225 check_dsp(ctx);
14226 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14227 break;
14228 case OPC_PRECEU_PH_QBRA:
14229 check_dsp(ctx);
14230 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14231 break;
14232 }
14233 break;
14234 case OPC_ADDU_QB_DSP:
14235 switch (op2) {
14236 case OPC_ADDQ_PH:
14237 check_dsp(ctx);
14238 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14239 break;
14240 case OPC_ADDQ_S_PH:
14241 check_dsp(ctx);
14242 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14243 break;
14244 case OPC_ADDQ_S_W:
14245 check_dsp(ctx);
14246 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14247 break;
14248 case OPC_ADDU_QB:
14249 check_dsp(ctx);
14250 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14251 break;
14252 case OPC_ADDU_S_QB:
14253 check_dsp(ctx);
14254 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14255 break;
14256 case OPC_ADDU_PH:
14257 check_dspr2(ctx);
14258 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14259 break;
14260 case OPC_ADDU_S_PH:
14261 check_dspr2(ctx);
14262 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14263 break;
14264 case OPC_SUBQ_PH:
14265 check_dsp(ctx);
14266 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14267 break;
14268 case OPC_SUBQ_S_PH:
14269 check_dsp(ctx);
14270 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14271 break;
14272 case OPC_SUBQ_S_W:
14273 check_dsp(ctx);
14274 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14275 break;
14276 case OPC_SUBU_QB:
14277 check_dsp(ctx);
14278 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14279 break;
14280 case OPC_SUBU_S_QB:
14281 check_dsp(ctx);
14282 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14283 break;
14284 case OPC_SUBU_PH:
14285 check_dspr2(ctx);
14286 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14287 break;
14288 case OPC_SUBU_S_PH:
14289 check_dspr2(ctx);
14290 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14291 break;
14292 case OPC_ADDSC:
14293 check_dsp(ctx);
14294 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14295 break;
14296 case OPC_ADDWC:
14297 check_dsp(ctx);
14298 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14299 break;
14300 case OPC_MODSUB:
14301 check_dsp(ctx);
14302 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14303 break;
14304 case OPC_RADDU_W_QB:
14305 check_dsp(ctx);
14306 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14307 break;
14308 }
14309 break;
14310 case OPC_CMPU_EQ_QB_DSP:
14311 switch (op2) {
14312 case OPC_PRECR_QB_PH:
14313 check_dspr2(ctx);
14314 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14315 break;
14316 case OPC_PRECRQ_QB_PH:
14317 check_dsp(ctx);
14318 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14319 break;
14320 case OPC_PRECR_SRA_PH_W:
14321 check_dspr2(ctx);
14322 {
14323 TCGv_i32 sa_t = tcg_const_i32(v2);
14324 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14325 cpu_gpr[ret]);
14326 tcg_temp_free_i32(sa_t);
14327 break;
14328 }
14329 case OPC_PRECR_SRA_R_PH_W:
14330 check_dspr2(ctx);
14331 {
14332 TCGv_i32 sa_t = tcg_const_i32(v2);
14333 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14334 cpu_gpr[ret]);
14335 tcg_temp_free_i32(sa_t);
14336 break;
14337 }
14338 case OPC_PRECRQ_PH_W:
14339 check_dsp(ctx);
14340 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14341 break;
14342 case OPC_PRECRQ_RS_PH_W:
14343 check_dsp(ctx);
14344 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14345 break;
14346 case OPC_PRECRQU_S_QB_PH:
14347 check_dsp(ctx);
14348 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14349 break;
14350 }
14351 break;
14352#ifdef TARGET_MIPS64
14353 case OPC_ABSQ_S_QH_DSP:
14354 switch (op2) {
14355 case OPC_PRECEQ_L_PWL:
14356 check_dsp(ctx);
14357 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14358 break;
14359 case OPC_PRECEQ_L_PWR:
14360 check_dsp(ctx);
14361 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14362 break;
14363 case OPC_PRECEQ_PW_QHL:
14364 check_dsp(ctx);
14365 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14366 break;
14367 case OPC_PRECEQ_PW_QHR:
14368 check_dsp(ctx);
14369 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14370 break;
14371 case OPC_PRECEQ_PW_QHLA:
14372 check_dsp(ctx);
14373 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14374 break;
14375 case OPC_PRECEQ_PW_QHRA:
14376 check_dsp(ctx);
14377 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14378 break;
14379 case OPC_PRECEQU_QH_OBL:
14380 check_dsp(ctx);
14381 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14382 break;
14383 case OPC_PRECEQU_QH_OBR:
14384 check_dsp(ctx);
14385 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14386 break;
14387 case OPC_PRECEQU_QH_OBLA:
14388 check_dsp(ctx);
14389 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14390 break;
14391 case OPC_PRECEQU_QH_OBRA:
14392 check_dsp(ctx);
14393 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14394 break;
14395 case OPC_PRECEU_QH_OBL:
14396 check_dsp(ctx);
14397 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14398 break;
14399 case OPC_PRECEU_QH_OBR:
14400 check_dsp(ctx);
14401 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14402 break;
14403 case OPC_PRECEU_QH_OBLA:
14404 check_dsp(ctx);
14405 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14406 break;
14407 case OPC_PRECEU_QH_OBRA:
14408 check_dsp(ctx);
14409 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14410 break;
14411 case OPC_ABSQ_S_OB:
14412 check_dspr2(ctx);
14413 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14414 break;
14415 case OPC_ABSQ_S_PW:
14416 check_dsp(ctx);
14417 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14418 break;
14419 case OPC_ABSQ_S_QH:
14420 check_dsp(ctx);
14421 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14422 break;
14423 }
14424 break;
14425 case OPC_ADDU_OB_DSP:
14426 switch (op2) {
14427 case OPC_RADDU_L_OB:
14428 check_dsp(ctx);
14429 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14430 break;
14431 case OPC_SUBQ_PW:
14432 check_dsp(ctx);
14433 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14434 break;
14435 case OPC_SUBQ_S_PW:
14436 check_dsp(ctx);
14437 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14438 break;
14439 case OPC_SUBQ_QH:
14440 check_dsp(ctx);
14441 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14442 break;
14443 case OPC_SUBQ_S_QH:
14444 check_dsp(ctx);
14445 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14446 break;
14447 case OPC_SUBU_OB:
14448 check_dsp(ctx);
14449 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14450 break;
14451 case OPC_SUBU_S_OB:
14452 check_dsp(ctx);
14453 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14454 break;
14455 case OPC_SUBU_QH:
14456 check_dspr2(ctx);
14457 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14458 break;
14459 case OPC_SUBU_S_QH:
14460 check_dspr2(ctx);
14461 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14462 break;
14463 case OPC_SUBUH_OB:
14464 check_dspr2(ctx);
14465 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14466 break;
14467 case OPC_SUBUH_R_OB:
14468 check_dspr2(ctx);
14469 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14470 break;
14471 case OPC_ADDQ_PW:
14472 check_dsp(ctx);
14473 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14474 break;
14475 case OPC_ADDQ_S_PW:
14476 check_dsp(ctx);
14477 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14478 break;
14479 case OPC_ADDQ_QH:
14480 check_dsp(ctx);
14481 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14482 break;
14483 case OPC_ADDQ_S_QH:
14484 check_dsp(ctx);
14485 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14486 break;
14487 case OPC_ADDU_OB:
14488 check_dsp(ctx);
14489 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14490 break;
14491 case OPC_ADDU_S_OB:
14492 check_dsp(ctx);
14493 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14494 break;
14495 case OPC_ADDU_QH:
14496 check_dspr2(ctx);
14497 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14498 break;
14499 case OPC_ADDU_S_QH:
14500 check_dspr2(ctx);
14501 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14502 break;
14503 case OPC_ADDUH_OB:
14504 check_dspr2(ctx);
14505 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14506 break;
14507 case OPC_ADDUH_R_OB:
14508 check_dspr2(ctx);
14509 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14510 break;
14511 }
14512 break;
14513 case OPC_CMPU_EQ_OB_DSP:
14514 switch (op2) {
14515 case OPC_PRECR_OB_QH:
14516 check_dspr2(ctx);
14517 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14518 break;
14519 case OPC_PRECR_SRA_QH_PW:
14520 check_dspr2(ctx);
14521 {
14522 TCGv_i32 ret_t = tcg_const_i32(ret);
14523 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14524 tcg_temp_free_i32(ret_t);
14525 break;
14526 }
14527 case OPC_PRECR_SRA_R_QH_PW:
14528 check_dspr2(ctx);
14529 {
14530 TCGv_i32 sa_v = tcg_const_i32(ret);
14531 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14532 tcg_temp_free_i32(sa_v);
14533 break;
14534 }
14535 case OPC_PRECRQ_OB_QH:
14536 check_dsp(ctx);
14537 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14538 break;
14539 case OPC_PRECRQ_PW_L:
14540 check_dsp(ctx);
14541 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14542 break;
14543 case OPC_PRECRQ_QH_PW:
14544 check_dsp(ctx);
14545 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14546 break;
14547 case OPC_PRECRQ_RS_QH_PW:
14548 check_dsp(ctx);
14549 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14550 break;
14551 case OPC_PRECRQU_S_OB_QH:
14552 check_dsp(ctx);
14553 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14554 break;
14555 }
14556 break;
14557#endif
14558 }
14559
14560 tcg_temp_free(v1_t);
14561 tcg_temp_free(v2_t);
14562
14563 (void)opn; /* avoid a compiler warning */
14564 MIPS_DEBUG("%s", opn);
14565}
9b1a1d68 14566
77c5fa8b
JL
14567static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14568 int ret, int v1, int v2)
14569{
14570 uint32_t op2;
14571 const char *opn = "mipsdsp shift";
14572 TCGv t0;
14573 TCGv v1_t;
14574 TCGv v2_t;
14575
14576 if (ret == 0) {
14577 /* Treat as NOP. */
14578 MIPS_DEBUG("NOP");
14579 return;
14580 }
14581
14582 t0 = tcg_temp_new();
14583 v1_t = tcg_temp_new();
14584 v2_t = tcg_temp_new();
14585
14586 tcg_gen_movi_tl(t0, v1);
14587 gen_load_gpr(v1_t, v1);
14588 gen_load_gpr(v2_t, v2);
14589
14590 switch (opc) {
14591 case OPC_SHLL_QB_DSP:
14592 {
14593 op2 = MASK_SHLL_QB(ctx->opcode);
14594 switch (op2) {
14595 case OPC_SHLL_QB:
14596 check_dsp(ctx);
14597 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14598 break;
14599 case OPC_SHLLV_QB:
14600 check_dsp(ctx);
14601 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14602 break;
14603 case OPC_SHLL_PH:
14604 check_dsp(ctx);
14605 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14606 break;
14607 case OPC_SHLLV_PH:
14608 check_dsp(ctx);
14609 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14610 break;
14611 case OPC_SHLL_S_PH:
14612 check_dsp(ctx);
14613 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14614 break;
14615 case OPC_SHLLV_S_PH:
14616 check_dsp(ctx);
14617 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14618 break;
14619 case OPC_SHLL_S_W:
14620 check_dsp(ctx);
14621 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14622 break;
14623 case OPC_SHLLV_S_W:
14624 check_dsp(ctx);
14625 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14626 break;
14627 case OPC_SHRL_QB:
14628 check_dsp(ctx);
14629 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14630 break;
14631 case OPC_SHRLV_QB:
14632 check_dsp(ctx);
14633 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14634 break;
14635 case OPC_SHRL_PH:
14636 check_dspr2(ctx);
14637 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14638 break;
14639 case OPC_SHRLV_PH:
14640 check_dspr2(ctx);
14641 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14642 break;
14643 case OPC_SHRA_QB:
14644 check_dspr2(ctx);
14645 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14646 break;
14647 case OPC_SHRA_R_QB:
14648 check_dspr2(ctx);
14649 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14650 break;
14651 case OPC_SHRAV_QB:
14652 check_dspr2(ctx);
14653 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14654 break;
14655 case OPC_SHRAV_R_QB:
14656 check_dspr2(ctx);
14657 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14658 break;
14659 case OPC_SHRA_PH:
14660 check_dsp(ctx);
14661 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14662 break;
14663 case OPC_SHRA_R_PH:
14664 check_dsp(ctx);
14665 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14666 break;
14667 case OPC_SHRAV_PH:
14668 check_dsp(ctx);
14669 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14670 break;
14671 case OPC_SHRAV_R_PH:
14672 check_dsp(ctx);
14673 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14674 break;
14675 case OPC_SHRA_R_W:
14676 check_dsp(ctx);
14677 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14678 break;
14679 case OPC_SHRAV_R_W:
14680 check_dsp(ctx);
14681 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14682 break;
14683 default: /* Invalid */
14684 MIPS_INVAL("MASK SHLL.QB");
14685 generate_exception(ctx, EXCP_RI);
14686 break;
14687 }
14688 break;
14689 }
14690#ifdef TARGET_MIPS64
14691 case OPC_SHLL_OB_DSP:
14692 op2 = MASK_SHLL_OB(ctx->opcode);
14693 switch (op2) {
14694 case OPC_SHLL_PW:
14695 check_dsp(ctx);
14696 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14697 break;
14698 case OPC_SHLLV_PW:
14699 check_dsp(ctx);
14700 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14701 break;
14702 case OPC_SHLL_S_PW:
14703 check_dsp(ctx);
14704 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14705 break;
14706 case OPC_SHLLV_S_PW:
14707 check_dsp(ctx);
14708 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14709 break;
14710 case OPC_SHLL_OB:
14711 check_dsp(ctx);
14712 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14713 break;
14714 case OPC_SHLLV_OB:
14715 check_dsp(ctx);
14716 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14717 break;
14718 case OPC_SHLL_QH:
14719 check_dsp(ctx);
14720 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14721 break;
14722 case OPC_SHLLV_QH:
14723 check_dsp(ctx);
14724 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14725 break;
14726 case OPC_SHLL_S_QH:
14727 check_dsp(ctx);
14728 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14729 break;
14730 case OPC_SHLLV_S_QH:
14731 check_dsp(ctx);
14732 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14733 break;
14734 case OPC_SHRA_OB:
14735 check_dspr2(ctx);
14736 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14737 break;
14738 case OPC_SHRAV_OB:
14739 check_dspr2(ctx);
14740 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14741 break;
14742 case OPC_SHRA_R_OB:
14743 check_dspr2(ctx);
14744 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14745 break;
14746 case OPC_SHRAV_R_OB:
14747 check_dspr2(ctx);
14748 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14749 break;
14750 case OPC_SHRA_PW:
14751 check_dsp(ctx);
14752 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14753 break;
14754 case OPC_SHRAV_PW:
14755 check_dsp(ctx);
14756 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14757 break;
14758 case OPC_SHRA_R_PW:
14759 check_dsp(ctx);
14760 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14761 break;
14762 case OPC_SHRAV_R_PW:
14763 check_dsp(ctx);
14764 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14765 break;
14766 case OPC_SHRA_QH:
14767 check_dsp(ctx);
14768 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14769 break;
14770 case OPC_SHRAV_QH:
14771 check_dsp(ctx);
14772 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14773 break;
14774 case OPC_SHRA_R_QH:
14775 check_dsp(ctx);
14776 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14777 break;
14778 case OPC_SHRAV_R_QH:
14779 check_dsp(ctx);
14780 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14781 break;
14782 case OPC_SHRL_OB:
14783 check_dsp(ctx);
14784 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14785 break;
14786 case OPC_SHRLV_OB:
14787 check_dsp(ctx);
14788 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14789 break;
14790 case OPC_SHRL_QH:
14791 check_dspr2(ctx);
14792 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14793 break;
14794 case OPC_SHRLV_QH:
14795 check_dspr2(ctx);
14796 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14797 break;
14798 default: /* Invalid */
14799 MIPS_INVAL("MASK SHLL.OB");
14800 generate_exception(ctx, EXCP_RI);
14801 break;
14802 }
14803 break;
14804#endif
14805 }
14806
14807 tcg_temp_free(t0);
14808 tcg_temp_free(v1_t);
14809 tcg_temp_free(v2_t);
14810 (void)opn; /* avoid a compiler warning */
14811 MIPS_DEBUG("%s", opn);
14812}
14813
a22260ae
JL
14814static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14815 int ret, int v1, int v2, int check_ret)
14816{
14817 const char *opn = "mipsdsp multiply";
14818 TCGv_i32 t0;
14819 TCGv v1_t;
14820 TCGv v2_t;
14821
14822 if ((ret == 0) && (check_ret == 1)) {
14823 /* Treat as NOP. */
14824 MIPS_DEBUG("NOP");
14825 return;
14826 }
14827
14828 t0 = tcg_temp_new_i32();
14829 v1_t = tcg_temp_new();
14830 v2_t = tcg_temp_new();
14831
14832 tcg_gen_movi_i32(t0, ret);
14833 gen_load_gpr(v1_t, v1);
14834 gen_load_gpr(v2_t, v2);
14835
14836 switch (op1) {
14837 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14838 * the same mask and op1. */
14839 case OPC_MULT_G_2E:
639eadb9 14840 check_dspr2(ctx);
a22260ae
JL
14841 switch (op2) {
14842 case OPC_MUL_PH:
14843 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14844 break;
14845 case OPC_MUL_S_PH:
14846 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14847 break;
14848 case OPC_MULQ_S_W:
14849 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14850 break;
14851 case OPC_MULQ_RS_W:
14852 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14853 break;
14854 }
14855 break;
14856 case OPC_DPA_W_PH_DSP:
14857 switch (op2) {
14858 case OPC_DPAU_H_QBL:
14859 check_dsp(ctx);
14860 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14861 break;
14862 case OPC_DPAU_H_QBR:
14863 check_dsp(ctx);
14864 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14865 break;
14866 case OPC_DPSU_H_QBL:
14867 check_dsp(ctx);
14868 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14869 break;
14870 case OPC_DPSU_H_QBR:
14871 check_dsp(ctx);
14872 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14873 break;
14874 case OPC_DPA_W_PH:
14875 check_dspr2(ctx);
14876 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14877 break;
14878 case OPC_DPAX_W_PH:
14879 check_dspr2(ctx);
14880 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14881 break;
14882 case OPC_DPAQ_S_W_PH:
14883 check_dsp(ctx);
14884 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14885 break;
14886 case OPC_DPAQX_S_W_PH:
14887 check_dspr2(ctx);
14888 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14889 break;
14890 case OPC_DPAQX_SA_W_PH:
14891 check_dspr2(ctx);
14892 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14893 break;
14894 case OPC_DPS_W_PH:
14895 check_dspr2(ctx);
14896 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14897 break;
14898 case OPC_DPSX_W_PH:
14899 check_dspr2(ctx);
14900 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
14901 break;
14902 case OPC_DPSQ_S_W_PH:
14903 check_dsp(ctx);
14904 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14905 break;
14906 case OPC_DPSQX_S_W_PH:
14907 check_dspr2(ctx);
14908 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14909 break;
14910 case OPC_DPSQX_SA_W_PH:
14911 check_dspr2(ctx);
14912 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14913 break;
14914 case OPC_MULSAQ_S_W_PH:
14915 check_dsp(ctx);
14916 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14917 break;
14918 case OPC_DPAQ_SA_L_W:
14919 check_dsp(ctx);
14920 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14921 break;
14922 case OPC_DPSQ_SA_L_W:
14923 check_dsp(ctx);
14924 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14925 break;
14926 case OPC_MAQ_S_W_PHL:
14927 check_dsp(ctx);
14928 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
14929 break;
14930 case OPC_MAQ_S_W_PHR:
14931 check_dsp(ctx);
14932 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
14933 break;
14934 case OPC_MAQ_SA_W_PHL:
14935 check_dsp(ctx);
14936 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
14937 break;
14938 case OPC_MAQ_SA_W_PHR:
14939 check_dsp(ctx);
14940 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
14941 break;
14942 case OPC_MULSA_W_PH:
14943 check_dspr2(ctx);
14944 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
14945 break;
14946 }
14947 break;
14948#ifdef TARGET_MIPS64
14949 case OPC_DPAQ_W_QH_DSP:
14950 {
14951 int ac = ret & 0x03;
14952 tcg_gen_movi_i32(t0, ac);
14953
14954 switch (op2) {
14955 case OPC_DMADD:
14956 check_dsp(ctx);
14957 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
14958 break;
14959 case OPC_DMADDU:
14960 check_dsp(ctx);
14961 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
14962 break;
14963 case OPC_DMSUB:
14964 check_dsp(ctx);
14965 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
14966 break;
14967 case OPC_DMSUBU:
14968 check_dsp(ctx);
14969 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
14970 break;
14971 case OPC_DPA_W_QH:
14972 check_dspr2(ctx);
14973 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
14974 break;
14975 case OPC_DPAQ_S_W_QH:
14976 check_dsp(ctx);
14977 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14978 break;
14979 case OPC_DPAQ_SA_L_PW:
14980 check_dsp(ctx);
14981 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14982 break;
14983 case OPC_DPAU_H_OBL:
14984 check_dsp(ctx);
14985 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
14986 break;
14987 case OPC_DPAU_H_OBR:
14988 check_dsp(ctx);
14989 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
14990 break;
14991 case OPC_DPS_W_QH:
14992 check_dspr2(ctx);
14993 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
14994 break;
14995 case OPC_DPSQ_S_W_QH:
14996 check_dsp(ctx);
14997 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14998 break;
14999 case OPC_DPSQ_SA_L_PW:
15000 check_dsp(ctx);
15001 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15002 break;
15003 case OPC_DPSU_H_OBL:
15004 check_dsp(ctx);
15005 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15006 break;
15007 case OPC_DPSU_H_OBR:
15008 check_dsp(ctx);
15009 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15010 break;
15011 case OPC_MAQ_S_L_PWL:
15012 check_dsp(ctx);
15013 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15014 break;
15015 case OPC_MAQ_S_L_PWR:
15016 check_dsp(ctx);
15017 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15018 break;
15019 case OPC_MAQ_S_W_QHLL:
15020 check_dsp(ctx);
15021 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15022 break;
15023 case OPC_MAQ_SA_W_QHLL:
15024 check_dsp(ctx);
15025 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15026 break;
15027 case OPC_MAQ_S_W_QHLR:
15028 check_dsp(ctx);
15029 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15030 break;
15031 case OPC_MAQ_SA_W_QHLR:
15032 check_dsp(ctx);
15033 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15034 break;
15035 case OPC_MAQ_S_W_QHRL:
15036 check_dsp(ctx);
15037 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15038 break;
15039 case OPC_MAQ_SA_W_QHRL:
15040 check_dsp(ctx);
15041 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15042 break;
15043 case OPC_MAQ_S_W_QHRR:
15044 check_dsp(ctx);
15045 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15046 break;
15047 case OPC_MAQ_SA_W_QHRR:
15048 check_dsp(ctx);
15049 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15050 break;
15051 case OPC_MULSAQ_S_L_PW:
15052 check_dsp(ctx);
15053 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15054 break;
15055 case OPC_MULSAQ_S_W_QH:
15056 check_dsp(ctx);
15057 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15058 break;
15059 }
15060 }
15061 break;
15062#endif
15063 case OPC_ADDU_QB_DSP:
15064 switch (op2) {
15065 case OPC_MULEU_S_PH_QBL:
15066 check_dsp(ctx);
15067 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15068 break;
15069 case OPC_MULEU_S_PH_QBR:
15070 check_dsp(ctx);
15071 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15072 break;
15073 case OPC_MULQ_RS_PH:
15074 check_dsp(ctx);
15075 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15076 break;
15077 case OPC_MULEQ_S_W_PHL:
15078 check_dsp(ctx);
15079 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15080 break;
15081 case OPC_MULEQ_S_W_PHR:
15082 check_dsp(ctx);
15083 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15084 break;
15085 case OPC_MULQ_S_PH:
15086 check_dspr2(ctx);
15087 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15088 break;
15089 }
15090 break;
15091#ifdef TARGET_MIPS64
15092 case OPC_ADDU_OB_DSP:
15093 switch (op2) {
15094 case OPC_MULEQ_S_PW_QHL:
15095 check_dsp(ctx);
15096 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15097 break;
15098 case OPC_MULEQ_S_PW_QHR:
15099 check_dsp(ctx);
15100 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15101 break;
15102 case OPC_MULEU_S_QH_OBL:
15103 check_dsp(ctx);
15104 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15105 break;
15106 case OPC_MULEU_S_QH_OBR:
15107 check_dsp(ctx);
15108 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15109 break;
15110 case OPC_MULQ_RS_QH:
15111 check_dsp(ctx);
15112 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15113 break;
15114 }
15115 break;
15116#endif
15117 }
15118
15119 tcg_temp_free_i32(t0);
15120 tcg_temp_free(v1_t);
15121 tcg_temp_free(v2_t);
15122
15123 (void)opn; /* avoid a compiler warning */
15124 MIPS_DEBUG("%s", opn);
15125
15126}
15127
d75c135e 15128static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15129 int ret, int val)
15130{
15131 const char *opn = "mipsdsp Bit/ Manipulation";
15132 int16_t imm;
15133 TCGv t0;
15134 TCGv val_t;
15135
15136 if (ret == 0) {
15137 /* Treat as NOP. */
15138 MIPS_DEBUG("NOP");
15139 return;
15140 }
15141
15142 t0 = tcg_temp_new();
15143 val_t = tcg_temp_new();
15144 gen_load_gpr(val_t, val);
15145
15146 switch (op1) {
15147 case OPC_ABSQ_S_PH_DSP:
15148 switch (op2) {
15149 case OPC_BITREV:
15150 check_dsp(ctx);
15151 gen_helper_bitrev(cpu_gpr[ret], val_t);
15152 break;
15153 case OPC_REPL_QB:
15154 check_dsp(ctx);
15155 {
15156 target_long result;
15157 imm = (ctx->opcode >> 16) & 0xFF;
15158 result = (uint32_t)imm << 24 |
15159 (uint32_t)imm << 16 |
15160 (uint32_t)imm << 8 |
15161 (uint32_t)imm;
15162 result = (int32_t)result;
15163 tcg_gen_movi_tl(cpu_gpr[ret], result);
15164 }
15165 break;
15166 case OPC_REPLV_QB:
15167 check_dsp(ctx);
15168 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15169 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15170 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15171 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15172 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15173 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15174 break;
15175 case OPC_REPL_PH:
15176 check_dsp(ctx);
15177 {
15178 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15179 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15180 tcg_gen_movi_tl(cpu_gpr[ret], \
15181 (target_long)((int32_t)imm << 16 | \
c4aaba92 15182 (uint16_t)imm));
1cb6686c
JL
15183 }
15184 break;
15185 case OPC_REPLV_PH:
15186 check_dsp(ctx);
15187 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15188 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15189 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15190 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15191 break;
15192 }
15193 break;
15194#ifdef TARGET_MIPS64
15195 case OPC_ABSQ_S_QH_DSP:
15196 switch (op2) {
15197 case OPC_REPL_OB:
15198 check_dsp(ctx);
15199 {
15200 target_long temp;
15201
15202 imm = (ctx->opcode >> 16) & 0xFF;
15203 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15204 temp = (temp << 16) | temp;
15205 temp = (temp << 32) | temp;
15206 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15207 break;
15208 }
15209 case OPC_REPL_PW:
15210 check_dsp(ctx);
15211 {
15212 target_long temp;
15213
15214 imm = (ctx->opcode >> 16) & 0x03FF;
15215 imm = (int16_t)(imm << 6) >> 6;
15216 temp = ((target_long)imm << 32) \
15217 | ((target_long)imm & 0xFFFFFFFF);
15218 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15219 break;
15220 }
15221 case OPC_REPL_QH:
15222 check_dsp(ctx);
15223 {
15224 target_long temp;
15225
15226 imm = (ctx->opcode >> 16) & 0x03FF;
15227 imm = (int16_t)(imm << 6) >> 6;
15228
15229 temp = ((uint64_t)(uint16_t)imm << 48) |
15230 ((uint64_t)(uint16_t)imm << 32) |
15231 ((uint64_t)(uint16_t)imm << 16) |
15232 (uint64_t)(uint16_t)imm;
15233 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15234 break;
15235 }
15236 case OPC_REPLV_OB:
15237 check_dsp(ctx);
15238 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15239 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15240 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15241 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15242 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15243 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15244 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15245 break;
15246 case OPC_REPLV_PW:
15247 check_dsp(ctx);
15248 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15249 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15250 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15251 break;
15252 case OPC_REPLV_QH:
15253 check_dsp(ctx);
15254 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15255 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15256 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15257 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15258 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15259 break;
15260 }
15261 break;
15262#endif
15263 }
15264 tcg_temp_free(t0);
15265 tcg_temp_free(val_t);
15266
15267 (void)opn; /* avoid a compiler warning */
15268 MIPS_DEBUG("%s", opn);
15269}
15270
26690560
JL
15271static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15272 uint32_t op1, uint32_t op2,
15273 int ret, int v1, int v2, int check_ret)
15274{
15275 const char *opn = "mipsdsp add compare pick";
26690560
JL
15276 TCGv t1;
15277 TCGv v1_t;
15278 TCGv v2_t;
15279
15280 if ((ret == 0) && (check_ret == 1)) {
15281 /* Treat as NOP. */
15282 MIPS_DEBUG("NOP");
15283 return;
15284 }
15285
26690560
JL
15286 t1 = tcg_temp_new();
15287 v1_t = tcg_temp_new();
15288 v2_t = tcg_temp_new();
15289
15290 gen_load_gpr(v1_t, v1);
15291 gen_load_gpr(v2_t, v2);
15292
15293 switch (op1) {
26690560
JL
15294 case OPC_CMPU_EQ_QB_DSP:
15295 switch (op2) {
15296 case OPC_CMPU_EQ_QB:
15297 check_dsp(ctx);
15298 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15299 break;
15300 case OPC_CMPU_LT_QB:
15301 check_dsp(ctx);
15302 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15303 break;
15304 case OPC_CMPU_LE_QB:
15305 check_dsp(ctx);
15306 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15307 break;
15308 case OPC_CMPGU_EQ_QB:
15309 check_dsp(ctx);
15310 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15311 break;
15312 case OPC_CMPGU_LT_QB:
15313 check_dsp(ctx);
15314 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15315 break;
15316 case OPC_CMPGU_LE_QB:
15317 check_dsp(ctx);
15318 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15319 break;
15320 case OPC_CMPGDU_EQ_QB:
15321 check_dspr2(ctx);
15322 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15323 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15324 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15325 tcg_gen_shli_tl(t1, t1, 24);
15326 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15327 break;
15328 case OPC_CMPGDU_LT_QB:
15329 check_dspr2(ctx);
15330 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15331 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15332 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15333 tcg_gen_shli_tl(t1, t1, 24);
15334 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15335 break;
15336 case OPC_CMPGDU_LE_QB:
15337 check_dspr2(ctx);
15338 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15339 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15340 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15341 tcg_gen_shli_tl(t1, t1, 24);
15342 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15343 break;
15344 case OPC_CMP_EQ_PH:
15345 check_dsp(ctx);
15346 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15347 break;
15348 case OPC_CMP_LT_PH:
15349 check_dsp(ctx);
15350 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15351 break;
15352 case OPC_CMP_LE_PH:
15353 check_dsp(ctx);
15354 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15355 break;
15356 case OPC_PICK_QB:
15357 check_dsp(ctx);
15358 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15359 break;
15360 case OPC_PICK_PH:
15361 check_dsp(ctx);
15362 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15363 break;
15364 case OPC_PACKRL_PH:
15365 check_dsp(ctx);
15366 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15367 break;
15368 }
15369 break;
15370#ifdef TARGET_MIPS64
15371 case OPC_CMPU_EQ_OB_DSP:
15372 switch (op2) {
15373 case OPC_CMP_EQ_PW:
15374 check_dsp(ctx);
15375 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15376 break;
15377 case OPC_CMP_LT_PW:
15378 check_dsp(ctx);
15379 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15380 break;
15381 case OPC_CMP_LE_PW:
15382 check_dsp(ctx);
15383 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15384 break;
15385 case OPC_CMP_EQ_QH:
15386 check_dsp(ctx);
15387 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15388 break;
15389 case OPC_CMP_LT_QH:
15390 check_dsp(ctx);
15391 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15392 break;
15393 case OPC_CMP_LE_QH:
15394 check_dsp(ctx);
15395 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15396 break;
15397 case OPC_CMPGDU_EQ_OB:
15398 check_dspr2(ctx);
15399 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15400 break;
15401 case OPC_CMPGDU_LT_OB:
15402 check_dspr2(ctx);
15403 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15404 break;
15405 case OPC_CMPGDU_LE_OB:
15406 check_dspr2(ctx);
15407 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15408 break;
15409 case OPC_CMPGU_EQ_OB:
15410 check_dsp(ctx);
15411 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15412 break;
15413 case OPC_CMPGU_LT_OB:
15414 check_dsp(ctx);
15415 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15416 break;
15417 case OPC_CMPGU_LE_OB:
15418 check_dsp(ctx);
15419 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15420 break;
15421 case OPC_CMPU_EQ_OB:
15422 check_dsp(ctx);
15423 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15424 break;
15425 case OPC_CMPU_LT_OB:
15426 check_dsp(ctx);
15427 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15428 break;
15429 case OPC_CMPU_LE_OB:
15430 check_dsp(ctx);
15431 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15432 break;
15433 case OPC_PACKRL_PW:
15434 check_dsp(ctx);
15435 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15436 break;
15437 case OPC_PICK_OB:
15438 check_dsp(ctx);
15439 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15440 break;
15441 case OPC_PICK_PW:
15442 check_dsp(ctx);
15443 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15444 break;
15445 case OPC_PICK_QH:
15446 check_dsp(ctx);
15447 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15448 break;
15449 }
15450 break;
df6126a7
AJ
15451#endif
15452 }
15453
15454 tcg_temp_free(t1);
15455 tcg_temp_free(v1_t);
15456 tcg_temp_free(v2_t);
15457
15458 (void)opn; /* avoid a compiler warning */
15459 MIPS_DEBUG("%s", opn);
15460}
15461
15462static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15463 uint32_t op1, int rt, int rs, int sa)
15464{
15465 const char *opn = "mipsdsp append/dappend";
15466 TCGv t0;
15467
15468 check_dspr2(ctx);
15469
15470 if (rt == 0) {
15471 /* Treat as NOP. */
15472 MIPS_DEBUG("NOP");
15473 return;
15474 }
15475
15476 t0 = tcg_temp_new();
15477 gen_load_gpr(t0, rs);
15478
15479 switch (op1) {
15480 case OPC_APPEND_DSP:
15481 switch (MASK_APPEND(ctx->opcode)) {
15482 case OPC_APPEND:
15483 if (sa != 0) {
15484 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15485 }
15486 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15487 break;
15488 case OPC_PREPEND:
15489 if (sa != 0) {
15490 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15491 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15492 tcg_gen_shli_tl(t0, t0, 32 - sa);
15493 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15494 }
15495 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15496 break;
15497 case OPC_BALIGN:
15498 sa &= 3;
15499 if (sa != 0 && sa != 2) {
15500 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15501 tcg_gen_ext32u_tl(t0, t0);
15502 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15503 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15504 }
15505 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15506 break;
15507 default: /* Invalid */
15508 MIPS_INVAL("MASK APPEND");
15509 generate_exception(ctx, EXCP_RI);
15510 break;
15511 }
15512 break;
15513#ifdef TARGET_MIPS64
26690560 15514 case OPC_DAPPEND_DSP:
df6126a7 15515 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15516 case OPC_DAPPEND:
df6126a7
AJ
15517 if (sa != 0) {
15518 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15519 }
26690560
JL
15520 break;
15521 case OPC_PREPENDD:
df6126a7
AJ
15522 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15523 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15524 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15525 break;
15526 case OPC_PREPENDW:
df6126a7
AJ
15527 if (sa != 0) {
15528 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15529 tcg_gen_shli_tl(t0, t0, 64 - sa);
15530 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15531 }
26690560
JL
15532 break;
15533 case OPC_DBALIGN:
df6126a7
AJ
15534 sa &= 7;
15535 if (sa != 0 && sa != 2 && sa != 4) {
15536 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15537 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15538 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15539 }
26690560
JL
15540 break;
15541 default: /* Invalid */
15542 MIPS_INVAL("MASK DAPPEND");
15543 generate_exception(ctx, EXCP_RI);
15544 break;
15545 }
15546 break;
15547#endif
15548 }
df6126a7 15549 tcg_temp_free(t0);
26690560
JL
15550 (void)opn; /* avoid a compiler warning */
15551 MIPS_DEBUG("%s", opn);
15552}
15553
b53371ed
JL
15554static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15555 int ret, int v1, int v2, int check_ret)
15556
15557{
15558 const char *opn = "mipsdsp accumulator";
15559 TCGv t0;
15560 TCGv t1;
15561 TCGv v1_t;
15562 TCGv v2_t;
15563 int16_t imm;
15564
15565 if ((ret == 0) && (check_ret == 1)) {
15566 /* Treat as NOP. */
15567 MIPS_DEBUG("NOP");
15568 return;
15569 }
15570
15571 t0 = tcg_temp_new();
15572 t1 = tcg_temp_new();
15573 v1_t = tcg_temp_new();
15574 v2_t = tcg_temp_new();
15575
15576 gen_load_gpr(v1_t, v1);
15577 gen_load_gpr(v2_t, v2);
15578
15579 switch (op1) {
15580 case OPC_EXTR_W_DSP:
15581 check_dsp(ctx);
15582 switch (op2) {
15583 case OPC_EXTR_W:
15584 tcg_gen_movi_tl(t0, v2);
15585 tcg_gen_movi_tl(t1, v1);
15586 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15587 break;
15588 case OPC_EXTR_R_W:
15589 tcg_gen_movi_tl(t0, v2);
15590 tcg_gen_movi_tl(t1, v1);
15591 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15592 break;
15593 case OPC_EXTR_RS_W:
15594 tcg_gen_movi_tl(t0, v2);
15595 tcg_gen_movi_tl(t1, v1);
15596 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15597 break;
15598 case OPC_EXTR_S_H:
15599 tcg_gen_movi_tl(t0, v2);
15600 tcg_gen_movi_tl(t1, v1);
15601 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15602 break;
15603 case OPC_EXTRV_S_H:
15604 tcg_gen_movi_tl(t0, v2);
15605 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15606 break;
15607 case OPC_EXTRV_W:
15608 tcg_gen_movi_tl(t0, v2);
15609 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15610 break;
15611 case OPC_EXTRV_R_W:
15612 tcg_gen_movi_tl(t0, v2);
15613 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15614 break;
15615 case OPC_EXTRV_RS_W:
15616 tcg_gen_movi_tl(t0, v2);
15617 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15618 break;
15619 case OPC_EXTP:
15620 tcg_gen_movi_tl(t0, v2);
15621 tcg_gen_movi_tl(t1, v1);
15622 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15623 break;
15624 case OPC_EXTPV:
15625 tcg_gen_movi_tl(t0, v2);
15626 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15627 break;
15628 case OPC_EXTPDP:
15629 tcg_gen_movi_tl(t0, v2);
15630 tcg_gen_movi_tl(t1, v1);
15631 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15632 break;
15633 case OPC_EXTPDPV:
15634 tcg_gen_movi_tl(t0, v2);
15635 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15636 break;
15637 case OPC_SHILO:
15638 imm = (ctx->opcode >> 20) & 0x3F;
15639 tcg_gen_movi_tl(t0, ret);
15640 tcg_gen_movi_tl(t1, imm);
15641 gen_helper_shilo(t0, t1, cpu_env);
15642 break;
15643 case OPC_SHILOV:
15644 tcg_gen_movi_tl(t0, ret);
15645 gen_helper_shilo(t0, v1_t, cpu_env);
15646 break;
15647 case OPC_MTHLIP:
15648 tcg_gen_movi_tl(t0, ret);
15649 gen_helper_mthlip(t0, v1_t, cpu_env);
15650 break;
15651 case OPC_WRDSP:
15652 imm = (ctx->opcode >> 11) & 0x3FF;
15653 tcg_gen_movi_tl(t0, imm);
15654 gen_helper_wrdsp(v1_t, t0, cpu_env);
15655 break;
15656 case OPC_RDDSP:
15657 imm = (ctx->opcode >> 16) & 0x03FF;
15658 tcg_gen_movi_tl(t0, imm);
15659 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15660 break;
15661 }
15662 break;
15663#ifdef TARGET_MIPS64
15664 case OPC_DEXTR_W_DSP:
15665 check_dsp(ctx);
15666 switch (op2) {
15667 case OPC_DMTHLIP:
15668 tcg_gen_movi_tl(t0, ret);
15669 gen_helper_dmthlip(v1_t, t0, cpu_env);
15670 break;
15671 case OPC_DSHILO:
15672 {
15673 int shift = (ctx->opcode >> 19) & 0x7F;
15674 int ac = (ctx->opcode >> 11) & 0x03;
15675 tcg_gen_movi_tl(t0, shift);
15676 tcg_gen_movi_tl(t1, ac);
15677 gen_helper_dshilo(t0, t1, cpu_env);
15678 break;
15679 }
15680 case OPC_DSHILOV:
15681 {
15682 int ac = (ctx->opcode >> 11) & 0x03;
15683 tcg_gen_movi_tl(t0, ac);
15684 gen_helper_dshilo(v1_t, t0, cpu_env);
15685 break;
15686 }
15687 case OPC_DEXTP:
15688 tcg_gen_movi_tl(t0, v2);
15689 tcg_gen_movi_tl(t1, v1);
15690
15691 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15692 break;
15693 case OPC_DEXTPV:
15694 tcg_gen_movi_tl(t0, v2);
15695 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15696 break;
15697 case OPC_DEXTPDP:
15698 tcg_gen_movi_tl(t0, v2);
15699 tcg_gen_movi_tl(t1, v1);
15700 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15701 break;
15702 case OPC_DEXTPDPV:
15703 tcg_gen_movi_tl(t0, v2);
15704 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15705 break;
15706 case OPC_DEXTR_L:
15707 tcg_gen_movi_tl(t0, v2);
15708 tcg_gen_movi_tl(t1, v1);
15709 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15710 break;
15711 case OPC_DEXTR_R_L:
15712 tcg_gen_movi_tl(t0, v2);
15713 tcg_gen_movi_tl(t1, v1);
15714 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15715 break;
15716 case OPC_DEXTR_RS_L:
15717 tcg_gen_movi_tl(t0, v2);
15718 tcg_gen_movi_tl(t1, v1);
15719 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15720 break;
15721 case OPC_DEXTR_W:
15722 tcg_gen_movi_tl(t0, v2);
15723 tcg_gen_movi_tl(t1, v1);
15724 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15725 break;
15726 case OPC_DEXTR_R_W:
15727 tcg_gen_movi_tl(t0, v2);
15728 tcg_gen_movi_tl(t1, v1);
15729 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15730 break;
15731 case OPC_DEXTR_RS_W:
15732 tcg_gen_movi_tl(t0, v2);
15733 tcg_gen_movi_tl(t1, v1);
15734 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15735 break;
15736 case OPC_DEXTR_S_H:
15737 tcg_gen_movi_tl(t0, v2);
15738 tcg_gen_movi_tl(t1, v1);
15739 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15740 break;
15741 case OPC_DEXTRV_S_H:
15742 tcg_gen_movi_tl(t0, v2);
15743 tcg_gen_movi_tl(t1, v1);
15744 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15745 break;
15746 case OPC_DEXTRV_L:
15747 tcg_gen_movi_tl(t0, v2);
15748 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15749 break;
15750 case OPC_DEXTRV_R_L:
15751 tcg_gen_movi_tl(t0, v2);
15752 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15753 break;
15754 case OPC_DEXTRV_RS_L:
15755 tcg_gen_movi_tl(t0, v2);
15756 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15757 break;
15758 case OPC_DEXTRV_W:
15759 tcg_gen_movi_tl(t0, v2);
15760 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15761 break;
15762 case OPC_DEXTRV_R_W:
15763 tcg_gen_movi_tl(t0, v2);
15764 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15765 break;
15766 case OPC_DEXTRV_RS_W:
15767 tcg_gen_movi_tl(t0, v2);
15768 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15769 break;
15770 }
15771 break;
15772#endif
15773 }
15774
15775 tcg_temp_free(t0);
15776 tcg_temp_free(t1);
15777 tcg_temp_free(v1_t);
15778 tcg_temp_free(v2_t);
15779
15780 (void)opn; /* avoid a compiler warning */
15781 MIPS_DEBUG("%s", opn);
15782}
15783
9b1a1d68
JL
15784/* End MIPSDSP functions. */
15785
31837be3
YK
15786/* Compact Branches */
15787static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15788 int rs, int rt, int32_t offset)
15789{
15790 int bcond_compute = 0;
15791 TCGv t0 = tcg_temp_new();
15792 TCGv t1 = tcg_temp_new();
15793
15794 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15795#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15796 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15797 "\n", ctx->pc);
31837be3
YK
15798#endif
15799 generate_exception(ctx, EXCP_RI);
15800 goto out;
15801 }
15802
15803 /* Load needed operands and calculate btarget */
15804 switch (opc) {
15805 /* compact branch */
15806 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15807 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15808 gen_load_gpr(t0, rs);
15809 gen_load_gpr(t1, rt);
15810 bcond_compute = 1;
15811 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15812 if (rs <= rt && rs == 0) {
15813 /* OPC_BEQZALC, OPC_BNEZALC */
15814 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15815 }
15816 break;
15817 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15818 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15819 gen_load_gpr(t0, rs);
15820 gen_load_gpr(t1, rt);
15821 bcond_compute = 1;
15822 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15823 break;
15824 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15825 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15826 if (rs == 0 || rs == rt) {
15827 /* OPC_BLEZALC, OPC_BGEZALC */
15828 /* OPC_BGTZALC, OPC_BLTZALC */
15829 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15830 }
15831 gen_load_gpr(t0, rs);
15832 gen_load_gpr(t1, rt);
15833 bcond_compute = 1;
15834 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15835 break;
15836 case OPC_BC:
15837 case OPC_BALC:
15838 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15839 break;
15840 case OPC_BEQZC:
15841 case OPC_BNEZC:
15842 if (rs != 0) {
15843 /* OPC_BEQZC, OPC_BNEZC */
15844 gen_load_gpr(t0, rs);
15845 bcond_compute = 1;
15846 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15847 } else {
15848 /* OPC_JIC, OPC_JIALC */
15849 TCGv tbase = tcg_temp_new();
15850 TCGv toffset = tcg_temp_new();
15851
15852 gen_load_gpr(tbase, rt);
15853 tcg_gen_movi_tl(toffset, offset);
15854 gen_op_addr_add(ctx, btarget, tbase, toffset);
15855 tcg_temp_free(tbase);
15856 tcg_temp_free(toffset);
15857 }
15858 break;
15859 default:
15860 MIPS_INVAL("Compact branch/jump");
15861 generate_exception(ctx, EXCP_RI);
15862 goto out;
15863 }
15864
15865 if (bcond_compute == 0) {
15866 /* Uncoditional compact branch */
15867 switch (opc) {
15868 case OPC_JIALC:
15869 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15870 /* Fallthrough */
15871 case OPC_JIC:
15872 ctx->hflags |= MIPS_HFLAG_BR;
15873 break;
15874 case OPC_BALC:
15875 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15876 /* Fallthrough */
15877 case OPC_BC:
15878 ctx->hflags |= MIPS_HFLAG_B;
15879 break;
15880 default:
15881 MIPS_INVAL("Compact branch/jump");
15882 generate_exception(ctx, EXCP_RI);
15883 goto out;
15884 }
15885
15886 /* Generating branch here as compact branches don't have delay slot */
15887 gen_branch(ctx, 4);
15888 } else {
15889 /* Conditional compact branch */
339cd2a8 15890 int fs = gen_new_label();
31837be3
YK
15891 save_cpu_state(ctx, 0);
15892
15893 switch (opc) {
15894 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15895 if (rs == 0 && rt != 0) {
15896 /* OPC_BLEZALC */
339cd2a8 15897 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
15898 } else if (rs != 0 && rt != 0 && rs == rt) {
15899 /* OPC_BGEZALC */
339cd2a8 15900 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
15901 } else {
15902 /* OPC_BGEUC */
339cd2a8 15903 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
15904 }
15905 break;
15906 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15907 if (rs == 0 && rt != 0) {
15908 /* OPC_BGTZALC */
339cd2a8 15909 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
15910 } else if (rs != 0 && rt != 0 && rs == rt) {
15911 /* OPC_BLTZALC */
339cd2a8 15912 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
15913 } else {
15914 /* OPC_BLTUC */
339cd2a8 15915 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
15916 }
15917 break;
15918 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15919 if (rs == 0 && rt != 0) {
15920 /* OPC_BLEZC */
339cd2a8 15921 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
15922 } else if (rs != 0 && rt != 0 && rs == rt) {
15923 /* OPC_BGEZC */
339cd2a8 15924 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
15925 } else {
15926 /* OPC_BGEC */
339cd2a8 15927 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
15928 }
15929 break;
15930 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15931 if (rs == 0 && rt != 0) {
15932 /* OPC_BGTZC */
339cd2a8 15933 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
15934 } else if (rs != 0 && rt != 0 && rs == rt) {
15935 /* OPC_BLTZC */
339cd2a8 15936 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
15937 } else {
15938 /* OPC_BLTC */
339cd2a8 15939 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
15940 }
15941 break;
15942 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15943 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15944 if (rs >= rt) {
15945 /* OPC_BOVC, OPC_BNVC */
15946 TCGv t2 = tcg_temp_new();
15947 TCGv t3 = tcg_temp_new();
15948 TCGv t4 = tcg_temp_new();
15949 TCGv input_overflow = tcg_temp_new();
15950
15951 gen_load_gpr(t0, rs);
15952 gen_load_gpr(t1, rt);
15953 tcg_gen_ext32s_tl(t2, t0);
15954 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
15955 tcg_gen_ext32s_tl(t3, t1);
15956 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
15957 tcg_gen_or_tl(input_overflow, input_overflow, t4);
15958
15959 tcg_gen_add_tl(t4, t2, t3);
15960 tcg_gen_ext32s_tl(t4, t4);
15961 tcg_gen_xor_tl(t2, t2, t3);
15962 tcg_gen_xor_tl(t3, t4, t3);
15963 tcg_gen_andc_tl(t2, t3, t2);
15964 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
15965 tcg_gen_or_tl(t4, t4, input_overflow);
15966 if (opc == OPC_BOVC) {
15967 /* OPC_BOVC */
339cd2a8 15968 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
15969 } else {
15970 /* OPC_BNVC */
339cd2a8 15971 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
15972 }
15973 tcg_temp_free(input_overflow);
15974 tcg_temp_free(t4);
15975 tcg_temp_free(t3);
15976 tcg_temp_free(t2);
15977 } else if (rs < rt && rs == 0) {
15978 /* OPC_BEQZALC, OPC_BNEZALC */
15979 if (opc == OPC_BEQZALC) {
15980 /* OPC_BEQZALC */
339cd2a8 15981 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
15982 } else {
15983 /* OPC_BNEZALC */
339cd2a8 15984 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
15985 }
15986 } else {
15987 /* OPC_BEQC, OPC_BNEC */
15988 if (opc == OPC_BEQC) {
15989 /* OPC_BEQC */
339cd2a8 15990 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
15991 } else {
15992 /* OPC_BNEC */
339cd2a8 15993 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
15994 }
15995 }
15996 break;
15997 case OPC_BEQZC:
339cd2a8 15998 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
15999 break;
16000 case OPC_BNEZC:
339cd2a8 16001 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16002 break;
16003 default:
16004 MIPS_INVAL("Compact conditional branch/jump");
16005 generate_exception(ctx, EXCP_RI);
16006 goto out;
16007 }
16008
16009 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16010 gen_goto_tb(ctx, 1, ctx->btarget);
16011 gen_set_label(fs);
16012
16013 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16014 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16015 }
16016
16017out:
16018 tcg_temp_free(t0);
16019 tcg_temp_free(t1);
16020}
16021
10dc65db
LA
16022static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16023{
4267d3e6 16024 int rs, rt, rd, sa;
b42ee5e1 16025 uint32_t op1, op2;
10dc65db
LA
16026
16027 rs = (ctx->opcode >> 21) & 0x1f;
16028 rt = (ctx->opcode >> 16) & 0x1f;
16029 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16030 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16031
16032 op1 = MASK_SPECIAL(ctx->opcode);
16033 switch (op1) {
d4ea6acd
LA
16034 case OPC_LSA:
16035 if (rd != 0) {
16036 int imm2 = extract32(ctx->opcode, 6, 3);
16037 TCGv t0 = tcg_temp_new();
16038 TCGv t1 = tcg_temp_new();
16039 gen_load_gpr(t0, rs);
16040 gen_load_gpr(t1, rt);
16041 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16042 tcg_gen_add_tl(t0, t0, t1);
16043 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16044 tcg_temp_free(t1);
16045 tcg_temp_free(t0);
16046 }
16047 break;
b42ee5e1
LA
16048 case OPC_MULT ... OPC_DIVU:
16049 op2 = MASK_R6_MULDIV(ctx->opcode);
16050 switch (op2) {
16051 case R6_OPC_MUL:
16052 case R6_OPC_MUH:
16053 case R6_OPC_MULU:
16054 case R6_OPC_MUHU:
16055 case R6_OPC_DIV:
16056 case R6_OPC_MOD:
16057 case R6_OPC_DIVU:
16058 case R6_OPC_MODU:
16059 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16060 break;
16061 default:
16062 MIPS_INVAL("special_r6 muldiv");
16063 generate_exception(ctx, EXCP_RI);
16064 break;
16065 }
16066 break;
10dc65db
LA
16067 case OPC_SELEQZ:
16068 case OPC_SELNEZ:
16069 gen_cond_move(ctx, op1, rd, rs, rt);
16070 break;
4267d3e6
LA
16071 case R6_OPC_CLO:
16072 case R6_OPC_CLZ:
16073 if (rt == 0 && sa == 1) {
16074 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16075 We need additionally to check other fields */
16076 gen_cl(ctx, op1, rd, rs);
16077 } else {
16078 generate_exception(ctx, EXCP_RI);
16079 }
16080 break;
16081 case R6_OPC_SDBBP:
faf1f68b
LA
16082 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16083 generate_exception(ctx, EXCP_RI);
16084 } else {
16085 generate_exception(ctx, EXCP_DBp);
16086 }
4267d3e6 16087 break;
b42ee5e1 16088#if defined(TARGET_MIPS64)
d4ea6acd
LA
16089 case OPC_DLSA:
16090 check_mips_64(ctx);
16091 if (rd != 0) {
16092 int imm2 = extract32(ctx->opcode, 6, 3);
16093 TCGv t0 = tcg_temp_new();
16094 TCGv t1 = tcg_temp_new();
16095 gen_load_gpr(t0, rs);
16096 gen_load_gpr(t1, rt);
16097 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16098 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16099 tcg_temp_free(t1);
16100 tcg_temp_free(t0);
16101 }
16102 break;
4267d3e6
LA
16103 case R6_OPC_DCLO:
16104 case R6_OPC_DCLZ:
16105 if (rt == 0 && sa == 1) {
16106 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16107 We need additionally to check other fields */
16108 check_mips_64(ctx);
16109 gen_cl(ctx, op1, rd, rs);
16110 } else {
16111 generate_exception(ctx, EXCP_RI);
16112 }
16113 break;
b42ee5e1
LA
16114 case OPC_DMULT ... OPC_DDIVU:
16115 op2 = MASK_R6_MULDIV(ctx->opcode);
16116 switch (op2) {
16117 case R6_OPC_DMUL:
16118 case R6_OPC_DMUH:
16119 case R6_OPC_DMULU:
16120 case R6_OPC_DMUHU:
16121 case R6_OPC_DDIV:
16122 case R6_OPC_DMOD:
16123 case R6_OPC_DDIVU:
16124 case R6_OPC_DMODU:
16125 check_mips_64(ctx);
16126 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16127 break;
16128 default:
16129 MIPS_INVAL("special_r6 muldiv");
16130 generate_exception(ctx, EXCP_RI);
16131 break;
16132 }
16133 break;
16134#endif
10dc65db
LA
16135 default: /* Invalid */
16136 MIPS_INVAL("special_r6");
16137 generate_exception(ctx, EXCP_RI);
16138 break;
16139 }
16140}
16141
16142static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16143{
b42ee5e1 16144 int rs, rt, rd, sa;
10dc65db
LA
16145 uint32_t op1;
16146
16147 rs = (ctx->opcode >> 21) & 0x1f;
16148 rt = (ctx->opcode >> 16) & 0x1f;
16149 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16150 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16151
16152 op1 = MASK_SPECIAL(ctx->opcode);
16153 switch (op1) {
16154 case OPC_MOVN: /* Conditional move */
16155 case OPC_MOVZ:
16156 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16157 INSN_LOONGSON2E | INSN_LOONGSON2F);
16158 gen_cond_move(ctx, op1, rd, rs, rt);
16159 break;
16160 case OPC_MFHI: /* Move from HI/LO */
16161 case OPC_MFLO:
16162 gen_HILO(ctx, op1, rs & 3, rd);
16163 break;
16164 case OPC_MTHI:
16165 case OPC_MTLO: /* Move to HI/LO */
16166 gen_HILO(ctx, op1, rd & 3, rs);
16167 break;
16168 case OPC_MOVCI:
16169 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16170 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16171 check_cp1_enabled(ctx);
16172 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16173 (ctx->opcode >> 16) & 1);
16174 } else {
16175 generate_exception_err(ctx, EXCP_CpU, 1);
16176 }
16177 break;
b42ee5e1
LA
16178 case OPC_MULT:
16179 case OPC_MULTU:
16180 if (sa) {
16181 check_insn(ctx, INSN_VR54XX);
16182 op1 = MASK_MUL_VR54XX(ctx->opcode);
16183 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16184 } else {
16185 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16186 }
16187 break;
16188 case OPC_DIV:
16189 case OPC_DIVU:
16190 gen_muldiv(ctx, op1, 0, rs, rt);
16191 break;
16192#if defined(TARGET_MIPS64)
16193 case OPC_DMULT ... OPC_DDIVU:
16194 check_insn(ctx, ISA_MIPS3);
16195 check_mips_64(ctx);
16196 gen_muldiv(ctx, op1, 0, rs, rt);
16197 break;
16198#endif
0aefa333 16199 case OPC_JR:
b231c103 16200 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16201 break;
4267d3e6
LA
16202 case OPC_SPIM:
16203#ifdef MIPS_STRICT_STANDARD
16204 MIPS_INVAL("SPIM");
16205 generate_exception(ctx, EXCP_RI);
16206#else
16207 /* Implemented as RI exception for now. */
16208 MIPS_INVAL("spim (unofficial)");
16209 generate_exception(ctx, EXCP_RI);
16210#endif
16211 break;
10dc65db
LA
16212 default: /* Invalid */
16213 MIPS_INVAL("special_legacy");
16214 generate_exception(ctx, EXCP_RI);
16215 break;
16216 }
16217}
16218
099e5b4d 16219static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16220{
3c824109 16221 int rs, rt, rd, sa;
099e5b4d 16222 uint32_t op1;
3c824109 16223
3c824109
NF
16224 rs = (ctx->opcode >> 21) & 0x1f;
16225 rt = (ctx->opcode >> 16) & 0x1f;
16226 rd = (ctx->opcode >> 11) & 0x1f;
16227 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16228
16229 op1 = MASK_SPECIAL(ctx->opcode);
16230 switch (op1) {
16231 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16232 if (sa == 5 && rd == 0 &&
16233 rs == 0 && rt == 0) { /* PAUSE */
16234 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16235 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16236 MIPS_DEBUG("CTI in delay / forbidden slot");
16237 generate_exception(ctx, EXCP_RI);
16238 break;
16239 }
16240 }
16241 /* Fallthrough */
099e5b4d
LA
16242 case OPC_SRA:
16243 gen_shift_imm(ctx, op1, rd, rt, sa);
16244 break;
16245 case OPC_SRL:
16246 switch ((ctx->opcode >> 21) & 0x1f) {
16247 case 1:
16248 /* rotr is decoded as srl on non-R2 CPUs */
16249 if (ctx->insn_flags & ISA_MIPS32R2) {
16250 op1 = OPC_ROTR;
ea63e2c3 16251 }
099e5b4d
LA
16252 /* Fallthrough */
16253 case 0:
16254 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16255 break;
099e5b4d
LA
16256 default:
16257 generate_exception(ctx, EXCP_RI);
ea63e2c3 16258 break;
099e5b4d
LA
16259 }
16260 break;
099e5b4d
LA
16261 case OPC_ADD ... OPC_SUBU:
16262 gen_arith(ctx, op1, rd, rs, rt);
16263 break;
16264 case OPC_SLLV: /* Shifts */
16265 case OPC_SRAV:
16266 gen_shift(ctx, op1, rd, rs, rt);
16267 break;
16268 case OPC_SRLV:
16269 switch ((ctx->opcode >> 6) & 0x1f) {
16270 case 1:
16271 /* rotrv is decoded as srlv on non-R2 CPUs */
16272 if (ctx->insn_flags & ISA_MIPS32R2) {
16273 op1 = OPC_ROTRV;
26135ead 16274 }
099e5b4d
LA
16275 /* Fallthrough */
16276 case 0:
16277 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16278 break;
099e5b4d
LA
16279 default:
16280 generate_exception(ctx, EXCP_RI);
6af0bf9c 16281 break;
099e5b4d
LA
16282 }
16283 break;
16284 case OPC_SLT: /* Set on less than */
16285 case OPC_SLTU:
16286 gen_slt(ctx, op1, rd, rs, rt);
16287 break;
16288 case OPC_AND: /* Logic*/
16289 case OPC_OR:
16290 case OPC_NOR:
16291 case OPC_XOR:
16292 gen_logic(ctx, op1, rd, rs, rt);
16293 break;
0aefa333 16294 case OPC_JALR:
b231c103 16295 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16296 break;
16297 case OPC_TGE ... OPC_TEQ: /* Traps */
16298 case OPC_TNE:
16299 gen_trap(ctx, op1, rs, rt, -1);
16300 break;
d4ea6acd
LA
16301 case OPC_LSA: /* OPC_PMON */
16302 if (ctx->insn_flags & ISA_MIPS32R6) {
16303 decode_opc_special_r6(env, ctx);
16304 } else {
16305 /* Pmon entry point, also R4010 selsl */
b48cfdff 16306#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16307 MIPS_INVAL("PMON / selsl");
16308 generate_exception(ctx, EXCP_RI);
b48cfdff 16309#else
d4ea6acd 16310 gen_helper_0e0i(pmon, sa);
b48cfdff 16311#endif
d4ea6acd 16312 }
099e5b4d
LA
16313 break;
16314 case OPC_SYSCALL:
16315 generate_exception(ctx, EXCP_SYSCALL);
16316 ctx->bstate = BS_STOP;
16317 break;
16318 case OPC_BREAK:
16319 generate_exception(ctx, EXCP_BREAK);
16320 break;
099e5b4d
LA
16321 case OPC_SYNC:
16322 /* Treat as NOP. */
16323 break;
4ad40f36 16324
d26bc211 16325#if defined(TARGET_MIPS64)
099e5b4d
LA
16326 /* MIPS64 specific opcodes */
16327 case OPC_DSLL:
16328 case OPC_DSRA:
16329 case OPC_DSLL32:
16330 case OPC_DSRA32:
16331 check_insn(ctx, ISA_MIPS3);
16332 check_mips_64(ctx);
16333 gen_shift_imm(ctx, op1, rd, rt, sa);
16334 break;
16335 case OPC_DSRL:
16336 switch ((ctx->opcode >> 21) & 0x1f) {
16337 case 1:
16338 /* drotr is decoded as dsrl on non-R2 CPUs */
16339 if (ctx->insn_flags & ISA_MIPS32R2) {
16340 op1 = OPC_DROTR;
ea63e2c3 16341 }
099e5b4d
LA
16342 /* Fallthrough */
16343 case 0:
d75c135e 16344 check_insn(ctx, ISA_MIPS3);
e189e748 16345 check_mips_64(ctx);
099e5b4d 16346 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16347 break;
099e5b4d
LA
16348 default:
16349 generate_exception(ctx, EXCP_RI);
460f00c4 16350 break;
099e5b4d
LA
16351 }
16352 break;
16353 case OPC_DSRL32:
16354 switch ((ctx->opcode >> 21) & 0x1f) {
16355 case 1:
16356 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16357 if (ctx->insn_flags & ISA_MIPS32R2) {
16358 op1 = OPC_DROTR32;
ea63e2c3 16359 }
099e5b4d
LA
16360 /* Fallthrough */
16361 case 0:
d75c135e 16362 check_insn(ctx, ISA_MIPS3);
e189e748 16363 check_mips_64(ctx);
099e5b4d 16364 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16365 break;
099e5b4d 16366 default:
6af0bf9c
FB
16367 generate_exception(ctx, EXCP_RI);
16368 break;
16369 }
16370 break;
099e5b4d
LA
16371 case OPC_DADD ... OPC_DSUBU:
16372 check_insn(ctx, ISA_MIPS3);
16373 check_mips_64(ctx);
16374 gen_arith(ctx, op1, rd, rs, rt);
16375 break;
16376 case OPC_DSLLV:
16377 case OPC_DSRAV:
16378 check_insn(ctx, ISA_MIPS3);
16379 check_mips_64(ctx);
16380 gen_shift(ctx, op1, rd, rs, rt);
16381 break;
16382 case OPC_DSRLV:
16383 switch ((ctx->opcode >> 6) & 0x1f) {
16384 case 1:
16385 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16386 if (ctx->insn_flags & ISA_MIPS32R2) {
16387 op1 = OPC_DROTRV;
6af0bf9c 16388 }
099e5b4d
LA
16389 /* Fallthrough */
16390 case 0:
16391 check_insn(ctx, ISA_MIPS3);
e189e748 16392 check_mips_64(ctx);
099e5b4d 16393 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16394 break;
099e5b4d 16395 default:
6af0bf9c
FB
16396 generate_exception(ctx, EXCP_RI);
16397 break;
16398 }
16399 break;
099e5b4d 16400#endif
10dc65db
LA
16401 default:
16402 if (ctx->insn_flags & ISA_MIPS32R6) {
16403 decode_opc_special_r6(env, ctx);
16404 } else {
16405 decode_opc_special_legacy(env, ctx);
16406 }
16407 }
16408}
16409
10dc65db 16410static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16411{
16412 int rs, rt, rd;
16413 uint32_t op1;
6c5c1e20 16414
4267d3e6
LA
16415 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16416
099e5b4d
LA
16417 rs = (ctx->opcode >> 21) & 0x1f;
16418 rt = (ctx->opcode >> 16) & 0x1f;
16419 rd = (ctx->opcode >> 11) & 0x1f;
16420
16421 op1 = MASK_SPECIAL2(ctx->opcode);
16422 switch (op1) {
16423 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16424 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16425 check_insn(ctx, ISA_MIPS32);
16426 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16427 break;
16428 case OPC_MUL:
099e5b4d
LA
16429 gen_arith(ctx, op1, rd, rs, rt);
16430 break;
fac5a073
LA
16431 case OPC_DIV_G_2F:
16432 case OPC_DIVU_G_2F:
16433 case OPC_MULT_G_2F:
16434 case OPC_MULTU_G_2F:
16435 case OPC_MOD_G_2F:
16436 case OPC_MODU_G_2F:
16437 check_insn(ctx, INSN_LOONGSON2F);
16438 gen_loongson_integer(ctx, op1, rd, rs, rt);
16439 break;
099e5b4d
LA
16440 case OPC_CLO:
16441 case OPC_CLZ:
16442 check_insn(ctx, ISA_MIPS32);
16443 gen_cl(ctx, op1, rd, rs);
16444 break;
16445 case OPC_SDBBP:
16446 /* XXX: not clear which exception should be raised
16447 * when in debug mode...
16448 */
16449 check_insn(ctx, ISA_MIPS32);
16450 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16451 generate_exception(ctx, EXCP_DBp);
16452 } else {
16453 generate_exception(ctx, EXCP_DBp);
16454 }
16455 /* Treat as NOP. */
16456 break;
9b1a1d68 16457#if defined(TARGET_MIPS64)
099e5b4d
LA
16458 case OPC_DCLO:
16459 case OPC_DCLZ:
16460 check_insn(ctx, ISA_MIPS64);
16461 check_mips_64(ctx);
16462 gen_cl(ctx, op1, rd, rs);
16463 break;
4267d3e6
LA
16464 case OPC_DMULT_G_2F:
16465 case OPC_DMULTU_G_2F:
16466 case OPC_DDIV_G_2F:
16467 case OPC_DDIVU_G_2F:
16468 case OPC_DMOD_G_2F:
16469 case OPC_DMODU_G_2F:
16470 check_insn(ctx, INSN_LOONGSON2F);
16471 gen_loongson_integer(ctx, op1, rd, rs, rt);
16472 break;
10dc65db 16473#endif
4267d3e6
LA
16474 default: /* Invalid */
16475 MIPS_INVAL("special2_legacy");
16476 generate_exception(ctx, EXCP_RI);
16477 break;
10dc65db
LA
16478 }
16479}
16480
16481static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16482{
15eacb9b
YK
16483 int rs, rt, rd, sa;
16484 uint32_t op1, op2;
10dc65db
LA
16485 int16_t imm;
16486
16487 rs = (ctx->opcode >> 21) & 0x1f;
16488 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16489 rd = (ctx->opcode >> 11) & 0x1f;
16490 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16491 imm = (int16_t)ctx->opcode >> 7;
16492
16493 op1 = MASK_SPECIAL3(ctx->opcode);
16494 switch (op1) {
bf7910c6
LA
16495 case R6_OPC_PREF:
16496 if (rt >= 24) {
16497 /* hint codes 24-31 are reserved and signal RI */
16498 generate_exception(ctx, EXCP_RI);
16499 }
16500 /* Treat as NOP. */
16501 break;
16502 case R6_OPC_CACHE:
16503 /* Treat as NOP. */
16504 break;
10dc65db
LA
16505 case R6_OPC_SC:
16506 gen_st_cond(ctx, op1, rt, rs, imm);
16507 break;
16508 case R6_OPC_LL:
16509 gen_ld(ctx, op1, rt, rs, imm);
16510 break;
15eacb9b
YK
16511 case OPC_BSHFL:
16512 {
16513 if (rd == 0) {
16514 /* Treat as NOP. */
16515 break;
16516 }
16517 TCGv t0 = tcg_temp_new();
16518 gen_load_gpr(t0, rt);
16519
16520 op2 = MASK_BSHFL(ctx->opcode);
16521 switch (op2) {
16522 case OPC_ALIGN ... OPC_ALIGN_END:
16523 sa &= 3;
16524 if (sa == 0) {
16525 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16526 } else {
16527 TCGv t1 = tcg_temp_new();
16528 TCGv_i64 t2 = tcg_temp_new_i64();
16529 gen_load_gpr(t1, rs);
16530 tcg_gen_concat_tl_i64(t2, t1, t0);
16531 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16532#if defined(TARGET_MIPS64)
16533 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16534#else
16535 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16536#endif
16537 tcg_temp_free_i64(t2);
16538 tcg_temp_free(t1);
16539 }
16540 break;
16541 case OPC_BITSWAP:
16542 gen_helper_bitswap(cpu_gpr[rd], t0);
16543 break;
16544 }
16545 tcg_temp_free(t0);
16546 }
16547 break;
bf7910c6
LA
16548#if defined(TARGET_MIPS64)
16549 case R6_OPC_SCD:
16550 gen_st_cond(ctx, op1, rt, rs, imm);
16551 break;
16552 case R6_OPC_LLD:
16553 gen_ld(ctx, op1, rt, rs, imm);
16554 break;
15eacb9b
YK
16555 case OPC_DBSHFL:
16556 check_mips_64(ctx);
16557 {
16558 if (rd == 0) {
16559 /* Treat as NOP. */
16560 break;
16561 }
16562 TCGv t0 = tcg_temp_new();
16563 gen_load_gpr(t0, rt);
16564
16565 op2 = MASK_DBSHFL(ctx->opcode);
16566 switch (op2) {
16567 case OPC_DALIGN ... OPC_DALIGN_END:
16568 sa &= 7;
16569 if (sa == 0) {
16570 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16571 } else {
16572 TCGv t1 = tcg_temp_new();
16573 gen_load_gpr(t1, rs);
16574 tcg_gen_shli_tl(t0, t0, 8 * sa);
16575 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16576 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16577 tcg_temp_free(t1);
16578 }
16579 break;
16580 case OPC_DBITSWAP:
16581 gen_helper_dbitswap(cpu_gpr[rd], t0);
16582 break;
16583 }
16584 tcg_temp_free(t0);
16585 }
16586 break;
bf7910c6 16587#endif
10dc65db
LA
16588 default: /* Invalid */
16589 MIPS_INVAL("special3_r6");
16590 generate_exception(ctx, EXCP_RI);
16591 break;
16592 }
16593}
16594
16595static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16596{
fac5a073 16597 int rs, rt, rd;
099e5b4d 16598 uint32_t op1, op2;
099e5b4d
LA
16599
16600 rs = (ctx->opcode >> 21) & 0x1f;
16601 rt = (ctx->opcode >> 16) & 0x1f;
16602 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16603
16604 op1 = MASK_SPECIAL3(ctx->opcode);
16605 switch (op1) {
099e5b4d
LA
16606 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16607 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16608 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16609 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16610 * the same mask and op1. */
16611 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16612 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16613 switch (op2) {
099e5b4d
LA
16614 case OPC_ADDUH_QB:
16615 case OPC_ADDUH_R_QB:
16616 case OPC_ADDQH_PH:
16617 case OPC_ADDQH_R_PH:
16618 case OPC_ADDQH_W:
16619 case OPC_ADDQH_R_W:
16620 case OPC_SUBUH_QB:
16621 case OPC_SUBUH_R_QB:
16622 case OPC_SUBQH_PH:
16623 case OPC_SUBQH_R_PH:
16624 case OPC_SUBQH_W:
16625 case OPC_SUBQH_R_W:
461c08df
JL
16626 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16627 break;
099e5b4d
LA
16628 case OPC_MUL_PH:
16629 case OPC_MUL_S_PH:
16630 case OPC_MULQ_S_W:
16631 case OPC_MULQ_RS_W:
16632 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16633 break;
461c08df 16634 default:
099e5b4d 16635 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16636 generate_exception(ctx, EXCP_RI);
16637 break;
16638 }
099e5b4d
LA
16639 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16640 gen_loongson_integer(ctx, op1, rd, rs, rt);
16641 } else {
16642 generate_exception(ctx, EXCP_RI);
16643 }
16644 break;
16645 case OPC_LX_DSP:
16646 op2 = MASK_LX(ctx->opcode);
16647 switch (op2) {
16648#if defined(TARGET_MIPS64)
16649 case OPC_LDX:
16650#endif
16651 case OPC_LBUX:
16652 case OPC_LHX:
16653 case OPC_LWX:
16654 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16655 break;
16656 default: /* Invalid */
16657 MIPS_INVAL("MASK LX");
16658 generate_exception(ctx, EXCP_RI);
16659 break;
16660 }
16661 break;
16662 case OPC_ABSQ_S_PH_DSP:
16663 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16664 switch (op2) {
16665 case OPC_ABSQ_S_QB:
16666 case OPC_ABSQ_S_PH:
16667 case OPC_ABSQ_S_W:
16668 case OPC_PRECEQ_W_PHL:
16669 case OPC_PRECEQ_W_PHR:
16670 case OPC_PRECEQU_PH_QBL:
16671 case OPC_PRECEQU_PH_QBR:
16672 case OPC_PRECEQU_PH_QBLA:
16673 case OPC_PRECEQU_PH_QBRA:
16674 case OPC_PRECEU_PH_QBL:
16675 case OPC_PRECEU_PH_QBR:
16676 case OPC_PRECEU_PH_QBLA:
16677 case OPC_PRECEU_PH_QBRA:
16678 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16679 break;
16680 case OPC_BITREV:
16681 case OPC_REPL_QB:
16682 case OPC_REPLV_QB:
16683 case OPC_REPL_PH:
16684 case OPC_REPLV_PH:
16685 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16686 break;
16687 default:
16688 MIPS_INVAL("MASK ABSQ_S.PH");
16689 generate_exception(ctx, EXCP_RI);
16690 break;
16691 }
16692 break;
16693 case OPC_ADDU_QB_DSP:
16694 op2 = MASK_ADDU_QB(ctx->opcode);
16695 switch (op2) {
16696 case OPC_ADDQ_PH:
16697 case OPC_ADDQ_S_PH:
16698 case OPC_ADDQ_S_W:
16699 case OPC_ADDU_QB:
16700 case OPC_ADDU_S_QB:
16701 case OPC_ADDU_PH:
16702 case OPC_ADDU_S_PH:
16703 case OPC_SUBQ_PH:
16704 case OPC_SUBQ_S_PH:
16705 case OPC_SUBQ_S_W:
16706 case OPC_SUBU_QB:
16707 case OPC_SUBU_S_QB:
16708 case OPC_SUBU_PH:
16709 case OPC_SUBU_S_PH:
16710 case OPC_ADDSC:
16711 case OPC_ADDWC:
16712 case OPC_MODSUB:
16713 case OPC_RADDU_W_QB:
16714 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16715 break;
16716 case OPC_MULEU_S_PH_QBL:
16717 case OPC_MULEU_S_PH_QBR:
16718 case OPC_MULQ_RS_PH:
16719 case OPC_MULEQ_S_W_PHL:
16720 case OPC_MULEQ_S_W_PHR:
16721 case OPC_MULQ_S_PH:
16722 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16723 break;
16724 default: /* Invalid */
16725 MIPS_INVAL("MASK ADDU.QB");
16726 generate_exception(ctx, EXCP_RI);
461c08df 16727 break;
461c08df 16728
099e5b4d
LA
16729 }
16730 break;
16731 case OPC_CMPU_EQ_QB_DSP:
16732 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16733 switch (op2) {
16734 case OPC_PRECR_SRA_PH_W:
16735 case OPC_PRECR_SRA_R_PH_W:
16736 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16737 break;
099e5b4d
LA
16738 case OPC_PRECR_QB_PH:
16739 case OPC_PRECRQ_QB_PH:
16740 case OPC_PRECRQ_PH_W:
16741 case OPC_PRECRQ_RS_PH_W:
16742 case OPC_PRECRQU_S_QB_PH:
16743 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16744 break;
099e5b4d
LA
16745 case OPC_CMPU_EQ_QB:
16746 case OPC_CMPU_LT_QB:
16747 case OPC_CMPU_LE_QB:
16748 case OPC_CMP_EQ_PH:
16749 case OPC_CMP_LT_PH:
16750 case OPC_CMP_LE_PH:
16751 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16752 break;
099e5b4d
LA
16753 case OPC_CMPGU_EQ_QB:
16754 case OPC_CMPGU_LT_QB:
16755 case OPC_CMPGU_LE_QB:
16756 case OPC_CMPGDU_EQ_QB:
16757 case OPC_CMPGDU_LT_QB:
16758 case OPC_CMPGDU_LE_QB:
16759 case OPC_PICK_QB:
16760 case OPC_PICK_PH:
16761 case OPC_PACKRL_PH:
16762 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16763 break;
16764 default: /* Invalid */
16765 MIPS_INVAL("MASK CMPU.EQ.QB");
16766 generate_exception(ctx, EXCP_RI);
16767 break;
16768 }
16769 break;
16770 case OPC_SHLL_QB_DSP:
16771 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16772 break;
16773 case OPC_DPA_W_PH_DSP:
16774 op2 = MASK_DPA_W_PH(ctx->opcode);
16775 switch (op2) {
16776 case OPC_DPAU_H_QBL:
16777 case OPC_DPAU_H_QBR:
16778 case OPC_DPSU_H_QBL:
16779 case OPC_DPSU_H_QBR:
16780 case OPC_DPA_W_PH:
16781 case OPC_DPAX_W_PH:
16782 case OPC_DPAQ_S_W_PH:
16783 case OPC_DPAQX_S_W_PH:
16784 case OPC_DPAQX_SA_W_PH:
16785 case OPC_DPS_W_PH:
16786 case OPC_DPSX_W_PH:
16787 case OPC_DPSQ_S_W_PH:
16788 case OPC_DPSQX_S_W_PH:
16789 case OPC_DPSQX_SA_W_PH:
16790 case OPC_MULSAQ_S_W_PH:
16791 case OPC_DPAQ_SA_L_W:
16792 case OPC_DPSQ_SA_L_W:
16793 case OPC_MAQ_S_W_PHL:
16794 case OPC_MAQ_S_W_PHR:
16795 case OPC_MAQ_SA_W_PHL:
16796 case OPC_MAQ_SA_W_PHR:
16797 case OPC_MULSA_W_PH:
16798 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16799 break;
16800 default: /* Invalid */
16801 MIPS_INVAL("MASK DPAW.PH");
16802 generate_exception(ctx, EXCP_RI);
16803 break;
16804 }
16805 break;
16806 case OPC_INSV_DSP:
16807 op2 = MASK_INSV(ctx->opcode);
16808 switch (op2) {
16809 case OPC_INSV:
16810 check_dsp(ctx);
16811 {
16812 TCGv t0, t1;
16813
16814 if (rt == 0) {
16815 MIPS_DEBUG("NOP");
16816 break;
16817 }
16818
16819 t0 = tcg_temp_new();
16820 t1 = tcg_temp_new();
16821
16822 gen_load_gpr(t0, rt);
16823 gen_load_gpr(t1, rs);
16824
16825 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16826
16827 tcg_temp_free(t0);
16828 tcg_temp_free(t1);
a22260ae
JL
16829 break;
16830 }
099e5b4d
LA
16831 default: /* Invalid */
16832 MIPS_INVAL("MASK INSV");
16833 generate_exception(ctx, EXCP_RI);
16834 break;
16835 }
16836 break;
16837 case OPC_APPEND_DSP:
16838 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16839 break;
16840 case OPC_EXTR_W_DSP:
16841 op2 = MASK_EXTR_W(ctx->opcode);
16842 switch (op2) {
16843 case OPC_EXTR_W:
16844 case OPC_EXTR_R_W:
16845 case OPC_EXTR_RS_W:
16846 case OPC_EXTR_S_H:
16847 case OPC_EXTRV_S_H:
16848 case OPC_EXTRV_W:
16849 case OPC_EXTRV_R_W:
16850 case OPC_EXTRV_RS_W:
16851 case OPC_EXTP:
16852 case OPC_EXTPV:
16853 case OPC_EXTPDP:
16854 case OPC_EXTPDPV:
16855 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16856 break;
16857 case OPC_RDDSP:
16858 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16859 break;
16860 case OPC_SHILO:
16861 case OPC_SHILOV:
16862 case OPC_MTHLIP:
16863 case OPC_WRDSP:
16864 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16865 break;
16866 default: /* Invalid */
16867 MIPS_INVAL("MASK EXTR.W");
16868 generate_exception(ctx, EXCP_RI);
16869 break;
16870 }
16871 break;
099e5b4d 16872#if defined(TARGET_MIPS64)
fac5a073
LA
16873 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16874 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16875 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16876 check_insn(ctx, INSN_LOONGSON2E);
16877 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 16878 break;
099e5b4d
LA
16879 case OPC_ABSQ_S_QH_DSP:
16880 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16881 switch (op2) {
16882 case OPC_PRECEQ_L_PWL:
16883 case OPC_PRECEQ_L_PWR:
16884 case OPC_PRECEQ_PW_QHL:
16885 case OPC_PRECEQ_PW_QHR:
16886 case OPC_PRECEQ_PW_QHLA:
16887 case OPC_PRECEQ_PW_QHRA:
16888 case OPC_PRECEQU_QH_OBL:
16889 case OPC_PRECEQU_QH_OBR:
16890 case OPC_PRECEQU_QH_OBLA:
16891 case OPC_PRECEQU_QH_OBRA:
16892 case OPC_PRECEU_QH_OBL:
16893 case OPC_PRECEU_QH_OBR:
16894 case OPC_PRECEU_QH_OBLA:
16895 case OPC_PRECEU_QH_OBRA:
16896 case OPC_ABSQ_S_OB:
16897 case OPC_ABSQ_S_PW:
16898 case OPC_ABSQ_S_QH:
16899 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16900 break;
16901 case OPC_REPL_OB:
16902 case OPC_REPL_PW:
16903 case OPC_REPL_QH:
16904 case OPC_REPLV_OB:
16905 case OPC_REPLV_PW:
16906 case OPC_REPLV_QH:
16907 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16908 break;
16909 default: /* Invalid */
16910 MIPS_INVAL("MASK ABSQ_S.QH");
16911 generate_exception(ctx, EXCP_RI);
16912 break;
16913 }
16914 break;
16915 case OPC_ADDU_OB_DSP:
16916 op2 = MASK_ADDU_OB(ctx->opcode);
16917 switch (op2) {
16918 case OPC_RADDU_L_OB:
16919 case OPC_SUBQ_PW:
16920 case OPC_SUBQ_S_PW:
16921 case OPC_SUBQ_QH:
16922 case OPC_SUBQ_S_QH:
16923 case OPC_SUBU_OB:
16924 case OPC_SUBU_S_OB:
16925 case OPC_SUBU_QH:
16926 case OPC_SUBU_S_QH:
16927 case OPC_SUBUH_OB:
16928 case OPC_SUBUH_R_OB:
16929 case OPC_ADDQ_PW:
16930 case OPC_ADDQ_S_PW:
16931 case OPC_ADDQ_QH:
16932 case OPC_ADDQ_S_QH:
16933 case OPC_ADDU_OB:
16934 case OPC_ADDU_S_OB:
16935 case OPC_ADDU_QH:
16936 case OPC_ADDU_S_QH:
16937 case OPC_ADDUH_OB:
16938 case OPC_ADDUH_R_OB:
16939 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 16940 break;
099e5b4d
LA
16941 case OPC_MULEQ_S_PW_QHL:
16942 case OPC_MULEQ_S_PW_QHR:
16943 case OPC_MULEU_S_QH_OBL:
16944 case OPC_MULEU_S_QH_OBR:
16945 case OPC_MULQ_RS_QH:
16946 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16947 break;
099e5b4d
LA
16948 default: /* Invalid */
16949 MIPS_INVAL("MASK ADDU.OB");
16950 generate_exception(ctx, EXCP_RI);
26690560 16951 break;
099e5b4d
LA
16952 }
16953 break;
16954 case OPC_CMPU_EQ_OB_DSP:
16955 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
16956 switch (op2) {
16957 case OPC_PRECR_SRA_QH_PW:
16958 case OPC_PRECR_SRA_R_QH_PW:
16959 /* Return value is rt. */
16960 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 16961 break;
099e5b4d
LA
16962 case OPC_PRECR_OB_QH:
16963 case OPC_PRECRQ_OB_QH:
16964 case OPC_PRECRQ_PW_L:
16965 case OPC_PRECRQ_QH_PW:
16966 case OPC_PRECRQ_RS_QH_PW:
16967 case OPC_PRECRQU_S_OB_QH:
16968 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 16969 break;
099e5b4d
LA
16970 case OPC_CMPU_EQ_OB:
16971 case OPC_CMPU_LT_OB:
16972 case OPC_CMPU_LE_OB:
16973 case OPC_CMP_EQ_QH:
16974 case OPC_CMP_LT_QH:
16975 case OPC_CMP_LE_QH:
16976 case OPC_CMP_EQ_PW:
16977 case OPC_CMP_LT_PW:
16978 case OPC_CMP_LE_PW:
16979 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 16980 break;
099e5b4d
LA
16981 case OPC_CMPGDU_EQ_OB:
16982 case OPC_CMPGDU_LT_OB:
16983 case OPC_CMPGDU_LE_OB:
16984 case OPC_CMPGU_EQ_OB:
16985 case OPC_CMPGU_LT_OB:
16986 case OPC_CMPGU_LE_OB:
16987 case OPC_PACKRL_PW:
16988 case OPC_PICK_OB:
16989 case OPC_PICK_PW:
16990 case OPC_PICK_QH:
16991 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 16992 break;
099e5b4d
LA
16993 default: /* Invalid */
16994 MIPS_INVAL("MASK CMPU_EQ.OB");
16995 generate_exception(ctx, EXCP_RI);
161f85e6 16996 break;
099e5b4d
LA
16997 }
16998 break;
16999 case OPC_DAPPEND_DSP:
17000 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17001 break;
17002 case OPC_DEXTR_W_DSP:
17003 op2 = MASK_DEXTR_W(ctx->opcode);
17004 switch (op2) {
17005 case OPC_DEXTP:
17006 case OPC_DEXTPDP:
17007 case OPC_DEXTPDPV:
17008 case OPC_DEXTPV:
17009 case OPC_DEXTR_L:
17010 case OPC_DEXTR_R_L:
17011 case OPC_DEXTR_RS_L:
17012 case OPC_DEXTR_W:
17013 case OPC_DEXTR_R_W:
17014 case OPC_DEXTR_RS_W:
17015 case OPC_DEXTR_S_H:
17016 case OPC_DEXTRV_L:
17017 case OPC_DEXTRV_R_L:
17018 case OPC_DEXTRV_RS_L:
17019 case OPC_DEXTRV_S_H:
17020 case OPC_DEXTRV_W:
17021 case OPC_DEXTRV_R_W:
17022 case OPC_DEXTRV_RS_W:
17023 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17024 break;
099e5b4d
LA
17025 case OPC_DMTHLIP:
17026 case OPC_DSHILO:
17027 case OPC_DSHILOV:
17028 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17029 break;
099e5b4d
LA
17030 default: /* Invalid */
17031 MIPS_INVAL("MASK EXTR.W");
17032 generate_exception(ctx, EXCP_RI);
461c08df 17033 break;
099e5b4d
LA
17034 }
17035 break;
17036 case OPC_DPAQ_W_QH_DSP:
17037 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17038 switch (op2) {
17039 case OPC_DPAU_H_OBL:
17040 case OPC_DPAU_H_OBR:
17041 case OPC_DPSU_H_OBL:
17042 case OPC_DPSU_H_OBR:
17043 case OPC_DPA_W_QH:
17044 case OPC_DPAQ_S_W_QH:
17045 case OPC_DPS_W_QH:
17046 case OPC_DPSQ_S_W_QH:
17047 case OPC_MULSAQ_S_W_QH:
17048 case OPC_DPAQ_SA_L_PW:
17049 case OPC_DPSQ_SA_L_PW:
17050 case OPC_MULSAQ_S_L_PW:
17051 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17052 break;
17053 case OPC_MAQ_S_W_QHLL:
17054 case OPC_MAQ_S_W_QHLR:
17055 case OPC_MAQ_S_W_QHRL:
17056 case OPC_MAQ_S_W_QHRR:
17057 case OPC_MAQ_SA_W_QHLL:
17058 case OPC_MAQ_SA_W_QHLR:
17059 case OPC_MAQ_SA_W_QHRL:
17060 case OPC_MAQ_SA_W_QHRR:
17061 case OPC_MAQ_S_L_PWL:
17062 case OPC_MAQ_S_L_PWR:
17063 case OPC_DMADD:
17064 case OPC_DMADDU:
17065 case OPC_DMSUB:
17066 case OPC_DMSUBU:
17067 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17068 break;
099e5b4d
LA
17069 default: /* Invalid */
17070 MIPS_INVAL("MASK DPAQ.W.QH");
17071 generate_exception(ctx, EXCP_RI);
b53371ed 17072 break;
099e5b4d
LA
17073 }
17074 break;
17075 case OPC_DINSV_DSP:
17076 op2 = MASK_INSV(ctx->opcode);
17077 switch (op2) {
17078 case OPC_DINSV:
17079 {
17080 TCGv t0, t1;
17081
17082 if (rt == 0) {
17083 MIPS_DEBUG("NOP");
a22260ae
JL
17084 break;
17085 }
099e5b4d 17086 check_dsp(ctx);
1cb6686c 17087
099e5b4d
LA
17088 t0 = tcg_temp_new();
17089 t1 = tcg_temp_new();
1cb6686c 17090
099e5b4d
LA
17091 gen_load_gpr(t0, rt);
17092 gen_load_gpr(t1, rs);
1cb6686c 17093
099e5b4d 17094 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17095
099e5b4d
LA
17096 tcg_temp_free(t0);
17097 tcg_temp_free(t1);
77c5fa8b 17098 break;
099e5b4d 17099 }
7a387fff 17100 default: /* Invalid */
099e5b4d 17101 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17102 generate_exception(ctx, EXCP_RI);
17103 break;
17104 }
17105 break;
099e5b4d
LA
17106 case OPC_SHLL_OB_DSP:
17107 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17108 break;
17109#endif
fac5a073
LA
17110 default: /* Invalid */
17111 MIPS_INVAL("special3_legacy");
17112 generate_exception(ctx, EXCP_RI);
17113 break;
17114 }
17115}
17116
17117static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17118{
17119 int rs, rt, rd, sa;
17120 uint32_t op1, op2;
17121
17122 rs = (ctx->opcode >> 21) & 0x1f;
17123 rt = (ctx->opcode >> 16) & 0x1f;
17124 rd = (ctx->opcode >> 11) & 0x1f;
17125 sa = (ctx->opcode >> 6) & 0x1f;
17126
17127 op1 = MASK_SPECIAL3(ctx->opcode);
17128 switch (op1) {
17129 case OPC_EXT:
17130 case OPC_INS:
17131 check_insn(ctx, ISA_MIPS32R2);
17132 gen_bitops(ctx, op1, rt, rs, sa, rd);
17133 break;
17134 case OPC_BSHFL:
fac5a073 17135 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17136 switch (op2) {
17137 case OPC_ALIGN ... OPC_ALIGN_END:
17138 case OPC_BITSWAP:
17139 check_insn(ctx, ISA_MIPS32R6);
17140 decode_opc_special3_r6(env, ctx);
17141 break;
17142 default:
17143 check_insn(ctx, ISA_MIPS32R2);
17144 gen_bshfl(ctx, op2, rt, rd);
17145 break;
17146 }
fac5a073
LA
17147 break;
17148#if defined(TARGET_MIPS64)
17149 case OPC_DEXTM ... OPC_DEXT:
17150 case OPC_DINSM ... OPC_DINS:
17151 check_insn(ctx, ISA_MIPS64R2);
17152 check_mips_64(ctx);
17153 gen_bitops(ctx, op1, rt, rs, sa, rd);
17154 break;
17155 case OPC_DBSHFL:
fac5a073 17156 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17157 switch (op2) {
17158 case OPC_DALIGN ... OPC_DALIGN_END:
17159 case OPC_DBITSWAP:
17160 check_insn(ctx, ISA_MIPS32R6);
17161 decode_opc_special3_r6(env, ctx);
17162 break;
17163 default:
17164 check_insn(ctx, ISA_MIPS64R2);
17165 check_mips_64(ctx);
17166 op2 = MASK_DBSHFL(ctx->opcode);
17167 gen_bshfl(ctx, op2, rt, rd);
17168 break;
17169 }
fac5a073
LA
17170 break;
17171#endif
17172 case OPC_RDHWR:
17173 gen_rdhwr(ctx, rt, rd);
17174 break;
17175 case OPC_FORK:
17176 check_insn(ctx, ASE_MT);
17177 {
17178 TCGv t0 = tcg_temp_new();
17179 TCGv t1 = tcg_temp_new();
17180
17181 gen_load_gpr(t0, rt);
17182 gen_load_gpr(t1, rs);
17183 gen_helper_fork(t0, t1);
17184 tcg_temp_free(t0);
17185 tcg_temp_free(t1);
17186 }
17187 break;
17188 case OPC_YIELD:
17189 check_insn(ctx, ASE_MT);
17190 {
17191 TCGv t0 = tcg_temp_new();
17192
17193 save_cpu_state(ctx, 1);
17194 gen_load_gpr(t0, rs);
17195 gen_helper_yield(t0, cpu_env, t0);
17196 gen_store_gpr(t0, rd);
17197 tcg_temp_free(t0);
17198 }
17199 break;
10dc65db
LA
17200 default:
17201 if (ctx->insn_flags & ISA_MIPS32R6) {
17202 decode_opc_special3_r6(env, ctx);
17203 } else {
17204 decode_opc_special3_legacy(env, ctx);
17205 }
099e5b4d
LA
17206 }
17207}
17208
17209static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
17210{
17211 int32_t offset;
17212 int rs, rt, rd, sa;
17213 uint32_t op, op1;
17214 int16_t imm;
17215
17216 /* make sure instructions are on a word boundary */
17217 if (ctx->pc & 0x3) {
17218 env->CP0_BadVAddr = ctx->pc;
aea14095 17219 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
17220 return;
17221 }
17222
17223 /* Handle blikely not taken case */
17224 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
17225 int l1 = gen_new_label();
17226
17227 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
17228 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
17229 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
17230 gen_goto_tb(ctx, 1, ctx->pc + 4);
17231 gen_set_label(l1);
17232 }
17233
17234 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
17235 tcg_gen_debug_insn_start(ctx->pc);
17236 }
17237
17238 op = MASK_OP_MAJOR(ctx->opcode);
17239 rs = (ctx->opcode >> 21) & 0x1f;
17240 rt = (ctx->opcode >> 16) & 0x1f;
17241 rd = (ctx->opcode >> 11) & 0x1f;
17242 sa = (ctx->opcode >> 6) & 0x1f;
17243 imm = (int16_t)ctx->opcode;
17244 switch (op) {
17245 case OPC_SPECIAL:
17246 decode_opc_special(env, ctx);
17247 break;
17248 case OPC_SPECIAL2:
4267d3e6 17249 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
17250 break;
17251 case OPC_SPECIAL3:
17252 decode_opc_special3(env, ctx);
17253 break;
7a387fff
TS
17254 case OPC_REGIMM:
17255 op1 = MASK_REGIMM(ctx->opcode);
17256 switch (op1) {
fecd2646
LA
17257 case OPC_BLTZL: /* REGIMM branches */
17258 case OPC_BGEZL:
17259 case OPC_BLTZALL:
17260 case OPC_BGEZALL:
17261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17262 case OPC_BLTZ:
17263 case OPC_BGEZ:
b231c103 17264 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 17265 break;
fecd2646
LA
17266 case OPC_BLTZAL:
17267 case OPC_BGEZAL:
0aefa333
YK
17268 if (ctx->insn_flags & ISA_MIPS32R6) {
17269 if (rs == 0) {
17270 /* OPC_NAL, OPC_BAL */
b231c103 17271 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
17272 } else {
17273 generate_exception(ctx, EXCP_RI);
17274 }
17275 } else {
b231c103 17276 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 17277 }
c9602061 17278 break;
7a387fff
TS
17279 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
17280 case OPC_TNEI:
fecd2646 17281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
17282 gen_trap(ctx, op1, rs, -1, imm);
17283 break;
17284 case OPC_SYNCI:
d75c135e 17285 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
17286 /* Break the TB to be able to sync copied instructions
17287 immediately */
17288 ctx->bstate = BS_STOP;
6af0bf9c 17289 break;
e45a93e2
JL
17290 case OPC_BPOSGE32: /* MIPS DSP branch */
17291#if defined(TARGET_MIPS64)
17292 case OPC_BPOSGE64:
17293#endif
17294 check_dsp(ctx);
b231c103 17295 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 17296 break;
d4ea6acd
LA
17297#if defined(TARGET_MIPS64)
17298 case OPC_DAHI:
17299 check_insn(ctx, ISA_MIPS32R6);
17300 check_mips_64(ctx);
17301 if (rs != 0) {
17302 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
17303 }
17304 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
17305 break;
17306 case OPC_DATI:
17307 check_insn(ctx, ISA_MIPS32R6);
17308 check_mips_64(ctx);
17309 if (rs != 0) {
17310 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
17311 }
17312 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
17313 break;
17314#endif
6af0bf9c 17315 default: /* Invalid */
923617a3 17316 MIPS_INVAL("regimm");
6af0bf9c
FB
17317 generate_exception(ctx, EXCP_RI);
17318 break;
17319 }
17320 break;
7a387fff 17321 case OPC_CP0:
387a8fe5 17322 check_cp0_enabled(ctx);
7a387fff 17323 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 17324 switch (op1) {
7a387fff
TS
17325 case OPC_MFC0:
17326 case OPC_MTC0:
ead9360e
TS
17327 case OPC_MFTR:
17328 case OPC_MTTR:
d26bc211 17329#if defined(TARGET_MIPS64)
7a387fff
TS
17330 case OPC_DMFC0:
17331 case OPC_DMTC0:
17332#endif
f1aa6320 17333#ifndef CONFIG_USER_ONLY
932e71cd 17334 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 17335#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
17336 break;
17337 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 17338#ifndef CONFIG_USER_ONLY
932e71cd 17339 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 17340#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
17341 break;
17342 case OPC_MFMC0:
8706c382 17343#ifndef CONFIG_USER_ONLY
932e71cd 17344 {
099e5b4d 17345 uint32_t op2;
35fbce2c 17346 TCGv t0 = tcg_temp_new();
6c5c1e20 17347
0eaef5aa 17348 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
17349 switch (op2) {
17350 case OPC_DMT:
d75c135e 17351 check_insn(ctx, ASE_MT);
9ed5726c 17352 gen_helper_dmt(t0);
35fbce2c 17353 gen_store_gpr(t0, rt);
6c5c1e20
TS
17354 break;
17355 case OPC_EMT:
d75c135e 17356 check_insn(ctx, ASE_MT);
9ed5726c 17357 gen_helper_emt(t0);
35fbce2c 17358 gen_store_gpr(t0, rt);
da80682b 17359 break;
6c5c1e20 17360 case OPC_DVPE:
d75c135e 17361 check_insn(ctx, ASE_MT);
895c2d04 17362 gen_helper_dvpe(t0, cpu_env);
35fbce2c 17363 gen_store_gpr(t0, rt);
6c5c1e20
TS
17364 break;
17365 case OPC_EVPE:
d75c135e 17366 check_insn(ctx, ASE_MT);
895c2d04 17367 gen_helper_evpe(t0, cpu_env);
35fbce2c 17368 gen_store_gpr(t0, rt);
6c5c1e20
TS
17369 break;
17370 case OPC_DI:
d75c135e 17371 check_insn(ctx, ISA_MIPS32R2);
867abc7e 17372 save_cpu_state(ctx, 1);
895c2d04 17373 gen_helper_di(t0, cpu_env);
35fbce2c 17374 gen_store_gpr(t0, rt);
6c5c1e20
TS
17375 /* Stop translation as we may have switched the execution mode */
17376 ctx->bstate = BS_STOP;
17377 break;
17378 case OPC_EI:
d75c135e 17379 check_insn(ctx, ISA_MIPS32R2);
867abc7e 17380 save_cpu_state(ctx, 1);
895c2d04 17381 gen_helper_ei(t0, cpu_env);
35fbce2c 17382 gen_store_gpr(t0, rt);
6c5c1e20
TS
17383 /* Stop translation as we may have switched the execution mode */
17384 ctx->bstate = BS_STOP;
17385 break;
17386 default: /* Invalid */
17387 MIPS_INVAL("mfmc0");
17388 generate_exception(ctx, EXCP_RI);
17389 break;
17390 }
6c5c1e20 17391 tcg_temp_free(t0);
7a387fff 17392 }
0eaef5aa 17393#endif /* !CONFIG_USER_ONLY */
6af0bf9c 17394 break;
7a387fff 17395 case OPC_RDPGPR:
d75c135e 17396 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 17397 gen_load_srsgpr(rt, rd);
ead9360e 17398 break;
7a387fff 17399 case OPC_WRPGPR:
d75c135e 17400 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 17401 gen_store_srsgpr(rt, rd);
38121543 17402 break;
6af0bf9c 17403 default:
923617a3 17404 MIPS_INVAL("cp0");
7a387fff 17405 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
17406 break;
17407 }
17408 break;
31837be3
YK
17409 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17410 if (ctx->insn_flags & ISA_MIPS32R6) {
17411 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17412 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17413 } else {
17414 /* OPC_ADDI */
17415 /* Arithmetic with immediate opcode */
17416 gen_arith_imm(ctx, op, rt, rs, imm);
17417 }
17418 break;
324d9e32 17419 case OPC_ADDIU:
d75c135e 17420 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 17421 break;
324d9e32
AJ
17422 case OPC_SLTI: /* Set on less than with immediate opcode */
17423 case OPC_SLTIU:
d75c135e 17424 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
17425 break;
17426 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 17427 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
17428 case OPC_ORI:
17429 case OPC_XORI:
d75c135e 17430 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 17431 break;
7a387fff
TS
17432 case OPC_J ... OPC_JAL: /* Jump */
17433 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 17434 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 17435 break;
31837be3
YK
17436 /* Branch */
17437 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17438 if (ctx->insn_flags & ISA_MIPS32R6) {
17439 if (rt == 0) {
17440 generate_exception(ctx, EXCP_RI);
17441 break;
17442 }
17443 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17444 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17445 } else {
17446 /* OPC_BLEZL */
b231c103 17447 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17448 }
17449 break;
17450 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17451 if (ctx->insn_flags & ISA_MIPS32R6) {
17452 if (rt == 0) {
17453 generate_exception(ctx, EXCP_RI);
17454 break;
17455 }
17456 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17457 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17458 } else {
17459 /* OPC_BGTZL */
b231c103 17460 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17461 }
17462 break;
17463 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17464 if (rt == 0) {
17465 /* OPC_BLEZ */
b231c103 17466 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17467 } else {
17468 check_insn(ctx, ISA_MIPS32R6);
17469 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17470 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17471 }
17472 break;
17473 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17474 if (rt == 0) {
17475 /* OPC_BGTZ */
b231c103 17476 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17477 } else {
17478 check_insn(ctx, ISA_MIPS32R6);
17479 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17480 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17481 }
17482 break;
17483 case OPC_BEQL:
17484 case OPC_BNEL:
fecd2646 17485 check_insn_opc_removed(ctx, ISA_MIPS32R6);
31837be3
YK
17486 case OPC_BEQ:
17487 case OPC_BNE:
b231c103 17488 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 17489 break;
fecd2646
LA
17490 case OPC_LWL: /* Load and stores */
17491 case OPC_LWR:
4368b29a 17492 case OPC_LL:
fecd2646
LA
17493 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17494 case OPC_LB ... OPC_LH:
17495 case OPC_LW ... OPC_LHU:
d75c135e 17496 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 17497 break;
fecd2646 17498 case OPC_SWL:
7a387fff 17499 case OPC_SWR:
fecd2646
LA
17500 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17501 case OPC_SB ... OPC_SH:
17502 case OPC_SW:
5c13fdfd 17503 gen_st(ctx, op, rt, rs, imm);
7a387fff 17504 break;
d66c7132 17505 case OPC_SC:
4368b29a 17506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
17507 gen_st_cond(ctx, op, rt, rs, imm);
17508 break;
7a387fff 17509 case OPC_CACHE:
bf7910c6 17510 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 17511 check_cp0_enabled(ctx);
d75c135e 17512 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 17513 /* Treat as NOP. */
34ae7b51 17514 break;
7a387fff 17515 case OPC_PREF:
bf7910c6 17516 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17517 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 17518 /* Treat as NOP. */
6af0bf9c 17519 break;
4ad40f36 17520
923617a3 17521 /* Floating point (COP1). */
7a387fff
TS
17522 case OPC_LWC1:
17523 case OPC_LDC1:
17524 case OPC_SWC1:
17525 case OPC_SDC1:
5ab5c041 17526 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
17527 break;
17528
7a387fff 17529 case OPC_CP1:
5ab5c041 17530 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17531 check_cp1_enabled(ctx);
36d23958
TS
17532 op1 = MASK_CP1(ctx->opcode);
17533 switch (op1) {
3a95e3a7
TS
17534 case OPC_MFHC1:
17535 case OPC_MTHC1:
d75c135e 17536 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
17537 case OPC_MFC1:
17538 case OPC_CFC1:
17539 case OPC_MTC1:
17540 case OPC_CTC1:
e189e748
TS
17541 gen_cp1(ctx, op1, rt, rd);
17542 break;
d26bc211 17543#if defined(TARGET_MIPS64)
36d23958
TS
17544 case OPC_DMFC1:
17545 case OPC_DMTC1:
d75c135e 17546 check_insn(ctx, ISA_MIPS3);
36d23958
TS
17547 gen_cp1(ctx, op1, rt, rd);
17548 break;
e189e748 17549#endif
31837be3
YK
17550 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
17551 if (ctx->insn_flags & ISA_MIPS32R6) {
17552 /* OPC_BC1EQZ */
17553 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17554 rt, imm << 2);
17555 } else {
17556 /* OPC_BC1ANY2 */
17557 check_cop1x(ctx);
17558 check_insn(ctx, ASE_MIPS3D);
17559 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
17560 (rt >> 2) & 0x7, imm << 2);
17561 }
17562 break;
17563 case OPC_BC1NEZ:
17564 check_insn(ctx, ISA_MIPS32R6);
17565 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17566 rt, imm << 2);
17567 break;
fbcc6828 17568 case OPC_BC1ANY4:
fecd2646 17569 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b8aa4598 17570 check_cop1x(ctx);
d75c135e 17571 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
17572 /* fall through */
17573 case OPC_BC1:
fecd2646 17574 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17575 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 17576 (rt >> 2) & 0x7, imm << 2);
c9602061 17577 break;
fecd2646
LA
17578 case OPC_PS_FMT:
17579 check_insn_opc_removed(ctx, ISA_MIPS32R6);
36d23958
TS
17580 case OPC_S_FMT:
17581 case OPC_D_FMT:
bf4120ad 17582 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 17583 (imm >> 8) & 0x7);
36d23958 17584 break;
3f493883
YK
17585 case OPC_W_FMT:
17586 case OPC_L_FMT:
17587 {
17588 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
17589 if (ctx->insn_flags & ISA_MIPS32R6) {
17590 switch (r6_op) {
17591 case R6_OPC_CMP_AF_S:
17592 case R6_OPC_CMP_UN_S:
17593 case R6_OPC_CMP_EQ_S:
17594 case R6_OPC_CMP_UEQ_S:
17595 case R6_OPC_CMP_LT_S:
17596 case R6_OPC_CMP_ULT_S:
17597 case R6_OPC_CMP_LE_S:
17598 case R6_OPC_CMP_ULE_S:
17599 case R6_OPC_CMP_SAF_S:
17600 case R6_OPC_CMP_SUN_S:
17601 case R6_OPC_CMP_SEQ_S:
17602 case R6_OPC_CMP_SEUQ_S:
17603 case R6_OPC_CMP_SLT_S:
17604 case R6_OPC_CMP_SULT_S:
17605 case R6_OPC_CMP_SLE_S:
17606 case R6_OPC_CMP_SULE_S:
17607 case R6_OPC_CMP_OR_S:
17608 case R6_OPC_CMP_UNE_S:
17609 case R6_OPC_CMP_NE_S:
17610 case R6_OPC_CMP_SOR_S:
17611 case R6_OPC_CMP_SUNE_S:
17612 case R6_OPC_CMP_SNE_S:
17613 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17614 break;
17615 case R6_OPC_CMP_AF_D:
17616 case R6_OPC_CMP_UN_D:
17617 case R6_OPC_CMP_EQ_D:
17618 case R6_OPC_CMP_UEQ_D:
17619 case R6_OPC_CMP_LT_D:
17620 case R6_OPC_CMP_ULT_D:
17621 case R6_OPC_CMP_LE_D:
17622 case R6_OPC_CMP_ULE_D:
17623 case R6_OPC_CMP_SAF_D:
17624 case R6_OPC_CMP_SUN_D:
17625 case R6_OPC_CMP_SEQ_D:
17626 case R6_OPC_CMP_SEUQ_D:
17627 case R6_OPC_CMP_SLT_D:
17628 case R6_OPC_CMP_SULT_D:
17629 case R6_OPC_CMP_SLE_D:
17630 case R6_OPC_CMP_SULE_D:
17631 case R6_OPC_CMP_OR_D:
17632 case R6_OPC_CMP_UNE_D:
17633 case R6_OPC_CMP_NE_D:
17634 case R6_OPC_CMP_SOR_D:
17635 case R6_OPC_CMP_SUNE_D:
17636 case R6_OPC_CMP_SNE_D:
17637 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17638 break;
17639 default:
17640 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17641 (imm >> 8) & 0x7);
17642 break;
17643 }
17644 } else {
17645 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17646 (imm >> 8) & 0x7);
17647 }
17648 break;
17649 }
36d23958 17650 default:
923617a3 17651 MIPS_INVAL("cp1");
e397ee33 17652 generate_exception (ctx, EXCP_RI);
36d23958
TS
17653 break;
17654 }
17655 } else {
17656 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 17657 }
4ad40f36
FB
17658 break;
17659
31837be3
YK
17660 /* Compact branches [R6] and COP2 [non-R6] */
17661 case OPC_BC: /* OPC_LWC2 */
17662 case OPC_BALC: /* OPC_SWC2 */
17663 if (ctx->insn_flags & ISA_MIPS32R6) {
17664 /* OPC_BC, OPC_BALC */
17665 gen_compute_compact_branch(ctx, op, 0, 0,
17666 sextract32(ctx->opcode << 2, 0, 28));
17667 } else {
17668 /* OPC_LWC2, OPC_SWC2 */
17669 /* COP2: Not implemented. */
17670 generate_exception_err(ctx, EXCP_CpU, 2);
17671 }
17672 break;
17673 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
17674 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
17675 if (ctx->insn_flags & ISA_MIPS32R6) {
17676 if (rs != 0) {
17677 /* OPC_BEQZC, OPC_BNEZC */
17678 gen_compute_compact_branch(ctx, op, rs, 0,
17679 sextract32(ctx->opcode << 2, 0, 23));
17680 } else {
17681 /* OPC_JIC, OPC_JIALC */
17682 gen_compute_compact_branch(ctx, op, 0, rt, imm);
17683 }
17684 } else {
17685 /* OPC_LWC2, OPC_SWC2 */
17686 /* COP2: Not implemented. */
17687 generate_exception_err(ctx, EXCP_CpU, 2);
17688 }
4ad40f36 17689 break;
bd277fa1 17690 case OPC_CP2:
d75c135e 17691 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
17692 /* Note that these instructions use different fields. */
17693 gen_loongson_multimedia(ctx, sa, rd, rt);
17694 break;
4ad40f36 17695
7a387fff 17696 case OPC_CP3:
fecd2646 17697 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 17698 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17699 check_cp1_enabled(ctx);
36d23958
TS
17700 op1 = MASK_CP3(ctx->opcode);
17701 switch (op1) {
5a5012ec
TS
17702 case OPC_LWXC1:
17703 case OPC_LDXC1:
17704 case OPC_LUXC1:
17705 case OPC_SWXC1:
17706 case OPC_SDXC1:
17707 case OPC_SUXC1:
93b12ccc 17708 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 17709 break;
e0c84da7 17710 case OPC_PREFX:
ead9360e 17711 /* Treat as NOP. */
e0c84da7 17712 break;
5a5012ec
TS
17713 case OPC_ALNV_PS:
17714 case OPC_MADD_S:
17715 case OPC_MADD_D:
17716 case OPC_MADD_PS:
17717 case OPC_MSUB_S:
17718 case OPC_MSUB_D:
17719 case OPC_MSUB_PS:
17720 case OPC_NMADD_S:
17721 case OPC_NMADD_D:
17722 case OPC_NMADD_PS:
17723 case OPC_NMSUB_S:
17724 case OPC_NMSUB_D:
17725 case OPC_NMSUB_PS:
17726 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
17727 break;
36d23958 17728 default:
923617a3 17729 MIPS_INVAL("cp3");
e397ee33 17730 generate_exception (ctx, EXCP_RI);
36d23958
TS
17731 break;
17732 }
17733 } else {
e397ee33 17734 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 17735 }
4ad40f36
FB
17736 break;
17737
d26bc211 17738#if defined(TARGET_MIPS64)
7a387fff 17739 /* MIPS64 opcodes */
7a387fff 17740 case OPC_LDL ... OPC_LDR:
bf7910c6 17741 case OPC_LLD:
fecd2646
LA
17742 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17743 case OPC_LWU:
7a387fff 17744 case OPC_LD:
d75c135e 17745 check_insn(ctx, ISA_MIPS3);
5c13fdfd 17746 check_mips_64(ctx);
d75c135e 17747 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
17748 break;
17749 case OPC_SDL ... OPC_SDR:
fecd2646 17750 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 17751 case OPC_SD:
d75c135e 17752 check_insn(ctx, ISA_MIPS3);
e189e748 17753 check_mips_64(ctx);
5c13fdfd 17754 gen_st(ctx, op, rt, rs, imm);
7a387fff 17755 break;
d66c7132 17756 case OPC_SCD:
bf7910c6 17757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17758 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
17759 check_mips_64(ctx);
17760 gen_st_cond(ctx, op, rt, rs, imm);
17761 break;
31837be3
YK
17762 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17763 if (ctx->insn_flags & ISA_MIPS32R6) {
17764 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17765 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17766 } else {
17767 /* OPC_DADDI */
17768 check_insn(ctx, ISA_MIPS3);
17769 check_mips_64(ctx);
17770 gen_arith_imm(ctx, op, rt, rs, imm);
17771 }
17772 break;
324d9e32 17773 case OPC_DADDIU:
d75c135e 17774 check_insn(ctx, ISA_MIPS3);
e189e748 17775 check_mips_64(ctx);
d75c135e 17776 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 17777 break;
31837be3
YK
17778#else
17779 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
17780 if (ctx->insn_flags & ISA_MIPS32R6) {
17781 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17782 } else {
17783 MIPS_INVAL("major opcode");
17784 generate_exception(ctx, EXCP_RI);
17785 }
17786 break;
6af0bf9c 17787#endif
d4ea6acd
LA
17788 case OPC_DAUI: /* OPC_JALX */
17789 if (ctx->insn_flags & ISA_MIPS32R6) {
17790#if defined(TARGET_MIPS64)
17791 /* OPC_DAUI */
17792 check_mips_64(ctx);
17793 if (rt != 0) {
17794 TCGv t0 = tcg_temp_new();
17795 gen_load_gpr(t0, rs);
17796 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
17797 tcg_temp_free(t0);
17798 }
17799 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
17800#else
17801 generate_exception(ctx, EXCP_RI);
17802 MIPS_INVAL("major opcode");
17803#endif
17804 } else {
17805 /* OPC_JALX */
17806 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
17807 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 17808 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 17809 }
364d4831 17810 break;
7a387fff 17811 case OPC_MDMX:
d75c135e 17812 check_insn(ctx, ASE_MDMX);
7a387fff 17813 /* MDMX: Not implemented. */
d4ea6acd
LA
17814 break;
17815 case OPC_PCREL:
17816 check_insn(ctx, ISA_MIPS32R6);
17817 gen_pcrel(ctx, rs, imm);
17818 break;
6af0bf9c 17819 default: /* Invalid */
923617a3 17820 MIPS_INVAL("major opcode");
6af0bf9c
FB
17821 generate_exception(ctx, EXCP_RI);
17822 break;
17823 }
6af0bf9c
FB
17824}
17825
2cfc5f17 17826static inline void
6429db34
AF
17827gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
17828 bool search_pc)
6af0bf9c 17829{
ed2803da 17830 CPUState *cs = CPU(cpu);
6429db34 17831 CPUMIPSState *env = &cpu->env;
278d0702 17832 DisasContext ctx;
6af0bf9c
FB
17833 target_ulong pc_start;
17834 uint16_t *gen_opc_end;
a1d1bb31 17835 CPUBreakpoint *bp;
6af0bf9c 17836 int j, lj = -1;
2e70f6ef
PB
17837 int num_insns;
17838 int max_insns;
c9602061 17839 int insn_bytes;
339cd2a8 17840 int is_slot;
6af0bf9c 17841
93fcfe39
AL
17842 if (search_pc)
17843 qemu_log("search pc %d\n", search_pc);
4ad40f36 17844
6af0bf9c 17845 pc_start = tb->pc;
92414b31 17846 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 17847 ctx.pc = pc_start;
4ad40f36 17848 ctx.saved_pc = -1;
ed2803da 17849 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 17850 ctx.insn_flags = env->insn_flags;
5ab5c041 17851 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
17852 ctx.tb = tb;
17853 ctx.bstate = BS_NONE;
e98c0d17 17854 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 17855 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 17856 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
17857 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
17858 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 17859 /* Restore delay slot state from the tb context. */
c068688b 17860 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 17861 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 17862 restore_cpu_state(env, &ctx);
932e71cd 17863#ifdef CONFIG_USER_ONLY
0eaef5aa 17864 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 17865#else
0eaef5aa 17866 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 17867#endif
2e70f6ef
PB
17868 num_insns = 0;
17869 max_insns = tb->cflags & CF_COUNT_MASK;
17870 if (max_insns == 0)
17871 max_insns = CF_COUNT_MASK;
d12d51d5 17872 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 17873 gen_tb_start();
faf7aaa9 17874 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
17875 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
17876 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 17877 if (bp->pc == ctx.pc) {
278d0702 17878 save_cpu_state(&ctx, 1);
4ad40f36 17879 ctx.bstate = BS_BRANCH;
895c2d04 17880 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
17881 /* Include the breakpoint location or the tb won't
17882 * be flushed when it must be. */
17883 ctx.pc += 4;
4ad40f36
FB
17884 goto done_generating;
17885 }
17886 }
17887 }
17888
6af0bf9c 17889 if (search_pc) {
92414b31 17890 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17891 if (lj < j) {
17892 lj++;
17893 while (lj < j)
ab1103de 17894 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 17895 }
25983cad 17896 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 17897 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 17898 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 17899 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 17900 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 17901 }
2e70f6ef
PB
17902 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
17903 gen_io_start();
c9602061 17904
339cd2a8 17905 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 17906 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 17907 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 17908 insn_bytes = 4;
240ce26a 17909 decode_opc(env, &ctx);
d75c135e 17910 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 17911 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17912 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 17913 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 17914 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17915 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
17916 } else {
17917 generate_exception(&ctx, EXCP_RI);
3c824109 17918 ctx.bstate = BS_STOP;
c9602061
NF
17919 break;
17920 }
31837be3 17921
b231c103 17922 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
17923 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
17924 MIPS_HFLAG_FBNSLOT))) {
17925 /* force to generate branch as there is neither delay nor
17926 forbidden slot */
17927 is_slot = 1;
b231c103
YK
17928 }
17929 }
339cd2a8 17930 if (is_slot) {
31837be3 17931 gen_branch(&ctx, insn_bytes);
c9602061
NF
17932 }
17933 ctx.pc += insn_bytes;
17934
2e70f6ef 17935 num_insns++;
4ad40f36 17936
7b270ef2
NF
17937 /* Execute a branch and its delay slot as a single instruction.
17938 This is what GDB expects and is consistent with what the
17939 hardware does (e.g. if a delay slot instruction faults, the
17940 reported PC is the PC of the branch). */
ed2803da 17941 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 17942 break;
ed2803da 17943 }
4ad40f36 17944
6af0bf9c
FB
17945 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
17946 break;
4ad40f36 17947
efd7f486 17948 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 17949 break;
efd7f486 17950 }
faf7aaa9 17951
2e70f6ef
PB
17952 if (num_insns >= max_insns)
17953 break;
1b530a6d
AJ
17954
17955 if (singlestep)
17956 break;
6af0bf9c 17957 }
ed2803da 17958 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 17959 gen_io_end();
ed2803da
AF
17960 }
17961 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 17962 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 17963 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 17964 } else {
6958549d 17965 switch (ctx.bstate) {
16c00cb2 17966 case BS_STOP:
df1561e2
TS
17967 gen_goto_tb(&ctx, 0, ctx.pc);
17968 break;
16c00cb2 17969 case BS_NONE:
278d0702 17970 save_cpu_state(&ctx, 0);
16c00cb2
TS
17971 gen_goto_tb(&ctx, 0, ctx.pc);
17972 break;
5a5012ec 17973 case BS_EXCP:
57fec1fe 17974 tcg_gen_exit_tb(0);
16c00cb2 17975 break;
5a5012ec
TS
17976 case BS_BRANCH:
17977 default:
17978 break;
6958549d 17979 }
6af0bf9c 17980 }
4ad40f36 17981done_generating:
806f352d 17982 gen_tb_end(tb, num_insns);
efd7f486 17983 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 17984 if (search_pc) {
92414b31 17985 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17986 lj++;
17987 while (lj <= j)
ab1103de 17988 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
17989 } else {
17990 tb->size = ctx.pc - pc_start;
2e70f6ef 17991 tb->icount = num_insns;
6af0bf9c
FB
17992 }
17993#ifdef DEBUG_DISAS
d12d51d5 17994 LOG_DISAS("\n");
8fec2b8c 17995 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 17996 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 17997 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 17998 qemu_log("\n");
6af0bf9c
FB
17999 }
18000#endif
6af0bf9c
FB
18001}
18002
7db13fae 18003void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 18004{
6429db34 18005 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
18006}
18007
7db13fae 18008void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 18009{
6429db34 18010 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
18011}
18012
7db13fae 18013static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 18014 int flags)
6ea83fed
FB
18015{
18016 int i;
5e755519 18017 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 18018
2a5612e6
SW
18019#define printfpr(fp) \
18020 do { \
18021 if (is_fpu64) \
18022 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18023 " fd:%13g fs:%13g psu: %13g\n", \
18024 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
18025 (double)(fp)->fd, \
18026 (double)(fp)->fs[FP_ENDIAN_IDX], \
18027 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
18028 else { \
18029 fpr_t tmp; \
18030 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
18031 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
18032 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18033 " fd:%13g fs:%13g psu:%13g\n", \
18034 tmp.w[FP_ENDIAN_IDX], tmp.d, \
18035 (double)tmp.fd, \
18036 (double)tmp.fs[FP_ENDIAN_IDX], \
18037 (double)tmp.fs[!FP_ENDIAN_IDX]); \
18038 } \
6ea83fed
FB
18039 } while(0)
18040
5a5012ec 18041
9a78eead
SW
18042 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
18043 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 18044 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
18045 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
18046 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 18047 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
18048 }
18049
18050#undef printfpr
18051}
18052
d26bc211 18053#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 18054/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 18055 sign-extended values on 64bit machines. */
c570fd16
TS
18056
18057#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
18058
8706c382 18059static void
7db13fae 18060cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 18061 fprintf_function cpu_fprintf,
8706c382 18062 int flags)
c570fd16
TS
18063{
18064 int i;
18065
b5dc7732
TS
18066 if (!SIGN_EXT_P(env->active_tc.PC))
18067 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
18068 if (!SIGN_EXT_P(env->active_tc.HI[0]))
18069 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
18070 if (!SIGN_EXT_P(env->active_tc.LO[0]))
18071 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 18072 if (!SIGN_EXT_P(env->btarget))
3594c774 18073 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
18074
18075 for (i = 0; i < 32; i++) {
b5dc7732
TS
18076 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
18077 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
18078 }
18079
18080 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 18081 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
18082 if (!SIGN_EXT_P(env->lladdr))
18083 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
18084}
18085#endif
18086
878096ee
AF
18087void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
18088 int flags)
6af0bf9c 18089{
878096ee
AF
18090 MIPSCPU *cpu = MIPS_CPU(cs);
18091 CPUMIPSState *env = &cpu->env;
6af0bf9c 18092 int i;
3b46e624 18093
a7200c9f
SW
18094 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
18095 " LO=0x" TARGET_FMT_lx " ds %04x "
18096 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
18097 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
18098 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
18099 for (i = 0; i < 32; i++) {
18100 if ((i & 3) == 0)
18101 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 18102 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
18103 if ((i & 3) == 3)
18104 cpu_fprintf(f, "\n");
18105 }
568b600d 18106
3594c774 18107 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 18108 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 18109 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 18110 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 18111 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 18112 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 18113#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
18114 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
18115#endif
6af0bf9c
FB
18116}
18117
78ce64f4 18118void mips_tcg_init(void)
39454628 18119{
f01be154 18120 int i;
39454628
TS
18121 static int inited;
18122
18123 /* Initialize various static tables. */
18124 if (inited)
6958549d 18125 return;
39454628 18126
a7812ae4 18127 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 18128 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 18129 for (i = 1; i < 32; i++)
a7812ae4 18130 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 18131 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 18132 regnames[i]);
d73ee8a2
RH
18133
18134 for (i = 0; i < 32; i++) {
18135 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
18136 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
18137 }
18138
a7812ae4 18139 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 18140 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 18141 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 18142 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 18143 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 18144 regnames_HI[i]);
a7812ae4 18145 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 18146 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 18147 regnames_LO[i]);
4b2eb8d2 18148 }
a7812ae4 18149 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 18150 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 18151 "DSPControl");
1ba74fb8 18152 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 18153 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 18154 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 18155 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 18156 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 18157 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 18158
a7812ae4 18159 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 18160 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
18161 "fcr0");
18162 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 18163 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 18164 "fcr31");
39454628
TS
18165
18166 inited = 1;
18167}
18168
aaed909a
FB
18169#include "translate_init.c"
18170
30bf942d 18171MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 18172{
0f71a709 18173 MIPSCPU *cpu;
6af0bf9c 18174 CPUMIPSState *env;
c227f099 18175 const mips_def_t *def;
6af0bf9c 18176
aaed909a
FB
18177 def = cpu_mips_find_by_name(cpu_model);
18178 if (!def)
18179 return NULL;
0f71a709
AF
18180 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
18181 env = &cpu->env;
aaed909a
FB
18182 env->cpu_model = def;
18183
51cc2e78
BS
18184#ifndef CONFIG_USER_ONLY
18185 mmu_init(env, def);
18186#endif
18187 fpu_init(env, def);
18188 mvp_init(env, def);
c1caf1d9
AF
18189
18190 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
18191
30bf942d 18192 return cpu;
6ae81775
TS
18193}
18194
1bba0dc9 18195void cpu_state_reset(CPUMIPSState *env)
6ae81775 18196{
55e5c285
AF
18197 MIPSCPU *cpu = mips_env_get_cpu(env);
18198 CPUState *cs = CPU(cpu);
6ae81775 18199
51cc2e78
BS
18200 /* Reset registers to their default values */
18201 env->CP0_PRid = env->cpu_model->CP0_PRid;
18202 env->CP0_Config0 = env->cpu_model->CP0_Config0;
18203#ifdef TARGET_WORDS_BIGENDIAN
18204 env->CP0_Config0 |= (1 << CP0C0_BE);
18205#endif
18206 env->CP0_Config1 = env->cpu_model->CP0_Config1;
18207 env->CP0_Config2 = env->cpu_model->CP0_Config2;
18208 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
18209 env->CP0_Config4 = env->cpu_model->CP0_Config4;
18210 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
18211 env->CP0_Config5 = env->cpu_model->CP0_Config5;
18212 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
18213 env->CP0_Config6 = env->cpu_model->CP0_Config6;
18214 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
18215 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
18216 << env->cpu_model->CP0_LLAddr_shift;
18217 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
18218 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
18219 env->CCRes = env->cpu_model->CCRes;
18220 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
18221 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
18222 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
18223 env->current_tc = 0;
18224 env->SEGBITS = env->cpu_model->SEGBITS;
18225 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
18226#if defined(TARGET_MIPS64)
18227 if (env->cpu_model->insn_flags & ISA_MIPS3) {
18228 env->SEGMask |= 3ULL << 62;
18229 }
18230#endif
18231 env->PABITS = env->cpu_model->PABITS;
18232 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
18233 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
18234 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
18235 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
18236 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
18237 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
18238 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
18239 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
18240 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
18241 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
18242 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
18243 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
18244 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 18245 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
18246 env->insn_flags = env->cpu_model->insn_flags;
18247
0eaef5aa 18248#if defined(CONFIG_USER_ONLY)
03e6e501 18249 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
18250# ifdef TARGET_MIPS64
18251 /* Enable 64-bit register mode. */
18252 env->CP0_Status |= (1 << CP0St_PX);
18253# endif
18254# ifdef TARGET_ABI_MIPSN64
18255 /* Enable 64-bit address mode. */
18256 env->CP0_Status |= (1 << CP0St_UX);
18257# endif
94159135
MI
18258 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
18259 hardware registers. */
18260 env->CP0_HWREna |= 0x0000000F;
91a75935 18261 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 18262 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 18263 }
6f0af304
PJ
18264 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
18265 env->CP0_Status |= (1 << CP0St_MX);
853c3240 18266 }
4d66261f
PJ
18267# if defined(TARGET_MIPS64)
18268 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
18269 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
18270 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
18271 env->CP0_Status |= (1 << CP0St_FR);
18272 }
4d66261f 18273# endif
932e71cd
AJ
18274#else
18275 if (env->hflags & MIPS_HFLAG_BMASK) {
18276 /* If the exception was raised from a delay slot,
18277 come back to the jump. */
18278 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 18279 } else {
932e71cd
AJ
18280 env->CP0_ErrorEPC = env->active_tc.PC;
18281 }
18282 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
18283 env->CP0_Random = env->tlb->nb_tlb - 1;
18284 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 18285 env->CP0_Wired = 0;
0a2672b7
JH
18286 env->CP0_EBase = (cs->cpu_index & 0x3FF);
18287 if (kvm_enabled()) {
18288 env->CP0_EBase |= 0x40000000;
18289 } else {
18290 env->CP0_EBase |= 0x80000000;
18291 }
932e71cd
AJ
18292 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
18293 /* vectored interrupts not implemented, timer on int 7,
18294 no performance counters. */
18295 env->CP0_IntCtl = 0xe0000000;
18296 {
18297 int i;
18298
18299 for (i = 0; i < 7; i++) {
18300 env->CP0_WatchLo[i] = 0;
18301 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 18302 }
932e71cd
AJ
18303 env->CP0_WatchLo[7] = 0;
18304 env->CP0_WatchHi[7] = 0;
fd88b6ab 18305 }
932e71cd
AJ
18306 /* Count register increments in debug mode, EJTAG version 1 */
18307 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 18308
4b69c7e2
JH
18309 cpu_mips_store_count(env, 1);
18310
9e56e756
EI
18311 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
18312 int i;
18313
18314 /* Only TC0 on VPE 0 starts as active. */
18315 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 18316 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
18317 env->tcs[i].CP0_TCHalt = 1;
18318 }
18319 env->active_tc.CP0_TCHalt = 1;
259186a7 18320 cs->halted = 1;
9e56e756 18321
55e5c285 18322 if (cs->cpu_index == 0) {
9e56e756
EI
18323 /* VPE0 starts up enabled. */
18324 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
18325 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
18326
18327 /* TC0 starts up unhalted. */
259186a7 18328 cs->halted = 0;
9e56e756
EI
18329 env->active_tc.CP0_TCHalt = 0;
18330 env->tcs[0].CP0_TCHalt = 0;
18331 /* With thread 0 active. */
18332 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
18333 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
18334 }
18335 }
51cc2e78 18336#endif
ddc584bd
LA
18337 if ((env->insn_flags & ISA_MIPS32R6) &&
18338 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
18339 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
18340 env->CP0_Status |= (1 << CP0St_FR);
18341 }
18342
03e6e501 18343 compute_hflags(env);
27103424 18344 cs->exception_index = EXCP_NONE;
6af0bf9c 18345}
d2856f1a 18346
7db13fae 18347void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 18348{
25983cad 18349 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
18350 env->hflags &= ~MIPS_HFLAG_BMASK;
18351 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
18352 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
18353 case MIPS_HFLAG_BR:
18354 break;
18355 case MIPS_HFLAG_BC:
18356 case MIPS_HFLAG_BL:
18357 case MIPS_HFLAG_B:
18358 env->btarget = gen_opc_btarget[pc_pos];
18359 break;
18360 }
d2856f1a 18361}