]> Git Repo - qemu.git/blame - target-mips/translate.c
target-mips: correct MFC0 for CP0.EntryLo in MIPS64
[qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
a7812ae4 32
a7e30d84
LV
33#include "trace-tcg.h"
34
35
fb7729e2 36#define MIPS_DEBUG_DISAS 0
c570fd16 37//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 38
7a387fff
TS
39/* MIPS major opcodes */
40#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
41
42enum {
43 /* indirect opcode tables */
7a387fff
TS
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 52 /* arithmetic with immediate */
7a387fff
TS
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
324d9e32 57 /* logic with immediate */
7a387fff
TS
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
324d9e32 62 /* arithmetic with immediate */
7a387fff
TS
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
e37e863f 65 /* Jump and branches */
7a387fff
TS
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
68 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL = (0x14 << 26),
70 OPC_BNE = (0x05 << 26),
71 OPC_BNEL = (0x15 << 26),
72 OPC_BLEZ = (0x06 << 26),
73 OPC_BLEZL = (0x16 << 26),
74 OPC_BGTZ = (0x07 << 26),
75 OPC_BGTZL = (0x17 << 26),
b231c103 76 OPC_JALX = (0x1D << 26),
d4ea6acd 77 OPC_DAUI = (0x1D << 26),
e37e863f 78 /* Load and stores */
7a387fff
TS
79 OPC_LDL = (0x1A << 26),
80 OPC_LDR = (0x1B << 26),
81 OPC_LB = (0x20 << 26),
82 OPC_LH = (0x21 << 26),
83 OPC_LWL = (0x22 << 26),
84 OPC_LW = (0x23 << 26),
364d4831 85 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
86 OPC_LBU = (0x24 << 26),
87 OPC_LHU = (0x25 << 26),
88 OPC_LWR = (0x26 << 26),
89 OPC_LWU = (0x27 << 26),
90 OPC_SB = (0x28 << 26),
91 OPC_SH = (0x29 << 26),
92 OPC_SWL = (0x2A << 26),
93 OPC_SW = (0x2B << 26),
94 OPC_SDL = (0x2C << 26),
95 OPC_SDR = (0x2D << 26),
96 OPC_SWR = (0x2E << 26),
97 OPC_LL = (0x30 << 26),
98 OPC_LLD = (0x34 << 26),
99 OPC_LD = (0x37 << 26),
364d4831 100 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
101 OPC_SC = (0x38 << 26),
102 OPC_SCD = (0x3C << 26),
103 OPC_SD = (0x3F << 26),
e37e863f 104 /* Floating point load/store */
7a387fff
TS
105 OPC_LWC1 = (0x31 << 26),
106 OPC_LWC2 = (0x32 << 26),
107 OPC_LDC1 = (0x35 << 26),
108 OPC_LDC2 = (0x36 << 26),
109 OPC_SWC1 = (0x39 << 26),
110 OPC_SWC2 = (0x3A << 26),
111 OPC_SDC1 = (0x3D << 26),
112 OPC_SDC2 = (0x3E << 26),
31837be3
YK
113 /* Compact Branches */
114 OPC_BLEZALC = (0x06 << 26),
115 OPC_BGEZALC = (0x06 << 26),
116 OPC_BGEUC = (0x06 << 26),
117 OPC_BGTZALC = (0x07 << 26),
118 OPC_BLTZALC = (0x07 << 26),
119 OPC_BLTUC = (0x07 << 26),
120 OPC_BOVC = (0x08 << 26),
121 OPC_BEQZALC = (0x08 << 26),
122 OPC_BEQC = (0x08 << 26),
123 OPC_BLEZC = (0x16 << 26),
124 OPC_BGEZC = (0x16 << 26),
125 OPC_BGEC = (0x16 << 26),
126 OPC_BGTZC = (0x17 << 26),
127 OPC_BLTZC = (0x17 << 26),
128 OPC_BLTC = (0x17 << 26),
129 OPC_BNVC = (0x18 << 26),
130 OPC_BNEZALC = (0x18 << 26),
131 OPC_BNEC = (0x18 << 26),
132 OPC_BC = (0x32 << 26),
133 OPC_BEQZC = (0x36 << 26),
134 OPC_JIC = (0x36 << 26),
135 OPC_BALC = (0x3A << 26),
136 OPC_BNEZC = (0x3E << 26),
137 OPC_JIALC = (0x3E << 26),
7a387fff
TS
138 /* MDMX ASE specific */
139 OPC_MDMX = (0x1E << 26),
239dfebe
YK
140 /* MSA ASE, same as MDMX */
141 OPC_MSA = OPC_MDMX,
e37e863f 142 /* Cache and prefetch */
7a387fff
TS
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
147};
148
149/* PC-relative address computation / loads */
150#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152enum {
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
157
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
161
162 /* Other */
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
164};
165
166/* MIPS special opcodes */
7a387fff
TS
167#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
168
e37e863f
FB
169enum {
170 /* Shifts */
7a387fff 171 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 176 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 180 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 188 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 194 /* Multiplication / division */
7a387fff
TS
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 203
e37e863f 204 /* 2 registers arithmetic / logic */
7a387fff
TS
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 219 /* Jumps */
7a387fff
TS
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 222 /* Traps */
7a387fff
TS
223 OPC_TGE = 0x30 | OPC_SPECIAL,
224 OPC_TGEU = 0x31 | OPC_SPECIAL,
225 OPC_TLT = 0x32 | OPC_SPECIAL,
226 OPC_TLTU = 0x33 | OPC_SPECIAL,
227 OPC_TEQ = 0x34 | OPC_SPECIAL,
228 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 229 /* HI / LO registers load & stores */
7a387fff
TS
230 OPC_MFHI = 0x10 | OPC_SPECIAL,
231 OPC_MTHI = 0x11 | OPC_SPECIAL,
232 OPC_MFLO = 0x12 | OPC_SPECIAL,
233 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 234 /* Conditional moves */
7a387fff
TS
235 OPC_MOVZ = 0x0A | OPC_SPECIAL,
236 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 237
b691d9d2
LA
238 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
239 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
240
7a387fff 241 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
242
243 /* Special */
a0d700e4 244 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
245 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
246 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 247 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
248 OPC_SYNC = 0x0F | OPC_SPECIAL,
249
7a387fff
TS
250 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
251 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
252 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
253 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
254};
255
b42ee5e1
LA
256/* R6 Multiply and Divide instructions have the same Opcode
257 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
258#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
259
260enum {
261 R6_OPC_MUL = OPC_MULT | (2 << 6),
262 R6_OPC_MUH = OPC_MULT | (3 << 6),
263 R6_OPC_MULU = OPC_MULTU | (2 << 6),
264 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
265 R6_OPC_DIV = OPC_DIV | (2 << 6),
266 R6_OPC_MOD = OPC_DIV | (3 << 6),
267 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
268 R6_OPC_MODU = OPC_DIVU | (3 << 6),
269
270 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
271 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
272 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
273 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
274 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
275 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
276 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
277 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
278
279 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
280 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
281 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
282 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
283 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
284
285 OPC_LSA = 0x05 | OPC_SPECIAL,
286 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
287};
288
e9c71dd1
TS
289/* Multiplication variants of the vr54xx. */
290#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
291
292enum {
293 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
294 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
295 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
296 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
297 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
298 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
299 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
300 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
302 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
303 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
304 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
305 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
306 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
307};
308
7a387fff
TS
309/* REGIMM (rt field) opcodes */
310#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
311
312enum {
313 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
314 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
315 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
316 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
317 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
318 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
319 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
320 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
321 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
322 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
323 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
324 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
325 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
326 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
327 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
328
329 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
330 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
331};
332
7a387fff
TS
333/* Special2 opcodes */
334#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
335
e37e863f 336enum {
7a387fff
TS
337 /* Multiply & xxx operations */
338 OPC_MADD = 0x00 | OPC_SPECIAL2,
339 OPC_MADDU = 0x01 | OPC_SPECIAL2,
340 OPC_MUL = 0x02 | OPC_SPECIAL2,
341 OPC_MSUB = 0x04 | OPC_SPECIAL2,
342 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
343 /* Loongson 2F */
344 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
345 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
346 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
347 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
348 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
349 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
350 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
351 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
352 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
353 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
354 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
355 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 356 /* Misc */
7a387fff
TS
357 OPC_CLZ = 0x20 | OPC_SPECIAL2,
358 OPC_CLO = 0x21 | OPC_SPECIAL2,
359 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
360 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 361 /* Special */
7a387fff
TS
362 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
363};
364
365/* Special3 opcodes */
366#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
367
368enum {
369 OPC_EXT = 0x00 | OPC_SPECIAL3,
370 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
371 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
372 OPC_DEXT = 0x03 | OPC_SPECIAL3,
373 OPC_INS = 0x04 | OPC_SPECIAL3,
374 OPC_DINSM = 0x05 | OPC_SPECIAL3,
375 OPC_DINSU = 0x06 | OPC_SPECIAL3,
376 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
377 OPC_FORK = 0x08 | OPC_SPECIAL3,
378 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
379 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
380 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
381 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
382
383 /* Loongson 2E */
384 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
385 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
386 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
387 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
388 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
389 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
390 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
391 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
392 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
393 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
394 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
395 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
396
397 /* MIPS DSP Load */
398 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
399 /* MIPS DSP Arithmetic */
400 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 401 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 402 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 403 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
404 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
405 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
406 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 407 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
408 /* MIPS DSP GPR-Based Shift Sub-class */
409 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 410 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
411 /* MIPS DSP Multiply Sub-class insns */
412 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
413 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
414 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 415 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
416 /* DSP Bit/Manipulation Sub-class */
417 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 418 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 419 /* MIPS DSP Append Sub-class */
26690560 420 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 421 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
422 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
423 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 424 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
425
426 /* R6 */
bf7910c6
LA
427 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
428 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
429 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
430 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
431 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
432 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
433};
434
7a387fff
TS
435/* BSHFL opcodes */
436#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
437
e37e863f 438enum {
15eacb9b
YK
439 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
440 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
441 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
442 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
443 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
444 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
445};
446
7a387fff
TS
447/* DBSHFL opcodes */
448#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
449
e37e863f 450enum {
15eacb9b
YK
451 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
452 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
453 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
454 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
455 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
456};
457
e45a93e2
JL
458/* MIPS DSP REGIMM opcodes */
459enum {
460 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 461 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
462};
463
9b1a1d68
JL
464#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
465/* MIPS DSP Load */
466enum {
467 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
468 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
469 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 470 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
471};
472
461c08df
JL
473#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
474enum {
475 /* MIPS DSP Arithmetic Sub-class */
476 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
491 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
492 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
493 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
494 /* MIPS DSP Multiply Sub-class insns */
495 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
501};
502
503#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
504#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505enum {
506 /* MIPS DSP Arithmetic Sub-class */
507 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
519 /* MIPS DSP Multiply Sub-class insns */
520 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
524};
525
526#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527enum {
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
542 /* DSP Bit/Manipulation Sub-class */
543 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
548};
549
550#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
560 /* DSP Compare-Pick Sub-class */
561 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 576};
a22260ae 577
77c5fa8b
JL
578#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
579enum {
580 /* MIPS DSP GPR-Based Shift Sub-class */
581 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
603};
461c08df 604
a22260ae
JL
605#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606enum {
607 /* MIPS DSP Multiply Sub-class insns */
608 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
622 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
630};
631
1cb6686c
JL
632#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633enum {
634 /* DSP Bit/Manipulation Sub-class */
635 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
636};
637
26690560
JL
638#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639enum {
df6126a7 640 /* MIPS DSP Append Sub-class */
26690560
JL
641 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
642 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
643 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
644};
645
b53371ed
JL
646#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
647enum {
648 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
649 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
662 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
663 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
664 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
665 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
666};
667
461c08df
JL
668#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
670 /* MIPS DSP Arithmetic Sub-class */
671 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
688 /* DSP Bit/Manipulation Sub-class */
689 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 695};
461c08df 696
461c08df
JL
697#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
698enum {
a22260ae
JL
699 /* MIPS DSP Multiply Sub-class insns */
700 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
727};
461c08df 728
461c08df
JL
729#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730enum {
26690560
JL
731 /* DSP Compare-Pick Sub-class */
732 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
751 /* MIPS DSP Arithmetic Sub-class */
752 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
760};
461c08df 761
26690560
JL
762#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763enum {
df6126a7 764 /* DSP Append Sub-class */
26690560
JL
765 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
767 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
768 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
769};
26690560 770
b53371ed
JL
771#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
772enum {
773 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
774 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
775 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
795};
796
1cb6686c
JL
797#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798enum {
799 /* DSP Bit/Manipulation Sub-class */
800 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
801};
1cb6686c 802
a22260ae
JL
803#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804enum {
805 /* MIPS DSP Multiply Sub-class insns */
806 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
832};
a22260ae 833
77c5fa8b
JL
834#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835enum {
836 /* MIPS DSP GPR-Based Shift Sub-class */
837 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
863};
77c5fa8b 864
7a387fff
TS
865/* Coprocessor 0 (rs field) */
866#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
867
6ea83fed 868enum {
7a387fff
TS
869 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
870 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 873 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
874 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
875 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 876 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
877 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
878 OPC_C0 = (0x10 << 21) | OPC_CP0,
879 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
880 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 881};
7a387fff
TS
882
883/* MFMC0 opcodes */
b48cfdff 884#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
885
886enum {
ead9360e
TS
887 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
888 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
890 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
891 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
892 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
893};
894
895/* Coprocessor 0 (with rs == C0) */
896#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
897
898enum {
899 OPC_TLBR = 0x01 | OPC_C0,
900 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
901 OPC_TLBINV = 0x03 | OPC_C0,
902 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
903 OPC_TLBWR = 0x06 | OPC_C0,
904 OPC_TLBP = 0x08 | OPC_C0,
905 OPC_RFE = 0x10 | OPC_C0,
906 OPC_ERET = 0x18 | OPC_C0,
907 OPC_DERET = 0x1F | OPC_C0,
908 OPC_WAIT = 0x20 | OPC_C0,
909};
910
911/* Coprocessor 1 (rs field) */
912#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
913
bf4120ad
NF
914/* Values for the fmt field in FP instructions */
915enum {
916 /* 0 - 15 are reserved */
e459440a
AJ
917 FMT_S = 16, /* single fp */
918 FMT_D = 17, /* double fp */
919 FMT_E = 18, /* extended fp */
920 FMT_Q = 19, /* quad fp */
921 FMT_W = 20, /* 32-bit fixed */
922 FMT_L = 21, /* 64-bit fixed */
923 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
924 /* 23 - 31 are reserved */
925};
926
7a387fff
TS
927enum {
928 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
929 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
930 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 931 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
932 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
933 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
934 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 935 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 936 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
937 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
938 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
939 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
940 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
950 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
951 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
952 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
953 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
954 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
955 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
956 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
957 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
958};
959
5a5012ec
TS
960#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
961#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
962
7a387fff
TS
963enum {
964 OPC_BC1F = (0x00 << 16) | OPC_BC1,
965 OPC_BC1T = (0x01 << 16) | OPC_BC1,
966 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
967 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
968};
969
5a5012ec
TS
970enum {
971 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
972 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
973};
974
975enum {
976 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
977 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
978};
7a387fff
TS
979
980#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
981
982enum {
983 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
984 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
985 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
986 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
987 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
988 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
989 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
990 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
991 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
992 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
993 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
994};
995
bd277fa1
RH
996#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
997
998enum {
999 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1000 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1007
1008 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1009 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1016
1017 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1018 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1021 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1022 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1023 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1024 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1025
1026 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1027 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1030 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1034
1035 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1036 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1037 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1041
1042 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1043 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1048
1049 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1050 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1055
1056 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1057 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1062
1063 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1064 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1065 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1066 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1067 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1069
1070 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1071 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1072 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1073 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1074 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1076
1077 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1078 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1079 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1081 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1083
1084 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1085 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1086 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1087 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1088 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1089 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1090};
1091
1092
e0c84da7
TS
1093#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1094
1095enum {
1096 OPC_LWXC1 = 0x00 | OPC_CP3,
1097 OPC_LDXC1 = 0x01 | OPC_CP3,
1098 OPC_LUXC1 = 0x05 | OPC_CP3,
1099 OPC_SWXC1 = 0x08 | OPC_CP3,
1100 OPC_SDXC1 = 0x09 | OPC_CP3,
1101 OPC_SUXC1 = 0x0D | OPC_CP3,
1102 OPC_PREFX = 0x0F | OPC_CP3,
1103 OPC_ALNV_PS = 0x1E | OPC_CP3,
1104 OPC_MADD_S = 0x20 | OPC_CP3,
1105 OPC_MADD_D = 0x21 | OPC_CP3,
1106 OPC_MADD_PS = 0x26 | OPC_CP3,
1107 OPC_MSUB_S = 0x28 | OPC_CP3,
1108 OPC_MSUB_D = 0x29 | OPC_CP3,
1109 OPC_MSUB_PS = 0x2E | OPC_CP3,
1110 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1111 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1112 OPC_NMADD_PS= 0x36 | OPC_CP3,
1113 OPC_NMSUB_S = 0x38 | OPC_CP3,
1114 OPC_NMSUB_D = 0x39 | OPC_CP3,
1115 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1116};
1117
239dfebe
YK
1118/* MSA Opcodes */
1119#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1120enum {
1121 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1122 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1123 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1124 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1125 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1126 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1127 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1128 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1129 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1130 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1131 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1132 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1133 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1134 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1135 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1136 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1137 OPC_MSA_ELM = 0x19 | OPC_MSA,
1138 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1139 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1140 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1141 OPC_MSA_VEC = 0x1E | OPC_MSA,
1142
1143 /* MI10 instruction */
1144 OPC_LD_B = (0x20) | OPC_MSA,
1145 OPC_LD_H = (0x21) | OPC_MSA,
1146 OPC_LD_W = (0x22) | OPC_MSA,
1147 OPC_LD_D = (0x23) | OPC_MSA,
1148 OPC_ST_B = (0x24) | OPC_MSA,
1149 OPC_ST_H = (0x25) | OPC_MSA,
1150 OPC_ST_W = (0x26) | OPC_MSA,
1151 OPC_ST_D = (0x27) | OPC_MSA,
1152};
1153
1154enum {
1155 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1156 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1157 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1158 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1159 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1160 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1161 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1162 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1163 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1164 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1165 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1166 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1167 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1168
1169 /* I8 instruction */
1170 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1171 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1172 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1173 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1174 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1175 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1176 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1177 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1179 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1180
1181 /* VEC/2R/2RF instruction */
1182 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1183 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1184 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1185 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1186 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1187 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1188 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1189
1190 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1191 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1192
1193 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1194 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1195 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1196 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1197 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1198
1199 /* 2RF instruction df(bit 16) = _w, _d */
1200 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1201 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1203 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1204 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1205 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1206 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1207 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1208 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1210 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1211 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1212 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1214 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1216
1217 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1218 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1219 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1220 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1221 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1222 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1223 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1224 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1225 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1226 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1227 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1228 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1229 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1230 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1231 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1232 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1233 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1234 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1235 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1236 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1237 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1238 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1239 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1240 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1241 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1242 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1243 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1244 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1245 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1246 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1249 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1250 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1251 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1252 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1254 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1255 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1256 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1257 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1258 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1259 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1260 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1261 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1262 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1263 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1264 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1265 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1266 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1267 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1268 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1269 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1270 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1271 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1272 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1273 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1274 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1276 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1281
1282 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1283 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1284 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1285 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1286 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1287 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1288 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1289 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292
1293 /* 3RF instruction _df(bit 21) = _w, _d */
1294 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1295 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1296 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1297 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1298 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1299 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1300 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1301 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1302 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1307 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1310 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1312 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1313 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1314 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1315 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1317 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1318 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1320 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1322 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1324 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1325 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1326 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1329 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1332 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1335
1336 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1337 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1338 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1339 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1340 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1341 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1342 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1343 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1344 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1345 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1346 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1347 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1349};
1350
39454628 1351/* global register indices */
a7812ae4
PB
1352static TCGv_ptr cpu_env;
1353static TCGv cpu_gpr[32], cpu_PC;
340fff72 1354static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1355static TCGv cpu_dspctrl, btarget, bcond;
1356static TCGv_i32 hflags;
a7812ae4 1357static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1358static TCGv_i64 fpu_f64[32];
863f264d 1359static TCGv_i64 msa_wr_d[64];
aa0bf00b 1360
1a7ff922 1361static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1362static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1363
022c62cb 1364#include "exec/gen-icount.h"
2e70f6ef 1365
895c2d04 1366#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1368 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1369 tcg_temp_free_i32(helper_tmp); \
1370 } while(0)
be24bb4f 1371
895c2d04 1372#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1375 tcg_temp_free_i32(helper_tmp); \
1376 } while(0)
be24bb4f 1377
895c2d04
BS
1378#define gen_helper_1e0i(name, ret, arg1) do { \
1379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1380 gen_helper_##name(ret, cpu_env, helper_tmp); \
1381 tcg_temp_free_i32(helper_tmp); \
1382 } while(0)
1383
1384#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1387 tcg_temp_free_i32(helper_tmp); \
1388 } while(0)
1389
1390#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1393 tcg_temp_free_i32(helper_tmp); \
1394 } while(0)
1395
1396#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1399 tcg_temp_free_i32(helper_tmp); \
1400 } while(0)
be24bb4f 1401
895c2d04 1402#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1405 tcg_temp_free_i32(helper_tmp); \
1406 } while(0)
c239529e 1407
8e9ade68
TS
1408typedef struct DisasContext {
1409 struct TranslationBlock *tb;
1410 target_ulong pc, saved_pc;
1411 uint32_t opcode;
7b270ef2 1412 int singlestep_enabled;
d75c135e 1413 int insn_flags;
5ab5c041 1414 int32_t CP0_Config1;
8e9ade68
TS
1415 /* Routine used to access memory */
1416 int mem_idx;
be3a8c53 1417 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1418 uint32_t hflags, saved_hflags;
1419 int bstate;
1420 target_ulong btarget;
d279279e 1421 bool ulri;
e98c0d17 1422 int kscrexist;
7207c7f9 1423 bool rxi;
9456c2fb 1424 int ie;
aea14095
LA
1425 bool bi;
1426 bool bp;
8e9ade68
TS
1427} DisasContext;
1428
1429enum {
1430 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1431 * exception condition */
8e9ade68
TS
1432 BS_STOP = 1, /* We want to stop translation for any reason */
1433 BS_BRANCH = 2, /* We reached a branch condition */
1434 BS_EXCP = 3, /* We reached an exception condition */
1435};
1436
d73ee8a2
RH
1437static const char * const regnames[] = {
1438 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1439 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1440 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1441 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1442};
6af0bf9c 1443
d73ee8a2
RH
1444static const char * const regnames_HI[] = {
1445 "HI0", "HI1", "HI2", "HI3",
1446};
4b2eb8d2 1447
d73ee8a2
RH
1448static const char * const regnames_LO[] = {
1449 "LO0", "LO1", "LO2", "LO3",
1450};
4b2eb8d2 1451
d73ee8a2
RH
1452static const char * const fregnames[] = {
1453 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1454 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1455 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1456 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1457};
958fb4a9 1458
863f264d
YK
1459static const char * const msaregnames[] = {
1460 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1461 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1462 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1463 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1464 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1465 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1466 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1467 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1468 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1469 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1470 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1471 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1472 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1473 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1474 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1475 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1476};
1477
fb7729e2
RH
1478#define MIPS_DEBUG(fmt, ...) \
1479 do { \
1480 if (MIPS_DEBUG_DISAS) { \
1481 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1482 TARGET_FMT_lx ": %08x " fmt "\n", \
1483 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1484 } \
1485 } while (0)
1486
1487#define LOG_DISAS(...) \
1488 do { \
1489 if (MIPS_DEBUG_DISAS) { \
1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1491 } \
1492 } while (0)
958fb4a9 1493
8e9ade68 1494#define MIPS_INVAL(op) \
8e9ade68 1495 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1496 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1497
8e9ade68
TS
1498/* General purpose registers moves. */
1499static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1500{
8e9ade68
TS
1501 if (reg == 0)
1502 tcg_gen_movi_tl(t, 0);
1503 else
4b2eb8d2 1504 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1505}
1506
8e9ade68 1507static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1508{
8e9ade68 1509 if (reg != 0)
4b2eb8d2 1510 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1511}
1512
8e9ade68 1513/* Moves to/from shadow registers. */
be24bb4f 1514static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1515{
d9bea114 1516 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1517
1518 if (from == 0)
d9bea114 1519 tcg_gen_movi_tl(t0, 0);
8e9ade68 1520 else {
d9bea114 1521 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1522 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1523
7db13fae 1524 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1525 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1526 tcg_gen_andi_i32(t2, t2, 0xf);
1527 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1528 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1529 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1530
d9bea114 1531 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1532 tcg_temp_free_ptr(addr);
d9bea114 1533 tcg_temp_free_i32(t2);
8e9ade68 1534 }
d9bea114
AJ
1535 gen_store_gpr(t0, to);
1536 tcg_temp_free(t0);
aaa9128a
TS
1537}
1538
be24bb4f 1539static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1540{
be24bb4f 1541 if (to != 0) {
d9bea114
AJ
1542 TCGv t0 = tcg_temp_new();
1543 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1544 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1545
d9bea114 1546 gen_load_gpr(t0, from);
7db13fae 1547 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1548 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1549 tcg_gen_andi_i32(t2, t2, 0xf);
1550 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1551 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1552 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1553
d9bea114 1554 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1555 tcg_temp_free_ptr(addr);
d9bea114
AJ
1556 tcg_temp_free_i32(t2);
1557 tcg_temp_free(t0);
8e9ade68 1558 }
aaa9128a
TS
1559}
1560
eab9944c
LA
1561/* Tests */
1562static inline void gen_save_pc(target_ulong pc)
1563{
1564 tcg_gen_movi_tl(cpu_PC, pc);
1565}
1566
1567static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1568{
1569 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1570 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1571 gen_save_pc(ctx->pc);
1572 ctx->saved_pc = ctx->pc;
1573 }
1574 if (ctx->hflags != ctx->saved_hflags) {
1575 tcg_gen_movi_i32(hflags, ctx->hflags);
1576 ctx->saved_hflags = ctx->hflags;
1577 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1578 case MIPS_HFLAG_BR:
1579 break;
1580 case MIPS_HFLAG_BC:
1581 case MIPS_HFLAG_BL:
1582 case MIPS_HFLAG_B:
1583 tcg_gen_movi_tl(btarget, ctx->btarget);
1584 break;
1585 }
1586 }
1587}
1588
1589static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1590{
1591 ctx->saved_hflags = ctx->hflags;
1592 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1593 case MIPS_HFLAG_BR:
1594 break;
1595 case MIPS_HFLAG_BC:
1596 case MIPS_HFLAG_BL:
1597 case MIPS_HFLAG_B:
1598 ctx->btarget = env->btarget;
1599 break;
1600 }
1601}
1602
1603static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1604{
1605 TCGv_i32 texcp = tcg_const_i32(excp);
1606 TCGv_i32 terr = tcg_const_i32(err);
1607 save_cpu_state(ctx, 1);
1608 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1609 tcg_temp_free_i32(terr);
1610 tcg_temp_free_i32(texcp);
1611}
1612
1613static inline void generate_exception(DisasContext *ctx, int excp)
1614{
1615 save_cpu_state(ctx, 1);
1616 gen_helper_0e0i(raise_exception, excp);
1617}
1618
aaa9128a 1619/* Floating point register moves. */
7c979afd 1620static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1621{
7c979afd
LA
1622 if (ctx->hflags & MIPS_HFLAG_FRE) {
1623 generate_exception(ctx, EXCP_RI);
1624 }
d73ee8a2 1625 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1626}
1627
7c979afd 1628static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1629{
7c979afd
LA
1630 TCGv_i64 t64;
1631 if (ctx->hflags & MIPS_HFLAG_FRE) {
1632 generate_exception(ctx, EXCP_RI);
1633 }
1634 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1635 tcg_gen_extu_i32_i64(t64, t);
1636 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1637 tcg_temp_free_i64(t64);
6d066274
AJ
1638}
1639
7f6613ce 1640static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1641{
7f6613ce
PJ
1642 if (ctx->hflags & MIPS_HFLAG_F64) {
1643 TCGv_i64 t64 = tcg_temp_new_i64();
1644 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1645 tcg_gen_trunc_i64_i32(t, t64);
1646 tcg_temp_free_i64(t64);
1647 } else {
7c979afd 1648 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1649 }
6d066274
AJ
1650}
1651
7f6613ce 1652static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1653{
7f6613ce
PJ
1654 if (ctx->hflags & MIPS_HFLAG_F64) {
1655 TCGv_i64 t64 = tcg_temp_new_i64();
1656 tcg_gen_extu_i32_i64(t64, t);
1657 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1658 tcg_temp_free_i64(t64);
1659 } else {
7c979afd 1660 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1661 }
aa0bf00b 1662}
6ea83fed 1663
d73ee8a2 1664static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1665{
f364515c 1666 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1667 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1668 } else {
d73ee8a2 1669 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1670 }
1671}
6ea83fed 1672
d73ee8a2 1673static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1674{
f364515c 1675 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1676 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1677 } else {
d73ee8a2
RH
1678 TCGv_i64 t0;
1679 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1680 t0 = tcg_temp_new_i64();
6d066274 1681 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1682 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1683 tcg_temp_free_i64(t0);
aa0bf00b
TS
1684 }
1685}
6ea83fed 1686
d94536f4 1687static inline int get_fp_bit (int cc)
a16336e4 1688{
d94536f4
AJ
1689 if (cc)
1690 return 24 + cc;
1691 else
1692 return 23;
a16336e4
TS
1693}
1694
48d38ca5 1695/* Addresses computation */
941694d0 1696static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1697{
941694d0 1698 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1699
1700#if defined(TARGET_MIPS64)
01f72885 1701 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1702 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1703 }
1704#endif
4ad40f36
FB
1705}
1706
31837be3
YK
1707/* Addresses computation (translation time) */
1708static target_long addr_add(DisasContext *ctx, target_long base,
1709 target_long offset)
1710{
1711 target_long sum = base + offset;
1712
1713#if defined(TARGET_MIPS64)
1714 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1715 sum = (int32_t)sum;
1716 }
1717#endif
1718 return sum;
1719}
1720
356265ae 1721static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1722{
fe253235 1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1724 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1725}
1726
356265ae 1727static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1728{
fe253235 1729 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1730 generate_exception_err(ctx, EXCP_CpU, 1);
1731}
1732
b8aa4598
TS
1733/* Verify that the processor is running with COP1X instructions enabled.
1734 This is associated with the nabla symbol in the MIPS32 and MIPS64
1735 opcode tables. */
1736
356265ae 1737static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1738{
1739 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1740 generate_exception(ctx, EXCP_RI);
1741}
1742
1743/* Verify that the processor is running with 64-bit floating-point
1744 operations enabled. */
1745
356265ae 1746static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1747{
b8aa4598 1748 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1749 generate_exception(ctx, EXCP_RI);
1750}
1751
1752/*
1753 * Verify if floating point register is valid; an operation is not defined
1754 * if bit 0 of any register specification is set and the FR bit in the
1755 * Status register equals zero, since the register numbers specify an
1756 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1757 * in the Status register equals one, both even and odd register numbers
1758 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1759 *
1760 * Multiple 64 bit wide registers can be checked by calling
1761 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1762 */
356265ae 1763static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1764{
fe253235 1765 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1766 generate_exception(ctx, EXCP_RI);
1767}
1768
853c3240
JL
1769/* Verify that the processor is running with DSP instructions enabled.
1770 This is enabled by CP0 Status register MX(24) bit.
1771 */
1772
1773static inline void check_dsp(DisasContext *ctx)
1774{
1775 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1776 if (ctx->insn_flags & ASE_DSP) {
1777 generate_exception(ctx, EXCP_DSPDIS);
1778 } else {
1779 generate_exception(ctx, EXCP_RI);
1780 }
853c3240
JL
1781 }
1782}
1783
1784static inline void check_dspr2(DisasContext *ctx)
1785{
1786 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1787 if (ctx->insn_flags & ASE_DSP) {
1788 generate_exception(ctx, EXCP_DSPDIS);
1789 } else {
1790 generate_exception(ctx, EXCP_RI);
1791 }
853c3240
JL
1792 }
1793}
1794
3a95e3a7 1795/* This code generates a "reserved instruction" exception if the
e189e748 1796 CPU does not support the instruction set corresponding to flags. */
d75c135e 1797static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1798{
d75c135e 1799 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1800 generate_exception(ctx, EXCP_RI);
d75c135e 1801 }
3a95e3a7
TS
1802}
1803
fecd2646
LA
1804/* This code generates a "reserved instruction" exception if the
1805 CPU has corresponding flag set which indicates that the instruction
1806 has been removed. */
1807static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1808{
1809 if (unlikely(ctx->insn_flags & flags)) {
1810 generate_exception(ctx, EXCP_RI);
1811 }
1812}
1813
c7986fd6 1814#ifdef TARGET_MIPS64
e189e748
TS
1815/* This code generates a "reserved instruction" exception if 64-bit
1816 instructions are not enabled. */
356265ae 1817static inline void check_mips_64(DisasContext *ctx)
e189e748 1818{
fe253235 1819 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1820 generate_exception(ctx, EXCP_RI);
1821}
c7986fd6 1822#endif
e189e748 1823
8153667c
NF
1824/* Define small wrappers for gen_load_fpr* so that we have a uniform
1825 calling interface for 32 and 64-bit FPRs. No sense in changing
1826 all callers for gen_load_fpr32 when we need the CTX parameter for
1827 this one use. */
7c979afd 1828#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1829#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1830#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1831static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1832 int ft, int fs, int cc) \
1833{ \
1834 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1835 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1836 switch (ifmt) { \
1837 case FMT_PS: \
1838 check_cp1_64bitmode(ctx); \
1839 break; \
1840 case FMT_D: \
1841 if (abs) { \
1842 check_cop1x(ctx); \
1843 } \
1844 check_cp1_registers(ctx, fs | ft); \
1845 break; \
1846 case FMT_S: \
1847 if (abs) { \
1848 check_cop1x(ctx); \
1849 } \
1850 break; \
1851 } \
1852 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1853 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1854 switch (n) { \
895c2d04
BS
1855 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1856 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1857 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1858 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1859 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1860 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1861 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1862 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1863 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1864 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1865 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1866 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1867 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1868 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1869 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1870 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1871 default: abort(); \
1872 } \
1873 tcg_temp_free_i##bits (fp0); \
1874 tcg_temp_free_i##bits (fp1); \
1875}
1876
1877FOP_CONDS(, 0, d, FMT_D, 64)
1878FOP_CONDS(abs, 1, d, FMT_D, 64)
1879FOP_CONDS(, 0, s, FMT_S, 32)
1880FOP_CONDS(abs, 1, s, FMT_S, 32)
1881FOP_CONDS(, 0, ps, FMT_PS, 64)
1882FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1883#undef FOP_CONDS
3f493883
YK
1884
1885#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1886static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1887 int ft, int fs, int fd) \
1888{ \
1889 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1890 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1891 if (ifmt == FMT_D) { \
3f493883 1892 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1893 } \
1894 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1895 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1896 switch (n) { \
1897 case 0: \
1898 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 1: \
1901 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 2: \
1904 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 3: \
1907 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 4: \
1910 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 5: \
1913 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 6: \
1916 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 7: \
1919 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 8: \
1922 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 9: \
1925 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 10: \
1928 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 11: \
1931 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 12: \
1934 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 13: \
1937 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 case 14: \
1940 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1941 break; \
1942 case 15: \
1943 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1944 break; \
1945 case 17: \
1946 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 18: \
1949 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 19: \
1952 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 25: \
1955 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 26: \
1958 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 27: \
1961 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 default: \
1964 abort(); \
1965 } \
1966 STORE; \
1967 tcg_temp_free_i ## bits (fp0); \
1968 tcg_temp_free_i ## bits (fp1); \
1969}
1970
1971FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 1972FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 1973#undef FOP_CONDNS
8153667c
NF
1974#undef gen_ldcmp_fpr32
1975#undef gen_ldcmp_fpr64
1976
958fb4a9 1977/* load/store instructions. */
e7139c44 1978#ifdef CONFIG_USER_ONLY
d9bea114 1979#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1980static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1981{ \
1982 TCGv t0 = tcg_temp_new(); \
1983 tcg_gen_mov_tl(t0, arg1); \
1984 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1985 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1986 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1987 tcg_temp_free(t0); \
aaa9128a 1988}
e7139c44
AJ
1989#else
1990#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1991static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1992{ \
895c2d04 1993 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1994}
1995#endif
aaa9128a
TS
1996OP_LD_ATOMIC(ll,ld32s);
1997#if defined(TARGET_MIPS64)
1998OP_LD_ATOMIC(lld,ld64);
1999#endif
2000#undef OP_LD_ATOMIC
2001
590bc601
PB
2002#ifdef CONFIG_USER_ONLY
2003#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2004static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2005{ \
2006 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2007 TCGLabel *l1 = gen_new_label(); \
2008 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2009 \
2010 tcg_gen_andi_tl(t0, arg2, almask); \
2011 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2012 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2013 generate_exception(ctx, EXCP_AdES); \
2014 gen_set_label(l1); \
7db13fae 2015 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2016 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2017 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2018 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2019 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2020 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2021 gen_set_label(l2); \
2022 tcg_gen_movi_tl(t0, 0); \
2023 gen_store_gpr(t0, rt); \
2024 tcg_temp_free(t0); \
2025}
2026#else
2027#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2028static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2029{ \
2030 TCGv t0 = tcg_temp_new(); \
895c2d04 2031 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2032 gen_store_gpr(t0, rt); \
590bc601
PB
2033 tcg_temp_free(t0); \
2034}
2035#endif
590bc601 2036OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2037#if defined(TARGET_MIPS64)
590bc601 2038OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2039#endif
2040#undef OP_ST_ATOMIC
2041
662d7485
NF
2042static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2043 int base, int16_t offset)
2044{
2045 if (base == 0) {
2046 tcg_gen_movi_tl(addr, offset);
2047 } else if (offset == 0) {
2048 gen_load_gpr(addr, base);
2049 } else {
2050 tcg_gen_movi_tl(addr, offset);
2051 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2052 }
2053}
2054
364d4831
NF
2055static target_ulong pc_relative_pc (DisasContext *ctx)
2056{
2057 target_ulong pc = ctx->pc;
2058
2059 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2060 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2061
2062 pc -= branch_bytes;
2063 }
2064
2065 pc &= ~(target_ulong)3;
2066 return pc;
2067}
2068
5c13fdfd 2069/* Load */
d75c135e
AJ
2070static void gen_ld(DisasContext *ctx, uint32_t opc,
2071 int rt, int base, int16_t offset)
6af0bf9c 2072{
5c13fdfd 2073 const char *opn = "ld";
fc40787a 2074 TCGv t0, t1, t2;
afa88c3a 2075
d75c135e 2076 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2077 /* Loongson CPU uses a load to zero register for prefetch.
2078 We emulate it as a NOP. On other CPU we must perform the
2079 actual memory access. */
2080 MIPS_DEBUG("NOP");
2081 return;
2082 }
6af0bf9c 2083
afa88c3a 2084 t0 = tcg_temp_new();
662d7485 2085 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2086
6af0bf9c 2087 switch (opc) {
d26bc211 2088#if defined(TARGET_MIPS64)
6e473128 2089 case OPC_LWU:
be3a8c53
YK
2090 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2091 ctx->default_tcg_memop_mask);
78723684 2092 gen_store_gpr(t0, rt);
6e473128
TS
2093 opn = "lwu";
2094 break;
6af0bf9c 2095 case OPC_LD:
be3a8c53
YK
2096 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2097 ctx->default_tcg_memop_mask);
78723684 2098 gen_store_gpr(t0, rt);
6af0bf9c
FB
2099 opn = "ld";
2100 break;
7a387fff 2101 case OPC_LLD:
bf7910c6 2102 case R6_OPC_LLD:
b835e919 2103 save_cpu_state(ctx, 1);
5c13fdfd 2104 op_ld_lld(t0, t0, ctx);
78723684 2105 gen_store_gpr(t0, rt);
7a387fff
TS
2106 opn = "lld";
2107 break;
6af0bf9c 2108 case OPC_LDL:
3cee3050 2109 t1 = tcg_temp_new();
fc40787a
AJ
2110 tcg_gen_andi_tl(t1, t0, 7);
2111#ifndef TARGET_WORDS_BIGENDIAN
2112 tcg_gen_xori_tl(t1, t1, 7);
2113#endif
2114 tcg_gen_shli_tl(t1, t1, 3);
2115 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2116 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2117 tcg_gen_shl_tl(t0, t0, t1);
2118 tcg_gen_xori_tl(t1, t1, 63);
2119 t2 = tcg_const_tl(0x7fffffffffffffffull);
2120 tcg_gen_shr_tl(t2, t2, t1);
78723684 2121 gen_load_gpr(t1, rt);
fc40787a
AJ
2122 tcg_gen_and_tl(t1, t1, t2);
2123 tcg_temp_free(t2);
2124 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2125 tcg_temp_free(t1);
fc40787a 2126 gen_store_gpr(t0, rt);
6af0bf9c
FB
2127 opn = "ldl";
2128 break;
6af0bf9c 2129 case OPC_LDR:
3cee3050 2130 t1 = tcg_temp_new();
fc40787a
AJ
2131 tcg_gen_andi_tl(t1, t0, 7);
2132#ifdef TARGET_WORDS_BIGENDIAN
2133 tcg_gen_xori_tl(t1, t1, 7);
2134#endif
2135 tcg_gen_shli_tl(t1, t1, 3);
2136 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2137 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2138 tcg_gen_shr_tl(t0, t0, t1);
2139 tcg_gen_xori_tl(t1, t1, 63);
2140 t2 = tcg_const_tl(0xfffffffffffffffeull);
2141 tcg_gen_shl_tl(t2, t2, t1);
78723684 2142 gen_load_gpr(t1, rt);
fc40787a
AJ
2143 tcg_gen_and_tl(t1, t1, t2);
2144 tcg_temp_free(t2);
2145 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2146 tcg_temp_free(t1);
fc40787a 2147 gen_store_gpr(t0, rt);
6af0bf9c
FB
2148 opn = "ldr";
2149 break;
364d4831 2150 case OPC_LDPC:
3cee3050 2151 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2152 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2153 tcg_temp_free(t1);
5f68f5ae 2154 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2155 gen_store_gpr(t0, rt);
5c13fdfd 2156 opn = "ldpc";
364d4831 2157 break;
6af0bf9c 2158#endif
364d4831 2159 case OPC_LWPC:
3cee3050 2160 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2161 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2162 tcg_temp_free(t1);
5f68f5ae 2163 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2164 gen_store_gpr(t0, rt);
5c13fdfd 2165 opn = "lwpc";
364d4831 2166 break;
6af0bf9c 2167 case OPC_LW:
be3a8c53
YK
2168 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2169 ctx->default_tcg_memop_mask);
78723684 2170 gen_store_gpr(t0, rt);
6af0bf9c
FB
2171 opn = "lw";
2172 break;
6af0bf9c 2173 case OPC_LH:
be3a8c53
YK
2174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2175 ctx->default_tcg_memop_mask);
78723684 2176 gen_store_gpr(t0, rt);
6af0bf9c
FB
2177 opn = "lh";
2178 break;
6af0bf9c 2179 case OPC_LHU:
be3a8c53
YK
2180 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2181 ctx->default_tcg_memop_mask);
78723684 2182 gen_store_gpr(t0, rt);
6af0bf9c
FB
2183 opn = "lhu";
2184 break;
2185 case OPC_LB:
5f68f5ae 2186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2187 gen_store_gpr(t0, rt);
6af0bf9c
FB
2188 opn = "lb";
2189 break;
6af0bf9c 2190 case OPC_LBU:
5f68f5ae 2191 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2192 gen_store_gpr(t0, rt);
6af0bf9c
FB
2193 opn = "lbu";
2194 break;
2195 case OPC_LWL:
3cee3050 2196 t1 = tcg_temp_new();
fc40787a
AJ
2197 tcg_gen_andi_tl(t1, t0, 3);
2198#ifndef TARGET_WORDS_BIGENDIAN
2199 tcg_gen_xori_tl(t1, t1, 3);
2200#endif
2201 tcg_gen_shli_tl(t1, t1, 3);
2202 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2204 tcg_gen_shl_tl(t0, t0, t1);
2205 tcg_gen_xori_tl(t1, t1, 31);
2206 t2 = tcg_const_tl(0x7fffffffull);
2207 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2208 gen_load_gpr(t1, rt);
fc40787a
AJ
2209 tcg_gen_and_tl(t1, t1, t2);
2210 tcg_temp_free(t2);
2211 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2212 tcg_temp_free(t1);
fc40787a
AJ
2213 tcg_gen_ext32s_tl(t0, t0);
2214 gen_store_gpr(t0, rt);
6af0bf9c
FB
2215 opn = "lwl";
2216 break;
6af0bf9c 2217 case OPC_LWR:
3cee3050 2218 t1 = tcg_temp_new();
fc40787a
AJ
2219 tcg_gen_andi_tl(t1, t0, 3);
2220#ifdef TARGET_WORDS_BIGENDIAN
2221 tcg_gen_xori_tl(t1, t1, 3);
2222#endif
2223 tcg_gen_shli_tl(t1, t1, 3);
2224 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2226 tcg_gen_shr_tl(t0, t0, t1);
2227 tcg_gen_xori_tl(t1, t1, 31);
2228 t2 = tcg_const_tl(0xfffffffeull);
2229 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2230 gen_load_gpr(t1, rt);
fc40787a
AJ
2231 tcg_gen_and_tl(t1, t1, t2);
2232 tcg_temp_free(t2);
2233 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2234 tcg_temp_free(t1);
c728154b 2235 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2236 gen_store_gpr(t0, rt);
6af0bf9c
FB
2237 opn = "lwr";
2238 break;
6af0bf9c 2239 case OPC_LL:
4368b29a 2240 case R6_OPC_LL:
e7139c44 2241 save_cpu_state(ctx, 1);
5c13fdfd 2242 op_ld_ll(t0, t0, ctx);
78723684 2243 gen_store_gpr(t0, rt);
6af0bf9c
FB
2244 opn = "ll";
2245 break;
d66c7132 2246 }
2abf314d 2247 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2248 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2249 tcg_temp_free(t0);
d66c7132
AJ
2250}
2251
5c13fdfd
AJ
2252/* Store */
2253static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2254 int base, int16_t offset)
2255{
2256 const char *opn = "st";
2257 TCGv t0 = tcg_temp_new();
2258 TCGv t1 = tcg_temp_new();
2259
2260 gen_base_offset_addr(ctx, t0, base, offset);
2261 gen_load_gpr(t1, rt);
2262 switch (opc) {
2263#if defined(TARGET_MIPS64)
2264 case OPC_SD:
be3a8c53
YK
2265 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2266 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2267 opn = "sd";
2268 break;
2269 case OPC_SDL:
2270 save_cpu_state(ctx, 1);
895c2d04 2271 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2272 opn = "sdl";
2273 break;
2274 case OPC_SDR:
2275 save_cpu_state(ctx, 1);
895c2d04 2276 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2277 opn = "sdr";
2278 break;
2279#endif
2280 case OPC_SW:
be3a8c53
YK
2281 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2282 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2283 opn = "sw";
2284 break;
2285 case OPC_SH:
be3a8c53
YK
2286 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2287 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2288 opn = "sh";
2289 break;
2290 case OPC_SB:
5f68f5ae 2291 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2292 opn = "sb";
2293 break;
2294 case OPC_SWL:
2295 save_cpu_state(ctx, 1);
895c2d04 2296 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2297 opn = "swl";
2298 break;
2299 case OPC_SWR:
2300 save_cpu_state(ctx, 1);
895c2d04 2301 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2302 opn = "swr";
2303 break;
2304 }
2abf314d 2305 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2306 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2307 tcg_temp_free(t0);
2308 tcg_temp_free(t1);
2309}
2310
2311
d66c7132
AJ
2312/* Store conditional */
2313static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2314 int base, int16_t offset)
2315{
2316 const char *opn = "st_cond";
2317 TCGv t0, t1;
2318
2d2826b9 2319#ifdef CONFIG_USER_ONLY
d66c7132 2320 t0 = tcg_temp_local_new();
d66c7132 2321 t1 = tcg_temp_local_new();
2d2826b9
AJ
2322#else
2323 t0 = tcg_temp_new();
2324 t1 = tcg_temp_new();
2325#endif
2326 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2327 gen_load_gpr(t1, rt);
2328 switch (opc) {
2329#if defined(TARGET_MIPS64)
2330 case OPC_SCD:
bf7910c6 2331 case R6_OPC_SCD:
b835e919 2332 save_cpu_state(ctx, 1);
5c13fdfd 2333 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2334 opn = "scd";
2335 break;
2336#endif
6af0bf9c 2337 case OPC_SC:
4368b29a 2338 case R6_OPC_SC:
e7139c44 2339 save_cpu_state(ctx, 1);
5c13fdfd 2340 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2341 opn = "sc";
2342 break;
6af0bf9c 2343 }
2abf314d 2344 (void)opn; /* avoid a compiler warning */
6af0bf9c 2345 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2346 tcg_temp_free(t1);
d66c7132 2347 tcg_temp_free(t0);
6af0bf9c
FB
2348}
2349
6ea83fed 2350/* Load and store */
7a387fff 2351static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2352 int base, int16_t offset)
6ea83fed 2353{
923617a3 2354 const char *opn = "flt_ldst";
4e2474d6 2355 TCGv t0 = tcg_temp_new();
6ea83fed 2356
662d7485 2357 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2358 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2359 memory access. */
6ea83fed
FB
2360 switch (opc) {
2361 case OPC_LWC1:
b6d96bed 2362 {
a7812ae4 2363 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2364 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2365 ctx->default_tcg_memop_mask);
7c979afd 2366 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2367 tcg_temp_free_i32(fp0);
b6d96bed 2368 }
6ea83fed
FB
2369 opn = "lwc1";
2370 break;
2371 case OPC_SWC1:
b6d96bed 2372 {
a7812ae4 2373 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2374 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2375 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2376 ctx->default_tcg_memop_mask);
a7812ae4 2377 tcg_temp_free_i32(fp0);
b6d96bed 2378 }
6ea83fed
FB
2379 opn = "swc1";
2380 break;
2381 case OPC_LDC1:
b6d96bed 2382 {
a7812ae4 2383 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2384 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2385 ctx->default_tcg_memop_mask);
b6d96bed 2386 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2387 tcg_temp_free_i64(fp0);
b6d96bed 2388 }
6ea83fed
FB
2389 opn = "ldc1";
2390 break;
2391 case OPC_SDC1:
b6d96bed 2392 {
a7812ae4 2393 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2394 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2395 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2396 ctx->default_tcg_memop_mask);
a7812ae4 2397 tcg_temp_free_i64(fp0);
b6d96bed 2398 }
6ea83fed
FB
2399 opn = "sdc1";
2400 break;
2401 default:
923617a3 2402 MIPS_INVAL(opn);
e397ee33 2403 generate_exception(ctx, EXCP_RI);
78723684 2404 goto out;
6ea83fed 2405 }
2abf314d 2406 (void)opn; /* avoid a compiler warning */
6ea83fed 2407 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2408 out:
2409 tcg_temp_free(t0);
6ea83fed 2410}
6ea83fed 2411
5ab5c041
AJ
2412static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2413 int rs, int16_t imm)
26ebe468 2414{
5ab5c041 2415 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2416 check_cp1_enabled(ctx);
d9224450
MR
2417 switch (op) {
2418 case OPC_LDC1:
2419 case OPC_SDC1:
2420 check_insn(ctx, ISA_MIPS2);
2421 /* Fallthrough */
2422 default:
2423 gen_flt_ldst(ctx, op, rt, rs, imm);
2424 }
26ebe468
NF
2425 } else {
2426 generate_exception_err(ctx, EXCP_CpU, 1);
2427 }
2428}
2429
6af0bf9c 2430/* Arithmetic with immediate operand */
d75c135e
AJ
2431static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2432 int rt, int rs, int16_t imm)
6af0bf9c 2433{
324d9e32 2434 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2435 const char *opn = "imm arith";
6af0bf9c 2436
7a387fff 2437 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2438 /* If no destination, treat it as a NOP.
2439 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2440 MIPS_DEBUG("NOP");
324d9e32 2441 return;
6af0bf9c
FB
2442 }
2443 switch (opc) {
2444 case OPC_ADDI:
48d38ca5 2445 {
324d9e32
AJ
2446 TCGv t0 = tcg_temp_local_new();
2447 TCGv t1 = tcg_temp_new();
2448 TCGv t2 = tcg_temp_new();
42a268c2 2449 TCGLabel *l1 = gen_new_label();
48d38ca5 2450
324d9e32
AJ
2451 gen_load_gpr(t1, rs);
2452 tcg_gen_addi_tl(t0, t1, uimm);
2453 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2454
324d9e32
AJ
2455 tcg_gen_xori_tl(t1, t1, ~uimm);
2456 tcg_gen_xori_tl(t2, t0, uimm);
2457 tcg_gen_and_tl(t1, t1, t2);
2458 tcg_temp_free(t2);
2459 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2460 tcg_temp_free(t1);
48d38ca5
TS
2461 /* operands of same sign, result different sign */
2462 generate_exception(ctx, EXCP_OVERFLOW);
2463 gen_set_label(l1);
78723684 2464 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2465 gen_store_gpr(t0, rt);
2466 tcg_temp_free(t0);
48d38ca5 2467 }
6af0bf9c
FB
2468 opn = "addi";
2469 break;
2470 case OPC_ADDIU:
324d9e32
AJ
2471 if (rs != 0) {
2472 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2473 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2474 } else {
2475 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2476 }
6af0bf9c
FB
2477 opn = "addiu";
2478 break;
d26bc211 2479#if defined(TARGET_MIPS64)
7a387fff 2480 case OPC_DADDI:
48d38ca5 2481 {
324d9e32
AJ
2482 TCGv t0 = tcg_temp_local_new();
2483 TCGv t1 = tcg_temp_new();
2484 TCGv t2 = tcg_temp_new();
42a268c2 2485 TCGLabel *l1 = gen_new_label();
48d38ca5 2486
324d9e32
AJ
2487 gen_load_gpr(t1, rs);
2488 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2489
324d9e32
AJ
2490 tcg_gen_xori_tl(t1, t1, ~uimm);
2491 tcg_gen_xori_tl(t2, t0, uimm);
2492 tcg_gen_and_tl(t1, t1, t2);
2493 tcg_temp_free(t2);
2494 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2495 tcg_temp_free(t1);
48d38ca5
TS
2496 /* operands of same sign, result different sign */
2497 generate_exception(ctx, EXCP_OVERFLOW);
2498 gen_set_label(l1);
324d9e32
AJ
2499 gen_store_gpr(t0, rt);
2500 tcg_temp_free(t0);
48d38ca5 2501 }
7a387fff
TS
2502 opn = "daddi";
2503 break;
2504 case OPC_DADDIU:
324d9e32
AJ
2505 if (rs != 0) {
2506 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2507 } else {
2508 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2509 }
7a387fff
TS
2510 opn = "daddiu";
2511 break;
2512#endif
324d9e32 2513 }
2abf314d 2514 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2515 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2516}
2517
2518/* Logic with immediate operand */
d75c135e 2519static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2520 int rt, int rs, int16_t imm)
324d9e32
AJ
2521{
2522 target_ulong uimm;
324d9e32
AJ
2523
2524 if (rt == 0) {
2525 /* If no destination, treat it as a NOP. */
2526 MIPS_DEBUG("NOP");
2527 return;
2528 }
2529 uimm = (uint16_t)imm;
2530 switch (opc) {
6af0bf9c 2531 case OPC_ANDI:
324d9e32
AJ
2532 if (likely(rs != 0))
2533 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2534 else
2535 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2536 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2537 regnames[rs], uimm);
6af0bf9c
FB
2538 break;
2539 case OPC_ORI:
324d9e32
AJ
2540 if (rs != 0)
2541 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2542 else
2543 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2544 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2545 regnames[rs], uimm);
6af0bf9c
FB
2546 break;
2547 case OPC_XORI:
324d9e32
AJ
2548 if (likely(rs != 0))
2549 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2550 else
2551 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2552 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2553 regnames[rs], uimm);
6af0bf9c
FB
2554 break;
2555 case OPC_LUI:
d4ea6acd
LA
2556 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2557 /* OPC_AUI */
2558 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2560 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2561 } else {
2562 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2563 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2564 }
7c2c3ea3
EJ
2565 break;
2566
2567 default:
2568 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2569 break;
324d9e32 2570 }
324d9e32
AJ
2571}
2572
2573/* Set on less than with immediate operand */
d75c135e 2574static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2575 int rt, int rs, int16_t imm)
324d9e32
AJ
2576{
2577 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2578 const char *opn = "imm arith";
2579 TCGv t0;
2580
2581 if (rt == 0) {
2582 /* If no destination, treat it as a NOP. */
2583 MIPS_DEBUG("NOP");
2584 return;
2585 }
2586 t0 = tcg_temp_new();
2587 gen_load_gpr(t0, rs);
2588 switch (opc) {
2589 case OPC_SLTI:
e68dd28f 2590 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2591 opn = "slti";
2592 break;
2593 case OPC_SLTIU:
e68dd28f 2594 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2595 opn = "sltiu";
2596 break;
2597 }
2abf314d 2598 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2599 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2600 tcg_temp_free(t0);
2601}
2602
2603/* Shifts with immediate operand */
d75c135e 2604static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2605 int rt, int rs, int16_t imm)
2606{
2607 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2608 const char *opn = "imm shift";
2609 TCGv t0;
2610
2611 if (rt == 0) {
2612 /* If no destination, treat it as a NOP. */
2613 MIPS_DEBUG("NOP");
2614 return;
2615 }
2616
2617 t0 = tcg_temp_new();
2618 gen_load_gpr(t0, rs);
2619 switch (opc) {
6af0bf9c 2620 case OPC_SLL:
78723684 2621 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2622 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2623 opn = "sll";
2624 break;
2625 case OPC_SRA:
324d9e32 2626 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2627 opn = "sra";
2628 break;
2629 case OPC_SRL:
ea63e2c3
NF
2630 if (uimm != 0) {
2631 tcg_gen_ext32u_tl(t0, t0);
2632 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2633 } else {
2634 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2635 }
ea63e2c3
NF
2636 opn = "srl";
2637 break;
2638 case OPC_ROTR:
2639 if (uimm != 0) {
2640 TCGv_i32 t1 = tcg_temp_new_i32();
2641
2642 tcg_gen_trunc_tl_i32(t1, t0);
2643 tcg_gen_rotri_i32(t1, t1, uimm);
2644 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2645 tcg_temp_free_i32(t1);
3399e30f
NF
2646 } else {
2647 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2648 }
2649 opn = "rotr";
7a387fff 2650 break;
d26bc211 2651#if defined(TARGET_MIPS64)
7a387fff 2652 case OPC_DSLL:
324d9e32 2653 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2654 opn = "dsll";
2655 break;
2656 case OPC_DSRA:
324d9e32 2657 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2658 opn = "dsra";
2659 break;
2660 case OPC_DSRL:
ea63e2c3
NF
2661 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2662 opn = "dsrl";
2663 break;
2664 case OPC_DROTR:
2665 if (uimm != 0) {
2666 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2667 } else {
2668 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2669 }
ea63e2c3 2670 opn = "drotr";
7a387fff
TS
2671 break;
2672 case OPC_DSLL32:
324d9e32 2673 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2674 opn = "dsll32";
2675 break;
2676 case OPC_DSRA32:
324d9e32 2677 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2678 opn = "dsra32";
2679 break;
2680 case OPC_DSRL32:
ea63e2c3
NF
2681 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2682 opn = "dsrl32";
2683 break;
2684 case OPC_DROTR32:
2685 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2686 opn = "drotr32";
6af0bf9c 2687 break;
7a387fff 2688#endif
6af0bf9c 2689 }
2abf314d 2690 (void)opn; /* avoid a compiler warning */
93b12ccc 2691 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2692 tcg_temp_free(t0);
6af0bf9c
FB
2693}
2694
2695/* Arithmetic */
d75c135e
AJ
2696static void gen_arith(DisasContext *ctx, uint32_t opc,
2697 int rd, int rs, int rt)
6af0bf9c 2698{
923617a3 2699 const char *opn = "arith";
6af0bf9c 2700
7a387fff
TS
2701 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2702 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2703 /* If no destination, treat it as a NOP.
2704 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2705 MIPS_DEBUG("NOP");
460f00c4 2706 return;
185f0762 2707 }
460f00c4 2708
6af0bf9c
FB
2709 switch (opc) {
2710 case OPC_ADD:
48d38ca5 2711 {
460f00c4
AJ
2712 TCGv t0 = tcg_temp_local_new();
2713 TCGv t1 = tcg_temp_new();
2714 TCGv t2 = tcg_temp_new();
42a268c2 2715 TCGLabel *l1 = gen_new_label();
48d38ca5 2716
460f00c4
AJ
2717 gen_load_gpr(t1, rs);
2718 gen_load_gpr(t2, rt);
2719 tcg_gen_add_tl(t0, t1, t2);
2720 tcg_gen_ext32s_tl(t0, t0);
2721 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2722 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2723 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2724 tcg_temp_free(t2);
2725 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2726 tcg_temp_free(t1);
48d38ca5
TS
2727 /* operands of same sign, result different sign */
2728 generate_exception(ctx, EXCP_OVERFLOW);
2729 gen_set_label(l1);
460f00c4
AJ
2730 gen_store_gpr(t0, rd);
2731 tcg_temp_free(t0);
48d38ca5 2732 }
6af0bf9c
FB
2733 opn = "add";
2734 break;
2735 case OPC_ADDU:
460f00c4
AJ
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739 } else if (rs == 0 && rt != 0) {
2740 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741 } else if (rs != 0 && rt == 0) {
2742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2743 } else {
2744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2745 }
6af0bf9c
FB
2746 opn = "addu";
2747 break;
2748 case OPC_SUB:
48d38ca5 2749 {
460f00c4
AJ
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
42a268c2 2753 TCGLabel *l1 = gen_new_label();
48d38ca5 2754
460f00c4
AJ
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_sub_tl(t0, t1, t2);
2758 tcg_gen_ext32s_tl(t0, t0);
2759 tcg_gen_xor_tl(t2, t1, t2);
2760 tcg_gen_xor_tl(t1, t0, t1);
2761 tcg_gen_and_tl(t1, t1, t2);
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
31e3104f 2765 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
460f00c4
AJ
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
48d38ca5 2770 }
6af0bf9c
FB
2771 opn = "sub";
2772 break;
2773 case OPC_SUBU:
460f00c4
AJ
2774 if (rs != 0 && rt != 0) {
2775 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2776 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2777 } else if (rs == 0 && rt != 0) {
2778 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2779 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2780 } else if (rs != 0 && rt == 0) {
2781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2782 } else {
2783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2784 }
6af0bf9c
FB
2785 opn = "subu";
2786 break;
d26bc211 2787#if defined(TARGET_MIPS64)
7a387fff 2788 case OPC_DADD:
48d38ca5 2789 {
460f00c4
AJ
2790 TCGv t0 = tcg_temp_local_new();
2791 TCGv t1 = tcg_temp_new();
2792 TCGv t2 = tcg_temp_new();
42a268c2 2793 TCGLabel *l1 = gen_new_label();
48d38ca5 2794
460f00c4
AJ
2795 gen_load_gpr(t1, rs);
2796 gen_load_gpr(t2, rt);
2797 tcg_gen_add_tl(t0, t1, t2);
2798 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2799 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2800 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2801 tcg_temp_free(t2);
2802 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2803 tcg_temp_free(t1);
48d38ca5
TS
2804 /* operands of same sign, result different sign */
2805 generate_exception(ctx, EXCP_OVERFLOW);
2806 gen_set_label(l1);
460f00c4
AJ
2807 gen_store_gpr(t0, rd);
2808 tcg_temp_free(t0);
48d38ca5 2809 }
7a387fff
TS
2810 opn = "dadd";
2811 break;
2812 case OPC_DADDU:
460f00c4
AJ
2813 if (rs != 0 && rt != 0) {
2814 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2815 } else if (rs == 0 && rt != 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2817 } else if (rs != 0 && rt == 0) {
2818 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2819 } else {
2820 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2821 }
7a387fff
TS
2822 opn = "daddu";
2823 break;
2824 case OPC_DSUB:
48d38ca5 2825 {
460f00c4
AJ
2826 TCGv t0 = tcg_temp_local_new();
2827 TCGv t1 = tcg_temp_new();
2828 TCGv t2 = tcg_temp_new();
42a268c2 2829 TCGLabel *l1 = gen_new_label();
48d38ca5 2830
460f00c4
AJ
2831 gen_load_gpr(t1, rs);
2832 gen_load_gpr(t2, rt);
2833 tcg_gen_sub_tl(t0, t1, t2);
2834 tcg_gen_xor_tl(t2, t1, t2);
2835 tcg_gen_xor_tl(t1, t0, t1);
2836 tcg_gen_and_tl(t1, t1, t2);
2837 tcg_temp_free(t2);
2838 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2839 tcg_temp_free(t1);
31e3104f 2840 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2841 generate_exception(ctx, EXCP_OVERFLOW);
2842 gen_set_label(l1);
460f00c4
AJ
2843 gen_store_gpr(t0, rd);
2844 tcg_temp_free(t0);
48d38ca5 2845 }
7a387fff
TS
2846 opn = "dsub";
2847 break;
2848 case OPC_DSUBU:
460f00c4
AJ
2849 if (rs != 0 && rt != 0) {
2850 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851 } else if (rs == 0 && rt != 0) {
2852 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853 } else if (rs != 0 && rt == 0) {
2854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2855 } else {
2856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2857 }
7a387fff
TS
2858 opn = "dsubu";
2859 break;
2860#endif
460f00c4
AJ
2861 case OPC_MUL:
2862 if (likely(rs != 0 && rt != 0)) {
2863 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2864 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2865 } else {
2866 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2867 }
2868 opn = "mul";
6af0bf9c 2869 break;
460f00c4 2870 }
2abf314d 2871 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2872 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2873}
2874
2875/* Conditional move */
d75c135e 2876static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2877 int rd, int rs, int rt)
460f00c4
AJ
2878{
2879 const char *opn = "cond move";
acf12465 2880 TCGv t0, t1, t2;
460f00c4
AJ
2881
2882 if (rd == 0) {
acf12465 2883 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2884 MIPS_DEBUG("NOP");
2885 return;
2886 }
2887
acf12465
AJ
2888 t0 = tcg_temp_new();
2889 gen_load_gpr(t0, rt);
2890 t1 = tcg_const_tl(0);
2891 t2 = tcg_temp_new();
2892 gen_load_gpr(t2, rs);
460f00c4
AJ
2893 switch (opc) {
2894 case OPC_MOVN:
acf12465 2895 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2896 opn = "movn";
6af0bf9c 2897 break;
460f00c4 2898 case OPC_MOVZ:
acf12465 2899 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2900 opn = "movz";
2901 break;
b691d9d2
LA
2902 case OPC_SELNEZ:
2903 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2904 opn = "selnez";
2905 break;
2906 case OPC_SELEQZ:
2907 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2908 opn = "seleqz";
2909 break;
460f00c4 2910 }
acf12465
AJ
2911 tcg_temp_free(t2);
2912 tcg_temp_free(t1);
2913 tcg_temp_free(t0);
460f00c4 2914
2abf314d 2915 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2916 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2917}
2918
2919/* Logic */
d75c135e 2920static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2921 int rd, int rs, int rt)
460f00c4
AJ
2922{
2923 const char *opn = "logic";
2924
2925 if (rd == 0) {
2926 /* If no destination, treat it as a NOP. */
2927 MIPS_DEBUG("NOP");
2928 return;
2929 }
2930
2931 switch (opc) {
6af0bf9c 2932 case OPC_AND:
460f00c4
AJ
2933 if (likely(rs != 0 && rt != 0)) {
2934 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2935 } else {
2936 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2937 }
6af0bf9c
FB
2938 opn = "and";
2939 break;
2940 case OPC_NOR:
460f00c4
AJ
2941 if (rs != 0 && rt != 0) {
2942 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2943 } else if (rs == 0 && rt != 0) {
2944 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2945 } else if (rs != 0 && rt == 0) {
2946 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2947 } else {
2948 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2949 }
6af0bf9c
FB
2950 opn = "nor";
2951 break;
2952 case OPC_OR:
460f00c4
AJ
2953 if (likely(rs != 0 && rt != 0)) {
2954 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2955 } else if (rs == 0 && rt != 0) {
2956 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2957 } else if (rs != 0 && rt == 0) {
2958 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2959 } else {
2960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2961 }
6af0bf9c
FB
2962 opn = "or";
2963 break;
2964 case OPC_XOR:
460f00c4
AJ
2965 if (likely(rs != 0 && rt != 0)) {
2966 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2967 } else if (rs == 0 && rt != 0) {
2968 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2969 } else if (rs != 0 && rt == 0) {
2970 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2971 } else {
2972 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2973 }
6af0bf9c
FB
2974 opn = "xor";
2975 break;
460f00c4 2976 }
2abf314d 2977 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2978 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2979}
2980
2981/* Set on lower than */
d75c135e 2982static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2983 int rd, int rs, int rt)
460f00c4
AJ
2984{
2985 const char *opn = "slt";
2986 TCGv t0, t1;
2987
2988 if (rd == 0) {
2989 /* If no destination, treat it as a NOP. */
2990 MIPS_DEBUG("NOP");
2991 return;
2992 }
2993
2994 t0 = tcg_temp_new();
2995 t1 = tcg_temp_new();
2996 gen_load_gpr(t0, rs);
2997 gen_load_gpr(t1, rt);
2998 switch (opc) {
2999 case OPC_SLT:
e68dd28f 3000 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 3001 opn = "slt";
6af0bf9c 3002 break;
460f00c4 3003 case OPC_SLTU:
e68dd28f 3004 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3005 opn = "sltu";
3006 break;
3007 }
2abf314d 3008 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
3009 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3010 tcg_temp_free(t0);
3011 tcg_temp_free(t1);
3012}
20c4c97c 3013
460f00c4 3014/* Shifts */
d75c135e
AJ
3015static void gen_shift(DisasContext *ctx, uint32_t opc,
3016 int rd, int rs, int rt)
460f00c4
AJ
3017{
3018 const char *opn = "shifts";
3019 TCGv t0, t1;
20c4c97c 3020
460f00c4
AJ
3021 if (rd == 0) {
3022 /* If no destination, treat it as a NOP.
3023 For add & sub, we must generate the overflow exception when needed. */
3024 MIPS_DEBUG("NOP");
3025 return;
3026 }
3027
3028 t0 = tcg_temp_new();
3029 t1 = tcg_temp_new();
3030 gen_load_gpr(t0, rs);
3031 gen_load_gpr(t1, rt);
3032 switch (opc) {
6af0bf9c 3033 case OPC_SLLV:
78723684
TS
3034 tcg_gen_andi_tl(t0, t0, 0x1f);
3035 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3036 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3037 opn = "sllv";
3038 break;
3039 case OPC_SRAV:
78723684 3040 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3041 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3042 opn = "srav";
3043 break;
3044 case OPC_SRLV:
ea63e2c3
NF
3045 tcg_gen_ext32u_tl(t1, t1);
3046 tcg_gen_andi_tl(t0, t0, 0x1f);
3047 tcg_gen_shr_tl(t0, t1, t0);
3048 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3049 opn = "srlv";
3050 break;
3051 case OPC_ROTRV:
3052 {
3053 TCGv_i32 t2 = tcg_temp_new_i32();
3054 TCGv_i32 t3 = tcg_temp_new_i32();
3055
3056 tcg_gen_trunc_tl_i32(t2, t0);
3057 tcg_gen_trunc_tl_i32(t3, t1);
3058 tcg_gen_andi_i32(t2, t2, 0x1f);
3059 tcg_gen_rotr_i32(t2, t3, t2);
3060 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3061 tcg_temp_free_i32(t2);
3062 tcg_temp_free_i32(t3);
3063 opn = "rotrv";
5a63bcb2 3064 }
7a387fff 3065 break;
d26bc211 3066#if defined(TARGET_MIPS64)
7a387fff 3067 case OPC_DSLLV:
78723684 3068 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3069 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3070 opn = "dsllv";
3071 break;
3072 case OPC_DSRAV:
78723684 3073 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3074 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3075 opn = "dsrav";
3076 break;
3077 case OPC_DSRLV:
ea63e2c3
NF
3078 tcg_gen_andi_tl(t0, t0, 0x3f);
3079 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3080 opn = "dsrlv";
3081 break;
3082 case OPC_DROTRV:
3083 tcg_gen_andi_tl(t0, t0, 0x3f);
3084 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3085 opn = "drotrv";
6af0bf9c 3086 break;
7a387fff 3087#endif
6af0bf9c 3088 }
2abf314d 3089 (void)opn; /* avoid a compiler warning */
6af0bf9c 3090 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3091 tcg_temp_free(t0);
3092 tcg_temp_free(t1);
6af0bf9c
FB
3093}
3094
3095/* Arithmetic on HI/LO registers */
26135ead 3096static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3097{
923617a3 3098 const char *opn = "hilo";
6af0bf9c
FB
3099
3100 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3101 /* Treat as NOP. */
6af0bf9c 3102 MIPS_DEBUG("NOP");
a1f6684d 3103 return;
6af0bf9c 3104 }
4133498f 3105
4133498f
JL
3106 if (acc != 0) {
3107 check_dsp(ctx);
3108 }
3109
6af0bf9c
FB
3110 switch (opc) {
3111 case OPC_MFHI:
4133498f
JL
3112#if defined(TARGET_MIPS64)
3113 if (acc != 0) {
3114 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3115 } else
3116#endif
3117 {
3118 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3119 }
6af0bf9c
FB
3120 opn = "mfhi";
3121 break;
3122 case OPC_MFLO:
4133498f
JL
3123#if defined(TARGET_MIPS64)
3124 if (acc != 0) {
3125 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3126 } else
3127#endif
3128 {
3129 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3130 }
6af0bf9c
FB
3131 opn = "mflo";
3132 break;
3133 case OPC_MTHI:
4133498f
JL
3134 if (reg != 0) {
3135#if defined(TARGET_MIPS64)
3136 if (acc != 0) {
3137 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3138 } else
3139#endif
3140 {
3141 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3142 }
3143 } else {
3144 tcg_gen_movi_tl(cpu_HI[acc], 0);
3145 }
6af0bf9c
FB
3146 opn = "mthi";
3147 break;
3148 case OPC_MTLO:
4133498f
JL
3149 if (reg != 0) {
3150#if defined(TARGET_MIPS64)
3151 if (acc != 0) {
3152 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3153 } else
3154#endif
3155 {
3156 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3157 }
3158 } else {
3159 tcg_gen_movi_tl(cpu_LO[acc], 0);
3160 }
6af0bf9c
FB
3161 opn = "mtlo";
3162 break;
6af0bf9c 3163 }
2abf314d 3164 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3165 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3166}
3167
d4ea6acd
LA
3168static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3169 TCGMemOp memop)
3170{
3171 TCGv t0 = tcg_const_tl(addr);
3172 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3173 gen_store_gpr(t0, reg);
3174 tcg_temp_free(t0);
3175}
3176
3177static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3178{
3179 target_long offset;
3180 target_long addr;
3181
3182 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3183 case OPC_ADDIUPC:
3184 if (rs != 0) {
3185 offset = sextract32(ctx->opcode << 2, 0, 21);
3186 addr = addr_add(ctx, ctx->pc, offset);
3187 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3188 }
3189 break;
3190 case R6_OPC_LWPC:
3191 offset = sextract32(ctx->opcode << 2, 0, 21);
3192 addr = addr_add(ctx, ctx->pc, offset);
3193 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3194 break;
3195#if defined(TARGET_MIPS64)
3196 case OPC_LWUPC:
3197 check_mips_64(ctx);
3198 offset = sextract32(ctx->opcode << 2, 0, 21);
3199 addr = addr_add(ctx, ctx->pc, offset);
3200 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3201 break;
3202#endif
3203 default:
3204 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3205 case OPC_AUIPC:
3206 if (rs != 0) {
3207 offset = imm << 16;
3208 addr = addr_add(ctx, ctx->pc, offset);
3209 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3210 }
3211 break;
3212 case OPC_ALUIPC:
3213 if (rs != 0) {
3214 offset = imm << 16;
3215 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3216 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3217 }
3218 break;
3219#if defined(TARGET_MIPS64)
3220 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3221 case R6_OPC_LDPC + (1 << 16):
3222 case R6_OPC_LDPC + (2 << 16):
3223 case R6_OPC_LDPC + (3 << 16):
3224 check_mips_64(ctx);
3225 offset = sextract32(ctx->opcode << 3, 0, 21);
3226 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3227 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3228 break;
3229#endif
3230 default:
3231 MIPS_INVAL("OPC_PCREL");
3232 generate_exception(ctx, EXCP_RI);
3233 break;
3234 }
3235 break;
3236 }
3237}
3238
b42ee5e1
LA
3239static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3240{
3241 const char *opn = "r6 mul/div";
3242 TCGv t0, t1;
3243
3244 if (rd == 0) {
3245 /* Treat as NOP. */
3246 MIPS_DEBUG("NOP");
3247 return;
3248 }
3249
3250 t0 = tcg_temp_new();
3251 t1 = tcg_temp_new();
3252
3253 gen_load_gpr(t0, rs);
3254 gen_load_gpr(t1, rt);
3255
3256 switch (opc) {
3257 case R6_OPC_DIV:
3258 {
3259 TCGv t2 = tcg_temp_new();
3260 TCGv t3 = tcg_temp_new();
3261 tcg_gen_ext32s_tl(t0, t0);
3262 tcg_gen_ext32s_tl(t1, t1);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3271 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3272 tcg_temp_free(t3);
3273 tcg_temp_free(t2);
3274 }
3275 opn = "div";
3276 break;
3277 case R6_OPC_MOD:
3278 {
3279 TCGv t2 = tcg_temp_new();
3280 TCGv t3 = tcg_temp_new();
3281 tcg_gen_ext32s_tl(t0, t0);
3282 tcg_gen_ext32s_tl(t1, t1);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3285 tcg_gen_and_tl(t2, t2, t3);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3287 tcg_gen_or_tl(t2, t2, t3);
3288 tcg_gen_movi_tl(t3, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3290 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3291 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3292 tcg_temp_free(t3);
3293 tcg_temp_free(t2);
3294 }
3295 opn = "mod";
3296 break;
3297 case R6_OPC_DIVU:
3298 {
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_ext32u_tl(t0, t0);
3302 tcg_gen_ext32u_tl(t1, t1);
3303 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3304 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3305 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3308 }
3309 opn = "divu";
3310 break;
3311 case R6_OPC_MODU:
3312 {
3313 TCGv t2 = tcg_const_tl(0);
3314 TCGv t3 = tcg_const_tl(1);
3315 tcg_gen_ext32u_tl(t0, t0);
3316 tcg_gen_ext32u_tl(t1, t1);
3317 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3319 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3320 tcg_temp_free(t3);
3321 tcg_temp_free(t2);
3322 }
3323 opn = "modu";
3324 break;
3325 case R6_OPC_MUL:
3326 {
3327 TCGv_i32 t2 = tcg_temp_new_i32();
3328 TCGv_i32 t3 = tcg_temp_new_i32();
3329 tcg_gen_trunc_tl_i32(t2, t0);
3330 tcg_gen_trunc_tl_i32(t3, t1);
3331 tcg_gen_mul_i32(t2, t2, t3);
3332 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3333 tcg_temp_free_i32(t2);
3334 tcg_temp_free_i32(t3);
3335 }
3336 opn = "mul";
3337 break;
3338 case R6_OPC_MUH:
3339 {
3340 TCGv_i32 t2 = tcg_temp_new_i32();
3341 TCGv_i32 t3 = tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2, t0);
3343 tcg_gen_trunc_tl_i32(t3, t1);
3344 tcg_gen_muls2_i32(t2, t3, t2, t3);
3345 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346 tcg_temp_free_i32(t2);
3347 tcg_temp_free_i32(t3);
3348 }
3349 opn = "muh";
3350 break;
3351 case R6_OPC_MULU:
3352 {
3353 TCGv_i32 t2 = tcg_temp_new_i32();
3354 TCGv_i32 t3 = tcg_temp_new_i32();
3355 tcg_gen_trunc_tl_i32(t2, t0);
3356 tcg_gen_trunc_tl_i32(t3, t1);
3357 tcg_gen_mul_i32(t2, t2, t3);
3358 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3359 tcg_temp_free_i32(t2);
3360 tcg_temp_free_i32(t3);
3361 }
3362 opn = "mulu";
3363 break;
3364 case R6_OPC_MUHU:
3365 {
3366 TCGv_i32 t2 = tcg_temp_new_i32();
3367 TCGv_i32 t3 = tcg_temp_new_i32();
3368 tcg_gen_trunc_tl_i32(t2, t0);
3369 tcg_gen_trunc_tl_i32(t3, t1);
3370 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3371 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3372 tcg_temp_free_i32(t2);
3373 tcg_temp_free_i32(t3);
3374 }
3375 opn = "muhu";
3376 break;
3377#if defined(TARGET_MIPS64)
3378 case R6_OPC_DDIV:
3379 {
3380 TCGv t2 = tcg_temp_new();
3381 TCGv t3 = tcg_temp_new();
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3384 tcg_gen_and_tl(t2, t2, t3);
3385 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3386 tcg_gen_or_tl(t2, t2, t3);
3387 tcg_gen_movi_tl(t3, 0);
3388 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3389 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3390 tcg_temp_free(t3);
3391 tcg_temp_free(t2);
3392 }
3393 opn = "ddiv";
3394 break;
3395 case R6_OPC_DMOD:
3396 {
3397 TCGv t2 = tcg_temp_new();
3398 TCGv t3 = tcg_temp_new();
3399 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3400 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3401 tcg_gen_and_tl(t2, t2, t3);
3402 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3403 tcg_gen_or_tl(t2, t2, t3);
3404 tcg_gen_movi_tl(t3, 0);
3405 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3406 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
3409 }
3410 opn = "dmod";
3411 break;
3412 case R6_OPC_DDIVU:
3413 {
3414 TCGv t2 = tcg_const_tl(0);
3415 TCGv t3 = tcg_const_tl(1);
3416 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3417 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3418 tcg_temp_free(t3);
3419 tcg_temp_free(t2);
3420 }
3421 opn = "ddivu";
3422 break;
3423 case R6_OPC_DMODU:
3424 {
3425 TCGv t2 = tcg_const_tl(0);
3426 TCGv t3 = tcg_const_tl(1);
3427 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3428 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3429 tcg_temp_free(t3);
3430 tcg_temp_free(t2);
3431 }
3432 opn = "dmodu";
3433 break;
3434 case R6_OPC_DMUL:
3435 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3436 opn = "dmul";
3437 break;
3438 case R6_OPC_DMUH:
3439 {
3440 TCGv t2 = tcg_temp_new();
3441 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3442 tcg_temp_free(t2);
3443 }
3444 opn = "dmuh";
3445 break;
3446 case R6_OPC_DMULU:
3447 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3448 opn = "dmulu";
3449 break;
3450 case R6_OPC_DMUHU:
3451 {
3452 TCGv t2 = tcg_temp_new();
3453 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3454 tcg_temp_free(t2);
3455 }
3456 opn = "dmuhu";
3457 break;
3458#endif
3459 default:
3460 MIPS_INVAL(opn);
3461 generate_exception(ctx, EXCP_RI);
3462 goto out;
3463 }
3464 (void)opn; /* avoid a compiler warning */
3465 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3466 out:
3467 tcg_temp_free(t0);
3468 tcg_temp_free(t1);
3469}
3470
26135ead
RS
3471static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3472 int acc, int rs, int rt)
6af0bf9c 3473{
923617a3 3474 const char *opn = "mul/div";
d45f89f4
AJ
3475 TCGv t0, t1;
3476
51127181
AJ
3477 t0 = tcg_temp_new();
3478 t1 = tcg_temp_new();
6af0bf9c 3479
78723684
TS
3480 gen_load_gpr(t0, rs);
3481 gen_load_gpr(t1, rt);
51127181 3482
26135ead
RS
3483 if (acc != 0) {
3484 check_dsp(ctx);
3485 }
3486
6af0bf9c
FB
3487 switch (opc) {
3488 case OPC_DIV:
48d38ca5 3489 {
51127181
AJ
3490 TCGv t2 = tcg_temp_new();
3491 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3492 tcg_gen_ext32s_tl(t0, t0);
3493 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3494 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3495 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3496 tcg_gen_and_tl(t2, t2, t3);
3497 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3498 tcg_gen_or_tl(t2, t2, t3);
3499 tcg_gen_movi_tl(t3, 0);
3500 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3501 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3502 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3503 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3504 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3505 tcg_temp_free(t3);
3506 tcg_temp_free(t2);
48d38ca5 3507 }
6af0bf9c
FB
3508 opn = "div";
3509 break;
3510 case OPC_DIVU:
48d38ca5 3511 {
51127181
AJ
3512 TCGv t2 = tcg_const_tl(0);
3513 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3514 tcg_gen_ext32u_tl(t0, t0);
3515 tcg_gen_ext32u_tl(t1, t1);
51127181 3516 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3517 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3518 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3519 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3520 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3521 tcg_temp_free(t3);
3522 tcg_temp_free(t2);
48d38ca5 3523 }
6af0bf9c
FB
3524 opn = "divu";
3525 break;
3526 case OPC_MULT:
214c465f 3527 {
ce1dd5d1
RH
3528 TCGv_i32 t2 = tcg_temp_new_i32();
3529 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3530 tcg_gen_trunc_tl_i32(t2, t0);
3531 tcg_gen_trunc_tl_i32(t3, t1);
3532 tcg_gen_muls2_i32(t2, t3, t2, t3);
3533 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3534 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3535 tcg_temp_free_i32(t2);
3536 tcg_temp_free_i32(t3);
214c465f 3537 }
6af0bf9c
FB
3538 opn = "mult";
3539 break;
3540 case OPC_MULTU:
214c465f 3541 {
ce1dd5d1
RH
3542 TCGv_i32 t2 = tcg_temp_new_i32();
3543 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3544 tcg_gen_trunc_tl_i32(t2, t0);
3545 tcg_gen_trunc_tl_i32(t3, t1);
3546 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3547 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3548 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3549 tcg_temp_free_i32(t2);
3550 tcg_temp_free_i32(t3);
214c465f 3551 }
6af0bf9c
FB
3552 opn = "multu";
3553 break;
d26bc211 3554#if defined(TARGET_MIPS64)
7a387fff 3555 case OPC_DDIV:
48d38ca5 3556 {
51127181
AJ
3557 TCGv t2 = tcg_temp_new();
3558 TCGv t3 = tcg_temp_new();
3559 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3560 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3561 tcg_gen_and_tl(t2, t2, t3);
3562 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3563 tcg_gen_or_tl(t2, t2, t3);
3564 tcg_gen_movi_tl(t3, 0);
3565 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3566 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3567 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3568 tcg_temp_free(t3);
3569 tcg_temp_free(t2);
48d38ca5 3570 }
7a387fff
TS
3571 opn = "ddiv";
3572 break;
3573 case OPC_DDIVU:
48d38ca5 3574 {
51127181
AJ
3575 TCGv t2 = tcg_const_tl(0);
3576 TCGv t3 = tcg_const_tl(1);
3577 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3578 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3579 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3580 tcg_temp_free(t3);
3581 tcg_temp_free(t2);
48d38ca5 3582 }
7a387fff
TS
3583 opn = "ddivu";
3584 break;
3585 case OPC_DMULT:
26135ead 3586 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3587 opn = "dmult";
3588 break;
3589 case OPC_DMULTU:
26135ead 3590 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3591 opn = "dmultu";
3592 break;
3593#endif
6af0bf9c 3594 case OPC_MADD:
214c465f 3595 {
d45f89f4
AJ
3596 TCGv_i64 t2 = tcg_temp_new_i64();
3597 TCGv_i64 t3 = tcg_temp_new_i64();
3598
3599 tcg_gen_ext_tl_i64(t2, t0);
3600 tcg_gen_ext_tl_i64(t3, t1);
3601 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3602 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3603 tcg_gen_add_i64(t2, t2, t3);
3604 tcg_temp_free_i64(t3);
3605 tcg_gen_trunc_i64_tl(t0, t2);
3606 tcg_gen_shri_i64(t2, t2, 32);
3607 tcg_gen_trunc_i64_tl(t1, t2);
3608 tcg_temp_free_i64(t2);
4133498f
JL
3609 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3610 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3611 }
6af0bf9c
FB
3612 opn = "madd";
3613 break;
3614 case OPC_MADDU:
4133498f 3615 {
d45f89f4
AJ
3616 TCGv_i64 t2 = tcg_temp_new_i64();
3617 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3618
78723684
TS
3619 tcg_gen_ext32u_tl(t0, t0);
3620 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3621 tcg_gen_extu_tl_i64(t2, t0);
3622 tcg_gen_extu_tl_i64(t3, t1);
3623 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3624 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3625 tcg_gen_add_i64(t2, t2, t3);
3626 tcg_temp_free_i64(t3);
3627 tcg_gen_trunc_i64_tl(t0, t2);
3628 tcg_gen_shri_i64(t2, t2, 32);
3629 tcg_gen_trunc_i64_tl(t1, t2);
3630 tcg_temp_free_i64(t2);
4133498f
JL
3631 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3632 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3633 }
6af0bf9c
FB
3634 opn = "maddu";
3635 break;
3636 case OPC_MSUB:
214c465f 3637 {
d45f89f4
AJ
3638 TCGv_i64 t2 = tcg_temp_new_i64();
3639 TCGv_i64 t3 = tcg_temp_new_i64();
3640
3641 tcg_gen_ext_tl_i64(t2, t0);
3642 tcg_gen_ext_tl_i64(t3, t1);
3643 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3644 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3645 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3646 tcg_temp_free_i64(t3);
3647 tcg_gen_trunc_i64_tl(t0, t2);
3648 tcg_gen_shri_i64(t2, t2, 32);
3649 tcg_gen_trunc_i64_tl(t1, t2);
3650 tcg_temp_free_i64(t2);
4133498f
JL
3651 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3652 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3653 }
6af0bf9c
FB
3654 opn = "msub";
3655 break;
3656 case OPC_MSUBU:
214c465f 3657 {
d45f89f4
AJ
3658 TCGv_i64 t2 = tcg_temp_new_i64();
3659 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3660
78723684
TS
3661 tcg_gen_ext32u_tl(t0, t0);
3662 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3663 tcg_gen_extu_tl_i64(t2, t0);
3664 tcg_gen_extu_tl_i64(t3, t1);
3665 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3666 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3667 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3668 tcg_temp_free_i64(t3);
3669 tcg_gen_trunc_i64_tl(t0, t2);
3670 tcg_gen_shri_i64(t2, t2, 32);
3671 tcg_gen_trunc_i64_tl(t1, t2);
3672 tcg_temp_free_i64(t2);
4133498f
JL
3673 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3674 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3675 }
6af0bf9c
FB
3676 opn = "msubu";
3677 break;
3678 default:
923617a3 3679 MIPS_INVAL(opn);
6af0bf9c 3680 generate_exception(ctx, EXCP_RI);
78723684 3681 goto out;
6af0bf9c 3682 }
2abf314d 3683 (void)opn; /* avoid a compiler warning */
6af0bf9c 3684 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3685 out:
3686 tcg_temp_free(t0);
3687 tcg_temp_free(t1);
6af0bf9c
FB
3688}
3689
e9c71dd1
TS
3690static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3691 int rd, int rs, int rt)
3692{
3693 const char *opn = "mul vr54xx";
f157bfe1
AJ
3694 TCGv t0 = tcg_temp_new();
3695 TCGv t1 = tcg_temp_new();
e9c71dd1 3696
6c5c1e20
TS
3697 gen_load_gpr(t0, rs);
3698 gen_load_gpr(t1, rt);
e9c71dd1
TS
3699
3700 switch (opc) {
3701 case OPC_VR54XX_MULS:
895c2d04 3702 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3703 opn = "muls";
6958549d 3704 break;
e9c71dd1 3705 case OPC_VR54XX_MULSU:
895c2d04 3706 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3707 opn = "mulsu";
6958549d 3708 break;
e9c71dd1 3709 case OPC_VR54XX_MACC:
895c2d04 3710 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3711 opn = "macc";
6958549d 3712 break;
e9c71dd1 3713 case OPC_VR54XX_MACCU:
895c2d04 3714 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3715 opn = "maccu";
6958549d 3716 break;
e9c71dd1 3717 case OPC_VR54XX_MSAC:
895c2d04 3718 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3719 opn = "msac";
6958549d 3720 break;
e9c71dd1 3721 case OPC_VR54XX_MSACU:
895c2d04 3722 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3723 opn = "msacu";
6958549d 3724 break;
e9c71dd1 3725 case OPC_VR54XX_MULHI:
895c2d04 3726 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3727 opn = "mulhi";
6958549d 3728 break;
e9c71dd1 3729 case OPC_VR54XX_MULHIU:
895c2d04 3730 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3731 opn = "mulhiu";
6958549d 3732 break;
e9c71dd1 3733 case OPC_VR54XX_MULSHI:
895c2d04 3734 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3735 opn = "mulshi";
6958549d 3736 break;
e9c71dd1 3737 case OPC_VR54XX_MULSHIU:
895c2d04 3738 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3739 opn = "mulshiu";
6958549d 3740 break;
e9c71dd1 3741 case OPC_VR54XX_MACCHI:
895c2d04 3742 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3743 opn = "macchi";
6958549d 3744 break;
e9c71dd1 3745 case OPC_VR54XX_MACCHIU:
895c2d04 3746 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3747 opn = "macchiu";
6958549d 3748 break;
e9c71dd1 3749 case OPC_VR54XX_MSACHI:
895c2d04 3750 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3751 opn = "msachi";
6958549d 3752 break;
e9c71dd1 3753 case OPC_VR54XX_MSACHIU:
895c2d04 3754 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3755 opn = "msachiu";
6958549d 3756 break;
e9c71dd1
TS
3757 default:
3758 MIPS_INVAL("mul vr54xx");
3759 generate_exception(ctx, EXCP_RI);
6c5c1e20 3760 goto out;
e9c71dd1 3761 }
6c5c1e20 3762 gen_store_gpr(t0, rd);
2abf314d 3763 (void)opn; /* avoid a compiler warning */
e9c71dd1 3764 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3765
3766 out:
3767 tcg_temp_free(t0);
3768 tcg_temp_free(t1);
e9c71dd1
TS
3769}
3770
7a387fff 3771static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3772 int rd, int rs)
3773{
923617a3 3774 const char *opn = "CLx";
20e1fb52 3775 TCGv t0;
6c5c1e20 3776
6af0bf9c 3777 if (rd == 0) {
ead9360e 3778 /* Treat as NOP. */
6af0bf9c 3779 MIPS_DEBUG("NOP");
20e1fb52 3780 return;
6af0bf9c 3781 }
20e1fb52 3782 t0 = tcg_temp_new();
6c5c1e20 3783 gen_load_gpr(t0, rs);
6af0bf9c
FB
3784 switch (opc) {
3785 case OPC_CLO:
4267d3e6 3786 case R6_OPC_CLO:
20e1fb52 3787 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3788 opn = "clo";
3789 break;
3790 case OPC_CLZ:
4267d3e6 3791 case R6_OPC_CLZ:
20e1fb52 3792 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3793 opn = "clz";
3794 break;
d26bc211 3795#if defined(TARGET_MIPS64)
7a387fff 3796 case OPC_DCLO:
4267d3e6 3797 case R6_OPC_DCLO:
20e1fb52 3798 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3799 opn = "dclo";
3800 break;
3801 case OPC_DCLZ:
4267d3e6 3802 case R6_OPC_DCLZ:
20e1fb52 3803 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3804 opn = "dclz";
3805 break;
3806#endif
6af0bf9c 3807 }
2abf314d 3808 (void)opn; /* avoid a compiler warning */
6af0bf9c 3809 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3810 tcg_temp_free(t0);
6af0bf9c
FB
3811}
3812
161f85e6 3813/* Godson integer instructions */
bd277fa1
RH
3814static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3815 int rd, int rs, int rt)
161f85e6
AJ
3816{
3817 const char *opn = "loongson";
3818 TCGv t0, t1;
3819
3820 if (rd == 0) {
3821 /* Treat as NOP. */
3822 MIPS_DEBUG("NOP");
3823 return;
3824 }
3825
3826 switch (opc) {
3827 case OPC_MULT_G_2E:
3828 case OPC_MULT_G_2F:
3829 case OPC_MULTU_G_2E:
3830 case OPC_MULTU_G_2F:
3831#if defined(TARGET_MIPS64)
3832 case OPC_DMULT_G_2E:
3833 case OPC_DMULT_G_2F:
3834 case OPC_DMULTU_G_2E:
3835 case OPC_DMULTU_G_2F:
3836#endif
3837 t0 = tcg_temp_new();
3838 t1 = tcg_temp_new();
3839 break;
3840 default:
3841 t0 = tcg_temp_local_new();
3842 t1 = tcg_temp_local_new();
3843 break;
3844 }
3845
3846 gen_load_gpr(t0, rs);
3847 gen_load_gpr(t1, rt);
3848
3849 switch (opc) {
3850 case OPC_MULT_G_2E:
3851 case OPC_MULT_G_2F:
3852 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3853 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3854 opn = "mult.g";
3855 break;
3856 case OPC_MULTU_G_2E:
3857 case OPC_MULTU_G_2F:
3858 tcg_gen_ext32u_tl(t0, t0);
3859 tcg_gen_ext32u_tl(t1, t1);
3860 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3861 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3862 opn = "multu.g";
3863 break;
3864 case OPC_DIV_G_2E:
3865 case OPC_DIV_G_2F:
3866 {
42a268c2
RH
3867 TCGLabel *l1 = gen_new_label();
3868 TCGLabel *l2 = gen_new_label();
3869 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3870 tcg_gen_ext32s_tl(t0, t0);
3871 tcg_gen_ext32s_tl(t1, t1);
3872 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3874 tcg_gen_br(l3);
3875 gen_set_label(l1);
3876 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3877 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3878 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3879 tcg_gen_br(l3);
3880 gen_set_label(l2);
3881 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3882 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3883 gen_set_label(l3);
3884 }
3885 opn = "div.g";
3886 break;
3887 case OPC_DIVU_G_2E:
3888 case OPC_DIVU_G_2F:
3889 {
42a268c2
RH
3890 TCGLabel *l1 = gen_new_label();
3891 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3892 tcg_gen_ext32u_tl(t0, t0);
3893 tcg_gen_ext32u_tl(t1, t1);
3894 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3896 tcg_gen_br(l2);
3897 gen_set_label(l1);
3898 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3899 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3900 gen_set_label(l2);
3901 }
3902 opn = "divu.g";
3903 break;
3904 case OPC_MOD_G_2E:
3905 case OPC_MOD_G_2F:
3906 {
42a268c2
RH
3907 TCGLabel *l1 = gen_new_label();
3908 TCGLabel *l2 = gen_new_label();
3909 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3910 tcg_gen_ext32u_tl(t0, t0);
3911 tcg_gen_ext32u_tl(t1, t1);
3912 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3913 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3915 gen_set_label(l1);
3916 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3917 tcg_gen_br(l3);
3918 gen_set_label(l2);
3919 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3920 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3921 gen_set_label(l3);
3922 }
3923 opn = "mod.g";
3924 break;
3925 case OPC_MODU_G_2E:
3926 case OPC_MODU_G_2F:
3927 {
42a268c2
RH
3928 TCGLabel *l1 = gen_new_label();
3929 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3930 tcg_gen_ext32u_tl(t0, t0);
3931 tcg_gen_ext32u_tl(t1, t1);
3932 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3933 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3934 tcg_gen_br(l2);
3935 gen_set_label(l1);
3936 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3937 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3938 gen_set_label(l2);
3939 }
3940 opn = "modu.g";
3941 break;
3942#if defined(TARGET_MIPS64)
3943 case OPC_DMULT_G_2E:
3944 case OPC_DMULT_G_2F:
3945 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3946 opn = "dmult.g";
3947 break;
3948 case OPC_DMULTU_G_2E:
3949 case OPC_DMULTU_G_2F:
3950 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3951 opn = "dmultu.g";
3952 break;
3953 case OPC_DDIV_G_2E:
3954 case OPC_DDIV_G_2F:
3955 {
42a268c2
RH
3956 TCGLabel *l1 = gen_new_label();
3957 TCGLabel *l2 = gen_new_label();
3958 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3959 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3960 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3961 tcg_gen_br(l3);
3962 gen_set_label(l1);
3963 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3964 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3965 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3966 tcg_gen_br(l3);
3967 gen_set_label(l2);
3968 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3969 gen_set_label(l3);
3970 }
3971 opn = "ddiv.g";
3972 break;
3973 case OPC_DDIVU_G_2E:
3974 case OPC_DDIVU_G_2F:
3975 {
42a268c2
RH
3976 TCGLabel *l1 = gen_new_label();
3977 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3978 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3979 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3980 tcg_gen_br(l2);
3981 gen_set_label(l1);
3982 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3983 gen_set_label(l2);
3984 }
3985 opn = "ddivu.g";
3986 break;
3987 case OPC_DMOD_G_2E:
3988 case OPC_DMOD_G_2F:
3989 {
42a268c2
RH
3990 TCGLabel *l1 = gen_new_label();
3991 TCGLabel *l2 = gen_new_label();
3992 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3993 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3994 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3995 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3996 gen_set_label(l1);
3997 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3998 tcg_gen_br(l3);
3999 gen_set_label(l2);
4000 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4001 gen_set_label(l3);
4002 }
4003 opn = "dmod.g";
4004 break;
4005 case OPC_DMODU_G_2E:
4006 case OPC_DMODU_G_2F:
4007 {
42a268c2
RH
4008 TCGLabel *l1 = gen_new_label();
4009 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4010 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4011 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4012 tcg_gen_br(l2);
4013 gen_set_label(l1);
4014 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4015 gen_set_label(l2);
4016 }
4017 opn = "dmodu.g";
4018 break;
4019#endif
4020 }
4021
2abf314d 4022 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4023 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4024 tcg_temp_free(t0);
4025 tcg_temp_free(t1);
4026}
4027
bd277fa1
RH
4028/* Loongson multimedia instructions */
4029static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4030{
4031 const char *opn = "loongson_cp2";
4032 uint32_t opc, shift_max;
4033 TCGv_i64 t0, t1;
4034
4035 opc = MASK_LMI(ctx->opcode);
4036 switch (opc) {
4037 case OPC_ADD_CP2:
4038 case OPC_SUB_CP2:
4039 case OPC_DADD_CP2:
4040 case OPC_DSUB_CP2:
4041 t0 = tcg_temp_local_new_i64();
4042 t1 = tcg_temp_local_new_i64();
4043 break;
4044 default:
4045 t0 = tcg_temp_new_i64();
4046 t1 = tcg_temp_new_i64();
4047 break;
4048 }
4049
4050 gen_load_fpr64(ctx, t0, rs);
4051 gen_load_fpr64(ctx, t1, rt);
4052
4053#define LMI_HELPER(UP, LO) \
4054 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4055#define LMI_HELPER_1(UP, LO) \
4056 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4057#define LMI_DIRECT(UP, LO, OP) \
4058 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4059
4060 switch (opc) {
4061 LMI_HELPER(PADDSH, paddsh);
4062 LMI_HELPER(PADDUSH, paddush);
4063 LMI_HELPER(PADDH, paddh);
4064 LMI_HELPER(PADDW, paddw);
4065 LMI_HELPER(PADDSB, paddsb);
4066 LMI_HELPER(PADDUSB, paddusb);
4067 LMI_HELPER(PADDB, paddb);
4068
4069 LMI_HELPER(PSUBSH, psubsh);
4070 LMI_HELPER(PSUBUSH, psubush);
4071 LMI_HELPER(PSUBH, psubh);
4072 LMI_HELPER(PSUBW, psubw);
4073 LMI_HELPER(PSUBSB, psubsb);
4074 LMI_HELPER(PSUBUSB, psubusb);
4075 LMI_HELPER(PSUBB, psubb);
4076
4077 LMI_HELPER(PSHUFH, pshufh);
4078 LMI_HELPER(PACKSSWH, packsswh);
4079 LMI_HELPER(PACKSSHB, packsshb);
4080 LMI_HELPER(PACKUSHB, packushb);
4081
4082 LMI_HELPER(PUNPCKLHW, punpcklhw);
4083 LMI_HELPER(PUNPCKHHW, punpckhhw);
4084 LMI_HELPER(PUNPCKLBH, punpcklbh);
4085 LMI_HELPER(PUNPCKHBH, punpckhbh);
4086 LMI_HELPER(PUNPCKLWD, punpcklwd);
4087 LMI_HELPER(PUNPCKHWD, punpckhwd);
4088
4089 LMI_HELPER(PAVGH, pavgh);
4090 LMI_HELPER(PAVGB, pavgb);
4091 LMI_HELPER(PMAXSH, pmaxsh);
4092 LMI_HELPER(PMINSH, pminsh);
4093 LMI_HELPER(PMAXUB, pmaxub);
4094 LMI_HELPER(PMINUB, pminub);
4095
4096 LMI_HELPER(PCMPEQW, pcmpeqw);
4097 LMI_HELPER(PCMPGTW, pcmpgtw);
4098 LMI_HELPER(PCMPEQH, pcmpeqh);
4099 LMI_HELPER(PCMPGTH, pcmpgth);
4100 LMI_HELPER(PCMPEQB, pcmpeqb);
4101 LMI_HELPER(PCMPGTB, pcmpgtb);
4102
4103 LMI_HELPER(PSLLW, psllw);
4104 LMI_HELPER(PSLLH, psllh);
4105 LMI_HELPER(PSRLW, psrlw);
4106 LMI_HELPER(PSRLH, psrlh);
4107 LMI_HELPER(PSRAW, psraw);
4108 LMI_HELPER(PSRAH, psrah);
4109
4110 LMI_HELPER(PMULLH, pmullh);
4111 LMI_HELPER(PMULHH, pmulhh);
4112 LMI_HELPER(PMULHUH, pmulhuh);
4113 LMI_HELPER(PMADDHW, pmaddhw);
4114
4115 LMI_HELPER(PASUBUB, pasubub);
4116 LMI_HELPER_1(BIADD, biadd);
4117 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4118
4119 LMI_DIRECT(PADDD, paddd, add);
4120 LMI_DIRECT(PSUBD, psubd, sub);
4121 LMI_DIRECT(XOR_CP2, xor, xor);
4122 LMI_DIRECT(NOR_CP2, nor, nor);
4123 LMI_DIRECT(AND_CP2, and, and);
4124 LMI_DIRECT(PANDN, pandn, andc);
4125 LMI_DIRECT(OR, or, or);
4126
4127 case OPC_PINSRH_0:
4128 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4129 opn = "pinsrh_0";
4130 break;
4131 case OPC_PINSRH_1:
4132 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4133 opn = "pinsrh_1";
4134 break;
4135 case OPC_PINSRH_2:
4136 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4137 opn = "pinsrh_2";
4138 break;
4139 case OPC_PINSRH_3:
4140 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4141 opn = "pinsrh_3";
4142 break;
4143
4144 case OPC_PEXTRH:
4145 tcg_gen_andi_i64(t1, t1, 3);
4146 tcg_gen_shli_i64(t1, t1, 4);
4147 tcg_gen_shr_i64(t0, t0, t1);
4148 tcg_gen_ext16u_i64(t0, t0);
4149 opn = "pextrh";
4150 break;
4151
4152 case OPC_ADDU_CP2:
4153 tcg_gen_add_i64(t0, t0, t1);
4154 tcg_gen_ext32s_i64(t0, t0);
4155 opn = "addu";
4156 break;
4157 case OPC_SUBU_CP2:
4158 tcg_gen_sub_i64(t0, t0, t1);
4159 tcg_gen_ext32s_i64(t0, t0);
4160 opn = "addu";
4161 break;
4162
4163 case OPC_SLL_CP2:
4164 opn = "sll";
4165 shift_max = 32;
4166 goto do_shift;
4167 case OPC_SRL_CP2:
4168 opn = "srl";
4169 shift_max = 32;
4170 goto do_shift;
4171 case OPC_SRA_CP2:
4172 opn = "sra";
4173 shift_max = 32;
4174 goto do_shift;
4175 case OPC_DSLL_CP2:
4176 opn = "dsll";
4177 shift_max = 64;
4178 goto do_shift;
4179 case OPC_DSRL_CP2:
4180 opn = "dsrl";
4181 shift_max = 64;
4182 goto do_shift;
4183 case OPC_DSRA_CP2:
4184 opn = "dsra";
4185 shift_max = 64;
4186 goto do_shift;
4187 do_shift:
4188 /* Make sure shift count isn't TCG undefined behaviour. */
4189 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4190
4191 switch (opc) {
4192 case OPC_SLL_CP2:
4193 case OPC_DSLL_CP2:
4194 tcg_gen_shl_i64(t0, t0, t1);
4195 break;
4196 case OPC_SRA_CP2:
4197 case OPC_DSRA_CP2:
4198 /* Since SRA is UndefinedResult without sign-extended inputs,
4199 we can treat SRA and DSRA the same. */
4200 tcg_gen_sar_i64(t0, t0, t1);
4201 break;
4202 case OPC_SRL_CP2:
4203 /* We want to shift in zeros for SRL; zero-extend first. */
4204 tcg_gen_ext32u_i64(t0, t0);
4205 /* FALLTHRU */
4206 case OPC_DSRL_CP2:
4207 tcg_gen_shr_i64(t0, t0, t1);
4208 break;
4209 }
4210
4211 if (shift_max == 32) {
4212 tcg_gen_ext32s_i64(t0, t0);
4213 }
4214
4215 /* Shifts larger than MAX produce zero. */
4216 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4217 tcg_gen_neg_i64(t1, t1);
4218 tcg_gen_and_i64(t0, t0, t1);
4219 break;
4220
4221 case OPC_ADD_CP2:
4222 case OPC_DADD_CP2:
4223 {
4224 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4225 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4226
4227 tcg_gen_mov_i64(t2, t0);
4228 tcg_gen_add_i64(t0, t1, t2);
4229 if (opc == OPC_ADD_CP2) {
4230 tcg_gen_ext32s_i64(t0, t0);
4231 }
4232 tcg_gen_xor_i64(t1, t1, t2);
4233 tcg_gen_xor_i64(t2, t2, t0);
4234 tcg_gen_andc_i64(t1, t2, t1);
4235 tcg_temp_free_i64(t2);
4236 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4237 generate_exception(ctx, EXCP_OVERFLOW);
4238 gen_set_label(lab);
4239
4240 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4241 break;
4242 }
4243
4244 case OPC_SUB_CP2:
4245 case OPC_DSUB_CP2:
4246 {
4247 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4248 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4249
4250 tcg_gen_mov_i64(t2, t0);
4251 tcg_gen_sub_i64(t0, t1, t2);
4252 if (opc == OPC_SUB_CP2) {
4253 tcg_gen_ext32s_i64(t0, t0);
4254 }
4255 tcg_gen_xor_i64(t1, t1, t2);
4256 tcg_gen_xor_i64(t2, t2, t0);
4257 tcg_gen_and_i64(t1, t1, t2);
4258 tcg_temp_free_i64(t2);
4259 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4260 generate_exception(ctx, EXCP_OVERFLOW);
4261 gen_set_label(lab);
4262
4263 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4264 break;
4265 }
4266
4267 case OPC_PMULUW:
4268 tcg_gen_ext32u_i64(t0, t0);
4269 tcg_gen_ext32u_i64(t1, t1);
4270 tcg_gen_mul_i64(t0, t0, t1);
4271 opn = "pmuluw";
4272 break;
4273
4274 case OPC_SEQU_CP2:
4275 case OPC_SEQ_CP2:
4276 case OPC_SLTU_CP2:
4277 case OPC_SLT_CP2:
4278 case OPC_SLEU_CP2:
4279 case OPC_SLE_CP2:
4280 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4281 FD field is the CC field? */
4282 default:
4283 MIPS_INVAL(opn);
4284 generate_exception(ctx, EXCP_RI);
4285 return;
4286 }
4287
4288#undef LMI_HELPER
4289#undef LMI_DIRECT
4290
4291 gen_store_fpr64(ctx, t0, rd);
4292
4293 (void)opn; /* avoid a compiler warning */
4294 MIPS_DEBUG("%s %s, %s, %s", opn,
4295 fregnames[rd], fregnames[rs], fregnames[rt]);
4296 tcg_temp_free_i64(t0);
4297 tcg_temp_free_i64(t1);
4298}
4299
6af0bf9c 4300/* Traps */
7a387fff 4301static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4302 int rs, int rt, int16_t imm)
4303{
4304 int cond;
cdc0faa6 4305 TCGv t0 = tcg_temp_new();
1ba74fb8 4306 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4307
4308 cond = 0;
4309 /* Load needed operands */
4310 switch (opc) {
4311 case OPC_TEQ:
4312 case OPC_TGE:
4313 case OPC_TGEU:
4314 case OPC_TLT:
4315 case OPC_TLTU:
4316 case OPC_TNE:
4317 /* Compare two registers */
4318 if (rs != rt) {
be24bb4f
TS
4319 gen_load_gpr(t0, rs);
4320 gen_load_gpr(t1, rt);
6af0bf9c
FB
4321 cond = 1;
4322 }
179e32bb 4323 break;
6af0bf9c
FB
4324 case OPC_TEQI:
4325 case OPC_TGEI:
4326 case OPC_TGEIU:
4327 case OPC_TLTI:
4328 case OPC_TLTIU:
4329 case OPC_TNEI:
4330 /* Compare register to immediate */
4331 if (rs != 0 || imm != 0) {
be24bb4f
TS
4332 gen_load_gpr(t0, rs);
4333 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4334 cond = 1;
4335 }
4336 break;
4337 }
4338 if (cond == 0) {
4339 switch (opc) {
4340 case OPC_TEQ: /* rs == rs */
4341 case OPC_TEQI: /* r0 == 0 */
4342 case OPC_TGE: /* rs >= rs */
4343 case OPC_TGEI: /* r0 >= 0 */
4344 case OPC_TGEU: /* rs >= rs unsigned */
4345 case OPC_TGEIU: /* r0 >= 0 unsigned */
4346 /* Always trap */
cdc0faa6 4347 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4348 break;
4349 case OPC_TLT: /* rs < rs */
4350 case OPC_TLTI: /* r0 < 0 */
4351 case OPC_TLTU: /* rs < rs unsigned */
4352 case OPC_TLTIU: /* r0 < 0 unsigned */
4353 case OPC_TNE: /* rs != rs */
4354 case OPC_TNEI: /* r0 != 0 */
ead9360e 4355 /* Never trap: treat as NOP. */
cdc0faa6 4356 break;
6af0bf9c
FB
4357 }
4358 } else {
42a268c2 4359 TCGLabel *l1 = gen_new_label();
cdc0faa6 4360
6af0bf9c
FB
4361 switch (opc) {
4362 case OPC_TEQ:
4363 case OPC_TEQI:
cdc0faa6 4364 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4365 break;
4366 case OPC_TGE:
4367 case OPC_TGEI:
cdc0faa6 4368 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4369 break;
4370 case OPC_TGEU:
4371 case OPC_TGEIU:
cdc0faa6 4372 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4373 break;
4374 case OPC_TLT:
4375 case OPC_TLTI:
cdc0faa6 4376 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4377 break;
4378 case OPC_TLTU:
4379 case OPC_TLTIU:
cdc0faa6 4380 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4381 break;
4382 case OPC_TNE:
4383 case OPC_TNEI:
cdc0faa6 4384 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4385 break;
6af0bf9c 4386 }
cdc0faa6 4387 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4388 gen_set_label(l1);
4389 }
be24bb4f
TS
4390 tcg_temp_free(t0);
4391 tcg_temp_free(t1);
6af0bf9c
FB
4392}
4393
356265ae 4394static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4395{
6e256c93
FB
4396 TranslationBlock *tb;
4397 tb = ctx->tb;
7b270ef2
NF
4398 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4399 likely(!ctx->singlestep_enabled)) {
57fec1fe 4400 tcg_gen_goto_tb(n);
9b9e4393 4401 gen_save_pc(dest);
8cfd0495 4402 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4403 } else {
9b9e4393 4404 gen_save_pc(dest);
7b270ef2
NF
4405 if (ctx->singlestep_enabled) {
4406 save_cpu_state(ctx, 0);
895c2d04 4407 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4408 }
57fec1fe 4409 tcg_gen_exit_tb(0);
6e256c93 4410 }
c53be334
FB
4411}
4412
6af0bf9c 4413/* Branches (before delay slot) */
7a387fff 4414static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4415 int insn_bytes,
b231c103
YK
4416 int rs, int rt, int32_t offset,
4417 int delayslot_size)
6af0bf9c 4418{
d077b6f7 4419 target_ulong btgt = -1;
3ad4bb2d 4420 int blink = 0;
2fdbad25 4421 int bcond_compute = 0;
1ba74fb8
AJ
4422 TCGv t0 = tcg_temp_new();
4423 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4424
4425 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4426#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4427 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4428 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4429#endif
3ad4bb2d 4430 generate_exception(ctx, EXCP_RI);
6c5c1e20 4431 goto out;
3ad4bb2d 4432 }
6af0bf9c 4433
6af0bf9c
FB
4434 /* Load needed operands */
4435 switch (opc) {
4436 case OPC_BEQ:
4437 case OPC_BEQL:
4438 case OPC_BNE:
4439 case OPC_BNEL:
4440 /* Compare two registers */
4441 if (rs != rt) {
6c5c1e20
TS
4442 gen_load_gpr(t0, rs);
4443 gen_load_gpr(t1, rt);
2fdbad25 4444 bcond_compute = 1;
6af0bf9c 4445 }
7dca4ad0 4446 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4447 break;
4448 case OPC_BGEZ:
4449 case OPC_BGEZAL:
4450 case OPC_BGEZALL:
4451 case OPC_BGEZL:
4452 case OPC_BGTZ:
4453 case OPC_BGTZL:
4454 case OPC_BLEZ:
4455 case OPC_BLEZL:
4456 case OPC_BLTZ:
4457 case OPC_BLTZAL:
4458 case OPC_BLTZALL:
4459 case OPC_BLTZL:
4460 /* Compare to zero */
4461 if (rs != 0) {
6c5c1e20 4462 gen_load_gpr(t0, rs);
2fdbad25 4463 bcond_compute = 1;
6af0bf9c 4464 }
7dca4ad0 4465 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4466 break;
e45a93e2
JL
4467 case OPC_BPOSGE32:
4468#if defined(TARGET_MIPS64)
4469 case OPC_BPOSGE64:
4470 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4471#else
4472 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4473#endif
4474 bcond_compute = 1;
4475 btgt = ctx->pc + insn_bytes + offset;
4476 break;
6af0bf9c
FB
4477 case OPC_J:
4478 case OPC_JAL:
364d4831 4479 case OPC_JALX:
6af0bf9c 4480 /* Jump to immediate */
7dca4ad0 4481 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4482 break;
4483 case OPC_JR:
4484 case OPC_JALR:
4485 /* Jump to register */
7a387fff
TS
4486 if (offset != 0 && offset != 16) {
4487 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4488 others are reserved. */
923617a3 4489 MIPS_INVAL("jump hint");
6af0bf9c 4490 generate_exception(ctx, EXCP_RI);
6c5c1e20 4491 goto out;
6af0bf9c 4492 }
d077b6f7 4493 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4494 break;
4495 default:
4496 MIPS_INVAL("branch/jump");
4497 generate_exception(ctx, EXCP_RI);
6c5c1e20 4498 goto out;
6af0bf9c 4499 }
2fdbad25 4500 if (bcond_compute == 0) {
6af0bf9c
FB
4501 /* No condition to be computed */
4502 switch (opc) {
4503 case OPC_BEQ: /* rx == rx */
4504 case OPC_BEQL: /* rx == rx likely */
4505 case OPC_BGEZ: /* 0 >= 0 */
4506 case OPC_BGEZL: /* 0 >= 0 likely */
4507 case OPC_BLEZ: /* 0 <= 0 */
4508 case OPC_BLEZL: /* 0 <= 0 likely */
4509 /* Always take */
4ad40f36 4510 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4511 MIPS_DEBUG("balways");
4512 break;
4513 case OPC_BGEZAL: /* 0 >= 0 */
4514 case OPC_BGEZALL: /* 0 >= 0 likely */
4515 /* Always take and link */
4516 blink = 31;
4ad40f36 4517 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4518 MIPS_DEBUG("balways and link");
4519 break;
4520 case OPC_BNE: /* rx != rx */
4521 case OPC_BGTZ: /* 0 > 0 */
4522 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4523 /* Treat as NOP. */
6af0bf9c 4524 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4525 goto out;
eeef26cd 4526 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4527 /* Handle as an unconditional branch to get correct delay
4528 slot checking. */
4529 blink = 31;
b231c103 4530 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4531 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4532 MIPS_DEBUG("bnever and link");
3c824109 4533 break;
eeef26cd 4534 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4535 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4536 /* Skip the instruction in the delay slot */
4537 MIPS_DEBUG("bnever, link and skip");
4538 ctx->pc += 4;
6c5c1e20 4539 goto out;
6af0bf9c
FB
4540 case OPC_BNEL: /* rx != rx likely */
4541 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4542 case OPC_BLTZL: /* 0 < 0 likely */
4543 /* Skip the instruction in the delay slot */
4544 MIPS_DEBUG("bnever and skip");
9898128f 4545 ctx->pc += 4;
6c5c1e20 4546 goto out;
6af0bf9c 4547 case OPC_J:
4ad40f36 4548 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4549 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4550 break;
364d4831
NF
4551 case OPC_JALX:
4552 ctx->hflags |= MIPS_HFLAG_BX;
4553 /* Fallthrough */
6af0bf9c
FB
4554 case OPC_JAL:
4555 blink = 31;
4ad40f36 4556 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4557 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4558 break;
4559 case OPC_JR:
4ad40f36 4560 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4561 MIPS_DEBUG("jr %s", regnames[rs]);
4562 break;
4563 case OPC_JALR:
4564 blink = rt;
4ad40f36 4565 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4566 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4567 break;
4568 default:
4569 MIPS_INVAL("branch/jump");
4570 generate_exception(ctx, EXCP_RI);
6c5c1e20 4571 goto out;
6af0bf9c
FB
4572 }
4573 } else {
4574 switch (opc) {
4575 case OPC_BEQ:
e68dd28f 4576 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4577 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4578 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4579 goto not_likely;
4580 case OPC_BEQL:
e68dd28f 4581 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4582 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4583 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4584 goto likely;
4585 case OPC_BNE:
e68dd28f 4586 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4587 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4588 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4589 goto not_likely;
4590 case OPC_BNEL:
e68dd28f 4591 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4592 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4593 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4594 goto likely;
4595 case OPC_BGEZ:
e68dd28f 4596 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4597 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4598 goto not_likely;
4599 case OPC_BGEZL:
e68dd28f 4600 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4601 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4602 goto likely;
4603 case OPC_BGEZAL:
e68dd28f 4604 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4605 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4606 blink = 31;
4607 goto not_likely;
4608 case OPC_BGEZALL:
e68dd28f 4609 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4610 blink = 31;
d077b6f7 4611 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4612 goto likely;
4613 case OPC_BGTZ:
e68dd28f 4614 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4615 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4616 goto not_likely;
4617 case OPC_BGTZL:
e68dd28f 4618 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4619 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4620 goto likely;
4621 case OPC_BLEZ:
e68dd28f 4622 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4623 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4624 goto not_likely;
4625 case OPC_BLEZL:
e68dd28f 4626 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4627 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4628 goto likely;
4629 case OPC_BLTZ:
e68dd28f 4630 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4631 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4632 goto not_likely;
4633 case OPC_BLTZL:
e68dd28f 4634 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4635 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4636 goto likely;
e45a93e2
JL
4637 case OPC_BPOSGE32:
4638 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4639 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4640 goto not_likely;
4641#if defined(TARGET_MIPS64)
4642 case OPC_BPOSGE64:
4643 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4644 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4645 goto not_likely;
4646#endif
6af0bf9c 4647 case OPC_BLTZAL:
e68dd28f 4648 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4649 blink = 31;
d077b6f7 4650 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4651 not_likely:
4ad40f36 4652 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4653 break;
4654 case OPC_BLTZALL:
e68dd28f 4655 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4656 blink = 31;
d077b6f7 4657 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4658 likely:
4ad40f36 4659 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4660 break;
c53f4a62
TS
4661 default:
4662 MIPS_INVAL("conditional branch/jump");
4663 generate_exception(ctx, EXCP_RI);
6c5c1e20 4664 goto out;
6af0bf9c 4665 }
6af0bf9c 4666 }
923617a3 4667 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4668 blink, ctx->hflags, btgt);
9b9e4393 4669
d077b6f7 4670 ctx->btarget = btgt;
b231c103
YK
4671
4672 switch (delayslot_size) {
4673 case 2:
4674 ctx->hflags |= MIPS_HFLAG_BDS16;
4675 break;
4676 case 4:
4677 ctx->hflags |= MIPS_HFLAG_BDS32;
4678 break;
4679 }
4680
6af0bf9c 4681 if (blink > 0) {
b231c103 4682 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4683 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4684
364d4831 4685 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4686 }
6c5c1e20
TS
4687
4688 out:
364d4831
NF
4689 if (insn_bytes == 2)
4690 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4691 tcg_temp_free(t0);
4692 tcg_temp_free(t1);
6af0bf9c
FB
4693}
4694
7a387fff
TS
4695/* special3 bitfield operations */
4696static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4697 int rs, int lsb, int msb)
7a387fff 4698{
a7812ae4
PB
4699 TCGv t0 = tcg_temp_new();
4700 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4701
4702 gen_load_gpr(t1, rs);
7a387fff
TS
4703 switch (opc) {
4704 case OPC_EXT:
4705 if (lsb + msb > 31)
4706 goto fail;
505ad7c2
AJ
4707 tcg_gen_shri_tl(t0, t1, lsb);
4708 if (msb != 31) {
4709 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4710 } else {
4711 tcg_gen_ext32s_tl(t0, t0);
4712 }
7a387fff 4713 break;
c6d6dd7c 4714#if defined(TARGET_MIPS64)
7a387fff 4715 case OPC_DEXTM:
505ad7c2
AJ
4716 tcg_gen_shri_tl(t0, t1, lsb);
4717 if (msb != 31) {
4718 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4719 }
7a387fff
TS
4720 break;
4721 case OPC_DEXTU:
505ad7c2
AJ
4722 tcg_gen_shri_tl(t0, t1, lsb + 32);
4723 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4724 break;
4725 case OPC_DEXT:
505ad7c2
AJ
4726 tcg_gen_shri_tl(t0, t1, lsb);
4727 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4728 break;
c6d6dd7c 4729#endif
7a387fff
TS
4730 case OPC_INS:
4731 if (lsb > msb)
4732 goto fail;
6c5c1e20 4733 gen_load_gpr(t0, rt);
e0d002f1 4734 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4735 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4736 break;
c6d6dd7c 4737#if defined(TARGET_MIPS64)
7a387fff 4738 case OPC_DINSM:
6c5c1e20 4739 gen_load_gpr(t0, rt);
e0d002f1 4740 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4741 break;
4742 case OPC_DINSU:
6c5c1e20 4743 gen_load_gpr(t0, rt);
e0d002f1 4744 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4745 break;
4746 case OPC_DINS:
6c5c1e20 4747 gen_load_gpr(t0, rt);
e0d002f1 4748 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4749 break;
c6d6dd7c 4750#endif
7a387fff
TS
4751 default:
4752fail:
4753 MIPS_INVAL("bitops");
4754 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4755 tcg_temp_free(t0);
4756 tcg_temp_free(t1);
7a387fff
TS
4757 return;
4758 }
6c5c1e20
TS
4759 gen_store_gpr(t0, rt);
4760 tcg_temp_free(t0);
4761 tcg_temp_free(t1);
7a387fff
TS
4762}
4763
49bcf33c
AJ
4764static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4765{
3a55fa47 4766 TCGv t0;
49bcf33c 4767
3a55fa47
AJ
4768 if (rd == 0) {
4769 /* If no destination, treat it as a NOP. */
4770 MIPS_DEBUG("NOP");
4771 return;
4772 }
4773
4774 t0 = tcg_temp_new();
4775 gen_load_gpr(t0, rt);
49bcf33c
AJ
4776 switch (op2) {
4777 case OPC_WSBH:
3a55fa47
AJ
4778 {
4779 TCGv t1 = tcg_temp_new();
4780
4781 tcg_gen_shri_tl(t1, t0, 8);
4782 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4783 tcg_gen_shli_tl(t0, t0, 8);
4784 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4785 tcg_gen_or_tl(t0, t0, t1);
4786 tcg_temp_free(t1);
4787 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4788 }
49bcf33c
AJ
4789 break;
4790 case OPC_SEB:
3a55fa47 4791 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4792 break;
4793 case OPC_SEH:
3a55fa47 4794 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4795 break;
4796#if defined(TARGET_MIPS64)
4797 case OPC_DSBH:
3a55fa47
AJ
4798 {
4799 TCGv t1 = tcg_temp_new();
4800
4801 tcg_gen_shri_tl(t1, t0, 8);
4802 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4803 tcg_gen_shli_tl(t0, t0, 8);
4804 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4805 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4806 tcg_temp_free(t1);
4807 }
49bcf33c
AJ
4808 break;
4809 case OPC_DSHD:
3a55fa47
AJ
4810 {
4811 TCGv t1 = tcg_temp_new();
4812
4813 tcg_gen_shri_tl(t1, t0, 16);
4814 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4815 tcg_gen_shli_tl(t0, t0, 16);
4816 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4817 tcg_gen_or_tl(t0, t0, t1);
4818 tcg_gen_shri_tl(t1, t0, 32);
4819 tcg_gen_shli_tl(t0, t0, 32);
4820 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4821 tcg_temp_free(t1);
4822 }
49bcf33c
AJ
4823 break;
4824#endif
4825 default:
4826 MIPS_INVAL("bsfhl");
4827 generate_exception(ctx, EXCP_RI);
4828 tcg_temp_free(t0);
49bcf33c
AJ
4829 return;
4830 }
49bcf33c 4831 tcg_temp_free(t0);
49bcf33c
AJ
4832}
4833
f1aa6320 4834#ifndef CONFIG_USER_ONLY
0eaef5aa 4835/* CP0 (MMU and control) */
d9bea114 4836static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4837{
d9bea114 4838 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4839
d9bea114
AJ
4840 tcg_gen_ld_i32(t0, cpu_env, off);
4841 tcg_gen_ext_i32_tl(arg, t0);
4842 tcg_temp_free_i32(t0);
4f57689a
TS
4843}
4844
d9bea114 4845static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4846{
d9bea114
AJ
4847 tcg_gen_ld_tl(arg, cpu_env, off);
4848 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4849}
4850
d9bea114 4851static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4852{
d9bea114 4853 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4854
d9bea114
AJ
4855 tcg_gen_trunc_tl_i32(t0, arg);
4856 tcg_gen_st_i32(t0, cpu_env, off);
4857 tcg_temp_free_i32(t0);
f1aa6320
TS
4858}
4859
d9bea114 4860static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4861{
d9bea114
AJ
4862 tcg_gen_ext32s_tl(arg, arg);
4863 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4864}
4865
e98c0d17
LA
4866static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4867{
4868 if (ctx->insn_flags & ISA_MIPS32R6) {
4869 tcg_gen_movi_tl(arg, 0);
4870 } else {
4871 tcg_gen_movi_tl(arg, ~0);
4872 }
4873}
4874
f31b035a
LA
4875#define CP0_CHECK(c) \
4876 do { \
4877 if (!(c)) { \
4878 goto cp0_unimplemented; \
4879 } \
4880 } while (0)
4881
d75c135e 4882static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4883{
7a387fff 4884 const char *rn = "invalid";
873eb012 4885
e189e748 4886 if (sel != 0)
d75c135e 4887 check_insn(ctx, ISA_MIPS32);
e189e748 4888
873eb012
TS
4889 switch (reg) {
4890 case 0:
7a387fff
TS
4891 switch (sel) {
4892 case 0:
7db13fae 4893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4894 rn = "Index";
4895 break;
4896 case 1:
f31b035a 4897 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4898 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4899 rn = "MVPControl";
ead9360e 4900 break;
7a387fff 4901 case 2:
f31b035a 4902 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4903 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4904 rn = "MVPConf0";
ead9360e 4905 break;
7a387fff 4906 case 3:
f31b035a 4907 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4908 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4909 rn = "MVPConf1";
ead9360e 4910 break;
7a387fff 4911 default:
f31b035a 4912 goto cp0_unimplemented;
7a387fff 4913 }
873eb012
TS
4914 break;
4915 case 1:
7a387fff
TS
4916 switch (sel) {
4917 case 0:
f31b035a 4918 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4919 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4920 rn = "Random";
2423f660 4921 break;
7a387fff 4922 case 1:
f31b035a 4923 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4924 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4925 rn = "VPEControl";
ead9360e 4926 break;
7a387fff 4927 case 2:
f31b035a 4928 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4930 rn = "VPEConf0";
ead9360e 4931 break;
7a387fff 4932 case 3:
f31b035a 4933 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4935 rn = "VPEConf1";
ead9360e 4936 break;
7a387fff 4937 case 4:
f31b035a 4938 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4939 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4940 rn = "YQMask";
ead9360e 4941 break;
7a387fff 4942 case 5:
f31b035a 4943 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4944 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4945 rn = "VPESchedule";
ead9360e 4946 break;
7a387fff 4947 case 6:
f31b035a 4948 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4949 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4950 rn = "VPEScheFBack";
ead9360e 4951 break;
7a387fff 4952 case 7:
f31b035a 4953 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4955 rn = "VPEOpt";
ead9360e 4956 break;
7a387fff 4957 default:
f31b035a 4958 goto cp0_unimplemented;
7a387fff 4959 }
873eb012
TS
4960 break;
4961 case 2:
7a387fff
TS
4962 switch (sel) {
4963 case 0:
7db13fae 4964 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4965#if defined(TARGET_MIPS64)
4966 if (ctx->rxi) {
b435f3f3 4967 /* Move RI/XI fields to bits 31:30 */
7207c7f9 4968 TCGv tmp = tcg_temp_new();
b435f3f3
LA
4969 tcg_gen_shri_tl(tmp, arg, CP0EnLo_XI);
4970 tcg_gen_deposit_tl(arg, arg, tmp, 30, 2);
7207c7f9
LA
4971 tcg_temp_free(tmp);
4972 }
4973#endif
d9bea114 4974 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4975 rn = "EntryLo0";
4976 break;
7a387fff 4977 case 1:
f31b035a 4978 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4979 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4980 rn = "TCStatus";
ead9360e 4981 break;
7a387fff 4982 case 2:
f31b035a 4983 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4984 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4985 rn = "TCBind";
ead9360e 4986 break;
7a387fff 4987 case 3:
f31b035a 4988 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4989 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4990 rn = "TCRestart";
ead9360e 4991 break;
7a387fff 4992 case 4:
f31b035a 4993 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4994 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4995 rn = "TCHalt";
ead9360e 4996 break;
7a387fff 4997 case 5:
f31b035a 4998 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4999 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5000 rn = "TCContext";
ead9360e 5001 break;
7a387fff 5002 case 6:
f31b035a 5003 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5004 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5005 rn = "TCSchedule";
ead9360e 5006 break;
7a387fff 5007 case 7:
f31b035a 5008 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5009 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5010 rn = "TCScheFBack";
ead9360e 5011 break;
7a387fff 5012 default:
f31b035a 5013 goto cp0_unimplemented;
7a387fff 5014 }
873eb012
TS
5015 break;
5016 case 3:
7a387fff
TS
5017 switch (sel) {
5018 case 0:
7db13fae 5019 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
5020#if defined(TARGET_MIPS64)
5021 if (ctx->rxi) {
b435f3f3 5022 /* Move RI/XI fields to bits 31:30 */
7207c7f9 5023 TCGv tmp = tcg_temp_new();
b435f3f3
LA
5024 tcg_gen_shri_tl(tmp, arg, CP0EnLo_XI);
5025 tcg_gen_deposit_tl(arg, arg, tmp, 30, 2);
7207c7f9
LA
5026 tcg_temp_free(tmp);
5027 }
5028#endif
d9bea114 5029 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5030 rn = "EntryLo1";
5031 break;
7a387fff 5032 default:
f31b035a 5033 goto cp0_unimplemented;
1579a72e 5034 }
873eb012
TS
5035 break;
5036 case 4:
7a387fff
TS
5037 switch (sel) {
5038 case 0:
7db13fae 5039 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5040 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5041 rn = "Context";
5042 break;
7a387fff 5043 case 1:
d9bea114 5044// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5045 rn = "ContextConfig";
f31b035a 5046 goto cp0_unimplemented;
2423f660 5047// break;
d279279e 5048 case 2:
f31b035a
LA
5049 CP0_CHECK(ctx->ulri);
5050 tcg_gen_ld32s_tl(arg, cpu_env,
5051 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5052 rn = "UserLocal";
d279279e 5053 break;
7a387fff 5054 default:
f31b035a 5055 goto cp0_unimplemented;
1579a72e 5056 }
873eb012
TS
5057 break;
5058 case 5:
7a387fff
TS
5059 switch (sel) {
5060 case 0:
7db13fae 5061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5062 rn = "PageMask";
5063 break;
7a387fff 5064 case 1:
d75c135e 5065 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5066 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5067 rn = "PageGrain";
5068 break;
7a387fff 5069 default:
f31b035a 5070 goto cp0_unimplemented;
1579a72e 5071 }
873eb012
TS
5072 break;
5073 case 6:
7a387fff
TS
5074 switch (sel) {
5075 case 0:
7db13fae 5076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5077 rn = "Wired";
5078 break;
7a387fff 5079 case 1:
d75c135e 5080 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5082 rn = "SRSConf0";
ead9360e 5083 break;
7a387fff 5084 case 2:
d75c135e 5085 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5087 rn = "SRSConf1";
ead9360e 5088 break;
7a387fff 5089 case 3:
d75c135e 5090 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5092 rn = "SRSConf2";
ead9360e 5093 break;
7a387fff 5094 case 4:
d75c135e 5095 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5097 rn = "SRSConf3";
ead9360e 5098 break;
7a387fff 5099 case 5:
d75c135e 5100 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5102 rn = "SRSConf4";
ead9360e 5103 break;
7a387fff 5104 default:
f31b035a 5105 goto cp0_unimplemented;
1579a72e 5106 }
873eb012 5107 break;
8c0fdd85 5108 case 7:
7a387fff
TS
5109 switch (sel) {
5110 case 0:
d75c135e 5111 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5113 rn = "HWREna";
5114 break;
7a387fff 5115 default:
f31b035a 5116 goto cp0_unimplemented;
1579a72e 5117 }
8c0fdd85 5118 break;
873eb012 5119 case 8:
7a387fff
TS
5120 switch (sel) {
5121 case 0:
7db13fae 5122 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5123 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5124 rn = "BadVAddr";
2423f660 5125 break;
aea14095 5126 case 1:
f31b035a
LA
5127 CP0_CHECK(ctx->bi);
5128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5129 rn = "BadInstr";
aea14095
LA
5130 break;
5131 case 2:
f31b035a
LA
5132 CP0_CHECK(ctx->bp);
5133 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5134 rn = "BadInstrP";
aea14095 5135 break;
7a387fff 5136 default:
f31b035a 5137 goto cp0_unimplemented;
aea14095 5138 }
873eb012
TS
5139 break;
5140 case 9:
7a387fff
TS
5141 switch (sel) {
5142 case 0:
2e70f6ef 5143 /* Mark as an IO operation because we read the time. */
bd79255d 5144 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5145 gen_io_start();
bd79255d 5146 }
895c2d04 5147 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5148 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5149 gen_io_end();
2e70f6ef 5150 }
55807224
EI
5151 /* Break the TB to be able to take timer interrupts immediately
5152 after reading count. */
5153 ctx->bstate = BS_STOP;
2423f660
TS
5154 rn = "Count";
5155 break;
5156 /* 6,7 are implementation dependent */
7a387fff 5157 default:
f31b035a 5158 goto cp0_unimplemented;
2423f660 5159 }
873eb012
TS
5160 break;
5161 case 10:
7a387fff
TS
5162 switch (sel) {
5163 case 0:
7db13fae 5164 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5165 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5166 rn = "EntryHi";
5167 break;
7a387fff 5168 default:
f31b035a 5169 goto cp0_unimplemented;
1579a72e 5170 }
873eb012
TS
5171 break;
5172 case 11:
7a387fff
TS
5173 switch (sel) {
5174 case 0:
7db13fae 5175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5176 rn = "Compare";
5177 break;
5178 /* 6,7 are implementation dependent */
7a387fff 5179 default:
f31b035a 5180 goto cp0_unimplemented;
2423f660 5181 }
873eb012
TS
5182 break;
5183 case 12:
7a387fff
TS
5184 switch (sel) {
5185 case 0:
7db13fae 5186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5187 rn = "Status";
5188 break;
7a387fff 5189 case 1:
d75c135e 5190 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5192 rn = "IntCtl";
5193 break;
7a387fff 5194 case 2:
d75c135e 5195 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5197 rn = "SRSCtl";
5198 break;
7a387fff 5199 case 3:
d75c135e 5200 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5202 rn = "SRSMap";
fd88b6ab 5203 break;
7a387fff 5204 default:
f31b035a 5205 goto cp0_unimplemented;
7a387fff 5206 }
873eb012
TS
5207 break;
5208 case 13:
7a387fff
TS
5209 switch (sel) {
5210 case 0:
7db13fae 5211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5212 rn = "Cause";
5213 break;
7a387fff 5214 default:
f31b035a 5215 goto cp0_unimplemented;
7a387fff 5216 }
873eb012
TS
5217 break;
5218 case 14:
7a387fff
TS
5219 switch (sel) {
5220 case 0:
7db13fae 5221 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5222 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5223 rn = "EPC";
5224 break;
7a387fff 5225 default:
f31b035a 5226 goto cp0_unimplemented;
1579a72e 5227 }
873eb012
TS
5228 break;
5229 case 15:
7a387fff
TS
5230 switch (sel) {
5231 case 0:
7db13fae 5232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5233 rn = "PRid";
5234 break;
7a387fff 5235 case 1:
d75c135e 5236 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5238 rn = "EBase";
5239 break;
7a387fff 5240 default:
f31b035a 5241 goto cp0_unimplemented;
7a387fff 5242 }
873eb012
TS
5243 break;
5244 case 16:
5245 switch (sel) {
5246 case 0:
7db13fae 5247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5248 rn = "Config";
5249 break;
5250 case 1:
7db13fae 5251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5252 rn = "Config1";
5253 break;
7a387fff 5254 case 2:
7db13fae 5255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5256 rn = "Config2";
5257 break;
5258 case 3:
7db13fae 5259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5260 rn = "Config3";
5261 break;
b4160af1
PJ
5262 case 4:
5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5264 rn = "Config4";
5265 break;
b4dd99a3
PJ
5266 case 5:
5267 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5268 rn = "Config5";
5269 break;
e397ee33
TS
5270 /* 6,7 are implementation dependent */
5271 case 6:
7db13fae 5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5273 rn = "Config6";
5274 break;
5275 case 7:
7db13fae 5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5277 rn = "Config7";
5278 break;
873eb012 5279 default:
f31b035a 5280 goto cp0_unimplemented;
873eb012
TS
5281 }
5282 break;
5283 case 17:
7a387fff
TS
5284 switch (sel) {
5285 case 0:
895c2d04 5286 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5287 rn = "LLAddr";
5288 break;
7a387fff 5289 default:
f31b035a 5290 goto cp0_unimplemented;
7a387fff 5291 }
873eb012
TS
5292 break;
5293 case 18:
7a387fff 5294 switch (sel) {
fd88b6ab 5295 case 0 ... 7:
895c2d04 5296 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5297 rn = "WatchLo";
5298 break;
7a387fff 5299 default:
f31b035a 5300 goto cp0_unimplemented;
7a387fff 5301 }
873eb012
TS
5302 break;
5303 case 19:
7a387fff 5304 switch (sel) {
fd88b6ab 5305 case 0 ...7:
895c2d04 5306 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5307 rn = "WatchHi";
5308 break;
7a387fff 5309 default:
f31b035a 5310 goto cp0_unimplemented;
7a387fff 5311 }
873eb012 5312 break;
8c0fdd85 5313 case 20:
7a387fff
TS
5314 switch (sel) {
5315 case 0:
d26bc211 5316#if defined(TARGET_MIPS64)
d75c135e 5317 check_insn(ctx, ISA_MIPS3);
7db13fae 5318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5319 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5320 rn = "XContext";
5321 break;
703eaf37 5322#endif
7a387fff 5323 default:
f31b035a 5324 goto cp0_unimplemented;
7a387fff 5325 }
8c0fdd85
TS
5326 break;
5327 case 21:
7a387fff 5328 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5329 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5330 switch (sel) {
5331 case 0:
7db13fae 5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5333 rn = "Framemask";
5334 break;
7a387fff 5335 default:
f31b035a 5336 goto cp0_unimplemented;
7a387fff 5337 }
8c0fdd85
TS
5338 break;
5339 case 22:
d9bea114 5340 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5341 rn = "'Diagnostic"; /* implementation dependent */
5342 break;
873eb012 5343 case 23:
7a387fff
TS
5344 switch (sel) {
5345 case 0:
895c2d04 5346 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5347 rn = "Debug";
5348 break;
7a387fff 5349 case 1:
d9bea114 5350// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5351 rn = "TraceControl";
5352// break;
7a387fff 5353 case 2:
d9bea114 5354// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5355 rn = "TraceControl2";
5356// break;
7a387fff 5357 case 3:
d9bea114 5358// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5359 rn = "UserTraceData";
5360// break;
7a387fff 5361 case 4:
d9bea114 5362// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5363 rn = "TraceBPC";
5364// break;
7a387fff 5365 default:
f31b035a 5366 goto cp0_unimplemented;
7a387fff 5367 }
873eb012
TS
5368 break;
5369 case 24:
7a387fff
TS
5370 switch (sel) {
5371 case 0:
f0b3f3ae 5372 /* EJTAG support */
7db13fae 5373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5374 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5375 rn = "DEPC";
5376 break;
7a387fff 5377 default:
f31b035a 5378 goto cp0_unimplemented;
7a387fff 5379 }
873eb012 5380 break;
8c0fdd85 5381 case 25:
7a387fff
TS
5382 switch (sel) {
5383 case 0:
7db13fae 5384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5385 rn = "Performance0";
7a387fff
TS
5386 break;
5387 case 1:
d9bea114 5388// gen_helper_mfc0_performance1(arg);
2423f660
TS
5389 rn = "Performance1";
5390// break;
7a387fff 5391 case 2:
d9bea114 5392// gen_helper_mfc0_performance2(arg);
2423f660
TS
5393 rn = "Performance2";
5394// break;
7a387fff 5395 case 3:
d9bea114 5396// gen_helper_mfc0_performance3(arg);
2423f660
TS
5397 rn = "Performance3";
5398// break;
7a387fff 5399 case 4:
d9bea114 5400// gen_helper_mfc0_performance4(arg);
2423f660
TS
5401 rn = "Performance4";
5402// break;
7a387fff 5403 case 5:
d9bea114 5404// gen_helper_mfc0_performance5(arg);
2423f660
TS
5405 rn = "Performance5";
5406// break;
7a387fff 5407 case 6:
d9bea114 5408// gen_helper_mfc0_performance6(arg);
2423f660
TS
5409 rn = "Performance6";
5410// break;
7a387fff 5411 case 7:
d9bea114 5412// gen_helper_mfc0_performance7(arg);
2423f660
TS
5413 rn = "Performance7";
5414// break;
7a387fff 5415 default:
f31b035a 5416 goto cp0_unimplemented;
7a387fff 5417 }
8c0fdd85
TS
5418 break;
5419 case 26:
d9bea114 5420 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5421 rn = "ECC";
5422 break;
8c0fdd85 5423 case 27:
7a387fff 5424 switch (sel) {
7a387fff 5425 case 0 ... 3:
d9bea114 5426 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5427 rn = "CacheErr";
5428 break;
7a387fff 5429 default:
f31b035a 5430 goto cp0_unimplemented;
7a387fff 5431 }
8c0fdd85 5432 break;
873eb012
TS
5433 case 28:
5434 switch (sel) {
5435 case 0:
7a387fff
TS
5436 case 2:
5437 case 4:
5438 case 6:
7db13fae 5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5440 rn = "TagLo";
5441 break;
5442 case 1:
7a387fff
TS
5443 case 3:
5444 case 5:
5445 case 7:
7db13fae 5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5447 rn = "DataLo";
5448 break;
5449 default:
f31b035a 5450 goto cp0_unimplemented;
873eb012
TS
5451 }
5452 break;
8c0fdd85 5453 case 29:
7a387fff
TS
5454 switch (sel) {
5455 case 0:
5456 case 2:
5457 case 4:
5458 case 6:
7db13fae 5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5460 rn = "TagHi";
5461 break;
5462 case 1:
5463 case 3:
5464 case 5:
5465 case 7:
7db13fae 5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5467 rn = "DataHi";
5468 break;
5469 default:
f31b035a 5470 goto cp0_unimplemented;
7a387fff 5471 }
8c0fdd85 5472 break;
873eb012 5473 case 30:
7a387fff
TS
5474 switch (sel) {
5475 case 0:
7db13fae 5476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5477 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5478 rn = "ErrorEPC";
5479 break;
7a387fff 5480 default:
f31b035a 5481 goto cp0_unimplemented;
7a387fff 5482 }
873eb012
TS
5483 break;
5484 case 31:
7a387fff
TS
5485 switch (sel) {
5486 case 0:
f0b3f3ae 5487 /* EJTAG support */
7db13fae 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5489 rn = "DESAVE";
5490 break;
e98c0d17 5491 case 2 ... 7:
f31b035a
LA
5492 CP0_CHECK(ctx->kscrexist & (1 << sel));
5493 tcg_gen_ld_tl(arg, cpu_env,
5494 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5495 tcg_gen_ext32s_tl(arg, arg);
5496 rn = "KScratch";
e98c0d17 5497 break;
7a387fff 5498 default:
f31b035a 5499 goto cp0_unimplemented;
7a387fff 5500 }
873eb012
TS
5501 break;
5502 default:
f31b035a 5503 goto cp0_unimplemented;
873eb012 5504 }
2abf314d 5505 (void)rn; /* avoid a compiler warning */
d12d51d5 5506 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5507 return;
5508
f31b035a 5509cp0_unimplemented:
d12d51d5 5510 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5511 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5512}
5513
d75c135e 5514static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5515{
7a387fff
TS
5516 const char *rn = "invalid";
5517
e189e748 5518 if (sel != 0)
d75c135e 5519 check_insn(ctx, ISA_MIPS32);
e189e748 5520
bd79255d 5521 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5522 gen_io_start();
bd79255d 5523 }
2e70f6ef 5524
8c0fdd85
TS
5525 switch (reg) {
5526 case 0:
7a387fff
TS
5527 switch (sel) {
5528 case 0:
895c2d04 5529 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5530 rn = "Index";
5531 break;
5532 case 1:
f31b035a 5533 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5534 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5535 rn = "MVPControl";
ead9360e 5536 break;
7a387fff 5537 case 2:
f31b035a 5538 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5539 /* ignored */
7a387fff 5540 rn = "MVPConf0";
ead9360e 5541 break;
7a387fff 5542 case 3:
f31b035a 5543 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5544 /* ignored */
7a387fff 5545 rn = "MVPConf1";
ead9360e 5546 break;
7a387fff 5547 default:
f31b035a 5548 goto cp0_unimplemented;
7a387fff 5549 }
8c0fdd85
TS
5550 break;
5551 case 1:
7a387fff
TS
5552 switch (sel) {
5553 case 0:
2423f660 5554 /* ignored */
7a387fff 5555 rn = "Random";
2423f660 5556 break;
7a387fff 5557 case 1:
f31b035a 5558 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5559 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5560 rn = "VPEControl";
ead9360e 5561 break;
7a387fff 5562 case 2:
f31b035a 5563 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5564 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5565 rn = "VPEConf0";
ead9360e 5566 break;
7a387fff 5567 case 3:
f31b035a 5568 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5569 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5570 rn = "VPEConf1";
ead9360e 5571 break;
7a387fff 5572 case 4:
f31b035a 5573 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5574 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5575 rn = "YQMask";
ead9360e 5576 break;
7a387fff 5577 case 5:
f31b035a 5578 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5579 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5580 rn = "VPESchedule";
ead9360e 5581 break;
7a387fff 5582 case 6:
f31b035a 5583 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5584 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5585 rn = "VPEScheFBack";
ead9360e 5586 break;
7a387fff 5587 case 7:
f31b035a 5588 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5589 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5590 rn = "VPEOpt";
ead9360e 5591 break;
7a387fff 5592 default:
f31b035a 5593 goto cp0_unimplemented;
7a387fff 5594 }
8c0fdd85
TS
5595 break;
5596 case 2:
7a387fff
TS
5597 switch (sel) {
5598 case 0:
895c2d04 5599 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5600 rn = "EntryLo0";
5601 break;
7a387fff 5602 case 1:
f31b035a 5603 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5604 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5605 rn = "TCStatus";
ead9360e 5606 break;
7a387fff 5607 case 2:
f31b035a 5608 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5609 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5610 rn = "TCBind";
ead9360e 5611 break;
7a387fff 5612 case 3:
f31b035a 5613 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5614 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5615 rn = "TCRestart";
ead9360e 5616 break;
7a387fff 5617 case 4:
f31b035a 5618 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5619 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5620 rn = "TCHalt";
ead9360e 5621 break;
7a387fff 5622 case 5:
f31b035a 5623 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5624 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5625 rn = "TCContext";
ead9360e 5626 break;
7a387fff 5627 case 6:
f31b035a 5628 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5629 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5630 rn = "TCSchedule";
ead9360e 5631 break;
7a387fff 5632 case 7:
f31b035a 5633 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5634 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5635 rn = "TCScheFBack";
ead9360e 5636 break;
7a387fff 5637 default:
f31b035a 5638 goto cp0_unimplemented;
7a387fff 5639 }
8c0fdd85
TS
5640 break;
5641 case 3:
7a387fff
TS
5642 switch (sel) {
5643 case 0:
895c2d04 5644 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5645 rn = "EntryLo1";
5646 break;
7a387fff 5647 default:
f31b035a 5648 goto cp0_unimplemented;
876d4b07 5649 }
8c0fdd85
TS
5650 break;
5651 case 4:
7a387fff
TS
5652 switch (sel) {
5653 case 0:
895c2d04 5654 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5655 rn = "Context";
5656 break;
7a387fff 5657 case 1:
895c2d04 5658// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5659 rn = "ContextConfig";
f31b035a 5660 goto cp0_unimplemented;
2423f660 5661// break;
d279279e 5662 case 2:
f31b035a
LA
5663 CP0_CHECK(ctx->ulri);
5664 tcg_gen_st_tl(arg, cpu_env,
5665 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5666 rn = "UserLocal";
d279279e 5667 break;
7a387fff 5668 default:
f31b035a 5669 goto cp0_unimplemented;
876d4b07 5670 }
8c0fdd85
TS
5671 break;
5672 case 5:
7a387fff
TS
5673 switch (sel) {
5674 case 0:
895c2d04 5675 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5676 rn = "PageMask";
5677 break;
7a387fff 5678 case 1:
d75c135e 5679 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5680 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5681 rn = "PageGrain";
5682 break;
7a387fff 5683 default:
f31b035a 5684 goto cp0_unimplemented;
876d4b07 5685 }
8c0fdd85
TS
5686 break;
5687 case 6:
7a387fff
TS
5688 switch (sel) {
5689 case 0:
895c2d04 5690 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5691 rn = "Wired";
5692 break;
7a387fff 5693 case 1:
d75c135e 5694 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5695 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5696 rn = "SRSConf0";
ead9360e 5697 break;
7a387fff 5698 case 2:
d75c135e 5699 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5700 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5701 rn = "SRSConf1";
ead9360e 5702 break;
7a387fff 5703 case 3:
d75c135e 5704 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5705 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5706 rn = "SRSConf2";
ead9360e 5707 break;
7a387fff 5708 case 4:
d75c135e 5709 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5710 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5711 rn = "SRSConf3";
ead9360e 5712 break;
7a387fff 5713 case 5:
d75c135e 5714 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5715 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5716 rn = "SRSConf4";
ead9360e 5717 break;
7a387fff 5718 default:
f31b035a 5719 goto cp0_unimplemented;
876d4b07 5720 }
8c0fdd85
TS
5721 break;
5722 case 7:
7a387fff
TS
5723 switch (sel) {
5724 case 0:
d75c135e 5725 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5726 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5727 ctx->bstate = BS_STOP;
2423f660
TS
5728 rn = "HWREna";
5729 break;
7a387fff 5730 default:
f31b035a 5731 goto cp0_unimplemented;
876d4b07 5732 }
8c0fdd85
TS
5733 break;
5734 case 8:
aea14095
LA
5735 switch (sel) {
5736 case 0:
5737 /* ignored */
5738 rn = "BadVAddr";
5739 break;
5740 case 1:
5741 /* ignored */
5742 rn = "BadInstr";
5743 break;
5744 case 2:
5745 /* ignored */
5746 rn = "BadInstrP";
5747 break;
5748 default:
f31b035a 5749 goto cp0_unimplemented;
aea14095 5750 }
8c0fdd85
TS
5751 break;
5752 case 9:
7a387fff
TS
5753 switch (sel) {
5754 case 0:
895c2d04 5755 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5756 rn = "Count";
5757 break;
876d4b07 5758 /* 6,7 are implementation dependent */
7a387fff 5759 default:
f31b035a 5760 goto cp0_unimplemented;
876d4b07 5761 }
8c0fdd85
TS
5762 break;
5763 case 10:
7a387fff
TS
5764 switch (sel) {
5765 case 0:
895c2d04 5766 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5767 rn = "EntryHi";
5768 break;
7a387fff 5769 default:
f31b035a 5770 goto cp0_unimplemented;
876d4b07 5771 }
8c0fdd85
TS
5772 break;
5773 case 11:
7a387fff
TS
5774 switch (sel) {
5775 case 0:
895c2d04 5776 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5777 rn = "Compare";
5778 break;
5779 /* 6,7 are implementation dependent */
7a387fff 5780 default:
f31b035a 5781 goto cp0_unimplemented;
876d4b07 5782 }
8c0fdd85
TS
5783 break;
5784 case 12:
7a387fff
TS
5785 switch (sel) {
5786 case 0:
867abc7e 5787 save_cpu_state(ctx, 1);
895c2d04 5788 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5789 /* BS_STOP isn't good enough here, hflags may have changed. */
5790 gen_save_pc(ctx->pc + 4);
5791 ctx->bstate = BS_EXCP;
2423f660
TS
5792 rn = "Status";
5793 break;
7a387fff 5794 case 1:
d75c135e 5795 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5796 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5797 /* Stop translation as we may have switched the execution mode */
5798 ctx->bstate = BS_STOP;
2423f660
TS
5799 rn = "IntCtl";
5800 break;
7a387fff 5801 case 2:
d75c135e 5802 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5803 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5804 /* Stop translation as we may have switched the execution mode */
5805 ctx->bstate = BS_STOP;
2423f660
TS
5806 rn = "SRSCtl";
5807 break;
7a387fff 5808 case 3:
d75c135e 5809 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5810 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5811 /* Stop translation as we may have switched the execution mode */
5812 ctx->bstate = BS_STOP;
2423f660 5813 rn = "SRSMap";
fd88b6ab 5814 break;
7a387fff 5815 default:
f31b035a 5816 goto cp0_unimplemented;
876d4b07 5817 }
8c0fdd85
TS
5818 break;
5819 case 13:
7a387fff
TS
5820 switch (sel) {
5821 case 0:
867abc7e 5822 save_cpu_state(ctx, 1);
895c2d04 5823 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5824 rn = "Cause";
5825 break;
7a387fff 5826 default:
f31b035a 5827 goto cp0_unimplemented;
876d4b07 5828 }
8c0fdd85
TS
5829 break;
5830 case 14:
7a387fff
TS
5831 switch (sel) {
5832 case 0:
7db13fae 5833 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5834 rn = "EPC";
5835 break;
7a387fff 5836 default:
f31b035a 5837 goto cp0_unimplemented;
876d4b07 5838 }
8c0fdd85
TS
5839 break;
5840 case 15:
7a387fff
TS
5841 switch (sel) {
5842 case 0:
2423f660
TS
5843 /* ignored */
5844 rn = "PRid";
5845 break;
7a387fff 5846 case 1:
d75c135e 5847 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5848 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5849 rn = "EBase";
5850 break;
7a387fff 5851 default:
f31b035a 5852 goto cp0_unimplemented;
1579a72e 5853 }
8c0fdd85
TS
5854 break;
5855 case 16:
5856 switch (sel) {
5857 case 0:
895c2d04 5858 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5859 rn = "Config";
2423f660
TS
5860 /* Stop translation as we may have switched the execution mode */
5861 ctx->bstate = BS_STOP;
7a387fff
TS
5862 break;
5863 case 1:
e397ee33 5864 /* ignored, read only */
7a387fff
TS
5865 rn = "Config1";
5866 break;
5867 case 2:
895c2d04 5868 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5869 rn = "Config2";
2423f660
TS
5870 /* Stop translation as we may have switched the execution mode */
5871 ctx->bstate = BS_STOP;
8c0fdd85 5872 break;
7a387fff 5873 case 3:
90f12d73 5874 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5875 rn = "Config3";
90f12d73
MR
5876 /* Stop translation as we may have switched the execution mode */
5877 ctx->bstate = BS_STOP;
7a387fff 5878 break;
b4160af1
PJ
5879 case 4:
5880 gen_helper_mtc0_config4(cpu_env, arg);
5881 rn = "Config4";
5882 ctx->bstate = BS_STOP;
5883 break;
b4dd99a3
PJ
5884 case 5:
5885 gen_helper_mtc0_config5(cpu_env, arg);
5886 rn = "Config5";
5887 /* Stop translation as we may have switched the execution mode */
5888 ctx->bstate = BS_STOP;
5889 break;
e397ee33
TS
5890 /* 6,7 are implementation dependent */
5891 case 6:
5892 /* ignored */
5893 rn = "Config6";
5894 break;
5895 case 7:
5896 /* ignored */
5897 rn = "Config7";
5898 break;
8c0fdd85
TS
5899 default:
5900 rn = "Invalid config selector";
f31b035a 5901 goto cp0_unimplemented;
8c0fdd85
TS
5902 }
5903 break;
5904 case 17:
7a387fff
TS
5905 switch (sel) {
5906 case 0:
895c2d04 5907 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5908 rn = "LLAddr";
5909 break;
7a387fff 5910 default:
f31b035a 5911 goto cp0_unimplemented;
7a387fff 5912 }
8c0fdd85
TS
5913 break;
5914 case 18:
7a387fff 5915 switch (sel) {
fd88b6ab 5916 case 0 ... 7:
895c2d04 5917 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5918 rn = "WatchLo";
5919 break;
7a387fff 5920 default:
f31b035a 5921 goto cp0_unimplemented;
7a387fff 5922 }
8c0fdd85
TS
5923 break;
5924 case 19:
7a387fff 5925 switch (sel) {
fd88b6ab 5926 case 0 ... 7:
895c2d04 5927 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5928 rn = "WatchHi";
5929 break;
7a387fff 5930 default:
f31b035a 5931 goto cp0_unimplemented;
7a387fff 5932 }
8c0fdd85
TS
5933 break;
5934 case 20:
7a387fff
TS
5935 switch (sel) {
5936 case 0:
d26bc211 5937#if defined(TARGET_MIPS64)
d75c135e 5938 check_insn(ctx, ISA_MIPS3);
895c2d04 5939 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5940 rn = "XContext";
5941 break;
703eaf37 5942#endif
7a387fff 5943 default:
f31b035a 5944 goto cp0_unimplemented;
7a387fff 5945 }
8c0fdd85
TS
5946 break;
5947 case 21:
7a387fff 5948 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5949 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5950 switch (sel) {
5951 case 0:
895c2d04 5952 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5953 rn = "Framemask";
5954 break;
7a387fff 5955 default:
f31b035a 5956 goto cp0_unimplemented;
7a387fff
TS
5957 }
5958 break;
8c0fdd85 5959 case 22:
7a387fff
TS
5960 /* ignored */
5961 rn = "Diagnostic"; /* implementation dependent */
2423f660 5962 break;
8c0fdd85 5963 case 23:
7a387fff
TS
5964 switch (sel) {
5965 case 0:
895c2d04 5966 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5967 /* BS_STOP isn't good enough here, hflags may have changed. */
5968 gen_save_pc(ctx->pc + 4);
5969 ctx->bstate = BS_EXCP;
2423f660
TS
5970 rn = "Debug";
5971 break;
7a387fff 5972 case 1:
895c2d04 5973// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5974 rn = "TraceControl";
8487327a
TS
5975 /* Stop translation as we may have switched the execution mode */
5976 ctx->bstate = BS_STOP;
2423f660 5977// break;
7a387fff 5978 case 2:
895c2d04 5979// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5980 rn = "TraceControl2";
8487327a
TS
5981 /* Stop translation as we may have switched the execution mode */
5982 ctx->bstate = BS_STOP;
2423f660 5983// break;
7a387fff 5984 case 3:
8487327a
TS
5985 /* Stop translation as we may have switched the execution mode */
5986 ctx->bstate = BS_STOP;
895c2d04 5987// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5988 rn = "UserTraceData";
8487327a
TS
5989 /* Stop translation as we may have switched the execution mode */
5990 ctx->bstate = BS_STOP;
2423f660 5991// break;
7a387fff 5992 case 4:
895c2d04 5993// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5994 /* Stop translation as we may have switched the execution mode */
5995 ctx->bstate = BS_STOP;
2423f660
TS
5996 rn = "TraceBPC";
5997// break;
7a387fff 5998 default:
f31b035a 5999 goto cp0_unimplemented;
7a387fff 6000 }
8c0fdd85
TS
6001 break;
6002 case 24:
7a387fff
TS
6003 switch (sel) {
6004 case 0:
f1aa6320 6005 /* EJTAG support */
7db13fae 6006 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6007 rn = "DEPC";
6008 break;
7a387fff 6009 default:
f31b035a 6010 goto cp0_unimplemented;
7a387fff 6011 }
8c0fdd85
TS
6012 break;
6013 case 25:
7a387fff
TS
6014 switch (sel) {
6015 case 0:
895c2d04 6016 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6017 rn = "Performance0";
6018 break;
7a387fff 6019 case 1:
d9bea114 6020// gen_helper_mtc0_performance1(arg);
2423f660
TS
6021 rn = "Performance1";
6022// break;
7a387fff 6023 case 2:
d9bea114 6024// gen_helper_mtc0_performance2(arg);
2423f660
TS
6025 rn = "Performance2";
6026// break;
7a387fff 6027 case 3:
d9bea114 6028// gen_helper_mtc0_performance3(arg);
2423f660
TS
6029 rn = "Performance3";
6030// break;
7a387fff 6031 case 4:
d9bea114 6032// gen_helper_mtc0_performance4(arg);
2423f660
TS
6033 rn = "Performance4";
6034// break;
7a387fff 6035 case 5:
d9bea114 6036// gen_helper_mtc0_performance5(arg);
2423f660
TS
6037 rn = "Performance5";
6038// break;
7a387fff 6039 case 6:
d9bea114 6040// gen_helper_mtc0_performance6(arg);
2423f660
TS
6041 rn = "Performance6";
6042// break;
7a387fff 6043 case 7:
d9bea114 6044// gen_helper_mtc0_performance7(arg);
2423f660
TS
6045 rn = "Performance7";
6046// break;
7a387fff 6047 default:
f31b035a 6048 goto cp0_unimplemented;
7a387fff 6049 }
8c0fdd85
TS
6050 break;
6051 case 26:
2423f660 6052 /* ignored */
8c0fdd85 6053 rn = "ECC";
2423f660 6054 break;
8c0fdd85 6055 case 27:
7a387fff
TS
6056 switch (sel) {
6057 case 0 ... 3:
2423f660
TS
6058 /* ignored */
6059 rn = "CacheErr";
6060 break;
7a387fff 6061 default:
f31b035a 6062 goto cp0_unimplemented;
7a387fff 6063 }
8c0fdd85
TS
6064 break;
6065 case 28:
6066 switch (sel) {
6067 case 0:
7a387fff
TS
6068 case 2:
6069 case 4:
6070 case 6:
895c2d04 6071 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6072 rn = "TagLo";
6073 break;
7a387fff
TS
6074 case 1:
6075 case 3:
6076 case 5:
6077 case 7:
895c2d04 6078 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6079 rn = "DataLo";
6080 break;
8c0fdd85 6081 default:
f31b035a 6082 goto cp0_unimplemented;
8c0fdd85
TS
6083 }
6084 break;
6085 case 29:
7a387fff
TS
6086 switch (sel) {
6087 case 0:
6088 case 2:
6089 case 4:
6090 case 6:
895c2d04 6091 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6092 rn = "TagHi";
6093 break;
6094 case 1:
6095 case 3:
6096 case 5:
6097 case 7:
895c2d04 6098 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6099 rn = "DataHi";
6100 break;
6101 default:
6102 rn = "invalid sel";
f31b035a 6103 goto cp0_unimplemented;
7a387fff 6104 }
8c0fdd85
TS
6105 break;
6106 case 30:
7a387fff
TS
6107 switch (sel) {
6108 case 0:
7db13fae 6109 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6110 rn = "ErrorEPC";
6111 break;
7a387fff 6112 default:
f31b035a 6113 goto cp0_unimplemented;
7a387fff 6114 }
8c0fdd85
TS
6115 break;
6116 case 31:
7a387fff
TS
6117 switch (sel) {
6118 case 0:
f1aa6320 6119 /* EJTAG support */
7db13fae 6120 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6121 rn = "DESAVE";
6122 break;
e98c0d17 6123 case 2 ... 7:
f31b035a
LA
6124 CP0_CHECK(ctx->kscrexist & (1 << sel));
6125 tcg_gen_st_tl(arg, cpu_env,
6126 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6127 rn = "KScratch";
e98c0d17 6128 break;
7a387fff 6129 default:
f31b035a 6130 goto cp0_unimplemented;
7a387fff 6131 }
2423f660
TS
6132 /* Stop translation as we may have switched the execution mode */
6133 ctx->bstate = BS_STOP;
8c0fdd85
TS
6134 break;
6135 default:
f31b035a 6136 goto cp0_unimplemented;
8c0fdd85 6137 }
2abf314d 6138 (void)rn; /* avoid a compiler warning */
d12d51d5 6139 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6140 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6141 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6142 gen_io_end();
6143 ctx->bstate = BS_STOP;
6144 }
8c0fdd85
TS
6145 return;
6146
f31b035a 6147cp0_unimplemented:
d12d51d5 6148 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6149}
6150
d26bc211 6151#if defined(TARGET_MIPS64)
d75c135e 6152static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6153{
6154 const char *rn = "invalid";
6155
e189e748 6156 if (sel != 0)
d75c135e 6157 check_insn(ctx, ISA_MIPS64);
e189e748 6158
9c2149c8
TS
6159 switch (reg) {
6160 case 0:
6161 switch (sel) {
6162 case 0:
7db13fae 6163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6164 rn = "Index";
6165 break;
6166 case 1:
f31b035a 6167 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6168 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6169 rn = "MVPControl";
ead9360e 6170 break;
9c2149c8 6171 case 2:
f31b035a 6172 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6173 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6174 rn = "MVPConf0";
ead9360e 6175 break;
9c2149c8 6176 case 3:
f31b035a 6177 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6178 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6179 rn = "MVPConf1";
ead9360e 6180 break;
9c2149c8 6181 default:
f31b035a 6182 goto cp0_unimplemented;
9c2149c8
TS
6183 }
6184 break;
6185 case 1:
6186 switch (sel) {
6187 case 0:
f31b035a 6188 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6189 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6190 rn = "Random";
2423f660 6191 break;
9c2149c8 6192 case 1:
f31b035a 6193 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6195 rn = "VPEControl";
ead9360e 6196 break;
9c2149c8 6197 case 2:
f31b035a 6198 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6200 rn = "VPEConf0";
ead9360e 6201 break;
9c2149c8 6202 case 3:
f31b035a 6203 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6205 rn = "VPEConf1";
ead9360e 6206 break;
9c2149c8 6207 case 4:
f31b035a 6208 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6209 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6210 rn = "YQMask";
ead9360e 6211 break;
9c2149c8 6212 case 5:
f31b035a 6213 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6215 rn = "VPESchedule";
ead9360e 6216 break;
9c2149c8 6217 case 6:
f31b035a 6218 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6219 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6220 rn = "VPEScheFBack";
ead9360e 6221 break;
9c2149c8 6222 case 7:
f31b035a 6223 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6224 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6225 rn = "VPEOpt";
ead9360e 6226 break;
9c2149c8 6227 default:
f31b035a 6228 goto cp0_unimplemented;
9c2149c8
TS
6229 }
6230 break;
6231 case 2:
6232 switch (sel) {
6233 case 0:
7db13fae 6234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6235 rn = "EntryLo0";
6236 break;
9c2149c8 6237 case 1:
f31b035a 6238 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6239 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6240 rn = "TCStatus";
ead9360e 6241 break;
9c2149c8 6242 case 2:
f31b035a 6243 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6244 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6245 rn = "TCBind";
ead9360e 6246 break;
9c2149c8 6247 case 3:
f31b035a 6248 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6249 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6250 rn = "TCRestart";
ead9360e 6251 break;
9c2149c8 6252 case 4:
f31b035a 6253 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6254 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6255 rn = "TCHalt";
ead9360e 6256 break;
9c2149c8 6257 case 5:
f31b035a 6258 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6259 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6260 rn = "TCContext";
ead9360e 6261 break;
9c2149c8 6262 case 6:
f31b035a 6263 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6264 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6265 rn = "TCSchedule";
ead9360e 6266 break;
9c2149c8 6267 case 7:
f31b035a 6268 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6269 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6270 rn = "TCScheFBack";
ead9360e 6271 break;
9c2149c8 6272 default:
f31b035a 6273 goto cp0_unimplemented;
9c2149c8
TS
6274 }
6275 break;
6276 case 3:
6277 switch (sel) {
6278 case 0:
7db13fae 6279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6280 rn = "EntryLo1";
6281 break;
9c2149c8 6282 default:
f31b035a 6283 goto cp0_unimplemented;
1579a72e 6284 }
9c2149c8
TS
6285 break;
6286 case 4:
6287 switch (sel) {
6288 case 0:
7db13fae 6289 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6290 rn = "Context";
6291 break;
9c2149c8 6292 case 1:
d9bea114 6293// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6294 rn = "ContextConfig";
f31b035a 6295 goto cp0_unimplemented;
2423f660 6296// break;
d279279e 6297 case 2:
f31b035a
LA
6298 CP0_CHECK(ctx->ulri);
6299 tcg_gen_ld_tl(arg, cpu_env,
6300 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6301 rn = "UserLocal";
d279279e 6302 break;
9c2149c8 6303 default:
f31b035a 6304 goto cp0_unimplemented;
876d4b07 6305 }
9c2149c8
TS
6306 break;
6307 case 5:
6308 switch (sel) {
6309 case 0:
7db13fae 6310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6311 rn = "PageMask";
6312 break;
9c2149c8 6313 case 1:
d75c135e 6314 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6316 rn = "PageGrain";
6317 break;
9c2149c8 6318 default:
f31b035a 6319 goto cp0_unimplemented;
876d4b07 6320 }
9c2149c8
TS
6321 break;
6322 case 6:
6323 switch (sel) {
6324 case 0:
7db13fae 6325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6326 rn = "Wired";
6327 break;
9c2149c8 6328 case 1:
d75c135e 6329 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6331 rn = "SRSConf0";
ead9360e 6332 break;
9c2149c8 6333 case 2:
d75c135e 6334 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6336 rn = "SRSConf1";
ead9360e 6337 break;
9c2149c8 6338 case 3:
d75c135e 6339 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6341 rn = "SRSConf2";
ead9360e 6342 break;
9c2149c8 6343 case 4:
d75c135e 6344 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6346 rn = "SRSConf3";
ead9360e 6347 break;
9c2149c8 6348 case 5:
d75c135e 6349 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6351 rn = "SRSConf4";
ead9360e 6352 break;
9c2149c8 6353 default:
f31b035a 6354 goto cp0_unimplemented;
876d4b07 6355 }
9c2149c8
TS
6356 break;
6357 case 7:
6358 switch (sel) {
6359 case 0:
d75c135e 6360 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6362 rn = "HWREna";
6363 break;
9c2149c8 6364 default:
f31b035a 6365 goto cp0_unimplemented;
876d4b07 6366 }
9c2149c8
TS
6367 break;
6368 case 8:
6369 switch (sel) {
6370 case 0:
7db13fae 6371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6372 rn = "BadVAddr";
2423f660 6373 break;
aea14095 6374 case 1:
f31b035a
LA
6375 CP0_CHECK(ctx->bi);
6376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6377 rn = "BadInstr";
aea14095
LA
6378 break;
6379 case 2:
f31b035a
LA
6380 CP0_CHECK(ctx->bp);
6381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6382 rn = "BadInstrP";
aea14095 6383 break;
9c2149c8 6384 default:
f31b035a 6385 goto cp0_unimplemented;
876d4b07 6386 }
9c2149c8
TS
6387 break;
6388 case 9:
6389 switch (sel) {
6390 case 0:
2e70f6ef 6391 /* Mark as an IO operation because we read the time. */
bd79255d 6392 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6393 gen_io_start();
bd79255d 6394 }
895c2d04 6395 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6396 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6397 gen_io_end();
2e70f6ef 6398 }
55807224
EI
6399 /* Break the TB to be able to take timer interrupts immediately
6400 after reading count. */
6401 ctx->bstate = BS_STOP;
2423f660
TS
6402 rn = "Count";
6403 break;
6404 /* 6,7 are implementation dependent */
9c2149c8 6405 default:
f31b035a 6406 goto cp0_unimplemented;
876d4b07 6407 }
9c2149c8
TS
6408 break;
6409 case 10:
6410 switch (sel) {
6411 case 0:
7db13fae 6412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6413 rn = "EntryHi";
6414 break;
9c2149c8 6415 default:
f31b035a 6416 goto cp0_unimplemented;
876d4b07 6417 }
9c2149c8
TS
6418 break;
6419 case 11:
6420 switch (sel) {
6421 case 0:
7db13fae 6422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6423 rn = "Compare";
6424 break;
876d4b07 6425 /* 6,7 are implementation dependent */
9c2149c8 6426 default:
f31b035a 6427 goto cp0_unimplemented;
876d4b07 6428 }
9c2149c8
TS
6429 break;
6430 case 12:
6431 switch (sel) {
6432 case 0:
7db13fae 6433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6434 rn = "Status";
6435 break;
9c2149c8 6436 case 1:
d75c135e 6437 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6439 rn = "IntCtl";
6440 break;
9c2149c8 6441 case 2:
d75c135e 6442 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6444 rn = "SRSCtl";
6445 break;
9c2149c8 6446 case 3:
d75c135e 6447 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6449 rn = "SRSMap";
6450 break;
9c2149c8 6451 default:
f31b035a 6452 goto cp0_unimplemented;
876d4b07 6453 }
9c2149c8
TS
6454 break;
6455 case 13:
6456 switch (sel) {
6457 case 0:
7db13fae 6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6459 rn = "Cause";
6460 break;
9c2149c8 6461 default:
f31b035a 6462 goto cp0_unimplemented;
876d4b07 6463 }
9c2149c8
TS
6464 break;
6465 case 14:
6466 switch (sel) {
6467 case 0:
7db13fae 6468 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6469 rn = "EPC";
6470 break;
9c2149c8 6471 default:
f31b035a 6472 goto cp0_unimplemented;
876d4b07 6473 }
9c2149c8
TS
6474 break;
6475 case 15:
6476 switch (sel) {
6477 case 0:
7db13fae 6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6479 rn = "PRid";
6480 break;
9c2149c8 6481 case 1:
d75c135e 6482 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6484 rn = "EBase";
6485 break;
9c2149c8 6486 default:
f31b035a 6487 goto cp0_unimplemented;
876d4b07 6488 }
9c2149c8
TS
6489 break;
6490 case 16:
6491 switch (sel) {
6492 case 0:
7db13fae 6493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6494 rn = "Config";
6495 break;
6496 case 1:
7db13fae 6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6498 rn = "Config1";
6499 break;
6500 case 2:
7db13fae 6501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6502 rn = "Config2";
6503 break;
6504 case 3:
7db13fae 6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6506 rn = "Config3";
6507 break;
faf1f68b
LA
6508 case 4:
6509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6510 rn = "Config4";
6511 break;
6512 case 5:
6513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6514 rn = "Config5";
6515 break;
9c2149c8 6516 /* 6,7 are implementation dependent */
f0b3f3ae 6517 case 6:
7db13fae 6518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6519 rn = "Config6";
6520 break;
6521 case 7:
7db13fae 6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6523 rn = "Config7";
6524 break;
9c2149c8 6525 default:
f31b035a 6526 goto cp0_unimplemented;
9c2149c8
TS
6527 }
6528 break;
6529 case 17:
6530 switch (sel) {
6531 case 0:
895c2d04 6532 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6533 rn = "LLAddr";
6534 break;
9c2149c8 6535 default:
f31b035a 6536 goto cp0_unimplemented;
9c2149c8
TS
6537 }
6538 break;
6539 case 18:
6540 switch (sel) {
fd88b6ab 6541 case 0 ... 7:
895c2d04 6542 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6543 rn = "WatchLo";
6544 break;
9c2149c8 6545 default:
f31b035a 6546 goto cp0_unimplemented;
9c2149c8
TS
6547 }
6548 break;
6549 case 19:
6550 switch (sel) {
fd88b6ab 6551 case 0 ... 7:
895c2d04 6552 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6553 rn = "WatchHi";
6554 break;
9c2149c8 6555 default:
f31b035a 6556 goto cp0_unimplemented;
9c2149c8
TS
6557 }
6558 break;
6559 case 20:
6560 switch (sel) {
6561 case 0:
d75c135e 6562 check_insn(ctx, ISA_MIPS3);
7db13fae 6563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6564 rn = "XContext";
6565 break;
9c2149c8 6566 default:
f31b035a 6567 goto cp0_unimplemented;
9c2149c8
TS
6568 }
6569 break;
6570 case 21:
6571 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6572 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6573 switch (sel) {
6574 case 0:
7db13fae 6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6576 rn = "Framemask";
6577 break;
9c2149c8 6578 default:
f31b035a 6579 goto cp0_unimplemented;
9c2149c8
TS
6580 }
6581 break;
6582 case 22:
d9bea114 6583 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6584 rn = "'Diagnostic"; /* implementation dependent */
6585 break;
9c2149c8
TS
6586 case 23:
6587 switch (sel) {
6588 case 0:
895c2d04 6589 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6590 rn = "Debug";
6591 break;
9c2149c8 6592 case 1:
895c2d04 6593// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6594 rn = "TraceControl";
6595// break;
9c2149c8 6596 case 2:
895c2d04 6597// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6598 rn = "TraceControl2";
6599// break;
9c2149c8 6600 case 3:
895c2d04 6601// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6602 rn = "UserTraceData";
6603// break;
9c2149c8 6604 case 4:
895c2d04 6605// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6606 rn = "TraceBPC";
6607// break;
9c2149c8 6608 default:
f31b035a 6609 goto cp0_unimplemented;
9c2149c8
TS
6610 }
6611 break;
6612 case 24:
6613 switch (sel) {
6614 case 0:
f0b3f3ae 6615 /* EJTAG support */
7db13fae 6616 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6617 rn = "DEPC";
6618 break;
9c2149c8 6619 default:
f31b035a 6620 goto cp0_unimplemented;
9c2149c8
TS
6621 }
6622 break;
6623 case 25:
6624 switch (sel) {
6625 case 0:
7db13fae 6626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6627 rn = "Performance0";
9c2149c8
TS
6628 break;
6629 case 1:
d9bea114 6630// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6631 rn = "Performance1";
6632// break;
9c2149c8 6633 case 2:
d9bea114 6634// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6635 rn = "Performance2";
6636// break;
9c2149c8 6637 case 3:
d9bea114 6638// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6639 rn = "Performance3";
6640// break;
9c2149c8 6641 case 4:
d9bea114 6642// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6643 rn = "Performance4";
6644// break;
9c2149c8 6645 case 5:
d9bea114 6646// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6647 rn = "Performance5";
6648// break;
9c2149c8 6649 case 6:
d9bea114 6650// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6651 rn = "Performance6";
6652// break;
9c2149c8 6653 case 7:
d9bea114 6654// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6655 rn = "Performance7";
6656// break;
9c2149c8 6657 default:
f31b035a 6658 goto cp0_unimplemented;
9c2149c8
TS
6659 }
6660 break;
6661 case 26:
d9bea114 6662 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6663 rn = "ECC";
6664 break;
9c2149c8
TS
6665 case 27:
6666 switch (sel) {
6667 /* ignored */
6668 case 0 ... 3:
d9bea114 6669 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6670 rn = "CacheErr";
6671 break;
9c2149c8 6672 default:
f31b035a 6673 goto cp0_unimplemented;
9c2149c8
TS
6674 }
6675 break;
6676 case 28:
6677 switch (sel) {
6678 case 0:
6679 case 2:
6680 case 4:
6681 case 6:
7db13fae 6682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6683 rn = "TagLo";
6684 break;
6685 case 1:
6686 case 3:
6687 case 5:
6688 case 7:
7db13fae 6689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6690 rn = "DataLo";
6691 break;
6692 default:
f31b035a 6693 goto cp0_unimplemented;
9c2149c8
TS
6694 }
6695 break;
6696 case 29:
6697 switch (sel) {
6698 case 0:
6699 case 2:
6700 case 4:
6701 case 6:
7db13fae 6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6703 rn = "TagHi";
6704 break;
6705 case 1:
6706 case 3:
6707 case 5:
6708 case 7:
7db13fae 6709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6710 rn = "DataHi";
6711 break;
6712 default:
f31b035a 6713 goto cp0_unimplemented;
9c2149c8
TS
6714 }
6715 break;
6716 case 30:
6717 switch (sel) {
6718 case 0:
7db13fae 6719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6720 rn = "ErrorEPC";
6721 break;
9c2149c8 6722 default:
f31b035a 6723 goto cp0_unimplemented;
9c2149c8
TS
6724 }
6725 break;
6726 case 31:
6727 switch (sel) {
6728 case 0:
f0b3f3ae 6729 /* EJTAG support */
7db13fae 6730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6731 rn = "DESAVE";
6732 break;
e98c0d17 6733 case 2 ... 7:
f31b035a
LA
6734 CP0_CHECK(ctx->kscrexist & (1 << sel));
6735 tcg_gen_ld_tl(arg, cpu_env,
6736 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6737 rn = "KScratch";
e98c0d17 6738 break;
9c2149c8 6739 default:
f31b035a 6740 goto cp0_unimplemented;
9c2149c8
TS
6741 }
6742 break;
6743 default:
f31b035a 6744 goto cp0_unimplemented;
9c2149c8 6745 }
2abf314d 6746 (void)rn; /* avoid a compiler warning */
d12d51d5 6747 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6748 return;
6749
f31b035a 6750cp0_unimplemented:
d12d51d5 6751 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6752 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6753}
6754
d75c135e 6755static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6756{
6757 const char *rn = "invalid";
6758
e189e748 6759 if (sel != 0)
d75c135e 6760 check_insn(ctx, ISA_MIPS64);
e189e748 6761
bd79255d 6762 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6763 gen_io_start();
bd79255d 6764 }
2e70f6ef 6765
9c2149c8
TS
6766 switch (reg) {
6767 case 0:
6768 switch (sel) {
6769 case 0:
895c2d04 6770 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6771 rn = "Index";
6772 break;
6773 case 1:
f31b035a 6774 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6775 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6776 rn = "MVPControl";
ead9360e 6777 break;
9c2149c8 6778 case 2:
f31b035a 6779 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6780 /* ignored */
9c2149c8 6781 rn = "MVPConf0";
ead9360e 6782 break;
9c2149c8 6783 case 3:
f31b035a 6784 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6785 /* ignored */
9c2149c8 6786 rn = "MVPConf1";
ead9360e 6787 break;
9c2149c8 6788 default:
f31b035a 6789 goto cp0_unimplemented;
9c2149c8
TS
6790 }
6791 break;
6792 case 1:
6793 switch (sel) {
6794 case 0:
2423f660 6795 /* ignored */
9c2149c8 6796 rn = "Random";
2423f660 6797 break;
9c2149c8 6798 case 1:
f31b035a 6799 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6800 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6801 rn = "VPEControl";
ead9360e 6802 break;
9c2149c8 6803 case 2:
f31b035a 6804 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6805 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6806 rn = "VPEConf0";
ead9360e 6807 break;
9c2149c8 6808 case 3:
f31b035a 6809 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6810 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6811 rn = "VPEConf1";
ead9360e 6812 break;
9c2149c8 6813 case 4:
f31b035a 6814 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6815 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6816 rn = "YQMask";
ead9360e 6817 break;
9c2149c8 6818 case 5:
f31b035a 6819 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6820 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6821 rn = "VPESchedule";
ead9360e 6822 break;
9c2149c8 6823 case 6:
f31b035a 6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6825 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6826 rn = "VPEScheFBack";
ead9360e 6827 break;
9c2149c8 6828 case 7:
f31b035a 6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6830 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6831 rn = "VPEOpt";
ead9360e 6832 break;
9c2149c8 6833 default:
f31b035a 6834 goto cp0_unimplemented;
9c2149c8
TS
6835 }
6836 break;
6837 case 2:
6838 switch (sel) {
6839 case 0:
7207c7f9 6840 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6841 rn = "EntryLo0";
6842 break;
9c2149c8 6843 case 1:
f31b035a 6844 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6845 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6846 rn = "TCStatus";
ead9360e 6847 break;
9c2149c8 6848 case 2:
f31b035a 6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6850 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6851 rn = "TCBind";
ead9360e 6852 break;
9c2149c8 6853 case 3:
f31b035a 6854 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6855 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6856 rn = "TCRestart";
ead9360e 6857 break;
9c2149c8 6858 case 4:
f31b035a 6859 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6860 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6861 rn = "TCHalt";
ead9360e 6862 break;
9c2149c8 6863 case 5:
f31b035a 6864 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6865 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6866 rn = "TCContext";
ead9360e 6867 break;
9c2149c8 6868 case 6:
f31b035a 6869 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6870 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6871 rn = "TCSchedule";
ead9360e 6872 break;
9c2149c8 6873 case 7:
f31b035a 6874 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6875 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6876 rn = "TCScheFBack";
ead9360e 6877 break;
9c2149c8 6878 default:
f31b035a 6879 goto cp0_unimplemented;
9c2149c8
TS
6880 }
6881 break;
6882 case 3:
6883 switch (sel) {
6884 case 0:
7207c7f9 6885 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6886 rn = "EntryLo1";
6887 break;
9c2149c8 6888 default:
f31b035a 6889 goto cp0_unimplemented;
876d4b07 6890 }
9c2149c8
TS
6891 break;
6892 case 4:
6893 switch (sel) {
6894 case 0:
895c2d04 6895 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6896 rn = "Context";
6897 break;
9c2149c8 6898 case 1:
895c2d04 6899// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6900 rn = "ContextConfig";
f31b035a 6901 goto cp0_unimplemented;
2423f660 6902// break;
d279279e 6903 case 2:
f31b035a
LA
6904 CP0_CHECK(ctx->ulri);
6905 tcg_gen_st_tl(arg, cpu_env,
6906 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6907 rn = "UserLocal";
d279279e 6908 break;
9c2149c8 6909 default:
f31b035a 6910 goto cp0_unimplemented;
876d4b07 6911 }
9c2149c8
TS
6912 break;
6913 case 5:
6914 switch (sel) {
6915 case 0:
895c2d04 6916 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6917 rn = "PageMask";
6918 break;
9c2149c8 6919 case 1:
d75c135e 6920 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6921 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6922 rn = "PageGrain";
6923 break;
9c2149c8 6924 default:
f31b035a 6925 goto cp0_unimplemented;
876d4b07 6926 }
9c2149c8
TS
6927 break;
6928 case 6:
6929 switch (sel) {
6930 case 0:
895c2d04 6931 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6932 rn = "Wired";
6933 break;
9c2149c8 6934 case 1:
d75c135e 6935 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6936 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6937 rn = "SRSConf0";
ead9360e 6938 break;
9c2149c8 6939 case 2:
d75c135e 6940 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6941 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6942 rn = "SRSConf1";
ead9360e 6943 break;
9c2149c8 6944 case 3:
d75c135e 6945 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6946 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6947 rn = "SRSConf2";
ead9360e 6948 break;
9c2149c8 6949 case 4:
d75c135e 6950 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6951 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6952 rn = "SRSConf3";
ead9360e 6953 break;
9c2149c8 6954 case 5:
d75c135e 6955 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6956 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6957 rn = "SRSConf4";
ead9360e 6958 break;
9c2149c8 6959 default:
f31b035a 6960 goto cp0_unimplemented;
876d4b07 6961 }
9c2149c8
TS
6962 break;
6963 case 7:
6964 switch (sel) {
6965 case 0:
d75c135e 6966 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6967 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6968 ctx->bstate = BS_STOP;
2423f660
TS
6969 rn = "HWREna";
6970 break;
9c2149c8 6971 default:
f31b035a 6972 goto cp0_unimplemented;
876d4b07 6973 }
9c2149c8
TS
6974 break;
6975 case 8:
aea14095
LA
6976 switch (sel) {
6977 case 0:
6978 /* ignored */
6979 rn = "BadVAddr";
6980 break;
6981 case 1:
6982 /* ignored */
6983 rn = "BadInstr";
6984 break;
6985 case 2:
6986 /* ignored */
6987 rn = "BadInstrP";
6988 break;
6989 default:
f31b035a 6990 goto cp0_unimplemented;
aea14095 6991 }
9c2149c8
TS
6992 break;
6993 case 9:
6994 switch (sel) {
6995 case 0:
895c2d04 6996 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6997 rn = "Count";
6998 break;
876d4b07 6999 /* 6,7 are implementation dependent */
9c2149c8 7000 default:
f31b035a 7001 goto cp0_unimplemented;
876d4b07
TS
7002 }
7003 /* Stop translation as we may have switched the execution mode */
7004 ctx->bstate = BS_STOP;
9c2149c8
TS
7005 break;
7006 case 10:
7007 switch (sel) {
7008 case 0:
895c2d04 7009 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7010 rn = "EntryHi";
7011 break;
9c2149c8 7012 default:
f31b035a 7013 goto cp0_unimplemented;
876d4b07 7014 }
9c2149c8
TS
7015 break;
7016 case 11:
7017 switch (sel) {
7018 case 0:
895c2d04 7019 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7020 rn = "Compare";
7021 break;
876d4b07 7022 /* 6,7 are implementation dependent */
9c2149c8 7023 default:
f31b035a 7024 goto cp0_unimplemented;
876d4b07 7025 }
de9a95f0
AJ
7026 /* Stop translation as we may have switched the execution mode */
7027 ctx->bstate = BS_STOP;
9c2149c8
TS
7028 break;
7029 case 12:
7030 switch (sel) {
7031 case 0:
867abc7e 7032 save_cpu_state(ctx, 1);
895c2d04 7033 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7034 /* BS_STOP isn't good enough here, hflags may have changed. */
7035 gen_save_pc(ctx->pc + 4);
7036 ctx->bstate = BS_EXCP;
2423f660
TS
7037 rn = "Status";
7038 break;
9c2149c8 7039 case 1:
d75c135e 7040 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7041 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7042 /* Stop translation as we may have switched the execution mode */
7043 ctx->bstate = BS_STOP;
2423f660
TS
7044 rn = "IntCtl";
7045 break;
9c2149c8 7046 case 2:
d75c135e 7047 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7048 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7049 /* Stop translation as we may have switched the execution mode */
7050 ctx->bstate = BS_STOP;
2423f660
TS
7051 rn = "SRSCtl";
7052 break;
9c2149c8 7053 case 3:
d75c135e 7054 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7055 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7056 /* Stop translation as we may have switched the execution mode */
7057 ctx->bstate = BS_STOP;
2423f660
TS
7058 rn = "SRSMap";
7059 break;
7060 default:
f31b035a 7061 goto cp0_unimplemented;
876d4b07 7062 }
9c2149c8
TS
7063 break;
7064 case 13:
7065 switch (sel) {
7066 case 0:
867abc7e 7067 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7068 /* Mark as an IO operation because we may trigger a software
7069 interrupt. */
bd79255d 7070 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7071 gen_io_start();
7072 }
895c2d04 7073 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7074 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7075 gen_io_end();
7076 }
7077 /* Stop translation as we may have triggered an intetrupt */
7078 ctx->bstate = BS_STOP;
2423f660
TS
7079 rn = "Cause";
7080 break;
9c2149c8 7081 default:
f31b035a 7082 goto cp0_unimplemented;
876d4b07 7083 }
9c2149c8
TS
7084 break;
7085 case 14:
7086 switch (sel) {
7087 case 0:
7db13fae 7088 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7089 rn = "EPC";
7090 break;
9c2149c8 7091 default:
f31b035a 7092 goto cp0_unimplemented;
876d4b07 7093 }
9c2149c8
TS
7094 break;
7095 case 15:
7096 switch (sel) {
7097 case 0:
2423f660
TS
7098 /* ignored */
7099 rn = "PRid";
7100 break;
9c2149c8 7101 case 1:
d75c135e 7102 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7103 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7104 rn = "EBase";
7105 break;
9c2149c8 7106 default:
f31b035a 7107 goto cp0_unimplemented;
876d4b07 7108 }
9c2149c8
TS
7109 break;
7110 case 16:
7111 switch (sel) {
7112 case 0:
895c2d04 7113 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7114 rn = "Config";
2423f660
TS
7115 /* Stop translation as we may have switched the execution mode */
7116 ctx->bstate = BS_STOP;
9c2149c8
TS
7117 break;
7118 case 1:
1fc7bf6e 7119 /* ignored, read only */
9c2149c8
TS
7120 rn = "Config1";
7121 break;
7122 case 2:
895c2d04 7123 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7124 rn = "Config2";
2423f660
TS
7125 /* Stop translation as we may have switched the execution mode */
7126 ctx->bstate = BS_STOP;
9c2149c8
TS
7127 break;
7128 case 3:
90f12d73 7129 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7130 rn = "Config3";
90f12d73
MR
7131 /* Stop translation as we may have switched the execution mode */
7132 ctx->bstate = BS_STOP;
9c2149c8 7133 break;
faf1f68b
LA
7134 case 4:
7135 /* currently ignored */
7136 rn = "Config4";
7137 break;
7138 case 5:
7139 gen_helper_mtc0_config5(cpu_env, arg);
7140 rn = "Config5";
7141 /* Stop translation as we may have switched the execution mode */
7142 ctx->bstate = BS_STOP;
7143 break;
9c2149c8
TS
7144 /* 6,7 are implementation dependent */
7145 default:
7146 rn = "Invalid config selector";
f31b035a 7147 goto cp0_unimplemented;
9c2149c8 7148 }
9c2149c8
TS
7149 break;
7150 case 17:
7151 switch (sel) {
7152 case 0:
895c2d04 7153 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7154 rn = "LLAddr";
7155 break;
9c2149c8 7156 default:
f31b035a 7157 goto cp0_unimplemented;
9c2149c8
TS
7158 }
7159 break;
7160 case 18:
7161 switch (sel) {
fd88b6ab 7162 case 0 ... 7:
895c2d04 7163 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7164 rn = "WatchLo";
7165 break;
9c2149c8 7166 default:
f31b035a 7167 goto cp0_unimplemented;
9c2149c8
TS
7168 }
7169 break;
7170 case 19:
7171 switch (sel) {
fd88b6ab 7172 case 0 ... 7:
895c2d04 7173 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7174 rn = "WatchHi";
7175 break;
9c2149c8 7176 default:
f31b035a 7177 goto cp0_unimplemented;
9c2149c8
TS
7178 }
7179 break;
7180 case 20:
7181 switch (sel) {
7182 case 0:
d75c135e 7183 check_insn(ctx, ISA_MIPS3);
895c2d04 7184 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7185 rn = "XContext";
7186 break;
9c2149c8 7187 default:
f31b035a 7188 goto cp0_unimplemented;
9c2149c8
TS
7189 }
7190 break;
7191 case 21:
7192 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7193 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7194 switch (sel) {
7195 case 0:
895c2d04 7196 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7197 rn = "Framemask";
7198 break;
9c2149c8 7199 default:
f31b035a 7200 goto cp0_unimplemented;
9c2149c8
TS
7201 }
7202 break;
7203 case 22:
7204 /* ignored */
7205 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7206 break;
9c2149c8
TS
7207 case 23:
7208 switch (sel) {
7209 case 0:
895c2d04 7210 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7211 /* BS_STOP isn't good enough here, hflags may have changed. */
7212 gen_save_pc(ctx->pc + 4);
7213 ctx->bstate = BS_EXCP;
2423f660
TS
7214 rn = "Debug";
7215 break;
9c2149c8 7216 case 1:
895c2d04 7217// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7218 /* Stop translation as we may have switched the execution mode */
7219 ctx->bstate = BS_STOP;
2423f660
TS
7220 rn = "TraceControl";
7221// break;
9c2149c8 7222 case 2:
895c2d04 7223// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7224 /* Stop translation as we may have switched the execution mode */
7225 ctx->bstate = BS_STOP;
2423f660
TS
7226 rn = "TraceControl2";
7227// break;
9c2149c8 7228 case 3:
895c2d04 7229// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7230 /* Stop translation as we may have switched the execution mode */
7231 ctx->bstate = BS_STOP;
2423f660
TS
7232 rn = "UserTraceData";
7233// break;
9c2149c8 7234 case 4:
895c2d04 7235// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7236 /* Stop translation as we may have switched the execution mode */
7237 ctx->bstate = BS_STOP;
2423f660
TS
7238 rn = "TraceBPC";
7239// break;
9c2149c8 7240 default:
f31b035a 7241 goto cp0_unimplemented;
9c2149c8 7242 }
9c2149c8
TS
7243 break;
7244 case 24:
7245 switch (sel) {
7246 case 0:
f1aa6320 7247 /* EJTAG support */
7db13fae 7248 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7249 rn = "DEPC";
7250 break;
9c2149c8 7251 default:
f31b035a 7252 goto cp0_unimplemented;
9c2149c8
TS
7253 }
7254 break;
7255 case 25:
7256 switch (sel) {
7257 case 0:
895c2d04 7258 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7259 rn = "Performance0";
7260 break;
9c2149c8 7261 case 1:
895c2d04 7262// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7263 rn = "Performance1";
7264// break;
9c2149c8 7265 case 2:
895c2d04 7266// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7267 rn = "Performance2";
7268// break;
9c2149c8 7269 case 3:
895c2d04 7270// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7271 rn = "Performance3";
7272// break;
9c2149c8 7273 case 4:
895c2d04 7274// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7275 rn = "Performance4";
7276// break;
9c2149c8 7277 case 5:
895c2d04 7278// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7279 rn = "Performance5";
7280// break;
9c2149c8 7281 case 6:
895c2d04 7282// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7283 rn = "Performance6";
7284// break;
9c2149c8 7285 case 7:
895c2d04 7286// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7287 rn = "Performance7";
7288// break;
9c2149c8 7289 default:
f31b035a 7290 goto cp0_unimplemented;
9c2149c8 7291 }
876d4b07 7292 break;
9c2149c8 7293 case 26:
876d4b07 7294 /* ignored */
9c2149c8 7295 rn = "ECC";
876d4b07 7296 break;
9c2149c8
TS
7297 case 27:
7298 switch (sel) {
7299 case 0 ... 3:
2423f660
TS
7300 /* ignored */
7301 rn = "CacheErr";
7302 break;
9c2149c8 7303 default:
f31b035a 7304 goto cp0_unimplemented;
9c2149c8 7305 }
876d4b07 7306 break;
9c2149c8
TS
7307 case 28:
7308 switch (sel) {
7309 case 0:
7310 case 2:
7311 case 4:
7312 case 6:
895c2d04 7313 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7314 rn = "TagLo";
7315 break;
7316 case 1:
7317 case 3:
7318 case 5:
7319 case 7:
895c2d04 7320 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7321 rn = "DataLo";
7322 break;
7323 default:
f31b035a 7324 goto cp0_unimplemented;
9c2149c8
TS
7325 }
7326 break;
7327 case 29:
7328 switch (sel) {
7329 case 0:
7330 case 2:
7331 case 4:
7332 case 6:
895c2d04 7333 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7334 rn = "TagHi";
7335 break;
7336 case 1:
7337 case 3:
7338 case 5:
7339 case 7:
895c2d04 7340 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7341 rn = "DataHi";
7342 break;
7343 default:
7344 rn = "invalid sel";
f31b035a 7345 goto cp0_unimplemented;
9c2149c8 7346 }
876d4b07 7347 break;
9c2149c8
TS
7348 case 30:
7349 switch (sel) {
7350 case 0:
7db13fae 7351 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7352 rn = "ErrorEPC";
7353 break;
9c2149c8 7354 default:
f31b035a 7355 goto cp0_unimplemented;
9c2149c8
TS
7356 }
7357 break;
7358 case 31:
7359 switch (sel) {
7360 case 0:
f1aa6320 7361 /* EJTAG support */
7db13fae 7362 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7363 rn = "DESAVE";
7364 break;
e98c0d17 7365 case 2 ... 7:
f31b035a
LA
7366 CP0_CHECK(ctx->kscrexist & (1 << sel));
7367 tcg_gen_st_tl(arg, cpu_env,
7368 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7369 rn = "KScratch";
e98c0d17 7370 break;
9c2149c8 7371 default:
f31b035a 7372 goto cp0_unimplemented;
9c2149c8 7373 }
876d4b07
TS
7374 /* Stop translation as we may have switched the execution mode */
7375 ctx->bstate = BS_STOP;
9c2149c8
TS
7376 break;
7377 default:
f31b035a 7378 goto cp0_unimplemented;
9c2149c8 7379 }
2abf314d 7380 (void)rn; /* avoid a compiler warning */
d12d51d5 7381 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7382 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7383 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7384 gen_io_end();
7385 ctx->bstate = BS_STOP;
7386 }
9c2149c8
TS
7387 return;
7388
f31b035a 7389cp0_unimplemented:
d12d51d5 7390 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7391}
d26bc211 7392#endif /* TARGET_MIPS64 */
9c2149c8 7393
7db13fae 7394static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7395 int u, int sel, int h)
7396{
7397 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7398 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7399
7400 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7401 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7402 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7403 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7404 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7405 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7406 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7407 else if (u == 0) {
7408 switch (rt) {
5a25ce94
EI
7409 case 1:
7410 switch (sel) {
7411 case 1:
895c2d04 7412 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7413 break;
7414 case 2:
895c2d04 7415 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7416 break;
7417 default:
7418 goto die;
7419 break;
7420 }
7421 break;
ead9360e
TS
7422 case 2:
7423 switch (sel) {
7424 case 1:
895c2d04 7425 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7426 break;
7427 case 2:
895c2d04 7428 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7429 break;
7430 case 3:
895c2d04 7431 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7432 break;
7433 case 4:
895c2d04 7434 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7435 break;
7436 case 5:
895c2d04 7437 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7438 break;
7439 case 6:
895c2d04 7440 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7441 break;
7442 case 7:
895c2d04 7443 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7444 break;
7445 default:
d75c135e 7446 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7447 break;
7448 }
7449 break;
7450 case 10:
7451 switch (sel) {
7452 case 0:
895c2d04 7453 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7454 break;
7455 default:
d75c135e 7456 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7457 break;
7458 }
7459 case 12:
7460 switch (sel) {
7461 case 0:
895c2d04 7462 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7463 break;
7464 default:
d75c135e 7465 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7466 break;
7467 }
5a25ce94
EI
7468 case 13:
7469 switch (sel) {
7470 case 0:
895c2d04 7471 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7472 break;
7473 default:
7474 goto die;
7475 break;
7476 }
7477 break;
7478 case 14:
7479 switch (sel) {
7480 case 0:
895c2d04 7481 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7482 break;
7483 default:
7484 goto die;
7485 break;
7486 }
7487 break;
7488 case 15:
7489 switch (sel) {
7490 case 1:
895c2d04 7491 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7492 break;
7493 default:
7494 goto die;
7495 break;
7496 }
7497 break;
7498 case 16:
7499 switch (sel) {
7500 case 0 ... 7:
895c2d04 7501 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7502 break;
7503 default:
7504 goto die;
7505 break;
7506 }
7507 break;
ead9360e
TS
7508 case 23:
7509 switch (sel) {
7510 case 0:
895c2d04 7511 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7512 break;
7513 default:
d75c135e 7514 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7515 break;
7516 }
7517 break;
7518 default:
d75c135e 7519 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7520 }
7521 } else switch (sel) {
7522 /* GPR registers. */
7523 case 0:
895c2d04 7524 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7525 break;
7526 /* Auxiliary CPU registers */
7527 case 1:
7528 switch (rt) {
7529 case 0:
895c2d04 7530 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7531 break;
7532 case 1:
895c2d04 7533 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7534 break;
7535 case 2:
895c2d04 7536 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7537 break;
7538 case 4:
895c2d04 7539 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7540 break;
7541 case 5:
895c2d04 7542 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7543 break;
7544 case 6:
895c2d04 7545 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7546 break;
7547 case 8:
895c2d04 7548 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7549 break;
7550 case 9:
895c2d04 7551 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7552 break;
7553 case 10:
895c2d04 7554 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7555 break;
7556 case 12:
895c2d04 7557 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7558 break;
7559 case 13:
895c2d04 7560 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7561 break;
7562 case 14:
895c2d04 7563 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7564 break;
7565 case 16:
895c2d04 7566 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7567 break;
7568 default:
7569 goto die;
7570 }
7571 break;
7572 /* Floating point (COP1). */
7573 case 2:
7574 /* XXX: For now we support only a single FPU context. */
7575 if (h == 0) {
a7812ae4 7576 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7577
7c979afd 7578 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7579 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7580 tcg_temp_free_i32(fp0);
ead9360e 7581 } else {
a7812ae4 7582 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7583
7f6613ce 7584 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7585 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7586 tcg_temp_free_i32(fp0);
ead9360e
TS
7587 }
7588 break;
7589 case 3:
7590 /* XXX: For now we support only a single FPU context. */
895c2d04 7591 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7592 break;
7593 /* COP2: Not implemented. */
7594 case 4:
7595 case 5:
7596 /* fall through */
7597 default:
7598 goto die;
7599 }
d12d51d5 7600 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7601 gen_store_gpr(t0, rd);
7602 tcg_temp_free(t0);
ead9360e
TS
7603 return;
7604
7605die:
1a3fd9c3 7606 tcg_temp_free(t0);
d12d51d5 7607 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7608 generate_exception(ctx, EXCP_RI);
7609}
7610
7db13fae 7611static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7612 int u, int sel, int h)
7613{
7614 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7615 TCGv t0 = tcg_temp_local_new();
ead9360e 7616
1a3fd9c3 7617 gen_load_gpr(t0, rt);
ead9360e 7618 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7619 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7620 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7621 /* NOP */ ;
7622 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7623 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7624 /* NOP */ ;
7625 else if (u == 0) {
7626 switch (rd) {
5a25ce94
EI
7627 case 1:
7628 switch (sel) {
7629 case 1:
895c2d04 7630 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7631 break;
7632 case 2:
895c2d04 7633 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7634 break;
7635 default:
7636 goto die;
7637 break;
7638 }
7639 break;
ead9360e
TS
7640 case 2:
7641 switch (sel) {
7642 case 1:
895c2d04 7643 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7644 break;
7645 case 2:
895c2d04 7646 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7647 break;
7648 case 3:
895c2d04 7649 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7650 break;
7651 case 4:
895c2d04 7652 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7653 break;
7654 case 5:
895c2d04 7655 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7656 break;
7657 case 6:
895c2d04 7658 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7659 break;
7660 case 7:
895c2d04 7661 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7662 break;
7663 default:
d75c135e 7664 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7665 break;
7666 }
7667 break;
7668 case 10:
7669 switch (sel) {
7670 case 0:
895c2d04 7671 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7672 break;
7673 default:
d75c135e 7674 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7675 break;
7676 }
7677 case 12:
7678 switch (sel) {
7679 case 0:
895c2d04 7680 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7681 break;
7682 default:
d75c135e 7683 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7684 break;
7685 }
5a25ce94
EI
7686 case 13:
7687 switch (sel) {
7688 case 0:
895c2d04 7689 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7690 break;
7691 default:
7692 goto die;
7693 break;
7694 }
7695 break;
7696 case 15:
7697 switch (sel) {
7698 case 1:
895c2d04 7699 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7700 break;
7701 default:
7702 goto die;
7703 break;
7704 }
7705 break;
ead9360e
TS
7706 case 23:
7707 switch (sel) {
7708 case 0:
895c2d04 7709 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7710 break;
7711 default:
d75c135e 7712 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7713 break;
7714 }
7715 break;
7716 default:
d75c135e 7717 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7718 }
7719 } else switch (sel) {
7720 /* GPR registers. */
7721 case 0:
895c2d04 7722 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7723 break;
7724 /* Auxiliary CPU registers */
7725 case 1:
7726 switch (rd) {
7727 case 0:
895c2d04 7728 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7729 break;
7730 case 1:
895c2d04 7731 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7732 break;
7733 case 2:
895c2d04 7734 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7735 break;
7736 case 4:
895c2d04 7737 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7738 break;
7739 case 5:
895c2d04 7740 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7741 break;
7742 case 6:
895c2d04 7743 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7744 break;
7745 case 8:
895c2d04 7746 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7747 break;
7748 case 9:
895c2d04 7749 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7750 break;
7751 case 10:
895c2d04 7752 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7753 break;
7754 case 12:
895c2d04 7755 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7756 break;
7757 case 13:
895c2d04 7758 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7759 break;
7760 case 14:
895c2d04 7761 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7762 break;
7763 case 16:
895c2d04 7764 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7765 break;
7766 default:
7767 goto die;
7768 }
7769 break;
7770 /* Floating point (COP1). */
7771 case 2:
7772 /* XXX: For now we support only a single FPU context. */
7773 if (h == 0) {
a7812ae4 7774 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7775
7776 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7777 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7778 tcg_temp_free_i32(fp0);
ead9360e 7779 } else {
a7812ae4 7780 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7781
7782 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7783 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7784 tcg_temp_free_i32(fp0);
ead9360e
TS
7785 }
7786 break;
7787 case 3:
7788 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7789 save_cpu_state(ctx, 1);
736d120a
PJ
7790 {
7791 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7792
7793 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7794 tcg_temp_free_i32(fs_tmp);
7795 }
4cf8a45f
YK
7796 /* Stop translation as we may have changed hflags */
7797 ctx->bstate = BS_STOP;
ead9360e
TS
7798 break;
7799 /* COP2: Not implemented. */
7800 case 4:
7801 case 5:
7802 /* fall through */
7803 default:
7804 goto die;
7805 }
d12d51d5 7806 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7807 tcg_temp_free(t0);
ead9360e
TS
7808 return;
7809
7810die:
1a3fd9c3 7811 tcg_temp_free(t0);
d12d51d5 7812 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7813 generate_exception(ctx, EXCP_RI);
7814}
7815
7db13fae 7816static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7817{
287c4b84 7818 const char *opn = "ldst";
6af0bf9c 7819
2e15497c 7820 check_cp0_enabled(ctx);
6af0bf9c
FB
7821 switch (opc) {
7822 case OPC_MFC0:
7823 if (rt == 0) {
ead9360e 7824 /* Treat as NOP. */
6af0bf9c
FB
7825 return;
7826 }
d75c135e 7827 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7828 opn = "mfc0";
7829 break;
7830 case OPC_MTC0:
1a3fd9c3 7831 {
1fc7bf6e 7832 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7833
7834 gen_load_gpr(t0, rt);
d75c135e 7835 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7836 tcg_temp_free(t0);
7837 }
6af0bf9c
FB
7838 opn = "mtc0";
7839 break;
d26bc211 7840#if defined(TARGET_MIPS64)
9c2149c8 7841 case OPC_DMFC0:
d75c135e 7842 check_insn(ctx, ISA_MIPS3);
9c2149c8 7843 if (rt == 0) {
ead9360e 7844 /* Treat as NOP. */
9c2149c8
TS
7845 return;
7846 }
d75c135e 7847 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7848 opn = "dmfc0";
7849 break;
7850 case OPC_DMTC0:
d75c135e 7851 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7852 {
1fc7bf6e 7853 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7854
7855 gen_load_gpr(t0, rt);
d75c135e 7856 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7857 tcg_temp_free(t0);
7858 }
9c2149c8
TS
7859 opn = "dmtc0";
7860 break;
534ce69f 7861#endif
ead9360e 7862 case OPC_MFTR:
d75c135e 7863 check_insn(ctx, ASE_MT);
ead9360e
TS
7864 if (rd == 0) {
7865 /* Treat as NOP. */
7866 return;
7867 }
6c5c1e20 7868 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7869 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7870 opn = "mftr";
7871 break;
7872 case OPC_MTTR:
d75c135e 7873 check_insn(ctx, ASE_MT);
6c5c1e20 7874 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7875 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7876 opn = "mttr";
7877 break;
6af0bf9c 7878 case OPC_TLBWI:
6af0bf9c 7879 opn = "tlbwi";
c01fccd2 7880 if (!env->tlb->helper_tlbwi)
29929e34 7881 goto die;
895c2d04 7882 gen_helper_tlbwi(cpu_env);
6af0bf9c 7883 break;
9456c2fb
LA
7884 case OPC_TLBINV:
7885 opn = "tlbinv";
7886 if (ctx->ie >= 2) {
7887 if (!env->tlb->helper_tlbinv) {
7888 goto die;
7889 }
7890 gen_helper_tlbinv(cpu_env);
7891 } /* treat as nop if TLBINV not supported */
7892 break;
7893 case OPC_TLBINVF:
7894 opn = "tlbinvf";
7895 if (ctx->ie >= 2) {
7896 if (!env->tlb->helper_tlbinvf) {
7897 goto die;
7898 }
7899 gen_helper_tlbinvf(cpu_env);
7900 } /* treat as nop if TLBINV not supported */
7901 break;
6af0bf9c 7902 case OPC_TLBWR:
6af0bf9c 7903 opn = "tlbwr";
c01fccd2 7904 if (!env->tlb->helper_tlbwr)
29929e34 7905 goto die;
895c2d04 7906 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7907 break;
7908 case OPC_TLBP:
6af0bf9c 7909 opn = "tlbp";
c01fccd2 7910 if (!env->tlb->helper_tlbp)
29929e34 7911 goto die;
895c2d04 7912 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7913 break;
7914 case OPC_TLBR:
6af0bf9c 7915 opn = "tlbr";
c01fccd2 7916 if (!env->tlb->helper_tlbr)
29929e34 7917 goto die;
895c2d04 7918 gen_helper_tlbr(cpu_env);
6af0bf9c 7919 break;
ce9782f4 7920 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
7921 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7922 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7923 MIPS_DEBUG("CTI in delay / forbidden slot");
7924 goto die;
ce9782f4
LA
7925 } else {
7926 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7927 if (ctx->opcode & (1 << bit_shift)) {
7928 /* OPC_ERETNC */
7929 opn = "eretnc";
7930 check_insn(ctx, ISA_MIPS32R5);
7931 gen_helper_eretnc(cpu_env);
7932 } else {
7933 /* OPC_ERET */
7934 opn = "eret";
7935 check_insn(ctx, ISA_MIPS2);
7936 gen_helper_eret(cpu_env);
7937 }
7938 ctx->bstate = BS_EXCP;
339cd2a8 7939 }
6af0bf9c
FB
7940 break;
7941 case OPC_DERET:
7942 opn = "deret";
d75c135e 7943 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7944 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7945 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7946 MIPS_DEBUG("CTI in delay / forbidden slot");
7947 goto die;
7948 }
6af0bf9c 7949 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7950 MIPS_INVAL(opn);
6af0bf9c
FB
7951 generate_exception(ctx, EXCP_RI);
7952 } else {
895c2d04 7953 gen_helper_deret(cpu_env);
6af0bf9c
FB
7954 ctx->bstate = BS_EXCP;
7955 }
7956 break;
4ad40f36
FB
7957 case OPC_WAIT:
7958 opn = "wait";
d75c135e 7959 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7960 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7961 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7962 MIPS_DEBUG("CTI in delay / forbidden slot");
7963 goto die;
7964 }
4ad40f36
FB
7965 /* If we get an exception, we want to restart at next instruction */
7966 ctx->pc += 4;
7967 save_cpu_state(ctx, 1);
7968 ctx->pc -= 4;
895c2d04 7969 gen_helper_wait(cpu_env);
4ad40f36
FB
7970 ctx->bstate = BS_EXCP;
7971 break;
6af0bf9c 7972 default:
29929e34 7973 die:
923617a3 7974 MIPS_INVAL(opn);
6af0bf9c
FB
7975 generate_exception(ctx, EXCP_RI);
7976 return;
7977 }
2abf314d 7978 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7979 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7980}
f1aa6320 7981#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7982
6ea83fed 7983/* CP1 Branches (before delay slot) */
d75c135e
AJ
7984static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7985 int32_t cc, int32_t offset)
6ea83fed
FB
7986{
7987 target_ulong btarget;
923617a3 7988 const char *opn = "cp1 cond branch";
a7812ae4 7989 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7990
339cd2a8
LA
7991 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7992 MIPS_DEBUG("CTI in delay / forbidden slot");
7993 generate_exception(ctx, EXCP_RI);
7994 goto out;
7995 }
7996
e189e748 7997 if (cc != 0)
d75c135e 7998 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7999
6ea83fed
FB
8000 btarget = ctx->pc + 4 + offset;
8001
7a387fff
TS
8002 switch (op) {
8003 case OPC_BC1F:
d94536f4
AJ
8004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8005 tcg_gen_not_i32(t0, t0);
8006 tcg_gen_andi_i32(t0, t0, 1);
8007 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8008 opn = "bc1f";
6ea83fed 8009 goto not_likely;
7a387fff 8010 case OPC_BC1FL:
d94536f4
AJ
8011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8012 tcg_gen_not_i32(t0, t0);
8013 tcg_gen_andi_i32(t0, t0, 1);
8014 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8015 opn = "bc1fl";
6ea83fed 8016 goto likely;
7a387fff 8017 case OPC_BC1T:
d94536f4
AJ
8018 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8019 tcg_gen_andi_i32(t0, t0, 1);
8020 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8021 opn = "bc1t";
5a5012ec 8022 goto not_likely;
7a387fff 8023 case OPC_BC1TL:
d94536f4
AJ
8024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8025 tcg_gen_andi_i32(t0, t0, 1);
8026 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8027 opn = "bc1tl";
6ea83fed
FB
8028 likely:
8029 ctx->hflags |= MIPS_HFLAG_BL;
8030 break;
5a5012ec 8031 case OPC_BC1FANY2:
a16336e4 8032 {
d94536f4
AJ
8033 TCGv_i32 t1 = tcg_temp_new_i32();
8034 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8036 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8037 tcg_temp_free_i32(t1);
d94536f4
AJ
8038 tcg_gen_andi_i32(t0, t0, 1);
8039 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8040 }
fd4a04eb 8041 opn = "bc1any2f";
5a5012ec
TS
8042 goto not_likely;
8043 case OPC_BC1TANY2:
a16336e4 8044 {
d94536f4
AJ
8045 TCGv_i32 t1 = tcg_temp_new_i32();
8046 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8047 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8048 tcg_gen_or_i32(t0, t0, t1);
8049 tcg_temp_free_i32(t1);
8050 tcg_gen_andi_i32(t0, t0, 1);
8051 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8052 }
fd4a04eb 8053 opn = "bc1any2t";
5a5012ec
TS
8054 goto not_likely;
8055 case OPC_BC1FANY4:
a16336e4 8056 {
d94536f4
AJ
8057 TCGv_i32 t1 = tcg_temp_new_i32();
8058 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8060 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8062 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8064 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8065 tcg_temp_free_i32(t1);
d94536f4
AJ
8066 tcg_gen_andi_i32(t0, t0, 1);
8067 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8068 }
fd4a04eb 8069 opn = "bc1any4f";
5a5012ec
TS
8070 goto not_likely;
8071 case OPC_BC1TANY4:
a16336e4 8072 {
d94536f4
AJ
8073 TCGv_i32 t1 = tcg_temp_new_i32();
8074 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8076 tcg_gen_or_i32(t0, t0, t1);
8077 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8078 tcg_gen_or_i32(t0, t0, t1);
8079 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8080 tcg_gen_or_i32(t0, t0, t1);
8081 tcg_temp_free_i32(t1);
8082 tcg_gen_andi_i32(t0, t0, 1);
8083 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8084 }
fd4a04eb 8085 opn = "bc1any4t";
5a5012ec
TS
8086 not_likely:
8087 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8088 break;
8089 default:
923617a3 8090 MIPS_INVAL(opn);
e397ee33 8091 generate_exception (ctx, EXCP_RI);
6c5c1e20 8092 goto out;
6ea83fed 8093 }
2abf314d 8094 (void)opn; /* avoid a compiler warning */
923617a3 8095 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8096 ctx->hflags, btarget);
8097 ctx->btarget = btarget;
b231c103 8098 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8099 out:
a7812ae4 8100 tcg_temp_free_i32(t0);
6ea83fed
FB
8101}
8102
31837be3
YK
8103/* R6 CP1 Branches */
8104static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8105 int32_t ft, int32_t offset)
8106{
8107 target_ulong btarget;
8108 const char *opn = "cp1 cond branch";
8109 TCGv_i64 t0 = tcg_temp_new_i64();
8110
8111 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8112#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8113 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8114 "\n", ctx->pc);
31837be3
YK
8115#endif
8116 generate_exception(ctx, EXCP_RI);
8117 goto out;
8118 }
8119
8120 gen_load_fpr64(ctx, t0, ft);
8121 tcg_gen_andi_i64(t0, t0, 1);
8122
8123 btarget = addr_add(ctx, ctx->pc + 4, offset);
8124
8125 switch (op) {
8126 case OPC_BC1EQZ:
8127 tcg_gen_xori_i64(t0, t0, 1);
8128 opn = "bc1eqz";
8129 ctx->hflags |= MIPS_HFLAG_BC;
8130 break;
8131 case OPC_BC1NEZ:
8132 /* t0 already set */
8133 opn = "bc1nez";
8134 ctx->hflags |= MIPS_HFLAG_BC;
8135 break;
8136 default:
8137 MIPS_INVAL(opn);
8138 generate_exception(ctx, EXCP_RI);
8139 goto out;
8140 }
8141
8142 tcg_gen_trunc_i64_tl(bcond, t0);
8143
8144 (void)opn; /* avoid a compiler warning */
8145 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8146 ctx->hflags, btarget);
8147 ctx->btarget = btarget;
85479575 8148 ctx->hflags |= MIPS_HFLAG_BDS32;
31837be3
YK
8149
8150out:
8151 tcg_temp_free_i64(t0);
8152}
8153
6af0bf9c 8154/* Coprocessor 1 (FPU) */
5a5012ec 8155
5a5012ec
TS
8156#define FOP(func, fmt) (((fmt) << 21) | (func))
8157
bf4120ad
NF
8158enum fopcode {
8159 OPC_ADD_S = FOP(0, FMT_S),
8160 OPC_SUB_S = FOP(1, FMT_S),
8161 OPC_MUL_S = FOP(2, FMT_S),
8162 OPC_DIV_S = FOP(3, FMT_S),
8163 OPC_SQRT_S = FOP(4, FMT_S),
8164 OPC_ABS_S = FOP(5, FMT_S),
8165 OPC_MOV_S = FOP(6, FMT_S),
8166 OPC_NEG_S = FOP(7, FMT_S),
8167 OPC_ROUND_L_S = FOP(8, FMT_S),
8168 OPC_TRUNC_L_S = FOP(9, FMT_S),
8169 OPC_CEIL_L_S = FOP(10, FMT_S),
8170 OPC_FLOOR_L_S = FOP(11, FMT_S),
8171 OPC_ROUND_W_S = FOP(12, FMT_S),
8172 OPC_TRUNC_W_S = FOP(13, FMT_S),
8173 OPC_CEIL_W_S = FOP(14, FMT_S),
8174 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8175 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8176 OPC_MOVCF_S = FOP(17, FMT_S),
8177 OPC_MOVZ_S = FOP(18, FMT_S),
8178 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8179 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8180 OPC_RECIP_S = FOP(21, FMT_S),
8181 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8182 OPC_SELNEZ_S = FOP(23, FMT_S),
8183 OPC_MADDF_S = FOP(24, FMT_S),
8184 OPC_MSUBF_S = FOP(25, FMT_S),
8185 OPC_RINT_S = FOP(26, FMT_S),
8186 OPC_CLASS_S = FOP(27, FMT_S),
8187 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8188 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8189 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8190 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8191 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8192 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8193 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8194 OPC_RSQRT2_S = FOP(31, FMT_S),
8195 OPC_CVT_D_S = FOP(33, FMT_S),
8196 OPC_CVT_W_S = FOP(36, FMT_S),
8197 OPC_CVT_L_S = FOP(37, FMT_S),
8198 OPC_CVT_PS_S = FOP(38, FMT_S),
8199 OPC_CMP_F_S = FOP (48, FMT_S),
8200 OPC_CMP_UN_S = FOP (49, FMT_S),
8201 OPC_CMP_EQ_S = FOP (50, FMT_S),
8202 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8203 OPC_CMP_OLT_S = FOP (52, FMT_S),
8204 OPC_CMP_ULT_S = FOP (53, FMT_S),
8205 OPC_CMP_OLE_S = FOP (54, FMT_S),
8206 OPC_CMP_ULE_S = FOP (55, FMT_S),
8207 OPC_CMP_SF_S = FOP (56, FMT_S),
8208 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8209 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8210 OPC_CMP_NGL_S = FOP (59, FMT_S),
8211 OPC_CMP_LT_S = FOP (60, FMT_S),
8212 OPC_CMP_NGE_S = FOP (61, FMT_S),
8213 OPC_CMP_LE_S = FOP (62, FMT_S),
8214 OPC_CMP_NGT_S = FOP (63, FMT_S),
8215
8216 OPC_ADD_D = FOP(0, FMT_D),
8217 OPC_SUB_D = FOP(1, FMT_D),
8218 OPC_MUL_D = FOP(2, FMT_D),
8219 OPC_DIV_D = FOP(3, FMT_D),
8220 OPC_SQRT_D = FOP(4, FMT_D),
8221 OPC_ABS_D = FOP(5, FMT_D),
8222 OPC_MOV_D = FOP(6, FMT_D),
8223 OPC_NEG_D = FOP(7, FMT_D),
8224 OPC_ROUND_L_D = FOP(8, FMT_D),
8225 OPC_TRUNC_L_D = FOP(9, FMT_D),
8226 OPC_CEIL_L_D = FOP(10, FMT_D),
8227 OPC_FLOOR_L_D = FOP(11, FMT_D),
8228 OPC_ROUND_W_D = FOP(12, FMT_D),
8229 OPC_TRUNC_W_D = FOP(13, FMT_D),
8230 OPC_CEIL_W_D = FOP(14, FMT_D),
8231 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8232 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8233 OPC_MOVCF_D = FOP(17, FMT_D),
8234 OPC_MOVZ_D = FOP(18, FMT_D),
8235 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8236 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8237 OPC_RECIP_D = FOP(21, FMT_D),
8238 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8239 OPC_SELNEZ_D = FOP(23, FMT_D),
8240 OPC_MADDF_D = FOP(24, FMT_D),
8241 OPC_MSUBF_D = FOP(25, FMT_D),
8242 OPC_RINT_D = FOP(26, FMT_D),
8243 OPC_CLASS_D = FOP(27, FMT_D),
8244 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8245 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8246 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8247 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8248 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8249 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8250 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8251 OPC_RSQRT2_D = FOP(31, FMT_D),
8252 OPC_CVT_S_D = FOP(32, FMT_D),
8253 OPC_CVT_W_D = FOP(36, FMT_D),
8254 OPC_CVT_L_D = FOP(37, FMT_D),
8255 OPC_CMP_F_D = FOP (48, FMT_D),
8256 OPC_CMP_UN_D = FOP (49, FMT_D),
8257 OPC_CMP_EQ_D = FOP (50, FMT_D),
8258 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8259 OPC_CMP_OLT_D = FOP (52, FMT_D),
8260 OPC_CMP_ULT_D = FOP (53, FMT_D),
8261 OPC_CMP_OLE_D = FOP (54, FMT_D),
8262 OPC_CMP_ULE_D = FOP (55, FMT_D),
8263 OPC_CMP_SF_D = FOP (56, FMT_D),
8264 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8265 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8266 OPC_CMP_NGL_D = FOP (59, FMT_D),
8267 OPC_CMP_LT_D = FOP (60, FMT_D),
8268 OPC_CMP_NGE_D = FOP (61, FMT_D),
8269 OPC_CMP_LE_D = FOP (62, FMT_D),
8270 OPC_CMP_NGT_D = FOP (63, FMT_D),
8271
8272 OPC_CVT_S_W = FOP(32, FMT_W),
8273 OPC_CVT_D_W = FOP(33, FMT_W),
8274 OPC_CVT_S_L = FOP(32, FMT_L),
8275 OPC_CVT_D_L = FOP(33, FMT_L),
8276 OPC_CVT_PS_PW = FOP(38, FMT_W),
8277
8278 OPC_ADD_PS = FOP(0, FMT_PS),
8279 OPC_SUB_PS = FOP(1, FMT_PS),
8280 OPC_MUL_PS = FOP(2, FMT_PS),
8281 OPC_DIV_PS = FOP(3, FMT_PS),
8282 OPC_ABS_PS = FOP(5, FMT_PS),
8283 OPC_MOV_PS = FOP(6, FMT_PS),
8284 OPC_NEG_PS = FOP(7, FMT_PS),
8285 OPC_MOVCF_PS = FOP(17, FMT_PS),
8286 OPC_MOVZ_PS = FOP(18, FMT_PS),
8287 OPC_MOVN_PS = FOP(19, FMT_PS),
8288 OPC_ADDR_PS = FOP(24, FMT_PS),
8289 OPC_MULR_PS = FOP(26, FMT_PS),
8290 OPC_RECIP2_PS = FOP(28, FMT_PS),
8291 OPC_RECIP1_PS = FOP(29, FMT_PS),
8292 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8293 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8294
8295 OPC_CVT_S_PU = FOP(32, FMT_PS),
8296 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8297 OPC_CVT_S_PL = FOP(40, FMT_PS),
8298 OPC_PLL_PS = FOP(44, FMT_PS),
8299 OPC_PLU_PS = FOP(45, FMT_PS),
8300 OPC_PUL_PS = FOP(46, FMT_PS),
8301 OPC_PUU_PS = FOP(47, FMT_PS),
8302 OPC_CMP_F_PS = FOP (48, FMT_PS),
8303 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8304 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8305 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8306 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8307 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8308 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8309 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8310 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8311 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8312 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8313 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8314 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8315 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8316 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8317 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8318};
8319
3f493883
YK
8320enum r6_f_cmp_op {
8321 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8322 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8323 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8324 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8325 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8326 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8327 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8328 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8329 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8330 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8331 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8332 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8333 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8334 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8335 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8336 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8337 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8338 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8339 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8340 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8341 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8342 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8343
8344 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8345 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8346 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8347 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8348 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8349 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8350 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8351 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8352 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8353 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8354 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8355 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8356 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8357 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8358 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8359 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8360 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8361 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8362 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8363 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8364 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8365 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8366};
7a387fff 8367static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8368{
923617a3 8369 const char *opn = "cp1 move";
72c3a3ee 8370 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8371
8372 switch (opc) {
8373 case OPC_MFC1:
b6d96bed 8374 {
a7812ae4 8375 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8376
7c979afd 8377 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8378 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8379 tcg_temp_free_i32(fp0);
6958549d 8380 }
6c5c1e20 8381 gen_store_gpr(t0, rt);
6ea83fed
FB
8382 opn = "mfc1";
8383 break;
8384 case OPC_MTC1:
6c5c1e20 8385 gen_load_gpr(t0, rt);
b6d96bed 8386 {
a7812ae4 8387 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8388
8389 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8390 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8391 tcg_temp_free_i32(fp0);
6958549d 8392 }
6ea83fed
FB
8393 opn = "mtc1";
8394 break;
8395 case OPC_CFC1:
895c2d04 8396 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8397 gen_store_gpr(t0, rt);
6ea83fed
FB
8398 opn = "cfc1";
8399 break;
8400 case OPC_CTC1:
6c5c1e20 8401 gen_load_gpr(t0, rt);
4cf8a45f 8402 save_cpu_state(ctx, 1);
736d120a
PJ
8403 {
8404 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8405
8406 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8407 tcg_temp_free_i32(fs_tmp);
8408 }
4cf8a45f
YK
8409 /* Stop translation as we may have changed hflags */
8410 ctx->bstate = BS_STOP;
6ea83fed
FB
8411 opn = "ctc1";
8412 break;
72c3a3ee 8413#if defined(TARGET_MIPS64)
9c2149c8 8414 case OPC_DMFC1:
72c3a3ee 8415 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8416 gen_store_gpr(t0, rt);
5a5012ec
TS
8417 opn = "dmfc1";
8418 break;
9c2149c8 8419 case OPC_DMTC1:
6c5c1e20 8420 gen_load_gpr(t0, rt);
72c3a3ee 8421 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8422 opn = "dmtc1";
8423 break;
72c3a3ee 8424#endif
5a5012ec 8425 case OPC_MFHC1:
b6d96bed 8426 {
a7812ae4 8427 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8428
7f6613ce 8429 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8430 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8431 tcg_temp_free_i32(fp0);
6958549d 8432 }
6c5c1e20 8433 gen_store_gpr(t0, rt);
5a5012ec
TS
8434 opn = "mfhc1";
8435 break;
8436 case OPC_MTHC1:
6c5c1e20 8437 gen_load_gpr(t0, rt);
b6d96bed 8438 {
a7812ae4 8439 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8440
8441 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8442 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8443 tcg_temp_free_i32(fp0);
6958549d 8444 }
5a5012ec
TS
8445 opn = "mthc1";
8446 break;
6ea83fed 8447 default:
923617a3 8448 MIPS_INVAL(opn);
e397ee33 8449 generate_exception (ctx, EXCP_RI);
6c5c1e20 8450 goto out;
6ea83fed 8451 }
2abf314d 8452 (void)opn; /* avoid a compiler warning */
6ea83fed 8453 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8454
8455 out:
8456 tcg_temp_free(t0);
6ea83fed
FB
8457}
8458
5a5012ec
TS
8459static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8460{
42a268c2 8461 TCGLabel *l1;
e214b9bb 8462 TCGCond cond;
af58f9ca
AJ
8463 TCGv_i32 t0;
8464
8465 if (rd == 0) {
8466 /* Treat as NOP. */
8467 return;
8468 }
6ea83fed 8469
e214b9bb 8470 if (tf)
e214b9bb 8471 cond = TCG_COND_EQ;
27848470
TS
8472 else
8473 cond = TCG_COND_NE;
8474
af58f9ca
AJ
8475 l1 = gen_new_label();
8476 t0 = tcg_temp_new_i32();
fa31af0e 8477 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8478 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8479 tcg_temp_free_i32(t0);
af58f9ca
AJ
8480 if (rs == 0) {
8481 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8482 } else {
8483 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8484 }
e214b9bb 8485 gen_set_label(l1);
5a5012ec
TS
8486}
8487
7c979afd
LA
8488static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8489 int tf)
a16336e4 8490{
a16336e4 8491 int cond;
cbc37b28 8492 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8493 TCGLabel *l1 = gen_new_label();
a16336e4 8494
a16336e4
TS
8495 if (tf)
8496 cond = TCG_COND_EQ;
8497 else
8498 cond = TCG_COND_NE;
8499
fa31af0e 8500 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8501 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8502 gen_load_fpr32(ctx, t0, fs);
8503 gen_store_fpr32(ctx, t0, fd);
a16336e4 8504 gen_set_label(l1);
cbc37b28 8505 tcg_temp_free_i32(t0);
5a5012ec 8506}
a16336e4 8507
b6d96bed 8508static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8509{
a16336e4 8510 int cond;
cbc37b28
AJ
8511 TCGv_i32 t0 = tcg_temp_new_i32();
8512 TCGv_i64 fp0;
42a268c2 8513 TCGLabel *l1 = gen_new_label();
a16336e4 8514
a16336e4
TS
8515 if (tf)
8516 cond = TCG_COND_EQ;
8517 else
8518 cond = TCG_COND_NE;
8519
fa31af0e 8520 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8521 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8522 tcg_temp_free_i32(t0);
11f94258 8523 fp0 = tcg_temp_new_i64();
9bf3eb2c 8524 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8525 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8526 tcg_temp_free_i64(fp0);
cbc37b28 8527 gen_set_label(l1);
a16336e4
TS
8528}
8529
7f6613ce
PJ
8530static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8531 int cc, int tf)
a16336e4
TS
8532{
8533 int cond;
cbc37b28 8534 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8535 TCGLabel *l1 = gen_new_label();
8536 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8537
8538 if (tf)
8539 cond = TCG_COND_EQ;
8540 else
8541 cond = TCG_COND_NE;
8542
fa31af0e 8543 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8544 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8545 gen_load_fpr32(ctx, t0, fs);
8546 gen_store_fpr32(ctx, t0, fd);
a16336e4 8547 gen_set_label(l1);
9bf3eb2c 8548
fa31af0e 8549 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8550 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8551 gen_load_fpr32h(ctx, t0, fs);
8552 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8553 tcg_temp_free_i32(t0);
a16336e4 8554 gen_set_label(l2);
a16336e4
TS
8555}
8556
e7f16abb
LA
8557static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8558 int fs)
8559{
8560 TCGv_i32 t1 = tcg_const_i32(0);
8561 TCGv_i32 fp0 = tcg_temp_new_i32();
8562 TCGv_i32 fp1 = tcg_temp_new_i32();
8563 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8564 gen_load_fpr32(ctx, fp0, fd);
8565 gen_load_fpr32(ctx, fp1, ft);
8566 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8567
8568 switch (op1) {
8569 case OPC_SEL_S:
8570 tcg_gen_andi_i32(fp0, fp0, 1);
8571 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8572 break;
8573 case OPC_SELEQZ_S:
8574 tcg_gen_andi_i32(fp1, fp1, 1);
8575 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8576 break;
8577 case OPC_SELNEZ_S:
8578 tcg_gen_andi_i32(fp1, fp1, 1);
8579 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8580 break;
8581 default:
8582 MIPS_INVAL("gen_sel_s");
8583 generate_exception (ctx, EXCP_RI);
8584 break;
8585 }
8586
7c979afd 8587 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8588 tcg_temp_free_i32(fp2);
8589 tcg_temp_free_i32(fp1);
8590 tcg_temp_free_i32(fp0);
8591 tcg_temp_free_i32(t1);
8592}
8593
8594static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8595 int fs)
8596{
8597 TCGv_i64 t1 = tcg_const_i64(0);
8598 TCGv_i64 fp0 = tcg_temp_new_i64();
8599 TCGv_i64 fp1 = tcg_temp_new_i64();
8600 TCGv_i64 fp2 = tcg_temp_new_i64();
8601 gen_load_fpr64(ctx, fp0, fd);
8602 gen_load_fpr64(ctx, fp1, ft);
8603 gen_load_fpr64(ctx, fp2, fs);
8604
8605 switch (op1) {
8606 case OPC_SEL_D:
8607 tcg_gen_andi_i64(fp0, fp0, 1);
8608 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8609 break;
8610 case OPC_SELEQZ_D:
8611 tcg_gen_andi_i64(fp1, fp1, 1);
8612 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8613 break;
8614 case OPC_SELNEZ_D:
8615 tcg_gen_andi_i64(fp1, fp1, 1);
8616 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8617 break;
8618 default:
8619 MIPS_INVAL("gen_sel_d");
8620 generate_exception (ctx, EXCP_RI);
8621 break;
8622 }
8623
8624 gen_store_fpr64(ctx, fp0, fd);
8625 tcg_temp_free_i64(fp2);
8626 tcg_temp_free_i64(fp1);
8627 tcg_temp_free_i64(fp0);
8628 tcg_temp_free_i64(t1);
8629}
6ea83fed 8630
bf4120ad 8631static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8632 int ft, int fs, int fd, int cc)
6ea83fed 8633{
923617a3 8634 const char *opn = "farith";
6ea83fed
FB
8635 const char *condnames[] = {
8636 "c.f",
8637 "c.un",
8638 "c.eq",
8639 "c.ueq",
8640 "c.olt",
8641 "c.ult",
8642 "c.ole",
8643 "c.ule",
8644 "c.sf",
8645 "c.ngle",
8646 "c.seq",
8647 "c.ngl",
8648 "c.lt",
8649 "c.nge",
8650 "c.le",
8651 "c.ngt",
8652 };
5a1e8ffb
TS
8653 const char *condnames_abs[] = {
8654 "cabs.f",
8655 "cabs.un",
8656 "cabs.eq",
8657 "cabs.ueq",
8658 "cabs.olt",
8659 "cabs.ult",
8660 "cabs.ole",
8661 "cabs.ule",
8662 "cabs.sf",
8663 "cabs.ngle",
8664 "cabs.seq",
8665 "cabs.ngl",
8666 "cabs.lt",
8667 "cabs.nge",
8668 "cabs.le",
8669 "cabs.ngt",
8670 };
8671 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8672 uint32_t func = ctx->opcode & 0x3f;
8673
bf4120ad
NF
8674 switch (op1) {
8675 case OPC_ADD_S:
b6d96bed 8676 {
a7812ae4
PB
8677 TCGv_i32 fp0 = tcg_temp_new_i32();
8678 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8679
7c979afd
LA
8680 gen_load_fpr32(ctx, fp0, fs);
8681 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8682 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8683 tcg_temp_free_i32(fp1);
7c979afd 8684 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8685 tcg_temp_free_i32(fp0);
b6d96bed 8686 }
5a5012ec 8687 opn = "add.s";
5a1e8ffb 8688 optype = BINOP;
5a5012ec 8689 break;
bf4120ad 8690 case OPC_SUB_S:
b6d96bed 8691 {
a7812ae4
PB
8692 TCGv_i32 fp0 = tcg_temp_new_i32();
8693 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8694
7c979afd
LA
8695 gen_load_fpr32(ctx, fp0, fs);
8696 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8697 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8698 tcg_temp_free_i32(fp1);
7c979afd 8699 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8700 tcg_temp_free_i32(fp0);
b6d96bed 8701 }
5a5012ec 8702 opn = "sub.s";
5a1e8ffb 8703 optype = BINOP;
5a5012ec 8704 break;
bf4120ad 8705 case OPC_MUL_S:
b6d96bed 8706 {
a7812ae4
PB
8707 TCGv_i32 fp0 = tcg_temp_new_i32();
8708 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8709
7c979afd
LA
8710 gen_load_fpr32(ctx, fp0, fs);
8711 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8712 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8713 tcg_temp_free_i32(fp1);
7c979afd 8714 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8715 tcg_temp_free_i32(fp0);
b6d96bed 8716 }
5a5012ec 8717 opn = "mul.s";
5a1e8ffb 8718 optype = BINOP;
5a5012ec 8719 break;
bf4120ad 8720 case OPC_DIV_S:
b6d96bed 8721 {
a7812ae4
PB
8722 TCGv_i32 fp0 = tcg_temp_new_i32();
8723 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8724
7c979afd
LA
8725 gen_load_fpr32(ctx, fp0, fs);
8726 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8727 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8728 tcg_temp_free_i32(fp1);
7c979afd 8729 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8730 tcg_temp_free_i32(fp0);
b6d96bed 8731 }
5a5012ec 8732 opn = "div.s";
5a1e8ffb 8733 optype = BINOP;
5a5012ec 8734 break;
bf4120ad 8735 case OPC_SQRT_S:
b6d96bed 8736 {
a7812ae4 8737 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8738
7c979afd 8739 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8740 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8741 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8742 tcg_temp_free_i32(fp0);
b6d96bed 8743 }
5a5012ec
TS
8744 opn = "sqrt.s";
8745 break;
bf4120ad 8746 case OPC_ABS_S:
b6d96bed 8747 {
a7812ae4 8748 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8749
7c979afd 8750 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8751 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8752 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8753 tcg_temp_free_i32(fp0);
b6d96bed 8754 }
5a5012ec
TS
8755 opn = "abs.s";
8756 break;
bf4120ad 8757 case OPC_MOV_S:
b6d96bed 8758 {
a7812ae4 8759 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8760
7c979afd
LA
8761 gen_load_fpr32(ctx, fp0, fs);
8762 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8763 tcg_temp_free_i32(fp0);
b6d96bed 8764 }
5a5012ec
TS
8765 opn = "mov.s";
8766 break;
bf4120ad 8767 case OPC_NEG_S:
b6d96bed 8768 {
a7812ae4 8769 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8770
7c979afd 8771 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8772 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8773 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8774 tcg_temp_free_i32(fp0);
b6d96bed 8775 }
5a5012ec
TS
8776 opn = "neg.s";
8777 break;
bf4120ad 8778 case OPC_ROUND_L_S:
5e755519 8779 check_cp1_64bitmode(ctx);
b6d96bed 8780 {
a7812ae4
PB
8781 TCGv_i32 fp32 = tcg_temp_new_i32();
8782 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8783
7c979afd 8784 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8785 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8786 tcg_temp_free_i32(fp32);
b6d96bed 8787 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8788 tcg_temp_free_i64(fp64);
b6d96bed 8789 }
5a5012ec
TS
8790 opn = "round.l.s";
8791 break;
bf4120ad 8792 case OPC_TRUNC_L_S:
5e755519 8793 check_cp1_64bitmode(ctx);
b6d96bed 8794 {
a7812ae4
PB
8795 TCGv_i32 fp32 = tcg_temp_new_i32();
8796 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8797
7c979afd 8798 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8799 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8800 tcg_temp_free_i32(fp32);
b6d96bed 8801 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8802 tcg_temp_free_i64(fp64);
b6d96bed 8803 }
5a5012ec
TS
8804 opn = "trunc.l.s";
8805 break;
bf4120ad 8806 case OPC_CEIL_L_S:
5e755519 8807 check_cp1_64bitmode(ctx);
b6d96bed 8808 {
a7812ae4
PB
8809 TCGv_i32 fp32 = tcg_temp_new_i32();
8810 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8811
7c979afd 8812 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8813 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8814 tcg_temp_free_i32(fp32);
b6d96bed 8815 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8816 tcg_temp_free_i64(fp64);
b6d96bed 8817 }
5a5012ec
TS
8818 opn = "ceil.l.s";
8819 break;
bf4120ad 8820 case OPC_FLOOR_L_S:
5e755519 8821 check_cp1_64bitmode(ctx);
b6d96bed 8822 {
a7812ae4
PB
8823 TCGv_i32 fp32 = tcg_temp_new_i32();
8824 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8825
7c979afd 8826 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8827 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8828 tcg_temp_free_i32(fp32);
b6d96bed 8829 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8830 tcg_temp_free_i64(fp64);
b6d96bed 8831 }
5a5012ec
TS
8832 opn = "floor.l.s";
8833 break;
bf4120ad 8834 case OPC_ROUND_W_S:
b6d96bed 8835 {
a7812ae4 8836 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8837
7c979afd 8838 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8839 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8840 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8841 tcg_temp_free_i32(fp0);
b6d96bed 8842 }
5a5012ec
TS
8843 opn = "round.w.s";
8844 break;
bf4120ad 8845 case OPC_TRUNC_W_S:
b6d96bed 8846 {
a7812ae4 8847 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8848
7c979afd 8849 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8850 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8851 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8852 tcg_temp_free_i32(fp0);
b6d96bed 8853 }
5a5012ec
TS
8854 opn = "trunc.w.s";
8855 break;
bf4120ad 8856 case OPC_CEIL_W_S:
b6d96bed 8857 {
a7812ae4 8858 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8859
7c979afd 8860 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8861 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8862 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8863 tcg_temp_free_i32(fp0);
b6d96bed 8864 }
5a5012ec
TS
8865 opn = "ceil.w.s";
8866 break;
bf4120ad 8867 case OPC_FLOOR_W_S:
b6d96bed 8868 {
a7812ae4 8869 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8870
7c979afd 8871 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8872 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8873 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8874 tcg_temp_free_i32(fp0);
b6d96bed 8875 }
5a5012ec
TS
8876 opn = "floor.w.s";
8877 break;
e7f16abb
LA
8878 case OPC_SEL_S:
8879 check_insn(ctx, ISA_MIPS32R6);
8880 gen_sel_s(ctx, op1, fd, ft, fs);
8881 opn = "sel.s";
8882 break;
8883 case OPC_SELEQZ_S:
8884 check_insn(ctx, ISA_MIPS32R6);
8885 gen_sel_s(ctx, op1, fd, ft, fs);
8886 opn = "seleqz.s";
8887 break;
8888 case OPC_SELNEZ_S:
8889 check_insn(ctx, ISA_MIPS32R6);
8890 gen_sel_s(ctx, op1, fd, ft, fs);
8891 opn = "selnez.s";
8892 break;
bf4120ad 8893 case OPC_MOVCF_S:
fecd2646 8894 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8895 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8896 opn = "movcf.s";
8897 break;
bf4120ad 8898 case OPC_MOVZ_S:
fecd2646 8899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8900 {
42a268c2 8901 TCGLabel *l1 = gen_new_label();
c9297f4d 8902 TCGv_i32 fp0;
a16336e4 8903
c9297f4d
AJ
8904 if (ft != 0) {
8905 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8906 }
8907 fp0 = tcg_temp_new_i32();
7c979afd
LA
8908 gen_load_fpr32(ctx, fp0, fs);
8909 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8910 tcg_temp_free_i32(fp0);
a16336e4
TS
8911 gen_set_label(l1);
8912 }
5a5012ec
TS
8913 opn = "movz.s";
8914 break;
bf4120ad 8915 case OPC_MOVN_S:
fecd2646 8916 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8917 {
42a268c2 8918 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8919 TCGv_i32 fp0;
8920
8921 if (ft != 0) {
8922 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8923 fp0 = tcg_temp_new_i32();
7c979afd
LA
8924 gen_load_fpr32(ctx, fp0, fs);
8925 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8926 tcg_temp_free_i32(fp0);
8927 gen_set_label(l1);
8928 }
a16336e4 8929 }
5a5012ec
TS
8930 opn = "movn.s";
8931 break;
bf4120ad 8932 case OPC_RECIP_S:
b8aa4598 8933 check_cop1x(ctx);
b6d96bed 8934 {
a7812ae4 8935 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8936
7c979afd 8937 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8938 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8939 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8940 tcg_temp_free_i32(fp0);
b6d96bed 8941 }
57fa1fb3
TS
8942 opn = "recip.s";
8943 break;
bf4120ad 8944 case OPC_RSQRT_S:
b8aa4598 8945 check_cop1x(ctx);
b6d96bed 8946 {
a7812ae4 8947 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8948
7c979afd 8949 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8950 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8951 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8952 tcg_temp_free_i32(fp0);
b6d96bed 8953 }
57fa1fb3
TS
8954 opn = "rsqrt.s";
8955 break;
e7f16abb
LA
8956 case OPC_MADDF_S:
8957 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8958 {
a7812ae4
PB
8959 TCGv_i32 fp0 = tcg_temp_new_i32();
8960 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8961 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8962 gen_load_fpr32(ctx, fp0, fs);
8963 gen_load_fpr32(ctx, fp1, ft);
8964 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8965 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8966 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 8967 tcg_temp_free_i32(fp2);
a7812ae4 8968 tcg_temp_free_i32(fp1);
a7812ae4 8969 tcg_temp_free_i32(fp0);
e7f16abb 8970 opn = "maddf.s";
b6d96bed 8971 }
57fa1fb3 8972 break;
e7f16abb
LA
8973 case OPC_MSUBF_S:
8974 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8975 {
a7812ae4 8976 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8977 TCGv_i32 fp1 = tcg_temp_new_i32();
8978 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8979 gen_load_fpr32(ctx, fp0, fs);
8980 gen_load_fpr32(ctx, fp1, ft);
8981 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8982 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8983 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8984 tcg_temp_free_i32(fp2);
8985 tcg_temp_free_i32(fp1);
a7812ae4 8986 tcg_temp_free_i32(fp0);
e7f16abb 8987 opn = "msubf.s";
b6d96bed 8988 }
57fa1fb3 8989 break;
e7f16abb
LA
8990 case OPC_RINT_S:
8991 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8992 {
a7812ae4 8993 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8994 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8995 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 8996 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8997 tcg_temp_free_i32(fp0);
e7f16abb 8998 opn = "rint.s";
b6d96bed 8999 }
57fa1fb3 9000 break;
e7f16abb
LA
9001 case OPC_CLASS_S:
9002 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9003 {
e7f16abb 9004 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9005 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9006 gen_helper_float_class_s(fp0, fp0);
7c979afd 9007 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9008 tcg_temp_free_i32(fp0);
9009 opn = "class.s";
9010 }
9011 break;
9012 case OPC_MIN_S: /* OPC_RECIP2_S */
9013 if (ctx->insn_flags & ISA_MIPS32R6) {
9014 /* OPC_MIN_S */
a7812ae4
PB
9015 TCGv_i32 fp0 = tcg_temp_new_i32();
9016 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9017 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9018 gen_load_fpr32(ctx, fp0, fs);
9019 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9020 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9021 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9022 tcg_temp_free_i32(fp2);
9023 tcg_temp_free_i32(fp1);
9024 tcg_temp_free_i32(fp0);
9025 opn = "min.s";
9026 } else {
9027 /* OPC_RECIP2_S */
9028 check_cp1_64bitmode(ctx);
9029 {
9030 TCGv_i32 fp0 = tcg_temp_new_i32();
9031 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9032
7c979afd
LA
9033 gen_load_fpr32(ctx, fp0, fs);
9034 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9035 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9036 tcg_temp_free_i32(fp1);
7c979afd 9037 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9038 tcg_temp_free_i32(fp0);
9039 }
9040 opn = "recip2.s";
9041 }
9042 break;
9043 case OPC_MINA_S: /* OPC_RECIP1_S */
9044 if (ctx->insn_flags & ISA_MIPS32R6) {
9045 /* OPC_MINA_S */
9046 TCGv_i32 fp0 = tcg_temp_new_i32();
9047 TCGv_i32 fp1 = tcg_temp_new_i32();
9048 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9049 gen_load_fpr32(ctx, fp0, fs);
9050 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9051 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9052 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9053 tcg_temp_free_i32(fp2);
9054 tcg_temp_free_i32(fp1);
9055 tcg_temp_free_i32(fp0);
9056 opn = "mina.s";
9057 } else {
9058 /* OPC_RECIP1_S */
9059 check_cp1_64bitmode(ctx);
9060 {
9061 TCGv_i32 fp0 = tcg_temp_new_i32();
9062
7c979afd 9063 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9064 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9065 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9066 tcg_temp_free_i32(fp0);
9067 }
9068 opn = "recip1.s";
9069 }
9070 break;
9071 case OPC_MAX_S: /* OPC_RSQRT1_S */
9072 if (ctx->insn_flags & ISA_MIPS32R6) {
9073 /* OPC_MAX_S */
9074 TCGv_i32 fp0 = tcg_temp_new_i32();
9075 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9076 gen_load_fpr32(ctx, fp0, fs);
9077 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9078 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9079 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9080 tcg_temp_free_i32(fp1);
9081 tcg_temp_free_i32(fp0);
9082 opn = "max.s";
9083 } else {
9084 /* OPC_RSQRT1_S */
9085 check_cp1_64bitmode(ctx);
9086 {
9087 TCGv_i32 fp0 = tcg_temp_new_i32();
9088
7c979afd 9089 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9090 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9091 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9092 tcg_temp_free_i32(fp0);
9093 }
9094 opn = "rsqrt1.s";
9095 }
9096 break;
9097 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9098 if (ctx->insn_flags & ISA_MIPS32R6) {
9099 /* OPC_MAXA_S */
9100 TCGv_i32 fp0 = tcg_temp_new_i32();
9101 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9102 gen_load_fpr32(ctx, fp0, fs);
9103 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9104 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9105 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9106 tcg_temp_free_i32(fp1);
a7812ae4 9107 tcg_temp_free_i32(fp0);
e7f16abb
LA
9108 opn = "maxa.s";
9109 } else {
9110 /* OPC_RSQRT2_S */
9111 check_cp1_64bitmode(ctx);
9112 {
9113 TCGv_i32 fp0 = tcg_temp_new_i32();
9114 TCGv_i32 fp1 = tcg_temp_new_i32();
9115
7c979afd
LA
9116 gen_load_fpr32(ctx, fp0, fs);
9117 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9118 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9119 tcg_temp_free_i32(fp1);
7c979afd 9120 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9121 tcg_temp_free_i32(fp0);
9122 }
9123 opn = "rsqrt2.s";
b6d96bed 9124 }
57fa1fb3 9125 break;
bf4120ad 9126 case OPC_CVT_D_S:
5e755519 9127 check_cp1_registers(ctx, fd);
b6d96bed 9128 {
a7812ae4
PB
9129 TCGv_i32 fp32 = tcg_temp_new_i32();
9130 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9131
7c979afd 9132 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9133 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9134 tcg_temp_free_i32(fp32);
b6d96bed 9135 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9136 tcg_temp_free_i64(fp64);
b6d96bed 9137 }
5a5012ec
TS
9138 opn = "cvt.d.s";
9139 break;
bf4120ad 9140 case OPC_CVT_W_S:
b6d96bed 9141 {
a7812ae4 9142 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9143
7c979afd 9144 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9145 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9146 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9147 tcg_temp_free_i32(fp0);
b6d96bed 9148 }
5a5012ec
TS
9149 opn = "cvt.w.s";
9150 break;
bf4120ad 9151 case OPC_CVT_L_S:
5e755519 9152 check_cp1_64bitmode(ctx);
b6d96bed 9153 {
a7812ae4
PB
9154 TCGv_i32 fp32 = tcg_temp_new_i32();
9155 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9156
7c979afd 9157 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9158 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9159 tcg_temp_free_i32(fp32);
b6d96bed 9160 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9161 tcg_temp_free_i64(fp64);
b6d96bed 9162 }
5a5012ec
TS
9163 opn = "cvt.l.s";
9164 break;
bf4120ad 9165 case OPC_CVT_PS_S:
fecd2646 9166 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9167 check_cp1_64bitmode(ctx);
b6d96bed 9168 {
a7812ae4
PB
9169 TCGv_i64 fp64 = tcg_temp_new_i64();
9170 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9171 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9172
7c979afd
LA
9173 gen_load_fpr32(ctx, fp32_0, fs);
9174 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9175 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9176 tcg_temp_free_i32(fp32_1);
9177 tcg_temp_free_i32(fp32_0);
36aa55dc 9178 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9179 tcg_temp_free_i64(fp64);
b6d96bed 9180 }
5a5012ec
TS
9181 opn = "cvt.ps.s";
9182 break;
bf4120ad
NF
9183 case OPC_CMP_F_S:
9184 case OPC_CMP_UN_S:
9185 case OPC_CMP_EQ_S:
9186 case OPC_CMP_UEQ_S:
9187 case OPC_CMP_OLT_S:
9188 case OPC_CMP_ULT_S:
9189 case OPC_CMP_OLE_S:
9190 case OPC_CMP_ULE_S:
9191 case OPC_CMP_SF_S:
9192 case OPC_CMP_NGLE_S:
9193 case OPC_CMP_SEQ_S:
9194 case OPC_CMP_NGL_S:
9195 case OPC_CMP_LT_S:
9196 case OPC_CMP_NGE_S:
9197 case OPC_CMP_LE_S:
9198 case OPC_CMP_NGT_S:
fecd2646 9199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9200 if (ctx->opcode & (1 << 6)) {
9201 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9202 opn = condnames_abs[func-48];
9203 } else {
9204 gen_cmp_s(ctx, func-48, ft, fs, cc);
9205 opn = condnames[func-48];
5a1e8ffb 9206 }
5a5012ec 9207 break;
bf4120ad 9208 case OPC_ADD_D:
5e755519 9209 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9210 {
a7812ae4
PB
9211 TCGv_i64 fp0 = tcg_temp_new_i64();
9212 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9213
9214 gen_load_fpr64(ctx, fp0, fs);
9215 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9216 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9217 tcg_temp_free_i64(fp1);
b6d96bed 9218 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9219 tcg_temp_free_i64(fp0);
b6d96bed 9220 }
6ea83fed 9221 opn = "add.d";
5a1e8ffb 9222 optype = BINOP;
6ea83fed 9223 break;
bf4120ad 9224 case OPC_SUB_D:
5e755519 9225 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9226 {
a7812ae4
PB
9227 TCGv_i64 fp0 = tcg_temp_new_i64();
9228 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9229
9230 gen_load_fpr64(ctx, fp0, fs);
9231 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9232 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9233 tcg_temp_free_i64(fp1);
b6d96bed 9234 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9235 tcg_temp_free_i64(fp0);
b6d96bed 9236 }
6ea83fed 9237 opn = "sub.d";
5a1e8ffb 9238 optype = BINOP;
6ea83fed 9239 break;
bf4120ad 9240 case OPC_MUL_D:
5e755519 9241 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9242 {
a7812ae4
PB
9243 TCGv_i64 fp0 = tcg_temp_new_i64();
9244 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9245
9246 gen_load_fpr64(ctx, fp0, fs);
9247 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9248 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9249 tcg_temp_free_i64(fp1);
b6d96bed 9250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9251 tcg_temp_free_i64(fp0);
b6d96bed 9252 }
6ea83fed 9253 opn = "mul.d";
5a1e8ffb 9254 optype = BINOP;
6ea83fed 9255 break;
bf4120ad 9256 case OPC_DIV_D:
5e755519 9257 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9258 {
a7812ae4
PB
9259 TCGv_i64 fp0 = tcg_temp_new_i64();
9260 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9261
9262 gen_load_fpr64(ctx, fp0, fs);
9263 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9264 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9265 tcg_temp_free_i64(fp1);
b6d96bed 9266 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9267 tcg_temp_free_i64(fp0);
b6d96bed 9268 }
6ea83fed 9269 opn = "div.d";
5a1e8ffb 9270 optype = BINOP;
6ea83fed 9271 break;
bf4120ad 9272 case OPC_SQRT_D:
5e755519 9273 check_cp1_registers(ctx, fs | fd);
b6d96bed 9274 {
a7812ae4 9275 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9276
9277 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9278 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9279 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9280 tcg_temp_free_i64(fp0);
b6d96bed 9281 }
6ea83fed
FB
9282 opn = "sqrt.d";
9283 break;
bf4120ad 9284 case OPC_ABS_D:
5e755519 9285 check_cp1_registers(ctx, fs | fd);
b6d96bed 9286 {
a7812ae4 9287 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9288
9289 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9290 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9291 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9292 tcg_temp_free_i64(fp0);
b6d96bed 9293 }
6ea83fed
FB
9294 opn = "abs.d";
9295 break;
bf4120ad 9296 case OPC_MOV_D:
5e755519 9297 check_cp1_registers(ctx, fs | fd);
b6d96bed 9298 {
a7812ae4 9299 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9300
9301 gen_load_fpr64(ctx, fp0, fs);
9302 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9303 tcg_temp_free_i64(fp0);
b6d96bed 9304 }
6ea83fed
FB
9305 opn = "mov.d";
9306 break;
bf4120ad 9307 case OPC_NEG_D:
5e755519 9308 check_cp1_registers(ctx, fs | fd);
b6d96bed 9309 {
a7812ae4 9310 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9311
9312 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9313 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9314 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9315 tcg_temp_free_i64(fp0);
b6d96bed 9316 }
6ea83fed
FB
9317 opn = "neg.d";
9318 break;
bf4120ad 9319 case OPC_ROUND_L_D:
5e755519 9320 check_cp1_64bitmode(ctx);
b6d96bed 9321 {
a7812ae4 9322 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9323
9324 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9325 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9326 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9327 tcg_temp_free_i64(fp0);
b6d96bed 9328 }
5a5012ec
TS
9329 opn = "round.l.d";
9330 break;
bf4120ad 9331 case OPC_TRUNC_L_D:
5e755519 9332 check_cp1_64bitmode(ctx);
b6d96bed 9333 {
a7812ae4 9334 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9335
9336 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9337 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9338 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9339 tcg_temp_free_i64(fp0);
b6d96bed 9340 }
5a5012ec
TS
9341 opn = "trunc.l.d";
9342 break;
bf4120ad 9343 case OPC_CEIL_L_D:
5e755519 9344 check_cp1_64bitmode(ctx);
b6d96bed 9345 {
a7812ae4 9346 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9347
9348 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9349 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9350 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9351 tcg_temp_free_i64(fp0);
b6d96bed 9352 }
5a5012ec
TS
9353 opn = "ceil.l.d";
9354 break;
bf4120ad 9355 case OPC_FLOOR_L_D:
5e755519 9356 check_cp1_64bitmode(ctx);
b6d96bed 9357 {
a7812ae4 9358 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9359
9360 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9361 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9362 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9363 tcg_temp_free_i64(fp0);
b6d96bed 9364 }
5a5012ec
TS
9365 opn = "floor.l.d";
9366 break;
bf4120ad 9367 case OPC_ROUND_W_D:
5e755519 9368 check_cp1_registers(ctx, fs);
b6d96bed 9369 {
a7812ae4
PB
9370 TCGv_i32 fp32 = tcg_temp_new_i32();
9371 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9372
9373 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9374 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9375 tcg_temp_free_i64(fp64);
7c979afd 9376 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9377 tcg_temp_free_i32(fp32);
b6d96bed 9378 }
6ea83fed
FB
9379 opn = "round.w.d";
9380 break;
bf4120ad 9381 case OPC_TRUNC_W_D:
5e755519 9382 check_cp1_registers(ctx, fs);
b6d96bed 9383 {
a7812ae4
PB
9384 TCGv_i32 fp32 = tcg_temp_new_i32();
9385 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9386
9387 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9388 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9389 tcg_temp_free_i64(fp64);
7c979afd 9390 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9391 tcg_temp_free_i32(fp32);
b6d96bed 9392 }
6ea83fed
FB
9393 opn = "trunc.w.d";
9394 break;
bf4120ad 9395 case OPC_CEIL_W_D:
5e755519 9396 check_cp1_registers(ctx, fs);
b6d96bed 9397 {
a7812ae4
PB
9398 TCGv_i32 fp32 = tcg_temp_new_i32();
9399 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9400
9401 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9402 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9403 tcg_temp_free_i64(fp64);
7c979afd 9404 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9405 tcg_temp_free_i32(fp32);
b6d96bed 9406 }
6ea83fed
FB
9407 opn = "ceil.w.d";
9408 break;
bf4120ad 9409 case OPC_FLOOR_W_D:
5e755519 9410 check_cp1_registers(ctx, fs);
b6d96bed 9411 {
a7812ae4
PB
9412 TCGv_i32 fp32 = tcg_temp_new_i32();
9413 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9414
9415 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9416 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9417 tcg_temp_free_i64(fp64);
7c979afd 9418 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9419 tcg_temp_free_i32(fp32);
b6d96bed 9420 }
7a387fff 9421 opn = "floor.w.d";
6ea83fed 9422 break;
e7f16abb
LA
9423 case OPC_SEL_D:
9424 check_insn(ctx, ISA_MIPS32R6);
9425 gen_sel_d(ctx, op1, fd, ft, fs);
9426 opn = "sel.d";
9427 break;
9428 case OPC_SELEQZ_D:
9429 check_insn(ctx, ISA_MIPS32R6);
9430 gen_sel_d(ctx, op1, fd, ft, fs);
9431 opn = "seleqz.d";
9432 break;
9433 case OPC_SELNEZ_D:
9434 check_insn(ctx, ISA_MIPS32R6);
9435 gen_sel_d(ctx, op1, fd, ft, fs);
9436 opn = "selnez.d";
9437 break;
bf4120ad 9438 case OPC_MOVCF_D:
fecd2646 9439 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9440 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9441 opn = "movcf.d";
dd016883 9442 break;
bf4120ad 9443 case OPC_MOVZ_D:
fecd2646 9444 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9445 {
42a268c2 9446 TCGLabel *l1 = gen_new_label();
c9297f4d 9447 TCGv_i64 fp0;
a16336e4 9448
c9297f4d
AJ
9449 if (ft != 0) {
9450 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9451 }
9452 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9453 gen_load_fpr64(ctx, fp0, fs);
9454 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9455 tcg_temp_free_i64(fp0);
a16336e4
TS
9456 gen_set_label(l1);
9457 }
5a5012ec
TS
9458 opn = "movz.d";
9459 break;
bf4120ad 9460 case OPC_MOVN_D:
fecd2646 9461 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9462 {
42a268c2 9463 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9464 TCGv_i64 fp0;
9465
9466 if (ft != 0) {
9467 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9468 fp0 = tcg_temp_new_i64();
9469 gen_load_fpr64(ctx, fp0, fs);
9470 gen_store_fpr64(ctx, fp0, fd);
9471 tcg_temp_free_i64(fp0);
9472 gen_set_label(l1);
9473 }
a16336e4 9474 }
5a5012ec 9475 opn = "movn.d";
6ea83fed 9476 break;
bf4120ad 9477 case OPC_RECIP_D:
b8aa4598 9478 check_cp1_64bitmode(ctx);
b6d96bed 9479 {
a7812ae4 9480 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9481
9482 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9483 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9484 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9485 tcg_temp_free_i64(fp0);
b6d96bed 9486 }
57fa1fb3
TS
9487 opn = "recip.d";
9488 break;
bf4120ad 9489 case OPC_RSQRT_D:
b8aa4598 9490 check_cp1_64bitmode(ctx);
b6d96bed 9491 {
a7812ae4 9492 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9493
9494 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9495 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9496 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9497 tcg_temp_free_i64(fp0);
b6d96bed 9498 }
57fa1fb3
TS
9499 opn = "rsqrt.d";
9500 break;
e7f16abb
LA
9501 case OPC_MADDF_D:
9502 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9503 {
a7812ae4
PB
9504 TCGv_i64 fp0 = tcg_temp_new_i64();
9505 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9506 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9507 gen_load_fpr64(ctx, fp0, fs);
9508 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9509 gen_load_fpr64(ctx, fp2, fd);
9510 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9511 gen_store_fpr64(ctx, fp2, fd);
9512 tcg_temp_free_i64(fp2);
a7812ae4 9513 tcg_temp_free_i64(fp1);
a7812ae4 9514 tcg_temp_free_i64(fp0);
e7f16abb 9515 opn = "maddf.d";
b6d96bed 9516 }
57fa1fb3 9517 break;
e7f16abb
LA
9518 case OPC_MSUBF_D:
9519 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9520 {
a7812ae4 9521 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9522 TCGv_i64 fp1 = tcg_temp_new_i64();
9523 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9524 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9525 gen_load_fpr64(ctx, fp1, ft);
9526 gen_load_fpr64(ctx, fp2, fd);
9527 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9528 gen_store_fpr64(ctx, fp2, fd);
9529 tcg_temp_free_i64(fp2);
9530 tcg_temp_free_i64(fp1);
a7812ae4 9531 tcg_temp_free_i64(fp0);
e7f16abb 9532 opn = "msubf.d";
b6d96bed 9533 }
57fa1fb3 9534 break;
e7f16abb
LA
9535 case OPC_RINT_D:
9536 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9537 {
a7812ae4 9538 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9539 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9540 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9541 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9542 tcg_temp_free_i64(fp0);
e7f16abb 9543 opn = "rint.d";
b6d96bed 9544 }
57fa1fb3 9545 break;
e7f16abb
LA
9546 case OPC_CLASS_D:
9547 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9548 {
e7f16abb
LA
9549 TCGv_i64 fp0 = tcg_temp_new_i64();
9550 gen_load_fpr64(ctx, fp0, fs);
9551 gen_helper_float_class_d(fp0, fp0);
9552 gen_store_fpr64(ctx, fp0, fd);
9553 tcg_temp_free_i64(fp0);
9554 opn = "class.d";
9555 }
9556 break;
9557 case OPC_MIN_D: /* OPC_RECIP2_D */
9558 if (ctx->insn_flags & ISA_MIPS32R6) {
9559 /* OPC_MIN_D */
a7812ae4
PB
9560 TCGv_i64 fp0 = tcg_temp_new_i64();
9561 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9562 gen_load_fpr64(ctx, fp0, fs);
9563 gen_load_fpr64(ctx, fp1, ft);
9564 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9565 gen_store_fpr64(ctx, fp1, fd);
9566 tcg_temp_free_i64(fp1);
9567 tcg_temp_free_i64(fp0);
9568 opn = "min.d";
9569 } else {
9570 /* OPC_RECIP2_D */
9571 check_cp1_64bitmode(ctx);
9572 {
9573 TCGv_i64 fp0 = tcg_temp_new_i64();
9574 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9575
e7f16abb
LA
9576 gen_load_fpr64(ctx, fp0, fs);
9577 gen_load_fpr64(ctx, fp1, ft);
9578 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9579 tcg_temp_free_i64(fp1);
9580 gen_store_fpr64(ctx, fp0, fd);
9581 tcg_temp_free_i64(fp0);
9582 }
9583 opn = "recip2.d";
9584 }
9585 break;
9586 case OPC_MINA_D: /* OPC_RECIP1_D */
9587 if (ctx->insn_flags & ISA_MIPS32R6) {
9588 /* OPC_MINA_D */
9589 TCGv_i64 fp0 = tcg_temp_new_i64();
9590 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9591 gen_load_fpr64(ctx, fp0, fs);
9592 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9593 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9594 gen_store_fpr64(ctx, fp1, fd);
9595 tcg_temp_free_i64(fp1);
9596 tcg_temp_free_i64(fp0);
9597 opn = "mina.d";
9598 } else {
9599 /* OPC_RECIP1_D */
9600 check_cp1_64bitmode(ctx);
9601 {
9602 TCGv_i64 fp0 = tcg_temp_new_i64();
9603
9604 gen_load_fpr64(ctx, fp0, fs);
9605 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9606 gen_store_fpr64(ctx, fp0, fd);
9607 tcg_temp_free_i64(fp0);
9608 }
9609 opn = "recip1.d";
9610 }
9611 break;
9612 case OPC_MAX_D: /* OPC_RSQRT1_D */
9613 if (ctx->insn_flags & ISA_MIPS32R6) {
9614 /* OPC_MAX_D */
9615 TCGv_i64 fp0 = tcg_temp_new_i64();
9616 TCGv_i64 fp1 = tcg_temp_new_i64();
9617 gen_load_fpr64(ctx, fp0, fs);
9618 gen_load_fpr64(ctx, fp1, ft);
9619 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9620 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9621 tcg_temp_free_i64(fp1);
a7812ae4 9622 tcg_temp_free_i64(fp0);
e7f16abb
LA
9623 opn = "max.d";
9624 } else {
9625 /* OPC_RSQRT1_D */
9626 check_cp1_64bitmode(ctx);
9627 {
9628 TCGv_i64 fp0 = tcg_temp_new_i64();
9629
9630 gen_load_fpr64(ctx, fp0, fs);
9631 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9632 gen_store_fpr64(ctx, fp0, fd);
9633 tcg_temp_free_i64(fp0);
9634 }
9635 opn = "rsqrt1.d";
9636 }
9637 break;
9638 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9639 if (ctx->insn_flags & ISA_MIPS32R6) {
9640 /* OPC_MAXA_D */
9641 TCGv_i64 fp0 = tcg_temp_new_i64();
9642 TCGv_i64 fp1 = tcg_temp_new_i64();
9643 gen_load_fpr64(ctx, fp0, fs);
9644 gen_load_fpr64(ctx, fp1, ft);
9645 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9646 gen_store_fpr64(ctx, fp1, fd);
9647 tcg_temp_free_i64(fp1);
9648 tcg_temp_free_i64(fp0);
9649 opn = "maxa.d";
9650 } else {
9651 /* OPC_RSQRT2_D */
9652 check_cp1_64bitmode(ctx);
9653 {
9654 TCGv_i64 fp0 = tcg_temp_new_i64();
9655 TCGv_i64 fp1 = tcg_temp_new_i64();
9656
9657 gen_load_fpr64(ctx, fp0, fs);
9658 gen_load_fpr64(ctx, fp1, ft);
9659 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9660 tcg_temp_free_i64(fp1);
9661 gen_store_fpr64(ctx, fp0, fd);
9662 tcg_temp_free_i64(fp0);
9663 }
9664 opn = "rsqrt2.d";
b6d96bed 9665 }
57fa1fb3 9666 break;
bf4120ad
NF
9667 case OPC_CMP_F_D:
9668 case OPC_CMP_UN_D:
9669 case OPC_CMP_EQ_D:
9670 case OPC_CMP_UEQ_D:
9671 case OPC_CMP_OLT_D:
9672 case OPC_CMP_ULT_D:
9673 case OPC_CMP_OLE_D:
9674 case OPC_CMP_ULE_D:
9675 case OPC_CMP_SF_D:
9676 case OPC_CMP_NGLE_D:
9677 case OPC_CMP_SEQ_D:
9678 case OPC_CMP_NGL_D:
9679 case OPC_CMP_LT_D:
9680 case OPC_CMP_NGE_D:
9681 case OPC_CMP_LE_D:
9682 case OPC_CMP_NGT_D:
fecd2646 9683 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9684 if (ctx->opcode & (1 << 6)) {
9685 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9686 opn = condnames_abs[func-48];
9687 } else {
9688 gen_cmp_d(ctx, func-48, ft, fs, cc);
9689 opn = condnames[func-48];
5a1e8ffb 9690 }
6ea83fed 9691 break;
bf4120ad 9692 case OPC_CVT_S_D:
5e755519 9693 check_cp1_registers(ctx, fs);
b6d96bed 9694 {
a7812ae4
PB
9695 TCGv_i32 fp32 = tcg_temp_new_i32();
9696 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9697
9698 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9699 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9700 tcg_temp_free_i64(fp64);
7c979afd 9701 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9702 tcg_temp_free_i32(fp32);
b6d96bed 9703 }
5a5012ec
TS
9704 opn = "cvt.s.d";
9705 break;
bf4120ad 9706 case OPC_CVT_W_D:
5e755519 9707 check_cp1_registers(ctx, fs);
b6d96bed 9708 {
a7812ae4
PB
9709 TCGv_i32 fp32 = tcg_temp_new_i32();
9710 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9711
9712 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9713 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9714 tcg_temp_free_i64(fp64);
7c979afd 9715 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9716 tcg_temp_free_i32(fp32);
b6d96bed 9717 }
5a5012ec
TS
9718 opn = "cvt.w.d";
9719 break;
bf4120ad 9720 case OPC_CVT_L_D:
5e755519 9721 check_cp1_64bitmode(ctx);
b6d96bed 9722 {
a7812ae4 9723 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9724
9725 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9726 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9727 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9728 tcg_temp_free_i64(fp0);
b6d96bed 9729 }
5a5012ec
TS
9730 opn = "cvt.l.d";
9731 break;
bf4120ad 9732 case OPC_CVT_S_W:
b6d96bed 9733 {
a7812ae4 9734 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9735
7c979afd 9736 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9737 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9738 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9739 tcg_temp_free_i32(fp0);
b6d96bed 9740 }
5a5012ec 9741 opn = "cvt.s.w";
6ea83fed 9742 break;
bf4120ad 9743 case OPC_CVT_D_W:
5e755519 9744 check_cp1_registers(ctx, fd);
b6d96bed 9745 {
a7812ae4
PB
9746 TCGv_i32 fp32 = tcg_temp_new_i32();
9747 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9748
7c979afd 9749 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9750 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9751 tcg_temp_free_i32(fp32);
b6d96bed 9752 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9753 tcg_temp_free_i64(fp64);
b6d96bed 9754 }
5a5012ec
TS
9755 opn = "cvt.d.w";
9756 break;
bf4120ad 9757 case OPC_CVT_S_L:
5e755519 9758 check_cp1_64bitmode(ctx);
b6d96bed 9759 {
a7812ae4
PB
9760 TCGv_i32 fp32 = tcg_temp_new_i32();
9761 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9762
9763 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9764 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9765 tcg_temp_free_i64(fp64);
7c979afd 9766 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9767 tcg_temp_free_i32(fp32);
b6d96bed 9768 }
5a5012ec
TS
9769 opn = "cvt.s.l";
9770 break;
bf4120ad 9771 case OPC_CVT_D_L:
5e755519 9772 check_cp1_64bitmode(ctx);
b6d96bed 9773 {
a7812ae4 9774 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9775
9776 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9777 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9778 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9779 tcg_temp_free_i64(fp0);
b6d96bed 9780 }
5a5012ec
TS
9781 opn = "cvt.d.l";
9782 break;
bf4120ad 9783 case OPC_CVT_PS_PW:
fecd2646 9784 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9785 check_cp1_64bitmode(ctx);
b6d96bed 9786 {
a7812ae4 9787 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9788
9789 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9790 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9791 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9792 tcg_temp_free_i64(fp0);
b6d96bed 9793 }
5a5012ec
TS
9794 opn = "cvt.ps.pw";
9795 break;
bf4120ad 9796 case OPC_ADD_PS:
5e755519 9797 check_cp1_64bitmode(ctx);
b6d96bed 9798 {
a7812ae4
PB
9799 TCGv_i64 fp0 = tcg_temp_new_i64();
9800 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9801
9802 gen_load_fpr64(ctx, fp0, fs);
9803 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9804 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9805 tcg_temp_free_i64(fp1);
b6d96bed 9806 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9807 tcg_temp_free_i64(fp0);
b6d96bed 9808 }
5a5012ec 9809 opn = "add.ps";
6ea83fed 9810 break;
bf4120ad 9811 case OPC_SUB_PS:
5e755519 9812 check_cp1_64bitmode(ctx);
b6d96bed 9813 {
a7812ae4
PB
9814 TCGv_i64 fp0 = tcg_temp_new_i64();
9815 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9816
9817 gen_load_fpr64(ctx, fp0, fs);
9818 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9819 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9820 tcg_temp_free_i64(fp1);
b6d96bed 9821 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9822 tcg_temp_free_i64(fp0);
b6d96bed 9823 }
5a5012ec 9824 opn = "sub.ps";
6ea83fed 9825 break;
bf4120ad 9826 case OPC_MUL_PS:
5e755519 9827 check_cp1_64bitmode(ctx);
b6d96bed 9828 {
a7812ae4
PB
9829 TCGv_i64 fp0 = tcg_temp_new_i64();
9830 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9831
9832 gen_load_fpr64(ctx, fp0, fs);
9833 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9834 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9835 tcg_temp_free_i64(fp1);
b6d96bed 9836 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9837 tcg_temp_free_i64(fp0);
b6d96bed 9838 }
5a5012ec 9839 opn = "mul.ps";
6ea83fed 9840 break;
bf4120ad 9841 case OPC_ABS_PS:
5e755519 9842 check_cp1_64bitmode(ctx);
b6d96bed 9843 {
a7812ae4 9844 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9845
9846 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9847 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9848 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9849 tcg_temp_free_i64(fp0);
b6d96bed 9850 }
5a5012ec 9851 opn = "abs.ps";
6ea83fed 9852 break;
bf4120ad 9853 case OPC_MOV_PS:
5e755519 9854 check_cp1_64bitmode(ctx);
b6d96bed 9855 {
a7812ae4 9856 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9857
9858 gen_load_fpr64(ctx, fp0, fs);
9859 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9860 tcg_temp_free_i64(fp0);
b6d96bed 9861 }
5a5012ec 9862 opn = "mov.ps";
6ea83fed 9863 break;
bf4120ad 9864 case OPC_NEG_PS:
5e755519 9865 check_cp1_64bitmode(ctx);
b6d96bed 9866 {
a7812ae4 9867 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9868
9869 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9870 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9871 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9872 tcg_temp_free_i64(fp0);
b6d96bed 9873 }
5a5012ec 9874 opn = "neg.ps";
6ea83fed 9875 break;
bf4120ad 9876 case OPC_MOVCF_PS:
5e755519 9877 check_cp1_64bitmode(ctx);
7f6613ce 9878 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9879 opn = "movcf.ps";
6ea83fed 9880 break;
bf4120ad 9881 case OPC_MOVZ_PS:
5e755519 9882 check_cp1_64bitmode(ctx);
a16336e4 9883 {
42a268c2 9884 TCGLabel *l1 = gen_new_label();
30a3848b 9885 TCGv_i64 fp0;
a16336e4 9886
c9297f4d
AJ
9887 if (ft != 0)
9888 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9889 fp0 = tcg_temp_new_i64();
9890 gen_load_fpr64(ctx, fp0, fs);
9891 gen_store_fpr64(ctx, fp0, fd);
9892 tcg_temp_free_i64(fp0);
a16336e4
TS
9893 gen_set_label(l1);
9894 }
5a5012ec 9895 opn = "movz.ps";
6ea83fed 9896 break;
bf4120ad 9897 case OPC_MOVN_PS:
5e755519 9898 check_cp1_64bitmode(ctx);
a16336e4 9899 {
42a268c2 9900 TCGLabel *l1 = gen_new_label();
30a3848b 9901 TCGv_i64 fp0;
c9297f4d
AJ
9902
9903 if (ft != 0) {
9904 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9905 fp0 = tcg_temp_new_i64();
9906 gen_load_fpr64(ctx, fp0, fs);
9907 gen_store_fpr64(ctx, fp0, fd);
9908 tcg_temp_free_i64(fp0);
9909 gen_set_label(l1);
9910 }
a16336e4 9911 }
5a5012ec 9912 opn = "movn.ps";
6ea83fed 9913 break;
bf4120ad 9914 case OPC_ADDR_PS:
5e755519 9915 check_cp1_64bitmode(ctx);
b6d96bed 9916 {
a7812ae4
PB
9917 TCGv_i64 fp0 = tcg_temp_new_i64();
9918 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9919
9920 gen_load_fpr64(ctx, fp0, ft);
9921 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9922 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9923 tcg_temp_free_i64(fp1);
b6d96bed 9924 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9925 tcg_temp_free_i64(fp0);
b6d96bed 9926 }
fbcc6828
TS
9927 opn = "addr.ps";
9928 break;
bf4120ad 9929 case OPC_MULR_PS:
5e755519 9930 check_cp1_64bitmode(ctx);
b6d96bed 9931 {
a7812ae4
PB
9932 TCGv_i64 fp0 = tcg_temp_new_i64();
9933 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9934
9935 gen_load_fpr64(ctx, fp0, ft);
9936 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9937 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9938 tcg_temp_free_i64(fp1);
b6d96bed 9939 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9940 tcg_temp_free_i64(fp0);
b6d96bed 9941 }
57fa1fb3
TS
9942 opn = "mulr.ps";
9943 break;
bf4120ad 9944 case OPC_RECIP2_PS:
5e755519 9945 check_cp1_64bitmode(ctx);
b6d96bed 9946 {
a7812ae4
PB
9947 TCGv_i64 fp0 = tcg_temp_new_i64();
9948 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9949
9950 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9951 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9952 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9953 tcg_temp_free_i64(fp1);
b6d96bed 9954 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9955 tcg_temp_free_i64(fp0);
b6d96bed 9956 }
57fa1fb3
TS
9957 opn = "recip2.ps";
9958 break;
bf4120ad 9959 case OPC_RECIP1_PS:
5e755519 9960 check_cp1_64bitmode(ctx);
b6d96bed 9961 {
a7812ae4 9962 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9963
9964 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9965 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9966 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9967 tcg_temp_free_i64(fp0);
b6d96bed 9968 }
57fa1fb3
TS
9969 opn = "recip1.ps";
9970 break;
bf4120ad 9971 case OPC_RSQRT1_PS:
5e755519 9972 check_cp1_64bitmode(ctx);
b6d96bed 9973 {
a7812ae4 9974 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9975
9976 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9977 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9978 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9979 tcg_temp_free_i64(fp0);
b6d96bed 9980 }
57fa1fb3
TS
9981 opn = "rsqrt1.ps";
9982 break;
bf4120ad 9983 case OPC_RSQRT2_PS:
5e755519 9984 check_cp1_64bitmode(ctx);
b6d96bed 9985 {
a7812ae4
PB
9986 TCGv_i64 fp0 = tcg_temp_new_i64();
9987 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9988
9989 gen_load_fpr64(ctx, fp0, fs);
9990 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9991 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9992 tcg_temp_free_i64(fp1);
b6d96bed 9993 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9994 tcg_temp_free_i64(fp0);
b6d96bed 9995 }
57fa1fb3
TS
9996 opn = "rsqrt2.ps";
9997 break;
bf4120ad 9998 case OPC_CVT_S_PU:
5e755519 9999 check_cp1_64bitmode(ctx);
b6d96bed 10000 {
a7812ae4 10001 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10002
7f6613ce 10003 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10004 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10005 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10006 tcg_temp_free_i32(fp0);
b6d96bed 10007 }
5a5012ec 10008 opn = "cvt.s.pu";
dd016883 10009 break;
bf4120ad 10010 case OPC_CVT_PW_PS:
5e755519 10011 check_cp1_64bitmode(ctx);
b6d96bed 10012 {
a7812ae4 10013 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10014
10015 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10016 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10017 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10018 tcg_temp_free_i64(fp0);
b6d96bed 10019 }
5a5012ec 10020 opn = "cvt.pw.ps";
6ea83fed 10021 break;
bf4120ad 10022 case OPC_CVT_S_PL:
5e755519 10023 check_cp1_64bitmode(ctx);
b6d96bed 10024 {
a7812ae4 10025 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10026
7c979afd 10027 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10028 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10029 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10030 tcg_temp_free_i32(fp0);
b6d96bed 10031 }
5a5012ec 10032 opn = "cvt.s.pl";
6ea83fed 10033 break;
bf4120ad 10034 case OPC_PLL_PS:
5e755519 10035 check_cp1_64bitmode(ctx);
b6d96bed 10036 {
a7812ae4
PB
10037 TCGv_i32 fp0 = tcg_temp_new_i32();
10038 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10039
7c979afd
LA
10040 gen_load_fpr32(ctx, fp0, fs);
10041 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10042 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10043 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10044 tcg_temp_free_i32(fp0);
10045 tcg_temp_free_i32(fp1);
b6d96bed 10046 }
5a5012ec 10047 opn = "pll.ps";
6ea83fed 10048 break;
bf4120ad 10049 case OPC_PLU_PS:
5e755519 10050 check_cp1_64bitmode(ctx);
b6d96bed 10051 {
a7812ae4
PB
10052 TCGv_i32 fp0 = tcg_temp_new_i32();
10053 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10054
7c979afd 10055 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10056 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10057 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10058 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10059 tcg_temp_free_i32(fp0);
10060 tcg_temp_free_i32(fp1);
b6d96bed 10061 }
5a5012ec
TS
10062 opn = "plu.ps";
10063 break;
bf4120ad 10064 case OPC_PUL_PS:
5e755519 10065 check_cp1_64bitmode(ctx);
b6d96bed 10066 {
a7812ae4
PB
10067 TCGv_i32 fp0 = tcg_temp_new_i32();
10068 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10069
7f6613ce 10070 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10071 gen_load_fpr32(ctx, fp1, ft);
10072 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10073 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10074 tcg_temp_free_i32(fp0);
10075 tcg_temp_free_i32(fp1);
b6d96bed 10076 }
5a5012ec
TS
10077 opn = "pul.ps";
10078 break;
bf4120ad 10079 case OPC_PUU_PS:
5e755519 10080 check_cp1_64bitmode(ctx);
b6d96bed 10081 {
a7812ae4
PB
10082 TCGv_i32 fp0 = tcg_temp_new_i32();
10083 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10084
7f6613ce
PJ
10085 gen_load_fpr32h(ctx, fp0, fs);
10086 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10087 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10088 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10089 tcg_temp_free_i32(fp0);
10090 tcg_temp_free_i32(fp1);
b6d96bed 10091 }
5a5012ec
TS
10092 opn = "puu.ps";
10093 break;
bf4120ad
NF
10094 case OPC_CMP_F_PS:
10095 case OPC_CMP_UN_PS:
10096 case OPC_CMP_EQ_PS:
10097 case OPC_CMP_UEQ_PS:
10098 case OPC_CMP_OLT_PS:
10099 case OPC_CMP_ULT_PS:
10100 case OPC_CMP_OLE_PS:
10101 case OPC_CMP_ULE_PS:
10102 case OPC_CMP_SF_PS:
10103 case OPC_CMP_NGLE_PS:
10104 case OPC_CMP_SEQ_PS:
10105 case OPC_CMP_NGL_PS:
10106 case OPC_CMP_LT_PS:
10107 case OPC_CMP_NGE_PS:
10108 case OPC_CMP_LE_PS:
10109 case OPC_CMP_NGT_PS:
8153667c
NF
10110 if (ctx->opcode & (1 << 6)) {
10111 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10112 opn = condnames_abs[func-48];
10113 } else {
10114 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10115 opn = condnames[func-48];
5a1e8ffb 10116 }
6ea83fed 10117 break;
5a5012ec 10118 default:
923617a3 10119 MIPS_INVAL(opn);
e397ee33 10120 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10121 return;
10122 }
2abf314d 10123 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10124 switch (optype) {
10125 case BINOP:
6ea83fed 10126 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10127 break;
10128 case CMPOP:
10129 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10130 break;
10131 default:
6ea83fed 10132 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10133 break;
10134 }
6ea83fed 10135}
6af0bf9c 10136
5a5012ec 10137/* Coprocessor 3 (FPU) */
5e755519
TS
10138static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10139 int fd, int fs, int base, int index)
7a387fff 10140{
923617a3 10141 const char *opn = "extended float load/store";
93b12ccc 10142 int store = 0;
4e2474d6 10143 TCGv t0 = tcg_temp_new();
7a387fff 10144
93b12ccc 10145 if (base == 0) {
6c5c1e20 10146 gen_load_gpr(t0, index);
93b12ccc 10147 } else if (index == 0) {
6c5c1e20 10148 gen_load_gpr(t0, base);
93b12ccc 10149 } else {
05168674 10150 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10151 }
5a5012ec 10152 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10153 memory access. */
5a5012ec
TS
10154 switch (opc) {
10155 case OPC_LWXC1:
8c0ab41f 10156 check_cop1x(ctx);
b6d96bed 10157 {
a7812ae4 10158 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10159
5f68f5ae 10160 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10161 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10162 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10163 tcg_temp_free_i32(fp0);
b6d96bed 10164 }
5a5012ec
TS
10165 opn = "lwxc1";
10166 break;
10167 case OPC_LDXC1:
8c0ab41f
AJ
10168 check_cop1x(ctx);
10169 check_cp1_registers(ctx, fd);
b6d96bed 10170 {
a7812ae4 10171 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10172 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10173 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10174 tcg_temp_free_i64(fp0);
b6d96bed 10175 }
5a5012ec
TS
10176 opn = "ldxc1";
10177 break;
10178 case OPC_LUXC1:
8c0ab41f 10179 check_cp1_64bitmode(ctx);
6c5c1e20 10180 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10181 {
a7812ae4 10182 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10183
5f68f5ae 10184 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10185 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10186 tcg_temp_free_i64(fp0);
b6d96bed 10187 }
5a5012ec
TS
10188 opn = "luxc1";
10189 break;
10190 case OPC_SWXC1:
8c0ab41f 10191 check_cop1x(ctx);
b6d96bed 10192 {
a7812ae4 10193 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10194 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10195 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10196 tcg_temp_free_i32(fp0);
b6d96bed 10197 }
5a5012ec 10198 opn = "swxc1";
93b12ccc 10199 store = 1;
5a5012ec
TS
10200 break;
10201 case OPC_SDXC1:
8c0ab41f
AJ
10202 check_cop1x(ctx);
10203 check_cp1_registers(ctx, fs);
b6d96bed 10204 {
a7812ae4 10205 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10206 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10207 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10208 tcg_temp_free_i64(fp0);
b6d96bed 10209 }
5a5012ec 10210 opn = "sdxc1";
93b12ccc 10211 store = 1;
5a5012ec
TS
10212 break;
10213 case OPC_SUXC1:
8c0ab41f 10214 check_cp1_64bitmode(ctx);
6c5c1e20 10215 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10216 {
a7812ae4 10217 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10218 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10219 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10220 tcg_temp_free_i64(fp0);
b6d96bed 10221 }
5a5012ec 10222 opn = "suxc1";
93b12ccc 10223 store = 1;
5a5012ec 10224 break;
5a5012ec 10225 }
6c5c1e20 10226 tcg_temp_free(t0);
2abf314d 10227 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10228 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10229 regnames[index], regnames[base]);
5a5012ec
TS
10230}
10231
5e755519
TS
10232static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10233 int fd, int fr, int fs, int ft)
5a5012ec 10234{
923617a3 10235 const char *opn = "flt3_arith";
5a5012ec 10236
5a5012ec
TS
10237 switch (opc) {
10238 case OPC_ALNV_PS:
b8aa4598 10239 check_cp1_64bitmode(ctx);
a16336e4 10240 {
a7812ae4 10241 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10242 TCGv_i32 fp = tcg_temp_new_i32();
10243 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10244 TCGLabel *l1 = gen_new_label();
10245 TCGLabel *l2 = gen_new_label();
a16336e4 10246
6c5c1e20
TS
10247 gen_load_gpr(t0, fr);
10248 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10249
10250 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10251 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10252 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10253 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10254 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10255 tcg_gen_br(l2);
10256 gen_set_label(l1);
6c5c1e20
TS
10257 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10258 tcg_temp_free(t0);
a16336e4 10259#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10260 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10261 gen_load_fpr32h(ctx, fph, ft);
10262 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10263 gen_store_fpr32(ctx, fph, fd);
a16336e4 10264#else
7f6613ce 10265 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10266 gen_load_fpr32(ctx, fp, ft);
10267 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10268 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10269#endif
10270 gen_set_label(l2);
c905fdac
AJ
10271 tcg_temp_free_i32(fp);
10272 tcg_temp_free_i32(fph);
a16336e4 10273 }
5a5012ec
TS
10274 opn = "alnv.ps";
10275 break;
10276 case OPC_MADD_S:
b8aa4598 10277 check_cop1x(ctx);
b6d96bed 10278 {
a7812ae4
PB
10279 TCGv_i32 fp0 = tcg_temp_new_i32();
10280 TCGv_i32 fp1 = tcg_temp_new_i32();
10281 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10282
7c979afd
LA
10283 gen_load_fpr32(ctx, fp0, fs);
10284 gen_load_fpr32(ctx, fp1, ft);
10285 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10286 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10287 tcg_temp_free_i32(fp0);
10288 tcg_temp_free_i32(fp1);
7c979afd 10289 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10290 tcg_temp_free_i32(fp2);
b6d96bed 10291 }
5a5012ec
TS
10292 opn = "madd.s";
10293 break;
10294 case OPC_MADD_D:
b8aa4598
TS
10295 check_cop1x(ctx);
10296 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10297 {
a7812ae4
PB
10298 TCGv_i64 fp0 = tcg_temp_new_i64();
10299 TCGv_i64 fp1 = tcg_temp_new_i64();
10300 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10301
10302 gen_load_fpr64(ctx, fp0, fs);
10303 gen_load_fpr64(ctx, fp1, ft);
10304 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10305 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10306 tcg_temp_free_i64(fp0);
10307 tcg_temp_free_i64(fp1);
b6d96bed 10308 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10309 tcg_temp_free_i64(fp2);
b6d96bed 10310 }
5a5012ec
TS
10311 opn = "madd.d";
10312 break;
10313 case OPC_MADD_PS:
b8aa4598 10314 check_cp1_64bitmode(ctx);
b6d96bed 10315 {
a7812ae4
PB
10316 TCGv_i64 fp0 = tcg_temp_new_i64();
10317 TCGv_i64 fp1 = tcg_temp_new_i64();
10318 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10319
10320 gen_load_fpr64(ctx, fp0, fs);
10321 gen_load_fpr64(ctx, fp1, ft);
10322 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10323 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10324 tcg_temp_free_i64(fp0);
10325 tcg_temp_free_i64(fp1);
b6d96bed 10326 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10327 tcg_temp_free_i64(fp2);
b6d96bed 10328 }
5a5012ec
TS
10329 opn = "madd.ps";
10330 break;
10331 case OPC_MSUB_S:
b8aa4598 10332 check_cop1x(ctx);
b6d96bed 10333 {
a7812ae4
PB
10334 TCGv_i32 fp0 = tcg_temp_new_i32();
10335 TCGv_i32 fp1 = tcg_temp_new_i32();
10336 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10337
7c979afd
LA
10338 gen_load_fpr32(ctx, fp0, fs);
10339 gen_load_fpr32(ctx, fp1, ft);
10340 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10341 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10342 tcg_temp_free_i32(fp0);
10343 tcg_temp_free_i32(fp1);
7c979afd 10344 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10345 tcg_temp_free_i32(fp2);
b6d96bed 10346 }
5a5012ec
TS
10347 opn = "msub.s";
10348 break;
10349 case OPC_MSUB_D:
b8aa4598
TS
10350 check_cop1x(ctx);
10351 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10352 {
a7812ae4
PB
10353 TCGv_i64 fp0 = tcg_temp_new_i64();
10354 TCGv_i64 fp1 = tcg_temp_new_i64();
10355 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10356
10357 gen_load_fpr64(ctx, fp0, fs);
10358 gen_load_fpr64(ctx, fp1, ft);
10359 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10360 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10361 tcg_temp_free_i64(fp0);
10362 tcg_temp_free_i64(fp1);
b6d96bed 10363 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10364 tcg_temp_free_i64(fp2);
b6d96bed 10365 }
5a5012ec
TS
10366 opn = "msub.d";
10367 break;
10368 case OPC_MSUB_PS:
b8aa4598 10369 check_cp1_64bitmode(ctx);
b6d96bed 10370 {
a7812ae4
PB
10371 TCGv_i64 fp0 = tcg_temp_new_i64();
10372 TCGv_i64 fp1 = tcg_temp_new_i64();
10373 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10374
10375 gen_load_fpr64(ctx, fp0, fs);
10376 gen_load_fpr64(ctx, fp1, ft);
10377 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10378 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10379 tcg_temp_free_i64(fp0);
10380 tcg_temp_free_i64(fp1);
b6d96bed 10381 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10382 tcg_temp_free_i64(fp2);
b6d96bed 10383 }
5a5012ec
TS
10384 opn = "msub.ps";
10385 break;
10386 case OPC_NMADD_S:
b8aa4598 10387 check_cop1x(ctx);
b6d96bed 10388 {
a7812ae4
PB
10389 TCGv_i32 fp0 = tcg_temp_new_i32();
10390 TCGv_i32 fp1 = tcg_temp_new_i32();
10391 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10392
7c979afd
LA
10393 gen_load_fpr32(ctx, fp0, fs);
10394 gen_load_fpr32(ctx, fp1, ft);
10395 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10396 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10397 tcg_temp_free_i32(fp0);
10398 tcg_temp_free_i32(fp1);
7c979afd 10399 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10400 tcg_temp_free_i32(fp2);
b6d96bed 10401 }
5a5012ec
TS
10402 opn = "nmadd.s";
10403 break;
10404 case OPC_NMADD_D:
b8aa4598
TS
10405 check_cop1x(ctx);
10406 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10407 {
a7812ae4
PB
10408 TCGv_i64 fp0 = tcg_temp_new_i64();
10409 TCGv_i64 fp1 = tcg_temp_new_i64();
10410 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10411
10412 gen_load_fpr64(ctx, fp0, fs);
10413 gen_load_fpr64(ctx, fp1, ft);
10414 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10415 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10416 tcg_temp_free_i64(fp0);
10417 tcg_temp_free_i64(fp1);
b6d96bed 10418 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10419 tcg_temp_free_i64(fp2);
b6d96bed 10420 }
5a5012ec
TS
10421 opn = "nmadd.d";
10422 break;
10423 case OPC_NMADD_PS:
b8aa4598 10424 check_cp1_64bitmode(ctx);
b6d96bed 10425 {
a7812ae4
PB
10426 TCGv_i64 fp0 = tcg_temp_new_i64();
10427 TCGv_i64 fp1 = tcg_temp_new_i64();
10428 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10429
10430 gen_load_fpr64(ctx, fp0, fs);
10431 gen_load_fpr64(ctx, fp1, ft);
10432 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10433 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10434 tcg_temp_free_i64(fp0);
10435 tcg_temp_free_i64(fp1);
b6d96bed 10436 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10437 tcg_temp_free_i64(fp2);
b6d96bed 10438 }
5a5012ec
TS
10439 opn = "nmadd.ps";
10440 break;
10441 case OPC_NMSUB_S:
b8aa4598 10442 check_cop1x(ctx);
b6d96bed 10443 {
a7812ae4
PB
10444 TCGv_i32 fp0 = tcg_temp_new_i32();
10445 TCGv_i32 fp1 = tcg_temp_new_i32();
10446 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10447
7c979afd
LA
10448 gen_load_fpr32(ctx, fp0, fs);
10449 gen_load_fpr32(ctx, fp1, ft);
10450 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10451 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10452 tcg_temp_free_i32(fp0);
10453 tcg_temp_free_i32(fp1);
7c979afd 10454 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10455 tcg_temp_free_i32(fp2);
b6d96bed 10456 }
5a5012ec
TS
10457 opn = "nmsub.s";
10458 break;
10459 case OPC_NMSUB_D:
b8aa4598
TS
10460 check_cop1x(ctx);
10461 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10462 {
a7812ae4
PB
10463 TCGv_i64 fp0 = tcg_temp_new_i64();
10464 TCGv_i64 fp1 = tcg_temp_new_i64();
10465 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10466
10467 gen_load_fpr64(ctx, fp0, fs);
10468 gen_load_fpr64(ctx, fp1, ft);
10469 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10470 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10471 tcg_temp_free_i64(fp0);
10472 tcg_temp_free_i64(fp1);
b6d96bed 10473 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10474 tcg_temp_free_i64(fp2);
b6d96bed 10475 }
5a5012ec
TS
10476 opn = "nmsub.d";
10477 break;
10478 case OPC_NMSUB_PS:
b8aa4598 10479 check_cp1_64bitmode(ctx);
b6d96bed 10480 {
a7812ae4
PB
10481 TCGv_i64 fp0 = tcg_temp_new_i64();
10482 TCGv_i64 fp1 = tcg_temp_new_i64();
10483 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10484
10485 gen_load_fpr64(ctx, fp0, fs);
10486 gen_load_fpr64(ctx, fp1, ft);
10487 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10488 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10489 tcg_temp_free_i64(fp0);
10490 tcg_temp_free_i64(fp1);
b6d96bed 10491 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10492 tcg_temp_free_i64(fp2);
b6d96bed 10493 }
5a5012ec
TS
10494 opn = "nmsub.ps";
10495 break;
923617a3
TS
10496 default:
10497 MIPS_INVAL(opn);
5a5012ec
TS
10498 generate_exception (ctx, EXCP_RI);
10499 return;
10500 }
2abf314d 10501 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10502 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10503 fregnames[fs], fregnames[ft]);
7a387fff
TS
10504}
10505
d75c135e 10506static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10507{
10508 TCGv t0;
10509
b3167288
RH
10510#if !defined(CONFIG_USER_ONLY)
10511 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10512 Therefore only check the ISA in system mode. */
d75c135e 10513 check_insn(ctx, ISA_MIPS32R2);
b3167288 10514#endif
26ebe468
NF
10515 t0 = tcg_temp_new();
10516
10517 switch (rd) {
10518 case 0:
10519 save_cpu_state(ctx, 1);
895c2d04 10520 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10521 gen_store_gpr(t0, rt);
10522 break;
10523 case 1:
10524 save_cpu_state(ctx, 1);
895c2d04 10525 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10526 gen_store_gpr(t0, rt);
10527 break;
10528 case 2:
10529 save_cpu_state(ctx, 1);
895c2d04 10530 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10531 gen_store_gpr(t0, rt);
10532 break;
10533 case 3:
10534 save_cpu_state(ctx, 1);
895c2d04 10535 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10536 gen_store_gpr(t0, rt);
10537 break;
10538 case 29:
10539#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10540 tcg_gen_ld_tl(t0, cpu_env,
10541 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10542 gen_store_gpr(t0, rt);
10543 break;
10544#else
d279279e
PJ
10545 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10546 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10547 tcg_gen_ld_tl(t0, cpu_env,
10548 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10549 gen_store_gpr(t0, rt);
10550 } else {
10551 generate_exception(ctx, EXCP_RI);
10552 }
10553 break;
26ebe468
NF
10554#endif
10555 default: /* Invalid */
10556 MIPS_INVAL("rdhwr");
10557 generate_exception(ctx, EXCP_RI);
10558 break;
10559 }
10560 tcg_temp_free(t0);
10561}
10562
a5f53390
LA
10563static inline void clear_branch_hflags(DisasContext *ctx)
10564{
10565 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10566 if (ctx->bstate == BS_NONE) {
10567 save_cpu_state(ctx, 0);
10568 } else {
10569 /* it is not safe to save ctx->hflags as hflags may be changed
10570 in execution time by the instruction in delay / forbidden slot. */
10571 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10572 }
10573}
10574
31837be3 10575static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10576{
10577 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10578 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10579 /* Branches completion */
a5f53390 10580 clear_branch_hflags(ctx);
c9602061 10581 ctx->bstate = BS_BRANCH;
c9602061 10582 /* FIXME: Need to clear can_do_io. */
364d4831 10583 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10584 case MIPS_HFLAG_FBNSLOT:
10585 MIPS_DEBUG("forbidden slot");
10586 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10587 break;
c9602061
NF
10588 case MIPS_HFLAG_B:
10589 /* unconditional branch */
10590 MIPS_DEBUG("unconditional branch");
364d4831
NF
10591 if (proc_hflags & MIPS_HFLAG_BX) {
10592 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10593 }
c9602061
NF
10594 gen_goto_tb(ctx, 0, ctx->btarget);
10595 break;
10596 case MIPS_HFLAG_BL:
10597 /* blikely taken case */
10598 MIPS_DEBUG("blikely branch taken");
10599 gen_goto_tb(ctx, 0, ctx->btarget);
10600 break;
10601 case MIPS_HFLAG_BC:
10602 /* Conditional branch */
10603 MIPS_DEBUG("conditional branch");
10604 {
42a268c2 10605 TCGLabel *l1 = gen_new_label();
c9602061
NF
10606
10607 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10608 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10609 gen_set_label(l1);
10610 gen_goto_tb(ctx, 0, ctx->btarget);
10611 }
10612 break;
10613 case MIPS_HFLAG_BR:
10614 /* unconditional branch to register */
10615 MIPS_DEBUG("branch to register");
d75c135e 10616 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10617 TCGv t0 = tcg_temp_new();
10618 TCGv_i32 t1 = tcg_temp_new_i32();
10619
10620 tcg_gen_andi_tl(t0, btarget, 0x1);
10621 tcg_gen_trunc_tl_i32(t1, t0);
10622 tcg_temp_free(t0);
10623 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10624 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10625 tcg_gen_or_i32(hflags, hflags, t1);
10626 tcg_temp_free_i32(t1);
10627
10628 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10629 } else {
10630 tcg_gen_mov_tl(cpu_PC, btarget);
10631 }
c9602061
NF
10632 if (ctx->singlestep_enabled) {
10633 save_cpu_state(ctx, 0);
895c2d04 10634 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10635 }
10636 tcg_gen_exit_tb(0);
10637 break;
10638 default:
a5f53390
LA
10639 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10640 abort();
c9602061
NF
10641 }
10642 }
10643}
10644
7a387fff 10645/* ISA extensions (ASEs) */
6af0bf9c 10646/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10647
10648/* MIPS16 major opcodes */
10649enum {
10650 M16_OPC_ADDIUSP = 0x00,
10651 M16_OPC_ADDIUPC = 0x01,
10652 M16_OPC_B = 0x02,
10653 M16_OPC_JAL = 0x03,
10654 M16_OPC_BEQZ = 0x04,
10655 M16_OPC_BNEQZ = 0x05,
10656 M16_OPC_SHIFT = 0x06,
10657 M16_OPC_LD = 0x07,
10658 M16_OPC_RRIA = 0x08,
10659 M16_OPC_ADDIU8 = 0x09,
10660 M16_OPC_SLTI = 0x0a,
10661 M16_OPC_SLTIU = 0x0b,
10662 M16_OPC_I8 = 0x0c,
10663 M16_OPC_LI = 0x0d,
10664 M16_OPC_CMPI = 0x0e,
10665 M16_OPC_SD = 0x0f,
10666 M16_OPC_LB = 0x10,
10667 M16_OPC_LH = 0x11,
10668 M16_OPC_LWSP = 0x12,
10669 M16_OPC_LW = 0x13,
10670 M16_OPC_LBU = 0x14,
10671 M16_OPC_LHU = 0x15,
10672 M16_OPC_LWPC = 0x16,
10673 M16_OPC_LWU = 0x17,
10674 M16_OPC_SB = 0x18,
10675 M16_OPC_SH = 0x19,
10676 M16_OPC_SWSP = 0x1a,
10677 M16_OPC_SW = 0x1b,
10678 M16_OPC_RRR = 0x1c,
10679 M16_OPC_RR = 0x1d,
10680 M16_OPC_EXTEND = 0x1e,
10681 M16_OPC_I64 = 0x1f
10682};
10683
10684/* I8 funct field */
10685enum {
10686 I8_BTEQZ = 0x0,
10687 I8_BTNEZ = 0x1,
10688 I8_SWRASP = 0x2,
10689 I8_ADJSP = 0x3,
10690 I8_SVRS = 0x4,
10691 I8_MOV32R = 0x5,
10692 I8_MOVR32 = 0x7
10693};
10694
10695/* RRR f field */
10696enum {
10697 RRR_DADDU = 0x0,
10698 RRR_ADDU = 0x1,
10699 RRR_DSUBU = 0x2,
10700 RRR_SUBU = 0x3
10701};
10702
10703/* RR funct field */
10704enum {
10705 RR_JR = 0x00,
10706 RR_SDBBP = 0x01,
10707 RR_SLT = 0x02,
10708 RR_SLTU = 0x03,
10709 RR_SLLV = 0x04,
10710 RR_BREAK = 0x05,
10711 RR_SRLV = 0x06,
10712 RR_SRAV = 0x07,
10713 RR_DSRL = 0x08,
10714 RR_CMP = 0x0a,
10715 RR_NEG = 0x0b,
10716 RR_AND = 0x0c,
10717 RR_OR = 0x0d,
10718 RR_XOR = 0x0e,
10719 RR_NOT = 0x0f,
10720 RR_MFHI = 0x10,
10721 RR_CNVT = 0x11,
10722 RR_MFLO = 0x12,
10723 RR_DSRA = 0x13,
10724 RR_DSLLV = 0x14,
10725 RR_DSRLV = 0x16,
10726 RR_DSRAV = 0x17,
10727 RR_MULT = 0x18,
10728 RR_MULTU = 0x19,
10729 RR_DIV = 0x1a,
10730 RR_DIVU = 0x1b,
10731 RR_DMULT = 0x1c,
10732 RR_DMULTU = 0x1d,
10733 RR_DDIV = 0x1e,
10734 RR_DDIVU = 0x1f
10735};
10736
10737/* I64 funct field */
10738enum {
10739 I64_LDSP = 0x0,
10740 I64_SDSP = 0x1,
10741 I64_SDRASP = 0x2,
10742 I64_DADJSP = 0x3,
10743 I64_LDPC = 0x4,
364d4831 10744 I64_DADDIU5 = 0x5,
6ea219d0
NF
10745 I64_DADDIUPC = 0x6,
10746 I64_DADDIUSP = 0x7
10747};
10748
10749/* RR ry field for CNVT */
10750enum {
10751 RR_RY_CNVT_ZEB = 0x0,
10752 RR_RY_CNVT_ZEH = 0x1,
10753 RR_RY_CNVT_ZEW = 0x2,
10754 RR_RY_CNVT_SEB = 0x4,
10755 RR_RY_CNVT_SEH = 0x5,
10756 RR_RY_CNVT_SEW = 0x6,
10757};
10758
364d4831
NF
10759static int xlat (int r)
10760{
10761 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10762
10763 return map[r];
10764}
10765
10766static void gen_mips16_save (DisasContext *ctx,
10767 int xsregs, int aregs,
10768 int do_ra, int do_s0, int do_s1,
10769 int framesize)
10770{
10771 TCGv t0 = tcg_temp_new();
10772 TCGv t1 = tcg_temp_new();
c48245f0 10773 TCGv t2 = tcg_temp_new();
364d4831
NF
10774 int args, astatic;
10775
10776 switch (aregs) {
10777 case 0:
10778 case 1:
10779 case 2:
10780 case 3:
10781 case 11:
10782 args = 0;
10783 break;
10784 case 4:
10785 case 5:
10786 case 6:
10787 case 7:
10788 args = 1;
10789 break;
10790 case 8:
10791 case 9:
10792 case 10:
10793 args = 2;
10794 break;
10795 case 12:
10796 case 13:
10797 args = 3;
10798 break;
10799 case 14:
10800 args = 4;
10801 break;
10802 default:
10803 generate_exception(ctx, EXCP_RI);
10804 return;
10805 }
10806
10807 switch (args) {
10808 case 4:
10809 gen_base_offset_addr(ctx, t0, 29, 12);
10810 gen_load_gpr(t1, 7);
5f68f5ae 10811 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10812 /* Fall through */
10813 case 3:
10814 gen_base_offset_addr(ctx, t0, 29, 8);
10815 gen_load_gpr(t1, 6);
5f68f5ae 10816 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10817 /* Fall through */
10818 case 2:
10819 gen_base_offset_addr(ctx, t0, 29, 4);
10820 gen_load_gpr(t1, 5);
5f68f5ae 10821 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10822 /* Fall through */
10823 case 1:
10824 gen_base_offset_addr(ctx, t0, 29, 0);
10825 gen_load_gpr(t1, 4);
5f68f5ae 10826 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10827 }
10828
10829 gen_load_gpr(t0, 29);
10830
5f68f5ae 10831#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10832 tcg_gen_movi_tl(t2, -4); \
10833 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10834 gen_load_gpr(t1, reg); \
10835 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10836 } while (0)
10837
10838 if (do_ra) {
10839 DECR_AND_STORE(31);
10840 }
10841
10842 switch (xsregs) {
10843 case 7:
10844 DECR_AND_STORE(30);
10845 /* Fall through */
10846 case 6:
10847 DECR_AND_STORE(23);
10848 /* Fall through */
10849 case 5:
10850 DECR_AND_STORE(22);
10851 /* Fall through */
10852 case 4:
10853 DECR_AND_STORE(21);
10854 /* Fall through */
10855 case 3:
10856 DECR_AND_STORE(20);
10857 /* Fall through */
10858 case 2:
10859 DECR_AND_STORE(19);
10860 /* Fall through */
10861 case 1:
10862 DECR_AND_STORE(18);
10863 }
10864
10865 if (do_s1) {
10866 DECR_AND_STORE(17);
10867 }
10868 if (do_s0) {
10869 DECR_AND_STORE(16);
10870 }
10871
10872 switch (aregs) {
10873 case 0:
10874 case 4:
10875 case 8:
10876 case 12:
10877 case 14:
10878 astatic = 0;
10879 break;
10880 case 1:
10881 case 5:
10882 case 9:
10883 case 13:
10884 astatic = 1;
10885 break;
10886 case 2:
10887 case 6:
10888 case 10:
10889 astatic = 2;
10890 break;
10891 case 3:
10892 case 7:
10893 astatic = 3;
10894 break;
10895 case 11:
10896 astatic = 4;
10897 break;
10898 default:
10899 generate_exception(ctx, EXCP_RI);
10900 return;
10901 }
10902
10903 if (astatic > 0) {
10904 DECR_AND_STORE(7);
10905 if (astatic > 1) {
10906 DECR_AND_STORE(6);
10907 if (astatic > 2) {
10908 DECR_AND_STORE(5);
10909 if (astatic > 3) {
10910 DECR_AND_STORE(4);
10911 }
10912 }
10913 }
10914 }
10915#undef DECR_AND_STORE
10916
c48245f0
MR
10917 tcg_gen_movi_tl(t2, -framesize);
10918 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10919 tcg_temp_free(t0);
10920 tcg_temp_free(t1);
c48245f0 10921 tcg_temp_free(t2);
364d4831
NF
10922}
10923
10924static void gen_mips16_restore (DisasContext *ctx,
10925 int xsregs, int aregs,
10926 int do_ra, int do_s0, int do_s1,
10927 int framesize)
10928{
10929 int astatic;
10930 TCGv t0 = tcg_temp_new();
10931 TCGv t1 = tcg_temp_new();
c48245f0 10932 TCGv t2 = tcg_temp_new();
364d4831 10933
c48245f0
MR
10934 tcg_gen_movi_tl(t2, framesize);
10935 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 10936
5f68f5ae 10937#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
10938 tcg_gen_movi_tl(t2, -4); \
10939 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10940 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10941 gen_store_gpr(t1, reg); \
364d4831
NF
10942 } while (0)
10943
10944 if (do_ra) {
10945 DECR_AND_LOAD(31);
10946 }
10947
10948 switch (xsregs) {
10949 case 7:
10950 DECR_AND_LOAD(30);
10951 /* Fall through */
10952 case 6:
10953 DECR_AND_LOAD(23);
10954 /* Fall through */
10955 case 5:
10956 DECR_AND_LOAD(22);
10957 /* Fall through */
10958 case 4:
10959 DECR_AND_LOAD(21);
10960 /* Fall through */
10961 case 3:
10962 DECR_AND_LOAD(20);
10963 /* Fall through */
10964 case 2:
10965 DECR_AND_LOAD(19);
10966 /* Fall through */
10967 case 1:
10968 DECR_AND_LOAD(18);
10969 }
10970
10971 if (do_s1) {
10972 DECR_AND_LOAD(17);
10973 }
10974 if (do_s0) {
10975 DECR_AND_LOAD(16);
10976 }
10977
10978 switch (aregs) {
10979 case 0:
10980 case 4:
10981 case 8:
10982 case 12:
10983 case 14:
10984 astatic = 0;
10985 break;
10986 case 1:
10987 case 5:
10988 case 9:
10989 case 13:
10990 astatic = 1;
10991 break;
10992 case 2:
10993 case 6:
10994 case 10:
10995 astatic = 2;
10996 break;
10997 case 3:
10998 case 7:
10999 astatic = 3;
11000 break;
11001 case 11:
11002 astatic = 4;
11003 break;
11004 default:
11005 generate_exception(ctx, EXCP_RI);
11006 return;
11007 }
11008
11009 if (astatic > 0) {
11010 DECR_AND_LOAD(7);
11011 if (astatic > 1) {
11012 DECR_AND_LOAD(6);
11013 if (astatic > 2) {
11014 DECR_AND_LOAD(5);
11015 if (astatic > 3) {
11016 DECR_AND_LOAD(4);
11017 }
11018 }
11019 }
11020 }
11021#undef DECR_AND_LOAD
11022
c48245f0
MR
11023 tcg_gen_movi_tl(t2, framesize);
11024 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11025 tcg_temp_free(t0);
11026 tcg_temp_free(t1);
c48245f0 11027 tcg_temp_free(t2);
364d4831
NF
11028}
11029
11030static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11031 int is_64_bit, int extended)
11032{
11033 TCGv t0;
11034
11035 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11036 generate_exception(ctx, EXCP_RI);
11037 return;
11038 }
11039
11040 t0 = tcg_temp_new();
11041
11042 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11043 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11044 if (!is_64_bit) {
11045 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11046 }
11047
11048 tcg_temp_free(t0);
11049}
11050
11051#if defined(TARGET_MIPS64)
d75c135e 11052static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11053 int ry, int funct, int16_t offset,
11054 int extended)
11055{
11056 switch (funct) {
11057 case I64_LDSP:
d9224450 11058 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11059 check_mips_64(ctx);
11060 offset = extended ? offset : offset << 3;
d75c135e 11061 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11062 break;
11063 case I64_SDSP:
d9224450 11064 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11065 check_mips_64(ctx);
11066 offset = extended ? offset : offset << 3;
5c13fdfd 11067 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11068 break;
11069 case I64_SDRASP:
d9224450 11070 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11071 check_mips_64(ctx);
11072 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11073 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11074 break;
11075 case I64_DADJSP:
d9224450 11076 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11077 check_mips_64(ctx);
11078 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11079 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11080 break;
11081 case I64_LDPC:
d9224450
MR
11082 check_insn(ctx, ISA_MIPS3);
11083 check_mips_64(ctx);
364d4831
NF
11084 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11085 generate_exception(ctx, EXCP_RI);
11086 } else {
11087 offset = extended ? offset : offset << 3;
d75c135e 11088 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11089 }
11090 break;
11091 case I64_DADDIU5:
d9224450 11092 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11093 check_mips_64(ctx);
11094 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11095 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11096 break;
11097 case I64_DADDIUPC:
d9224450 11098 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11099 check_mips_64(ctx);
11100 offset = extended ? offset : offset << 2;
11101 gen_addiupc(ctx, ry, offset, 1, extended);
11102 break;
11103 case I64_DADDIUSP:
d9224450 11104 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11105 check_mips_64(ctx);
11106 offset = extended ? offset : offset << 2;
d75c135e 11107 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11108 break;
11109 }
11110}
11111#endif
11112
240ce26a 11113static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11114{
895c2d04 11115 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11116 int op, rx, ry, funct, sa;
11117 int16_t imm, offset;
11118
11119 ctx->opcode = (ctx->opcode << 16) | extend;
11120 op = (ctx->opcode >> 11) & 0x1f;
11121 sa = (ctx->opcode >> 22) & 0x1f;
11122 funct = (ctx->opcode >> 8) & 0x7;
11123 rx = xlat((ctx->opcode >> 8) & 0x7);
11124 ry = xlat((ctx->opcode >> 5) & 0x7);
11125 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11126 | ((ctx->opcode >> 21) & 0x3f) << 5
11127 | (ctx->opcode & 0x1f));
11128
11129 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11130 counterparts. */
11131 switch (op) {
11132 case M16_OPC_ADDIUSP:
d75c135e 11133 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11134 break;
11135 case M16_OPC_ADDIUPC:
11136 gen_addiupc(ctx, rx, imm, 0, 1);
11137 break;
11138 case M16_OPC_B:
b231c103 11139 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11140 /* No delay slot, so just process as a normal instruction */
11141 break;
11142 case M16_OPC_BEQZ:
b231c103 11143 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11144 /* No delay slot, so just process as a normal instruction */
11145 break;
11146 case M16_OPC_BNEQZ:
b231c103 11147 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11148 /* No delay slot, so just process as a normal instruction */
11149 break;
11150 case M16_OPC_SHIFT:
11151 switch (ctx->opcode & 0x3) {
11152 case 0x0:
d75c135e 11153 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11154 break;
11155 case 0x1:
11156#if defined(TARGET_MIPS64)
11157 check_mips_64(ctx);
d75c135e 11158 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11159#else
11160 generate_exception(ctx, EXCP_RI);
11161#endif
11162 break;
11163 case 0x2:
d75c135e 11164 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11165 break;
11166 case 0x3:
d75c135e 11167 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11168 break;
11169 }
11170 break;
11171#if defined(TARGET_MIPS64)
11172 case M16_OPC_LD:
d9224450 11173 check_insn(ctx, ISA_MIPS3);
d75de749 11174 check_mips_64(ctx);
d75c135e 11175 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11176 break;
11177#endif
11178 case M16_OPC_RRIA:
11179 imm = ctx->opcode & 0xf;
11180 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11181 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11182 imm = (int16_t) (imm << 1) >> 1;
11183 if ((ctx->opcode >> 4) & 0x1) {
11184#if defined(TARGET_MIPS64)
11185 check_mips_64(ctx);
d75c135e 11186 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11187#else
11188 generate_exception(ctx, EXCP_RI);
11189#endif
11190 } else {
d75c135e 11191 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11192 }
11193 break;
11194 case M16_OPC_ADDIU8:
d75c135e 11195 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11196 break;
11197 case M16_OPC_SLTI:
d75c135e 11198 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11199 break;
11200 case M16_OPC_SLTIU:
d75c135e 11201 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11202 break;
11203 case M16_OPC_I8:
11204 switch (funct) {
11205 case I8_BTEQZ:
b231c103 11206 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11207 break;
11208 case I8_BTNEZ:
b231c103 11209 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11210 break;
11211 case I8_SWRASP:
5c13fdfd 11212 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11213 break;
11214 case I8_ADJSP:
d75c135e 11215 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11216 break;
11217 case I8_SVRS:
d9224450 11218 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11219 {
11220 int xsregs = (ctx->opcode >> 24) & 0x7;
11221 int aregs = (ctx->opcode >> 16) & 0xf;
11222 int do_ra = (ctx->opcode >> 6) & 0x1;
11223 int do_s0 = (ctx->opcode >> 5) & 0x1;
11224 int do_s1 = (ctx->opcode >> 4) & 0x1;
11225 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11226 | (ctx->opcode & 0xf)) << 3;
11227
11228 if (ctx->opcode & (1 << 7)) {
11229 gen_mips16_save(ctx, xsregs, aregs,
11230 do_ra, do_s0, do_s1,
11231 framesize);
11232 } else {
11233 gen_mips16_restore(ctx, xsregs, aregs,
11234 do_ra, do_s0, do_s1,
11235 framesize);
11236 }
11237 }
11238 break;
11239 default:
11240 generate_exception(ctx, EXCP_RI);
11241 break;
11242 }
11243 break;
11244 case M16_OPC_LI:
11245 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11246 break;
11247 case M16_OPC_CMPI:
11248 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11249 break;
11250#if defined(TARGET_MIPS64)
11251 case M16_OPC_SD:
d9224450
MR
11252 check_insn(ctx, ISA_MIPS3);
11253 check_mips_64(ctx);
5c13fdfd 11254 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11255 break;
11256#endif
11257 case M16_OPC_LB:
d75c135e 11258 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11259 break;
11260 case M16_OPC_LH:
d75c135e 11261 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11262 break;
11263 case M16_OPC_LWSP:
d75c135e 11264 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11265 break;
11266 case M16_OPC_LW:
d75c135e 11267 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11268 break;
11269 case M16_OPC_LBU:
d75c135e 11270 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11271 break;
11272 case M16_OPC_LHU:
d75c135e 11273 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11274 break;
11275 case M16_OPC_LWPC:
d75c135e 11276 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11277 break;
11278#if defined(TARGET_MIPS64)
11279 case M16_OPC_LWU:
d9224450
MR
11280 check_insn(ctx, ISA_MIPS3);
11281 check_mips_64(ctx);
d75c135e 11282 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11283 break;
11284#endif
11285 case M16_OPC_SB:
5c13fdfd 11286 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11287 break;
11288 case M16_OPC_SH:
5c13fdfd 11289 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11290 break;
11291 case M16_OPC_SWSP:
5c13fdfd 11292 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11293 break;
11294 case M16_OPC_SW:
5c13fdfd 11295 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11296 break;
11297#if defined(TARGET_MIPS64)
11298 case M16_OPC_I64:
d75c135e 11299 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11300 break;
11301#endif
11302 default:
11303 generate_exception(ctx, EXCP_RI);
11304 break;
11305 }
11306
11307 return 4;
11308}
11309
240ce26a 11310static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11311{
11312 int rx, ry;
11313 int sa;
11314 int op, cnvt_op, op1, offset;
11315 int funct;
11316 int n_bytes;
11317
11318 op = (ctx->opcode >> 11) & 0x1f;
11319 sa = (ctx->opcode >> 2) & 0x7;
11320 sa = sa == 0 ? 8 : sa;
11321 rx = xlat((ctx->opcode >> 8) & 0x7);
11322 cnvt_op = (ctx->opcode >> 5) & 0x7;
11323 ry = xlat((ctx->opcode >> 5) & 0x7);
11324 op1 = offset = ctx->opcode & 0x1f;
11325
11326 n_bytes = 2;
11327
11328 switch (op) {
11329 case M16_OPC_ADDIUSP:
11330 {
11331 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11332
d75c135e 11333 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11334 }
11335 break;
11336 case M16_OPC_ADDIUPC:
11337 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11338 break;
11339 case M16_OPC_B:
11340 offset = (ctx->opcode & 0x7ff) << 1;
11341 offset = (int16_t)(offset << 4) >> 4;
b231c103 11342 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11343 /* No delay slot, so just process as a normal instruction */
11344 break;
11345 case M16_OPC_JAL:
895c2d04 11346 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11347 offset = (((ctx->opcode & 0x1f) << 21)
11348 | ((ctx->opcode >> 5) & 0x1f) << 16
11349 | offset) << 2;
b231c103
YK
11350 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11351 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11352 n_bytes = 4;
364d4831
NF
11353 break;
11354 case M16_OPC_BEQZ:
b231c103
YK
11355 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11356 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11357 /* No delay slot, so just process as a normal instruction */
11358 break;
11359 case M16_OPC_BNEQZ:
b231c103
YK
11360 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11361 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11362 /* No delay slot, so just process as a normal instruction */
11363 break;
11364 case M16_OPC_SHIFT:
11365 switch (ctx->opcode & 0x3) {
11366 case 0x0:
d75c135e 11367 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11368 break;
11369 case 0x1:
11370#if defined(TARGET_MIPS64)
d9224450 11371 check_insn(ctx, ISA_MIPS3);
364d4831 11372 check_mips_64(ctx);
d75c135e 11373 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11374#else
11375 generate_exception(ctx, EXCP_RI);
11376#endif
11377 break;
11378 case 0x2:
d75c135e 11379 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11380 break;
11381 case 0x3:
d75c135e 11382 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11383 break;
11384 }
11385 break;
11386#if defined(TARGET_MIPS64)
11387 case M16_OPC_LD:
d9224450 11388 check_insn(ctx, ISA_MIPS3);
364d4831 11389 check_mips_64(ctx);
d75c135e 11390 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11391 break;
11392#endif
11393 case M16_OPC_RRIA:
11394 {
11395 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11396
11397 if ((ctx->opcode >> 4) & 1) {
11398#if defined(TARGET_MIPS64)
d9224450 11399 check_insn(ctx, ISA_MIPS3);
364d4831 11400 check_mips_64(ctx);
d75c135e 11401 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11402#else
11403 generate_exception(ctx, EXCP_RI);
11404#endif
11405 } else {
d75c135e 11406 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11407 }
11408 }
11409 break;
11410 case M16_OPC_ADDIU8:
11411 {
11412 int16_t imm = (int8_t) ctx->opcode;
11413
d75c135e 11414 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11415 }
11416 break;
11417 case M16_OPC_SLTI:
11418 {
11419 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11420 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11421 }
11422 break;
11423 case M16_OPC_SLTIU:
11424 {
11425 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11426 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11427 }
11428 break;
11429 case M16_OPC_I8:
11430 {
11431 int reg32;
11432
11433 funct = (ctx->opcode >> 8) & 0x7;
11434 switch (funct) {
11435 case I8_BTEQZ:
11436 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11437 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11438 break;
11439 case I8_BTNEZ:
11440 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11441 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11442 break;
11443 case I8_SWRASP:
5c13fdfd 11444 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11445 break;
11446 case I8_ADJSP:
d75c135e 11447 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11448 ((int8_t)ctx->opcode) << 3);
11449 break;
11450 case I8_SVRS:
d9224450 11451 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11452 {
11453 int do_ra = ctx->opcode & (1 << 6);
11454 int do_s0 = ctx->opcode & (1 << 5);
11455 int do_s1 = ctx->opcode & (1 << 4);
11456 int framesize = ctx->opcode & 0xf;
11457
11458 if (framesize == 0) {
11459 framesize = 128;
11460 } else {
11461 framesize = framesize << 3;
11462 }
11463
11464 if (ctx->opcode & (1 << 7)) {
11465 gen_mips16_save(ctx, 0, 0,
11466 do_ra, do_s0, do_s1, framesize);
11467 } else {
11468 gen_mips16_restore(ctx, 0, 0,
11469 do_ra, do_s0, do_s1, framesize);
11470 }
11471 }
11472 break;
11473 case I8_MOV32R:
11474 {
11475 int rz = xlat(ctx->opcode & 0x7);
11476
11477 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11478 ((ctx->opcode >> 5) & 0x7);
d75c135e 11479 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11480 }
11481 break;
11482 case I8_MOVR32:
11483 reg32 = ctx->opcode & 0x1f;
d75c135e 11484 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11485 break;
11486 default:
11487 generate_exception(ctx, EXCP_RI);
11488 break;
11489 }
11490 }
11491 break;
11492 case M16_OPC_LI:
11493 {
11494 int16_t imm = (uint8_t) ctx->opcode;
11495
d75c135e 11496 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11497 }
11498 break;
11499 case M16_OPC_CMPI:
11500 {
11501 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11502 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11503 }
11504 break;
11505#if defined(TARGET_MIPS64)
11506 case M16_OPC_SD:
d9224450 11507 check_insn(ctx, ISA_MIPS3);
364d4831 11508 check_mips_64(ctx);
5c13fdfd 11509 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11510 break;
11511#endif
11512 case M16_OPC_LB:
d75c135e 11513 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11514 break;
11515 case M16_OPC_LH:
d75c135e 11516 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11517 break;
11518 case M16_OPC_LWSP:
d75c135e 11519 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11520 break;
11521 case M16_OPC_LW:
d75c135e 11522 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11523 break;
11524 case M16_OPC_LBU:
d75c135e 11525 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11526 break;
11527 case M16_OPC_LHU:
d75c135e 11528 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11529 break;
11530 case M16_OPC_LWPC:
d75c135e 11531 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11532 break;
11533#if defined (TARGET_MIPS64)
11534 case M16_OPC_LWU:
d9224450 11535 check_insn(ctx, ISA_MIPS3);
364d4831 11536 check_mips_64(ctx);
d75c135e 11537 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11538 break;
11539#endif
11540 case M16_OPC_SB:
5c13fdfd 11541 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11542 break;
11543 case M16_OPC_SH:
5c13fdfd 11544 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11545 break;
11546 case M16_OPC_SWSP:
5c13fdfd 11547 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11548 break;
11549 case M16_OPC_SW:
5c13fdfd 11550 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11551 break;
11552 case M16_OPC_RRR:
11553 {
11554 int rz = xlat((ctx->opcode >> 2) & 0x7);
11555 int mips32_op;
11556
11557 switch (ctx->opcode & 0x3) {
11558 case RRR_ADDU:
11559 mips32_op = OPC_ADDU;
11560 break;
11561 case RRR_SUBU:
11562 mips32_op = OPC_SUBU;
11563 break;
11564#if defined(TARGET_MIPS64)
11565 case RRR_DADDU:
11566 mips32_op = OPC_DADDU;
d9224450 11567 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11568 check_mips_64(ctx);
11569 break;
11570 case RRR_DSUBU:
11571 mips32_op = OPC_DSUBU;
d9224450 11572 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11573 check_mips_64(ctx);
11574 break;
11575#endif
11576 default:
11577 generate_exception(ctx, EXCP_RI);
11578 goto done;
11579 }
11580
d75c135e 11581 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11582 done:
11583 ;
11584 }
11585 break;
11586 case M16_OPC_RR:
11587 switch (op1) {
11588 case RR_JR:
11589 {
11590 int nd = (ctx->opcode >> 7) & 0x1;
11591 int link = (ctx->opcode >> 6) & 0x1;
11592 int ra = (ctx->opcode >> 5) & 0x1;
11593
d9224450
MR
11594 if (nd) {
11595 check_insn(ctx, ISA_MIPS32);
11596 }
11597
364d4831 11598 if (link) {
b231c103 11599 op = OPC_JALR;
364d4831
NF
11600 } else {
11601 op = OPC_JR;
11602 }
11603
b231c103
YK
11604 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11605 (nd ? 0 : 2));
364d4831
NF
11606 }
11607 break;
11608 case RR_SDBBP:
11609 /* XXX: not clear which exception should be raised
11610 * when in debug mode...
11611 */
d75c135e 11612 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11613 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11614 generate_exception(ctx, EXCP_DBp);
11615 } else {
11616 generate_exception(ctx, EXCP_DBp);
11617 }
11618 break;
11619 case RR_SLT:
d75c135e 11620 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11621 break;
11622 case RR_SLTU:
d75c135e 11623 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11624 break;
11625 case RR_BREAK:
11626 generate_exception(ctx, EXCP_BREAK);
11627 break;
11628 case RR_SLLV:
d75c135e 11629 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11630 break;
11631 case RR_SRLV:
d75c135e 11632 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11633 break;
11634 case RR_SRAV:
d75c135e 11635 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11636 break;
11637#if defined (TARGET_MIPS64)
11638 case RR_DSRL:
d9224450 11639 check_insn(ctx, ISA_MIPS3);
364d4831 11640 check_mips_64(ctx);
d75c135e 11641 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11642 break;
11643#endif
11644 case RR_CMP:
d75c135e 11645 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11646 break;
11647 case RR_NEG:
d75c135e 11648 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11649 break;
11650 case RR_AND:
d75c135e 11651 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11652 break;
11653 case RR_OR:
d75c135e 11654 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11655 break;
11656 case RR_XOR:
d75c135e 11657 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11658 break;
11659 case RR_NOT:
d75c135e 11660 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11661 break;
11662 case RR_MFHI:
26135ead 11663 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11664 break;
11665 case RR_CNVT:
d9224450 11666 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11667 switch (cnvt_op) {
11668 case RR_RY_CNVT_ZEB:
11669 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11670 break;
11671 case RR_RY_CNVT_ZEH:
11672 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11673 break;
11674 case RR_RY_CNVT_SEB:
11675 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11676 break;
11677 case RR_RY_CNVT_SEH:
11678 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11679 break;
11680#if defined (TARGET_MIPS64)
11681 case RR_RY_CNVT_ZEW:
d9224450 11682 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11683 check_mips_64(ctx);
11684 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11685 break;
11686 case RR_RY_CNVT_SEW:
d9224450 11687 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11688 check_mips_64(ctx);
11689 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11690 break;
11691#endif
11692 default:
11693 generate_exception(ctx, EXCP_RI);
11694 break;
11695 }
11696 break;
11697 case RR_MFLO:
26135ead 11698 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11699 break;
11700#if defined (TARGET_MIPS64)
11701 case RR_DSRA:
d9224450 11702 check_insn(ctx, ISA_MIPS3);
364d4831 11703 check_mips_64(ctx);
d75c135e 11704 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11705 break;
11706 case RR_DSLLV:
d9224450 11707 check_insn(ctx, ISA_MIPS3);
364d4831 11708 check_mips_64(ctx);
d75c135e 11709 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11710 break;
11711 case RR_DSRLV:
d9224450 11712 check_insn(ctx, ISA_MIPS3);
364d4831 11713 check_mips_64(ctx);
d75c135e 11714 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11715 break;
11716 case RR_DSRAV:
d9224450 11717 check_insn(ctx, ISA_MIPS3);
364d4831 11718 check_mips_64(ctx);
d75c135e 11719 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11720 break;
11721#endif
11722 case RR_MULT:
26135ead 11723 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11724 break;
11725 case RR_MULTU:
26135ead 11726 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11727 break;
11728 case RR_DIV:
26135ead 11729 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11730 break;
11731 case RR_DIVU:
26135ead 11732 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11733 break;
11734#if defined (TARGET_MIPS64)
11735 case RR_DMULT:
d9224450 11736 check_insn(ctx, ISA_MIPS3);
364d4831 11737 check_mips_64(ctx);
26135ead 11738 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11739 break;
11740 case RR_DMULTU:
d9224450 11741 check_insn(ctx, ISA_MIPS3);
364d4831 11742 check_mips_64(ctx);
26135ead 11743 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11744 break;
11745 case RR_DDIV:
d9224450 11746 check_insn(ctx, ISA_MIPS3);
364d4831 11747 check_mips_64(ctx);
26135ead 11748 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11749 break;
11750 case RR_DDIVU:
d9224450 11751 check_insn(ctx, ISA_MIPS3);
364d4831 11752 check_mips_64(ctx);
26135ead 11753 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11754 break;
11755#endif
11756 default:
11757 generate_exception(ctx, EXCP_RI);
11758 break;
11759 }
11760 break;
11761 case M16_OPC_EXTEND:
240ce26a 11762 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11763 n_bytes = 4;
11764 break;
11765#if defined(TARGET_MIPS64)
11766 case M16_OPC_I64:
11767 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11768 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11769 break;
11770#endif
11771 default:
11772 generate_exception(ctx, EXCP_RI);
11773 break;
11774 }
11775
11776 return n_bytes;
11777}
11778
211da992 11779/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11780
211da992
CWR
11781/*
11782 * microMIPS32/microMIPS64 major opcodes
11783 *
11784 * 1. MIPS Architecture for Programmers Volume II-B:
11785 * The microMIPS32 Instruction Set (Revision 3.05)
11786 *
11787 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11788 *
11789 * 2. MIPS Architecture For Programmers Volume II-A:
11790 * The MIPS64 Instruction Set (Revision 3.51)
11791 */
6af0bf9c 11792
3c824109
NF
11793enum {
11794 POOL32A = 0x00,
11795 POOL16A = 0x01,
11796 LBU16 = 0x02,
11797 MOVE16 = 0x03,
11798 ADDI32 = 0x04,
11799 LBU32 = 0x05,
11800 SB32 = 0x06,
11801 LB32 = 0x07,
11802
11803 POOL32B = 0x08,
11804 POOL16B = 0x09,
11805 LHU16 = 0x0a,
11806 ANDI16 = 0x0b,
11807 ADDIU32 = 0x0c,
11808 LHU32 = 0x0d,
11809 SH32 = 0x0e,
11810 LH32 = 0x0f,
11811
11812 POOL32I = 0x10,
11813 POOL16C = 0x11,
11814 LWSP16 = 0x12,
11815 POOL16D = 0x13,
11816 ORI32 = 0x14,
11817 POOL32F = 0x15,
211da992
CWR
11818 POOL32S = 0x16, /* MIPS64 */
11819 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11820
211da992 11821 /* 0x1f is reserved */
3c824109
NF
11822 POOL32C = 0x18,
11823 LWGP16 = 0x19,
11824 LW16 = 0x1a,
11825 POOL16E = 0x1b,
11826 XORI32 = 0x1c,
11827 JALS32 = 0x1d,
11828 ADDIUPC = 0x1e,
3c824109
NF
11829
11830 /* 0x20 is reserved */
11831 RES_20 = 0x20,
11832 POOL16F = 0x21,
11833 SB16 = 0x22,
11834 BEQZ16 = 0x23,
11835 SLTI32 = 0x24,
11836 BEQ32 = 0x25,
11837 SWC132 = 0x26,
11838 LWC132 = 0x27,
11839
11840 /* 0x28 and 0x29 are reserved */
11841 RES_28 = 0x28,
11842 RES_29 = 0x29,
11843 SH16 = 0x2a,
11844 BNEZ16 = 0x2b,
11845 SLTIU32 = 0x2c,
11846 BNE32 = 0x2d,
11847 SDC132 = 0x2e,
11848 LDC132 = 0x2f,
11849
11850 /* 0x30 and 0x31 are reserved */
11851 RES_30 = 0x30,
11852 RES_31 = 0x31,
11853 SWSP16 = 0x32,
11854 B16 = 0x33,
11855 ANDI32 = 0x34,
11856 J32 = 0x35,
211da992
CWR
11857 SD32 = 0x36, /* MIPS64 */
11858 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11859
11860 /* 0x38 and 0x39 are reserved */
11861 RES_38 = 0x38,
11862 RES_39 = 0x39,
11863 SW16 = 0x3a,
11864 LI16 = 0x3b,
11865 JALX32 = 0x3c,
11866 JAL32 = 0x3d,
11867 SW32 = 0x3e,
11868 LW32 = 0x3f
11869};
11870
11871/* POOL32A encoding of minor opcode field */
11872
11873enum {
11874 /* These opcodes are distinguished only by bits 9..6; those bits are
11875 * what are recorded below. */
11876 SLL32 = 0x0,
11877 SRL32 = 0x1,
11878 SRA = 0x2,
11879 ROTR = 0x3,
11880
11881 SLLV = 0x0,
11882 SRLV = 0x1,
11883 SRAV = 0x2,
11884 ROTRV = 0x3,
11885 ADD = 0x4,
11886 ADDU32 = 0x5,
11887 SUB = 0x6,
11888 SUBU32 = 0x7,
11889 MUL = 0x8,
11890 AND = 0x9,
11891 OR32 = 0xa,
11892 NOR = 0xb,
11893 XOR32 = 0xc,
11894 SLT = 0xd,
11895 SLTU = 0xe,
11896
11897 MOVN = 0x0,
11898 MOVZ = 0x1,
11899 LWXS = 0x4,
11900
11901 /* The following can be distinguished by their lower 6 bits. */
11902 INS = 0x0c,
11903 EXT = 0x2c,
11904 POOL32AXF = 0x3c
11905};
11906
11907/* POOL32AXF encoding of minor opcode field extension */
11908
d132c79f
CWR
11909/*
11910 * 1. MIPS Architecture for Programmers Volume II-B:
11911 * The microMIPS32 Instruction Set (Revision 3.05)
11912 *
11913 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11914 *
11915 * 2. MIPS Architecture for Programmers VolumeIV-e:
11916 * The MIPS DSP Application-Specific Extension
11917 * to the microMIPS32 Architecture (Revision 2.34)
11918 *
11919 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11920 */
11921
3c824109
NF
11922enum {
11923 /* bits 11..6 */
11924 TEQ = 0x00,
11925 TGE = 0x08,
11926 TGEU = 0x10,
11927 TLT = 0x20,
11928 TLTU = 0x28,
11929 TNE = 0x30,
11930
11931 MFC0 = 0x03,
11932 MTC0 = 0x0b,
11933
d132c79f
CWR
11934 /* begin of microMIPS32 DSP */
11935
3c824109
NF
11936 /* bits 13..12 for 0x01 */
11937 MFHI_ACC = 0x0,
11938 MFLO_ACC = 0x1,
11939 MTHI_ACC = 0x2,
11940 MTLO_ACC = 0x3,
11941
11942 /* bits 13..12 for 0x2a */
11943 MADD_ACC = 0x0,
11944 MADDU_ACC = 0x1,
11945 MSUB_ACC = 0x2,
11946 MSUBU_ACC = 0x3,
11947
11948 /* bits 13..12 for 0x32 */
11949 MULT_ACC = 0x0,
6801038b 11950 MULTU_ACC = 0x1,
3c824109 11951
d132c79f
CWR
11952 /* end of microMIPS32 DSP */
11953
3c824109
NF
11954 /* bits 15..12 for 0x2c */
11955 SEB = 0x2,
11956 SEH = 0x3,
11957 CLO = 0x4,
11958 CLZ = 0x5,
11959 RDHWR = 0x6,
11960 WSBH = 0x7,
11961 MULT = 0x8,
11962 MULTU = 0x9,
11963 DIV = 0xa,
11964 DIVU = 0xb,
11965 MADD = 0xc,
11966 MADDU = 0xd,
11967 MSUB = 0xe,
11968 MSUBU = 0xf,
11969
11970 /* bits 15..12 for 0x34 */
11971 MFC2 = 0x4,
11972 MTC2 = 0x5,
11973 MFHC2 = 0x8,
11974 MTHC2 = 0x9,
11975 CFC2 = 0xc,
11976 CTC2 = 0xd,
11977
11978 /* bits 15..12 for 0x3c */
11979 JALR = 0x0,
11980 JR = 0x0, /* alias */
11981 JALR_HB = 0x1,
11982 JALRS = 0x4,
11983 JALRS_HB = 0x5,
11984
11985 /* bits 15..12 for 0x05 */
11986 RDPGPR = 0xe,
11987 WRPGPR = 0xf,
11988
11989 /* bits 15..12 for 0x0d */
11990 TLBP = 0x0,
11991 TLBR = 0x1,
11992 TLBWI = 0x2,
11993 TLBWR = 0x3,
11994 WAIT = 0x9,
11995 IRET = 0xd,
11996 DERET = 0xe,
11997 ERET = 0xf,
11998
11999 /* bits 15..12 for 0x15 */
12000 DMT = 0x0,
12001 DVPE = 0x1,
12002 EMT = 0x2,
12003 EVPE = 0x3,
12004
12005 /* bits 15..12 for 0x1d */
12006 DI = 0x4,
12007 EI = 0x5,
12008
12009 /* bits 15..12 for 0x2d */
12010 SYNC = 0x6,
12011 SYSCALL = 0x8,
12012 SDBBP = 0xd,
12013
12014 /* bits 15..12 for 0x35 */
12015 MFHI32 = 0x0,
12016 MFLO32 = 0x1,
12017 MTHI32 = 0x2,
12018 MTLO32 = 0x3,
12019};
12020
12021/* POOL32B encoding of minor opcode field (bits 15..12) */
12022
12023enum {
12024 LWC2 = 0x0,
12025 LWP = 0x1,
12026 LDP = 0x4,
12027 LWM32 = 0x5,
12028 CACHE = 0x6,
12029 LDM = 0x7,
12030 SWC2 = 0x8,
12031 SWP = 0x9,
12032 SDP = 0xc,
12033 SWM32 = 0xd,
12034 SDM = 0xf
12035};
12036
12037/* POOL32C encoding of minor opcode field (bits 15..12) */
12038
12039enum {
12040 LWL = 0x0,
12041 SWL = 0x8,
12042 LWR = 0x1,
12043 SWR = 0x9,
12044 PREF = 0x2,
12045 /* 0xa is reserved */
12046 LL = 0x3,
12047 SC = 0xb,
12048 LDL = 0x4,
12049 SDL = 0xc,
12050 LDR = 0x5,
12051 SDR = 0xd,
12052 /* 0x6 is reserved */
12053 LWU = 0xe,
12054 LLD = 0x7,
12055 SCD = 0xf
12056};
12057
12058/* POOL32F encoding of minor opcode field (bits 5..0) */
12059
12060enum {
12061 /* These are the bit 7..6 values */
12062 ADD_FMT = 0x0,
12063 MOVN_FMT = 0x0,
12064
12065 SUB_FMT = 0x1,
12066 MOVZ_FMT = 0x1,
12067
12068 MUL_FMT = 0x2,
12069
12070 DIV_FMT = 0x3,
12071
12072 /* These are the bit 8..6 values */
12073 RSQRT2_FMT = 0x0,
12074 MOVF_FMT = 0x0,
12075
12076 LWXC1 = 0x1,
12077 MOVT_FMT = 0x1,
12078
12079 PLL_PS = 0x2,
12080 SWXC1 = 0x2,
12081
12082 PLU_PS = 0x3,
12083 LDXC1 = 0x3,
12084
12085 PUL_PS = 0x4,
12086 SDXC1 = 0x4,
12087 RECIP2_FMT = 0x4,
12088
12089 PUU_PS = 0x5,
12090 LUXC1 = 0x5,
12091
12092 CVT_PS_S = 0x6,
12093 SUXC1 = 0x6,
12094 ADDR_PS = 0x6,
12095 PREFX = 0x6,
12096
12097 MULR_PS = 0x7,
12098
12099 MADD_S = 0x01,
12100 MADD_D = 0x09,
12101 MADD_PS = 0x11,
12102 ALNV_PS = 0x19,
12103 MSUB_S = 0x21,
12104 MSUB_D = 0x29,
12105 MSUB_PS = 0x31,
12106
12107 NMADD_S = 0x02,
12108 NMADD_D = 0x0a,
12109 NMADD_PS = 0x12,
12110 NMSUB_S = 0x22,
12111 NMSUB_D = 0x2a,
12112 NMSUB_PS = 0x32,
12113
12114 POOL32FXF = 0x3b,
12115
12116 CABS_COND_FMT = 0x1c, /* MIPS3D */
12117 C_COND_FMT = 0x3c
12118};
12119
12120/* POOL32Fxf encoding of minor opcode extension field */
12121
12122enum {
12123 CVT_L = 0x04,
12124 RSQRT_FMT = 0x08,
12125 FLOOR_L = 0x0c,
12126 CVT_PW_PS = 0x1c,
12127 CVT_W = 0x24,
12128 SQRT_FMT = 0x28,
12129 FLOOR_W = 0x2c,
12130 CVT_PS_PW = 0x3c,
12131 CFC1 = 0x40,
12132 RECIP_FMT = 0x48,
12133 CEIL_L = 0x4c,
12134 CTC1 = 0x60,
12135 CEIL_W = 0x6c,
12136 MFC1 = 0x80,
12137 CVT_S_PL = 0x84,
12138 TRUNC_L = 0x8c,
12139 MTC1 = 0xa0,
12140 CVT_S_PU = 0xa4,
12141 TRUNC_W = 0xac,
12142 MFHC1 = 0xc0,
12143 ROUND_L = 0xcc,
12144 MTHC1 = 0xe0,
12145 ROUND_W = 0xec,
12146
12147 MOV_FMT = 0x01,
12148 MOVF = 0x05,
12149 ABS_FMT = 0x0d,
12150 RSQRT1_FMT = 0x1d,
12151 MOVT = 0x25,
12152 NEG_FMT = 0x2d,
12153 CVT_D = 0x4d,
12154 RECIP1_FMT = 0x5d,
12155 CVT_S = 0x6d
12156};
12157
12158/* POOL32I encoding of minor opcode field (bits 25..21) */
12159
12160enum {
12161 BLTZ = 0x00,
12162 BLTZAL = 0x01,
12163 BGEZ = 0x02,
12164 BGEZAL = 0x03,
12165 BLEZ = 0x04,
12166 BNEZC = 0x05,
12167 BGTZ = 0x06,
12168 BEQZC = 0x07,
12169 TLTI = 0x08,
12170 TGEI = 0x09,
12171 TLTIU = 0x0a,
12172 TGEIU = 0x0b,
12173 TNEI = 0x0c,
12174 LUI = 0x0d,
12175 TEQI = 0x0e,
12176 SYNCI = 0x10,
12177 BLTZALS = 0x11,
12178 BGEZALS = 0x13,
12179 BC2F = 0x14,
12180 BC2T = 0x15,
12181 BPOSGE64 = 0x1a,
12182 BPOSGE32 = 0x1b,
12183 /* These overlap and are distinguished by bit16 of the instruction */
12184 BC1F = 0x1c,
12185 BC1T = 0x1d,
12186 BC1ANY2F = 0x1c,
12187 BC1ANY2T = 0x1d,
12188 BC1ANY4F = 0x1e,
12189 BC1ANY4T = 0x1f
12190};
12191
12192/* POOL16A encoding of minor opcode field */
12193
12194enum {
12195 ADDU16 = 0x0,
12196 SUBU16 = 0x1
12197};
12198
12199/* POOL16B encoding of minor opcode field */
12200
12201enum {
12202 SLL16 = 0x0,
12203 SRL16 = 0x1
12204};
12205
12206/* POOL16C encoding of minor opcode field */
12207
12208enum {
12209 NOT16 = 0x00,
12210 XOR16 = 0x04,
12211 AND16 = 0x08,
12212 OR16 = 0x0c,
12213 LWM16 = 0x10,
12214 SWM16 = 0x14,
12215 JR16 = 0x18,
12216 JRC16 = 0x1a,
12217 JALR16 = 0x1c,
12218 JALR16S = 0x1e,
12219 MFHI16 = 0x20,
12220 MFLO16 = 0x24,
12221 BREAK16 = 0x28,
12222 SDBBP16 = 0x2c,
12223 JRADDIUSP = 0x30
12224};
12225
12226/* POOL16D encoding of minor opcode field */
12227
12228enum {
12229 ADDIUS5 = 0x0,
12230 ADDIUSP = 0x1
12231};
12232
12233/* POOL16E encoding of minor opcode field */
12234
12235enum {
12236 ADDIUR2 = 0x0,
12237 ADDIUR1SP = 0x1
12238};
12239
12240static int mmreg (int r)
12241{
12242 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12243
12244 return map[r];
12245}
12246
12247/* Used for 16-bit store instructions. */
12248static int mmreg2 (int r)
12249{
12250 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12251
12252 return map[r];
12253}
12254
12255#define uMIPS_RD(op) ((op >> 7) & 0x7)
12256#define uMIPS_RS(op) ((op >> 4) & 0x7)
12257#define uMIPS_RS2(op) uMIPS_RS(op)
12258#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12259#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12260#define uMIPS_RS5(op) (op & 0x1f)
12261
12262/* Signed immediate */
12263#define SIMM(op, start, width) \
12264 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12265 << (32-width)) \
12266 >> (32-width))
12267/* Zero-extended immediate */
12268#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12269
d75c135e 12270static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12271{
12272 int rd = mmreg(uMIPS_RD(ctx->opcode));
12273
d75c135e 12274 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12275}
12276
d75c135e 12277static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12278{
12279 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12280 int rd = mmreg(uMIPS_RD(ctx->opcode));
12281 int rs = mmreg(uMIPS_RS(ctx->opcode));
12282
d75c135e 12283 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12284}
12285
d75c135e 12286static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12287{
12288 int encoded = ZIMM(ctx->opcode, 1, 9);
12289 int decoded;
12290
12291 if (encoded <= 1) {
12292 decoded = 256 + encoded;
12293 } else if (encoded <= 255) {
12294 decoded = encoded;
12295 } else if (encoded <= 509) {
12296 decoded = encoded - 512;
12297 } else {
12298 decoded = encoded - 768;
12299 }
12300
d75c135e 12301 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12302}
12303
d75c135e 12304static void gen_addius5(DisasContext *ctx)
3c824109
NF
12305{
12306 int imm = SIMM(ctx->opcode, 1, 4);
12307 int rd = (ctx->opcode >> 5) & 0x1f;
12308
d75c135e 12309 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12310}
12311
d75c135e 12312static void gen_andi16(DisasContext *ctx)
3c824109
NF
12313{
12314 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12315 31, 32, 63, 64, 255, 32768, 65535 };
12316 int rd = mmreg(uMIPS_RD(ctx->opcode));
12317 int rs = mmreg(uMIPS_RS(ctx->opcode));
12318 int encoded = ZIMM(ctx->opcode, 0, 4);
12319
d75c135e 12320 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12321}
12322
12323static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12324 int base, int16_t offset)
12325{
e1050a76 12326 const char *opn = "ldst_multiple";
3c824109
NF
12327 TCGv t0, t1;
12328 TCGv_i32 t2;
12329
12330 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12331 generate_exception(ctx, EXCP_RI);
12332 return;
12333 }
12334
12335 t0 = tcg_temp_new();
12336
12337 gen_base_offset_addr(ctx, t0, base, offset);
12338
12339 t1 = tcg_const_tl(reglist);
12340 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12341
3c824109
NF
12342 save_cpu_state(ctx, 1);
12343 switch (opc) {
12344 case LWM32:
895c2d04 12345 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12346 opn = "lwm";
3c824109
NF
12347 break;
12348 case SWM32:
895c2d04 12349 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12350 opn = "swm";
3c824109
NF
12351 break;
12352#ifdef TARGET_MIPS64
12353 case LDM:
895c2d04 12354 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12355 opn = "ldm";
3c824109
NF
12356 break;
12357 case SDM:
895c2d04 12358 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12359 opn = "sdm";
3c824109 12360 break;
6af0bf9c 12361#endif
3c824109 12362 }
e1050a76 12363 (void)opn;
3c824109
NF
12364 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12365 tcg_temp_free(t0);
33087598 12366 tcg_temp_free(t1);
3c824109
NF
12367 tcg_temp_free_i32(t2);
12368}
6af0bf9c 12369
3c824109 12370
240ce26a 12371static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12372{
3c824109
NF
12373 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12374 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12375
3c824109
NF
12376 switch (((ctx->opcode) >> 4) & 0x3f) {
12377 case NOT16 + 0:
12378 case NOT16 + 1:
12379 case NOT16 + 2:
12380 case NOT16 + 3:
d75c135e 12381 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12382 break;
12383 case XOR16 + 0:
12384 case XOR16 + 1:
12385 case XOR16 + 2:
12386 case XOR16 + 3:
d75c135e 12387 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12388 break;
12389 case AND16 + 0:
12390 case AND16 + 1:
12391 case AND16 + 2:
12392 case AND16 + 3:
d75c135e 12393 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12394 break;
12395 case OR16 + 0:
12396 case OR16 + 1:
12397 case OR16 + 2:
12398 case OR16 + 3:
d75c135e 12399 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12400 break;
12401 case LWM16 + 0:
12402 case LWM16 + 1:
12403 case LWM16 + 2:
12404 case LWM16 + 3:
12405 {
12406 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12407 int offset = ZIMM(ctx->opcode, 0, 4);
12408
12409 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12410 29, offset << 2);
12411 }
12412 break;
12413 case SWM16 + 0:
12414 case SWM16 + 1:
12415 case SWM16 + 2:
12416 case SWM16 + 3:
12417 {
12418 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12419 int offset = ZIMM(ctx->opcode, 0, 4);
12420
12421 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12422 29, offset << 2);
12423 }
12424 break;
12425 case JR16 + 0:
12426 case JR16 + 1:
12427 {
12428 int reg = ctx->opcode & 0x1f;
12429
b231c103 12430 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12431 }
3c824109
NF
12432 break;
12433 case JRC16 + 0:
12434 case JRC16 + 1:
12435 {
12436 int reg = ctx->opcode & 0x1f;
b231c103 12437 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12438 /* Let normal delay slot handling in our caller take us
12439 to the branch target. */
12440 }
12441 break;
12442 case JALR16 + 0:
12443 case JALR16 + 1:
b231c103
YK
12444 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12445 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12446 break;
3c824109
NF
12447 case JALR16S + 0:
12448 case JALR16S + 1:
b231c103
YK
12449 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12450 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12451 break;
12452 case MFHI16 + 0:
12453 case MFHI16 + 1:
26135ead 12454 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12455 break;
12456 case MFLO16 + 0:
12457 case MFLO16 + 1:
26135ead 12458 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12459 break;
12460 case BREAK16:
12461 generate_exception(ctx, EXCP_BREAK);
12462 break;
12463 case SDBBP16:
12464 /* XXX: not clear which exception should be raised
12465 * when in debug mode...
12466 */
d75c135e 12467 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12468 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12469 generate_exception(ctx, EXCP_DBp);
12470 } else {
12471 generate_exception(ctx, EXCP_DBp);
12472 }
12473 break;
12474 case JRADDIUSP + 0:
12475 case JRADDIUSP + 1:
12476 {
12477 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12478 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12479 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12480 /* Let normal delay slot handling in our caller take us
12481 to the branch target. */
12482 }
12483 break;
12484 default:
12485 generate_exception(ctx, EXCP_RI);
12486 break;
12487 }
12488}
12489
12490static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12491{
12492 TCGv t0 = tcg_temp_new();
12493 TCGv t1 = tcg_temp_new();
12494
12495 gen_load_gpr(t0, base);
12496
12497 if (index != 0) {
12498 gen_load_gpr(t1, index);
12499 tcg_gen_shli_tl(t1, t1, 2);
12500 gen_op_addr_add(ctx, t0, t1, t0);
12501 }
12502
5f68f5ae 12503 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12504 gen_store_gpr(t1, rd);
12505
12506 tcg_temp_free(t0);
12507 tcg_temp_free(t1);
12508}
12509
12510static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12511 int base, int16_t offset)
12512{
12513 const char *opn = "ldst_pair";
12514 TCGv t0, t1;
12515
36c6711b 12516 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12517 generate_exception(ctx, EXCP_RI);
d796321b
FB
12518 return;
12519 }
12520
3c824109
NF
12521 t0 = tcg_temp_new();
12522 t1 = tcg_temp_new();
8e9ade68 12523
3c824109
NF
12524 gen_base_offset_addr(ctx, t0, base, offset);
12525
12526 switch (opc) {
12527 case LWP:
36c6711b
EJ
12528 if (rd == base) {
12529 generate_exception(ctx, EXCP_RI);
12530 return;
12531 }
5f68f5ae 12532 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12533 gen_store_gpr(t1, rd);
12534 tcg_gen_movi_tl(t1, 4);
12535 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12536 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12537 gen_store_gpr(t1, rd+1);
12538 opn = "lwp";
12539 break;
12540 case SWP:
3c824109 12541 gen_load_gpr(t1, rd);
5f68f5ae 12542 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12543 tcg_gen_movi_tl(t1, 4);
12544 gen_op_addr_add(ctx, t0, t0, t1);
12545 gen_load_gpr(t1, rd+1);
5f68f5ae 12546 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12547 opn = "swp";
12548 break;
12549#ifdef TARGET_MIPS64
12550 case LDP:
36c6711b
EJ
12551 if (rd == base) {
12552 generate_exception(ctx, EXCP_RI);
12553 return;
12554 }
5f68f5ae 12555 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12556 gen_store_gpr(t1, rd);
12557 tcg_gen_movi_tl(t1, 8);
12558 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12559 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12560 gen_store_gpr(t1, rd+1);
12561 opn = "ldp";
12562 break;
12563 case SDP:
3c824109 12564 gen_load_gpr(t1, rd);
5f68f5ae 12565 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12566 tcg_gen_movi_tl(t1, 8);
12567 gen_op_addr_add(ctx, t0, t0, t1);
12568 gen_load_gpr(t1, rd+1);
5f68f5ae 12569 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12570 opn = "sdp";
12571 break;
12572#endif
6af0bf9c 12573 }
2abf314d 12574 (void)opn; /* avoid a compiler warning */
3c824109
NF
12575 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12576 tcg_temp_free(t0);
12577 tcg_temp_free(t1);
12578}
618b0fe9 12579
240ce26a 12580static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12581{
12582 int extension = (ctx->opcode >> 6) & 0x3f;
12583 int minor = (ctx->opcode >> 12) & 0xf;
12584 uint32_t mips32_op;
12585
12586 switch (extension) {
12587 case TEQ:
12588 mips32_op = OPC_TEQ;
12589 goto do_trap;
12590 case TGE:
12591 mips32_op = OPC_TGE;
12592 goto do_trap;
12593 case TGEU:
12594 mips32_op = OPC_TGEU;
12595 goto do_trap;
12596 case TLT:
12597 mips32_op = OPC_TLT;
12598 goto do_trap;
12599 case TLTU:
12600 mips32_op = OPC_TLTU;
12601 goto do_trap;
12602 case TNE:
12603 mips32_op = OPC_TNE;
12604 do_trap:
12605 gen_trap(ctx, mips32_op, rs, rt, -1);
12606 break;
12607#ifndef CONFIG_USER_ONLY
12608 case MFC0:
12609 case MFC0 + 32:
2e15497c 12610 check_cp0_enabled(ctx);
3c824109
NF
12611 if (rt == 0) {
12612 /* Treat as NOP. */
12613 break;
12614 }
d75c135e 12615 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12616 break;
12617 case MTC0:
12618 case MTC0 + 32:
2e15497c 12619 check_cp0_enabled(ctx);
3c824109
NF
12620 {
12621 TCGv t0 = tcg_temp_new();
618b0fe9 12622
3c824109 12623 gen_load_gpr(t0, rt);
d75c135e 12624 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12625 tcg_temp_free(t0);
12626 }
12627 break;
12628#endif
a1fc6246
LA
12629 case 0x2a:
12630 switch (minor & 3) {
12631 case MADD_ACC:
12632 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12633 break;
12634 case MADDU_ACC:
12635 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12636 break;
12637 case MSUB_ACC:
12638 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12639 break;
12640 case MSUBU_ACC:
12641 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12642 break;
12643 default:
12644 goto pool32axf_invalid;
12645 }
12646 break;
12647 case 0x32:
12648 switch (minor & 3) {
12649 case MULT_ACC:
12650 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12651 break;
12652 case MULTU_ACC:
12653 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12654 break;
12655 default:
12656 goto pool32axf_invalid;
12657 }
12658 break;
3c824109
NF
12659 case 0x2c:
12660 switch (minor) {
12661 case SEB:
12662 gen_bshfl(ctx, OPC_SEB, rs, rt);
12663 break;
12664 case SEH:
12665 gen_bshfl(ctx, OPC_SEH, rs, rt);
12666 break;
12667 case CLO:
12668 mips32_op = OPC_CLO;
12669 goto do_cl;
12670 case CLZ:
12671 mips32_op = OPC_CLZ;
12672 do_cl:
d75c135e 12673 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12674 gen_cl(ctx, mips32_op, rt, rs);
12675 break;
12676 case RDHWR:
d75c135e 12677 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12678 break;
12679 case WSBH:
12680 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12681 break;
12682 case MULT:
12683 mips32_op = OPC_MULT;
26135ead 12684 goto do_mul;
3c824109
NF
12685 case MULTU:
12686 mips32_op = OPC_MULTU;
26135ead 12687 goto do_mul;
3c824109
NF
12688 case DIV:
12689 mips32_op = OPC_DIV;
26135ead 12690 goto do_div;
3c824109
NF
12691 case DIVU:
12692 mips32_op = OPC_DIVU;
26135ead
RS
12693 goto do_div;
12694 do_div:
12695 check_insn(ctx, ISA_MIPS32);
12696 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12697 break;
3c824109
NF
12698 case MADD:
12699 mips32_op = OPC_MADD;
26135ead 12700 goto do_mul;
3c824109
NF
12701 case MADDU:
12702 mips32_op = OPC_MADDU;
26135ead 12703 goto do_mul;
3c824109
NF
12704 case MSUB:
12705 mips32_op = OPC_MSUB;
26135ead 12706 goto do_mul;
3c824109
NF
12707 case MSUBU:
12708 mips32_op = OPC_MSUBU;
26135ead 12709 do_mul:
d75c135e 12710 check_insn(ctx, ISA_MIPS32);
a1fc6246 12711 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12712 break;
12713 default:
12714 goto pool32axf_invalid;
12715 }
12716 break;
12717 case 0x34:
12718 switch (minor) {
12719 case MFC2:
12720 case MTC2:
12721 case MFHC2:
12722 case MTHC2:
12723 case CFC2:
12724 case CTC2:
12725 generate_exception_err(ctx, EXCP_CpU, 2);
12726 break;
12727 default:
12728 goto pool32axf_invalid;
12729 }
12730 break;
12731 case 0x3c:
12732 switch (minor) {
12733 case JALR:
12734 case JALR_HB:
b231c103
YK
12735 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12736 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12737 break;
12738 case JALRS:
12739 case JALRS_HB:
b231c103
YK
12740 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12741 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12742 break;
12743 default:
12744 goto pool32axf_invalid;
12745 }
12746 break;
12747 case 0x05:
12748 switch (minor) {
12749 case RDPGPR:
2e15497c 12750 check_cp0_enabled(ctx);
d75c135e 12751 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12752 gen_load_srsgpr(rt, rs);
12753 break;
12754 case WRPGPR:
2e15497c 12755 check_cp0_enabled(ctx);
d75c135e 12756 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12757 gen_store_srsgpr(rt, rs);
12758 break;
12759 default:
12760 goto pool32axf_invalid;
12761 }
12762 break;
12763#ifndef CONFIG_USER_ONLY
12764 case 0x0d:
12765 switch (minor) {
12766 case TLBP:
12767 mips32_op = OPC_TLBP;
12768 goto do_cp0;
12769 case TLBR:
12770 mips32_op = OPC_TLBR;
12771 goto do_cp0;
12772 case TLBWI:
12773 mips32_op = OPC_TLBWI;
12774 goto do_cp0;
12775 case TLBWR:
12776 mips32_op = OPC_TLBWR;
12777 goto do_cp0;
12778 case WAIT:
12779 mips32_op = OPC_WAIT;
12780 goto do_cp0;
12781 case DERET:
12782 mips32_op = OPC_DERET;
12783 goto do_cp0;
12784 case ERET:
12785 mips32_op = OPC_ERET;
12786 do_cp0:
12787 gen_cp0(env, ctx, mips32_op, rt, rs);
12788 break;
12789 default:
12790 goto pool32axf_invalid;
12791 }
12792 break;
12793 case 0x1d:
12794 switch (minor) {
12795 case DI:
2e15497c 12796 check_cp0_enabled(ctx);
3c824109
NF
12797 {
12798 TCGv t0 = tcg_temp_new();
12799
12800 save_cpu_state(ctx, 1);
895c2d04 12801 gen_helper_di(t0, cpu_env);
3c824109
NF
12802 gen_store_gpr(t0, rs);
12803 /* Stop translation as we may have switched the execution mode */
12804 ctx->bstate = BS_STOP;
12805 tcg_temp_free(t0);
12806 }
12807 break;
12808 case EI:
2e15497c 12809 check_cp0_enabled(ctx);
3c824109
NF
12810 {
12811 TCGv t0 = tcg_temp_new();
12812
12813 save_cpu_state(ctx, 1);
895c2d04 12814 gen_helper_ei(t0, cpu_env);
3c824109
NF
12815 gen_store_gpr(t0, rs);
12816 /* Stop translation as we may have switched the execution mode */
12817 ctx->bstate = BS_STOP;
12818 tcg_temp_free(t0);
12819 }
12820 break;
12821 default:
12822 goto pool32axf_invalid;
12823 }
12824 break;
12825#endif
12826 case 0x2d:
12827 switch (minor) {
12828 case SYNC:
12829 /* NOP */
12830 break;
12831 case SYSCALL:
12832 generate_exception(ctx, EXCP_SYSCALL);
12833 ctx->bstate = BS_STOP;
12834 break;
12835 case SDBBP:
d75c135e 12836 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12837 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12838 generate_exception(ctx, EXCP_DBp);
12839 } else {
12840 generate_exception(ctx, EXCP_DBp);
12841 }
12842 break;
12843 default:
12844 goto pool32axf_invalid;
12845 }
12846 break;
a1fc6246 12847 case 0x01:
26135ead 12848 switch (minor & 3) {
a1fc6246 12849 case MFHI_ACC:
26135ead 12850 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12851 break;
a1fc6246 12852 case MFLO_ACC:
26135ead 12853 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12854 break;
a1fc6246 12855 case MTHI_ACC:
26135ead 12856 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12857 break;
a1fc6246 12858 case MTLO_ACC:
26135ead 12859 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12860 break;
12861 default:
12862 goto pool32axf_invalid;
12863 }
12864 break;
a1fc6246
LA
12865 case 0x35:
12866 switch (minor) {
12867 case MFHI32:
12868 gen_HILO(ctx, OPC_MFHI, 0, rs);
12869 break;
12870 case MFLO32:
12871 gen_HILO(ctx, OPC_MFLO, 0, rs);
12872 break;
12873 case MTHI32:
12874 gen_HILO(ctx, OPC_MTHI, 0, rs);
12875 break;
12876 case MTLO32:
12877 gen_HILO(ctx, OPC_MTLO, 0, rs);
12878 break;
12879 default:
12880 goto pool32axf_invalid;
12881 }
12882 break;
3c824109
NF
12883 default:
12884 pool32axf_invalid:
12885 MIPS_INVAL("pool32axf");
12886 generate_exception(ctx, EXCP_RI);
12887 break;
12888 }
12889}
12890
12891/* Values for microMIPS fmt field. Variable-width, depending on which
12892 formats the instruction supports. */
12893
12894enum {
12895 FMT_SD_S = 0,
12896 FMT_SD_D = 1,
12897
12898 FMT_SDPS_S = 0,
12899 FMT_SDPS_D = 1,
12900 FMT_SDPS_PS = 2,
12901
12902 FMT_SWL_S = 0,
12903 FMT_SWL_W = 1,
12904 FMT_SWL_L = 2,
12905
12906 FMT_DWL_D = 0,
12907 FMT_DWL_W = 1,
12908 FMT_DWL_L = 2
12909};
12910
d75c135e 12911static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12912{
12913 int extension = (ctx->opcode >> 6) & 0x3ff;
12914 uint32_t mips32_op;
12915
12916#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12917#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12918#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12919
12920 switch (extension) {
12921 case FLOAT_1BIT_FMT(CFC1, 0):
12922 mips32_op = OPC_CFC1;
12923 goto do_cp1;
12924 case FLOAT_1BIT_FMT(CTC1, 0):
12925 mips32_op = OPC_CTC1;
12926 goto do_cp1;
12927 case FLOAT_1BIT_FMT(MFC1, 0):
12928 mips32_op = OPC_MFC1;
12929 goto do_cp1;
12930 case FLOAT_1BIT_FMT(MTC1, 0):
12931 mips32_op = OPC_MTC1;
12932 goto do_cp1;
12933 case FLOAT_1BIT_FMT(MFHC1, 0):
12934 mips32_op = OPC_MFHC1;
12935 goto do_cp1;
12936 case FLOAT_1BIT_FMT(MTHC1, 0):
12937 mips32_op = OPC_MTHC1;
12938 do_cp1:
12939 gen_cp1(ctx, mips32_op, rt, rs);
12940 break;
12941
12942 /* Reciprocal square root */
12943 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12944 mips32_op = OPC_RSQRT_S;
12945 goto do_unaryfp;
12946 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12947 mips32_op = OPC_RSQRT_D;
12948 goto do_unaryfp;
12949
12950 /* Square root */
12951 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12952 mips32_op = OPC_SQRT_S;
12953 goto do_unaryfp;
12954 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12955 mips32_op = OPC_SQRT_D;
12956 goto do_unaryfp;
12957
12958 /* Reciprocal */
12959 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12960 mips32_op = OPC_RECIP_S;
12961 goto do_unaryfp;
12962 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12963 mips32_op = OPC_RECIP_D;
12964 goto do_unaryfp;
12965
12966 /* Floor */
12967 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12968 mips32_op = OPC_FLOOR_L_S;
12969 goto do_unaryfp;
12970 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12971 mips32_op = OPC_FLOOR_L_D;
12972 goto do_unaryfp;
12973 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12974 mips32_op = OPC_FLOOR_W_S;
12975 goto do_unaryfp;
12976 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12977 mips32_op = OPC_FLOOR_W_D;
12978 goto do_unaryfp;
12979
12980 /* Ceiling */
12981 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12982 mips32_op = OPC_CEIL_L_S;
12983 goto do_unaryfp;
12984 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12985 mips32_op = OPC_CEIL_L_D;
12986 goto do_unaryfp;
12987 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12988 mips32_op = OPC_CEIL_W_S;
12989 goto do_unaryfp;
12990 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12991 mips32_op = OPC_CEIL_W_D;
12992 goto do_unaryfp;
12993
12994 /* Truncation */
12995 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12996 mips32_op = OPC_TRUNC_L_S;
12997 goto do_unaryfp;
12998 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12999 mips32_op = OPC_TRUNC_L_D;
13000 goto do_unaryfp;
13001 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13002 mips32_op = OPC_TRUNC_W_S;
13003 goto do_unaryfp;
13004 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13005 mips32_op = OPC_TRUNC_W_D;
13006 goto do_unaryfp;
13007
13008 /* Round */
13009 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13010 mips32_op = OPC_ROUND_L_S;
13011 goto do_unaryfp;
13012 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13013 mips32_op = OPC_ROUND_L_D;
13014 goto do_unaryfp;
13015 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13016 mips32_op = OPC_ROUND_W_S;
13017 goto do_unaryfp;
13018 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13019 mips32_op = OPC_ROUND_W_D;
13020 goto do_unaryfp;
13021
13022 /* Integer to floating-point conversion */
13023 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13024 mips32_op = OPC_CVT_L_S;
13025 goto do_unaryfp;
13026 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13027 mips32_op = OPC_CVT_L_D;
13028 goto do_unaryfp;
13029 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13030 mips32_op = OPC_CVT_W_S;
13031 goto do_unaryfp;
13032 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13033 mips32_op = OPC_CVT_W_D;
13034 goto do_unaryfp;
13035
13036 /* Paired-foo conversions */
13037 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13038 mips32_op = OPC_CVT_S_PL;
13039 goto do_unaryfp;
13040 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13041 mips32_op = OPC_CVT_S_PU;
13042 goto do_unaryfp;
13043 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13044 mips32_op = OPC_CVT_PW_PS;
13045 goto do_unaryfp;
13046 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13047 mips32_op = OPC_CVT_PS_PW;
13048 goto do_unaryfp;
13049
13050 /* Floating-point moves */
13051 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13052 mips32_op = OPC_MOV_S;
13053 goto do_unaryfp;
13054 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13055 mips32_op = OPC_MOV_D;
13056 goto do_unaryfp;
13057 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13058 mips32_op = OPC_MOV_PS;
13059 goto do_unaryfp;
13060
13061 /* Absolute value */
13062 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13063 mips32_op = OPC_ABS_S;
13064 goto do_unaryfp;
13065 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13066 mips32_op = OPC_ABS_D;
13067 goto do_unaryfp;
13068 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13069 mips32_op = OPC_ABS_PS;
13070 goto do_unaryfp;
13071
13072 /* Negation */
13073 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13074 mips32_op = OPC_NEG_S;
13075 goto do_unaryfp;
13076 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13077 mips32_op = OPC_NEG_D;
13078 goto do_unaryfp;
13079 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13080 mips32_op = OPC_NEG_PS;
13081 goto do_unaryfp;
13082
13083 /* Reciprocal square root step */
13084 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13085 mips32_op = OPC_RSQRT1_S;
13086 goto do_unaryfp;
13087 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13088 mips32_op = OPC_RSQRT1_D;
13089 goto do_unaryfp;
13090 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13091 mips32_op = OPC_RSQRT1_PS;
13092 goto do_unaryfp;
13093
13094 /* Reciprocal step */
13095 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13096 mips32_op = OPC_RECIP1_S;
13097 goto do_unaryfp;
13098 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13099 mips32_op = OPC_RECIP1_S;
13100 goto do_unaryfp;
13101 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13102 mips32_op = OPC_RECIP1_PS;
13103 goto do_unaryfp;
13104
13105 /* Conversions from double */
13106 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13107 mips32_op = OPC_CVT_D_S;
13108 goto do_unaryfp;
13109 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13110 mips32_op = OPC_CVT_D_W;
13111 goto do_unaryfp;
13112 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13113 mips32_op = OPC_CVT_D_L;
13114 goto do_unaryfp;
13115
13116 /* Conversions from single */
13117 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13118 mips32_op = OPC_CVT_S_D;
13119 goto do_unaryfp;
13120 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13121 mips32_op = OPC_CVT_S_W;
13122 goto do_unaryfp;
13123 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13124 mips32_op = OPC_CVT_S_L;
13125 do_unaryfp:
13126 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13127 break;
13128
13129 /* Conditional moves on floating-point codes */
13130 case COND_FLOAT_MOV(MOVT, 0):
13131 case COND_FLOAT_MOV(MOVT, 1):
13132 case COND_FLOAT_MOV(MOVT, 2):
13133 case COND_FLOAT_MOV(MOVT, 3):
13134 case COND_FLOAT_MOV(MOVT, 4):
13135 case COND_FLOAT_MOV(MOVT, 5):
13136 case COND_FLOAT_MOV(MOVT, 6):
13137 case COND_FLOAT_MOV(MOVT, 7):
13138 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13139 break;
13140 case COND_FLOAT_MOV(MOVF, 0):
13141 case COND_FLOAT_MOV(MOVF, 1):
13142 case COND_FLOAT_MOV(MOVF, 2):
13143 case COND_FLOAT_MOV(MOVF, 3):
13144 case COND_FLOAT_MOV(MOVF, 4):
13145 case COND_FLOAT_MOV(MOVF, 5):
13146 case COND_FLOAT_MOV(MOVF, 6):
13147 case COND_FLOAT_MOV(MOVF, 7):
13148 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13149 break;
13150 default:
13151 MIPS_INVAL("pool32fxf");
13152 generate_exception(ctx, EXCP_RI);
13153 break;
13154 }
13155}
13156
7db13fae 13157static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13158 uint16_t insn_hw1)
3c824109
NF
13159{
13160 int32_t offset;
13161 uint16_t insn;
13162 int rt, rs, rd, rr;
13163 int16_t imm;
13164 uint32_t op, minor, mips32_op;
13165 uint32_t cond, fmt, cc;
13166
895c2d04 13167 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13168 ctx->opcode = (ctx->opcode << 16) | insn;
13169
13170 rt = (ctx->opcode >> 21) & 0x1f;
13171 rs = (ctx->opcode >> 16) & 0x1f;
13172 rd = (ctx->opcode >> 11) & 0x1f;
13173 rr = (ctx->opcode >> 6) & 0x1f;
13174 imm = (int16_t) ctx->opcode;
13175
13176 op = (ctx->opcode >> 26) & 0x3f;
13177 switch (op) {
13178 case POOL32A:
13179 minor = ctx->opcode & 0x3f;
13180 switch (minor) {
13181 case 0x00:
13182 minor = (ctx->opcode >> 6) & 0xf;
13183 switch (minor) {
13184 case SLL32:
13185 mips32_op = OPC_SLL;
13186 goto do_shifti;
13187 case SRA:
13188 mips32_op = OPC_SRA;
13189 goto do_shifti;
13190 case SRL32:
13191 mips32_op = OPC_SRL;
13192 goto do_shifti;
13193 case ROTR:
13194 mips32_op = OPC_ROTR;
13195 do_shifti:
d75c135e 13196 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13197 break;
13198 default:
13199 goto pool32a_invalid;
13200 }
13201 break;
13202 case 0x10:
13203 minor = (ctx->opcode >> 6) & 0xf;
13204 switch (minor) {
13205 /* Arithmetic */
13206 case ADD:
13207 mips32_op = OPC_ADD;
13208 goto do_arith;
13209 case ADDU32:
13210 mips32_op = OPC_ADDU;
13211 goto do_arith;
13212 case SUB:
13213 mips32_op = OPC_SUB;
13214 goto do_arith;
13215 case SUBU32:
13216 mips32_op = OPC_SUBU;
13217 goto do_arith;
13218 case MUL:
13219 mips32_op = OPC_MUL;
13220 do_arith:
d75c135e 13221 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13222 break;
13223 /* Shifts */
13224 case SLLV:
13225 mips32_op = OPC_SLLV;
13226 goto do_shift;
13227 case SRLV:
13228 mips32_op = OPC_SRLV;
13229 goto do_shift;
13230 case SRAV:
13231 mips32_op = OPC_SRAV;
13232 goto do_shift;
13233 case ROTRV:
13234 mips32_op = OPC_ROTRV;
13235 do_shift:
d75c135e 13236 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13237 break;
13238 /* Logical operations */
13239 case AND:
13240 mips32_op = OPC_AND;
13241 goto do_logic;
13242 case OR32:
13243 mips32_op = OPC_OR;
13244 goto do_logic;
13245 case NOR:
13246 mips32_op = OPC_NOR;
13247 goto do_logic;
13248 case XOR32:
13249 mips32_op = OPC_XOR;
13250 do_logic:
d75c135e 13251 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13252 break;
13253 /* Set less than */
13254 case SLT:
13255 mips32_op = OPC_SLT;
13256 goto do_slt;
13257 case SLTU:
13258 mips32_op = OPC_SLTU;
13259 do_slt:
d75c135e 13260 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13261 break;
13262 default:
13263 goto pool32a_invalid;
13264 }
13265 break;
13266 case 0x18:
13267 minor = (ctx->opcode >> 6) & 0xf;
13268 switch (minor) {
13269 /* Conditional moves */
13270 case MOVN:
13271 mips32_op = OPC_MOVN;
13272 goto do_cmov;
13273 case MOVZ:
13274 mips32_op = OPC_MOVZ;
13275 do_cmov:
d75c135e 13276 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13277 break;
13278 case LWXS:
13279 gen_ldxs(ctx, rs, rt, rd);
13280 break;
13281 default:
13282 goto pool32a_invalid;
13283 }
13284 break;
13285 case INS:
13286 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13287 return;
13288 case EXT:
13289 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13290 return;
13291 case POOL32AXF:
240ce26a 13292 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13293 break;
13294 case 0x07:
13295 generate_exception(ctx, EXCP_BREAK);
13296 break;
13297 default:
13298 pool32a_invalid:
13299 MIPS_INVAL("pool32a");
13300 generate_exception(ctx, EXCP_RI);
13301 break;
13302 }
13303 break;
13304 case POOL32B:
13305 minor = (ctx->opcode >> 12) & 0xf;
13306 switch (minor) {
13307 case CACHE:
2e15497c 13308 check_cp0_enabled(ctx);
3c824109
NF
13309 /* Treat as no-op. */
13310 break;
13311 case LWC2:
13312 case SWC2:
13313 /* COP2: Not implemented. */
13314 generate_exception_err(ctx, EXCP_CpU, 2);
13315 break;
3c824109
NF
13316#ifdef TARGET_MIPS64
13317 case LDP:
13318 case SDP:
d9224450
MR
13319 check_insn(ctx, ISA_MIPS3);
13320 check_mips_64(ctx);
13321 /* Fallthrough */
3c824109 13322#endif
d9224450
MR
13323 case LWP:
13324 case SWP:
3c824109
NF
13325 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13326 break;
3c824109
NF
13327#ifdef TARGET_MIPS64
13328 case LDM:
13329 case SDM:
d9224450
MR
13330 check_insn(ctx, ISA_MIPS3);
13331 check_mips_64(ctx);
13332 /* Fallthrough */
3c824109 13333#endif
d9224450
MR
13334 case LWM32:
13335 case SWM32:
3c824109
NF
13336 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13337 break;
13338 default:
13339 MIPS_INVAL("pool32b");
13340 generate_exception(ctx, EXCP_RI);
13341 break;
13342 }
13343 break;
13344 case POOL32F:
5ab5c041 13345 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13346 minor = ctx->opcode & 0x3f;
13347 check_cp1_enabled(ctx);
13348 switch (minor) {
13349 case ALNV_PS:
13350 mips32_op = OPC_ALNV_PS;
13351 goto do_madd;
13352 case MADD_S:
13353 mips32_op = OPC_MADD_S;
13354 goto do_madd;
13355 case MADD_D:
13356 mips32_op = OPC_MADD_D;
13357 goto do_madd;
13358 case MADD_PS:
13359 mips32_op = OPC_MADD_PS;
13360 goto do_madd;
13361 case MSUB_S:
13362 mips32_op = OPC_MSUB_S;
13363 goto do_madd;
13364 case MSUB_D:
13365 mips32_op = OPC_MSUB_D;
13366 goto do_madd;
13367 case MSUB_PS:
13368 mips32_op = OPC_MSUB_PS;
13369 goto do_madd;
13370 case NMADD_S:
13371 mips32_op = OPC_NMADD_S;
13372 goto do_madd;
13373 case NMADD_D:
13374 mips32_op = OPC_NMADD_D;
13375 goto do_madd;
13376 case NMADD_PS:
13377 mips32_op = OPC_NMADD_PS;
13378 goto do_madd;
13379 case NMSUB_S:
13380 mips32_op = OPC_NMSUB_S;
13381 goto do_madd;
13382 case NMSUB_D:
13383 mips32_op = OPC_NMSUB_D;
13384 goto do_madd;
13385 case NMSUB_PS:
13386 mips32_op = OPC_NMSUB_PS;
13387 do_madd:
13388 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13389 break;
13390 case CABS_COND_FMT:
13391 cond = (ctx->opcode >> 6) & 0xf;
13392 cc = (ctx->opcode >> 13) & 0x7;
13393 fmt = (ctx->opcode >> 10) & 0x3;
13394 switch (fmt) {
13395 case 0x0:
13396 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13397 break;
13398 case 0x1:
13399 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13400 break;
13401 case 0x2:
13402 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13403 break;
13404 default:
13405 goto pool32f_invalid;
13406 }
13407 break;
13408 case C_COND_FMT:
13409 cond = (ctx->opcode >> 6) & 0xf;
13410 cc = (ctx->opcode >> 13) & 0x7;
13411 fmt = (ctx->opcode >> 10) & 0x3;
13412 switch (fmt) {
13413 case 0x0:
13414 gen_cmp_s(ctx, cond, rt, rs, cc);
13415 break;
13416 case 0x1:
13417 gen_cmp_d(ctx, cond, rt, rs, cc);
13418 break;
13419 case 0x2:
13420 gen_cmp_ps(ctx, cond, rt, rs, cc);
13421 break;
13422 default:
13423 goto pool32f_invalid;
13424 }
13425 break;
13426 case POOL32FXF:
d75c135e 13427 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13428 break;
13429 case 0x00:
13430 /* PLL foo */
13431 switch ((ctx->opcode >> 6) & 0x7) {
13432 case PLL_PS:
13433 mips32_op = OPC_PLL_PS;
13434 goto do_ps;
13435 case PLU_PS:
13436 mips32_op = OPC_PLU_PS;
13437 goto do_ps;
13438 case PUL_PS:
13439 mips32_op = OPC_PUL_PS;
13440 goto do_ps;
13441 case PUU_PS:
13442 mips32_op = OPC_PUU_PS;
13443 goto do_ps;
13444 case CVT_PS_S:
13445 mips32_op = OPC_CVT_PS_S;
13446 do_ps:
13447 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13448 break;
13449 default:
13450 goto pool32f_invalid;
13451 }
13452 break;
13453 case 0x08:
13454 /* [LS][WDU]XC1 */
13455 switch ((ctx->opcode >> 6) & 0x7) {
13456 case LWXC1:
13457 mips32_op = OPC_LWXC1;
13458 goto do_ldst_cp1;
13459 case SWXC1:
13460 mips32_op = OPC_SWXC1;
13461 goto do_ldst_cp1;
13462 case LDXC1:
13463 mips32_op = OPC_LDXC1;
13464 goto do_ldst_cp1;
13465 case SDXC1:
13466 mips32_op = OPC_SDXC1;
13467 goto do_ldst_cp1;
13468 case LUXC1:
13469 mips32_op = OPC_LUXC1;
13470 goto do_ldst_cp1;
13471 case SUXC1:
13472 mips32_op = OPC_SUXC1;
13473 do_ldst_cp1:
13474 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13475 break;
13476 default:
13477 goto pool32f_invalid;
13478 }
13479 break;
13480 case 0x18:
13481 /* 3D insns */
13482 fmt = (ctx->opcode >> 9) & 0x3;
13483 switch ((ctx->opcode >> 6) & 0x7) {
13484 case RSQRT2_FMT:
13485 switch (fmt) {
13486 case FMT_SDPS_S:
13487 mips32_op = OPC_RSQRT2_S;
13488 goto do_3d;
13489 case FMT_SDPS_D:
13490 mips32_op = OPC_RSQRT2_D;
13491 goto do_3d;
13492 case FMT_SDPS_PS:
13493 mips32_op = OPC_RSQRT2_PS;
13494 goto do_3d;
13495 default:
13496 goto pool32f_invalid;
13497 }
13498 break;
13499 case RECIP2_FMT:
13500 switch (fmt) {
13501 case FMT_SDPS_S:
13502 mips32_op = OPC_RECIP2_S;
13503 goto do_3d;
13504 case FMT_SDPS_D:
13505 mips32_op = OPC_RECIP2_D;
13506 goto do_3d;
13507 case FMT_SDPS_PS:
13508 mips32_op = OPC_RECIP2_PS;
13509 goto do_3d;
13510 default:
13511 goto pool32f_invalid;
13512 }
13513 break;
13514 case ADDR_PS:
13515 mips32_op = OPC_ADDR_PS;
13516 goto do_3d;
13517 case MULR_PS:
13518 mips32_op = OPC_MULR_PS;
13519 do_3d:
13520 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13521 break;
13522 default:
13523 goto pool32f_invalid;
13524 }
13525 break;
13526 case 0x20:
13527 /* MOV[FT].fmt and PREFX */
13528 cc = (ctx->opcode >> 13) & 0x7;
13529 fmt = (ctx->opcode >> 9) & 0x3;
13530 switch ((ctx->opcode >> 6) & 0x7) {
13531 case MOVF_FMT:
13532 switch (fmt) {
13533 case FMT_SDPS_S:
7c979afd 13534 gen_movcf_s(ctx, rs, rt, cc, 0);
3c824109
NF
13535 break;
13536 case FMT_SDPS_D:
13537 gen_movcf_d(ctx, rs, rt, cc, 0);
13538 break;
13539 case FMT_SDPS_PS:
7f6613ce 13540 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13541 break;
13542 default:
13543 goto pool32f_invalid;
13544 }
13545 break;
13546 case MOVT_FMT:
13547 switch (fmt) {
13548 case FMT_SDPS_S:
7c979afd 13549 gen_movcf_s(ctx, rs, rt, cc, 1);
3c824109
NF
13550 break;
13551 case FMT_SDPS_D:
13552 gen_movcf_d(ctx, rs, rt, cc, 1);
13553 break;
13554 case FMT_SDPS_PS:
7f6613ce 13555 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13556 break;
13557 default:
13558 goto pool32f_invalid;
13559 }
13560 break;
13561 case PREFX:
13562 break;
13563 default:
13564 goto pool32f_invalid;
13565 }
13566 break;
13567#define FINSN_3ARG_SDPS(prfx) \
13568 switch ((ctx->opcode >> 8) & 0x3) { \
13569 case FMT_SDPS_S: \
13570 mips32_op = OPC_##prfx##_S; \
13571 goto do_fpop; \
13572 case FMT_SDPS_D: \
13573 mips32_op = OPC_##prfx##_D; \
13574 goto do_fpop; \
13575 case FMT_SDPS_PS: \
13576 mips32_op = OPC_##prfx##_PS; \
13577 goto do_fpop; \
13578 default: \
13579 goto pool32f_invalid; \
13580 }
13581 case 0x30:
13582 /* regular FP ops */
13583 switch ((ctx->opcode >> 6) & 0x3) {
13584 case ADD_FMT:
13585 FINSN_3ARG_SDPS(ADD);
13586 break;
13587 case SUB_FMT:
13588 FINSN_3ARG_SDPS(SUB);
13589 break;
13590 case MUL_FMT:
13591 FINSN_3ARG_SDPS(MUL);
13592 break;
13593 case DIV_FMT:
13594 fmt = (ctx->opcode >> 8) & 0x3;
13595 if (fmt == 1) {
13596 mips32_op = OPC_DIV_D;
13597 } else if (fmt == 0) {
13598 mips32_op = OPC_DIV_S;
13599 } else {
13600 goto pool32f_invalid;
13601 }
13602 goto do_fpop;
13603 default:
13604 goto pool32f_invalid;
13605 }
13606 break;
13607 case 0x38:
13608 /* cmovs */
13609 switch ((ctx->opcode >> 6) & 0x3) {
13610 case MOVN_FMT:
13611 FINSN_3ARG_SDPS(MOVN);
13612 break;
13613 case MOVZ_FMT:
13614 FINSN_3ARG_SDPS(MOVZ);
13615 break;
13616 default:
13617 goto pool32f_invalid;
13618 }
13619 break;
13620 do_fpop:
13621 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13622 break;
13623 default:
13624 pool32f_invalid:
13625 MIPS_INVAL("pool32f");
13626 generate_exception(ctx, EXCP_RI);
13627 break;
13628 }
13629 } else {
13630 generate_exception_err(ctx, EXCP_CpU, 1);
13631 }
13632 break;
13633 case POOL32I:
13634 minor = (ctx->opcode >> 21) & 0x1f;
13635 switch (minor) {
13636 case BLTZ:
b231c103
YK
13637 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13638 break;
3c824109 13639 case BLTZAL:
b231c103
YK
13640 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13641 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13642 break;
3c824109 13643 case BLTZALS:
b231c103
YK
13644 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13645 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13646 break;
3c824109 13647 case BGEZ:
b231c103
YK
13648 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13649 break;
3c824109 13650 case BGEZAL:
b231c103
YK
13651 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13652 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13653 break;
3c824109 13654 case BGEZALS:
b231c103
YK
13655 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13656 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13657 break;
3c824109 13658 case BLEZ:
b231c103
YK
13659 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13660 break;
3c824109 13661 case BGTZ:
b231c103 13662 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13663 break;
13664
13665 /* Traps */
13666 case TLTI:
13667 mips32_op = OPC_TLTI;
13668 goto do_trapi;
13669 case TGEI:
13670 mips32_op = OPC_TGEI;
13671 goto do_trapi;
13672 case TLTIU:
13673 mips32_op = OPC_TLTIU;
13674 goto do_trapi;
13675 case TGEIU:
13676 mips32_op = OPC_TGEIU;
13677 goto do_trapi;
13678 case TNEI:
13679 mips32_op = OPC_TNEI;
13680 goto do_trapi;
13681 case TEQI:
13682 mips32_op = OPC_TEQI;
13683 do_trapi:
13684 gen_trap(ctx, mips32_op, rs, -1, imm);
13685 break;
13686
13687 case BNEZC:
13688 case BEQZC:
13689 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13690 4, rs, 0, imm << 1, 0);
3c824109
NF
13691 /* Compact branches don't have a delay slot, so just let
13692 the normal delay slot handling take us to the branch
13693 target. */
13694 break;
13695 case LUI:
5e88759a 13696 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
13697 break;
13698 case SYNCI:
a83bddd6
DZ
13699 /* Break the TB to be able to sync copied instructions
13700 immediately */
13701 ctx->bstate = BS_STOP;
3c824109
NF
13702 break;
13703 case BC2F:
13704 case BC2T:
13705 /* COP2: Not implemented. */
13706 generate_exception_err(ctx, EXCP_CpU, 2);
13707 break;
13708 case BC1F:
13709 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13710 goto do_cp1branch;
13711 case BC1T:
13712 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13713 goto do_cp1branch;
13714 case BC1ANY4F:
13715 mips32_op = OPC_BC1FANY4;
13716 goto do_cp1mips3d;
13717 case BC1ANY4T:
13718 mips32_op = OPC_BC1TANY4;
13719 do_cp1mips3d:
13720 check_cop1x(ctx);
d75c135e 13721 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13722 /* Fall through */
13723 do_cp1branch:
272f458d
MR
13724 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13725 check_cp1_enabled(ctx);
13726 gen_compute_branch1(ctx, mips32_op,
13727 (ctx->opcode >> 18) & 0x7, imm << 1);
13728 } else {
13729 generate_exception_err(ctx, EXCP_CpU, 1);
13730 }
3c824109
NF
13731 break;
13732 case BPOSGE64:
13733 case BPOSGE32:
13734 /* MIPS DSP: not implemented */
13735 /* Fall through */
13736 default:
13737 MIPS_INVAL("pool32i");
13738 generate_exception(ctx, EXCP_RI);
13739 break;
13740 }
13741 break;
13742 case POOL32C:
13743 minor = (ctx->opcode >> 12) & 0xf;
13744 switch (minor) {
13745 case LWL:
13746 mips32_op = OPC_LWL;
5c13fdfd 13747 goto do_ld_lr;
3c824109
NF
13748 case SWL:
13749 mips32_op = OPC_SWL;
5c13fdfd 13750 goto do_st_lr;
3c824109
NF
13751 case LWR:
13752 mips32_op = OPC_LWR;
5c13fdfd 13753 goto do_ld_lr;
3c824109
NF
13754 case SWR:
13755 mips32_op = OPC_SWR;
5c13fdfd 13756 goto do_st_lr;
3c824109
NF
13757#if defined(TARGET_MIPS64)
13758 case LDL:
d9224450
MR
13759 check_insn(ctx, ISA_MIPS3);
13760 check_mips_64(ctx);
3c824109 13761 mips32_op = OPC_LDL;
5c13fdfd 13762 goto do_ld_lr;
3c824109 13763 case SDL:
d9224450
MR
13764 check_insn(ctx, ISA_MIPS3);
13765 check_mips_64(ctx);
3c824109 13766 mips32_op = OPC_SDL;
5c13fdfd 13767 goto do_st_lr;
3c824109 13768 case LDR:
d9224450
MR
13769 check_insn(ctx, ISA_MIPS3);
13770 check_mips_64(ctx);
3c824109 13771 mips32_op = OPC_LDR;
5c13fdfd 13772 goto do_ld_lr;
3c824109 13773 case SDR:
d9224450
MR
13774 check_insn(ctx, ISA_MIPS3);
13775 check_mips_64(ctx);
3c824109 13776 mips32_op = OPC_SDR;
5c13fdfd 13777 goto do_st_lr;
3c824109 13778 case LWU:
d9224450
MR
13779 check_insn(ctx, ISA_MIPS3);
13780 check_mips_64(ctx);
3c824109 13781 mips32_op = OPC_LWU;
5c13fdfd 13782 goto do_ld_lr;
3c824109 13783 case LLD:
d9224450
MR
13784 check_insn(ctx, ISA_MIPS3);
13785 check_mips_64(ctx);
3c824109 13786 mips32_op = OPC_LLD;
5c13fdfd 13787 goto do_ld_lr;
3c824109
NF
13788#endif
13789 case LL:
13790 mips32_op = OPC_LL;
5c13fdfd
AJ
13791 goto do_ld_lr;
13792 do_ld_lr:
d75c135e 13793 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13794 break;
13795 do_st_lr:
13796 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13797 break;
13798 case SC:
13799 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13800 break;
13801#if defined(TARGET_MIPS64)
13802 case SCD:
d9224450
MR
13803 check_insn(ctx, ISA_MIPS3);
13804 check_mips_64(ctx);
3c824109
NF
13805 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13806 break;
13807#endif
13808 case PREF:
13809 /* Treat as no-op */
13810 break;
13811 default:
13812 MIPS_INVAL("pool32c");
13813 generate_exception(ctx, EXCP_RI);
13814 break;
13815 }
13816 break;
13817 case ADDI32:
13818 mips32_op = OPC_ADDI;
13819 goto do_addi;
13820 case ADDIU32:
13821 mips32_op = OPC_ADDIU;
13822 do_addi:
d75c135e 13823 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13824 break;
13825
13826 /* Logical operations */
13827 case ORI32:
13828 mips32_op = OPC_ORI;
13829 goto do_logici;
13830 case XORI32:
13831 mips32_op = OPC_XORI;
13832 goto do_logici;
13833 case ANDI32:
13834 mips32_op = OPC_ANDI;
13835 do_logici:
d75c135e 13836 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13837 break;
13838
13839 /* Set less than immediate */
13840 case SLTI32:
13841 mips32_op = OPC_SLTI;
13842 goto do_slti;
13843 case SLTIU32:
13844 mips32_op = OPC_SLTIU;
13845 do_slti:
d75c135e 13846 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13847 break;
13848 case JALX32:
13849 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13850 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13851 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13852 break;
13853 case JALS32:
13854 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13855 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13856 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13857 break;
13858 case BEQ32:
b231c103 13859 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13860 break;
13861 case BNE32:
b231c103 13862 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13863 break;
13864 case J32:
13865 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13866 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13867 break;
13868 case JAL32:
13869 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13870 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13871 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13872 break;
13873 /* Floating point (COP1) */
13874 case LWC132:
13875 mips32_op = OPC_LWC1;
13876 goto do_cop1;
13877 case LDC132:
13878 mips32_op = OPC_LDC1;
13879 goto do_cop1;
13880 case SWC132:
13881 mips32_op = OPC_SWC1;
13882 goto do_cop1;
13883 case SDC132:
13884 mips32_op = OPC_SDC1;
13885 do_cop1:
5ab5c041 13886 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13887 break;
13888 case ADDIUPC:
13889 {
13890 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13891 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13892
13893 gen_addiupc(ctx, reg, offset, 0, 0);
13894 }
13895 break;
13896 /* Loads and stores */
13897 case LB32:
13898 mips32_op = OPC_LB;
5c13fdfd 13899 goto do_ld;
3c824109
NF
13900 case LBU32:
13901 mips32_op = OPC_LBU;
5c13fdfd 13902 goto do_ld;
3c824109
NF
13903 case LH32:
13904 mips32_op = OPC_LH;
5c13fdfd 13905 goto do_ld;
3c824109
NF
13906 case LHU32:
13907 mips32_op = OPC_LHU;
5c13fdfd 13908 goto do_ld;
3c824109
NF
13909 case LW32:
13910 mips32_op = OPC_LW;
5c13fdfd 13911 goto do_ld;
3c824109
NF
13912#ifdef TARGET_MIPS64
13913 case LD32:
d9224450
MR
13914 check_insn(ctx, ISA_MIPS3);
13915 check_mips_64(ctx);
3c824109 13916 mips32_op = OPC_LD;
5c13fdfd 13917 goto do_ld;
3c824109 13918 case SD32:
d9224450
MR
13919 check_insn(ctx, ISA_MIPS3);
13920 check_mips_64(ctx);
3c824109 13921 mips32_op = OPC_SD;
5c13fdfd 13922 goto do_st;
3c824109
NF
13923#endif
13924 case SB32:
13925 mips32_op = OPC_SB;
5c13fdfd 13926 goto do_st;
3c824109
NF
13927 case SH32:
13928 mips32_op = OPC_SH;
5c13fdfd 13929 goto do_st;
3c824109
NF
13930 case SW32:
13931 mips32_op = OPC_SW;
5c13fdfd
AJ
13932 goto do_st;
13933 do_ld:
d75c135e 13934 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13935 break;
13936 do_st:
13937 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13938 break;
13939 default:
13940 generate_exception(ctx, EXCP_RI);
13941 break;
13942 }
13943}
13944
240ce26a 13945static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13946{
13947 uint32_t op;
13948
13949 /* make sure instructions are on a halfword boundary */
13950 if (ctx->pc & 0x1) {
13951 env->CP0_BadVAddr = ctx->pc;
13952 generate_exception(ctx, EXCP_AdEL);
13953 ctx->bstate = BS_STOP;
13954 return 2;
13955 }
13956
13957 op = (ctx->opcode >> 10) & 0x3f;
13958 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13959 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13960 switch (op & 0x7) { /* MSB-3..MSB-5 */
13961 case 0:
13962 /* POOL32A, POOL32B, POOL32I, POOL32C */
13963 case 4:
13964 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13965 case 5:
13966 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13967 case 6:
13968 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13969 case 7:
13970 /* LB32, LH32, LWC132, LDC132, LW32 */
13971 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13972 generate_exception(ctx, EXCP_RI);
13973 /* Just stop translation; the user is confused. */
13974 ctx->bstate = BS_STOP;
13975 return 2;
13976 }
13977 break;
b231c103
YK
13978 case 1:
13979 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13980 case 2:
13981 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13982 case 3:
13983 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13984 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13985 generate_exception(ctx, EXCP_RI);
13986 /* Just stop translation; the user is confused. */
13987 ctx->bstate = BS_STOP;
13988 return 2;
13989 }
13990 break;
3c824109
NF
13991 }
13992 }
b231c103 13993
3c824109
NF
13994 switch (op) {
13995 case POOL16A:
13996 {
13997 int rd = mmreg(uMIPS_RD(ctx->opcode));
13998 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13999 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14000 uint32_t opc = 0;
14001
14002 switch (ctx->opcode & 0x1) {
14003 case ADDU16:
14004 opc = OPC_ADDU;
14005 break;
14006 case SUBU16:
14007 opc = OPC_SUBU;
14008 break;
14009 }
14010
d75c135e 14011 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
14012 }
14013 break;
14014 case POOL16B:
14015 {
14016 int rd = mmreg(uMIPS_RD(ctx->opcode));
14017 int rs = mmreg(uMIPS_RS(ctx->opcode));
14018 int amount = (ctx->opcode >> 1) & 0x7;
14019 uint32_t opc = 0;
14020 amount = amount == 0 ? 8 : amount;
14021
14022 switch (ctx->opcode & 0x1) {
14023 case SLL16:
14024 opc = OPC_SLL;
14025 break;
14026 case SRL16:
14027 opc = OPC_SRL;
14028 break;
14029 }
14030
d75c135e 14031 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14032 }
14033 break;
14034 case POOL16C:
240ce26a 14035 gen_pool16c_insn(ctx);
3c824109
NF
14036 break;
14037 case LWGP16:
14038 {
14039 int rd = mmreg(uMIPS_RD(ctx->opcode));
14040 int rb = 28; /* GP */
14041 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14042
d75c135e 14043 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14044 }
14045 break;
14046 case POOL16F:
14047 if (ctx->opcode & 1) {
14048 generate_exception(ctx, EXCP_RI);
14049 } else {
14050 /* MOVEP */
14051 int enc_dest = uMIPS_RD(ctx->opcode);
14052 int enc_rt = uMIPS_RS2(ctx->opcode);
14053 int enc_rs = uMIPS_RS1(ctx->opcode);
14054 int rd, rs, re, rt;
14055 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14056 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14057 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14058
14059 rd = rd_enc[enc_dest];
14060 re = re_enc[enc_dest];
14061 rs = rs_rt_enc[enc_rs];
14062 rt = rs_rt_enc[enc_rt];
14063
7215d7e7
MR
14064 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14065 gen_arith(ctx, OPC_ADDU, re, rt, 0);
3c824109
NF
14066 }
14067 break;
14068 case LBU16:
14069 {
14070 int rd = mmreg(uMIPS_RD(ctx->opcode));
14071 int rb = mmreg(uMIPS_RS(ctx->opcode));
14072 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14073 offset = (offset == 0xf ? -1 : offset);
14074
d75c135e 14075 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14076 }
14077 break;
14078 case LHU16:
14079 {
14080 int rd = mmreg(uMIPS_RD(ctx->opcode));
14081 int rb = mmreg(uMIPS_RS(ctx->opcode));
14082 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14083
d75c135e 14084 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14085 }
14086 break;
14087 case LWSP16:
14088 {
14089 int rd = (ctx->opcode >> 5) & 0x1f;
14090 int rb = 29; /* SP */
14091 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14092
d75c135e 14093 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14094 }
14095 break;
14096 case LW16:
14097 {
14098 int rd = mmreg(uMIPS_RD(ctx->opcode));
14099 int rb = mmreg(uMIPS_RS(ctx->opcode));
14100 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14101
d75c135e 14102 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14103 }
14104 break;
14105 case SB16:
14106 {
14107 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14108 int rb = mmreg(uMIPS_RS(ctx->opcode));
14109 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14110
5c13fdfd 14111 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14112 }
14113 break;
14114 case SH16:
14115 {
14116 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14117 int rb = mmreg(uMIPS_RS(ctx->opcode));
14118 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14119
5c13fdfd 14120 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14121 }
14122 break;
14123 case SWSP16:
14124 {
14125 int rd = (ctx->opcode >> 5) & 0x1f;
14126 int rb = 29; /* SP */
14127 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14128
5c13fdfd 14129 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14130 }
14131 break;
14132 case SW16:
14133 {
14134 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14135 int rb = mmreg(uMIPS_RS(ctx->opcode));
14136 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14137
5c13fdfd 14138 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14139 }
14140 break;
14141 case MOVE16:
14142 {
14143 int rd = uMIPS_RD5(ctx->opcode);
14144 int rs = uMIPS_RS5(ctx->opcode);
14145
7215d7e7 14146 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14147 }
14148 break;
14149 case ANDI16:
d75c135e 14150 gen_andi16(ctx);
3c824109
NF
14151 break;
14152 case POOL16D:
14153 switch (ctx->opcode & 0x1) {
14154 case ADDIUS5:
d75c135e 14155 gen_addius5(ctx);
3c824109
NF
14156 break;
14157 case ADDIUSP:
d75c135e 14158 gen_addiusp(ctx);
3c824109
NF
14159 break;
14160 }
14161 break;
14162 case POOL16E:
14163 switch (ctx->opcode & 0x1) {
14164 case ADDIUR2:
d75c135e 14165 gen_addiur2(ctx);
3c824109
NF
14166 break;
14167 case ADDIUR1SP:
d75c135e 14168 gen_addiur1sp(ctx);
3c824109
NF
14169 break;
14170 }
14171 break;
14172 case B16:
14173 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14174 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14175 break;
14176 case BNEZ16:
14177 case BEQZ16:
14178 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14179 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14180 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14181 break;
14182 case LI16:
14183 {
14184 int reg = mmreg(uMIPS_RD(ctx->opcode));
14185 int imm = ZIMM(ctx->opcode, 0, 7);
14186
14187 imm = (imm == 0x7f ? -1 : imm);
14188 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14189 }
14190 break;
14191 case RES_20:
14192 case RES_28:
14193 case RES_29:
14194 case RES_30:
14195 case RES_31:
14196 case RES_38:
14197 case RES_39:
14198 generate_exception(ctx, EXCP_RI);
14199 break;
14200 default:
240ce26a 14201 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14202 return 4;
14203 }
14204
14205 return 2;
14206}
14207
14208/* SmartMIPS extension to MIPS32 */
14209
14210#if defined(TARGET_MIPS64)
14211
14212/* MDMX extension to MIPS64 */
14213
14214#endif
14215
9b1a1d68 14216/* MIPSDSP functions. */
d75c135e 14217static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14218 int rd, int base, int offset)
14219{
14220 const char *opn = "ldx";
14221 TCGv t0;
14222
9b1a1d68
JL
14223 check_dsp(ctx);
14224 t0 = tcg_temp_new();
14225
14226 if (base == 0) {
14227 gen_load_gpr(t0, offset);
14228 } else if (offset == 0) {
14229 gen_load_gpr(t0, base);
14230 } else {
14231 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14232 }
14233
9b1a1d68
JL
14234 switch (opc) {
14235 case OPC_LBUX:
5f68f5ae 14236 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14237 gen_store_gpr(t0, rd);
14238 opn = "lbux";
14239 break;
14240 case OPC_LHX:
5f68f5ae 14241 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14242 gen_store_gpr(t0, rd);
14243 opn = "lhx";
14244 break;
14245 case OPC_LWX:
5f68f5ae 14246 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14247 gen_store_gpr(t0, rd);
14248 opn = "lwx";
14249 break;
14250#if defined(TARGET_MIPS64)
14251 case OPC_LDX:
5f68f5ae 14252 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14253 gen_store_gpr(t0, rd);
14254 opn = "ldx";
14255 break;
14256#endif
14257 }
14258 (void)opn; /* avoid a compiler warning */
14259 MIPS_DEBUG("%s %s, %s(%s)", opn,
14260 regnames[rd], regnames[offset], regnames[base]);
14261 tcg_temp_free(t0);
14262}
14263
461c08df
JL
14264static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14265 int ret, int v1, int v2)
14266{
14267 const char *opn = "mipsdsp arith";
14268 TCGv v1_t;
14269 TCGv v2_t;
14270
14271 if (ret == 0) {
14272 /* Treat as NOP. */
14273 MIPS_DEBUG("NOP");
14274 return;
14275 }
14276
14277 v1_t = tcg_temp_new();
14278 v2_t = tcg_temp_new();
14279
14280 gen_load_gpr(v1_t, v1);
14281 gen_load_gpr(v2_t, v2);
14282
14283 switch (op1) {
14284 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14285 case OPC_MULT_G_2E:
14286 check_dspr2(ctx);
14287 switch (op2) {
14288 case OPC_ADDUH_QB:
14289 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14290 break;
14291 case OPC_ADDUH_R_QB:
14292 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14293 break;
14294 case OPC_ADDQH_PH:
14295 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14296 break;
14297 case OPC_ADDQH_R_PH:
14298 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14299 break;
14300 case OPC_ADDQH_W:
14301 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14302 break;
14303 case OPC_ADDQH_R_W:
14304 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14305 break;
14306 case OPC_SUBUH_QB:
14307 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14308 break;
14309 case OPC_SUBUH_R_QB:
14310 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14311 break;
14312 case OPC_SUBQH_PH:
14313 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14314 break;
14315 case OPC_SUBQH_R_PH:
14316 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14317 break;
14318 case OPC_SUBQH_W:
14319 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14320 break;
14321 case OPC_SUBQH_R_W:
14322 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14323 break;
14324 }
14325 break;
14326 case OPC_ABSQ_S_PH_DSP:
14327 switch (op2) {
14328 case OPC_ABSQ_S_QB:
14329 check_dspr2(ctx);
14330 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14331 break;
14332 case OPC_ABSQ_S_PH:
14333 check_dsp(ctx);
14334 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14335 break;
14336 case OPC_ABSQ_S_W:
14337 check_dsp(ctx);
14338 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14339 break;
14340 case OPC_PRECEQ_W_PHL:
14341 check_dsp(ctx);
14342 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14343 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14344 break;
14345 case OPC_PRECEQ_W_PHR:
14346 check_dsp(ctx);
14347 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14348 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14349 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14350 break;
14351 case OPC_PRECEQU_PH_QBL:
14352 check_dsp(ctx);
14353 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14354 break;
14355 case OPC_PRECEQU_PH_QBR:
14356 check_dsp(ctx);
14357 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14358 break;
14359 case OPC_PRECEQU_PH_QBLA:
14360 check_dsp(ctx);
14361 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14362 break;
14363 case OPC_PRECEQU_PH_QBRA:
14364 check_dsp(ctx);
14365 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14366 break;
14367 case OPC_PRECEU_PH_QBL:
14368 check_dsp(ctx);
14369 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14370 break;
14371 case OPC_PRECEU_PH_QBR:
14372 check_dsp(ctx);
14373 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14374 break;
14375 case OPC_PRECEU_PH_QBLA:
14376 check_dsp(ctx);
14377 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14378 break;
14379 case OPC_PRECEU_PH_QBRA:
14380 check_dsp(ctx);
14381 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14382 break;
14383 }
14384 break;
14385 case OPC_ADDU_QB_DSP:
14386 switch (op2) {
14387 case OPC_ADDQ_PH:
14388 check_dsp(ctx);
14389 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14390 break;
14391 case OPC_ADDQ_S_PH:
14392 check_dsp(ctx);
14393 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14394 break;
14395 case OPC_ADDQ_S_W:
14396 check_dsp(ctx);
14397 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14398 break;
14399 case OPC_ADDU_QB:
14400 check_dsp(ctx);
14401 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14402 break;
14403 case OPC_ADDU_S_QB:
14404 check_dsp(ctx);
14405 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14406 break;
14407 case OPC_ADDU_PH:
14408 check_dspr2(ctx);
14409 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14410 break;
14411 case OPC_ADDU_S_PH:
14412 check_dspr2(ctx);
14413 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14414 break;
14415 case OPC_SUBQ_PH:
14416 check_dsp(ctx);
14417 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14418 break;
14419 case OPC_SUBQ_S_PH:
14420 check_dsp(ctx);
14421 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14422 break;
14423 case OPC_SUBQ_S_W:
14424 check_dsp(ctx);
14425 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14426 break;
14427 case OPC_SUBU_QB:
14428 check_dsp(ctx);
14429 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14430 break;
14431 case OPC_SUBU_S_QB:
14432 check_dsp(ctx);
14433 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14434 break;
14435 case OPC_SUBU_PH:
14436 check_dspr2(ctx);
14437 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14438 break;
14439 case OPC_SUBU_S_PH:
14440 check_dspr2(ctx);
14441 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14442 break;
14443 case OPC_ADDSC:
14444 check_dsp(ctx);
14445 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14446 break;
14447 case OPC_ADDWC:
14448 check_dsp(ctx);
14449 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14450 break;
14451 case OPC_MODSUB:
14452 check_dsp(ctx);
14453 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14454 break;
14455 case OPC_RADDU_W_QB:
14456 check_dsp(ctx);
14457 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14458 break;
14459 }
14460 break;
14461 case OPC_CMPU_EQ_QB_DSP:
14462 switch (op2) {
14463 case OPC_PRECR_QB_PH:
14464 check_dspr2(ctx);
14465 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14466 break;
14467 case OPC_PRECRQ_QB_PH:
14468 check_dsp(ctx);
14469 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14470 break;
14471 case OPC_PRECR_SRA_PH_W:
14472 check_dspr2(ctx);
14473 {
14474 TCGv_i32 sa_t = tcg_const_i32(v2);
14475 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14476 cpu_gpr[ret]);
14477 tcg_temp_free_i32(sa_t);
14478 break;
14479 }
14480 case OPC_PRECR_SRA_R_PH_W:
14481 check_dspr2(ctx);
14482 {
14483 TCGv_i32 sa_t = tcg_const_i32(v2);
14484 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14485 cpu_gpr[ret]);
14486 tcg_temp_free_i32(sa_t);
14487 break;
14488 }
14489 case OPC_PRECRQ_PH_W:
14490 check_dsp(ctx);
14491 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14492 break;
14493 case OPC_PRECRQ_RS_PH_W:
14494 check_dsp(ctx);
14495 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14496 break;
14497 case OPC_PRECRQU_S_QB_PH:
14498 check_dsp(ctx);
14499 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14500 break;
14501 }
14502 break;
14503#ifdef TARGET_MIPS64
14504 case OPC_ABSQ_S_QH_DSP:
14505 switch (op2) {
14506 case OPC_PRECEQ_L_PWL:
14507 check_dsp(ctx);
14508 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14509 break;
14510 case OPC_PRECEQ_L_PWR:
14511 check_dsp(ctx);
14512 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14513 break;
14514 case OPC_PRECEQ_PW_QHL:
14515 check_dsp(ctx);
14516 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14517 break;
14518 case OPC_PRECEQ_PW_QHR:
14519 check_dsp(ctx);
14520 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14521 break;
14522 case OPC_PRECEQ_PW_QHLA:
14523 check_dsp(ctx);
14524 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14525 break;
14526 case OPC_PRECEQ_PW_QHRA:
14527 check_dsp(ctx);
14528 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14529 break;
14530 case OPC_PRECEQU_QH_OBL:
14531 check_dsp(ctx);
14532 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14533 break;
14534 case OPC_PRECEQU_QH_OBR:
14535 check_dsp(ctx);
14536 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14537 break;
14538 case OPC_PRECEQU_QH_OBLA:
14539 check_dsp(ctx);
14540 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14541 break;
14542 case OPC_PRECEQU_QH_OBRA:
14543 check_dsp(ctx);
14544 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14545 break;
14546 case OPC_PRECEU_QH_OBL:
14547 check_dsp(ctx);
14548 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14549 break;
14550 case OPC_PRECEU_QH_OBR:
14551 check_dsp(ctx);
14552 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14553 break;
14554 case OPC_PRECEU_QH_OBLA:
14555 check_dsp(ctx);
14556 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14557 break;
14558 case OPC_PRECEU_QH_OBRA:
14559 check_dsp(ctx);
14560 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14561 break;
14562 case OPC_ABSQ_S_OB:
14563 check_dspr2(ctx);
14564 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14565 break;
14566 case OPC_ABSQ_S_PW:
14567 check_dsp(ctx);
14568 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14569 break;
14570 case OPC_ABSQ_S_QH:
14571 check_dsp(ctx);
14572 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14573 break;
14574 }
14575 break;
14576 case OPC_ADDU_OB_DSP:
14577 switch (op2) {
14578 case OPC_RADDU_L_OB:
14579 check_dsp(ctx);
14580 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14581 break;
14582 case OPC_SUBQ_PW:
14583 check_dsp(ctx);
14584 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14585 break;
14586 case OPC_SUBQ_S_PW:
14587 check_dsp(ctx);
14588 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14589 break;
14590 case OPC_SUBQ_QH:
14591 check_dsp(ctx);
14592 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14593 break;
14594 case OPC_SUBQ_S_QH:
14595 check_dsp(ctx);
14596 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14597 break;
14598 case OPC_SUBU_OB:
14599 check_dsp(ctx);
14600 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14601 break;
14602 case OPC_SUBU_S_OB:
14603 check_dsp(ctx);
14604 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14605 break;
14606 case OPC_SUBU_QH:
14607 check_dspr2(ctx);
14608 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14609 break;
14610 case OPC_SUBU_S_QH:
14611 check_dspr2(ctx);
14612 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14613 break;
14614 case OPC_SUBUH_OB:
14615 check_dspr2(ctx);
14616 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14617 break;
14618 case OPC_SUBUH_R_OB:
14619 check_dspr2(ctx);
14620 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14621 break;
14622 case OPC_ADDQ_PW:
14623 check_dsp(ctx);
14624 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14625 break;
14626 case OPC_ADDQ_S_PW:
14627 check_dsp(ctx);
14628 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14629 break;
14630 case OPC_ADDQ_QH:
14631 check_dsp(ctx);
14632 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14633 break;
14634 case OPC_ADDQ_S_QH:
14635 check_dsp(ctx);
14636 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14637 break;
14638 case OPC_ADDU_OB:
14639 check_dsp(ctx);
14640 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14641 break;
14642 case OPC_ADDU_S_OB:
14643 check_dsp(ctx);
14644 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14645 break;
14646 case OPC_ADDU_QH:
14647 check_dspr2(ctx);
14648 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14649 break;
14650 case OPC_ADDU_S_QH:
14651 check_dspr2(ctx);
14652 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14653 break;
14654 case OPC_ADDUH_OB:
14655 check_dspr2(ctx);
14656 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14657 break;
14658 case OPC_ADDUH_R_OB:
14659 check_dspr2(ctx);
14660 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14661 break;
14662 }
14663 break;
14664 case OPC_CMPU_EQ_OB_DSP:
14665 switch (op2) {
14666 case OPC_PRECR_OB_QH:
14667 check_dspr2(ctx);
14668 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14669 break;
14670 case OPC_PRECR_SRA_QH_PW:
14671 check_dspr2(ctx);
14672 {
14673 TCGv_i32 ret_t = tcg_const_i32(ret);
14674 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14675 tcg_temp_free_i32(ret_t);
14676 break;
14677 }
14678 case OPC_PRECR_SRA_R_QH_PW:
14679 check_dspr2(ctx);
14680 {
14681 TCGv_i32 sa_v = tcg_const_i32(ret);
14682 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14683 tcg_temp_free_i32(sa_v);
14684 break;
14685 }
14686 case OPC_PRECRQ_OB_QH:
14687 check_dsp(ctx);
14688 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14689 break;
14690 case OPC_PRECRQ_PW_L:
14691 check_dsp(ctx);
14692 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14693 break;
14694 case OPC_PRECRQ_QH_PW:
14695 check_dsp(ctx);
14696 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14697 break;
14698 case OPC_PRECRQ_RS_QH_PW:
14699 check_dsp(ctx);
14700 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14701 break;
14702 case OPC_PRECRQU_S_OB_QH:
14703 check_dsp(ctx);
14704 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14705 break;
14706 }
14707 break;
14708#endif
14709 }
14710
14711 tcg_temp_free(v1_t);
14712 tcg_temp_free(v2_t);
14713
14714 (void)opn; /* avoid a compiler warning */
14715 MIPS_DEBUG("%s", opn);
14716}
9b1a1d68 14717
77c5fa8b
JL
14718static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14719 int ret, int v1, int v2)
14720{
14721 uint32_t op2;
14722 const char *opn = "mipsdsp shift";
14723 TCGv t0;
14724 TCGv v1_t;
14725 TCGv v2_t;
14726
14727 if (ret == 0) {
14728 /* Treat as NOP. */
14729 MIPS_DEBUG("NOP");
14730 return;
14731 }
14732
14733 t0 = tcg_temp_new();
14734 v1_t = tcg_temp_new();
14735 v2_t = tcg_temp_new();
14736
14737 tcg_gen_movi_tl(t0, v1);
14738 gen_load_gpr(v1_t, v1);
14739 gen_load_gpr(v2_t, v2);
14740
14741 switch (opc) {
14742 case OPC_SHLL_QB_DSP:
14743 {
14744 op2 = MASK_SHLL_QB(ctx->opcode);
14745 switch (op2) {
14746 case OPC_SHLL_QB:
14747 check_dsp(ctx);
14748 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14749 break;
14750 case OPC_SHLLV_QB:
14751 check_dsp(ctx);
14752 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14753 break;
14754 case OPC_SHLL_PH:
14755 check_dsp(ctx);
14756 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14757 break;
14758 case OPC_SHLLV_PH:
14759 check_dsp(ctx);
14760 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14761 break;
14762 case OPC_SHLL_S_PH:
14763 check_dsp(ctx);
14764 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14765 break;
14766 case OPC_SHLLV_S_PH:
14767 check_dsp(ctx);
14768 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14769 break;
14770 case OPC_SHLL_S_W:
14771 check_dsp(ctx);
14772 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14773 break;
14774 case OPC_SHLLV_S_W:
14775 check_dsp(ctx);
14776 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14777 break;
14778 case OPC_SHRL_QB:
14779 check_dsp(ctx);
14780 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14781 break;
14782 case OPC_SHRLV_QB:
14783 check_dsp(ctx);
14784 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14785 break;
14786 case OPC_SHRL_PH:
14787 check_dspr2(ctx);
14788 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14789 break;
14790 case OPC_SHRLV_PH:
14791 check_dspr2(ctx);
14792 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14793 break;
14794 case OPC_SHRA_QB:
14795 check_dspr2(ctx);
14796 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14797 break;
14798 case OPC_SHRA_R_QB:
14799 check_dspr2(ctx);
14800 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14801 break;
14802 case OPC_SHRAV_QB:
14803 check_dspr2(ctx);
14804 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14805 break;
14806 case OPC_SHRAV_R_QB:
14807 check_dspr2(ctx);
14808 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14809 break;
14810 case OPC_SHRA_PH:
14811 check_dsp(ctx);
14812 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14813 break;
14814 case OPC_SHRA_R_PH:
14815 check_dsp(ctx);
14816 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14817 break;
14818 case OPC_SHRAV_PH:
14819 check_dsp(ctx);
14820 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14821 break;
14822 case OPC_SHRAV_R_PH:
14823 check_dsp(ctx);
14824 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14825 break;
14826 case OPC_SHRA_R_W:
14827 check_dsp(ctx);
14828 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14829 break;
14830 case OPC_SHRAV_R_W:
14831 check_dsp(ctx);
14832 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14833 break;
14834 default: /* Invalid */
14835 MIPS_INVAL("MASK SHLL.QB");
14836 generate_exception(ctx, EXCP_RI);
14837 break;
14838 }
14839 break;
14840 }
14841#ifdef TARGET_MIPS64
14842 case OPC_SHLL_OB_DSP:
14843 op2 = MASK_SHLL_OB(ctx->opcode);
14844 switch (op2) {
14845 case OPC_SHLL_PW:
14846 check_dsp(ctx);
14847 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14848 break;
14849 case OPC_SHLLV_PW:
14850 check_dsp(ctx);
14851 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14852 break;
14853 case OPC_SHLL_S_PW:
14854 check_dsp(ctx);
14855 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14856 break;
14857 case OPC_SHLLV_S_PW:
14858 check_dsp(ctx);
14859 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14860 break;
14861 case OPC_SHLL_OB:
14862 check_dsp(ctx);
14863 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14864 break;
14865 case OPC_SHLLV_OB:
14866 check_dsp(ctx);
14867 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14868 break;
14869 case OPC_SHLL_QH:
14870 check_dsp(ctx);
14871 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14872 break;
14873 case OPC_SHLLV_QH:
14874 check_dsp(ctx);
14875 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14876 break;
14877 case OPC_SHLL_S_QH:
14878 check_dsp(ctx);
14879 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14880 break;
14881 case OPC_SHLLV_S_QH:
14882 check_dsp(ctx);
14883 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14884 break;
14885 case OPC_SHRA_OB:
14886 check_dspr2(ctx);
14887 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14888 break;
14889 case OPC_SHRAV_OB:
14890 check_dspr2(ctx);
14891 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14892 break;
14893 case OPC_SHRA_R_OB:
14894 check_dspr2(ctx);
14895 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14896 break;
14897 case OPC_SHRAV_R_OB:
14898 check_dspr2(ctx);
14899 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14900 break;
14901 case OPC_SHRA_PW:
14902 check_dsp(ctx);
14903 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14904 break;
14905 case OPC_SHRAV_PW:
14906 check_dsp(ctx);
14907 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14908 break;
14909 case OPC_SHRA_R_PW:
14910 check_dsp(ctx);
14911 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14912 break;
14913 case OPC_SHRAV_R_PW:
14914 check_dsp(ctx);
14915 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14916 break;
14917 case OPC_SHRA_QH:
14918 check_dsp(ctx);
14919 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14920 break;
14921 case OPC_SHRAV_QH:
14922 check_dsp(ctx);
14923 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14924 break;
14925 case OPC_SHRA_R_QH:
14926 check_dsp(ctx);
14927 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14928 break;
14929 case OPC_SHRAV_R_QH:
14930 check_dsp(ctx);
14931 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14932 break;
14933 case OPC_SHRL_OB:
14934 check_dsp(ctx);
14935 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14936 break;
14937 case OPC_SHRLV_OB:
14938 check_dsp(ctx);
14939 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14940 break;
14941 case OPC_SHRL_QH:
14942 check_dspr2(ctx);
14943 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14944 break;
14945 case OPC_SHRLV_QH:
14946 check_dspr2(ctx);
14947 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14948 break;
14949 default: /* Invalid */
14950 MIPS_INVAL("MASK SHLL.OB");
14951 generate_exception(ctx, EXCP_RI);
14952 break;
14953 }
14954 break;
14955#endif
14956 }
14957
14958 tcg_temp_free(t0);
14959 tcg_temp_free(v1_t);
14960 tcg_temp_free(v2_t);
14961 (void)opn; /* avoid a compiler warning */
14962 MIPS_DEBUG("%s", opn);
14963}
14964
a22260ae
JL
14965static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14966 int ret, int v1, int v2, int check_ret)
14967{
14968 const char *opn = "mipsdsp multiply";
14969 TCGv_i32 t0;
14970 TCGv v1_t;
14971 TCGv v2_t;
14972
14973 if ((ret == 0) && (check_ret == 1)) {
14974 /* Treat as NOP. */
14975 MIPS_DEBUG("NOP");
14976 return;
14977 }
14978
14979 t0 = tcg_temp_new_i32();
14980 v1_t = tcg_temp_new();
14981 v2_t = tcg_temp_new();
14982
14983 tcg_gen_movi_i32(t0, ret);
14984 gen_load_gpr(v1_t, v1);
14985 gen_load_gpr(v2_t, v2);
14986
14987 switch (op1) {
14988 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14989 * the same mask and op1. */
14990 case OPC_MULT_G_2E:
639eadb9 14991 check_dspr2(ctx);
a22260ae
JL
14992 switch (op2) {
14993 case OPC_MUL_PH:
14994 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14995 break;
14996 case OPC_MUL_S_PH:
14997 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14998 break;
14999 case OPC_MULQ_S_W:
15000 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15001 break;
15002 case OPC_MULQ_RS_W:
15003 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15004 break;
15005 }
15006 break;
15007 case OPC_DPA_W_PH_DSP:
15008 switch (op2) {
15009 case OPC_DPAU_H_QBL:
15010 check_dsp(ctx);
15011 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15012 break;
15013 case OPC_DPAU_H_QBR:
15014 check_dsp(ctx);
15015 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15016 break;
15017 case OPC_DPSU_H_QBL:
15018 check_dsp(ctx);
15019 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15020 break;
15021 case OPC_DPSU_H_QBR:
15022 check_dsp(ctx);
15023 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15024 break;
15025 case OPC_DPA_W_PH:
15026 check_dspr2(ctx);
15027 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15028 break;
15029 case OPC_DPAX_W_PH:
15030 check_dspr2(ctx);
15031 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15032 break;
15033 case OPC_DPAQ_S_W_PH:
15034 check_dsp(ctx);
15035 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15036 break;
15037 case OPC_DPAQX_S_W_PH:
15038 check_dspr2(ctx);
15039 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15040 break;
15041 case OPC_DPAQX_SA_W_PH:
15042 check_dspr2(ctx);
15043 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15044 break;
15045 case OPC_DPS_W_PH:
15046 check_dspr2(ctx);
15047 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15048 break;
15049 case OPC_DPSX_W_PH:
15050 check_dspr2(ctx);
15051 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15052 break;
15053 case OPC_DPSQ_S_W_PH:
15054 check_dsp(ctx);
15055 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15056 break;
15057 case OPC_DPSQX_S_W_PH:
15058 check_dspr2(ctx);
15059 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15060 break;
15061 case OPC_DPSQX_SA_W_PH:
15062 check_dspr2(ctx);
15063 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15064 break;
15065 case OPC_MULSAQ_S_W_PH:
15066 check_dsp(ctx);
15067 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15068 break;
15069 case OPC_DPAQ_SA_L_W:
15070 check_dsp(ctx);
15071 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15072 break;
15073 case OPC_DPSQ_SA_L_W:
15074 check_dsp(ctx);
15075 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15076 break;
15077 case OPC_MAQ_S_W_PHL:
15078 check_dsp(ctx);
15079 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15080 break;
15081 case OPC_MAQ_S_W_PHR:
15082 check_dsp(ctx);
15083 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15084 break;
15085 case OPC_MAQ_SA_W_PHL:
15086 check_dsp(ctx);
15087 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15088 break;
15089 case OPC_MAQ_SA_W_PHR:
15090 check_dsp(ctx);
15091 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15092 break;
15093 case OPC_MULSA_W_PH:
15094 check_dspr2(ctx);
15095 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15096 break;
15097 }
15098 break;
15099#ifdef TARGET_MIPS64
15100 case OPC_DPAQ_W_QH_DSP:
15101 {
15102 int ac = ret & 0x03;
15103 tcg_gen_movi_i32(t0, ac);
15104
15105 switch (op2) {
15106 case OPC_DMADD:
15107 check_dsp(ctx);
15108 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15109 break;
15110 case OPC_DMADDU:
15111 check_dsp(ctx);
15112 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15113 break;
15114 case OPC_DMSUB:
15115 check_dsp(ctx);
15116 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15117 break;
15118 case OPC_DMSUBU:
15119 check_dsp(ctx);
15120 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15121 break;
15122 case OPC_DPA_W_QH:
15123 check_dspr2(ctx);
15124 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15125 break;
15126 case OPC_DPAQ_S_W_QH:
15127 check_dsp(ctx);
15128 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15129 break;
15130 case OPC_DPAQ_SA_L_PW:
15131 check_dsp(ctx);
15132 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15133 break;
15134 case OPC_DPAU_H_OBL:
15135 check_dsp(ctx);
15136 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15137 break;
15138 case OPC_DPAU_H_OBR:
15139 check_dsp(ctx);
15140 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15141 break;
15142 case OPC_DPS_W_QH:
15143 check_dspr2(ctx);
15144 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15145 break;
15146 case OPC_DPSQ_S_W_QH:
15147 check_dsp(ctx);
15148 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15149 break;
15150 case OPC_DPSQ_SA_L_PW:
15151 check_dsp(ctx);
15152 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15153 break;
15154 case OPC_DPSU_H_OBL:
15155 check_dsp(ctx);
15156 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15157 break;
15158 case OPC_DPSU_H_OBR:
15159 check_dsp(ctx);
15160 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15161 break;
15162 case OPC_MAQ_S_L_PWL:
15163 check_dsp(ctx);
15164 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15165 break;
15166 case OPC_MAQ_S_L_PWR:
15167 check_dsp(ctx);
15168 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15169 break;
15170 case OPC_MAQ_S_W_QHLL:
15171 check_dsp(ctx);
15172 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15173 break;
15174 case OPC_MAQ_SA_W_QHLL:
15175 check_dsp(ctx);
15176 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15177 break;
15178 case OPC_MAQ_S_W_QHLR:
15179 check_dsp(ctx);
15180 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15181 break;
15182 case OPC_MAQ_SA_W_QHLR:
15183 check_dsp(ctx);
15184 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15185 break;
15186 case OPC_MAQ_S_W_QHRL:
15187 check_dsp(ctx);
15188 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15189 break;
15190 case OPC_MAQ_SA_W_QHRL:
15191 check_dsp(ctx);
15192 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15193 break;
15194 case OPC_MAQ_S_W_QHRR:
15195 check_dsp(ctx);
15196 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15197 break;
15198 case OPC_MAQ_SA_W_QHRR:
15199 check_dsp(ctx);
15200 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15201 break;
15202 case OPC_MULSAQ_S_L_PW:
15203 check_dsp(ctx);
15204 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15205 break;
15206 case OPC_MULSAQ_S_W_QH:
15207 check_dsp(ctx);
15208 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15209 break;
15210 }
15211 }
15212 break;
15213#endif
15214 case OPC_ADDU_QB_DSP:
15215 switch (op2) {
15216 case OPC_MULEU_S_PH_QBL:
15217 check_dsp(ctx);
15218 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15219 break;
15220 case OPC_MULEU_S_PH_QBR:
15221 check_dsp(ctx);
15222 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15223 break;
15224 case OPC_MULQ_RS_PH:
15225 check_dsp(ctx);
15226 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15227 break;
15228 case OPC_MULEQ_S_W_PHL:
15229 check_dsp(ctx);
15230 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15231 break;
15232 case OPC_MULEQ_S_W_PHR:
15233 check_dsp(ctx);
15234 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15235 break;
15236 case OPC_MULQ_S_PH:
15237 check_dspr2(ctx);
15238 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15239 break;
15240 }
15241 break;
15242#ifdef TARGET_MIPS64
15243 case OPC_ADDU_OB_DSP:
15244 switch (op2) {
15245 case OPC_MULEQ_S_PW_QHL:
15246 check_dsp(ctx);
15247 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15248 break;
15249 case OPC_MULEQ_S_PW_QHR:
15250 check_dsp(ctx);
15251 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15252 break;
15253 case OPC_MULEU_S_QH_OBL:
15254 check_dsp(ctx);
15255 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15256 break;
15257 case OPC_MULEU_S_QH_OBR:
15258 check_dsp(ctx);
15259 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15260 break;
15261 case OPC_MULQ_RS_QH:
15262 check_dsp(ctx);
15263 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15264 break;
15265 }
15266 break;
15267#endif
15268 }
15269
15270 tcg_temp_free_i32(t0);
15271 tcg_temp_free(v1_t);
15272 tcg_temp_free(v2_t);
15273
15274 (void)opn; /* avoid a compiler warning */
15275 MIPS_DEBUG("%s", opn);
15276
15277}
15278
d75c135e 15279static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15280 int ret, int val)
15281{
15282 const char *opn = "mipsdsp Bit/ Manipulation";
15283 int16_t imm;
15284 TCGv t0;
15285 TCGv val_t;
15286
15287 if (ret == 0) {
15288 /* Treat as NOP. */
15289 MIPS_DEBUG("NOP");
15290 return;
15291 }
15292
15293 t0 = tcg_temp_new();
15294 val_t = tcg_temp_new();
15295 gen_load_gpr(val_t, val);
15296
15297 switch (op1) {
15298 case OPC_ABSQ_S_PH_DSP:
15299 switch (op2) {
15300 case OPC_BITREV:
15301 check_dsp(ctx);
15302 gen_helper_bitrev(cpu_gpr[ret], val_t);
15303 break;
15304 case OPC_REPL_QB:
15305 check_dsp(ctx);
15306 {
15307 target_long result;
15308 imm = (ctx->opcode >> 16) & 0xFF;
15309 result = (uint32_t)imm << 24 |
15310 (uint32_t)imm << 16 |
15311 (uint32_t)imm << 8 |
15312 (uint32_t)imm;
15313 result = (int32_t)result;
15314 tcg_gen_movi_tl(cpu_gpr[ret], result);
15315 }
15316 break;
15317 case OPC_REPLV_QB:
15318 check_dsp(ctx);
15319 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15320 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15321 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15322 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15323 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15324 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15325 break;
15326 case OPC_REPL_PH:
15327 check_dsp(ctx);
15328 {
15329 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15330 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15331 tcg_gen_movi_tl(cpu_gpr[ret], \
15332 (target_long)((int32_t)imm << 16 | \
c4aaba92 15333 (uint16_t)imm));
1cb6686c
JL
15334 }
15335 break;
15336 case OPC_REPLV_PH:
15337 check_dsp(ctx);
15338 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15339 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15340 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15341 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15342 break;
15343 }
15344 break;
15345#ifdef TARGET_MIPS64
15346 case OPC_ABSQ_S_QH_DSP:
15347 switch (op2) {
15348 case OPC_REPL_OB:
15349 check_dsp(ctx);
15350 {
15351 target_long temp;
15352
15353 imm = (ctx->opcode >> 16) & 0xFF;
15354 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15355 temp = (temp << 16) | temp;
15356 temp = (temp << 32) | temp;
15357 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15358 break;
15359 }
15360 case OPC_REPL_PW:
15361 check_dsp(ctx);
15362 {
15363 target_long temp;
15364
15365 imm = (ctx->opcode >> 16) & 0x03FF;
15366 imm = (int16_t)(imm << 6) >> 6;
15367 temp = ((target_long)imm << 32) \
15368 | ((target_long)imm & 0xFFFFFFFF);
15369 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15370 break;
15371 }
15372 case OPC_REPL_QH:
15373 check_dsp(ctx);
15374 {
15375 target_long temp;
15376
15377 imm = (ctx->opcode >> 16) & 0x03FF;
15378 imm = (int16_t)(imm << 6) >> 6;
15379
15380 temp = ((uint64_t)(uint16_t)imm << 48) |
15381 ((uint64_t)(uint16_t)imm << 32) |
15382 ((uint64_t)(uint16_t)imm << 16) |
15383 (uint64_t)(uint16_t)imm;
15384 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15385 break;
15386 }
15387 case OPC_REPLV_OB:
15388 check_dsp(ctx);
15389 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15390 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15391 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15392 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15393 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15394 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15395 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15396 break;
15397 case OPC_REPLV_PW:
15398 check_dsp(ctx);
15399 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15400 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15401 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15402 break;
15403 case OPC_REPLV_QH:
15404 check_dsp(ctx);
15405 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15406 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15407 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15408 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15409 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15410 break;
15411 }
15412 break;
15413#endif
15414 }
15415 tcg_temp_free(t0);
15416 tcg_temp_free(val_t);
15417
15418 (void)opn; /* avoid a compiler warning */
15419 MIPS_DEBUG("%s", opn);
15420}
15421
26690560
JL
15422static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15423 uint32_t op1, uint32_t op2,
15424 int ret, int v1, int v2, int check_ret)
15425{
15426 const char *opn = "mipsdsp add compare pick";
26690560
JL
15427 TCGv t1;
15428 TCGv v1_t;
15429 TCGv v2_t;
15430
15431 if ((ret == 0) && (check_ret == 1)) {
15432 /* Treat as NOP. */
15433 MIPS_DEBUG("NOP");
15434 return;
15435 }
15436
26690560
JL
15437 t1 = tcg_temp_new();
15438 v1_t = tcg_temp_new();
15439 v2_t = tcg_temp_new();
15440
15441 gen_load_gpr(v1_t, v1);
15442 gen_load_gpr(v2_t, v2);
15443
15444 switch (op1) {
26690560
JL
15445 case OPC_CMPU_EQ_QB_DSP:
15446 switch (op2) {
15447 case OPC_CMPU_EQ_QB:
15448 check_dsp(ctx);
15449 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15450 break;
15451 case OPC_CMPU_LT_QB:
15452 check_dsp(ctx);
15453 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15454 break;
15455 case OPC_CMPU_LE_QB:
15456 check_dsp(ctx);
15457 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15458 break;
15459 case OPC_CMPGU_EQ_QB:
15460 check_dsp(ctx);
15461 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15462 break;
15463 case OPC_CMPGU_LT_QB:
15464 check_dsp(ctx);
15465 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15466 break;
15467 case OPC_CMPGU_LE_QB:
15468 check_dsp(ctx);
15469 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15470 break;
15471 case OPC_CMPGDU_EQ_QB:
15472 check_dspr2(ctx);
15473 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15474 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15475 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15476 tcg_gen_shli_tl(t1, t1, 24);
15477 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15478 break;
15479 case OPC_CMPGDU_LT_QB:
15480 check_dspr2(ctx);
15481 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15482 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15483 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15484 tcg_gen_shli_tl(t1, t1, 24);
15485 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15486 break;
15487 case OPC_CMPGDU_LE_QB:
15488 check_dspr2(ctx);
15489 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15490 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15491 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15492 tcg_gen_shli_tl(t1, t1, 24);
15493 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15494 break;
15495 case OPC_CMP_EQ_PH:
15496 check_dsp(ctx);
15497 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15498 break;
15499 case OPC_CMP_LT_PH:
15500 check_dsp(ctx);
15501 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15502 break;
15503 case OPC_CMP_LE_PH:
15504 check_dsp(ctx);
15505 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15506 break;
15507 case OPC_PICK_QB:
15508 check_dsp(ctx);
15509 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15510 break;
15511 case OPC_PICK_PH:
15512 check_dsp(ctx);
15513 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15514 break;
15515 case OPC_PACKRL_PH:
15516 check_dsp(ctx);
15517 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15518 break;
15519 }
15520 break;
15521#ifdef TARGET_MIPS64
15522 case OPC_CMPU_EQ_OB_DSP:
15523 switch (op2) {
15524 case OPC_CMP_EQ_PW:
15525 check_dsp(ctx);
15526 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15527 break;
15528 case OPC_CMP_LT_PW:
15529 check_dsp(ctx);
15530 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15531 break;
15532 case OPC_CMP_LE_PW:
15533 check_dsp(ctx);
15534 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15535 break;
15536 case OPC_CMP_EQ_QH:
15537 check_dsp(ctx);
15538 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15539 break;
15540 case OPC_CMP_LT_QH:
15541 check_dsp(ctx);
15542 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15543 break;
15544 case OPC_CMP_LE_QH:
15545 check_dsp(ctx);
15546 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15547 break;
15548 case OPC_CMPGDU_EQ_OB:
15549 check_dspr2(ctx);
15550 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15551 break;
15552 case OPC_CMPGDU_LT_OB:
15553 check_dspr2(ctx);
15554 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15555 break;
15556 case OPC_CMPGDU_LE_OB:
15557 check_dspr2(ctx);
15558 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15559 break;
15560 case OPC_CMPGU_EQ_OB:
15561 check_dsp(ctx);
15562 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15563 break;
15564 case OPC_CMPGU_LT_OB:
15565 check_dsp(ctx);
15566 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15567 break;
15568 case OPC_CMPGU_LE_OB:
15569 check_dsp(ctx);
15570 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15571 break;
15572 case OPC_CMPU_EQ_OB:
15573 check_dsp(ctx);
15574 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15575 break;
15576 case OPC_CMPU_LT_OB:
15577 check_dsp(ctx);
15578 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15579 break;
15580 case OPC_CMPU_LE_OB:
15581 check_dsp(ctx);
15582 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15583 break;
15584 case OPC_PACKRL_PW:
15585 check_dsp(ctx);
15586 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15587 break;
15588 case OPC_PICK_OB:
15589 check_dsp(ctx);
15590 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15591 break;
15592 case OPC_PICK_PW:
15593 check_dsp(ctx);
15594 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15595 break;
15596 case OPC_PICK_QH:
15597 check_dsp(ctx);
15598 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15599 break;
15600 }
15601 break;
df6126a7
AJ
15602#endif
15603 }
15604
15605 tcg_temp_free(t1);
15606 tcg_temp_free(v1_t);
15607 tcg_temp_free(v2_t);
15608
15609 (void)opn; /* avoid a compiler warning */
15610 MIPS_DEBUG("%s", opn);
15611}
15612
15613static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15614 uint32_t op1, int rt, int rs, int sa)
15615{
15616 const char *opn = "mipsdsp append/dappend";
15617 TCGv t0;
15618
15619 check_dspr2(ctx);
15620
15621 if (rt == 0) {
15622 /* Treat as NOP. */
15623 MIPS_DEBUG("NOP");
15624 return;
15625 }
15626
15627 t0 = tcg_temp_new();
15628 gen_load_gpr(t0, rs);
15629
15630 switch (op1) {
15631 case OPC_APPEND_DSP:
15632 switch (MASK_APPEND(ctx->opcode)) {
15633 case OPC_APPEND:
15634 if (sa != 0) {
15635 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15636 }
15637 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15638 break;
15639 case OPC_PREPEND:
15640 if (sa != 0) {
15641 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15642 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15643 tcg_gen_shli_tl(t0, t0, 32 - sa);
15644 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15645 }
15646 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15647 break;
15648 case OPC_BALIGN:
15649 sa &= 3;
15650 if (sa != 0 && sa != 2) {
15651 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15652 tcg_gen_ext32u_tl(t0, t0);
15653 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15654 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15655 }
15656 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15657 break;
15658 default: /* Invalid */
15659 MIPS_INVAL("MASK APPEND");
15660 generate_exception(ctx, EXCP_RI);
15661 break;
15662 }
15663 break;
15664#ifdef TARGET_MIPS64
26690560 15665 case OPC_DAPPEND_DSP:
df6126a7 15666 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15667 case OPC_DAPPEND:
df6126a7
AJ
15668 if (sa != 0) {
15669 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15670 }
26690560
JL
15671 break;
15672 case OPC_PREPENDD:
df6126a7
AJ
15673 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15674 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15675 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15676 break;
15677 case OPC_PREPENDW:
df6126a7
AJ
15678 if (sa != 0) {
15679 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15680 tcg_gen_shli_tl(t0, t0, 64 - sa);
15681 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15682 }
26690560
JL
15683 break;
15684 case OPC_DBALIGN:
df6126a7
AJ
15685 sa &= 7;
15686 if (sa != 0 && sa != 2 && sa != 4) {
15687 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15688 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15689 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15690 }
26690560
JL
15691 break;
15692 default: /* Invalid */
15693 MIPS_INVAL("MASK DAPPEND");
15694 generate_exception(ctx, EXCP_RI);
15695 break;
15696 }
15697 break;
15698#endif
15699 }
df6126a7 15700 tcg_temp_free(t0);
26690560
JL
15701 (void)opn; /* avoid a compiler warning */
15702 MIPS_DEBUG("%s", opn);
15703}
15704
b53371ed
JL
15705static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15706 int ret, int v1, int v2, int check_ret)
15707
15708{
15709 const char *opn = "mipsdsp accumulator";
15710 TCGv t0;
15711 TCGv t1;
15712 TCGv v1_t;
15713 TCGv v2_t;
15714 int16_t imm;
15715
15716 if ((ret == 0) && (check_ret == 1)) {
15717 /* Treat as NOP. */
15718 MIPS_DEBUG("NOP");
15719 return;
15720 }
15721
15722 t0 = tcg_temp_new();
15723 t1 = tcg_temp_new();
15724 v1_t = tcg_temp_new();
15725 v2_t = tcg_temp_new();
15726
15727 gen_load_gpr(v1_t, v1);
15728 gen_load_gpr(v2_t, v2);
15729
15730 switch (op1) {
15731 case OPC_EXTR_W_DSP:
15732 check_dsp(ctx);
15733 switch (op2) {
15734 case OPC_EXTR_W:
15735 tcg_gen_movi_tl(t0, v2);
15736 tcg_gen_movi_tl(t1, v1);
15737 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15738 break;
15739 case OPC_EXTR_R_W:
15740 tcg_gen_movi_tl(t0, v2);
15741 tcg_gen_movi_tl(t1, v1);
15742 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15743 break;
15744 case OPC_EXTR_RS_W:
15745 tcg_gen_movi_tl(t0, v2);
15746 tcg_gen_movi_tl(t1, v1);
15747 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15748 break;
15749 case OPC_EXTR_S_H:
15750 tcg_gen_movi_tl(t0, v2);
15751 tcg_gen_movi_tl(t1, v1);
15752 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15753 break;
15754 case OPC_EXTRV_S_H:
15755 tcg_gen_movi_tl(t0, v2);
15756 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15757 break;
15758 case OPC_EXTRV_W:
15759 tcg_gen_movi_tl(t0, v2);
15760 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15761 break;
15762 case OPC_EXTRV_R_W:
15763 tcg_gen_movi_tl(t0, v2);
15764 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15765 break;
15766 case OPC_EXTRV_RS_W:
15767 tcg_gen_movi_tl(t0, v2);
15768 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15769 break;
15770 case OPC_EXTP:
15771 tcg_gen_movi_tl(t0, v2);
15772 tcg_gen_movi_tl(t1, v1);
15773 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15774 break;
15775 case OPC_EXTPV:
15776 tcg_gen_movi_tl(t0, v2);
15777 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15778 break;
15779 case OPC_EXTPDP:
15780 tcg_gen_movi_tl(t0, v2);
15781 tcg_gen_movi_tl(t1, v1);
15782 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15783 break;
15784 case OPC_EXTPDPV:
15785 tcg_gen_movi_tl(t0, v2);
15786 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15787 break;
15788 case OPC_SHILO:
15789 imm = (ctx->opcode >> 20) & 0x3F;
15790 tcg_gen_movi_tl(t0, ret);
15791 tcg_gen_movi_tl(t1, imm);
15792 gen_helper_shilo(t0, t1, cpu_env);
15793 break;
15794 case OPC_SHILOV:
15795 tcg_gen_movi_tl(t0, ret);
15796 gen_helper_shilo(t0, v1_t, cpu_env);
15797 break;
15798 case OPC_MTHLIP:
15799 tcg_gen_movi_tl(t0, ret);
15800 gen_helper_mthlip(t0, v1_t, cpu_env);
15801 break;
15802 case OPC_WRDSP:
15803 imm = (ctx->opcode >> 11) & 0x3FF;
15804 tcg_gen_movi_tl(t0, imm);
15805 gen_helper_wrdsp(v1_t, t0, cpu_env);
15806 break;
15807 case OPC_RDDSP:
15808 imm = (ctx->opcode >> 16) & 0x03FF;
15809 tcg_gen_movi_tl(t0, imm);
15810 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15811 break;
15812 }
15813 break;
15814#ifdef TARGET_MIPS64
15815 case OPC_DEXTR_W_DSP:
15816 check_dsp(ctx);
15817 switch (op2) {
15818 case OPC_DMTHLIP:
15819 tcg_gen_movi_tl(t0, ret);
15820 gen_helper_dmthlip(v1_t, t0, cpu_env);
15821 break;
15822 case OPC_DSHILO:
15823 {
15824 int shift = (ctx->opcode >> 19) & 0x7F;
15825 int ac = (ctx->opcode >> 11) & 0x03;
15826 tcg_gen_movi_tl(t0, shift);
15827 tcg_gen_movi_tl(t1, ac);
15828 gen_helper_dshilo(t0, t1, cpu_env);
15829 break;
15830 }
15831 case OPC_DSHILOV:
15832 {
15833 int ac = (ctx->opcode >> 11) & 0x03;
15834 tcg_gen_movi_tl(t0, ac);
15835 gen_helper_dshilo(v1_t, t0, cpu_env);
15836 break;
15837 }
15838 case OPC_DEXTP:
15839 tcg_gen_movi_tl(t0, v2);
15840 tcg_gen_movi_tl(t1, v1);
15841
15842 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15843 break;
15844 case OPC_DEXTPV:
15845 tcg_gen_movi_tl(t0, v2);
15846 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15847 break;
15848 case OPC_DEXTPDP:
15849 tcg_gen_movi_tl(t0, v2);
15850 tcg_gen_movi_tl(t1, v1);
15851 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15852 break;
15853 case OPC_DEXTPDPV:
15854 tcg_gen_movi_tl(t0, v2);
15855 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15856 break;
15857 case OPC_DEXTR_L:
15858 tcg_gen_movi_tl(t0, v2);
15859 tcg_gen_movi_tl(t1, v1);
15860 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15861 break;
15862 case OPC_DEXTR_R_L:
15863 tcg_gen_movi_tl(t0, v2);
15864 tcg_gen_movi_tl(t1, v1);
15865 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15866 break;
15867 case OPC_DEXTR_RS_L:
15868 tcg_gen_movi_tl(t0, v2);
15869 tcg_gen_movi_tl(t1, v1);
15870 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15871 break;
15872 case OPC_DEXTR_W:
15873 tcg_gen_movi_tl(t0, v2);
15874 tcg_gen_movi_tl(t1, v1);
15875 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15876 break;
15877 case OPC_DEXTR_R_W:
15878 tcg_gen_movi_tl(t0, v2);
15879 tcg_gen_movi_tl(t1, v1);
15880 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15881 break;
15882 case OPC_DEXTR_RS_W:
15883 tcg_gen_movi_tl(t0, v2);
15884 tcg_gen_movi_tl(t1, v1);
15885 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15886 break;
15887 case OPC_DEXTR_S_H:
15888 tcg_gen_movi_tl(t0, v2);
15889 tcg_gen_movi_tl(t1, v1);
15890 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15891 break;
15892 case OPC_DEXTRV_S_H:
15893 tcg_gen_movi_tl(t0, v2);
15894 tcg_gen_movi_tl(t1, v1);
15895 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15896 break;
15897 case OPC_DEXTRV_L:
15898 tcg_gen_movi_tl(t0, v2);
15899 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15900 break;
15901 case OPC_DEXTRV_R_L:
15902 tcg_gen_movi_tl(t0, v2);
15903 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15904 break;
15905 case OPC_DEXTRV_RS_L:
15906 tcg_gen_movi_tl(t0, v2);
15907 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15908 break;
15909 case OPC_DEXTRV_W:
15910 tcg_gen_movi_tl(t0, v2);
15911 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15912 break;
15913 case OPC_DEXTRV_R_W:
15914 tcg_gen_movi_tl(t0, v2);
15915 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15916 break;
15917 case OPC_DEXTRV_RS_W:
15918 tcg_gen_movi_tl(t0, v2);
15919 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15920 break;
15921 }
15922 break;
15923#endif
15924 }
15925
15926 tcg_temp_free(t0);
15927 tcg_temp_free(t1);
15928 tcg_temp_free(v1_t);
15929 tcg_temp_free(v2_t);
15930
15931 (void)opn; /* avoid a compiler warning */
15932 MIPS_DEBUG("%s", opn);
15933}
15934
9b1a1d68
JL
15935/* End MIPSDSP functions. */
15936
31837be3
YK
15937/* Compact Branches */
15938static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15939 int rs, int rt, int32_t offset)
15940{
15941 int bcond_compute = 0;
15942 TCGv t0 = tcg_temp_new();
15943 TCGv t1 = tcg_temp_new();
15944
15945 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15946#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15947 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15948 "\n", ctx->pc);
31837be3
YK
15949#endif
15950 generate_exception(ctx, EXCP_RI);
15951 goto out;
15952 }
15953
15954 /* Load needed operands and calculate btarget */
15955 switch (opc) {
15956 /* compact branch */
15957 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15958 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15959 gen_load_gpr(t0, rs);
15960 gen_load_gpr(t1, rt);
15961 bcond_compute = 1;
15962 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15963 if (rs <= rt && rs == 0) {
15964 /* OPC_BEQZALC, OPC_BNEZALC */
15965 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15966 }
15967 break;
15968 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15969 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15970 gen_load_gpr(t0, rs);
15971 gen_load_gpr(t1, rt);
15972 bcond_compute = 1;
15973 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15974 break;
15975 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15976 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15977 if (rs == 0 || rs == rt) {
15978 /* OPC_BLEZALC, OPC_BGEZALC */
15979 /* OPC_BGTZALC, OPC_BLTZALC */
15980 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15981 }
15982 gen_load_gpr(t0, rs);
15983 gen_load_gpr(t1, rt);
15984 bcond_compute = 1;
15985 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15986 break;
15987 case OPC_BC:
15988 case OPC_BALC:
15989 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15990 break;
15991 case OPC_BEQZC:
15992 case OPC_BNEZC:
15993 if (rs != 0) {
15994 /* OPC_BEQZC, OPC_BNEZC */
15995 gen_load_gpr(t0, rs);
15996 bcond_compute = 1;
15997 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15998 } else {
15999 /* OPC_JIC, OPC_JIALC */
16000 TCGv tbase = tcg_temp_new();
16001 TCGv toffset = tcg_temp_new();
16002
16003 gen_load_gpr(tbase, rt);
16004 tcg_gen_movi_tl(toffset, offset);
16005 gen_op_addr_add(ctx, btarget, tbase, toffset);
16006 tcg_temp_free(tbase);
16007 tcg_temp_free(toffset);
16008 }
16009 break;
16010 default:
16011 MIPS_INVAL("Compact branch/jump");
16012 generate_exception(ctx, EXCP_RI);
16013 goto out;
16014 }
16015
16016 if (bcond_compute == 0) {
16017 /* Uncoditional compact branch */
16018 switch (opc) {
16019 case OPC_JIALC:
16020 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16021 /* Fallthrough */
16022 case OPC_JIC:
16023 ctx->hflags |= MIPS_HFLAG_BR;
16024 break;
16025 case OPC_BALC:
16026 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
16027 /* Fallthrough */
16028 case OPC_BC:
16029 ctx->hflags |= MIPS_HFLAG_B;
16030 break;
16031 default:
16032 MIPS_INVAL("Compact branch/jump");
16033 generate_exception(ctx, EXCP_RI);
16034 goto out;
16035 }
16036
16037 /* Generating branch here as compact branches don't have delay slot */
16038 gen_branch(ctx, 4);
16039 } else {
16040 /* Conditional compact branch */
42a268c2 16041 TCGLabel *fs = gen_new_label();
31837be3
YK
16042 save_cpu_state(ctx, 0);
16043
16044 switch (opc) {
16045 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
16046 if (rs == 0 && rt != 0) {
16047 /* OPC_BLEZALC */
339cd2a8 16048 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16049 } else if (rs != 0 && rt != 0 && rs == rt) {
16050 /* OPC_BGEZALC */
339cd2a8 16051 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16052 } else {
16053 /* OPC_BGEUC */
339cd2a8 16054 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
16055 }
16056 break;
16057 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16058 if (rs == 0 && rt != 0) {
16059 /* OPC_BGTZALC */
339cd2a8 16060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16061 } else if (rs != 0 && rt != 0 && rs == rt) {
16062 /* OPC_BLTZALC */
339cd2a8 16063 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16064 } else {
16065 /* OPC_BLTUC */
339cd2a8 16066 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
16067 }
16068 break;
16069 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16070 if (rs == 0 && rt != 0) {
16071 /* OPC_BLEZC */
339cd2a8 16072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16073 } else if (rs != 0 && rt != 0 && rs == rt) {
16074 /* OPC_BGEZC */
339cd2a8 16075 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16076 } else {
16077 /* OPC_BGEC */
339cd2a8 16078 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
16079 }
16080 break;
16081 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16082 if (rs == 0 && rt != 0) {
16083 /* OPC_BGTZC */
339cd2a8 16084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16085 } else if (rs != 0 && rt != 0 && rs == rt) {
16086 /* OPC_BLTZC */
339cd2a8 16087 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16088 } else {
16089 /* OPC_BLTC */
339cd2a8 16090 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
16091 }
16092 break;
16093 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16094 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16095 if (rs >= rt) {
16096 /* OPC_BOVC, OPC_BNVC */
16097 TCGv t2 = tcg_temp_new();
16098 TCGv t3 = tcg_temp_new();
16099 TCGv t4 = tcg_temp_new();
16100 TCGv input_overflow = tcg_temp_new();
16101
16102 gen_load_gpr(t0, rs);
16103 gen_load_gpr(t1, rt);
16104 tcg_gen_ext32s_tl(t2, t0);
16105 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
16106 tcg_gen_ext32s_tl(t3, t1);
16107 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
16108 tcg_gen_or_tl(input_overflow, input_overflow, t4);
16109
16110 tcg_gen_add_tl(t4, t2, t3);
16111 tcg_gen_ext32s_tl(t4, t4);
16112 tcg_gen_xor_tl(t2, t2, t3);
16113 tcg_gen_xor_tl(t3, t4, t3);
16114 tcg_gen_andc_tl(t2, t3, t2);
16115 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
16116 tcg_gen_or_tl(t4, t4, input_overflow);
16117 if (opc == OPC_BOVC) {
16118 /* OPC_BOVC */
339cd2a8 16119 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
16120 } else {
16121 /* OPC_BNVC */
339cd2a8 16122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
16123 }
16124 tcg_temp_free(input_overflow);
16125 tcg_temp_free(t4);
16126 tcg_temp_free(t3);
16127 tcg_temp_free(t2);
16128 } else if (rs < rt && rs == 0) {
16129 /* OPC_BEQZALC, OPC_BNEZALC */
16130 if (opc == OPC_BEQZALC) {
16131 /* OPC_BEQZALC */
339cd2a8 16132 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
16133 } else {
16134 /* OPC_BNEZALC */
339cd2a8 16135 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
16136 }
16137 } else {
16138 /* OPC_BEQC, OPC_BNEC */
16139 if (opc == OPC_BEQC) {
16140 /* OPC_BEQC */
339cd2a8 16141 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
16142 } else {
16143 /* OPC_BNEC */
339cd2a8 16144 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
16145 }
16146 }
16147 break;
16148 case OPC_BEQZC:
339cd2a8 16149 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
16150 break;
16151 case OPC_BNEZC:
339cd2a8 16152 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16153 break;
16154 default:
16155 MIPS_INVAL("Compact conditional branch/jump");
16156 generate_exception(ctx, EXCP_RI);
16157 goto out;
16158 }
16159
16160 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16161 gen_goto_tb(ctx, 1, ctx->btarget);
16162 gen_set_label(fs);
16163
16164 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16165 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16166 }
16167
16168out:
16169 tcg_temp_free(t0);
16170 tcg_temp_free(t1);
16171}
16172
10dc65db
LA
16173static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16174{
4267d3e6 16175 int rs, rt, rd, sa;
b42ee5e1 16176 uint32_t op1, op2;
10dc65db
LA
16177
16178 rs = (ctx->opcode >> 21) & 0x1f;
16179 rt = (ctx->opcode >> 16) & 0x1f;
16180 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16181 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16182
16183 op1 = MASK_SPECIAL(ctx->opcode);
16184 switch (op1) {
d4ea6acd
LA
16185 case OPC_LSA:
16186 if (rd != 0) {
16187 int imm2 = extract32(ctx->opcode, 6, 3);
16188 TCGv t0 = tcg_temp_new();
16189 TCGv t1 = tcg_temp_new();
16190 gen_load_gpr(t0, rs);
16191 gen_load_gpr(t1, rt);
16192 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16193 tcg_gen_add_tl(t0, t0, t1);
16194 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16195 tcg_temp_free(t1);
16196 tcg_temp_free(t0);
16197 }
16198 break;
b42ee5e1
LA
16199 case OPC_MULT ... OPC_DIVU:
16200 op2 = MASK_R6_MULDIV(ctx->opcode);
16201 switch (op2) {
16202 case R6_OPC_MUL:
16203 case R6_OPC_MUH:
16204 case R6_OPC_MULU:
16205 case R6_OPC_MUHU:
16206 case R6_OPC_DIV:
16207 case R6_OPC_MOD:
16208 case R6_OPC_DIVU:
16209 case R6_OPC_MODU:
16210 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16211 break;
16212 default:
16213 MIPS_INVAL("special_r6 muldiv");
16214 generate_exception(ctx, EXCP_RI);
16215 break;
16216 }
16217 break;
10dc65db
LA
16218 case OPC_SELEQZ:
16219 case OPC_SELNEZ:
16220 gen_cond_move(ctx, op1, rd, rs, rt);
16221 break;
4267d3e6
LA
16222 case R6_OPC_CLO:
16223 case R6_OPC_CLZ:
16224 if (rt == 0 && sa == 1) {
16225 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16226 We need additionally to check other fields */
16227 gen_cl(ctx, op1, rd, rs);
16228 } else {
16229 generate_exception(ctx, EXCP_RI);
16230 }
16231 break;
16232 case R6_OPC_SDBBP:
faf1f68b
LA
16233 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16234 generate_exception(ctx, EXCP_RI);
16235 } else {
16236 generate_exception(ctx, EXCP_DBp);
16237 }
4267d3e6 16238 break;
b42ee5e1 16239#if defined(TARGET_MIPS64)
d4ea6acd
LA
16240 case OPC_DLSA:
16241 check_mips_64(ctx);
16242 if (rd != 0) {
16243 int imm2 = extract32(ctx->opcode, 6, 3);
16244 TCGv t0 = tcg_temp_new();
16245 TCGv t1 = tcg_temp_new();
16246 gen_load_gpr(t0, rs);
16247 gen_load_gpr(t1, rt);
16248 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16249 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16250 tcg_temp_free(t1);
16251 tcg_temp_free(t0);
16252 }
16253 break;
4267d3e6
LA
16254 case R6_OPC_DCLO:
16255 case R6_OPC_DCLZ:
16256 if (rt == 0 && sa == 1) {
16257 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16258 We need additionally to check other fields */
16259 check_mips_64(ctx);
16260 gen_cl(ctx, op1, rd, rs);
16261 } else {
16262 generate_exception(ctx, EXCP_RI);
16263 }
16264 break;
b42ee5e1
LA
16265 case OPC_DMULT ... OPC_DDIVU:
16266 op2 = MASK_R6_MULDIV(ctx->opcode);
16267 switch (op2) {
16268 case R6_OPC_DMUL:
16269 case R6_OPC_DMUH:
16270 case R6_OPC_DMULU:
16271 case R6_OPC_DMUHU:
16272 case R6_OPC_DDIV:
16273 case R6_OPC_DMOD:
16274 case R6_OPC_DDIVU:
16275 case R6_OPC_DMODU:
16276 check_mips_64(ctx);
16277 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16278 break;
16279 default:
16280 MIPS_INVAL("special_r6 muldiv");
16281 generate_exception(ctx, EXCP_RI);
16282 break;
16283 }
16284 break;
16285#endif
10dc65db
LA
16286 default: /* Invalid */
16287 MIPS_INVAL("special_r6");
16288 generate_exception(ctx, EXCP_RI);
16289 break;
16290 }
16291}
16292
16293static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16294{
b42ee5e1 16295 int rs, rt, rd, sa;
10dc65db
LA
16296 uint32_t op1;
16297
16298 rs = (ctx->opcode >> 21) & 0x1f;
16299 rt = (ctx->opcode >> 16) & 0x1f;
16300 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16301 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16302
16303 op1 = MASK_SPECIAL(ctx->opcode);
16304 switch (op1) {
16305 case OPC_MOVN: /* Conditional move */
16306 case OPC_MOVZ:
16307 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16308 INSN_LOONGSON2E | INSN_LOONGSON2F);
16309 gen_cond_move(ctx, op1, rd, rs, rt);
16310 break;
16311 case OPC_MFHI: /* Move from HI/LO */
16312 case OPC_MFLO:
16313 gen_HILO(ctx, op1, rs & 3, rd);
16314 break;
16315 case OPC_MTHI:
16316 case OPC_MTLO: /* Move to HI/LO */
16317 gen_HILO(ctx, op1, rd & 3, rs);
16318 break;
16319 case OPC_MOVCI:
16320 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16321 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16322 check_cp1_enabled(ctx);
16323 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16324 (ctx->opcode >> 16) & 1);
16325 } else {
16326 generate_exception_err(ctx, EXCP_CpU, 1);
16327 }
16328 break;
b42ee5e1
LA
16329 case OPC_MULT:
16330 case OPC_MULTU:
16331 if (sa) {
16332 check_insn(ctx, INSN_VR54XX);
16333 op1 = MASK_MUL_VR54XX(ctx->opcode);
16334 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16335 } else {
16336 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16337 }
16338 break;
16339 case OPC_DIV:
16340 case OPC_DIVU:
16341 gen_muldiv(ctx, op1, 0, rs, rt);
16342 break;
16343#if defined(TARGET_MIPS64)
16344 case OPC_DMULT ... OPC_DDIVU:
16345 check_insn(ctx, ISA_MIPS3);
16346 check_mips_64(ctx);
16347 gen_muldiv(ctx, op1, 0, rs, rt);
16348 break;
16349#endif
0aefa333 16350 case OPC_JR:
b231c103 16351 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16352 break;
4267d3e6
LA
16353 case OPC_SPIM:
16354#ifdef MIPS_STRICT_STANDARD
16355 MIPS_INVAL("SPIM");
16356 generate_exception(ctx, EXCP_RI);
16357#else
16358 /* Implemented as RI exception for now. */
16359 MIPS_INVAL("spim (unofficial)");
16360 generate_exception(ctx, EXCP_RI);
16361#endif
16362 break;
10dc65db
LA
16363 default: /* Invalid */
16364 MIPS_INVAL("special_legacy");
16365 generate_exception(ctx, EXCP_RI);
16366 break;
16367 }
16368}
16369
099e5b4d 16370static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16371{
3c824109 16372 int rs, rt, rd, sa;
099e5b4d 16373 uint32_t op1;
3c824109 16374
3c824109
NF
16375 rs = (ctx->opcode >> 21) & 0x1f;
16376 rt = (ctx->opcode >> 16) & 0x1f;
16377 rd = (ctx->opcode >> 11) & 0x1f;
16378 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16379
16380 op1 = MASK_SPECIAL(ctx->opcode);
16381 switch (op1) {
16382 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16383 if (sa == 5 && rd == 0 &&
16384 rs == 0 && rt == 0) { /* PAUSE */
16385 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16386 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16387 MIPS_DEBUG("CTI in delay / forbidden slot");
16388 generate_exception(ctx, EXCP_RI);
16389 break;
16390 }
16391 }
16392 /* Fallthrough */
099e5b4d
LA
16393 case OPC_SRA:
16394 gen_shift_imm(ctx, op1, rd, rt, sa);
16395 break;
16396 case OPC_SRL:
16397 switch ((ctx->opcode >> 21) & 0x1f) {
16398 case 1:
16399 /* rotr is decoded as srl on non-R2 CPUs */
16400 if (ctx->insn_flags & ISA_MIPS32R2) {
16401 op1 = OPC_ROTR;
ea63e2c3 16402 }
099e5b4d
LA
16403 /* Fallthrough */
16404 case 0:
16405 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16406 break;
099e5b4d
LA
16407 default:
16408 generate_exception(ctx, EXCP_RI);
ea63e2c3 16409 break;
099e5b4d
LA
16410 }
16411 break;
099e5b4d
LA
16412 case OPC_ADD ... OPC_SUBU:
16413 gen_arith(ctx, op1, rd, rs, rt);
16414 break;
16415 case OPC_SLLV: /* Shifts */
16416 case OPC_SRAV:
16417 gen_shift(ctx, op1, rd, rs, rt);
16418 break;
16419 case OPC_SRLV:
16420 switch ((ctx->opcode >> 6) & 0x1f) {
16421 case 1:
16422 /* rotrv is decoded as srlv on non-R2 CPUs */
16423 if (ctx->insn_flags & ISA_MIPS32R2) {
16424 op1 = OPC_ROTRV;
26135ead 16425 }
099e5b4d
LA
16426 /* Fallthrough */
16427 case 0:
16428 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16429 break;
099e5b4d
LA
16430 default:
16431 generate_exception(ctx, EXCP_RI);
6af0bf9c 16432 break;
099e5b4d
LA
16433 }
16434 break;
16435 case OPC_SLT: /* Set on less than */
16436 case OPC_SLTU:
16437 gen_slt(ctx, op1, rd, rs, rt);
16438 break;
16439 case OPC_AND: /* Logic*/
16440 case OPC_OR:
16441 case OPC_NOR:
16442 case OPC_XOR:
16443 gen_logic(ctx, op1, rd, rs, rt);
16444 break;
0aefa333 16445 case OPC_JALR:
b231c103 16446 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16447 break;
16448 case OPC_TGE ... OPC_TEQ: /* Traps */
16449 case OPC_TNE:
d9224450 16450 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16451 gen_trap(ctx, op1, rs, rt, -1);
16452 break;
d4ea6acd 16453 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16454 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16455 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16456 decode_opc_special_r6(env, ctx);
16457 } else {
16458 /* Pmon entry point, also R4010 selsl */
b48cfdff 16459#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16460 MIPS_INVAL("PMON / selsl");
16461 generate_exception(ctx, EXCP_RI);
b48cfdff 16462#else
d4ea6acd 16463 gen_helper_0e0i(pmon, sa);
b48cfdff 16464#endif
d4ea6acd 16465 }
099e5b4d
LA
16466 break;
16467 case OPC_SYSCALL:
16468 generate_exception(ctx, EXCP_SYSCALL);
16469 ctx->bstate = BS_STOP;
16470 break;
16471 case OPC_BREAK:
16472 generate_exception(ctx, EXCP_BREAK);
16473 break;
099e5b4d 16474 case OPC_SYNC:
d9224450 16475 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16476 /* Treat as NOP. */
16477 break;
4ad40f36 16478
d26bc211 16479#if defined(TARGET_MIPS64)
099e5b4d
LA
16480 /* MIPS64 specific opcodes */
16481 case OPC_DSLL:
16482 case OPC_DSRA:
16483 case OPC_DSLL32:
16484 case OPC_DSRA32:
16485 check_insn(ctx, ISA_MIPS3);
16486 check_mips_64(ctx);
16487 gen_shift_imm(ctx, op1, rd, rt, sa);
16488 break;
16489 case OPC_DSRL:
16490 switch ((ctx->opcode >> 21) & 0x1f) {
16491 case 1:
16492 /* drotr is decoded as dsrl on non-R2 CPUs */
16493 if (ctx->insn_flags & ISA_MIPS32R2) {
16494 op1 = OPC_DROTR;
ea63e2c3 16495 }
099e5b4d
LA
16496 /* Fallthrough */
16497 case 0:
d75c135e 16498 check_insn(ctx, ISA_MIPS3);
e189e748 16499 check_mips_64(ctx);
099e5b4d 16500 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16501 break;
099e5b4d
LA
16502 default:
16503 generate_exception(ctx, EXCP_RI);
460f00c4 16504 break;
099e5b4d
LA
16505 }
16506 break;
16507 case OPC_DSRL32:
16508 switch ((ctx->opcode >> 21) & 0x1f) {
16509 case 1:
16510 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16511 if (ctx->insn_flags & ISA_MIPS32R2) {
16512 op1 = OPC_DROTR32;
ea63e2c3 16513 }
099e5b4d
LA
16514 /* Fallthrough */
16515 case 0:
d75c135e 16516 check_insn(ctx, ISA_MIPS3);
e189e748 16517 check_mips_64(ctx);
099e5b4d 16518 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16519 break;
099e5b4d 16520 default:
6af0bf9c
FB
16521 generate_exception(ctx, EXCP_RI);
16522 break;
16523 }
16524 break;
099e5b4d
LA
16525 case OPC_DADD ... OPC_DSUBU:
16526 check_insn(ctx, ISA_MIPS3);
16527 check_mips_64(ctx);
16528 gen_arith(ctx, op1, rd, rs, rt);
16529 break;
16530 case OPC_DSLLV:
16531 case OPC_DSRAV:
16532 check_insn(ctx, ISA_MIPS3);
16533 check_mips_64(ctx);
16534 gen_shift(ctx, op1, rd, rs, rt);
16535 break;
16536 case OPC_DSRLV:
16537 switch ((ctx->opcode >> 6) & 0x1f) {
16538 case 1:
16539 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16540 if (ctx->insn_flags & ISA_MIPS32R2) {
16541 op1 = OPC_DROTRV;
6af0bf9c 16542 }
099e5b4d
LA
16543 /* Fallthrough */
16544 case 0:
16545 check_insn(ctx, ISA_MIPS3);
e189e748 16546 check_mips_64(ctx);
099e5b4d 16547 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16548 break;
099e5b4d 16549 default:
6af0bf9c
FB
16550 generate_exception(ctx, EXCP_RI);
16551 break;
16552 }
16553 break;
f7685877
YK
16554 case OPC_DLSA:
16555 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16556 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16557 decode_opc_special_r6(env, ctx);
16558 }
16559 break;
099e5b4d 16560#endif
10dc65db
LA
16561 default:
16562 if (ctx->insn_flags & ISA_MIPS32R6) {
16563 decode_opc_special_r6(env, ctx);
16564 } else {
16565 decode_opc_special_legacy(env, ctx);
16566 }
16567 }
16568}
16569
10dc65db 16570static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16571{
16572 int rs, rt, rd;
16573 uint32_t op1;
6c5c1e20 16574
4267d3e6
LA
16575 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16576
099e5b4d
LA
16577 rs = (ctx->opcode >> 21) & 0x1f;
16578 rt = (ctx->opcode >> 16) & 0x1f;
16579 rd = (ctx->opcode >> 11) & 0x1f;
16580
16581 op1 = MASK_SPECIAL2(ctx->opcode);
16582 switch (op1) {
16583 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16584 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16585 check_insn(ctx, ISA_MIPS32);
16586 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16587 break;
16588 case OPC_MUL:
099e5b4d
LA
16589 gen_arith(ctx, op1, rd, rs, rt);
16590 break;
fac5a073
LA
16591 case OPC_DIV_G_2F:
16592 case OPC_DIVU_G_2F:
16593 case OPC_MULT_G_2F:
16594 case OPC_MULTU_G_2F:
16595 case OPC_MOD_G_2F:
16596 case OPC_MODU_G_2F:
16597 check_insn(ctx, INSN_LOONGSON2F);
16598 gen_loongson_integer(ctx, op1, rd, rs, rt);
16599 break;
099e5b4d
LA
16600 case OPC_CLO:
16601 case OPC_CLZ:
16602 check_insn(ctx, ISA_MIPS32);
16603 gen_cl(ctx, op1, rd, rs);
16604 break;
16605 case OPC_SDBBP:
16606 /* XXX: not clear which exception should be raised
16607 * when in debug mode...
16608 */
16609 check_insn(ctx, ISA_MIPS32);
16610 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16611 generate_exception(ctx, EXCP_DBp);
16612 } else {
16613 generate_exception(ctx, EXCP_DBp);
16614 }
16615 /* Treat as NOP. */
16616 break;
9b1a1d68 16617#if defined(TARGET_MIPS64)
099e5b4d
LA
16618 case OPC_DCLO:
16619 case OPC_DCLZ:
16620 check_insn(ctx, ISA_MIPS64);
16621 check_mips_64(ctx);
16622 gen_cl(ctx, op1, rd, rs);
16623 break;
4267d3e6
LA
16624 case OPC_DMULT_G_2F:
16625 case OPC_DMULTU_G_2F:
16626 case OPC_DDIV_G_2F:
16627 case OPC_DDIVU_G_2F:
16628 case OPC_DMOD_G_2F:
16629 case OPC_DMODU_G_2F:
16630 check_insn(ctx, INSN_LOONGSON2F);
16631 gen_loongson_integer(ctx, op1, rd, rs, rt);
16632 break;
10dc65db 16633#endif
4267d3e6
LA
16634 default: /* Invalid */
16635 MIPS_INVAL("special2_legacy");
16636 generate_exception(ctx, EXCP_RI);
16637 break;
10dc65db
LA
16638 }
16639}
16640
16641static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16642{
15eacb9b
YK
16643 int rs, rt, rd, sa;
16644 uint32_t op1, op2;
10dc65db
LA
16645 int16_t imm;
16646
16647 rs = (ctx->opcode >> 21) & 0x1f;
16648 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16649 rd = (ctx->opcode >> 11) & 0x1f;
16650 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16651 imm = (int16_t)ctx->opcode >> 7;
16652
16653 op1 = MASK_SPECIAL3(ctx->opcode);
16654 switch (op1) {
bf7910c6
LA
16655 case R6_OPC_PREF:
16656 if (rt >= 24) {
16657 /* hint codes 24-31 are reserved and signal RI */
16658 generate_exception(ctx, EXCP_RI);
16659 }
16660 /* Treat as NOP. */
16661 break;
16662 case R6_OPC_CACHE:
16663 /* Treat as NOP. */
16664 break;
10dc65db
LA
16665 case R6_OPC_SC:
16666 gen_st_cond(ctx, op1, rt, rs, imm);
16667 break;
16668 case R6_OPC_LL:
16669 gen_ld(ctx, op1, rt, rs, imm);
16670 break;
15eacb9b
YK
16671 case OPC_BSHFL:
16672 {
16673 if (rd == 0) {
16674 /* Treat as NOP. */
16675 break;
16676 }
16677 TCGv t0 = tcg_temp_new();
16678 gen_load_gpr(t0, rt);
16679
16680 op2 = MASK_BSHFL(ctx->opcode);
16681 switch (op2) {
16682 case OPC_ALIGN ... OPC_ALIGN_END:
16683 sa &= 3;
16684 if (sa == 0) {
16685 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16686 } else {
16687 TCGv t1 = tcg_temp_new();
16688 TCGv_i64 t2 = tcg_temp_new_i64();
16689 gen_load_gpr(t1, rs);
16690 tcg_gen_concat_tl_i64(t2, t1, t0);
16691 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16692#if defined(TARGET_MIPS64)
16693 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16694#else
16695 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16696#endif
16697 tcg_temp_free_i64(t2);
16698 tcg_temp_free(t1);
16699 }
16700 break;
16701 case OPC_BITSWAP:
16702 gen_helper_bitswap(cpu_gpr[rd], t0);
16703 break;
16704 }
16705 tcg_temp_free(t0);
16706 }
16707 break;
bf7910c6
LA
16708#if defined(TARGET_MIPS64)
16709 case R6_OPC_SCD:
16710 gen_st_cond(ctx, op1, rt, rs, imm);
16711 break;
16712 case R6_OPC_LLD:
16713 gen_ld(ctx, op1, rt, rs, imm);
16714 break;
15eacb9b
YK
16715 case OPC_DBSHFL:
16716 check_mips_64(ctx);
16717 {
16718 if (rd == 0) {
16719 /* Treat as NOP. */
16720 break;
16721 }
16722 TCGv t0 = tcg_temp_new();
16723 gen_load_gpr(t0, rt);
16724
16725 op2 = MASK_DBSHFL(ctx->opcode);
16726 switch (op2) {
16727 case OPC_DALIGN ... OPC_DALIGN_END:
16728 sa &= 7;
16729 if (sa == 0) {
16730 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16731 } else {
16732 TCGv t1 = tcg_temp_new();
16733 gen_load_gpr(t1, rs);
16734 tcg_gen_shli_tl(t0, t0, 8 * sa);
16735 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16736 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16737 tcg_temp_free(t1);
16738 }
16739 break;
16740 case OPC_DBITSWAP:
16741 gen_helper_dbitswap(cpu_gpr[rd], t0);
16742 break;
16743 }
16744 tcg_temp_free(t0);
16745 }
16746 break;
bf7910c6 16747#endif
10dc65db
LA
16748 default: /* Invalid */
16749 MIPS_INVAL("special3_r6");
16750 generate_exception(ctx, EXCP_RI);
16751 break;
16752 }
16753}
16754
16755static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16756{
fac5a073 16757 int rs, rt, rd;
099e5b4d 16758 uint32_t op1, op2;
099e5b4d
LA
16759
16760 rs = (ctx->opcode >> 21) & 0x1f;
16761 rt = (ctx->opcode >> 16) & 0x1f;
16762 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16763
16764 op1 = MASK_SPECIAL3(ctx->opcode);
16765 switch (op1) {
099e5b4d
LA
16766 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16767 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16768 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16769 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16770 * the same mask and op1. */
16771 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16772 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16773 switch (op2) {
099e5b4d
LA
16774 case OPC_ADDUH_QB:
16775 case OPC_ADDUH_R_QB:
16776 case OPC_ADDQH_PH:
16777 case OPC_ADDQH_R_PH:
16778 case OPC_ADDQH_W:
16779 case OPC_ADDQH_R_W:
16780 case OPC_SUBUH_QB:
16781 case OPC_SUBUH_R_QB:
16782 case OPC_SUBQH_PH:
16783 case OPC_SUBQH_R_PH:
16784 case OPC_SUBQH_W:
16785 case OPC_SUBQH_R_W:
461c08df
JL
16786 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16787 break;
099e5b4d
LA
16788 case OPC_MUL_PH:
16789 case OPC_MUL_S_PH:
16790 case OPC_MULQ_S_W:
16791 case OPC_MULQ_RS_W:
16792 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16793 break;
461c08df 16794 default:
099e5b4d 16795 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16796 generate_exception(ctx, EXCP_RI);
16797 break;
16798 }
099e5b4d
LA
16799 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16800 gen_loongson_integer(ctx, op1, rd, rs, rt);
16801 } else {
16802 generate_exception(ctx, EXCP_RI);
16803 }
16804 break;
16805 case OPC_LX_DSP:
16806 op2 = MASK_LX(ctx->opcode);
16807 switch (op2) {
16808#if defined(TARGET_MIPS64)
16809 case OPC_LDX:
16810#endif
16811 case OPC_LBUX:
16812 case OPC_LHX:
16813 case OPC_LWX:
16814 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16815 break;
16816 default: /* Invalid */
16817 MIPS_INVAL("MASK LX");
16818 generate_exception(ctx, EXCP_RI);
16819 break;
16820 }
16821 break;
16822 case OPC_ABSQ_S_PH_DSP:
16823 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16824 switch (op2) {
16825 case OPC_ABSQ_S_QB:
16826 case OPC_ABSQ_S_PH:
16827 case OPC_ABSQ_S_W:
16828 case OPC_PRECEQ_W_PHL:
16829 case OPC_PRECEQ_W_PHR:
16830 case OPC_PRECEQU_PH_QBL:
16831 case OPC_PRECEQU_PH_QBR:
16832 case OPC_PRECEQU_PH_QBLA:
16833 case OPC_PRECEQU_PH_QBRA:
16834 case OPC_PRECEU_PH_QBL:
16835 case OPC_PRECEU_PH_QBR:
16836 case OPC_PRECEU_PH_QBLA:
16837 case OPC_PRECEU_PH_QBRA:
16838 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16839 break;
16840 case OPC_BITREV:
16841 case OPC_REPL_QB:
16842 case OPC_REPLV_QB:
16843 case OPC_REPL_PH:
16844 case OPC_REPLV_PH:
16845 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16846 break;
16847 default:
16848 MIPS_INVAL("MASK ABSQ_S.PH");
16849 generate_exception(ctx, EXCP_RI);
16850 break;
16851 }
16852 break;
16853 case OPC_ADDU_QB_DSP:
16854 op2 = MASK_ADDU_QB(ctx->opcode);
16855 switch (op2) {
16856 case OPC_ADDQ_PH:
16857 case OPC_ADDQ_S_PH:
16858 case OPC_ADDQ_S_W:
16859 case OPC_ADDU_QB:
16860 case OPC_ADDU_S_QB:
16861 case OPC_ADDU_PH:
16862 case OPC_ADDU_S_PH:
16863 case OPC_SUBQ_PH:
16864 case OPC_SUBQ_S_PH:
16865 case OPC_SUBQ_S_W:
16866 case OPC_SUBU_QB:
16867 case OPC_SUBU_S_QB:
16868 case OPC_SUBU_PH:
16869 case OPC_SUBU_S_PH:
16870 case OPC_ADDSC:
16871 case OPC_ADDWC:
16872 case OPC_MODSUB:
16873 case OPC_RADDU_W_QB:
16874 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16875 break;
16876 case OPC_MULEU_S_PH_QBL:
16877 case OPC_MULEU_S_PH_QBR:
16878 case OPC_MULQ_RS_PH:
16879 case OPC_MULEQ_S_W_PHL:
16880 case OPC_MULEQ_S_W_PHR:
16881 case OPC_MULQ_S_PH:
16882 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16883 break;
16884 default: /* Invalid */
16885 MIPS_INVAL("MASK ADDU.QB");
16886 generate_exception(ctx, EXCP_RI);
461c08df 16887 break;
461c08df 16888
099e5b4d
LA
16889 }
16890 break;
16891 case OPC_CMPU_EQ_QB_DSP:
16892 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16893 switch (op2) {
16894 case OPC_PRECR_SRA_PH_W:
16895 case OPC_PRECR_SRA_R_PH_W:
16896 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16897 break;
099e5b4d
LA
16898 case OPC_PRECR_QB_PH:
16899 case OPC_PRECRQ_QB_PH:
16900 case OPC_PRECRQ_PH_W:
16901 case OPC_PRECRQ_RS_PH_W:
16902 case OPC_PRECRQU_S_QB_PH:
16903 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16904 break;
099e5b4d
LA
16905 case OPC_CMPU_EQ_QB:
16906 case OPC_CMPU_LT_QB:
16907 case OPC_CMPU_LE_QB:
16908 case OPC_CMP_EQ_PH:
16909 case OPC_CMP_LT_PH:
16910 case OPC_CMP_LE_PH:
16911 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16912 break;
099e5b4d
LA
16913 case OPC_CMPGU_EQ_QB:
16914 case OPC_CMPGU_LT_QB:
16915 case OPC_CMPGU_LE_QB:
16916 case OPC_CMPGDU_EQ_QB:
16917 case OPC_CMPGDU_LT_QB:
16918 case OPC_CMPGDU_LE_QB:
16919 case OPC_PICK_QB:
16920 case OPC_PICK_PH:
16921 case OPC_PACKRL_PH:
16922 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16923 break;
16924 default: /* Invalid */
16925 MIPS_INVAL("MASK CMPU.EQ.QB");
16926 generate_exception(ctx, EXCP_RI);
16927 break;
16928 }
16929 break;
16930 case OPC_SHLL_QB_DSP:
16931 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16932 break;
16933 case OPC_DPA_W_PH_DSP:
16934 op2 = MASK_DPA_W_PH(ctx->opcode);
16935 switch (op2) {
16936 case OPC_DPAU_H_QBL:
16937 case OPC_DPAU_H_QBR:
16938 case OPC_DPSU_H_QBL:
16939 case OPC_DPSU_H_QBR:
16940 case OPC_DPA_W_PH:
16941 case OPC_DPAX_W_PH:
16942 case OPC_DPAQ_S_W_PH:
16943 case OPC_DPAQX_S_W_PH:
16944 case OPC_DPAQX_SA_W_PH:
16945 case OPC_DPS_W_PH:
16946 case OPC_DPSX_W_PH:
16947 case OPC_DPSQ_S_W_PH:
16948 case OPC_DPSQX_S_W_PH:
16949 case OPC_DPSQX_SA_W_PH:
16950 case OPC_MULSAQ_S_W_PH:
16951 case OPC_DPAQ_SA_L_W:
16952 case OPC_DPSQ_SA_L_W:
16953 case OPC_MAQ_S_W_PHL:
16954 case OPC_MAQ_S_W_PHR:
16955 case OPC_MAQ_SA_W_PHL:
16956 case OPC_MAQ_SA_W_PHR:
16957 case OPC_MULSA_W_PH:
16958 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16959 break;
16960 default: /* Invalid */
16961 MIPS_INVAL("MASK DPAW.PH");
16962 generate_exception(ctx, EXCP_RI);
16963 break;
16964 }
16965 break;
16966 case OPC_INSV_DSP:
16967 op2 = MASK_INSV(ctx->opcode);
16968 switch (op2) {
16969 case OPC_INSV:
16970 check_dsp(ctx);
16971 {
16972 TCGv t0, t1;
16973
16974 if (rt == 0) {
16975 MIPS_DEBUG("NOP");
16976 break;
16977 }
16978
16979 t0 = tcg_temp_new();
16980 t1 = tcg_temp_new();
16981
16982 gen_load_gpr(t0, rt);
16983 gen_load_gpr(t1, rs);
16984
16985 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16986
16987 tcg_temp_free(t0);
16988 tcg_temp_free(t1);
a22260ae
JL
16989 break;
16990 }
099e5b4d
LA
16991 default: /* Invalid */
16992 MIPS_INVAL("MASK INSV");
16993 generate_exception(ctx, EXCP_RI);
16994 break;
16995 }
16996 break;
16997 case OPC_APPEND_DSP:
16998 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16999 break;
17000 case OPC_EXTR_W_DSP:
17001 op2 = MASK_EXTR_W(ctx->opcode);
17002 switch (op2) {
17003 case OPC_EXTR_W:
17004 case OPC_EXTR_R_W:
17005 case OPC_EXTR_RS_W:
17006 case OPC_EXTR_S_H:
17007 case OPC_EXTRV_S_H:
17008 case OPC_EXTRV_W:
17009 case OPC_EXTRV_R_W:
17010 case OPC_EXTRV_RS_W:
17011 case OPC_EXTP:
17012 case OPC_EXTPV:
17013 case OPC_EXTPDP:
17014 case OPC_EXTPDPV:
17015 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17016 break;
17017 case OPC_RDDSP:
17018 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17019 break;
17020 case OPC_SHILO:
17021 case OPC_SHILOV:
17022 case OPC_MTHLIP:
17023 case OPC_WRDSP:
17024 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17025 break;
17026 default: /* Invalid */
17027 MIPS_INVAL("MASK EXTR.W");
17028 generate_exception(ctx, EXCP_RI);
17029 break;
17030 }
17031 break;
099e5b4d 17032#if defined(TARGET_MIPS64)
fac5a073
LA
17033 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17034 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17035 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17036 check_insn(ctx, INSN_LOONGSON2E);
17037 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17038 break;
099e5b4d
LA
17039 case OPC_ABSQ_S_QH_DSP:
17040 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17041 switch (op2) {
17042 case OPC_PRECEQ_L_PWL:
17043 case OPC_PRECEQ_L_PWR:
17044 case OPC_PRECEQ_PW_QHL:
17045 case OPC_PRECEQ_PW_QHR:
17046 case OPC_PRECEQ_PW_QHLA:
17047 case OPC_PRECEQ_PW_QHRA:
17048 case OPC_PRECEQU_QH_OBL:
17049 case OPC_PRECEQU_QH_OBR:
17050 case OPC_PRECEQU_QH_OBLA:
17051 case OPC_PRECEQU_QH_OBRA:
17052 case OPC_PRECEU_QH_OBL:
17053 case OPC_PRECEU_QH_OBR:
17054 case OPC_PRECEU_QH_OBLA:
17055 case OPC_PRECEU_QH_OBRA:
17056 case OPC_ABSQ_S_OB:
17057 case OPC_ABSQ_S_PW:
17058 case OPC_ABSQ_S_QH:
17059 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17060 break;
17061 case OPC_REPL_OB:
17062 case OPC_REPL_PW:
17063 case OPC_REPL_QH:
17064 case OPC_REPLV_OB:
17065 case OPC_REPLV_PW:
17066 case OPC_REPLV_QH:
17067 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17068 break;
17069 default: /* Invalid */
17070 MIPS_INVAL("MASK ABSQ_S.QH");
17071 generate_exception(ctx, EXCP_RI);
17072 break;
17073 }
17074 break;
17075 case OPC_ADDU_OB_DSP:
17076 op2 = MASK_ADDU_OB(ctx->opcode);
17077 switch (op2) {
17078 case OPC_RADDU_L_OB:
17079 case OPC_SUBQ_PW:
17080 case OPC_SUBQ_S_PW:
17081 case OPC_SUBQ_QH:
17082 case OPC_SUBQ_S_QH:
17083 case OPC_SUBU_OB:
17084 case OPC_SUBU_S_OB:
17085 case OPC_SUBU_QH:
17086 case OPC_SUBU_S_QH:
17087 case OPC_SUBUH_OB:
17088 case OPC_SUBUH_R_OB:
17089 case OPC_ADDQ_PW:
17090 case OPC_ADDQ_S_PW:
17091 case OPC_ADDQ_QH:
17092 case OPC_ADDQ_S_QH:
17093 case OPC_ADDU_OB:
17094 case OPC_ADDU_S_OB:
17095 case OPC_ADDU_QH:
17096 case OPC_ADDU_S_QH:
17097 case OPC_ADDUH_OB:
17098 case OPC_ADDUH_R_OB:
17099 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17100 break;
099e5b4d
LA
17101 case OPC_MULEQ_S_PW_QHL:
17102 case OPC_MULEQ_S_PW_QHR:
17103 case OPC_MULEU_S_QH_OBL:
17104 case OPC_MULEU_S_QH_OBR:
17105 case OPC_MULQ_RS_QH:
17106 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17107 break;
099e5b4d
LA
17108 default: /* Invalid */
17109 MIPS_INVAL("MASK ADDU.OB");
17110 generate_exception(ctx, EXCP_RI);
26690560 17111 break;
099e5b4d
LA
17112 }
17113 break;
17114 case OPC_CMPU_EQ_OB_DSP:
17115 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17116 switch (op2) {
17117 case OPC_PRECR_SRA_QH_PW:
17118 case OPC_PRECR_SRA_R_QH_PW:
17119 /* Return value is rt. */
17120 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17121 break;
099e5b4d
LA
17122 case OPC_PRECR_OB_QH:
17123 case OPC_PRECRQ_OB_QH:
17124 case OPC_PRECRQ_PW_L:
17125 case OPC_PRECRQ_QH_PW:
17126 case OPC_PRECRQ_RS_QH_PW:
17127 case OPC_PRECRQU_S_OB_QH:
17128 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17129 break;
099e5b4d
LA
17130 case OPC_CMPU_EQ_OB:
17131 case OPC_CMPU_LT_OB:
17132 case OPC_CMPU_LE_OB:
17133 case OPC_CMP_EQ_QH:
17134 case OPC_CMP_LT_QH:
17135 case OPC_CMP_LE_QH:
17136 case OPC_CMP_EQ_PW:
17137 case OPC_CMP_LT_PW:
17138 case OPC_CMP_LE_PW:
17139 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17140 break;
099e5b4d
LA
17141 case OPC_CMPGDU_EQ_OB:
17142 case OPC_CMPGDU_LT_OB:
17143 case OPC_CMPGDU_LE_OB:
17144 case OPC_CMPGU_EQ_OB:
17145 case OPC_CMPGU_LT_OB:
17146 case OPC_CMPGU_LE_OB:
17147 case OPC_PACKRL_PW:
17148 case OPC_PICK_OB:
17149 case OPC_PICK_PW:
17150 case OPC_PICK_QH:
17151 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17152 break;
099e5b4d
LA
17153 default: /* Invalid */
17154 MIPS_INVAL("MASK CMPU_EQ.OB");
17155 generate_exception(ctx, EXCP_RI);
161f85e6 17156 break;
099e5b4d
LA
17157 }
17158 break;
17159 case OPC_DAPPEND_DSP:
17160 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17161 break;
17162 case OPC_DEXTR_W_DSP:
17163 op2 = MASK_DEXTR_W(ctx->opcode);
17164 switch (op2) {
17165 case OPC_DEXTP:
17166 case OPC_DEXTPDP:
17167 case OPC_DEXTPDPV:
17168 case OPC_DEXTPV:
17169 case OPC_DEXTR_L:
17170 case OPC_DEXTR_R_L:
17171 case OPC_DEXTR_RS_L:
17172 case OPC_DEXTR_W:
17173 case OPC_DEXTR_R_W:
17174 case OPC_DEXTR_RS_W:
17175 case OPC_DEXTR_S_H:
17176 case OPC_DEXTRV_L:
17177 case OPC_DEXTRV_R_L:
17178 case OPC_DEXTRV_RS_L:
17179 case OPC_DEXTRV_S_H:
17180 case OPC_DEXTRV_W:
17181 case OPC_DEXTRV_R_W:
17182 case OPC_DEXTRV_RS_W:
17183 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17184 break;
099e5b4d
LA
17185 case OPC_DMTHLIP:
17186 case OPC_DSHILO:
17187 case OPC_DSHILOV:
17188 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17189 break;
099e5b4d
LA
17190 default: /* Invalid */
17191 MIPS_INVAL("MASK EXTR.W");
17192 generate_exception(ctx, EXCP_RI);
461c08df 17193 break;
099e5b4d
LA
17194 }
17195 break;
17196 case OPC_DPAQ_W_QH_DSP:
17197 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17198 switch (op2) {
17199 case OPC_DPAU_H_OBL:
17200 case OPC_DPAU_H_OBR:
17201 case OPC_DPSU_H_OBL:
17202 case OPC_DPSU_H_OBR:
17203 case OPC_DPA_W_QH:
17204 case OPC_DPAQ_S_W_QH:
17205 case OPC_DPS_W_QH:
17206 case OPC_DPSQ_S_W_QH:
17207 case OPC_MULSAQ_S_W_QH:
17208 case OPC_DPAQ_SA_L_PW:
17209 case OPC_DPSQ_SA_L_PW:
17210 case OPC_MULSAQ_S_L_PW:
17211 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17212 break;
17213 case OPC_MAQ_S_W_QHLL:
17214 case OPC_MAQ_S_W_QHLR:
17215 case OPC_MAQ_S_W_QHRL:
17216 case OPC_MAQ_S_W_QHRR:
17217 case OPC_MAQ_SA_W_QHLL:
17218 case OPC_MAQ_SA_W_QHLR:
17219 case OPC_MAQ_SA_W_QHRL:
17220 case OPC_MAQ_SA_W_QHRR:
17221 case OPC_MAQ_S_L_PWL:
17222 case OPC_MAQ_S_L_PWR:
17223 case OPC_DMADD:
17224 case OPC_DMADDU:
17225 case OPC_DMSUB:
17226 case OPC_DMSUBU:
17227 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17228 break;
099e5b4d
LA
17229 default: /* Invalid */
17230 MIPS_INVAL("MASK DPAQ.W.QH");
17231 generate_exception(ctx, EXCP_RI);
b53371ed 17232 break;
099e5b4d
LA
17233 }
17234 break;
17235 case OPC_DINSV_DSP:
17236 op2 = MASK_INSV(ctx->opcode);
17237 switch (op2) {
17238 case OPC_DINSV:
17239 {
17240 TCGv t0, t1;
17241
17242 if (rt == 0) {
17243 MIPS_DEBUG("NOP");
a22260ae
JL
17244 break;
17245 }
099e5b4d 17246 check_dsp(ctx);
1cb6686c 17247
099e5b4d
LA
17248 t0 = tcg_temp_new();
17249 t1 = tcg_temp_new();
1cb6686c 17250
099e5b4d
LA
17251 gen_load_gpr(t0, rt);
17252 gen_load_gpr(t1, rs);
1cb6686c 17253
099e5b4d 17254 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17255
099e5b4d
LA
17256 tcg_temp_free(t0);
17257 tcg_temp_free(t1);
77c5fa8b 17258 break;
099e5b4d 17259 }
7a387fff 17260 default: /* Invalid */
099e5b4d 17261 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17262 generate_exception(ctx, EXCP_RI);
17263 break;
17264 }
17265 break;
099e5b4d
LA
17266 case OPC_SHLL_OB_DSP:
17267 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17268 break;
17269#endif
fac5a073
LA
17270 default: /* Invalid */
17271 MIPS_INVAL("special3_legacy");
17272 generate_exception(ctx, EXCP_RI);
17273 break;
17274 }
17275}
17276
17277static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17278{
17279 int rs, rt, rd, sa;
17280 uint32_t op1, op2;
17281
17282 rs = (ctx->opcode >> 21) & 0x1f;
17283 rt = (ctx->opcode >> 16) & 0x1f;
17284 rd = (ctx->opcode >> 11) & 0x1f;
17285 sa = (ctx->opcode >> 6) & 0x1f;
17286
17287 op1 = MASK_SPECIAL3(ctx->opcode);
17288 switch (op1) {
17289 case OPC_EXT:
17290 case OPC_INS:
17291 check_insn(ctx, ISA_MIPS32R2);
17292 gen_bitops(ctx, op1, rt, rs, sa, rd);
17293 break;
17294 case OPC_BSHFL:
fac5a073 17295 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17296 switch (op2) {
17297 case OPC_ALIGN ... OPC_ALIGN_END:
17298 case OPC_BITSWAP:
17299 check_insn(ctx, ISA_MIPS32R6);
17300 decode_opc_special3_r6(env, ctx);
17301 break;
17302 default:
17303 check_insn(ctx, ISA_MIPS32R2);
17304 gen_bshfl(ctx, op2, rt, rd);
17305 break;
17306 }
fac5a073
LA
17307 break;
17308#if defined(TARGET_MIPS64)
17309 case OPC_DEXTM ... OPC_DEXT:
17310 case OPC_DINSM ... OPC_DINS:
17311 check_insn(ctx, ISA_MIPS64R2);
17312 check_mips_64(ctx);
17313 gen_bitops(ctx, op1, rt, rs, sa, rd);
17314 break;
17315 case OPC_DBSHFL:
fac5a073 17316 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17317 switch (op2) {
17318 case OPC_DALIGN ... OPC_DALIGN_END:
17319 case OPC_DBITSWAP:
17320 check_insn(ctx, ISA_MIPS32R6);
17321 decode_opc_special3_r6(env, ctx);
17322 break;
17323 default:
17324 check_insn(ctx, ISA_MIPS64R2);
17325 check_mips_64(ctx);
17326 op2 = MASK_DBSHFL(ctx->opcode);
17327 gen_bshfl(ctx, op2, rt, rd);
17328 break;
17329 }
fac5a073
LA
17330 break;
17331#endif
17332 case OPC_RDHWR:
17333 gen_rdhwr(ctx, rt, rd);
17334 break;
17335 case OPC_FORK:
17336 check_insn(ctx, ASE_MT);
17337 {
17338 TCGv t0 = tcg_temp_new();
17339 TCGv t1 = tcg_temp_new();
17340
17341 gen_load_gpr(t0, rt);
17342 gen_load_gpr(t1, rs);
17343 gen_helper_fork(t0, t1);
17344 tcg_temp_free(t0);
17345 tcg_temp_free(t1);
17346 }
17347 break;
17348 case OPC_YIELD:
17349 check_insn(ctx, ASE_MT);
17350 {
17351 TCGv t0 = tcg_temp_new();
17352
17353 save_cpu_state(ctx, 1);
17354 gen_load_gpr(t0, rs);
17355 gen_helper_yield(t0, cpu_env, t0);
17356 gen_store_gpr(t0, rd);
17357 tcg_temp_free(t0);
17358 }
17359 break;
10dc65db
LA
17360 default:
17361 if (ctx->insn_flags & ISA_MIPS32R6) {
17362 decode_opc_special3_r6(env, ctx);
17363 } else {
17364 decode_opc_special3_legacy(env, ctx);
17365 }
099e5b4d
LA
17366 }
17367}
17368
863f264d
YK
17369/* MIPS SIMD Architecture (MSA) */
17370static inline int check_msa_access(DisasContext *ctx)
17371{
17372 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17373 !(ctx->hflags & MIPS_HFLAG_F64))) {
17374 generate_exception(ctx, EXCP_RI);
17375 return 0;
17376 }
17377
17378 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17379 if (ctx->insn_flags & ASE_MSA) {
17380 generate_exception(ctx, EXCP_MSADIS);
17381 return 0;
17382 } else {
17383 generate_exception(ctx, EXCP_RI);
17384 return 0;
17385 }
17386 }
17387 return 1;
17388}
17389
5692c6e1
YK
17390static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17391{
17392 /* generates tcg ops to check if any element is 0 */
17393 /* Note this function only works with MSA_WRLEN = 128 */
17394 uint64_t eval_zero_or_big = 0;
17395 uint64_t eval_big = 0;
17396 TCGv_i64 t0 = tcg_temp_new_i64();
17397 TCGv_i64 t1 = tcg_temp_new_i64();
17398 switch (df) {
17399 case DF_BYTE:
17400 eval_zero_or_big = 0x0101010101010101ULL;
17401 eval_big = 0x8080808080808080ULL;
17402 break;
17403 case DF_HALF:
17404 eval_zero_or_big = 0x0001000100010001ULL;
17405 eval_big = 0x8000800080008000ULL;
17406 break;
17407 case DF_WORD:
17408 eval_zero_or_big = 0x0000000100000001ULL;
17409 eval_big = 0x8000000080000000ULL;
17410 break;
17411 case DF_DOUBLE:
17412 eval_zero_or_big = 0x0000000000000001ULL;
17413 eval_big = 0x8000000000000000ULL;
17414 break;
17415 }
17416 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17417 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17418 tcg_gen_andi_i64(t0, t0, eval_big);
17419 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17420 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17421 tcg_gen_andi_i64(t1, t1, eval_big);
17422 tcg_gen_or_i64(t0, t0, t1);
17423 /* if all bits are zero then all elements are not zero */
17424 /* if some bit is non-zero then some element is zero */
17425 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17426 tcg_gen_trunc_i64_tl(tresult, t0);
17427 tcg_temp_free_i64(t0);
17428 tcg_temp_free_i64(t1);
17429}
17430
17431static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17432{
17433 uint8_t df = (ctx->opcode >> 21) & 0x3;
17434 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17435 int64_t s16 = (int16_t)ctx->opcode;
17436
17437 check_msa_access(ctx);
17438
17439 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17440 MIPS_DEBUG("CTI in delay / forbidden slot");
17441 generate_exception(ctx, EXCP_RI);
17442 return;
17443 }
17444 switch (op1) {
17445 case OPC_BZ_V:
17446 case OPC_BNZ_V:
17447 {
17448 TCGv_i64 t0 = tcg_temp_new_i64();
17449 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17450 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17451 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17452 tcg_gen_trunc_i64_tl(bcond, t0);
17453 tcg_temp_free_i64(t0);
17454 }
17455 break;
17456 case OPC_BZ_B:
17457 case OPC_BZ_H:
17458 case OPC_BZ_W:
17459 case OPC_BZ_D:
17460 gen_check_zero_element(bcond, df, wt);
17461 break;
17462 case OPC_BNZ_B:
17463 case OPC_BNZ_H:
17464 case OPC_BNZ_W:
17465 case OPC_BNZ_D:
17466 gen_check_zero_element(bcond, df, wt);
17467 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17468 break;
17469 }
17470
17471 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17472
17473 ctx->hflags |= MIPS_HFLAG_BC;
17474 ctx->hflags |= MIPS_HFLAG_BDS32;
17475}
17476
4c789546
YK
17477static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17478{
17479#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17480 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17481 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17482 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17483
17484 TCGv_i32 twd = tcg_const_i32(wd);
17485 TCGv_i32 tws = tcg_const_i32(ws);
17486 TCGv_i32 ti8 = tcg_const_i32(i8);
17487
17488 switch (MASK_MSA_I8(ctx->opcode)) {
17489 case OPC_ANDI_B:
17490 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17491 break;
17492 case OPC_ORI_B:
17493 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17494 break;
17495 case OPC_NORI_B:
17496 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17497 break;
17498 case OPC_XORI_B:
17499 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17500 break;
17501 case OPC_BMNZI_B:
17502 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17503 break;
17504 case OPC_BMZI_B:
17505 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17506 break;
17507 case OPC_BSELI_B:
17508 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17509 break;
17510 case OPC_SHF_B:
17511 case OPC_SHF_H:
17512 case OPC_SHF_W:
17513 {
17514 uint8_t df = (ctx->opcode >> 24) & 0x3;
17515 if (df == DF_DOUBLE) {
17516 generate_exception(ctx, EXCP_RI);
17517 } else {
17518 TCGv_i32 tdf = tcg_const_i32(df);
17519 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17520 tcg_temp_free_i32(tdf);
17521 }
17522 }
17523 break;
17524 default:
17525 MIPS_INVAL("MSA instruction");
17526 generate_exception(ctx, EXCP_RI);
17527 break;
17528 }
17529
17530 tcg_temp_free_i32(twd);
17531 tcg_temp_free_i32(tws);
17532 tcg_temp_free_i32(ti8);
17533}
17534
80e71591
YK
17535static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17536{
17537#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17538 uint8_t df = (ctx->opcode >> 21) & 0x3;
17539 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17540 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17541 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17542 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17543
17544 TCGv_i32 tdf = tcg_const_i32(df);
17545 TCGv_i32 twd = tcg_const_i32(wd);
17546 TCGv_i32 tws = tcg_const_i32(ws);
17547 TCGv_i32 timm = tcg_temp_new_i32();
17548 tcg_gen_movi_i32(timm, u5);
17549
17550 switch (MASK_MSA_I5(ctx->opcode)) {
17551 case OPC_ADDVI_df:
17552 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17553 break;
17554 case OPC_SUBVI_df:
17555 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17556 break;
17557 case OPC_MAXI_S_df:
17558 tcg_gen_movi_i32(timm, s5);
17559 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17560 break;
17561 case OPC_MAXI_U_df:
17562 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17563 break;
17564 case OPC_MINI_S_df:
17565 tcg_gen_movi_i32(timm, s5);
17566 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17567 break;
17568 case OPC_MINI_U_df:
17569 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17570 break;
17571 case OPC_CEQI_df:
17572 tcg_gen_movi_i32(timm, s5);
17573 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17574 break;
17575 case OPC_CLTI_S_df:
17576 tcg_gen_movi_i32(timm, s5);
17577 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17578 break;
17579 case OPC_CLTI_U_df:
17580 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17581 break;
17582 case OPC_CLEI_S_df:
17583 tcg_gen_movi_i32(timm, s5);
17584 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17585 break;
17586 case OPC_CLEI_U_df:
17587 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17588 break;
17589 case OPC_LDI_df:
17590 {
17591 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17592 tcg_gen_movi_i32(timm, s10);
17593 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17594 }
17595 break;
17596 default:
17597 MIPS_INVAL("MSA instruction");
17598 generate_exception(ctx, EXCP_RI);
17599 break;
17600 }
17601
17602 tcg_temp_free_i32(tdf);
17603 tcg_temp_free_i32(twd);
17604 tcg_temp_free_i32(tws);
17605 tcg_temp_free_i32(timm);
17606}
17607
d4cf28de
YK
17608static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17609{
17610#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17611 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17612 uint32_t df = 0, m = 0;
17613 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17614 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17615
17616 TCGv_i32 tdf;
17617 TCGv_i32 tm;
17618 TCGv_i32 twd;
17619 TCGv_i32 tws;
17620
17621 if ((dfm & 0x40) == 0x00) {
17622 m = dfm & 0x3f;
17623 df = DF_DOUBLE;
17624 } else if ((dfm & 0x60) == 0x40) {
17625 m = dfm & 0x1f;
17626 df = DF_WORD;
17627 } else if ((dfm & 0x70) == 0x60) {
17628 m = dfm & 0x0f;
17629 df = DF_HALF;
17630 } else if ((dfm & 0x78) == 0x70) {
17631 m = dfm & 0x7;
17632 df = DF_BYTE;
17633 } else {
17634 generate_exception(ctx, EXCP_RI);
17635 return;
17636 }
17637
17638 tdf = tcg_const_i32(df);
17639 tm = tcg_const_i32(m);
17640 twd = tcg_const_i32(wd);
17641 tws = tcg_const_i32(ws);
17642
17643 switch (MASK_MSA_BIT(ctx->opcode)) {
17644 case OPC_SLLI_df:
17645 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17646 break;
17647 case OPC_SRAI_df:
17648 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17649 break;
17650 case OPC_SRLI_df:
17651 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17652 break;
17653 case OPC_BCLRI_df:
17654 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17655 break;
17656 case OPC_BSETI_df:
17657 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17658 break;
17659 case OPC_BNEGI_df:
17660 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17661 break;
17662 case OPC_BINSLI_df:
17663 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17664 break;
17665 case OPC_BINSRI_df:
17666 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17667 break;
17668 case OPC_SAT_S_df:
17669 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17670 break;
17671 case OPC_SAT_U_df:
17672 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17673 break;
17674 case OPC_SRARI_df:
17675 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17676 break;
17677 case OPC_SRLRI_df:
17678 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17679 break;
17680 default:
17681 MIPS_INVAL("MSA instruction");
17682 generate_exception(ctx, EXCP_RI);
17683 break;
17684 }
17685
17686 tcg_temp_free_i32(tdf);
17687 tcg_temp_free_i32(tm);
17688 tcg_temp_free_i32(twd);
17689 tcg_temp_free_i32(tws);
17690}
17691
28f99f08
YK
17692static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17693{
17694#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17695 uint8_t df = (ctx->opcode >> 21) & 0x3;
17696 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17697 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17698 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17699
17700 TCGv_i32 tdf = tcg_const_i32(df);
17701 TCGv_i32 twd = tcg_const_i32(wd);
17702 TCGv_i32 tws = tcg_const_i32(ws);
17703 TCGv_i32 twt = tcg_const_i32(wt);
17704
17705 switch (MASK_MSA_3R(ctx->opcode)) {
17706 case OPC_SLL_df:
17707 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17708 break;
17709 case OPC_ADDV_df:
17710 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17711 break;
17712 case OPC_CEQ_df:
17713 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17714 break;
17715 case OPC_ADD_A_df:
17716 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17717 break;
17718 case OPC_SUBS_S_df:
17719 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17720 break;
17721 case OPC_MULV_df:
17722 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17723 break;
17724 case OPC_SLD_df:
17725 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17726 break;
17727 case OPC_VSHF_df:
17728 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17729 break;
17730 case OPC_SRA_df:
17731 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17732 break;
17733 case OPC_SUBV_df:
17734 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17735 break;
17736 case OPC_ADDS_A_df:
17737 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17738 break;
17739 case OPC_SUBS_U_df:
17740 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17741 break;
17742 case OPC_MADDV_df:
17743 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17744 break;
17745 case OPC_SPLAT_df:
17746 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17747 break;
17748 case OPC_SRAR_df:
17749 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17750 break;
17751 case OPC_SRL_df:
17752 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17753 break;
17754 case OPC_MAX_S_df:
17755 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17756 break;
17757 case OPC_CLT_S_df:
17758 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17759 break;
17760 case OPC_ADDS_S_df:
17761 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17762 break;
17763 case OPC_SUBSUS_U_df:
17764 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17765 break;
17766 case OPC_MSUBV_df:
17767 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17768 break;
17769 case OPC_PCKEV_df:
17770 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17771 break;
17772 case OPC_SRLR_df:
17773 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17774 break;
17775 case OPC_BCLR_df:
17776 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17777 break;
17778 case OPC_MAX_U_df:
17779 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17780 break;
17781 case OPC_CLT_U_df:
17782 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17783 break;
17784 case OPC_ADDS_U_df:
17785 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17786 break;
17787 case OPC_SUBSUU_S_df:
17788 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17789 break;
17790 case OPC_PCKOD_df:
17791 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17792 break;
17793 case OPC_BSET_df:
17794 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17795 break;
17796 case OPC_MIN_S_df:
17797 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17798 break;
17799 case OPC_CLE_S_df:
17800 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17801 break;
17802 case OPC_AVE_S_df:
17803 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17804 break;
17805 case OPC_ASUB_S_df:
17806 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17807 break;
17808 case OPC_DIV_S_df:
17809 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17810 break;
17811 case OPC_ILVL_df:
17812 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17813 break;
17814 case OPC_BNEG_df:
17815 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17816 break;
17817 case OPC_MIN_U_df:
17818 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17819 break;
17820 case OPC_CLE_U_df:
17821 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17822 break;
17823 case OPC_AVE_U_df:
17824 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17825 break;
17826 case OPC_ASUB_U_df:
17827 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17828 break;
17829 case OPC_DIV_U_df:
17830 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17831 break;
17832 case OPC_ILVR_df:
17833 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17834 break;
17835 case OPC_BINSL_df:
17836 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17837 break;
17838 case OPC_MAX_A_df:
17839 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17840 break;
17841 case OPC_AVER_S_df:
17842 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17843 break;
17844 case OPC_MOD_S_df:
17845 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17846 break;
17847 case OPC_ILVEV_df:
17848 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17849 break;
17850 case OPC_BINSR_df:
17851 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17852 break;
17853 case OPC_MIN_A_df:
17854 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17855 break;
17856 case OPC_AVER_U_df:
17857 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17858 break;
17859 case OPC_MOD_U_df:
17860 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17861 break;
17862 case OPC_ILVOD_df:
17863 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17864 break;
17865
17866 case OPC_DOTP_S_df:
17867 case OPC_DOTP_U_df:
17868 case OPC_DPADD_S_df:
17869 case OPC_DPADD_U_df:
17870 case OPC_DPSUB_S_df:
17871 case OPC_HADD_S_df:
17872 case OPC_DPSUB_U_df:
17873 case OPC_HADD_U_df:
17874 case OPC_HSUB_S_df:
17875 case OPC_HSUB_U_df:
17876 if (df == DF_BYTE) {
17877 generate_exception(ctx, EXCP_RI);
17878 }
17879 switch (MASK_MSA_3R(ctx->opcode)) {
17880 case OPC_DOTP_S_df:
17881 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17882 break;
17883 case OPC_DOTP_U_df:
17884 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17885 break;
17886 case OPC_DPADD_S_df:
17887 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17888 break;
17889 case OPC_DPADD_U_df:
17890 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17891 break;
17892 case OPC_DPSUB_S_df:
17893 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17894 break;
17895 case OPC_HADD_S_df:
17896 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17897 break;
17898 case OPC_DPSUB_U_df:
17899 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17900 break;
17901 case OPC_HADD_U_df:
17902 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17903 break;
17904 case OPC_HSUB_S_df:
17905 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17906 break;
17907 case OPC_HSUB_U_df:
17908 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17909 break;
17910 }
17911 break;
17912 default:
17913 MIPS_INVAL("MSA instruction");
17914 generate_exception(ctx, EXCP_RI);
17915 break;
17916 }
17917 tcg_temp_free_i32(twd);
17918 tcg_temp_free_i32(tws);
17919 tcg_temp_free_i32(twt);
17920 tcg_temp_free_i32(tdf);
17921}
17922
1e608ec1
YK
17923static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17924{
17925#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17926 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17927 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17928 TCGv telm = tcg_temp_new();
17929 TCGv_i32 tsr = tcg_const_i32(source);
17930 TCGv_i32 tdt = tcg_const_i32(dest);
17931
17932 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17933 case OPC_CTCMSA:
17934 gen_load_gpr(telm, source);
17935 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17936 break;
17937 case OPC_CFCMSA:
17938 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17939 gen_store_gpr(telm, dest);
17940 break;
17941 case OPC_MOVE_V:
17942 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17943 break;
17944 default:
17945 MIPS_INVAL("MSA instruction");
17946 generate_exception(ctx, EXCP_RI);
17947 break;
17948 }
17949
17950 tcg_temp_free(telm);
17951 tcg_temp_free_i32(tdt);
17952 tcg_temp_free_i32(tsr);
17953}
17954
17955static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17956 uint32_t n)
17957{
17958#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17959 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17960 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17961
17962 TCGv_i32 tws = tcg_const_i32(ws);
17963 TCGv_i32 twd = tcg_const_i32(wd);
17964 TCGv_i32 tn = tcg_const_i32(n);
17965 TCGv_i32 tdf = tcg_const_i32(df);
17966
17967 switch (MASK_MSA_ELM(ctx->opcode)) {
17968 case OPC_SLDI_df:
17969 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17970 break;
17971 case OPC_SPLATI_df:
17972 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17973 break;
17974 case OPC_INSVE_df:
17975 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17976 break;
17977 case OPC_COPY_S_df:
17978 case OPC_COPY_U_df:
17979 case OPC_INSERT_df:
17980#if !defined(TARGET_MIPS64)
17981 /* Double format valid only for MIPS64 */
17982 if (df == DF_DOUBLE) {
17983 generate_exception(ctx, EXCP_RI);
17984 break;
17985 }
17986#endif
17987 switch (MASK_MSA_ELM(ctx->opcode)) {
17988 case OPC_COPY_S_df:
17989 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
17990 break;
17991 case OPC_COPY_U_df:
17992 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
17993 break;
17994 case OPC_INSERT_df:
17995 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
17996 break;
17997 }
17998 break;
17999 default:
18000 MIPS_INVAL("MSA instruction");
18001 generate_exception(ctx, EXCP_RI);
18002 }
18003 tcg_temp_free_i32(twd);
18004 tcg_temp_free_i32(tws);
18005 tcg_temp_free_i32(tn);
18006 tcg_temp_free_i32(tdf);
18007}
18008
18009static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18010{
18011 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18012 uint32_t df = 0, n = 0;
18013
18014 if ((dfn & 0x30) == 0x00) {
18015 n = dfn & 0x0f;
18016 df = DF_BYTE;
18017 } else if ((dfn & 0x38) == 0x20) {
18018 n = dfn & 0x07;
18019 df = DF_HALF;
18020 } else if ((dfn & 0x3c) == 0x30) {
18021 n = dfn & 0x03;
18022 df = DF_WORD;
18023 } else if ((dfn & 0x3e) == 0x38) {
18024 n = dfn & 0x01;
18025 df = DF_DOUBLE;
18026 } else if (dfn == 0x3E) {
18027 /* CTCMSA, CFCMSA, MOVE.V */
18028 gen_msa_elm_3e(env, ctx);
18029 return;
18030 } else {
18031 generate_exception(ctx, EXCP_RI);
18032 return;
18033 }
18034
18035 gen_msa_elm_df(env, ctx, df, n);
18036}
18037
7d05b9c8
YK
18038static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18039{
18040#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18041 uint8_t df = (ctx->opcode >> 21) & 0x1;
18042 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18043 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18044 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18045
18046 TCGv_i32 twd = tcg_const_i32(wd);
18047 TCGv_i32 tws = tcg_const_i32(ws);
18048 TCGv_i32 twt = tcg_const_i32(wt);
18049 TCGv_i32 tdf = tcg_temp_new_i32();
18050
18051 /* adjust df value for floating-point instruction */
18052 tcg_gen_movi_i32(tdf, df + 2);
18053
18054 switch (MASK_MSA_3RF(ctx->opcode)) {
18055 case OPC_FCAF_df:
18056 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18057 break;
18058 case OPC_FADD_df:
18059 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18060 break;
18061 case OPC_FCUN_df:
18062 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18063 break;
18064 case OPC_FSUB_df:
18065 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18066 break;
18067 case OPC_FCOR_df:
18068 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18069 break;
18070 case OPC_FCEQ_df:
18071 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18072 break;
18073 case OPC_FMUL_df:
18074 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18075 break;
18076 case OPC_FCUNE_df:
18077 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18078 break;
18079 case OPC_FCUEQ_df:
18080 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18081 break;
18082 case OPC_FDIV_df:
18083 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18084 break;
18085 case OPC_FCNE_df:
18086 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18087 break;
18088 case OPC_FCLT_df:
18089 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18090 break;
18091 case OPC_FMADD_df:
18092 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18093 break;
18094 case OPC_MUL_Q_df:
18095 tcg_gen_movi_i32(tdf, df + 1);
18096 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18097 break;
18098 case OPC_FCULT_df:
18099 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18100 break;
18101 case OPC_FMSUB_df:
18102 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18103 break;
18104 case OPC_MADD_Q_df:
18105 tcg_gen_movi_i32(tdf, df + 1);
18106 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18107 break;
18108 case OPC_FCLE_df:
18109 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18110 break;
18111 case OPC_MSUB_Q_df:
18112 tcg_gen_movi_i32(tdf, df + 1);
18113 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18114 break;
18115 case OPC_FCULE_df:
18116 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18117 break;
18118 case OPC_FEXP2_df:
18119 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18120 break;
18121 case OPC_FSAF_df:
18122 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18123 break;
18124 case OPC_FEXDO_df:
18125 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18126 break;
18127 case OPC_FSUN_df:
18128 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18129 break;
18130 case OPC_FSOR_df:
18131 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18132 break;
18133 case OPC_FSEQ_df:
18134 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18135 break;
18136 case OPC_FTQ_df:
18137 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18138 break;
18139 case OPC_FSUNE_df:
18140 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18141 break;
18142 case OPC_FSUEQ_df:
18143 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18144 break;
18145 case OPC_FSNE_df:
18146 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18147 break;
18148 case OPC_FSLT_df:
18149 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18150 break;
18151 case OPC_FMIN_df:
18152 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18153 break;
18154 case OPC_MULR_Q_df:
18155 tcg_gen_movi_i32(tdf, df + 1);
18156 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18157 break;
18158 case OPC_FSULT_df:
18159 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18160 break;
18161 case OPC_FMIN_A_df:
18162 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18163 break;
18164 case OPC_MADDR_Q_df:
18165 tcg_gen_movi_i32(tdf, df + 1);
18166 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18167 break;
18168 case OPC_FSLE_df:
18169 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18170 break;
18171 case OPC_FMAX_df:
18172 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18173 break;
18174 case OPC_MSUBR_Q_df:
18175 tcg_gen_movi_i32(tdf, df + 1);
18176 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18177 break;
18178 case OPC_FSULE_df:
18179 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18180 break;
18181 case OPC_FMAX_A_df:
18182 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18183 break;
18184 default:
18185 MIPS_INVAL("MSA instruction");
18186 generate_exception(ctx, EXCP_RI);
18187 break;
18188 }
18189
18190 tcg_temp_free_i32(twd);
18191 tcg_temp_free_i32(tws);
18192 tcg_temp_free_i32(twt);
18193 tcg_temp_free_i32(tdf);
18194}
18195
cbe50b9a
YK
18196static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18197{
18198#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18199 (op & (0x7 << 18)))
18200 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18201 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18202 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18203 uint8_t df = (ctx->opcode >> 16) & 0x3;
18204 TCGv_i32 twd = tcg_const_i32(wd);
18205 TCGv_i32 tws = tcg_const_i32(ws);
18206 TCGv_i32 twt = tcg_const_i32(wt);
18207 TCGv_i32 tdf = tcg_const_i32(df);
18208
18209 switch (MASK_MSA_2R(ctx->opcode)) {
18210 case OPC_FILL_df:
18211#if !defined(TARGET_MIPS64)
18212 /* Double format valid only for MIPS64 */
18213 if (df == DF_DOUBLE) {
18214 generate_exception(ctx, EXCP_RI);
18215 break;
18216 }
18217#endif
18218 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18219 break;
18220 case OPC_PCNT_df:
18221 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18222 break;
18223 case OPC_NLOC_df:
18224 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18225 break;
18226 case OPC_NLZC_df:
18227 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18228 break;
18229 default:
18230 MIPS_INVAL("MSA instruction");
18231 generate_exception(ctx, EXCP_RI);
18232 break;
18233 }
18234
18235 tcg_temp_free_i32(twd);
18236 tcg_temp_free_i32(tws);
18237 tcg_temp_free_i32(twt);
18238 tcg_temp_free_i32(tdf);
18239}
18240
3bdeb688
YK
18241static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18242{
18243#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18244 (op & (0xf << 17)))
18245 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18246 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18247 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18248 uint8_t df = (ctx->opcode >> 16) & 0x1;
18249 TCGv_i32 twd = tcg_const_i32(wd);
18250 TCGv_i32 tws = tcg_const_i32(ws);
18251 TCGv_i32 twt = tcg_const_i32(wt);
18252 /* adjust df value for floating-point instruction */
18253 TCGv_i32 tdf = tcg_const_i32(df + 2);
18254
18255 switch (MASK_MSA_2RF(ctx->opcode)) {
18256 case OPC_FCLASS_df:
18257 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18258 break;
18259 case OPC_FTRUNC_S_df:
18260 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18261 break;
18262 case OPC_FTRUNC_U_df:
18263 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18264 break;
18265 case OPC_FSQRT_df:
18266 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18267 break;
18268 case OPC_FRSQRT_df:
18269 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18270 break;
18271 case OPC_FRCP_df:
18272 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18273 break;
18274 case OPC_FRINT_df:
18275 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18276 break;
18277 case OPC_FLOG2_df:
18278 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18279 break;
18280 case OPC_FEXUPL_df:
18281 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18282 break;
18283 case OPC_FEXUPR_df:
18284 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18285 break;
18286 case OPC_FFQL_df:
18287 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18288 break;
18289 case OPC_FFQR_df:
18290 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18291 break;
18292 case OPC_FTINT_S_df:
18293 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18294 break;
18295 case OPC_FTINT_U_df:
18296 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18297 break;
18298 case OPC_FFINT_S_df:
18299 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18300 break;
18301 case OPC_FFINT_U_df:
18302 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18303 break;
18304 }
18305
18306 tcg_temp_free_i32(twd);
18307 tcg_temp_free_i32(tws);
18308 tcg_temp_free_i32(twt);
18309 tcg_temp_free_i32(tdf);
18310}
18311
cbe50b9a
YK
18312static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18313{
18314#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18315 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18316 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18317 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18318 TCGv_i32 twd = tcg_const_i32(wd);
18319 TCGv_i32 tws = tcg_const_i32(ws);
18320 TCGv_i32 twt = tcg_const_i32(wt);
18321
18322 switch (MASK_MSA_VEC(ctx->opcode)) {
18323 case OPC_AND_V:
18324 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18325 break;
18326 case OPC_OR_V:
18327 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18328 break;
18329 case OPC_NOR_V:
18330 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18331 break;
18332 case OPC_XOR_V:
18333 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18334 break;
18335 case OPC_BMNZ_V:
18336 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18337 break;
18338 case OPC_BMZ_V:
18339 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18340 break;
18341 case OPC_BSEL_V:
18342 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18343 break;
18344 default:
18345 MIPS_INVAL("MSA instruction");
18346 generate_exception(ctx, EXCP_RI);
18347 break;
18348 }
18349
18350 tcg_temp_free_i32(twd);
18351 tcg_temp_free_i32(tws);
18352 tcg_temp_free_i32(twt);
18353}
18354
18355static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18356{
18357 switch (MASK_MSA_VEC(ctx->opcode)) {
18358 case OPC_AND_V:
18359 case OPC_OR_V:
18360 case OPC_NOR_V:
18361 case OPC_XOR_V:
18362 case OPC_BMNZ_V:
18363 case OPC_BMZ_V:
18364 case OPC_BSEL_V:
18365 gen_msa_vec_v(env, ctx);
18366 break;
18367 case OPC_MSA_2R:
18368 gen_msa_2r(env, ctx);
18369 break;
3bdeb688
YK
18370 case OPC_MSA_2RF:
18371 gen_msa_2rf(env, ctx);
18372 break;
cbe50b9a
YK
18373 default:
18374 MIPS_INVAL("MSA instruction");
18375 generate_exception(ctx, EXCP_RI);
18376 break;
18377 }
18378}
18379
4c789546
YK
18380static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18381{
18382 uint32_t opcode = ctx->opcode;
18383 check_insn(ctx, ASE_MSA);
18384 check_msa_access(ctx);
18385
18386 switch (MASK_MSA_MINOR(opcode)) {
18387 case OPC_MSA_I8_00:
18388 case OPC_MSA_I8_01:
18389 case OPC_MSA_I8_02:
18390 gen_msa_i8(env, ctx);
18391 break;
80e71591
YK
18392 case OPC_MSA_I5_06:
18393 case OPC_MSA_I5_07:
18394 gen_msa_i5(env, ctx);
18395 break;
d4cf28de
YK
18396 case OPC_MSA_BIT_09:
18397 case OPC_MSA_BIT_0A:
18398 gen_msa_bit(env, ctx);
18399 break;
28f99f08
YK
18400 case OPC_MSA_3R_0D:
18401 case OPC_MSA_3R_0E:
18402 case OPC_MSA_3R_0F:
18403 case OPC_MSA_3R_10:
18404 case OPC_MSA_3R_11:
18405 case OPC_MSA_3R_12:
18406 case OPC_MSA_3R_13:
18407 case OPC_MSA_3R_14:
18408 case OPC_MSA_3R_15:
18409 gen_msa_3r(env, ctx);
18410 break;
1e608ec1
YK
18411 case OPC_MSA_ELM:
18412 gen_msa_elm(env, ctx);
18413 break;
7d05b9c8
YK
18414 case OPC_MSA_3RF_1A:
18415 case OPC_MSA_3RF_1B:
18416 case OPC_MSA_3RF_1C:
18417 gen_msa_3rf(env, ctx);
18418 break;
cbe50b9a
YK
18419 case OPC_MSA_VEC:
18420 gen_msa_vec(env, ctx);
18421 break;
f7685877
YK
18422 case OPC_LD_B:
18423 case OPC_LD_H:
18424 case OPC_LD_W:
18425 case OPC_LD_D:
18426 case OPC_ST_B:
18427 case OPC_ST_H:
18428 case OPC_ST_W:
18429 case OPC_ST_D:
18430 {
18431 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18432 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18433 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18434 uint8_t df = (ctx->opcode >> 0) & 0x3;
18435
f7685877 18436 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18437 TCGv taddr = tcg_temp_new();
18438 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18439
18440 switch (MASK_MSA_MINOR(opcode)) {
18441 case OPC_LD_B:
adc370a4
YK
18442 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18443 break;
f7685877 18444 case OPC_LD_H:
adc370a4
YK
18445 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18446 break;
f7685877 18447 case OPC_LD_W:
adc370a4
YK
18448 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18449 break;
f7685877 18450 case OPC_LD_D:
adc370a4 18451 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18452 break;
18453 case OPC_ST_B:
adc370a4
YK
18454 gen_helper_msa_st_b(cpu_env, twd, taddr);
18455 break;
f7685877 18456 case OPC_ST_H:
adc370a4
YK
18457 gen_helper_msa_st_h(cpu_env, twd, taddr);
18458 break;
f7685877 18459 case OPC_ST_W:
adc370a4
YK
18460 gen_helper_msa_st_w(cpu_env, twd, taddr);
18461 break;
f7685877 18462 case OPC_ST_D:
adc370a4 18463 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18464 break;
18465 }
18466
18467 tcg_temp_free_i32(twd);
adc370a4 18468 tcg_temp_free(taddr);
f7685877
YK
18469 }
18470 break;
4c789546
YK
18471 default:
18472 MIPS_INVAL("MSA instruction");
18473 generate_exception(ctx, EXCP_RI);
18474 break;
18475 }
18476
18477}
18478
d2bfa6e6 18479static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18480{
18481 int32_t offset;
18482 int rs, rt, rd, sa;
18483 uint32_t op, op1;
18484 int16_t imm;
18485
18486 /* make sure instructions are on a word boundary */
18487 if (ctx->pc & 0x3) {
18488 env->CP0_BadVAddr = ctx->pc;
aea14095 18489 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
62c68869 18490 ctx->bstate = BS_STOP;
099e5b4d
LA
18491 return;
18492 }
18493
18494 /* Handle blikely not taken case */
18495 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18496 TCGLabel *l1 = gen_new_label();
099e5b4d
LA
18497
18498 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18499 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18500 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18501 gen_goto_tb(ctx, 1, ctx->pc + 4);
18502 gen_set_label(l1);
18503 }
18504
18505 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18506 tcg_gen_debug_insn_start(ctx->pc);
18507 }
18508
18509 op = MASK_OP_MAJOR(ctx->opcode);
18510 rs = (ctx->opcode >> 21) & 0x1f;
18511 rt = (ctx->opcode >> 16) & 0x1f;
18512 rd = (ctx->opcode >> 11) & 0x1f;
18513 sa = (ctx->opcode >> 6) & 0x1f;
18514 imm = (int16_t)ctx->opcode;
18515 switch (op) {
18516 case OPC_SPECIAL:
18517 decode_opc_special(env, ctx);
18518 break;
18519 case OPC_SPECIAL2:
4267d3e6 18520 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18521 break;
18522 case OPC_SPECIAL3:
18523 decode_opc_special3(env, ctx);
18524 break;
7a387fff
TS
18525 case OPC_REGIMM:
18526 op1 = MASK_REGIMM(ctx->opcode);
18527 switch (op1) {
fecd2646
LA
18528 case OPC_BLTZL: /* REGIMM branches */
18529 case OPC_BGEZL:
18530 case OPC_BLTZALL:
18531 case OPC_BGEZALL:
d9224450 18532 check_insn(ctx, ISA_MIPS2);
fecd2646 18533 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18534 /* Fallthrough */
fecd2646
LA
18535 case OPC_BLTZ:
18536 case OPC_BGEZ:
b231c103 18537 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18538 break;
fecd2646
LA
18539 case OPC_BLTZAL:
18540 case OPC_BGEZAL:
0aefa333
YK
18541 if (ctx->insn_flags & ISA_MIPS32R6) {
18542 if (rs == 0) {
18543 /* OPC_NAL, OPC_BAL */
b231c103 18544 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18545 } else {
18546 generate_exception(ctx, EXCP_RI);
18547 }
18548 } else {
b231c103 18549 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18550 }
c9602061 18551 break;
7a387fff
TS
18552 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18553 case OPC_TNEI:
d9224450 18554 check_insn(ctx, ISA_MIPS2);
fecd2646 18555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18556 gen_trap(ctx, op1, rs, -1, imm);
18557 break;
18558 case OPC_SYNCI:
d75c135e 18559 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18560 /* Break the TB to be able to sync copied instructions
18561 immediately */
18562 ctx->bstate = BS_STOP;
6af0bf9c 18563 break;
e45a93e2
JL
18564 case OPC_BPOSGE32: /* MIPS DSP branch */
18565#if defined(TARGET_MIPS64)
18566 case OPC_BPOSGE64:
18567#endif
18568 check_dsp(ctx);
b231c103 18569 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18570 break;
d4ea6acd
LA
18571#if defined(TARGET_MIPS64)
18572 case OPC_DAHI:
18573 check_insn(ctx, ISA_MIPS32R6);
18574 check_mips_64(ctx);
18575 if (rs != 0) {
18576 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18577 }
18578 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18579 break;
18580 case OPC_DATI:
18581 check_insn(ctx, ISA_MIPS32R6);
18582 check_mips_64(ctx);
18583 if (rs != 0) {
18584 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18585 }
18586 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18587 break;
18588#endif
6af0bf9c 18589 default: /* Invalid */
923617a3 18590 MIPS_INVAL("regimm");
6af0bf9c
FB
18591 generate_exception(ctx, EXCP_RI);
18592 break;
18593 }
18594 break;
7a387fff 18595 case OPC_CP0:
387a8fe5 18596 check_cp0_enabled(ctx);
7a387fff 18597 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18598 switch (op1) {
7a387fff
TS
18599 case OPC_MFC0:
18600 case OPC_MTC0:
ead9360e
TS
18601 case OPC_MFTR:
18602 case OPC_MTTR:
d26bc211 18603#if defined(TARGET_MIPS64)
7a387fff
TS
18604 case OPC_DMFC0:
18605 case OPC_DMTC0:
18606#endif
f1aa6320 18607#ifndef CONFIG_USER_ONLY
932e71cd 18608 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 18609#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18610 break;
18611 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 18612#ifndef CONFIG_USER_ONLY
932e71cd 18613 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 18614#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18615 break;
18616 case OPC_MFMC0:
8706c382 18617#ifndef CONFIG_USER_ONLY
932e71cd 18618 {
099e5b4d 18619 uint32_t op2;
35fbce2c 18620 TCGv t0 = tcg_temp_new();
6c5c1e20 18621
0eaef5aa 18622 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
18623 switch (op2) {
18624 case OPC_DMT:
d75c135e 18625 check_insn(ctx, ASE_MT);
9ed5726c 18626 gen_helper_dmt(t0);
35fbce2c 18627 gen_store_gpr(t0, rt);
6c5c1e20
TS
18628 break;
18629 case OPC_EMT:
d75c135e 18630 check_insn(ctx, ASE_MT);
9ed5726c 18631 gen_helper_emt(t0);
35fbce2c 18632 gen_store_gpr(t0, rt);
da80682b 18633 break;
6c5c1e20 18634 case OPC_DVPE:
d75c135e 18635 check_insn(ctx, ASE_MT);
895c2d04 18636 gen_helper_dvpe(t0, cpu_env);
35fbce2c 18637 gen_store_gpr(t0, rt);
6c5c1e20
TS
18638 break;
18639 case OPC_EVPE:
d75c135e 18640 check_insn(ctx, ASE_MT);
895c2d04 18641 gen_helper_evpe(t0, cpu_env);
35fbce2c 18642 gen_store_gpr(t0, rt);
6c5c1e20
TS
18643 break;
18644 case OPC_DI:
d75c135e 18645 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18646 save_cpu_state(ctx, 1);
895c2d04 18647 gen_helper_di(t0, cpu_env);
35fbce2c 18648 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18649 /* Stop translation as we may have switched
18650 the execution mode. */
6c5c1e20
TS
18651 ctx->bstate = BS_STOP;
18652 break;
18653 case OPC_EI:
d75c135e 18654 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18655 save_cpu_state(ctx, 1);
895c2d04 18656 gen_helper_ei(t0, cpu_env);
35fbce2c 18657 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18658 /* Stop translation as we may have switched
18659 the execution mode. */
6c5c1e20
TS
18660 ctx->bstate = BS_STOP;
18661 break;
18662 default: /* Invalid */
18663 MIPS_INVAL("mfmc0");
18664 generate_exception(ctx, EXCP_RI);
18665 break;
18666 }
6c5c1e20 18667 tcg_temp_free(t0);
7a387fff 18668 }
0eaef5aa 18669#endif /* !CONFIG_USER_ONLY */
6af0bf9c 18670 break;
7a387fff 18671 case OPC_RDPGPR:
d75c135e 18672 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18673 gen_load_srsgpr(rt, rd);
ead9360e 18674 break;
7a387fff 18675 case OPC_WRPGPR:
d75c135e 18676 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18677 gen_store_srsgpr(rt, rd);
38121543 18678 break;
6af0bf9c 18679 default:
923617a3 18680 MIPS_INVAL("cp0");
7a387fff 18681 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
18682 break;
18683 }
18684 break;
31837be3
YK
18685 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18686 if (ctx->insn_flags & ISA_MIPS32R6) {
18687 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18688 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18689 } else {
18690 /* OPC_ADDI */
18691 /* Arithmetic with immediate opcode */
18692 gen_arith_imm(ctx, op, rt, rs, imm);
18693 }
18694 break;
324d9e32 18695 case OPC_ADDIU:
d75c135e 18696 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18697 break;
324d9e32
AJ
18698 case OPC_SLTI: /* Set on less than with immediate opcode */
18699 case OPC_SLTIU:
d75c135e 18700 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
18701 break;
18702 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 18703 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
18704 case OPC_ORI:
18705 case OPC_XORI:
d75c135e 18706 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 18707 break;
7a387fff
TS
18708 case OPC_J ... OPC_JAL: /* Jump */
18709 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18710 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 18711 break;
31837be3
YK
18712 /* Branch */
18713 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18714 if (ctx->insn_flags & ISA_MIPS32R6) {
18715 if (rt == 0) {
18716 generate_exception(ctx, EXCP_RI);
18717 break;
18718 }
18719 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18720 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18721 } else {
18722 /* OPC_BLEZL */
b231c103 18723 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18724 }
18725 break;
18726 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18727 if (ctx->insn_flags & ISA_MIPS32R6) {
18728 if (rt == 0) {
18729 generate_exception(ctx, EXCP_RI);
18730 break;
18731 }
18732 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18733 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18734 } else {
18735 /* OPC_BGTZL */
b231c103 18736 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18737 }
18738 break;
18739 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18740 if (rt == 0) {
18741 /* OPC_BLEZ */
b231c103 18742 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18743 } else {
18744 check_insn(ctx, ISA_MIPS32R6);
18745 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18746 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18747 }
18748 break;
18749 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18750 if (rt == 0) {
18751 /* OPC_BGTZ */
b231c103 18752 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18753 } else {
18754 check_insn(ctx, ISA_MIPS32R6);
18755 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18756 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18757 }
18758 break;
18759 case OPC_BEQL:
18760 case OPC_BNEL:
d9224450 18761 check_insn(ctx, ISA_MIPS2);
fecd2646 18762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18763 /* Fallthrough */
31837be3
YK
18764 case OPC_BEQ:
18765 case OPC_BNE:
b231c103 18766 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 18767 break;
d9224450
MR
18768 case OPC_LL: /* Load and stores */
18769 check_insn(ctx, ISA_MIPS2);
18770 /* Fallthrough */
18771 case OPC_LWL:
fecd2646
LA
18772 case OPC_LWR:
18773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18774 /* Fallthrough */
fecd2646
LA
18775 case OPC_LB ... OPC_LH:
18776 case OPC_LW ... OPC_LHU:
d75c135e 18777 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 18778 break;
fecd2646 18779 case OPC_SWL:
7a387fff 18780 case OPC_SWR:
fecd2646 18781 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18782 /* fall through */
fecd2646
LA
18783 case OPC_SB ... OPC_SH:
18784 case OPC_SW:
5c13fdfd 18785 gen_st(ctx, op, rt, rs, imm);
7a387fff 18786 break;
d66c7132 18787 case OPC_SC:
d9224450 18788 check_insn(ctx, ISA_MIPS2);
4368b29a 18789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
18790 gen_st_cond(ctx, op, rt, rs, imm);
18791 break;
7a387fff 18792 case OPC_CACHE:
bf7910c6 18793 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 18794 check_cp0_enabled(ctx);
d75c135e 18795 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 18796 /* Treat as NOP. */
34ae7b51 18797 break;
7a387fff 18798 case OPC_PREF:
bf7910c6 18799 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18800 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 18801 /* Treat as NOP. */
6af0bf9c 18802 break;
4ad40f36 18803
923617a3 18804 /* Floating point (COP1). */
7a387fff
TS
18805 case OPC_LWC1:
18806 case OPC_LDC1:
18807 case OPC_SWC1:
18808 case OPC_SDC1:
5ab5c041 18809 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
18810 break;
18811
7a387fff 18812 case OPC_CP1:
5692c6e1
YK
18813 op1 = MASK_CP1(ctx->opcode);
18814
18815 switch (op1) {
18816 case OPC_MFHC1:
18817 case OPC_MTHC1:
5e755519 18818 check_cp1_enabled(ctx);
5692c6e1
YK
18819 check_insn(ctx, ISA_MIPS32R2);
18820 case OPC_MFC1:
18821 case OPC_CFC1:
18822 case OPC_MTC1:
18823 case OPC_CTC1:
18824 check_cp1_enabled(ctx);
18825 gen_cp1(ctx, op1, rt, rd);
18826 break;
d26bc211 18827#if defined(TARGET_MIPS64)
5692c6e1
YK
18828 case OPC_DMFC1:
18829 case OPC_DMTC1:
18830 check_cp1_enabled(ctx);
18831 check_insn(ctx, ISA_MIPS3);
d9224450 18832 check_mips_64(ctx);
5692c6e1
YK
18833 gen_cp1(ctx, op1, rt, rd);
18834 break;
e189e748 18835#endif
5692c6e1
YK
18836 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18837 check_cp1_enabled(ctx);
18838 if (ctx->insn_flags & ISA_MIPS32R6) {
18839 /* OPC_BC1EQZ */
31837be3
YK
18840 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18841 rt, imm << 2);
5692c6e1
YK
18842 } else {
18843 /* OPC_BC1ANY2 */
b8aa4598 18844 check_cop1x(ctx);
d75c135e 18845 check_insn(ctx, ASE_MIPS3D);
d75c135e 18846 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 18847 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
18848 }
18849 break;
18850 case OPC_BC1NEZ:
18851 check_cp1_enabled(ctx);
18852 check_insn(ctx, ISA_MIPS32R6);
18853 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18854 rt, imm << 2);
18855 break;
18856 case OPC_BC1ANY4:
18857 check_cp1_enabled(ctx);
18858 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18859 check_cop1x(ctx);
18860 check_insn(ctx, ASE_MIPS3D);
18861 /* fall through */
18862 case OPC_BC1:
18863 check_cp1_enabled(ctx);
18864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18865 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18866 (rt >> 2) & 0x7, imm << 2);
18867 break;
18868 case OPC_PS_FMT:
18869 check_cp1_enabled(ctx);
18870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 18871 /* fall through */
5692c6e1
YK
18872 case OPC_S_FMT:
18873 case OPC_D_FMT:
18874 check_cp1_enabled(ctx);
18875 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18876 (imm >> 8) & 0x7);
18877 break;
18878 case OPC_W_FMT:
18879 case OPC_L_FMT:
18880 {
18881 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18882 check_cp1_enabled(ctx);
18883 if (ctx->insn_flags & ISA_MIPS32R6) {
18884 switch (r6_op) {
18885 case R6_OPC_CMP_AF_S:
18886 case R6_OPC_CMP_UN_S:
18887 case R6_OPC_CMP_EQ_S:
18888 case R6_OPC_CMP_UEQ_S:
18889 case R6_OPC_CMP_LT_S:
18890 case R6_OPC_CMP_ULT_S:
18891 case R6_OPC_CMP_LE_S:
18892 case R6_OPC_CMP_ULE_S:
18893 case R6_OPC_CMP_SAF_S:
18894 case R6_OPC_CMP_SUN_S:
18895 case R6_OPC_CMP_SEQ_S:
18896 case R6_OPC_CMP_SEUQ_S:
18897 case R6_OPC_CMP_SLT_S:
18898 case R6_OPC_CMP_SULT_S:
18899 case R6_OPC_CMP_SLE_S:
18900 case R6_OPC_CMP_SULE_S:
18901 case R6_OPC_CMP_OR_S:
18902 case R6_OPC_CMP_UNE_S:
18903 case R6_OPC_CMP_NE_S:
18904 case R6_OPC_CMP_SOR_S:
18905 case R6_OPC_CMP_SUNE_S:
18906 case R6_OPC_CMP_SNE_S:
18907 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18908 break;
18909 case R6_OPC_CMP_AF_D:
18910 case R6_OPC_CMP_UN_D:
18911 case R6_OPC_CMP_EQ_D:
18912 case R6_OPC_CMP_UEQ_D:
18913 case R6_OPC_CMP_LT_D:
18914 case R6_OPC_CMP_ULT_D:
18915 case R6_OPC_CMP_LE_D:
18916 case R6_OPC_CMP_ULE_D:
18917 case R6_OPC_CMP_SAF_D:
18918 case R6_OPC_CMP_SUN_D:
18919 case R6_OPC_CMP_SEQ_D:
18920 case R6_OPC_CMP_SEUQ_D:
18921 case R6_OPC_CMP_SLT_D:
18922 case R6_OPC_CMP_SULT_D:
18923 case R6_OPC_CMP_SLE_D:
18924 case R6_OPC_CMP_SULE_D:
18925 case R6_OPC_CMP_OR_D:
18926 case R6_OPC_CMP_UNE_D:
18927 case R6_OPC_CMP_NE_D:
18928 case R6_OPC_CMP_SOR_D:
18929 case R6_OPC_CMP_SUNE_D:
18930 case R6_OPC_CMP_SNE_D:
18931 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18932 break;
18933 default:
d2bfa6e6
MR
18934 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
18935 rt, rd, sa, (imm >> 8) & 0x7);
18936
5692c6e1 18937 break;
3f493883 18938 }
5692c6e1
YK
18939 } else {
18940 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18941 (imm >> 8) & 0x7);
36d23958 18942 }
5692c6e1
YK
18943 break;
18944 }
18945 case OPC_BZ_V:
18946 case OPC_BNZ_V:
18947 case OPC_BZ_B:
18948 case OPC_BZ_H:
18949 case OPC_BZ_W:
18950 case OPC_BZ_D:
18951 case OPC_BNZ_B:
18952 case OPC_BNZ_H:
18953 case OPC_BNZ_W:
18954 case OPC_BNZ_D:
18955 check_insn(ctx, ASE_MSA);
18956 gen_msa_branch(env, ctx, op1);
18957 break;
18958 default:
18959 MIPS_INVAL("cp1");
18960 generate_exception(ctx, EXCP_RI);
18961 break;
6ea83fed 18962 }
4ad40f36
FB
18963 break;
18964
31837be3
YK
18965 /* Compact branches [R6] and COP2 [non-R6] */
18966 case OPC_BC: /* OPC_LWC2 */
18967 case OPC_BALC: /* OPC_SWC2 */
18968 if (ctx->insn_flags & ISA_MIPS32R6) {
18969 /* OPC_BC, OPC_BALC */
18970 gen_compute_compact_branch(ctx, op, 0, 0,
18971 sextract32(ctx->opcode << 2, 0, 28));
18972 } else {
18973 /* OPC_LWC2, OPC_SWC2 */
18974 /* COP2: Not implemented. */
18975 generate_exception_err(ctx, EXCP_CpU, 2);
18976 }
18977 break;
18978 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18979 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
18980 if (ctx->insn_flags & ISA_MIPS32R6) {
18981 if (rs != 0) {
18982 /* OPC_BEQZC, OPC_BNEZC */
18983 gen_compute_compact_branch(ctx, op, rs, 0,
18984 sextract32(ctx->opcode << 2, 0, 23));
18985 } else {
18986 /* OPC_JIC, OPC_JIALC */
18987 gen_compute_compact_branch(ctx, op, 0, rt, imm);
18988 }
18989 } else {
18990 /* OPC_LWC2, OPC_SWC2 */
18991 /* COP2: Not implemented. */
18992 generate_exception_err(ctx, EXCP_CpU, 2);
18993 }
4ad40f36 18994 break;
bd277fa1 18995 case OPC_CP2:
d75c135e 18996 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
18997 /* Note that these instructions use different fields. */
18998 gen_loongson_multimedia(ctx, sa, rd, rt);
18999 break;
4ad40f36 19000
7a387fff 19001 case OPC_CP3:
fecd2646 19002 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19003 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19004 check_cp1_enabled(ctx);
36d23958
TS
19005 op1 = MASK_CP3(ctx->opcode);
19006 switch (op1) {
d9224450
MR
19007 case OPC_LUXC1:
19008 case OPC_SUXC1:
19009 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19010 /* Fallthrough */
5a5012ec
TS
19011 case OPC_LWXC1:
19012 case OPC_LDXC1:
5a5012ec
TS
19013 case OPC_SWXC1:
19014 case OPC_SDXC1:
d9224450 19015 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19016 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19017 break;
e0c84da7 19018 case OPC_PREFX:
d9224450 19019 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19020 /* Treat as NOP. */
e0c84da7 19021 break;
5a5012ec 19022 case OPC_ALNV_PS:
d9224450
MR
19023 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19024 /* Fallthrough */
5a5012ec
TS
19025 case OPC_MADD_S:
19026 case OPC_MADD_D:
19027 case OPC_MADD_PS:
19028 case OPC_MSUB_S:
19029 case OPC_MSUB_D:
19030 case OPC_MSUB_PS:
19031 case OPC_NMADD_S:
19032 case OPC_NMADD_D:
19033 case OPC_NMADD_PS:
19034 case OPC_NMSUB_S:
19035 case OPC_NMSUB_D:
19036 case OPC_NMSUB_PS:
d9224450 19037 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19038 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19039 break;
36d23958 19040 default:
923617a3 19041 MIPS_INVAL("cp3");
e397ee33 19042 generate_exception (ctx, EXCP_RI);
36d23958
TS
19043 break;
19044 }
19045 } else {
e397ee33 19046 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19047 }
4ad40f36
FB
19048 break;
19049
d26bc211 19050#if defined(TARGET_MIPS64)
7a387fff 19051 /* MIPS64 opcodes */
7a387fff 19052 case OPC_LDL ... OPC_LDR:
bf7910c6 19053 case OPC_LLD:
fecd2646 19054 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19055 /* fall through */
fecd2646 19056 case OPC_LWU:
7a387fff 19057 case OPC_LD:
d75c135e 19058 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19059 check_mips_64(ctx);
d75c135e 19060 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19061 break;
19062 case OPC_SDL ... OPC_SDR:
fecd2646 19063 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19064 /* fall through */
7a387fff 19065 case OPC_SD:
d75c135e 19066 check_insn(ctx, ISA_MIPS3);
e189e748 19067 check_mips_64(ctx);
5c13fdfd 19068 gen_st(ctx, op, rt, rs, imm);
7a387fff 19069 break;
d66c7132 19070 case OPC_SCD:
bf7910c6 19071 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19072 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19073 check_mips_64(ctx);
19074 gen_st_cond(ctx, op, rt, rs, imm);
19075 break;
31837be3
YK
19076 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19077 if (ctx->insn_flags & ISA_MIPS32R6) {
19078 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19079 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19080 } else {
19081 /* OPC_DADDI */
19082 check_insn(ctx, ISA_MIPS3);
19083 check_mips_64(ctx);
19084 gen_arith_imm(ctx, op, rt, rs, imm);
19085 }
19086 break;
324d9e32 19087 case OPC_DADDIU:
d75c135e 19088 check_insn(ctx, ISA_MIPS3);
e189e748 19089 check_mips_64(ctx);
d75c135e 19090 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19091 break;
31837be3
YK
19092#else
19093 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19094 if (ctx->insn_flags & ISA_MIPS32R6) {
19095 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19096 } else {
19097 MIPS_INVAL("major opcode");
19098 generate_exception(ctx, EXCP_RI);
19099 }
19100 break;
6af0bf9c 19101#endif
d4ea6acd
LA
19102 case OPC_DAUI: /* OPC_JALX */
19103 if (ctx->insn_flags & ISA_MIPS32R6) {
19104#if defined(TARGET_MIPS64)
19105 /* OPC_DAUI */
19106 check_mips_64(ctx);
19107 if (rt != 0) {
19108 TCGv t0 = tcg_temp_new();
19109 gen_load_gpr(t0, rs);
19110 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19111 tcg_temp_free(t0);
19112 }
19113 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19114#else
19115 generate_exception(ctx, EXCP_RI);
19116 MIPS_INVAL("major opcode");
19117#endif
19118 } else {
19119 /* OPC_JALX */
19120 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19121 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19122 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19123 }
364d4831 19124 break;
4c789546 19125 case OPC_MSA: /* OPC_MDMX */
7a387fff 19126 /* MDMX: Not implemented. */
4c789546 19127 gen_msa(env, ctx);
d4ea6acd
LA
19128 break;
19129 case OPC_PCREL:
19130 check_insn(ctx, ISA_MIPS32R6);
19131 gen_pcrel(ctx, rs, imm);
19132 break;
6af0bf9c 19133 default: /* Invalid */
923617a3 19134 MIPS_INVAL("major opcode");
6af0bf9c
FB
19135 generate_exception(ctx, EXCP_RI);
19136 break;
19137 }
6af0bf9c
FB
19138}
19139
2cfc5f17 19140static inline void
6429db34
AF
19141gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19142 bool search_pc)
6af0bf9c 19143{
ed2803da 19144 CPUState *cs = CPU(cpu);
6429db34 19145 CPUMIPSState *env = &cpu->env;
278d0702 19146 DisasContext ctx;
6af0bf9c 19147 target_ulong pc_start;
fe237291 19148 target_ulong next_page_start;
a1d1bb31 19149 CPUBreakpoint *bp;
6af0bf9c 19150 int j, lj = -1;
2e70f6ef
PB
19151 int num_insns;
19152 int max_insns;
c9602061 19153 int insn_bytes;
339cd2a8 19154 int is_slot;
6af0bf9c 19155
93fcfe39
AL
19156 if (search_pc)
19157 qemu_log("search pc %d\n", search_pc);
4ad40f36 19158
6af0bf9c 19159 pc_start = tb->pc;
fe237291 19160 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19161 ctx.pc = pc_start;
4ad40f36 19162 ctx.saved_pc = -1;
ed2803da 19163 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19164 ctx.insn_flags = env->insn_flags;
5ab5c041 19165 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19166 ctx.tb = tb;
19167 ctx.bstate = BS_NONE;
e98c0d17 19168 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19169 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19170 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19171 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19172 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 19173 /* Restore delay slot state from the tb context. */
c068688b 19174 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19175 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
fd4a04eb 19176 restore_cpu_state(env, &ctx);
932e71cd 19177#ifdef CONFIG_USER_ONLY
0eaef5aa 19178 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19179#else
0eaef5aa 19180 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19181#endif
be3a8c53
YK
19182 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19183 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19184 num_insns = 0;
19185 max_insns = tb->cflags & CF_COUNT_MASK;
19186 if (max_insns == 0)
19187 max_insns = CF_COUNT_MASK;
d12d51d5 19188 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19189 gen_tb_start(tb);
faf7aaa9 19190 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19191 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19192 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19193 if (bp->pc == ctx.pc) {
278d0702 19194 save_cpu_state(&ctx, 1);
4ad40f36 19195 ctx.bstate = BS_BRANCH;
895c2d04 19196 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
19197 /* Include the breakpoint location or the tb won't
19198 * be flushed when it must be. */
19199 ctx.pc += 4;
4ad40f36
FB
19200 goto done_generating;
19201 }
19202 }
19203 }
19204
6af0bf9c 19205 if (search_pc) {
fe700adb 19206 j = tcg_op_buf_count();
6af0bf9c
FB
19207 if (lj < j) {
19208 lj++;
19209 while (lj < j)
ab1103de 19210 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19211 }
25983cad 19212 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19213 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19214 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19215 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19216 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19217 }
2e70f6ef
PB
19218 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19219 gen_io_start();
c9602061 19220
339cd2a8 19221 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19222 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19223 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19224 insn_bytes = 4;
240ce26a 19225 decode_opc(env, &ctx);
d75c135e 19226 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19227 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19228 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19229 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19230 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19231 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
19232 } else {
19233 generate_exception(&ctx, EXCP_RI);
3c824109 19234 ctx.bstate = BS_STOP;
c9602061
NF
19235 break;
19236 }
31837be3 19237
b231c103 19238 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19239 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19240 MIPS_HFLAG_FBNSLOT))) {
19241 /* force to generate branch as there is neither delay nor
19242 forbidden slot */
19243 is_slot = 1;
b231c103
YK
19244 }
19245 }
339cd2a8 19246 if (is_slot) {
31837be3 19247 gen_branch(&ctx, insn_bytes);
c9602061
NF
19248 }
19249 ctx.pc += insn_bytes;
19250
2e70f6ef 19251 num_insns++;
4ad40f36 19252
7b270ef2
NF
19253 /* Execute a branch and its delay slot as a single instruction.
19254 This is what GDB expects and is consistent with what the
19255 hardware does (e.g. if a delay slot instruction faults, the
19256 reported PC is the PC of the branch). */
ed2803da 19257 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19258 break;
ed2803da 19259 }
4ad40f36 19260
fe237291 19261 if (ctx.pc >= next_page_start) {
6af0bf9c 19262 break;
fe237291 19263 }
4ad40f36 19264
fe700adb 19265 if (tcg_op_buf_full()) {
faf7aaa9 19266 break;
efd7f486 19267 }
faf7aaa9 19268
2e70f6ef
PB
19269 if (num_insns >= max_insns)
19270 break;
1b530a6d
AJ
19271
19272 if (singlestep)
19273 break;
6af0bf9c 19274 }
ed2803da 19275 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19276 gen_io_end();
ed2803da
AF
19277 }
19278 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19279 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 19280 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 19281 } else {
6958549d 19282 switch (ctx.bstate) {
16c00cb2 19283 case BS_STOP:
df1561e2
TS
19284 gen_goto_tb(&ctx, 0, ctx.pc);
19285 break;
16c00cb2 19286 case BS_NONE:
278d0702 19287 save_cpu_state(&ctx, 0);
16c00cb2
TS
19288 gen_goto_tb(&ctx, 0, ctx.pc);
19289 break;
5a5012ec 19290 case BS_EXCP:
57fec1fe 19291 tcg_gen_exit_tb(0);
16c00cb2 19292 break;
5a5012ec
TS
19293 case BS_BRANCH:
19294 default:
19295 break;
6958549d 19296 }
6af0bf9c 19297 }
4ad40f36 19298done_generating:
806f352d 19299 gen_tb_end(tb, num_insns);
0a7df5da 19300
6af0bf9c 19301 if (search_pc) {
fe700adb 19302 j = tcg_op_buf_count();
6af0bf9c
FB
19303 lj++;
19304 while (lj <= j)
ab1103de 19305 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19306 } else {
19307 tb->size = ctx.pc - pc_start;
2e70f6ef 19308 tb->icount = num_insns;
6af0bf9c
FB
19309 }
19310#ifdef DEBUG_DISAS
d12d51d5 19311 LOG_DISAS("\n");
8fec2b8c 19312 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19313 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 19314 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19315 qemu_log("\n");
6af0bf9c
FB
19316 }
19317#endif
6af0bf9c
FB
19318}
19319
7db13fae 19320void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19321{
6429db34 19322 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19323}
19324
7db13fae 19325void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19326{
6429db34 19327 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19328}
19329
7db13fae 19330static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19331 int flags)
6ea83fed
FB
19332{
19333 int i;
5e755519 19334 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19335
2a5612e6
SW
19336#define printfpr(fp) \
19337 do { \
19338 if (is_fpu64) \
19339 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19340 " fd:%13g fs:%13g psu: %13g\n", \
19341 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19342 (double)(fp)->fd, \
19343 (double)(fp)->fs[FP_ENDIAN_IDX], \
19344 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19345 else { \
19346 fpr_t tmp; \
19347 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19348 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19349 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19350 " fd:%13g fs:%13g psu:%13g\n", \
19351 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19352 (double)tmp.fd, \
19353 (double)tmp.fs[FP_ENDIAN_IDX], \
19354 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19355 } \
6ea83fed
FB
19356 } while(0)
19357
5a5012ec 19358
9a78eead
SW
19359 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19360 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19361 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19362 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19363 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19364 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19365 }
19366
19367#undef printfpr
19368}
19369
d26bc211 19370#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 19371/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 19372 sign-extended values on 64bit machines. */
c570fd16
TS
19373
19374#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19375
8706c382 19376static void
7db13fae 19377cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 19378 fprintf_function cpu_fprintf,
8706c382 19379 int flags)
c570fd16
TS
19380{
19381 int i;
19382
b5dc7732
TS
19383 if (!SIGN_EXT_P(env->active_tc.PC))
19384 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19385 if (!SIGN_EXT_P(env->active_tc.HI[0]))
19386 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19387 if (!SIGN_EXT_P(env->active_tc.LO[0]))
19388 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 19389 if (!SIGN_EXT_P(env->btarget))
3594c774 19390 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
19391
19392 for (i = 0; i < 32; i++) {
b5dc7732
TS
19393 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19394 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
19395 }
19396
19397 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 19398 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
19399 if (!SIGN_EXT_P(env->lladdr))
19400 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
19401}
19402#endif
19403
878096ee
AF
19404void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19405 int flags)
6af0bf9c 19406{
878096ee
AF
19407 MIPSCPU *cpu = MIPS_CPU(cs);
19408 CPUMIPSState *env = &cpu->env;
6af0bf9c 19409 int i;
3b46e624 19410
a7200c9f
SW
19411 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19412 " LO=0x" TARGET_FMT_lx " ds %04x "
19413 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19414 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19415 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19416 for (i = 0; i < 32; i++) {
19417 if ((i & 3) == 0)
19418 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19419 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19420 if ((i & 3) == 3)
19421 cpu_fprintf(f, "\n");
19422 }
568b600d 19423
3594c774 19424 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19425 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 19426 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 19427 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19428 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19429 env->CP0_Config2, env->CP0_Config3);
19430 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19431 env->CP0_Config4, env->CP0_Config5);
5e755519 19432 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19433 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 19434#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
19435 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19436#endif
6af0bf9c
FB
19437}
19438
78ce64f4 19439void mips_tcg_init(void)
39454628 19440{
f01be154 19441 int i;
39454628
TS
19442 static int inited;
19443
19444 /* Initialize various static tables. */
19445 if (inited)
6958549d 19446 return;
39454628 19447
a7812ae4 19448 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19449 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19450 for (i = 1; i < 32; i++)
a7812ae4 19451 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19452 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19453 regnames[i]);
d73ee8a2 19454
863f264d
YK
19455 for (i = 0; i < 32; i++) {
19456 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19457 msa_wr_d[i * 2] =
19458 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19459 /* The scalar floating-point unit (FPU) registers are mapped on
19460 * the MSA vector registers. */
19461 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19462 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19463 msa_wr_d[i * 2 + 1] =
19464 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19465 }
19466
a7812ae4 19467 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19468 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19469 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19470 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19471 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19472 regnames_HI[i]);
a7812ae4 19473 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19474 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19475 regnames_LO[i]);
4b2eb8d2 19476 }
a7812ae4 19477 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19478 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19479 "DSPControl");
1ba74fb8 19480 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19481 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19482 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19483 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19484 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19485 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19486
a7812ae4 19487 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19488 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19489 "fcr0");
19490 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19491 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19492 "fcr31");
39454628
TS
19493
19494 inited = 1;
19495}
19496
aaed909a
FB
19497#include "translate_init.c"
19498
30bf942d 19499MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19500{
0f71a709 19501 MIPSCPU *cpu;
6af0bf9c 19502 CPUMIPSState *env;
c227f099 19503 const mips_def_t *def;
6af0bf9c 19504
aaed909a
FB
19505 def = cpu_mips_find_by_name(cpu_model);
19506 if (!def)
19507 return NULL;
0f71a709
AF
19508 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19509 env = &cpu->env;
aaed909a
FB
19510 env->cpu_model = def;
19511
51cc2e78
BS
19512#ifndef CONFIG_USER_ONLY
19513 mmu_init(env, def);
19514#endif
19515 fpu_init(env, def);
19516 mvp_init(env, def);
c1caf1d9
AF
19517
19518 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19519
30bf942d 19520 return cpu;
6ae81775
TS
19521}
19522
1bba0dc9 19523void cpu_state_reset(CPUMIPSState *env)
6ae81775 19524{
55e5c285
AF
19525 MIPSCPU *cpu = mips_env_get_cpu(env);
19526 CPUState *cs = CPU(cpu);
6ae81775 19527
51cc2e78
BS
19528 /* Reset registers to their default values */
19529 env->CP0_PRid = env->cpu_model->CP0_PRid;
19530 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19531#ifdef TARGET_WORDS_BIGENDIAN
19532 env->CP0_Config0 |= (1 << CP0C0_BE);
19533#endif
19534 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19535 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19536 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19537 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19538 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19539 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19540 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19541 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19542 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19543 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19544 << env->cpu_model->CP0_LLAddr_shift;
19545 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19546 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19547 env->CCRes = env->cpu_model->CCRes;
19548 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19549 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19550 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19551 env->current_tc = 0;
19552 env->SEGBITS = env->cpu_model->SEGBITS;
19553 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19554#if defined(TARGET_MIPS64)
19555 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19556 env->SEGMask |= 3ULL << 62;
19557 }
19558#endif
19559 env->PABITS = env->cpu_model->PABITS;
19560 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19561 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19562 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19563 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19564 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19565 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19566 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19567 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19568 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19569 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19570 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19571 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19572 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19573 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19574 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19575 env->insn_flags = env->cpu_model->insn_flags;
19576
0eaef5aa 19577#if defined(CONFIG_USER_ONLY)
03e6e501 19578 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19579# ifdef TARGET_MIPS64
19580 /* Enable 64-bit register mode. */
19581 env->CP0_Status |= (1 << CP0St_PX);
19582# endif
19583# ifdef TARGET_ABI_MIPSN64
19584 /* Enable 64-bit address mode. */
19585 env->CP0_Status |= (1 << CP0St_UX);
19586# endif
94159135
MI
19587 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19588 hardware registers. */
19589 env->CP0_HWREna |= 0x0000000F;
91a75935 19590 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19591 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19592 }
6f0af304
PJ
19593 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19594 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19595 }
4d66261f
PJ
19596# if defined(TARGET_MIPS64)
19597 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19598 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19599 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19600 env->CP0_Status |= (1 << CP0St_FR);
19601 }
4d66261f 19602# endif
932e71cd
AJ
19603#else
19604 if (env->hflags & MIPS_HFLAG_BMASK) {
19605 /* If the exception was raised from a delay slot,
19606 come back to the jump. */
c3577479
MR
19607 env->CP0_ErrorEPC = (env->active_tc.PC
19608 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 19609 } else {
932e71cd
AJ
19610 env->CP0_ErrorEPC = env->active_tc.PC;
19611 }
19612 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19613 env->CP0_Random = env->tlb->nb_tlb - 1;
19614 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19615 env->CP0_Wired = 0;
0a2672b7
JH
19616 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19617 if (kvm_enabled()) {
19618 env->CP0_EBase |= 0x40000000;
19619 } else {
19620 env->CP0_EBase |= 0x80000000;
19621 }
932e71cd
AJ
19622 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19623 /* vectored interrupts not implemented, timer on int 7,
19624 no performance counters. */
19625 env->CP0_IntCtl = 0xe0000000;
19626 {
19627 int i;
19628
19629 for (i = 0; i < 7; i++) {
19630 env->CP0_WatchLo[i] = 0;
19631 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 19632 }
932e71cd
AJ
19633 env->CP0_WatchLo[7] = 0;
19634 env->CP0_WatchHi[7] = 0;
fd88b6ab 19635 }
932e71cd
AJ
19636 /* Count register increments in debug mode, EJTAG version 1 */
19637 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 19638
4b69c7e2
JH
19639 cpu_mips_store_count(env, 1);
19640
9e56e756
EI
19641 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19642 int i;
19643
19644 /* Only TC0 on VPE 0 starts as active. */
19645 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 19646 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
19647 env->tcs[i].CP0_TCHalt = 1;
19648 }
19649 env->active_tc.CP0_TCHalt = 1;
259186a7 19650 cs->halted = 1;
9e56e756 19651
55e5c285 19652 if (cs->cpu_index == 0) {
9e56e756
EI
19653 /* VPE0 starts up enabled. */
19654 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19655 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19656
19657 /* TC0 starts up unhalted. */
259186a7 19658 cs->halted = 0;
9e56e756
EI
19659 env->active_tc.CP0_TCHalt = 0;
19660 env->tcs[0].CP0_TCHalt = 0;
19661 /* With thread 0 active. */
19662 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19663 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19664 }
19665 }
51cc2e78 19666#endif
ddc584bd
LA
19667 if ((env->insn_flags & ISA_MIPS32R6) &&
19668 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19669 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19670 env->CP0_Status |= (1 << CP0St_FR);
19671 }
19672
863f264d
YK
19673 /* MSA */
19674 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19675 msa_reset(env);
19676 }
19677
03e6e501 19678 compute_hflags(env);
bb962386
MR
19679 restore_rounding_mode(env);
19680 restore_flush_mode(env);
27103424 19681 cs->exception_index = EXCP_NONE;
6af0bf9c 19682}
d2856f1a 19683
7db13fae 19684void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 19685{
25983cad 19686 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
19687 env->hflags &= ~MIPS_HFLAG_BMASK;
19688 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
19689 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19690 case MIPS_HFLAG_BR:
19691 break;
19692 case MIPS_HFLAG_BC:
19693 case MIPS_HFLAG_BL:
19694 case MIPS_HFLAG_B:
19695 env->btarget = gen_opc_btarget[pc_pos];
19696 break;
19697 }
d2856f1a 19698}
This page took 4.190108 seconds and 4 git commands to generate.