]> Git Repo - qemu.git/blame - target-mips/translate.c
target-*: Unconditionally emit tcg_gen_insn_start
[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"
3b3c1694 32#include "exec/semihost.h"
a7812ae4 33
a7e30d84
LV
34#include "trace-tcg.h"
35
fb7729e2 36#define MIPS_DEBUG_DISAS 0
6af0bf9c 37
7a387fff
TS
38/* MIPS major opcodes */
39#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
40
41enum {
42 /* indirect opcode tables */
7a387fff
TS
43 OPC_SPECIAL = (0x00 << 26),
44 OPC_REGIMM = (0x01 << 26),
45 OPC_CP0 = (0x10 << 26),
46 OPC_CP1 = (0x11 << 26),
47 OPC_CP2 = (0x12 << 26),
48 OPC_CP3 = (0x13 << 26),
49 OPC_SPECIAL2 = (0x1C << 26),
50 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 51 /* arithmetic with immediate */
7a387fff
TS
52 OPC_ADDI = (0x08 << 26),
53 OPC_ADDIU = (0x09 << 26),
54 OPC_SLTI = (0x0A << 26),
55 OPC_SLTIU = (0x0B << 26),
324d9e32 56 /* logic with immediate */
7a387fff
TS
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
324d9e32 61 /* arithmetic with immediate */
7a387fff
TS
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
e37e863f 64 /* Jump and branches */
7a387fff
TS
65 OPC_J = (0x02 << 26),
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
b231c103 75 OPC_JALX = (0x1D << 26),
d4ea6acd 76 OPC_DAUI = (0x1D << 26),
e37e863f 77 /* Load and stores */
7a387fff
TS
78 OPC_LDL = (0x1A << 26),
79 OPC_LDR = (0x1B << 26),
80 OPC_LB = (0x20 << 26),
81 OPC_LH = (0x21 << 26),
82 OPC_LWL = (0x22 << 26),
83 OPC_LW = (0x23 << 26),
364d4831 84 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
85 OPC_LBU = (0x24 << 26),
86 OPC_LHU = (0x25 << 26),
87 OPC_LWR = (0x26 << 26),
88 OPC_LWU = (0x27 << 26),
89 OPC_SB = (0x28 << 26),
90 OPC_SH = (0x29 << 26),
91 OPC_SWL = (0x2A << 26),
92 OPC_SW = (0x2B << 26),
93 OPC_SDL = (0x2C << 26),
94 OPC_SDR = (0x2D << 26),
95 OPC_SWR = (0x2E << 26),
96 OPC_LL = (0x30 << 26),
97 OPC_LLD = (0x34 << 26),
98 OPC_LD = (0x37 << 26),
364d4831 99 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
e37e863f 103 /* Floating point load/store */
7a387fff
TS
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
31837be3
YK
112 /* Compact Branches */
113 OPC_BLEZALC = (0x06 << 26),
114 OPC_BGEZALC = (0x06 << 26),
115 OPC_BGEUC = (0x06 << 26),
116 OPC_BGTZALC = (0x07 << 26),
117 OPC_BLTZALC = (0x07 << 26),
118 OPC_BLTUC = (0x07 << 26),
119 OPC_BOVC = (0x08 << 26),
120 OPC_BEQZALC = (0x08 << 26),
121 OPC_BEQC = (0x08 << 26),
122 OPC_BLEZC = (0x16 << 26),
123 OPC_BGEZC = (0x16 << 26),
124 OPC_BGEC = (0x16 << 26),
125 OPC_BGTZC = (0x17 << 26),
126 OPC_BLTZC = (0x17 << 26),
127 OPC_BLTC = (0x17 << 26),
128 OPC_BNVC = (0x18 << 26),
129 OPC_BNEZALC = (0x18 << 26),
130 OPC_BNEC = (0x18 << 26),
131 OPC_BC = (0x32 << 26),
132 OPC_BEQZC = (0x36 << 26),
133 OPC_JIC = (0x36 << 26),
134 OPC_BALC = (0x3A << 26),
135 OPC_BNEZC = (0x3E << 26),
136 OPC_JIALC = (0x3E << 26),
7a387fff
TS
137 /* MDMX ASE specific */
138 OPC_MDMX = (0x1E << 26),
239dfebe
YK
139 /* MSA ASE, same as MDMX */
140 OPC_MSA = OPC_MDMX,
e37e863f 141 /* Cache and prefetch */
7a387fff
TS
142 OPC_CACHE = (0x2F << 26),
143 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
144 /* PC-relative address computation / loads */
145 OPC_PCREL = (0x3B << 26),
146};
147
148/* PC-relative address computation / loads */
149#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
150#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
151enum {
152 /* Instructions determined by bits 19 and 20 */
153 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
154 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
155 OPC_LWUPC = OPC_PCREL | (2 << 19),
156
157 /* Instructions determined by bits 16 ... 20 */
158 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
159 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
160
161 /* Other */
162 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
163};
164
165/* MIPS special opcodes */
7a387fff
TS
166#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
167
e37e863f
FB
168enum {
169 /* Shifts */
7a387fff 170 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
171 /* NOP is SLL r0, r0, 0 */
172 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
173 /* EHB is SLL r0, r0, 3 */
174 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 175 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
176 OPC_SRA = 0x03 | OPC_SPECIAL,
177 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 178 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 179 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
180 OPC_SRAV = 0x07 | OPC_SPECIAL,
181 OPC_DSLLV = 0x14 | OPC_SPECIAL,
182 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 183 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
184 OPC_DSRAV = 0x17 | OPC_SPECIAL,
185 OPC_DSLL = 0x38 | OPC_SPECIAL,
186 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 187 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
188 OPC_DSRA = 0x3B | OPC_SPECIAL,
189 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
190 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 191 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 192 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 193 /* Multiplication / division */
7a387fff
TS
194 OPC_MULT = 0x18 | OPC_SPECIAL,
195 OPC_MULTU = 0x19 | OPC_SPECIAL,
196 OPC_DIV = 0x1A | OPC_SPECIAL,
197 OPC_DIVU = 0x1B | OPC_SPECIAL,
198 OPC_DMULT = 0x1C | OPC_SPECIAL,
199 OPC_DMULTU = 0x1D | OPC_SPECIAL,
200 OPC_DDIV = 0x1E | OPC_SPECIAL,
201 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 202
e37e863f 203 /* 2 registers arithmetic / logic */
7a387fff
TS
204 OPC_ADD = 0x20 | OPC_SPECIAL,
205 OPC_ADDU = 0x21 | OPC_SPECIAL,
206 OPC_SUB = 0x22 | OPC_SPECIAL,
207 OPC_SUBU = 0x23 | OPC_SPECIAL,
208 OPC_AND = 0x24 | OPC_SPECIAL,
209 OPC_OR = 0x25 | OPC_SPECIAL,
210 OPC_XOR = 0x26 | OPC_SPECIAL,
211 OPC_NOR = 0x27 | OPC_SPECIAL,
212 OPC_SLT = 0x2A | OPC_SPECIAL,
213 OPC_SLTU = 0x2B | OPC_SPECIAL,
214 OPC_DADD = 0x2C | OPC_SPECIAL,
215 OPC_DADDU = 0x2D | OPC_SPECIAL,
216 OPC_DSUB = 0x2E | OPC_SPECIAL,
217 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 218 /* Jumps */
7a387fff
TS
219 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
220 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 221 /* Traps */
7a387fff
TS
222 OPC_TGE = 0x30 | OPC_SPECIAL,
223 OPC_TGEU = 0x31 | OPC_SPECIAL,
224 OPC_TLT = 0x32 | OPC_SPECIAL,
225 OPC_TLTU = 0x33 | OPC_SPECIAL,
226 OPC_TEQ = 0x34 | OPC_SPECIAL,
227 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 228 /* HI / LO registers load & stores */
7a387fff
TS
229 OPC_MFHI = 0x10 | OPC_SPECIAL,
230 OPC_MTHI = 0x11 | OPC_SPECIAL,
231 OPC_MFLO = 0x12 | OPC_SPECIAL,
232 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 233 /* Conditional moves */
7a387fff
TS
234 OPC_MOVZ = 0x0A | OPC_SPECIAL,
235 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 236
b691d9d2
LA
237 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
238 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
239
7a387fff 240 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
241
242 /* Special */
a0d700e4 243 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
244 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
245 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 246 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
247 OPC_SYNC = 0x0F | OPC_SPECIAL,
248
7a387fff
TS
249 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
250 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
251 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
252 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
253};
254
b42ee5e1
LA
255/* R6 Multiply and Divide instructions have the same Opcode
256 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
257#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
258
259enum {
260 R6_OPC_MUL = OPC_MULT | (2 << 6),
261 R6_OPC_MUH = OPC_MULT | (3 << 6),
262 R6_OPC_MULU = OPC_MULTU | (2 << 6),
263 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
264 R6_OPC_DIV = OPC_DIV | (2 << 6),
265 R6_OPC_MOD = OPC_DIV | (3 << 6),
266 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
267 R6_OPC_MODU = OPC_DIVU | (3 << 6),
268
269 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
270 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
271 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
272 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
273 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
274 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
275 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
276 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
277
278 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
279 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
280 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
281 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
282 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
283
284 OPC_LSA = 0x05 | OPC_SPECIAL,
285 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
286};
287
e9c71dd1
TS
288/* Multiplication variants of the vr54xx. */
289#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
290
291enum {
292 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
293 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
294 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
295 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
296 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
297 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
298 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
299 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
301 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
302 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
303 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
304 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
305 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
306};
307
7a387fff
TS
308/* REGIMM (rt field) opcodes */
309#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
310
311enum {
312 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
313 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
314 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
315 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
316 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
317 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
318 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
319 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
320 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
321 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
322 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
323 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
324 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
325 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
326 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
327
328 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
329 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
330};
331
7a387fff
TS
332/* Special2 opcodes */
333#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
334
e37e863f 335enum {
7a387fff
TS
336 /* Multiply & xxx operations */
337 OPC_MADD = 0x00 | OPC_SPECIAL2,
338 OPC_MADDU = 0x01 | OPC_SPECIAL2,
339 OPC_MUL = 0x02 | OPC_SPECIAL2,
340 OPC_MSUB = 0x04 | OPC_SPECIAL2,
341 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
342 /* Loongson 2F */
343 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
344 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
345 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
346 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
347 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
348 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
349 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
350 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
351 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
352 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
353 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
354 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 355 /* Misc */
7a387fff
TS
356 OPC_CLZ = 0x20 | OPC_SPECIAL2,
357 OPC_CLO = 0x21 | OPC_SPECIAL2,
358 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
359 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 360 /* Special */
7a387fff
TS
361 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
362};
363
364/* Special3 opcodes */
365#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
366
367enum {
368 OPC_EXT = 0x00 | OPC_SPECIAL3,
369 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
370 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
371 OPC_DEXT = 0x03 | OPC_SPECIAL3,
372 OPC_INS = 0x04 | OPC_SPECIAL3,
373 OPC_DINSM = 0x05 | OPC_SPECIAL3,
374 OPC_DINSU = 0x06 | OPC_SPECIAL3,
375 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
376 OPC_FORK = 0x08 | OPC_SPECIAL3,
377 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
378 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
379 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
380 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
381
382 /* Loongson 2E */
383 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
384 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
385 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
386 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
387 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
388 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
389 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
390 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
391 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
392 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
393 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
394 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
395
396 /* MIPS DSP Load */
397 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
398 /* MIPS DSP Arithmetic */
399 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 400 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 401 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 402 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
403 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
404 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
405 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 406 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
407 /* MIPS DSP GPR-Based Shift Sub-class */
408 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 409 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
410 /* MIPS DSP Multiply Sub-class insns */
411 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
412 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
413 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 414 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
415 /* DSP Bit/Manipulation Sub-class */
416 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 417 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 418 /* MIPS DSP Append Sub-class */
26690560 419 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 420 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
421 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
422 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 423 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
424
425 /* R6 */
bf7910c6
LA
426 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
427 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
428 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
429 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
430 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
431 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
432};
433
7a387fff
TS
434/* BSHFL opcodes */
435#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
436
e37e863f 437enum {
15eacb9b
YK
438 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
439 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
440 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
441 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
442 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
443 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
444};
445
7a387fff
TS
446/* DBSHFL opcodes */
447#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
448
e37e863f 449enum {
15eacb9b
YK
450 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
451 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
452 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
453 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
454 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
455};
456
e45a93e2
JL
457/* MIPS DSP REGIMM opcodes */
458enum {
459 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 460 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
461};
462
9b1a1d68
JL
463#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
464/* MIPS DSP Load */
465enum {
466 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
467 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
468 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 469 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
470};
471
461c08df
JL
472#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
473enum {
474 /* MIPS DSP Arithmetic Sub-class */
475 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
476 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
482 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
489 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
491 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
492 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
493 /* MIPS DSP Multiply Sub-class insns */
494 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
500};
501
502#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
503#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
504enum {
505 /* MIPS DSP Arithmetic Sub-class */
506 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
507 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
520 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
523};
524
525#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
526enum {
527 /* MIPS DSP Arithmetic Sub-class */
528 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
529 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
541 /* DSP Bit/Manipulation Sub-class */
542 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
547};
548
549#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
550enum {
551 /* MIPS DSP Arithmetic Sub-class */
552 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
553 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
559 /* DSP Compare-Pick Sub-class */
560 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 575};
a22260ae 576
77c5fa8b
JL
577#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
578enum {
579 /* MIPS DSP GPR-Based Shift Sub-class */
580 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
581 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
602};
461c08df 603
a22260ae
JL
604#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605enum {
606 /* MIPS DSP Multiply Sub-class insns */
607 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
608 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
621 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
629};
630
1cb6686c
JL
631#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
632enum {
633 /* DSP Bit/Manipulation Sub-class */
634 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
635};
636
26690560
JL
637#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638enum {
df6126a7 639 /* MIPS DSP Append Sub-class */
26690560
JL
640 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
641 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
642 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
643};
644
b53371ed
JL
645#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646enum {
647 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
648 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
649 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
660 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
662 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
663 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
664 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
665};
666
461c08df
JL
667#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668enum {
669 /* MIPS DSP Arithmetic Sub-class */
670 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
671 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
687 /* DSP Bit/Manipulation Sub-class */
688 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 694};
461c08df 695
461c08df
JL
696#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697enum {
a22260ae
JL
698 /* MIPS DSP Multiply Sub-class insns */
699 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
700 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
704 /* MIPS DSP Arithmetic Sub-class */
705 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
706 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
716 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
726};
461c08df 727
461c08df
JL
728#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
729enum {
26690560
JL
730 /* DSP Compare-Pick Sub-class */
731 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
732 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
750 /* MIPS DSP Arithmetic Sub-class */
751 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
759};
461c08df 760
26690560
JL
761#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762enum {
df6126a7 763 /* DSP Append Sub-class */
26690560
JL
764 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
765 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
767 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
768};
26690560 769
b53371ed
JL
770#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
771enum {
772 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
773 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
774 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
775 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
794};
795
1cb6686c
JL
796#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797enum {
798 /* DSP Bit/Manipulation Sub-class */
799 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
800};
1cb6686c 801
a22260ae
JL
802#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
803enum {
804 /* MIPS DSP Multiply Sub-class insns */
805 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
806 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
831};
a22260ae 832
77c5fa8b
JL
833#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
834enum {
835 /* MIPS DSP GPR-Based Shift Sub-class */
836 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
837 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
862};
77c5fa8b 863
7a387fff
TS
864/* Coprocessor 0 (rs field) */
865#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
866
6ea83fed 867enum {
7a387fff
TS
868 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
869 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 870 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 873 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 874 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
875 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
876 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 877 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
878 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
879 OPC_C0 = (0x10 << 21) | OPC_CP0,
880 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
881 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 882};
7a387fff
TS
883
884/* MFMC0 opcodes */
b48cfdff 885#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
886
887enum {
ead9360e
TS
888 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
890 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
891 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
892 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
893 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
894};
895
896/* Coprocessor 0 (with rs == C0) */
897#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
898
899enum {
900 OPC_TLBR = 0x01 | OPC_C0,
901 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
902 OPC_TLBINV = 0x03 | OPC_C0,
903 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
904 OPC_TLBWR = 0x06 | OPC_C0,
905 OPC_TLBP = 0x08 | OPC_C0,
906 OPC_RFE = 0x10 | OPC_C0,
907 OPC_ERET = 0x18 | OPC_C0,
908 OPC_DERET = 0x1F | OPC_C0,
909 OPC_WAIT = 0x20 | OPC_C0,
910};
911
912/* Coprocessor 1 (rs field) */
913#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
914
bf4120ad
NF
915/* Values for the fmt field in FP instructions */
916enum {
917 /* 0 - 15 are reserved */
e459440a
AJ
918 FMT_S = 16, /* single fp */
919 FMT_D = 17, /* double fp */
920 FMT_E = 18, /* extended fp */
921 FMT_Q = 19, /* quad fp */
922 FMT_W = 20, /* 32-bit fixed */
923 FMT_L = 21, /* 64-bit fixed */
924 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
925 /* 23 - 31 are reserved */
926};
927
7a387fff
TS
928enum {
929 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
930 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
931 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 932 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
933 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
934 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
935 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 936 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 937 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
938 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
939 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
940 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
941 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
942 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
943 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
944 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
945 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
946 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
947 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
948 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
949 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
950 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
951 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
952 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
953 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
954 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
955 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
956 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
957 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
958 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
959};
960
5a5012ec
TS
961#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
962#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
963
7a387fff
TS
964enum {
965 OPC_BC1F = (0x00 << 16) | OPC_BC1,
966 OPC_BC1T = (0x01 << 16) | OPC_BC1,
967 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
968 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
969};
970
5a5012ec
TS
971enum {
972 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
973 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
974};
975
976enum {
977 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
978 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
979};
7a387fff
TS
980
981#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
982
983enum {
984 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
985 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
986 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
987 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
988 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
989 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
990 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
991 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
992 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
993 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
994 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
995};
996
bd277fa1
RH
997#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
998
999enum {
1000 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1008
1009 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1017
1018 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1021 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1022 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1023 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1024 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1025 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1026
1027 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1030 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1034 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1035
1036 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1037 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1041 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1042
1043 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1048 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1049
1050 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1055 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1056
1057 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1062 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1063
1064 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1065 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1066 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1067 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1069 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1070
1071 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1072 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1073 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1074 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1076 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1077
1078 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1079 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1081 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1083 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1084
1085 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1086 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1087 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1088 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1089 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1090 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1091};
1092
1093
e0c84da7
TS
1094#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1095
1096enum {
1097 OPC_LWXC1 = 0x00 | OPC_CP3,
1098 OPC_LDXC1 = 0x01 | OPC_CP3,
1099 OPC_LUXC1 = 0x05 | OPC_CP3,
1100 OPC_SWXC1 = 0x08 | OPC_CP3,
1101 OPC_SDXC1 = 0x09 | OPC_CP3,
1102 OPC_SUXC1 = 0x0D | OPC_CP3,
1103 OPC_PREFX = 0x0F | OPC_CP3,
1104 OPC_ALNV_PS = 0x1E | OPC_CP3,
1105 OPC_MADD_S = 0x20 | OPC_CP3,
1106 OPC_MADD_D = 0x21 | OPC_CP3,
1107 OPC_MADD_PS = 0x26 | OPC_CP3,
1108 OPC_MSUB_S = 0x28 | OPC_CP3,
1109 OPC_MSUB_D = 0x29 | OPC_CP3,
1110 OPC_MSUB_PS = 0x2E | OPC_CP3,
1111 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1112 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1113 OPC_NMADD_PS= 0x36 | OPC_CP3,
1114 OPC_NMSUB_S = 0x38 | OPC_CP3,
1115 OPC_NMSUB_D = 0x39 | OPC_CP3,
1116 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1117};
1118
239dfebe
YK
1119/* MSA Opcodes */
1120#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1121enum {
1122 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1123 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1124 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1125 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1126 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1127 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1128 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1129 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1130 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1131 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1132 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1133 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1134 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1135 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1136 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1137 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1138 OPC_MSA_ELM = 0x19 | OPC_MSA,
1139 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1140 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1141 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1142 OPC_MSA_VEC = 0x1E | OPC_MSA,
1143
1144 /* MI10 instruction */
1145 OPC_LD_B = (0x20) | OPC_MSA,
1146 OPC_LD_H = (0x21) | OPC_MSA,
1147 OPC_LD_W = (0x22) | OPC_MSA,
1148 OPC_LD_D = (0x23) | OPC_MSA,
1149 OPC_ST_B = (0x24) | OPC_MSA,
1150 OPC_ST_H = (0x25) | OPC_MSA,
1151 OPC_ST_W = (0x26) | OPC_MSA,
1152 OPC_ST_D = (0x27) | OPC_MSA,
1153};
1154
1155enum {
1156 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1157 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1158 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1159 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1160 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1161 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1162 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1163 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1164 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1165 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1166 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1167 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1168 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1169
1170 /* I8 instruction */
1171 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1172 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1173 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1174 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1175 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1176 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1177 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1178 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1179 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1180 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1181
1182 /* VEC/2R/2RF instruction */
1183 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1184 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1185 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1186 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1187 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1188 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1189 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1190
1191 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1192 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1193
1194 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1195 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1196 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1197 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1198 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1199
1200 /* 2RF instruction df(bit 16) = _w, _d */
1201 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1203 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1204 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1205 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1206 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1207 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1208 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1210 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1211 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1212 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1214 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1216 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1217
1218 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1219 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1220 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1221 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1222 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1223 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1224 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1225 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1226 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1227 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1228 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1229 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1230 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1231 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1232 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1233 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1234 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1235 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1236 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1237 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1238 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1239 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1240 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1241 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1242 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1243 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1244 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1245 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1246 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1247 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1248 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1249 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1250 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1251 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1252 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1253 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1254 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1255 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1256 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1257 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1258 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1259 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1260 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1261 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1262 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1263 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1264 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1265 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1266 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1267 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1268 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1269 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1270 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1271 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1272 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1273 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1274 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1275 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1276 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1277 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1278 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1279 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1280 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1281 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1282
1283 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1284 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1285 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1286 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1287 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1288 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1289 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1290 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293
1294 /* 3RF instruction _df(bit 21) = _w, _d */
1295 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1296 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1297 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1298 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1299 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1300 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1303 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1304 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1305 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1306 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1307 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1308 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1309 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1310 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1311 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1312 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1313 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1316 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1317 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1318 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1319 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1320 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1321 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1322 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1323 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1326 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1327 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1329 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1330 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1331 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1333 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1334 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1336
1337 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1338 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1339 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1340 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1341 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1342 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1343 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1344 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1345 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1346 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1347 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1349 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1350};
1351
39454628 1352/* global register indices */
a7812ae4
PB
1353static TCGv_ptr cpu_env;
1354static TCGv cpu_gpr[32], cpu_PC;
340fff72 1355static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1356static TCGv cpu_dspctrl, btarget, bcond;
1357static TCGv_i32 hflags;
a7812ae4 1358static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1359static TCGv_i64 fpu_f64[32];
863f264d 1360static TCGv_i64 msa_wr_d[64];
aa0bf00b 1361
1a7ff922 1362static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1363static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1364
022c62cb 1365#include "exec/gen-icount.h"
2e70f6ef 1366
895c2d04 1367#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1368 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1369 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1370 tcg_temp_free_i32(helper_tmp); \
1371 } while(0)
be24bb4f 1372
895c2d04 1373#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1374 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1375 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1376 tcg_temp_free_i32(helper_tmp); \
1377 } while(0)
be24bb4f 1378
895c2d04
BS
1379#define gen_helper_1e0i(name, ret, arg1) do { \
1380 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1381 gen_helper_##name(ret, cpu_env, helper_tmp); \
1382 tcg_temp_free_i32(helper_tmp); \
1383 } while(0)
1384
1385#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1386 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1387 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1388 tcg_temp_free_i32(helper_tmp); \
1389 } while(0)
1390
1391#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1392 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1393 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1394 tcg_temp_free_i32(helper_tmp); \
1395 } while(0)
1396
1397#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1398 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1399 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1400 tcg_temp_free_i32(helper_tmp); \
1401 } while(0)
be24bb4f 1402
895c2d04 1403#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1404 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1405 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1406 tcg_temp_free_i32(helper_tmp); \
1407 } while(0)
c239529e 1408
8e9ade68
TS
1409typedef struct DisasContext {
1410 struct TranslationBlock *tb;
1411 target_ulong pc, saved_pc;
1412 uint32_t opcode;
7b270ef2 1413 int singlestep_enabled;
d75c135e 1414 int insn_flags;
5ab5c041 1415 int32_t CP0_Config1;
8e9ade68
TS
1416 /* Routine used to access memory */
1417 int mem_idx;
be3a8c53 1418 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1419 uint32_t hflags, saved_hflags;
1420 int bstate;
1421 target_ulong btarget;
d279279e 1422 bool ulri;
e98c0d17 1423 int kscrexist;
7207c7f9 1424 bool rxi;
9456c2fb 1425 int ie;
aea14095
LA
1426 bool bi;
1427 bool bp;
5204ea79
LA
1428 uint64_t PAMask;
1429 bool mvh;
1430 int CP0_LLAddr_shift;
e29c9628 1431 bool ps;
8e9ade68
TS
1432} DisasContext;
1433
1434enum {
1435 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1436 * exception condition */
8e9ade68
TS
1437 BS_STOP = 1, /* We want to stop translation for any reason */
1438 BS_BRANCH = 2, /* We reached a branch condition */
1439 BS_EXCP = 3, /* We reached an exception condition */
1440};
1441
d73ee8a2
RH
1442static const char * const regnames[] = {
1443 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1444 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1445 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1446 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1447};
6af0bf9c 1448
d73ee8a2
RH
1449static const char * const regnames_HI[] = {
1450 "HI0", "HI1", "HI2", "HI3",
1451};
4b2eb8d2 1452
d73ee8a2
RH
1453static const char * const regnames_LO[] = {
1454 "LO0", "LO1", "LO2", "LO3",
1455};
4b2eb8d2 1456
d73ee8a2
RH
1457static const char * const fregnames[] = {
1458 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1459 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1460 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1461 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1462};
958fb4a9 1463
863f264d
YK
1464static const char * const msaregnames[] = {
1465 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1466 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1467 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1468 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1469 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1470 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1471 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1472 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1473 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1474 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1475 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1476 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1477 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1478 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1479 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1480 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1481};
1482
9d68ac14 1483#define LOG_DISAS(...) \
fb7729e2
RH
1484 do { \
1485 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1486 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1487 } \
1488 } while (0)
1489
9d68ac14 1490#define MIPS_INVAL(op) \
fb7729e2
RH
1491 do { \
1492 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1493 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1494 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1495 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1496 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1497 } \
1498 } while (0)
958fb4a9 1499
8e9ade68
TS
1500/* General purpose registers moves. */
1501static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1502{
8e9ade68
TS
1503 if (reg == 0)
1504 tcg_gen_movi_tl(t, 0);
1505 else
4b2eb8d2 1506 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1507}
1508
8e9ade68 1509static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1510{
8e9ade68 1511 if (reg != 0)
4b2eb8d2 1512 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1513}
1514
8e9ade68 1515/* Moves to/from shadow registers. */
be24bb4f 1516static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1517{
d9bea114 1518 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1519
1520 if (from == 0)
d9bea114 1521 tcg_gen_movi_tl(t0, 0);
8e9ade68 1522 else {
d9bea114 1523 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1524 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1525
7db13fae 1526 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1527 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1528 tcg_gen_andi_i32(t2, t2, 0xf);
1529 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1530 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1531 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1532
d9bea114 1533 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1534 tcg_temp_free_ptr(addr);
d9bea114 1535 tcg_temp_free_i32(t2);
8e9ade68 1536 }
d9bea114
AJ
1537 gen_store_gpr(t0, to);
1538 tcg_temp_free(t0);
aaa9128a
TS
1539}
1540
be24bb4f 1541static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1542{
be24bb4f 1543 if (to != 0) {
d9bea114
AJ
1544 TCGv t0 = tcg_temp_new();
1545 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1546 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1547
d9bea114 1548 gen_load_gpr(t0, from);
7db13fae 1549 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1550 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1551 tcg_gen_andi_i32(t2, t2, 0xf);
1552 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1553 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1554 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1555
d9bea114 1556 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1557 tcg_temp_free_ptr(addr);
d9bea114
AJ
1558 tcg_temp_free_i32(t2);
1559 tcg_temp_free(t0);
8e9ade68 1560 }
aaa9128a
TS
1561}
1562
eab9944c
LA
1563/* Tests */
1564static inline void gen_save_pc(target_ulong pc)
1565{
1566 tcg_gen_movi_tl(cpu_PC, pc);
1567}
1568
1569static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1570{
1571 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1572 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1573 gen_save_pc(ctx->pc);
1574 ctx->saved_pc = ctx->pc;
1575 }
1576 if (ctx->hflags != ctx->saved_hflags) {
1577 tcg_gen_movi_i32(hflags, ctx->hflags);
1578 ctx->saved_hflags = ctx->hflags;
1579 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1580 case MIPS_HFLAG_BR:
1581 break;
1582 case MIPS_HFLAG_BC:
1583 case MIPS_HFLAG_BL:
1584 case MIPS_HFLAG_B:
1585 tcg_gen_movi_tl(btarget, ctx->btarget);
1586 break;
1587 }
1588 }
1589}
1590
1591static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1592{
1593 ctx->saved_hflags = ctx->hflags;
1594 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1595 case MIPS_HFLAG_BR:
1596 break;
1597 case MIPS_HFLAG_BC:
1598 case MIPS_HFLAG_BL:
1599 case MIPS_HFLAG_B:
1600 ctx->btarget = env->btarget;
1601 break;
1602 }
1603}
1604
1605static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1606{
1607 TCGv_i32 texcp = tcg_const_i32(excp);
1608 TCGv_i32 terr = tcg_const_i32(err);
1609 save_cpu_state(ctx, 1);
1610 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1611 tcg_temp_free_i32(terr);
1612 tcg_temp_free_i32(texcp);
9c708c7f 1613 ctx->bstate = BS_EXCP;
eab9944c
LA
1614}
1615
1616static inline void generate_exception(DisasContext *ctx, int excp)
1617{
eab9944c
LA
1618 gen_helper_0e0i(raise_exception, excp);
1619}
1620
9c708c7f
PD
1621static inline void generate_exception_end(DisasContext *ctx, int excp)
1622{
1623 generate_exception_err(ctx, excp, 0);
1624}
1625
aaa9128a 1626/* Floating point register moves. */
7c979afd 1627static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1628{
7c979afd
LA
1629 if (ctx->hflags & MIPS_HFLAG_FRE) {
1630 generate_exception(ctx, EXCP_RI);
1631 }
ecc7b3aa 1632 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1633}
1634
7c979afd 1635static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1636{
7c979afd
LA
1637 TCGv_i64 t64;
1638 if (ctx->hflags & MIPS_HFLAG_FRE) {
1639 generate_exception(ctx, EXCP_RI);
1640 }
1641 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1642 tcg_gen_extu_i32_i64(t64, t);
1643 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1644 tcg_temp_free_i64(t64);
6d066274
AJ
1645}
1646
7f6613ce 1647static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1648{
7f6613ce 1649 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1650 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1651 } else {
7c979afd 1652 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1653 }
6d066274
AJ
1654}
1655
7f6613ce 1656static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1657{
7f6613ce
PJ
1658 if (ctx->hflags & MIPS_HFLAG_F64) {
1659 TCGv_i64 t64 = tcg_temp_new_i64();
1660 tcg_gen_extu_i32_i64(t64, t);
1661 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1662 tcg_temp_free_i64(t64);
1663 } else {
7c979afd 1664 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1665 }
aa0bf00b 1666}
6ea83fed 1667
d73ee8a2 1668static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1669{
f364515c 1670 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1671 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1672 } else {
d73ee8a2 1673 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1674 }
1675}
6ea83fed 1676
d73ee8a2 1677static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1678{
f364515c 1679 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1680 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1681 } else {
d73ee8a2
RH
1682 TCGv_i64 t0;
1683 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1684 t0 = tcg_temp_new_i64();
6d066274 1685 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1686 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1687 tcg_temp_free_i64(t0);
aa0bf00b
TS
1688 }
1689}
6ea83fed 1690
d94536f4 1691static inline int get_fp_bit (int cc)
a16336e4 1692{
d94536f4
AJ
1693 if (cc)
1694 return 24 + cc;
1695 else
1696 return 23;
a16336e4
TS
1697}
1698
48d38ca5 1699/* Addresses computation */
941694d0 1700static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1701{
941694d0 1702 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1703
1704#if defined(TARGET_MIPS64)
01f72885 1705 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1706 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1707 }
1708#endif
4ad40f36
FB
1709}
1710
31837be3
YK
1711/* Addresses computation (translation time) */
1712static target_long addr_add(DisasContext *ctx, target_long base,
1713 target_long offset)
1714{
1715 target_long sum = base + offset;
1716
1717#if defined(TARGET_MIPS64)
1718 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1719 sum = (int32_t)sum;
1720 }
1721#endif
1722 return sum;
1723}
1724
71f303cd 1725/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1726static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1727{
1728#if defined(TARGET_MIPS64)
71f303cd
RH
1729 tcg_gen_ext32s_i64(ret, arg);
1730#else
1731 tcg_gen_extrl_i64_i32(ret, arg);
1732#endif
1733}
1734
1735/* Sign-extract the high 32-bits to a target_long. */
1736static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1737{
1738#if defined(TARGET_MIPS64)
1739 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1740#else
71f303cd 1741 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1742#endif
1743}
1744
356265ae 1745static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1746{
fe253235 1747 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1748 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1749}
1750
356265ae 1751static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1752{
fe253235 1753 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1754 generate_exception_err(ctx, EXCP_CpU, 1);
1755}
1756
b8aa4598
TS
1757/* Verify that the processor is running with COP1X instructions enabled.
1758 This is associated with the nabla symbol in the MIPS32 and MIPS64
1759 opcode tables. */
1760
356265ae 1761static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1762{
1763 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1764 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1765}
1766
1767/* Verify that the processor is running with 64-bit floating-point
1768 operations enabled. */
1769
356265ae 1770static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1771{
b8aa4598 1772 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1773 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1774}
1775
1776/*
1777 * Verify if floating point register is valid; an operation is not defined
1778 * if bit 0 of any register specification is set and the FR bit in the
1779 * Status register equals zero, since the register numbers specify an
1780 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1781 * in the Status register equals one, both even and odd register numbers
1782 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1783 *
1784 * Multiple 64 bit wide registers can be checked by calling
1785 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1786 */
356265ae 1787static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1788{
fe253235 1789 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1790 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1791}
1792
853c3240
JL
1793/* Verify that the processor is running with DSP instructions enabled.
1794 This is enabled by CP0 Status register MX(24) bit.
1795 */
1796
1797static inline void check_dsp(DisasContext *ctx)
1798{
1799 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1800 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1801 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1802 } else {
9c708c7f 1803 generate_exception_end(ctx, EXCP_RI);
ad153f15 1804 }
853c3240
JL
1805 }
1806}
1807
1808static inline void check_dspr2(DisasContext *ctx)
1809{
1810 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1811 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1812 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1813 } else {
9c708c7f 1814 generate_exception_end(ctx, EXCP_RI);
ad153f15 1815 }
853c3240
JL
1816 }
1817}
1818
3a95e3a7 1819/* This code generates a "reserved instruction" exception if the
e189e748 1820 CPU does not support the instruction set corresponding to flags. */
d75c135e 1821static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1822{
d75c135e 1823 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1824 generate_exception_end(ctx, EXCP_RI);
d75c135e 1825 }
3a95e3a7
TS
1826}
1827
fecd2646
LA
1828/* This code generates a "reserved instruction" exception if the
1829 CPU has corresponding flag set which indicates that the instruction
1830 has been removed. */
1831static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1832{
1833 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1834 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1835 }
1836}
1837
e29c9628
YK
1838/* This code generates a "reserved instruction" exception if the
1839 CPU does not support 64-bit paired-single (PS) floating point data type */
1840static inline void check_ps(DisasContext *ctx)
1841{
1842 if (unlikely(!ctx->ps)) {
1843 generate_exception(ctx, EXCP_RI);
1844 }
1845 check_cp1_64bitmode(ctx);
1846}
1847
c7986fd6 1848#ifdef TARGET_MIPS64
e189e748
TS
1849/* This code generates a "reserved instruction" exception if 64-bit
1850 instructions are not enabled. */
356265ae 1851static inline void check_mips_64(DisasContext *ctx)
e189e748 1852{
fe253235 1853 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1854 generate_exception_end(ctx, EXCP_RI);
e189e748 1855}
c7986fd6 1856#endif
e189e748 1857
5204ea79
LA
1858#ifndef CONFIG_USER_ONLY
1859static inline void check_mvh(DisasContext *ctx)
1860{
1861 if (unlikely(!ctx->mvh)) {
1862 generate_exception(ctx, EXCP_RI);
1863 }
1864}
1865#endif
1866
8153667c
NF
1867/* Define small wrappers for gen_load_fpr* so that we have a uniform
1868 calling interface for 32 and 64-bit FPRs. No sense in changing
1869 all callers for gen_load_fpr32 when we need the CTX parameter for
1870 this one use. */
7c979afd 1871#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1872#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1873#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1874static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1875 int ft, int fs, int cc) \
1876{ \
1877 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1878 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1879 switch (ifmt) { \
1880 case FMT_PS: \
e29c9628 1881 check_ps(ctx); \
8153667c
NF
1882 break; \
1883 case FMT_D: \
1884 if (abs) { \
1885 check_cop1x(ctx); \
1886 } \
1887 check_cp1_registers(ctx, fs | ft); \
1888 break; \
1889 case FMT_S: \
1890 if (abs) { \
1891 check_cop1x(ctx); \
1892 } \
1893 break; \
1894 } \
1895 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1896 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1897 switch (n) { \
895c2d04
BS
1898 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1899 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1900 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1901 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1902 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1903 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1904 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1905 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1906 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1907 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1908 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1909 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1910 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1911 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1912 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1913 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1914 default: abort(); \
1915 } \
1916 tcg_temp_free_i##bits (fp0); \
1917 tcg_temp_free_i##bits (fp1); \
1918}
1919
1920FOP_CONDS(, 0, d, FMT_D, 64)
1921FOP_CONDS(abs, 1, d, FMT_D, 64)
1922FOP_CONDS(, 0, s, FMT_S, 32)
1923FOP_CONDS(abs, 1, s, FMT_S, 32)
1924FOP_CONDS(, 0, ps, FMT_PS, 64)
1925FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1926#undef FOP_CONDS
3f493883
YK
1927
1928#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1929static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1930 int ft, int fs, int fd) \
1931{ \
1932 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1933 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1934 if (ifmt == FMT_D) { \
3f493883 1935 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1936 } \
1937 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1938 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1939 switch (n) { \
1940 case 0: \
1941 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1942 break; \
1943 case 1: \
1944 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1945 break; \
1946 case 2: \
1947 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1948 break; \
1949 case 3: \
1950 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1951 break; \
1952 case 4: \
1953 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1954 break; \
1955 case 5: \
1956 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1957 break; \
1958 case 6: \
1959 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1960 break; \
1961 case 7: \
1962 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1963 break; \
1964 case 8: \
1965 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 9: \
1968 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 10: \
1971 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 11: \
1974 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 12: \
1977 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 13: \
1980 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 14: \
1983 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 15: \
1986 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 17: \
1989 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 18: \
1992 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 19: \
1995 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 25: \
1998 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 26: \
2001 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 case 27: \
2004 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2005 break; \
2006 default: \
2007 abort(); \
2008 } \
2009 STORE; \
2010 tcg_temp_free_i ## bits (fp0); \
2011 tcg_temp_free_i ## bits (fp1); \
2012}
2013
2014FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2015FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2016#undef FOP_CONDNS
8153667c
NF
2017#undef gen_ldcmp_fpr32
2018#undef gen_ldcmp_fpr64
2019
958fb4a9 2020/* load/store instructions. */
e7139c44 2021#ifdef CONFIG_USER_ONLY
d9bea114 2022#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2023static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2024{ \
2025 TCGv t0 = tcg_temp_new(); \
2026 tcg_gen_mov_tl(t0, arg1); \
2027 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2028 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2029 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2030 tcg_temp_free(t0); \
aaa9128a 2031}
e7139c44
AJ
2032#else
2033#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2034static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2035{ \
895c2d04 2036 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2037}
2038#endif
aaa9128a
TS
2039OP_LD_ATOMIC(ll,ld32s);
2040#if defined(TARGET_MIPS64)
2041OP_LD_ATOMIC(lld,ld64);
2042#endif
2043#undef OP_LD_ATOMIC
2044
590bc601
PB
2045#ifdef CONFIG_USER_ONLY
2046#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2047static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2048{ \
2049 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2050 TCGLabel *l1 = gen_new_label(); \
2051 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2052 \
2053 tcg_gen_andi_tl(t0, arg2, almask); \
2054 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2055 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2056 generate_exception(ctx, EXCP_AdES); \
2057 gen_set_label(l1); \
7db13fae 2058 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2059 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2060 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2061 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2062 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2063 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2064 gen_set_label(l2); \
2065 tcg_gen_movi_tl(t0, 0); \
2066 gen_store_gpr(t0, rt); \
2067 tcg_temp_free(t0); \
2068}
2069#else
2070#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2071static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2072{ \
2073 TCGv t0 = tcg_temp_new(); \
895c2d04 2074 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2075 gen_store_gpr(t0, rt); \
590bc601
PB
2076 tcg_temp_free(t0); \
2077}
2078#endif
590bc601 2079OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2080#if defined(TARGET_MIPS64)
590bc601 2081OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2082#endif
2083#undef OP_ST_ATOMIC
2084
662d7485
NF
2085static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2086 int base, int16_t offset)
2087{
2088 if (base == 0) {
2089 tcg_gen_movi_tl(addr, offset);
2090 } else if (offset == 0) {
2091 gen_load_gpr(addr, base);
2092 } else {
2093 tcg_gen_movi_tl(addr, offset);
2094 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2095 }
2096}
2097
364d4831
NF
2098static target_ulong pc_relative_pc (DisasContext *ctx)
2099{
2100 target_ulong pc = ctx->pc;
2101
2102 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2103 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2104
2105 pc -= branch_bytes;
2106 }
2107
2108 pc &= ~(target_ulong)3;
2109 return pc;
2110}
2111
5c13fdfd 2112/* Load */
d75c135e
AJ
2113static void gen_ld(DisasContext *ctx, uint32_t opc,
2114 int rt, int base, int16_t offset)
6af0bf9c 2115{
fc40787a 2116 TCGv t0, t1, t2;
afa88c3a 2117
d75c135e 2118 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2119 /* Loongson CPU uses a load to zero register for prefetch.
2120 We emulate it as a NOP. On other CPU we must perform the
2121 actual memory access. */
afa88c3a
AJ
2122 return;
2123 }
6af0bf9c 2124
afa88c3a 2125 t0 = tcg_temp_new();
662d7485 2126 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2127
6af0bf9c 2128 switch (opc) {
d26bc211 2129#if defined(TARGET_MIPS64)
6e473128 2130 case OPC_LWU:
be3a8c53
YK
2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2132 ctx->default_tcg_memop_mask);
78723684 2133 gen_store_gpr(t0, rt);
6e473128 2134 break;
6af0bf9c 2135 case OPC_LD:
be3a8c53
YK
2136 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2137 ctx->default_tcg_memop_mask);
78723684 2138 gen_store_gpr(t0, rt);
6af0bf9c 2139 break;
7a387fff 2140 case OPC_LLD:
bf7910c6 2141 case R6_OPC_LLD:
5c13fdfd 2142 op_ld_lld(t0, t0, ctx);
78723684 2143 gen_store_gpr(t0, rt);
7a387fff 2144 break;
6af0bf9c 2145 case OPC_LDL:
3cee3050 2146 t1 = tcg_temp_new();
908680c6
AJ
2147 /* Do a byte access to possibly trigger a page
2148 fault with the unaligned address. */
2149 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2150 tcg_gen_andi_tl(t1, t0, 7);
2151#ifndef TARGET_WORDS_BIGENDIAN
2152 tcg_gen_xori_tl(t1, t1, 7);
2153#endif
2154 tcg_gen_shli_tl(t1, t1, 3);
2155 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2156 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a 2157 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2158 t2 = tcg_const_tl(-1);
2159 tcg_gen_shl_tl(t2, t2, t1);
78723684 2160 gen_load_gpr(t1, rt);
eb02cc3f 2161 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2162 tcg_temp_free(t2);
2163 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2164 tcg_temp_free(t1);
fc40787a 2165 gen_store_gpr(t0, rt);
6af0bf9c 2166 break;
6af0bf9c 2167 case OPC_LDR:
3cee3050 2168 t1 = tcg_temp_new();
908680c6
AJ
2169 /* Do a byte access to possibly trigger a page
2170 fault with the unaligned address. */
2171 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2172 tcg_gen_andi_tl(t1, t0, 7);
2173#ifdef TARGET_WORDS_BIGENDIAN
2174 tcg_gen_xori_tl(t1, t1, 7);
2175#endif
2176 tcg_gen_shli_tl(t1, t1, 3);
2177 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2178 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2179 tcg_gen_shr_tl(t0, t0, t1);
2180 tcg_gen_xori_tl(t1, t1, 63);
2181 t2 = tcg_const_tl(0xfffffffffffffffeull);
2182 tcg_gen_shl_tl(t2, t2, t1);
78723684 2183 gen_load_gpr(t1, rt);
fc40787a
AJ
2184 tcg_gen_and_tl(t1, t1, t2);
2185 tcg_temp_free(t2);
2186 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2187 tcg_temp_free(t1);
fc40787a 2188 gen_store_gpr(t0, rt);
6af0bf9c 2189 break;
364d4831 2190 case OPC_LDPC:
3cee3050 2191 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2192 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2193 tcg_temp_free(t1);
5f68f5ae 2194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831
NF
2195 gen_store_gpr(t0, rt);
2196 break;
6af0bf9c 2197#endif
364d4831 2198 case OPC_LWPC:
3cee3050 2199 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2200 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2201 tcg_temp_free(t1);
5f68f5ae 2202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831
NF
2203 gen_store_gpr(t0, rt);
2204 break;
6af0bf9c 2205 case OPC_LW:
be3a8c53
YK
2206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2207 ctx->default_tcg_memop_mask);
78723684 2208 gen_store_gpr(t0, rt);
6af0bf9c 2209 break;
6af0bf9c 2210 case OPC_LH:
be3a8c53
YK
2211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2212 ctx->default_tcg_memop_mask);
78723684 2213 gen_store_gpr(t0, rt);
6af0bf9c 2214 break;
6af0bf9c 2215 case OPC_LHU:
be3a8c53
YK
2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2217 ctx->default_tcg_memop_mask);
78723684 2218 gen_store_gpr(t0, rt);
6af0bf9c
FB
2219 break;
2220 case OPC_LB:
5f68f5ae 2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2222 gen_store_gpr(t0, rt);
6af0bf9c 2223 break;
6af0bf9c 2224 case OPC_LBU:
5f68f5ae 2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2226 gen_store_gpr(t0, rt);
6af0bf9c
FB
2227 break;
2228 case OPC_LWL:
3cee3050 2229 t1 = tcg_temp_new();
908680c6
AJ
2230 /* Do a byte access to possibly trigger a page
2231 fault with the unaligned address. */
2232 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2233 tcg_gen_andi_tl(t1, t0, 3);
2234#ifndef TARGET_WORDS_BIGENDIAN
2235 tcg_gen_xori_tl(t1, t1, 3);
2236#endif
2237 tcg_gen_shli_tl(t1, t1, 3);
2238 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2239 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a 2240 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2241 t2 = tcg_const_tl(-1);
2242 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2243 gen_load_gpr(t1, rt);
eb02cc3f 2244 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2245 tcg_temp_free(t2);
2246 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2247 tcg_temp_free(t1);
fc40787a
AJ
2248 tcg_gen_ext32s_tl(t0, t0);
2249 gen_store_gpr(t0, rt);
6af0bf9c 2250 break;
6af0bf9c 2251 case OPC_LWR:
3cee3050 2252 t1 = tcg_temp_new();
908680c6
AJ
2253 /* Do a byte access to possibly trigger a page
2254 fault with the unaligned address. */
2255 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2256 tcg_gen_andi_tl(t1, t0, 3);
2257#ifdef TARGET_WORDS_BIGENDIAN
2258 tcg_gen_xori_tl(t1, t1, 3);
2259#endif
2260 tcg_gen_shli_tl(t1, t1, 3);
2261 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2262 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2263 tcg_gen_shr_tl(t0, t0, t1);
2264 tcg_gen_xori_tl(t1, t1, 31);
2265 t2 = tcg_const_tl(0xfffffffeull);
2266 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2267 gen_load_gpr(t1, rt);
fc40787a
AJ
2268 tcg_gen_and_tl(t1, t1, t2);
2269 tcg_temp_free(t2);
2270 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2271 tcg_temp_free(t1);
c728154b 2272 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2273 gen_store_gpr(t0, rt);
6af0bf9c 2274 break;
6af0bf9c 2275 case OPC_LL:
4368b29a 2276 case R6_OPC_LL:
5c13fdfd 2277 op_ld_ll(t0, t0, ctx);
78723684 2278 gen_store_gpr(t0, rt);
6af0bf9c 2279 break;
d66c7132 2280 }
d66c7132 2281 tcg_temp_free(t0);
d66c7132
AJ
2282}
2283
5c13fdfd
AJ
2284/* Store */
2285static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2286 int base, int16_t offset)
2287{
5c13fdfd
AJ
2288 TCGv t0 = tcg_temp_new();
2289 TCGv t1 = tcg_temp_new();
2290
2291 gen_base_offset_addr(ctx, t0, base, offset);
2292 gen_load_gpr(t1, rt);
2293 switch (opc) {
2294#if defined(TARGET_MIPS64)
2295 case OPC_SD:
be3a8c53
YK
2296 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2297 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2298 break;
2299 case OPC_SDL:
895c2d04 2300 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2301 break;
2302 case OPC_SDR:
895c2d04 2303 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2304 break;
2305#endif
2306 case OPC_SW:
be3a8c53
YK
2307 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2308 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2309 break;
2310 case OPC_SH:
be3a8c53
YK
2311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2312 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2313 break;
2314 case OPC_SB:
5f68f5ae 2315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2316 break;
2317 case OPC_SWL:
895c2d04 2318 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2319 break;
2320 case OPC_SWR:
895c2d04 2321 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2322 break;
2323 }
5c13fdfd
AJ
2324 tcg_temp_free(t0);
2325 tcg_temp_free(t1);
2326}
2327
2328
d66c7132
AJ
2329/* Store conditional */
2330static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2331 int base, int16_t offset)
2332{
d66c7132
AJ
2333 TCGv t0, t1;
2334
2d2826b9 2335#ifdef CONFIG_USER_ONLY
d66c7132 2336 t0 = tcg_temp_local_new();
d66c7132 2337 t1 = tcg_temp_local_new();
2d2826b9
AJ
2338#else
2339 t0 = tcg_temp_new();
2340 t1 = tcg_temp_new();
2341#endif
2342 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2343 gen_load_gpr(t1, rt);
2344 switch (opc) {
2345#if defined(TARGET_MIPS64)
2346 case OPC_SCD:
bf7910c6 2347 case R6_OPC_SCD:
5c13fdfd 2348 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2349 break;
2350#endif
6af0bf9c 2351 case OPC_SC:
4368b29a 2352 case R6_OPC_SC:
5c13fdfd 2353 op_st_sc(t1, t0, rt, ctx);
6af0bf9c 2354 break;
6af0bf9c 2355 }
78723684 2356 tcg_temp_free(t1);
d66c7132 2357 tcg_temp_free(t0);
6af0bf9c
FB
2358}
2359
6ea83fed 2360/* Load and store */
7a387fff 2361static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2362 int base, int16_t offset)
6ea83fed 2363{
4e2474d6 2364 TCGv t0 = tcg_temp_new();
6ea83fed 2365
662d7485 2366 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2367 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2368 memory access. */
6ea83fed
FB
2369 switch (opc) {
2370 case OPC_LWC1:
b6d96bed 2371 {
a7812ae4 2372 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2373 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2374 ctx->default_tcg_memop_mask);
7c979afd 2375 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2376 tcg_temp_free_i32(fp0);
b6d96bed 2377 }
6ea83fed
FB
2378 break;
2379 case OPC_SWC1:
b6d96bed 2380 {
a7812ae4 2381 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2382 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2383 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2384 ctx->default_tcg_memop_mask);
a7812ae4 2385 tcg_temp_free_i32(fp0);
b6d96bed 2386 }
6ea83fed
FB
2387 break;
2388 case OPC_LDC1:
b6d96bed 2389 {
a7812ae4 2390 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2391 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2392 ctx->default_tcg_memop_mask);
b6d96bed 2393 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2394 tcg_temp_free_i64(fp0);
b6d96bed 2395 }
6ea83fed
FB
2396 break;
2397 case OPC_SDC1:
b6d96bed 2398 {
a7812ae4 2399 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2400 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2401 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2402 ctx->default_tcg_memop_mask);
a7812ae4 2403 tcg_temp_free_i64(fp0);
b6d96bed 2404 }
6ea83fed
FB
2405 break;
2406 default:
9d68ac14 2407 MIPS_INVAL("flt_ldst");
9c708c7f 2408 generate_exception_end(ctx, EXCP_RI);
78723684 2409 goto out;
6ea83fed 2410 }
78723684
TS
2411 out:
2412 tcg_temp_free(t0);
6ea83fed 2413}
6ea83fed 2414
5ab5c041
AJ
2415static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2416 int rs, int16_t imm)
26ebe468 2417{
5ab5c041 2418 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2419 check_cp1_enabled(ctx);
d9224450
MR
2420 switch (op) {
2421 case OPC_LDC1:
2422 case OPC_SDC1:
2423 check_insn(ctx, ISA_MIPS2);
2424 /* Fallthrough */
2425 default:
2426 gen_flt_ldst(ctx, op, rt, rs, imm);
2427 }
26ebe468
NF
2428 } else {
2429 generate_exception_err(ctx, EXCP_CpU, 1);
2430 }
2431}
2432
6af0bf9c 2433/* Arithmetic with immediate operand */
d75c135e
AJ
2434static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2435 int rt, int rs, int16_t imm)
6af0bf9c 2436{
324d9e32 2437 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2438
7a387fff 2439 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2440 /* If no destination, treat it as a NOP.
2441 For addi, we must generate the overflow exception when needed. */
324d9e32 2442 return;
6af0bf9c
FB
2443 }
2444 switch (opc) {
2445 case OPC_ADDI:
48d38ca5 2446 {
324d9e32
AJ
2447 TCGv t0 = tcg_temp_local_new();
2448 TCGv t1 = tcg_temp_new();
2449 TCGv t2 = tcg_temp_new();
42a268c2 2450 TCGLabel *l1 = gen_new_label();
48d38ca5 2451
324d9e32
AJ
2452 gen_load_gpr(t1, rs);
2453 tcg_gen_addi_tl(t0, t1, uimm);
2454 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2455
324d9e32
AJ
2456 tcg_gen_xori_tl(t1, t1, ~uimm);
2457 tcg_gen_xori_tl(t2, t0, uimm);
2458 tcg_gen_and_tl(t1, t1, t2);
2459 tcg_temp_free(t2);
2460 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2461 tcg_temp_free(t1);
48d38ca5
TS
2462 /* operands of same sign, result different sign */
2463 generate_exception(ctx, EXCP_OVERFLOW);
2464 gen_set_label(l1);
78723684 2465 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2466 gen_store_gpr(t0, rt);
2467 tcg_temp_free(t0);
48d38ca5 2468 }
6af0bf9c
FB
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 2477 break;
d26bc211 2478#if defined(TARGET_MIPS64)
7a387fff 2479 case OPC_DADDI:
48d38ca5 2480 {
324d9e32
AJ
2481 TCGv t0 = tcg_temp_local_new();
2482 TCGv t1 = tcg_temp_new();
2483 TCGv t2 = tcg_temp_new();
42a268c2 2484 TCGLabel *l1 = gen_new_label();
48d38ca5 2485
324d9e32
AJ
2486 gen_load_gpr(t1, rs);
2487 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2488
324d9e32
AJ
2489 tcg_gen_xori_tl(t1, t1, ~uimm);
2490 tcg_gen_xori_tl(t2, t0, uimm);
2491 tcg_gen_and_tl(t1, t1, t2);
2492 tcg_temp_free(t2);
2493 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2494 tcg_temp_free(t1);
48d38ca5
TS
2495 /* operands of same sign, result different sign */
2496 generate_exception(ctx, EXCP_OVERFLOW);
2497 gen_set_label(l1);
324d9e32
AJ
2498 gen_store_gpr(t0, rt);
2499 tcg_temp_free(t0);
48d38ca5 2500 }
7a387fff
TS
2501 break;
2502 case OPC_DADDIU:
324d9e32
AJ
2503 if (rs != 0) {
2504 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2505 } else {
2506 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2507 }
7a387fff
TS
2508 break;
2509#endif
324d9e32 2510 }
324d9e32
AJ
2511}
2512
2513/* Logic with immediate operand */
d75c135e 2514static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2515 int rt, int rs, int16_t imm)
324d9e32
AJ
2516{
2517 target_ulong uimm;
324d9e32
AJ
2518
2519 if (rt == 0) {
2520 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2521 return;
2522 }
2523 uimm = (uint16_t)imm;
2524 switch (opc) {
6af0bf9c 2525 case OPC_ANDI:
324d9e32
AJ
2526 if (likely(rs != 0))
2527 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2528 else
2529 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2530 break;
2531 case OPC_ORI:
324d9e32
AJ
2532 if (rs != 0)
2533 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2534 else
2535 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2536 break;
2537 case OPC_XORI:
324d9e32
AJ
2538 if (likely(rs != 0))
2539 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2540 else
2541 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2542 break;
2543 case OPC_LUI:
d4ea6acd
LA
2544 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2545 /* OPC_AUI */
2546 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2547 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2548 } else {
2549 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2550 }
7c2c3ea3
EJ
2551 break;
2552
2553 default:
6af0bf9c 2554 break;
324d9e32 2555 }
324d9e32
AJ
2556}
2557
2558/* Set on less than with immediate operand */
d75c135e 2559static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2560 int rt, int rs, int16_t imm)
324d9e32
AJ
2561{
2562 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2563 TCGv t0;
2564
2565 if (rt == 0) {
2566 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2567 return;
2568 }
2569 t0 = tcg_temp_new();
2570 gen_load_gpr(t0, rs);
2571 switch (opc) {
2572 case OPC_SLTI:
e68dd28f 2573 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2574 break;
2575 case OPC_SLTIU:
e68dd28f 2576 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2577 break;
2578 }
324d9e32
AJ
2579 tcg_temp_free(t0);
2580}
2581
2582/* Shifts with immediate operand */
d75c135e 2583static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2584 int rt, int rs, int16_t imm)
2585{
2586 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2587 TCGv t0;
2588
2589 if (rt == 0) {
2590 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2591 return;
2592 }
2593
2594 t0 = tcg_temp_new();
2595 gen_load_gpr(t0, rs);
2596 switch (opc) {
6af0bf9c 2597 case OPC_SLL:
78723684 2598 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2599 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2600 break;
2601 case OPC_SRA:
324d9e32 2602 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2603 break;
2604 case OPC_SRL:
ea63e2c3
NF
2605 if (uimm != 0) {
2606 tcg_gen_ext32u_tl(t0, t0);
2607 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2608 } else {
2609 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2610 }
ea63e2c3
NF
2611 break;
2612 case OPC_ROTR:
2613 if (uimm != 0) {
2614 TCGv_i32 t1 = tcg_temp_new_i32();
2615
2616 tcg_gen_trunc_tl_i32(t1, t0);
2617 tcg_gen_rotri_i32(t1, t1, uimm);
2618 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2619 tcg_temp_free_i32(t1);
3399e30f
NF
2620 } else {
2621 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2622 }
7a387fff 2623 break;
d26bc211 2624#if defined(TARGET_MIPS64)
7a387fff 2625 case OPC_DSLL:
324d9e32 2626 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2627 break;
2628 case OPC_DSRA:
324d9e32 2629 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2630 break;
2631 case OPC_DSRL:
ea63e2c3 2632 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2633 break;
2634 case OPC_DROTR:
2635 if (uimm != 0) {
2636 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2637 } else {
2638 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2639 }
7a387fff
TS
2640 break;
2641 case OPC_DSLL32:
324d9e32 2642 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2643 break;
2644 case OPC_DSRA32:
324d9e32 2645 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2646 break;
2647 case OPC_DSRL32:
ea63e2c3 2648 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2649 break;
2650 case OPC_DROTR32:
2651 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2652 break;
7a387fff 2653#endif
6af0bf9c 2654 }
78723684 2655 tcg_temp_free(t0);
6af0bf9c
FB
2656}
2657
2658/* Arithmetic */
d75c135e
AJ
2659static void gen_arith(DisasContext *ctx, uint32_t opc,
2660 int rd, int rs, int rt)
6af0bf9c 2661{
7a387fff
TS
2662 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2663 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2664 /* If no destination, treat it as a NOP.
2665 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2666 return;
185f0762 2667 }
460f00c4 2668
6af0bf9c
FB
2669 switch (opc) {
2670 case OPC_ADD:
48d38ca5 2671 {
460f00c4
AJ
2672 TCGv t0 = tcg_temp_local_new();
2673 TCGv t1 = tcg_temp_new();
2674 TCGv t2 = tcg_temp_new();
42a268c2 2675 TCGLabel *l1 = gen_new_label();
48d38ca5 2676
460f00c4
AJ
2677 gen_load_gpr(t1, rs);
2678 gen_load_gpr(t2, rt);
2679 tcg_gen_add_tl(t0, t1, t2);
2680 tcg_gen_ext32s_tl(t0, t0);
2681 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2682 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2683 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2684 tcg_temp_free(t2);
2685 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2686 tcg_temp_free(t1);
48d38ca5
TS
2687 /* operands of same sign, result different sign */
2688 generate_exception(ctx, EXCP_OVERFLOW);
2689 gen_set_label(l1);
460f00c4
AJ
2690 gen_store_gpr(t0, rd);
2691 tcg_temp_free(t0);
48d38ca5 2692 }
6af0bf9c
FB
2693 break;
2694 case OPC_ADDU:
460f00c4
AJ
2695 if (rs != 0 && rt != 0) {
2696 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2697 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2698 } else if (rs == 0 && rt != 0) {
2699 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2700 } else if (rs != 0 && rt == 0) {
2701 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2702 } else {
2703 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2704 }
6af0bf9c
FB
2705 break;
2706 case OPC_SUB:
48d38ca5 2707 {
460f00c4
AJ
2708 TCGv t0 = tcg_temp_local_new();
2709 TCGv t1 = tcg_temp_new();
2710 TCGv t2 = tcg_temp_new();
42a268c2 2711 TCGLabel *l1 = gen_new_label();
48d38ca5 2712
460f00c4
AJ
2713 gen_load_gpr(t1, rs);
2714 gen_load_gpr(t2, rt);
2715 tcg_gen_sub_tl(t0, t1, t2);
2716 tcg_gen_ext32s_tl(t0, t0);
2717 tcg_gen_xor_tl(t2, t1, t2);
2718 tcg_gen_xor_tl(t1, t0, t1);
2719 tcg_gen_and_tl(t1, t1, t2);
2720 tcg_temp_free(t2);
2721 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2722 tcg_temp_free(t1);
31e3104f 2723 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2724 generate_exception(ctx, EXCP_OVERFLOW);
2725 gen_set_label(l1);
460f00c4
AJ
2726 gen_store_gpr(t0, rd);
2727 tcg_temp_free(t0);
48d38ca5 2728 }
6af0bf9c
FB
2729 break;
2730 case OPC_SUBU:
460f00c4
AJ
2731 if (rs != 0 && rt != 0) {
2732 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2733 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2734 } else if (rs == 0 && rt != 0) {
2735 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2736 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2737 } else if (rs != 0 && rt == 0) {
2738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2739 } else {
2740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2741 }
6af0bf9c 2742 break;
d26bc211 2743#if defined(TARGET_MIPS64)
7a387fff 2744 case OPC_DADD:
48d38ca5 2745 {
460f00c4
AJ
2746 TCGv t0 = tcg_temp_local_new();
2747 TCGv t1 = tcg_temp_new();
2748 TCGv t2 = tcg_temp_new();
42a268c2 2749 TCGLabel *l1 = gen_new_label();
48d38ca5 2750
460f00c4
AJ
2751 gen_load_gpr(t1, rs);
2752 gen_load_gpr(t2, rt);
2753 tcg_gen_add_tl(t0, t1, t2);
2754 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2755 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2756 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2757 tcg_temp_free(t2);
2758 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2759 tcg_temp_free(t1);
48d38ca5
TS
2760 /* operands of same sign, result different sign */
2761 generate_exception(ctx, EXCP_OVERFLOW);
2762 gen_set_label(l1);
460f00c4
AJ
2763 gen_store_gpr(t0, rd);
2764 tcg_temp_free(t0);
48d38ca5 2765 }
7a387fff
TS
2766 break;
2767 case OPC_DADDU:
460f00c4
AJ
2768 if (rs != 0 && rt != 0) {
2769 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770 } else if (rs == 0 && rt != 0) {
2771 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2772 } else if (rs != 0 && rt == 0) {
2773 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2774 } else {
2775 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2776 }
7a387fff
TS
2777 break;
2778 case OPC_DSUB:
48d38ca5 2779 {
460f00c4
AJ
2780 TCGv t0 = tcg_temp_local_new();
2781 TCGv t1 = tcg_temp_new();
2782 TCGv t2 = tcg_temp_new();
42a268c2 2783 TCGLabel *l1 = gen_new_label();
48d38ca5 2784
460f00c4
AJ
2785 gen_load_gpr(t1, rs);
2786 gen_load_gpr(t2, rt);
2787 tcg_gen_sub_tl(t0, t1, t2);
2788 tcg_gen_xor_tl(t2, t1, t2);
2789 tcg_gen_xor_tl(t1, t0, t1);
2790 tcg_gen_and_tl(t1, t1, t2);
2791 tcg_temp_free(t2);
2792 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2793 tcg_temp_free(t1);
31e3104f 2794 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2795 generate_exception(ctx, EXCP_OVERFLOW);
2796 gen_set_label(l1);
460f00c4
AJ
2797 gen_store_gpr(t0, rd);
2798 tcg_temp_free(t0);
48d38ca5 2799 }
7a387fff
TS
2800 break;
2801 case OPC_DSUBU:
460f00c4
AJ
2802 if (rs != 0 && rt != 0) {
2803 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2804 } else if (rs == 0 && rt != 0) {
2805 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2806 } else if (rs != 0 && rt == 0) {
2807 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2808 } else {
2809 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2810 }
7a387fff
TS
2811 break;
2812#endif
460f00c4
AJ
2813 case OPC_MUL:
2814 if (likely(rs != 0 && rt != 0)) {
2815 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2816 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2817 } else {
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819 }
6af0bf9c 2820 break;
460f00c4 2821 }
460f00c4
AJ
2822}
2823
2824/* Conditional move */
d75c135e 2825static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2826 int rd, int rs, int rt)
460f00c4 2827{
acf12465 2828 TCGv t0, t1, t2;
460f00c4
AJ
2829
2830 if (rd == 0) {
acf12465 2831 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2832 return;
2833 }
2834
acf12465
AJ
2835 t0 = tcg_temp_new();
2836 gen_load_gpr(t0, rt);
2837 t1 = tcg_const_tl(0);
2838 t2 = tcg_temp_new();
2839 gen_load_gpr(t2, rs);
460f00c4
AJ
2840 switch (opc) {
2841 case OPC_MOVN:
acf12465 2842 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2843 break;
460f00c4 2844 case OPC_MOVZ:
acf12465 2845 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2846 break;
b691d9d2
LA
2847 case OPC_SELNEZ:
2848 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2849 break;
2850 case OPC_SELEQZ:
2851 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2852 break;
460f00c4 2853 }
acf12465
AJ
2854 tcg_temp_free(t2);
2855 tcg_temp_free(t1);
2856 tcg_temp_free(t0);
460f00c4
AJ
2857}
2858
2859/* Logic */
d75c135e 2860static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2861 int rd, int rs, int rt)
460f00c4 2862{
460f00c4
AJ
2863 if (rd == 0) {
2864 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2865 return;
2866 }
2867
2868 switch (opc) {
6af0bf9c 2869 case OPC_AND:
460f00c4
AJ
2870 if (likely(rs != 0 && rt != 0)) {
2871 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2872 } else {
2873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2874 }
6af0bf9c
FB
2875 break;
2876 case OPC_NOR:
460f00c4
AJ
2877 if (rs != 0 && rt != 0) {
2878 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2879 } else if (rs == 0 && rt != 0) {
2880 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2881 } else if (rs != 0 && rt == 0) {
2882 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2883 } else {
2884 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2885 }
6af0bf9c
FB
2886 break;
2887 case OPC_OR:
460f00c4
AJ
2888 if (likely(rs != 0 && rt != 0)) {
2889 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2890 } else if (rs == 0 && rt != 0) {
2891 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2892 } else if (rs != 0 && rt == 0) {
2893 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2894 } else {
2895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2896 }
6af0bf9c
FB
2897 break;
2898 case OPC_XOR:
460f00c4
AJ
2899 if (likely(rs != 0 && rt != 0)) {
2900 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2901 } else if (rs == 0 && rt != 0) {
2902 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2903 } else if (rs != 0 && rt == 0) {
2904 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2905 } else {
2906 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2907 }
6af0bf9c 2908 break;
460f00c4 2909 }
460f00c4
AJ
2910}
2911
2912/* Set on lower than */
d75c135e 2913static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2914 int rd, int rs, int rt)
460f00c4 2915{
460f00c4
AJ
2916 TCGv t0, t1;
2917
2918 if (rd == 0) {
2919 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2920 return;
2921 }
2922
2923 t0 = tcg_temp_new();
2924 t1 = tcg_temp_new();
2925 gen_load_gpr(t0, rs);
2926 gen_load_gpr(t1, rt);
2927 switch (opc) {
2928 case OPC_SLT:
e68dd28f 2929 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2930 break;
460f00c4 2931 case OPC_SLTU:
e68dd28f 2932 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2933 break;
2934 }
460f00c4
AJ
2935 tcg_temp_free(t0);
2936 tcg_temp_free(t1);
2937}
20c4c97c 2938
460f00c4 2939/* Shifts */
d75c135e
AJ
2940static void gen_shift(DisasContext *ctx, uint32_t opc,
2941 int rd, int rs, int rt)
460f00c4 2942{
460f00c4 2943 TCGv t0, t1;
20c4c97c 2944
460f00c4
AJ
2945 if (rd == 0) {
2946 /* If no destination, treat it as a NOP.
2947 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
2948 return;
2949 }
2950
2951 t0 = tcg_temp_new();
2952 t1 = tcg_temp_new();
2953 gen_load_gpr(t0, rs);
2954 gen_load_gpr(t1, rt);
2955 switch (opc) {
6af0bf9c 2956 case OPC_SLLV:
78723684
TS
2957 tcg_gen_andi_tl(t0, t0, 0x1f);
2958 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2959 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2960 break;
2961 case OPC_SRAV:
78723684 2962 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2963 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2964 break;
2965 case OPC_SRLV:
ea63e2c3
NF
2966 tcg_gen_ext32u_tl(t1, t1);
2967 tcg_gen_andi_tl(t0, t0, 0x1f);
2968 tcg_gen_shr_tl(t0, t1, t0);
2969 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2970 break;
2971 case OPC_ROTRV:
2972 {
2973 TCGv_i32 t2 = tcg_temp_new_i32();
2974 TCGv_i32 t3 = tcg_temp_new_i32();
2975
2976 tcg_gen_trunc_tl_i32(t2, t0);
2977 tcg_gen_trunc_tl_i32(t3, t1);
2978 tcg_gen_andi_i32(t2, t2, 0x1f);
2979 tcg_gen_rotr_i32(t2, t3, t2);
2980 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2981 tcg_temp_free_i32(t2);
2982 tcg_temp_free_i32(t3);
5a63bcb2 2983 }
7a387fff 2984 break;
d26bc211 2985#if defined(TARGET_MIPS64)
7a387fff 2986 case OPC_DSLLV:
78723684 2987 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2988 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2989 break;
2990 case OPC_DSRAV:
78723684 2991 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2992 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2993 break;
2994 case OPC_DSRLV:
ea63e2c3
NF
2995 tcg_gen_andi_tl(t0, t0, 0x3f);
2996 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
2997 break;
2998 case OPC_DROTRV:
2999 tcg_gen_andi_tl(t0, t0, 0x3f);
3000 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3001 break;
7a387fff 3002#endif
6af0bf9c 3003 }
78723684
TS
3004 tcg_temp_free(t0);
3005 tcg_temp_free(t1);
6af0bf9c
FB
3006}
3007
3008/* Arithmetic on HI/LO registers */
26135ead 3009static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3010{
6af0bf9c 3011 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3012 /* Treat as NOP. */
a1f6684d 3013 return;
6af0bf9c 3014 }
4133498f 3015
4133498f
JL
3016 if (acc != 0) {
3017 check_dsp(ctx);
3018 }
3019
6af0bf9c
FB
3020 switch (opc) {
3021 case OPC_MFHI:
4133498f
JL
3022#if defined(TARGET_MIPS64)
3023 if (acc != 0) {
3024 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3025 } else
3026#endif
3027 {
3028 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3029 }
6af0bf9c
FB
3030 break;
3031 case OPC_MFLO:
4133498f
JL
3032#if defined(TARGET_MIPS64)
3033 if (acc != 0) {
3034 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3035 } else
3036#endif
3037 {
3038 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3039 }
6af0bf9c
FB
3040 break;
3041 case OPC_MTHI:
4133498f
JL
3042 if (reg != 0) {
3043#if defined(TARGET_MIPS64)
3044 if (acc != 0) {
3045 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3046 } else
3047#endif
3048 {
3049 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3050 }
3051 } else {
3052 tcg_gen_movi_tl(cpu_HI[acc], 0);
3053 }
6af0bf9c
FB
3054 break;
3055 case OPC_MTLO:
4133498f
JL
3056 if (reg != 0) {
3057#if defined(TARGET_MIPS64)
3058 if (acc != 0) {
3059 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3060 } else
3061#endif
3062 {
3063 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3064 }
3065 } else {
3066 tcg_gen_movi_tl(cpu_LO[acc], 0);
3067 }
6af0bf9c 3068 break;
6af0bf9c 3069 }
6af0bf9c
FB
3070}
3071
d4ea6acd
LA
3072static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3073 TCGMemOp memop)
3074{
3075 TCGv t0 = tcg_const_tl(addr);
3076 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3077 gen_store_gpr(t0, reg);
3078 tcg_temp_free(t0);
3079}
3080
ab39ee45
YK
3081static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3082 int rs)
d4ea6acd
LA
3083{
3084 target_long offset;
3085 target_long addr;
3086
ab39ee45 3087 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3088 case OPC_ADDIUPC:
3089 if (rs != 0) {
3090 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3091 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3092 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3093 }
3094 break;
3095 case R6_OPC_LWPC:
3096 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3097 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3098 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3099 break;
3100#if defined(TARGET_MIPS64)
3101 case OPC_LWUPC:
3102 check_mips_64(ctx);
3103 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3104 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3105 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3106 break;
3107#endif
3108 default:
ab39ee45 3109 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3110 case OPC_AUIPC:
3111 if (rs != 0) {
ab39ee45
YK
3112 offset = sextract32(ctx->opcode, 0, 16) << 16;
3113 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3114 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3115 }
3116 break;
3117 case OPC_ALUIPC:
3118 if (rs != 0) {
ab39ee45
YK
3119 offset = sextract32(ctx->opcode, 0, 16) << 16;
3120 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3121 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3122 }
3123 break;
3124#if defined(TARGET_MIPS64)
3125 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3126 case R6_OPC_LDPC + (1 << 16):
3127 case R6_OPC_LDPC + (2 << 16):
3128 case R6_OPC_LDPC + (3 << 16):
3129 check_mips_64(ctx);
3130 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3131 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3132 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3133 break;
3134#endif
3135 default:
3136 MIPS_INVAL("OPC_PCREL");
9c708c7f 3137 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3138 break;
3139 }
3140 break;
3141 }
3142}
3143
b42ee5e1
LA
3144static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3145{
b42ee5e1
LA
3146 TCGv t0, t1;
3147
3148 if (rd == 0) {
3149 /* Treat as NOP. */
b42ee5e1
LA
3150 return;
3151 }
3152
3153 t0 = tcg_temp_new();
3154 t1 = tcg_temp_new();
3155
3156 gen_load_gpr(t0, rs);
3157 gen_load_gpr(t1, rt);
3158
3159 switch (opc) {
3160 case R6_OPC_DIV:
3161 {
3162 TCGv t2 = tcg_temp_new();
3163 TCGv t3 = tcg_temp_new();
3164 tcg_gen_ext32s_tl(t0, t0);
3165 tcg_gen_ext32s_tl(t1, t1);
3166 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3167 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3168 tcg_gen_and_tl(t2, t2, t3);
3169 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3170 tcg_gen_or_tl(t2, t2, t3);
3171 tcg_gen_movi_tl(t3, 0);
3172 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3173 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3174 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3175 tcg_temp_free(t3);
3176 tcg_temp_free(t2);
3177 }
b42ee5e1
LA
3178 break;
3179 case R6_OPC_MOD:
3180 {
3181 TCGv t2 = tcg_temp_new();
3182 TCGv t3 = tcg_temp_new();
3183 tcg_gen_ext32s_tl(t0, t0);
3184 tcg_gen_ext32s_tl(t1, t1);
3185 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3186 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3187 tcg_gen_and_tl(t2, t2, t3);
3188 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3189 tcg_gen_or_tl(t2, t2, t3);
3190 tcg_gen_movi_tl(t3, 0);
3191 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3192 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3193 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3194 tcg_temp_free(t3);
3195 tcg_temp_free(t2);
3196 }
b42ee5e1
LA
3197 break;
3198 case R6_OPC_DIVU:
3199 {
3200 TCGv t2 = tcg_const_tl(0);
3201 TCGv t3 = tcg_const_tl(1);
3202 tcg_gen_ext32u_tl(t0, t0);
3203 tcg_gen_ext32u_tl(t1, t1);
3204 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3205 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3206 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3207 tcg_temp_free(t3);
3208 tcg_temp_free(t2);
3209 }
b42ee5e1
LA
3210 break;
3211 case R6_OPC_MODU:
3212 {
3213 TCGv t2 = tcg_const_tl(0);
3214 TCGv t3 = tcg_const_tl(1);
3215 tcg_gen_ext32u_tl(t0, t0);
3216 tcg_gen_ext32u_tl(t1, t1);
3217 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3218 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3219 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3220 tcg_temp_free(t3);
3221 tcg_temp_free(t2);
3222 }
b42ee5e1
LA
3223 break;
3224 case R6_OPC_MUL:
3225 {
3226 TCGv_i32 t2 = tcg_temp_new_i32();
3227 TCGv_i32 t3 = tcg_temp_new_i32();
3228 tcg_gen_trunc_tl_i32(t2, t0);
3229 tcg_gen_trunc_tl_i32(t3, t1);
3230 tcg_gen_mul_i32(t2, t2, t3);
3231 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3232 tcg_temp_free_i32(t2);
3233 tcg_temp_free_i32(t3);
3234 }
b42ee5e1
LA
3235 break;
3236 case R6_OPC_MUH:
3237 {
3238 TCGv_i32 t2 = tcg_temp_new_i32();
3239 TCGv_i32 t3 = tcg_temp_new_i32();
3240 tcg_gen_trunc_tl_i32(t2, t0);
3241 tcg_gen_trunc_tl_i32(t3, t1);
3242 tcg_gen_muls2_i32(t2, t3, t2, t3);
3243 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3244 tcg_temp_free_i32(t2);
3245 tcg_temp_free_i32(t3);
3246 }
b42ee5e1
LA
3247 break;
3248 case R6_OPC_MULU:
3249 {
3250 TCGv_i32 t2 = tcg_temp_new_i32();
3251 TCGv_i32 t3 = tcg_temp_new_i32();
3252 tcg_gen_trunc_tl_i32(t2, t0);
3253 tcg_gen_trunc_tl_i32(t3, t1);
3254 tcg_gen_mul_i32(t2, t2, t3);
3255 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3256 tcg_temp_free_i32(t2);
3257 tcg_temp_free_i32(t3);
3258 }
b42ee5e1
LA
3259 break;
3260 case R6_OPC_MUHU:
3261 {
3262 TCGv_i32 t2 = tcg_temp_new_i32();
3263 TCGv_i32 t3 = tcg_temp_new_i32();
3264 tcg_gen_trunc_tl_i32(t2, t0);
3265 tcg_gen_trunc_tl_i32(t3, t1);
3266 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3267 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3268 tcg_temp_free_i32(t2);
3269 tcg_temp_free_i32(t3);
3270 }
b42ee5e1
LA
3271 break;
3272#if defined(TARGET_MIPS64)
3273 case R6_OPC_DDIV:
3274 {
3275 TCGv t2 = tcg_temp_new();
3276 TCGv t3 = tcg_temp_new();
3277 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3278 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3279 tcg_gen_and_tl(t2, t2, t3);
3280 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3281 tcg_gen_or_tl(t2, t2, t3);
3282 tcg_gen_movi_tl(t3, 0);
3283 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3284 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3285 tcg_temp_free(t3);
3286 tcg_temp_free(t2);
3287 }
b42ee5e1
LA
3288 break;
3289 case R6_OPC_DMOD:
3290 {
3291 TCGv t2 = tcg_temp_new();
3292 TCGv t3 = tcg_temp_new();
3293 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3294 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3295 tcg_gen_and_tl(t2, t2, t3);
3296 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3297 tcg_gen_or_tl(t2, t2, t3);
3298 tcg_gen_movi_tl(t3, 0);
3299 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3300 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3301 tcg_temp_free(t3);
3302 tcg_temp_free(t2);
3303 }
b42ee5e1
LA
3304 break;
3305 case R6_OPC_DDIVU:
3306 {
3307 TCGv t2 = tcg_const_tl(0);
3308 TCGv t3 = tcg_const_tl(1);
3309 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3310 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3311 tcg_temp_free(t3);
3312 tcg_temp_free(t2);
3313 }
b42ee5e1
LA
3314 break;
3315 case R6_OPC_DMODU:
3316 {
3317 TCGv t2 = tcg_const_tl(0);
3318 TCGv t3 = tcg_const_tl(1);
3319 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3320 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3321 tcg_temp_free(t3);
3322 tcg_temp_free(t2);
3323 }
b42ee5e1
LA
3324 break;
3325 case R6_OPC_DMUL:
3326 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3327 break;
3328 case R6_OPC_DMUH:
3329 {
3330 TCGv t2 = tcg_temp_new();
3331 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3332 tcg_temp_free(t2);
3333 }
b42ee5e1
LA
3334 break;
3335 case R6_OPC_DMULU:
3336 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3337 break;
3338 case R6_OPC_DMUHU:
3339 {
3340 TCGv t2 = tcg_temp_new();
3341 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3342 tcg_temp_free(t2);
3343 }
b42ee5e1
LA
3344 break;
3345#endif
3346 default:
9d68ac14 3347 MIPS_INVAL("r6 mul/div");
9c708c7f 3348 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3349 goto out;
3350 }
b42ee5e1
LA
3351 out:
3352 tcg_temp_free(t0);
3353 tcg_temp_free(t1);
3354}
3355
26135ead
RS
3356static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3357 int acc, int rs, int rt)
6af0bf9c 3358{
d45f89f4
AJ
3359 TCGv t0, t1;
3360
51127181
AJ
3361 t0 = tcg_temp_new();
3362 t1 = tcg_temp_new();
6af0bf9c 3363
78723684
TS
3364 gen_load_gpr(t0, rs);
3365 gen_load_gpr(t1, rt);
51127181 3366
26135ead
RS
3367 if (acc != 0) {
3368 check_dsp(ctx);
3369 }
3370
6af0bf9c
FB
3371 switch (opc) {
3372 case OPC_DIV:
48d38ca5 3373 {
51127181
AJ
3374 TCGv t2 = tcg_temp_new();
3375 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3376 tcg_gen_ext32s_tl(t0, t0);
3377 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3378 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3380 tcg_gen_and_tl(t2, t2, t3);
3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3382 tcg_gen_or_tl(t2, t2, t3);
3383 tcg_gen_movi_tl(t3, 0);
3384 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3385 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3386 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3387 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3388 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3389 tcg_temp_free(t3);
3390 tcg_temp_free(t2);
48d38ca5 3391 }
6af0bf9c
FB
3392 break;
3393 case OPC_DIVU:
48d38ca5 3394 {
51127181
AJ
3395 TCGv t2 = tcg_const_tl(0);
3396 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3397 tcg_gen_ext32u_tl(t0, t0);
3398 tcg_gen_ext32u_tl(t1, t1);
51127181 3399 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3400 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3401 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3402 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3403 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3404 tcg_temp_free(t3);
3405 tcg_temp_free(t2);
48d38ca5 3406 }
6af0bf9c
FB
3407 break;
3408 case OPC_MULT:
214c465f 3409 {
ce1dd5d1
RH
3410 TCGv_i32 t2 = tcg_temp_new_i32();
3411 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3412 tcg_gen_trunc_tl_i32(t2, t0);
3413 tcg_gen_trunc_tl_i32(t3, t1);
3414 tcg_gen_muls2_i32(t2, t3, t2, t3);
3415 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3416 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3417 tcg_temp_free_i32(t2);
3418 tcg_temp_free_i32(t3);
214c465f 3419 }
6af0bf9c
FB
3420 break;
3421 case OPC_MULTU:
214c465f 3422 {
ce1dd5d1
RH
3423 TCGv_i32 t2 = tcg_temp_new_i32();
3424 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3425 tcg_gen_trunc_tl_i32(t2, t0);
3426 tcg_gen_trunc_tl_i32(t3, t1);
3427 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3428 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3429 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3430 tcg_temp_free_i32(t2);
3431 tcg_temp_free_i32(t3);
214c465f 3432 }
6af0bf9c 3433 break;
d26bc211 3434#if defined(TARGET_MIPS64)
7a387fff 3435 case OPC_DDIV:
48d38ca5 3436 {
51127181
AJ
3437 TCGv t2 = tcg_temp_new();
3438 TCGv t3 = tcg_temp_new();
3439 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3440 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3441 tcg_gen_and_tl(t2, t2, t3);
3442 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3443 tcg_gen_or_tl(t2, t2, t3);
3444 tcg_gen_movi_tl(t3, 0);
3445 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3446 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3447 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3448 tcg_temp_free(t3);
3449 tcg_temp_free(t2);
48d38ca5 3450 }
7a387fff
TS
3451 break;
3452 case OPC_DDIVU:
48d38ca5 3453 {
51127181
AJ
3454 TCGv t2 = tcg_const_tl(0);
3455 TCGv t3 = tcg_const_tl(1);
3456 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3457 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3458 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3459 tcg_temp_free(t3);
3460 tcg_temp_free(t2);
48d38ca5 3461 }
7a387fff
TS
3462 break;
3463 case OPC_DMULT:
26135ead 3464 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3465 break;
3466 case OPC_DMULTU:
26135ead 3467 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3468 break;
3469#endif
6af0bf9c 3470 case OPC_MADD:
214c465f 3471 {
d45f89f4
AJ
3472 TCGv_i64 t2 = tcg_temp_new_i64();
3473 TCGv_i64 t3 = tcg_temp_new_i64();
3474
3475 tcg_gen_ext_tl_i64(t2, t0);
3476 tcg_gen_ext_tl_i64(t3, t1);
3477 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3478 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3479 tcg_gen_add_i64(t2, t2, t3);
3480 tcg_temp_free_i64(t3);
71f303cd
RH
3481 gen_move_low32(cpu_LO[acc], t2);
3482 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3483 tcg_temp_free_i64(t2);
214c465f 3484 }
6af0bf9c
FB
3485 break;
3486 case OPC_MADDU:
4133498f 3487 {
d45f89f4
AJ
3488 TCGv_i64 t2 = tcg_temp_new_i64();
3489 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3490
78723684
TS
3491 tcg_gen_ext32u_tl(t0, t0);
3492 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3493 tcg_gen_extu_tl_i64(t2, t0);
3494 tcg_gen_extu_tl_i64(t3, t1);
3495 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3496 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3497 tcg_gen_add_i64(t2, t2, t3);
3498 tcg_temp_free_i64(t3);
71f303cd
RH
3499 gen_move_low32(cpu_LO[acc], t2);
3500 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3501 tcg_temp_free_i64(t2);
214c465f 3502 }
6af0bf9c
FB
3503 break;
3504 case OPC_MSUB:
214c465f 3505 {
d45f89f4
AJ
3506 TCGv_i64 t2 = tcg_temp_new_i64();
3507 TCGv_i64 t3 = tcg_temp_new_i64();
3508
3509 tcg_gen_ext_tl_i64(t2, t0);
3510 tcg_gen_ext_tl_i64(t3, t1);
3511 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3512 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3513 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3514 tcg_temp_free_i64(t3);
71f303cd
RH
3515 gen_move_low32(cpu_LO[acc], t2);
3516 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3517 tcg_temp_free_i64(t2);
214c465f 3518 }
6af0bf9c
FB
3519 break;
3520 case OPC_MSUBU:
214c465f 3521 {
d45f89f4
AJ
3522 TCGv_i64 t2 = tcg_temp_new_i64();
3523 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3524
78723684
TS
3525 tcg_gen_ext32u_tl(t0, t0);
3526 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3527 tcg_gen_extu_tl_i64(t2, t0);
3528 tcg_gen_extu_tl_i64(t3, t1);
3529 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3530 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3531 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3532 tcg_temp_free_i64(t3);
71f303cd
RH
3533 gen_move_low32(cpu_LO[acc], t2);
3534 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3535 tcg_temp_free_i64(t2);
214c465f 3536 }
6af0bf9c
FB
3537 break;
3538 default:
9d68ac14 3539 MIPS_INVAL("mul/div");
9c708c7f 3540 generate_exception_end(ctx, EXCP_RI);
78723684 3541 goto out;
6af0bf9c 3542 }
78723684
TS
3543 out:
3544 tcg_temp_free(t0);
3545 tcg_temp_free(t1);
6af0bf9c
FB
3546}
3547
e9c71dd1
TS
3548static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3549 int rd, int rs, int rt)
3550{
f157bfe1
AJ
3551 TCGv t0 = tcg_temp_new();
3552 TCGv t1 = tcg_temp_new();
e9c71dd1 3553
6c5c1e20
TS
3554 gen_load_gpr(t0, rs);
3555 gen_load_gpr(t1, rt);
e9c71dd1
TS
3556
3557 switch (opc) {
3558 case OPC_VR54XX_MULS:
895c2d04 3559 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3560 break;
e9c71dd1 3561 case OPC_VR54XX_MULSU:
895c2d04 3562 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3563 break;
e9c71dd1 3564 case OPC_VR54XX_MACC:
895c2d04 3565 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3566 break;
e9c71dd1 3567 case OPC_VR54XX_MACCU:
895c2d04 3568 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3569 break;
e9c71dd1 3570 case OPC_VR54XX_MSAC:
895c2d04 3571 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3572 break;
e9c71dd1 3573 case OPC_VR54XX_MSACU:
895c2d04 3574 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3575 break;
e9c71dd1 3576 case OPC_VR54XX_MULHI:
895c2d04 3577 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3578 break;
e9c71dd1 3579 case OPC_VR54XX_MULHIU:
895c2d04 3580 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3581 break;
e9c71dd1 3582 case OPC_VR54XX_MULSHI:
895c2d04 3583 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3584 break;
e9c71dd1 3585 case OPC_VR54XX_MULSHIU:
895c2d04 3586 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3587 break;
e9c71dd1 3588 case OPC_VR54XX_MACCHI:
895c2d04 3589 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3590 break;
e9c71dd1 3591 case OPC_VR54XX_MACCHIU:
895c2d04 3592 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3593 break;
e9c71dd1 3594 case OPC_VR54XX_MSACHI:
895c2d04 3595 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3596 break;
e9c71dd1 3597 case OPC_VR54XX_MSACHIU:
895c2d04 3598 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3599 break;
e9c71dd1
TS
3600 default:
3601 MIPS_INVAL("mul vr54xx");
9c708c7f 3602 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3603 goto out;
e9c71dd1 3604 }
6c5c1e20 3605 gen_store_gpr(t0, rd);
6c5c1e20
TS
3606
3607 out:
3608 tcg_temp_free(t0);
3609 tcg_temp_free(t1);
e9c71dd1
TS
3610}
3611
7a387fff 3612static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3613 int rd, int rs)
3614{
20e1fb52 3615 TCGv t0;
6c5c1e20 3616
6af0bf9c 3617 if (rd == 0) {
ead9360e 3618 /* Treat as NOP. */
20e1fb52 3619 return;
6af0bf9c 3620 }
20e1fb52 3621 t0 = tcg_temp_new();
6c5c1e20 3622 gen_load_gpr(t0, rs);
6af0bf9c
FB
3623 switch (opc) {
3624 case OPC_CLO:
4267d3e6 3625 case R6_OPC_CLO:
20e1fb52 3626 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3627 break;
3628 case OPC_CLZ:
4267d3e6 3629 case R6_OPC_CLZ:
20e1fb52 3630 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c 3631 break;
d26bc211 3632#if defined(TARGET_MIPS64)
7a387fff 3633 case OPC_DCLO:
4267d3e6 3634 case R6_OPC_DCLO:
20e1fb52 3635 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3636 break;
3637 case OPC_DCLZ:
4267d3e6 3638 case R6_OPC_DCLZ:
20e1fb52 3639 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3640 break;
3641#endif
6af0bf9c 3642 }
6c5c1e20 3643 tcg_temp_free(t0);
6af0bf9c
FB
3644}
3645
161f85e6 3646/* Godson integer instructions */
bd277fa1
RH
3647static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3648 int rd, int rs, int rt)
161f85e6 3649{
161f85e6
AJ
3650 TCGv t0, t1;
3651
3652 if (rd == 0) {
3653 /* Treat as NOP. */
161f85e6
AJ
3654 return;
3655 }
3656
3657 switch (opc) {
3658 case OPC_MULT_G_2E:
3659 case OPC_MULT_G_2F:
3660 case OPC_MULTU_G_2E:
3661 case OPC_MULTU_G_2F:
3662#if defined(TARGET_MIPS64)
3663 case OPC_DMULT_G_2E:
3664 case OPC_DMULT_G_2F:
3665 case OPC_DMULTU_G_2E:
3666 case OPC_DMULTU_G_2F:
3667#endif
3668 t0 = tcg_temp_new();
3669 t1 = tcg_temp_new();
3670 break;
3671 default:
3672 t0 = tcg_temp_local_new();
3673 t1 = tcg_temp_local_new();
3674 break;
3675 }
3676
3677 gen_load_gpr(t0, rs);
3678 gen_load_gpr(t1, rt);
3679
3680 switch (opc) {
3681 case OPC_MULT_G_2E:
3682 case OPC_MULT_G_2F:
3683 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3684 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3685 break;
3686 case OPC_MULTU_G_2E:
3687 case OPC_MULTU_G_2F:
3688 tcg_gen_ext32u_tl(t0, t0);
3689 tcg_gen_ext32u_tl(t1, t1);
3690 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3691 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3692 break;
3693 case OPC_DIV_G_2E:
3694 case OPC_DIV_G_2F:
3695 {
42a268c2
RH
3696 TCGLabel *l1 = gen_new_label();
3697 TCGLabel *l2 = gen_new_label();
3698 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3699 tcg_gen_ext32s_tl(t0, t0);
3700 tcg_gen_ext32s_tl(t1, t1);
3701 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3702 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3703 tcg_gen_br(l3);
3704 gen_set_label(l1);
3705 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3706 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3707 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3708 tcg_gen_br(l3);
3709 gen_set_label(l2);
3710 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3711 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3712 gen_set_label(l3);
3713 }
161f85e6
AJ
3714 break;
3715 case OPC_DIVU_G_2E:
3716 case OPC_DIVU_G_2F:
3717 {
42a268c2
RH
3718 TCGLabel *l1 = gen_new_label();
3719 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3720 tcg_gen_ext32u_tl(t0, t0);
3721 tcg_gen_ext32u_tl(t1, t1);
3722 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3723 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3724 tcg_gen_br(l2);
3725 gen_set_label(l1);
3726 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3727 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3728 gen_set_label(l2);
3729 }
161f85e6
AJ
3730 break;
3731 case OPC_MOD_G_2E:
3732 case OPC_MOD_G_2F:
3733 {
42a268c2
RH
3734 TCGLabel *l1 = gen_new_label();
3735 TCGLabel *l2 = gen_new_label();
3736 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3737 tcg_gen_ext32u_tl(t0, t0);
3738 tcg_gen_ext32u_tl(t1, t1);
3739 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3740 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3741 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3742 gen_set_label(l1);
3743 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3744 tcg_gen_br(l3);
3745 gen_set_label(l2);
3746 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3747 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3748 gen_set_label(l3);
3749 }
161f85e6
AJ
3750 break;
3751 case OPC_MODU_G_2E:
3752 case OPC_MODU_G_2F:
3753 {
42a268c2
RH
3754 TCGLabel *l1 = gen_new_label();
3755 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3756 tcg_gen_ext32u_tl(t0, t0);
3757 tcg_gen_ext32u_tl(t1, t1);
3758 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3759 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3760 tcg_gen_br(l2);
3761 gen_set_label(l1);
3762 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3763 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3764 gen_set_label(l2);
3765 }
161f85e6
AJ
3766 break;
3767#if defined(TARGET_MIPS64)
3768 case OPC_DMULT_G_2E:
3769 case OPC_DMULT_G_2F:
3770 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3771 break;
3772 case OPC_DMULTU_G_2E:
3773 case OPC_DMULTU_G_2F:
3774 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3775 break;
3776 case OPC_DDIV_G_2E:
3777 case OPC_DDIV_G_2F:
3778 {
42a268c2
RH
3779 TCGLabel *l1 = gen_new_label();
3780 TCGLabel *l2 = gen_new_label();
3781 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3782 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3784 tcg_gen_br(l3);
3785 gen_set_label(l1);
3786 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3787 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3788 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3789 tcg_gen_br(l3);
3790 gen_set_label(l2);
3791 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3792 gen_set_label(l3);
3793 }
161f85e6
AJ
3794 break;
3795 case OPC_DDIVU_G_2E:
3796 case OPC_DDIVU_G_2F:
3797 {
42a268c2
RH
3798 TCGLabel *l1 = gen_new_label();
3799 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3802 tcg_gen_br(l2);
3803 gen_set_label(l1);
3804 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3805 gen_set_label(l2);
3806 }
161f85e6
AJ
3807 break;
3808 case OPC_DMOD_G_2E:
3809 case OPC_DMOD_G_2F:
3810 {
42a268c2
RH
3811 TCGLabel *l1 = gen_new_label();
3812 TCGLabel *l2 = gen_new_label();
3813 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3814 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3815 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3816 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3817 gen_set_label(l1);
3818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3819 tcg_gen_br(l3);
3820 gen_set_label(l2);
3821 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3822 gen_set_label(l3);
3823 }
161f85e6
AJ
3824 break;
3825 case OPC_DMODU_G_2E:
3826 case OPC_DMODU_G_2F:
3827 {
42a268c2
RH
3828 TCGLabel *l1 = gen_new_label();
3829 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3830 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3831 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3832 tcg_gen_br(l2);
3833 gen_set_label(l1);
3834 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3835 gen_set_label(l2);
3836 }
161f85e6
AJ
3837 break;
3838#endif
3839 }
3840
161f85e6
AJ
3841 tcg_temp_free(t0);
3842 tcg_temp_free(t1);
3843}
3844
bd277fa1
RH
3845/* Loongson multimedia instructions */
3846static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3847{
bd277fa1
RH
3848 uint32_t opc, shift_max;
3849 TCGv_i64 t0, t1;
3850
3851 opc = MASK_LMI(ctx->opcode);
3852 switch (opc) {
3853 case OPC_ADD_CP2:
3854 case OPC_SUB_CP2:
3855 case OPC_DADD_CP2:
3856 case OPC_DSUB_CP2:
3857 t0 = tcg_temp_local_new_i64();
3858 t1 = tcg_temp_local_new_i64();
3859 break;
3860 default:
3861 t0 = tcg_temp_new_i64();
3862 t1 = tcg_temp_new_i64();
3863 break;
3864 }
3865
3866 gen_load_fpr64(ctx, t0, rs);
3867 gen_load_fpr64(ctx, t1, rt);
3868
3869#define LMI_HELPER(UP, LO) \
9d68ac14 3870 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3871#define LMI_HELPER_1(UP, LO) \
9d68ac14 3872 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3873#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3874 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3875
3876 switch (opc) {
3877 LMI_HELPER(PADDSH, paddsh);
3878 LMI_HELPER(PADDUSH, paddush);
3879 LMI_HELPER(PADDH, paddh);
3880 LMI_HELPER(PADDW, paddw);
3881 LMI_HELPER(PADDSB, paddsb);
3882 LMI_HELPER(PADDUSB, paddusb);
3883 LMI_HELPER(PADDB, paddb);
3884
3885 LMI_HELPER(PSUBSH, psubsh);
3886 LMI_HELPER(PSUBUSH, psubush);
3887 LMI_HELPER(PSUBH, psubh);
3888 LMI_HELPER(PSUBW, psubw);
3889 LMI_HELPER(PSUBSB, psubsb);
3890 LMI_HELPER(PSUBUSB, psubusb);
3891 LMI_HELPER(PSUBB, psubb);
3892
3893 LMI_HELPER(PSHUFH, pshufh);
3894 LMI_HELPER(PACKSSWH, packsswh);
3895 LMI_HELPER(PACKSSHB, packsshb);
3896 LMI_HELPER(PACKUSHB, packushb);
3897
3898 LMI_HELPER(PUNPCKLHW, punpcklhw);
3899 LMI_HELPER(PUNPCKHHW, punpckhhw);
3900 LMI_HELPER(PUNPCKLBH, punpcklbh);
3901 LMI_HELPER(PUNPCKHBH, punpckhbh);
3902 LMI_HELPER(PUNPCKLWD, punpcklwd);
3903 LMI_HELPER(PUNPCKHWD, punpckhwd);
3904
3905 LMI_HELPER(PAVGH, pavgh);
3906 LMI_HELPER(PAVGB, pavgb);
3907 LMI_HELPER(PMAXSH, pmaxsh);
3908 LMI_HELPER(PMINSH, pminsh);
3909 LMI_HELPER(PMAXUB, pmaxub);
3910 LMI_HELPER(PMINUB, pminub);
3911
3912 LMI_HELPER(PCMPEQW, pcmpeqw);
3913 LMI_HELPER(PCMPGTW, pcmpgtw);
3914 LMI_HELPER(PCMPEQH, pcmpeqh);
3915 LMI_HELPER(PCMPGTH, pcmpgth);
3916 LMI_HELPER(PCMPEQB, pcmpeqb);
3917 LMI_HELPER(PCMPGTB, pcmpgtb);
3918
3919 LMI_HELPER(PSLLW, psllw);
3920 LMI_HELPER(PSLLH, psllh);
3921 LMI_HELPER(PSRLW, psrlw);
3922 LMI_HELPER(PSRLH, psrlh);
3923 LMI_HELPER(PSRAW, psraw);
3924 LMI_HELPER(PSRAH, psrah);
3925
3926 LMI_HELPER(PMULLH, pmullh);
3927 LMI_HELPER(PMULHH, pmulhh);
3928 LMI_HELPER(PMULHUH, pmulhuh);
3929 LMI_HELPER(PMADDHW, pmaddhw);
3930
3931 LMI_HELPER(PASUBUB, pasubub);
3932 LMI_HELPER_1(BIADD, biadd);
3933 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3934
3935 LMI_DIRECT(PADDD, paddd, add);
3936 LMI_DIRECT(PSUBD, psubd, sub);
3937 LMI_DIRECT(XOR_CP2, xor, xor);
3938 LMI_DIRECT(NOR_CP2, nor, nor);
3939 LMI_DIRECT(AND_CP2, and, and);
3940 LMI_DIRECT(PANDN, pandn, andc);
3941 LMI_DIRECT(OR, or, or);
3942
3943 case OPC_PINSRH_0:
3944 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3945 break;
3946 case OPC_PINSRH_1:
3947 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3948 break;
3949 case OPC_PINSRH_2:
3950 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3951 break;
3952 case OPC_PINSRH_3:
3953 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3954 break;
3955
3956 case OPC_PEXTRH:
3957 tcg_gen_andi_i64(t1, t1, 3);
3958 tcg_gen_shli_i64(t1, t1, 4);
3959 tcg_gen_shr_i64(t0, t0, t1);
3960 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3961 break;
3962
3963 case OPC_ADDU_CP2:
3964 tcg_gen_add_i64(t0, t0, t1);
3965 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3966 break;
3967 case OPC_SUBU_CP2:
3968 tcg_gen_sub_i64(t0, t0, t1);
3969 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3970 break;
3971
3972 case OPC_SLL_CP2:
bd277fa1
RH
3973 shift_max = 32;
3974 goto do_shift;
3975 case OPC_SRL_CP2:
bd277fa1
RH
3976 shift_max = 32;
3977 goto do_shift;
3978 case OPC_SRA_CP2:
bd277fa1
RH
3979 shift_max = 32;
3980 goto do_shift;
3981 case OPC_DSLL_CP2:
bd277fa1
RH
3982 shift_max = 64;
3983 goto do_shift;
3984 case OPC_DSRL_CP2:
bd277fa1
RH
3985 shift_max = 64;
3986 goto do_shift;
3987 case OPC_DSRA_CP2:
bd277fa1
RH
3988 shift_max = 64;
3989 goto do_shift;
3990 do_shift:
3991 /* Make sure shift count isn't TCG undefined behaviour. */
3992 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3993
3994 switch (opc) {
3995 case OPC_SLL_CP2:
3996 case OPC_DSLL_CP2:
3997 tcg_gen_shl_i64(t0, t0, t1);
3998 break;
3999 case OPC_SRA_CP2:
4000 case OPC_DSRA_CP2:
4001 /* Since SRA is UndefinedResult without sign-extended inputs,
4002 we can treat SRA and DSRA the same. */
4003 tcg_gen_sar_i64(t0, t0, t1);
4004 break;
4005 case OPC_SRL_CP2:
4006 /* We want to shift in zeros for SRL; zero-extend first. */
4007 tcg_gen_ext32u_i64(t0, t0);
4008 /* FALLTHRU */
4009 case OPC_DSRL_CP2:
4010 tcg_gen_shr_i64(t0, t0, t1);
4011 break;
4012 }
4013
4014 if (shift_max == 32) {
4015 tcg_gen_ext32s_i64(t0, t0);
4016 }
4017
4018 /* Shifts larger than MAX produce zero. */
4019 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4020 tcg_gen_neg_i64(t1, t1);
4021 tcg_gen_and_i64(t0, t0, t1);
4022 break;
4023
4024 case OPC_ADD_CP2:
4025 case OPC_DADD_CP2:
4026 {
4027 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4028 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4029
4030 tcg_gen_mov_i64(t2, t0);
4031 tcg_gen_add_i64(t0, t1, t2);
4032 if (opc == OPC_ADD_CP2) {
4033 tcg_gen_ext32s_i64(t0, t0);
4034 }
4035 tcg_gen_xor_i64(t1, t1, t2);
4036 tcg_gen_xor_i64(t2, t2, t0);
4037 tcg_gen_andc_i64(t1, t2, t1);
4038 tcg_temp_free_i64(t2);
4039 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4040 generate_exception(ctx, EXCP_OVERFLOW);
4041 gen_set_label(lab);
bd277fa1
RH
4042 break;
4043 }
4044
4045 case OPC_SUB_CP2:
4046 case OPC_DSUB_CP2:
4047 {
4048 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4049 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4050
4051 tcg_gen_mov_i64(t2, t0);
4052 tcg_gen_sub_i64(t0, t1, t2);
4053 if (opc == OPC_SUB_CP2) {
4054 tcg_gen_ext32s_i64(t0, t0);
4055 }
4056 tcg_gen_xor_i64(t1, t1, t2);
4057 tcg_gen_xor_i64(t2, t2, t0);
4058 tcg_gen_and_i64(t1, t1, t2);
4059 tcg_temp_free_i64(t2);
4060 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4061 generate_exception(ctx, EXCP_OVERFLOW);
4062 gen_set_label(lab);
bd277fa1
RH
4063 break;
4064 }
4065
4066 case OPC_PMULUW:
4067 tcg_gen_ext32u_i64(t0, t0);
4068 tcg_gen_ext32u_i64(t1, t1);
4069 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4070 break;
4071
4072 case OPC_SEQU_CP2:
4073 case OPC_SEQ_CP2:
4074 case OPC_SLTU_CP2:
4075 case OPC_SLT_CP2:
4076 case OPC_SLEU_CP2:
4077 case OPC_SLE_CP2:
4078 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4079 FD field is the CC field? */
4080 default:
9d68ac14 4081 MIPS_INVAL("loongson_cp2");
9c708c7f 4082 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4083 return;
4084 }
4085
4086#undef LMI_HELPER
4087#undef LMI_DIRECT
4088
4089 gen_store_fpr64(ctx, t0, rd);
4090
bd277fa1
RH
4091 tcg_temp_free_i64(t0);
4092 tcg_temp_free_i64(t1);
4093}
4094
6af0bf9c 4095/* Traps */
7a387fff 4096static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4097 int rs, int rt, int16_t imm)
4098{
4099 int cond;
cdc0faa6 4100 TCGv t0 = tcg_temp_new();
1ba74fb8 4101 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4102
4103 cond = 0;
4104 /* Load needed operands */
4105 switch (opc) {
4106 case OPC_TEQ:
4107 case OPC_TGE:
4108 case OPC_TGEU:
4109 case OPC_TLT:
4110 case OPC_TLTU:
4111 case OPC_TNE:
4112 /* Compare two registers */
4113 if (rs != rt) {
be24bb4f
TS
4114 gen_load_gpr(t0, rs);
4115 gen_load_gpr(t1, rt);
6af0bf9c
FB
4116 cond = 1;
4117 }
179e32bb 4118 break;
6af0bf9c
FB
4119 case OPC_TEQI:
4120 case OPC_TGEI:
4121 case OPC_TGEIU:
4122 case OPC_TLTI:
4123 case OPC_TLTIU:
4124 case OPC_TNEI:
4125 /* Compare register to immediate */
4126 if (rs != 0 || imm != 0) {
be24bb4f
TS
4127 gen_load_gpr(t0, rs);
4128 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4129 cond = 1;
4130 }
4131 break;
4132 }
4133 if (cond == 0) {
4134 switch (opc) {
4135 case OPC_TEQ: /* rs == rs */
4136 case OPC_TEQI: /* r0 == 0 */
4137 case OPC_TGE: /* rs >= rs */
4138 case OPC_TGEI: /* r0 >= 0 */
4139 case OPC_TGEU: /* rs >= rs unsigned */
4140 case OPC_TGEIU: /* r0 >= 0 unsigned */
4141 /* Always trap */
9c708c7f 4142 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4143 break;
4144 case OPC_TLT: /* rs < rs */
4145 case OPC_TLTI: /* r0 < 0 */
4146 case OPC_TLTU: /* rs < rs unsigned */
4147 case OPC_TLTIU: /* r0 < 0 unsigned */
4148 case OPC_TNE: /* rs != rs */
4149 case OPC_TNEI: /* r0 != 0 */
ead9360e 4150 /* Never trap: treat as NOP. */
cdc0faa6 4151 break;
6af0bf9c
FB
4152 }
4153 } else {
42a268c2 4154 TCGLabel *l1 = gen_new_label();
cdc0faa6 4155
6af0bf9c
FB
4156 switch (opc) {
4157 case OPC_TEQ:
4158 case OPC_TEQI:
cdc0faa6 4159 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4160 break;
4161 case OPC_TGE:
4162 case OPC_TGEI:
cdc0faa6 4163 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4164 break;
4165 case OPC_TGEU:
4166 case OPC_TGEIU:
cdc0faa6 4167 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4168 break;
4169 case OPC_TLT:
4170 case OPC_TLTI:
cdc0faa6 4171 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4172 break;
4173 case OPC_TLTU:
4174 case OPC_TLTIU:
cdc0faa6 4175 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4176 break;
4177 case OPC_TNE:
4178 case OPC_TNEI:
cdc0faa6 4179 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4180 break;
6af0bf9c 4181 }
cdc0faa6 4182 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4183 gen_set_label(l1);
4184 }
be24bb4f
TS
4185 tcg_temp_free(t0);
4186 tcg_temp_free(t1);
6af0bf9c
FB
4187}
4188
356265ae 4189static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4190{
6e256c93
FB
4191 TranslationBlock *tb;
4192 tb = ctx->tb;
7b270ef2
NF
4193 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4194 likely(!ctx->singlestep_enabled)) {
57fec1fe 4195 tcg_gen_goto_tb(n);
9b9e4393 4196 gen_save_pc(dest);
8cfd0495 4197 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4198 } else {
9b9e4393 4199 gen_save_pc(dest);
7b270ef2
NF
4200 if (ctx->singlestep_enabled) {
4201 save_cpu_state(ctx, 0);
9c708c7f 4202 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4203 }
57fec1fe 4204 tcg_gen_exit_tb(0);
6e256c93 4205 }
c53be334
FB
4206}
4207
6af0bf9c 4208/* Branches (before delay slot) */
7a387fff 4209static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4210 int insn_bytes,
b231c103
YK
4211 int rs, int rt, int32_t offset,
4212 int delayslot_size)
6af0bf9c 4213{
d077b6f7 4214 target_ulong btgt = -1;
3ad4bb2d 4215 int blink = 0;
2fdbad25 4216 int bcond_compute = 0;
1ba74fb8
AJ
4217 TCGv t0 = tcg_temp_new();
4218 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4219
4220 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4221#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4222 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4223 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4224#endif
9c708c7f 4225 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4226 goto out;
3ad4bb2d 4227 }
6af0bf9c 4228
6af0bf9c
FB
4229 /* Load needed operands */
4230 switch (opc) {
4231 case OPC_BEQ:
4232 case OPC_BEQL:
4233 case OPC_BNE:
4234 case OPC_BNEL:
4235 /* Compare two registers */
4236 if (rs != rt) {
6c5c1e20
TS
4237 gen_load_gpr(t0, rs);
4238 gen_load_gpr(t1, rt);
2fdbad25 4239 bcond_compute = 1;
6af0bf9c 4240 }
7dca4ad0 4241 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4242 break;
4243 case OPC_BGEZ:
4244 case OPC_BGEZAL:
4245 case OPC_BGEZALL:
4246 case OPC_BGEZL:
4247 case OPC_BGTZ:
4248 case OPC_BGTZL:
4249 case OPC_BLEZ:
4250 case OPC_BLEZL:
4251 case OPC_BLTZ:
4252 case OPC_BLTZAL:
4253 case OPC_BLTZALL:
4254 case OPC_BLTZL:
4255 /* Compare to zero */
4256 if (rs != 0) {
6c5c1e20 4257 gen_load_gpr(t0, rs);
2fdbad25 4258 bcond_compute = 1;
6af0bf9c 4259 }
7dca4ad0 4260 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4261 break;
e45a93e2
JL
4262 case OPC_BPOSGE32:
4263#if defined(TARGET_MIPS64)
4264 case OPC_BPOSGE64:
4265 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4266#else
4267 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4268#endif
4269 bcond_compute = 1;
4270 btgt = ctx->pc + insn_bytes + offset;
4271 break;
6af0bf9c
FB
4272 case OPC_J:
4273 case OPC_JAL:
364d4831 4274 case OPC_JALX:
6af0bf9c 4275 /* Jump to immediate */
7dca4ad0 4276 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4277 break;
4278 case OPC_JR:
4279 case OPC_JALR:
4280 /* Jump to register */
7a387fff
TS
4281 if (offset != 0 && offset != 16) {
4282 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4283 others are reserved. */
923617a3 4284 MIPS_INVAL("jump hint");
9c708c7f 4285 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4286 goto out;
6af0bf9c 4287 }
d077b6f7 4288 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4289 break;
4290 default:
4291 MIPS_INVAL("branch/jump");
9c708c7f 4292 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4293 goto out;
6af0bf9c 4294 }
2fdbad25 4295 if (bcond_compute == 0) {
6af0bf9c
FB
4296 /* No condition to be computed */
4297 switch (opc) {
4298 case OPC_BEQ: /* rx == rx */
4299 case OPC_BEQL: /* rx == rx likely */
4300 case OPC_BGEZ: /* 0 >= 0 */
4301 case OPC_BGEZL: /* 0 >= 0 likely */
4302 case OPC_BLEZ: /* 0 <= 0 */
4303 case OPC_BLEZL: /* 0 <= 0 likely */
4304 /* Always take */
4ad40f36 4305 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4306 break;
4307 case OPC_BGEZAL: /* 0 >= 0 */
4308 case OPC_BGEZALL: /* 0 >= 0 likely */
4309 /* Always take and link */
4310 blink = 31;
4ad40f36 4311 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4312 break;
4313 case OPC_BNE: /* rx != rx */
4314 case OPC_BGTZ: /* 0 > 0 */
4315 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4316 /* Treat as NOP. */
6c5c1e20 4317 goto out;
eeef26cd 4318 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4319 /* Handle as an unconditional branch to get correct delay
4320 slot checking. */
4321 blink = 31;
b231c103 4322 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4323 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4324 break;
eeef26cd 4325 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4326 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4327 /* Skip the instruction in the delay slot */
9898128f 4328 ctx->pc += 4;
6c5c1e20 4329 goto out;
6af0bf9c
FB
4330 case OPC_BNEL: /* rx != rx likely */
4331 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4332 case OPC_BLTZL: /* 0 < 0 likely */
4333 /* Skip the instruction in the delay slot */
9898128f 4334 ctx->pc += 4;
6c5c1e20 4335 goto out;
6af0bf9c 4336 case OPC_J:
4ad40f36 4337 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4338 break;
364d4831
NF
4339 case OPC_JALX:
4340 ctx->hflags |= MIPS_HFLAG_BX;
4341 /* Fallthrough */
6af0bf9c
FB
4342 case OPC_JAL:
4343 blink = 31;
4ad40f36 4344 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4345 break;
4346 case OPC_JR:
4ad40f36 4347 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4348 break;
4349 case OPC_JALR:
4350 blink = rt;
4ad40f36 4351 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4352 break;
4353 default:
4354 MIPS_INVAL("branch/jump");
9c708c7f 4355 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4356 goto out;
6af0bf9c
FB
4357 }
4358 } else {
4359 switch (opc) {
4360 case OPC_BEQ:
e68dd28f 4361 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4362 goto not_likely;
4363 case OPC_BEQL:
e68dd28f 4364 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4365 goto likely;
4366 case OPC_BNE:
e68dd28f 4367 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4368 goto not_likely;
4369 case OPC_BNEL:
e68dd28f 4370 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4371 goto likely;
4372 case OPC_BGEZ:
e68dd28f 4373 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4374 goto not_likely;
4375 case OPC_BGEZL:
e68dd28f 4376 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4377 goto likely;
4378 case OPC_BGEZAL:
e68dd28f 4379 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4380 blink = 31;
4381 goto not_likely;
4382 case OPC_BGEZALL:
e68dd28f 4383 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4384 blink = 31;
6af0bf9c
FB
4385 goto likely;
4386 case OPC_BGTZ:
e68dd28f 4387 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4388 goto not_likely;
4389 case OPC_BGTZL:
e68dd28f 4390 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4391 goto likely;
4392 case OPC_BLEZ:
e68dd28f 4393 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4394 goto not_likely;
4395 case OPC_BLEZL:
e68dd28f 4396 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4397 goto likely;
4398 case OPC_BLTZ:
e68dd28f 4399 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4400 goto not_likely;
4401 case OPC_BLTZL:
e68dd28f 4402 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4403 goto likely;
e45a93e2
JL
4404 case OPC_BPOSGE32:
4405 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4406 goto not_likely;
4407#if defined(TARGET_MIPS64)
4408 case OPC_BPOSGE64:
4409 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4410 goto not_likely;
4411#endif
6af0bf9c 4412 case OPC_BLTZAL:
e68dd28f 4413 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4414 blink = 31;
6af0bf9c 4415 not_likely:
4ad40f36 4416 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4417 break;
4418 case OPC_BLTZALL:
e68dd28f 4419 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4420 blink = 31;
6af0bf9c 4421 likely:
4ad40f36 4422 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4423 break;
c53f4a62
TS
4424 default:
4425 MIPS_INVAL("conditional branch/jump");
9c708c7f 4426 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4427 goto out;
6af0bf9c 4428 }
6af0bf9c 4429 }
9b9e4393 4430
d077b6f7 4431 ctx->btarget = btgt;
b231c103
YK
4432
4433 switch (delayslot_size) {
4434 case 2:
4435 ctx->hflags |= MIPS_HFLAG_BDS16;
4436 break;
4437 case 4:
4438 ctx->hflags |= MIPS_HFLAG_BDS32;
4439 break;
4440 }
4441
6af0bf9c 4442 if (blink > 0) {
b231c103 4443 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4444 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4445
364d4831 4446 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4447 }
6c5c1e20
TS
4448
4449 out:
364d4831
NF
4450 if (insn_bytes == 2)
4451 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4452 tcg_temp_free(t0);
4453 tcg_temp_free(t1);
6af0bf9c
FB
4454}
4455
7a387fff
TS
4456/* special3 bitfield operations */
4457static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4458 int rs, int lsb, int msb)
7a387fff 4459{
a7812ae4
PB
4460 TCGv t0 = tcg_temp_new();
4461 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4462
4463 gen_load_gpr(t1, rs);
7a387fff
TS
4464 switch (opc) {
4465 case OPC_EXT:
b7f26e52 4466 if (lsb + msb > 31) {
7a387fff 4467 goto fail;
b7f26e52 4468 }
505ad7c2
AJ
4469 tcg_gen_shri_tl(t0, t1, lsb);
4470 if (msb != 31) {
b7f26e52 4471 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
505ad7c2
AJ
4472 } else {
4473 tcg_gen_ext32s_tl(t0, t0);
4474 }
7a387fff 4475 break;
c6d6dd7c 4476#if defined(TARGET_MIPS64)
7a387fff 4477 case OPC_DEXTU:
b7f26e52
RH
4478 lsb += 32;
4479 goto do_dext;
4480 case OPC_DEXTM:
4481 msb += 32;
4482 goto do_dext;
7a387fff 4483 case OPC_DEXT:
b7f26e52
RH
4484 do_dext:
4485 if (lsb + msb > 63) {
4486 goto fail;
4487 }
505ad7c2 4488 tcg_gen_shri_tl(t0, t1, lsb);
b7f26e52
RH
4489 if (msb != 63) {
4490 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4491 }
7a387fff 4492 break;
c6d6dd7c 4493#endif
7a387fff 4494 case OPC_INS:
b7f26e52 4495 if (lsb > msb) {
7a387fff 4496 goto fail;
b7f26e52 4497 }
6c5c1e20 4498 gen_load_gpr(t0, rt);
e0d002f1 4499 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4500 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4501 break;
c6d6dd7c 4502#if defined(TARGET_MIPS64)
7a387fff 4503 case OPC_DINSU:
b7f26e52
RH
4504 lsb += 32;
4505 /* FALLTHRU */
4506 case OPC_DINSM:
4507 msb += 32;
4508 /* FALLTHRU */
7a387fff 4509 case OPC_DINS:
b7f26e52
RH
4510 if (lsb > msb) {
4511 goto fail;
4512 }
6c5c1e20 4513 gen_load_gpr(t0, rt);
e0d002f1 4514 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4515 break;
c6d6dd7c 4516#endif
7a387fff
TS
4517 default:
4518fail:
4519 MIPS_INVAL("bitops");
9c708c7f 4520 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4521 tcg_temp_free(t0);
4522 tcg_temp_free(t1);
7a387fff
TS
4523 return;
4524 }
6c5c1e20
TS
4525 gen_store_gpr(t0, rt);
4526 tcg_temp_free(t0);
4527 tcg_temp_free(t1);
7a387fff
TS
4528}
4529
49bcf33c
AJ
4530static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4531{
3a55fa47 4532 TCGv t0;
49bcf33c 4533
3a55fa47
AJ
4534 if (rd == 0) {
4535 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4536 return;
4537 }
4538
4539 t0 = tcg_temp_new();
4540 gen_load_gpr(t0, rt);
49bcf33c
AJ
4541 switch (op2) {
4542 case OPC_WSBH:
3a55fa47
AJ
4543 {
4544 TCGv t1 = tcg_temp_new();
4545
4546 tcg_gen_shri_tl(t1, t0, 8);
4547 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4548 tcg_gen_shli_tl(t0, t0, 8);
4549 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4550 tcg_gen_or_tl(t0, t0, t1);
4551 tcg_temp_free(t1);
4552 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4553 }
49bcf33c
AJ
4554 break;
4555 case OPC_SEB:
3a55fa47 4556 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4557 break;
4558 case OPC_SEH:
3a55fa47 4559 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4560 break;
4561#if defined(TARGET_MIPS64)
4562 case OPC_DSBH:
3a55fa47
AJ
4563 {
4564 TCGv t1 = tcg_temp_new();
4565
4566 tcg_gen_shri_tl(t1, t0, 8);
4567 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4568 tcg_gen_shli_tl(t0, t0, 8);
4569 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4570 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4571 tcg_temp_free(t1);
4572 }
49bcf33c
AJ
4573 break;
4574 case OPC_DSHD:
3a55fa47
AJ
4575 {
4576 TCGv t1 = tcg_temp_new();
4577
4578 tcg_gen_shri_tl(t1, t0, 16);
4579 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4580 tcg_gen_shli_tl(t0, t0, 16);
4581 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4582 tcg_gen_or_tl(t0, t0, t1);
4583 tcg_gen_shri_tl(t1, t0, 32);
4584 tcg_gen_shli_tl(t0, t0, 32);
4585 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4586 tcg_temp_free(t1);
4587 }
49bcf33c
AJ
4588 break;
4589#endif
4590 default:
4591 MIPS_INVAL("bsfhl");
9c708c7f 4592 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4593 tcg_temp_free(t0);
49bcf33c
AJ
4594 return;
4595 }
49bcf33c 4596 tcg_temp_free(t0);
49bcf33c
AJ
4597}
4598
1f1b4c00
YK
4599static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4600 int imm2)
4601{
4602 TCGv t0;
4603 TCGv t1;
4604 if (rd == 0) {
4605 /* Treat as NOP. */
4606 return;
4607 }
4608 t0 = tcg_temp_new();
4609 t1 = tcg_temp_new();
4610 gen_load_gpr(t0, rs);
4611 gen_load_gpr(t1, rt);
4612 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4613 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4614 if (opc == OPC_LSA) {
4615 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4616 }
4617
4618 tcg_temp_free(t1);
4619 tcg_temp_free(t0);
4620
4621 return;
4622}
4623
4624static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4625 int bp)
284b731a 4626{
1f1b4c00
YK
4627 TCGv t0;
4628 if (rd == 0) {
4629 /* Treat as NOP. */
4630 return;
4631 }
4632 t0 = tcg_temp_new();
4633 gen_load_gpr(t0, rt);
4634 if (bp == 0) {
4635 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4636 } else {
4637 TCGv t1 = tcg_temp_new();
4638 gen_load_gpr(t1, rs);
4639 switch (opc) {
4640 case OPC_ALIGN:
4641 {
4642 TCGv_i64 t2 = tcg_temp_new_i64();
4643 tcg_gen_concat_tl_i64(t2, t1, t0);
4644 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4645 gen_move_low32(cpu_gpr[rd], t2);
4646 tcg_temp_free_i64(t2);
4647 }
4648 break;
284b731a 4649#if defined(TARGET_MIPS64)
1f1b4c00
YK
4650 case OPC_DALIGN:
4651 tcg_gen_shli_tl(t0, t0, 8 * bp);
4652 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4653 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4654 break;
284b731a 4655#endif
1f1b4c00
YK
4656 }
4657 tcg_temp_free(t1);
4658 }
4659
4660 tcg_temp_free(t0);
4661}
4662
4663static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4664{
4665 TCGv t0;
4666 if (rd == 0) {
4667 /* Treat as NOP. */
4668 return;
4669 }
4670 t0 = tcg_temp_new();
4671 gen_load_gpr(t0, rt);
4672 switch (opc) {
4673 case OPC_BITSWAP:
4674 gen_helper_bitswap(cpu_gpr[rd], t0);
4675 break;
4676#if defined(TARGET_MIPS64)
4677 case OPC_DBITSWAP:
4678 gen_helper_dbitswap(cpu_gpr[rd], t0);
4679 break;
4680#endif
4681 }
4682 tcg_temp_free(t0);
284b731a
LA
4683}
4684
1f1b4c00
YK
4685#ifndef CONFIG_USER_ONLY
4686/* CP0 (MMU and control) */
5204ea79
LA
4687static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4688{
4689 TCGv_i64 t0 = tcg_temp_new_i64();
4690 TCGv_i64 t1 = tcg_temp_new_i64();
4691
4692 tcg_gen_ext_tl_i64(t0, arg);
4693 tcg_gen_ld_i64(t1, cpu_env, off);
4694#if defined(TARGET_MIPS64)
4695 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4696#else
4697 tcg_gen_concat32_i64(t1, t1, t0);
4698#endif
4699 tcg_gen_st_i64(t1, cpu_env, off);
4700 tcg_temp_free_i64(t1);
4701 tcg_temp_free_i64(t0);
4702}
4703
4704static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4705{
4706 TCGv_i64 t0 = tcg_temp_new_i64();
4707 TCGv_i64 t1 = tcg_temp_new_i64();
4708
4709 tcg_gen_ext_tl_i64(t0, arg);
4710 tcg_gen_ld_i64(t1, cpu_env, off);
4711 tcg_gen_concat32_i64(t1, t1, t0);
4712 tcg_gen_st_i64(t1, cpu_env, off);
4713 tcg_temp_free_i64(t1);
4714 tcg_temp_free_i64(t0);
4715}
4716
4717static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4718{
4719 TCGv_i64 t0 = tcg_temp_new_i64();
4720
4721 tcg_gen_ld_i64(t0, cpu_env, off);
4722#if defined(TARGET_MIPS64)
4723 tcg_gen_shri_i64(t0, t0, 30);
4724#else
4725 tcg_gen_shri_i64(t0, t0, 32);
4726#endif
4727 gen_move_low32(arg, t0);
4728 tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4732{
4733 TCGv_i64 t0 = tcg_temp_new_i64();
4734
4735 tcg_gen_ld_i64(t0, cpu_env, off);
4736 tcg_gen_shri_i64(t0, t0, 32 + shift);
4737 gen_move_low32(arg, t0);
4738 tcg_temp_free_i64(t0);
4739}
4740
d9bea114 4741static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4742{
d9bea114 4743 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4744
d9bea114
AJ
4745 tcg_gen_ld_i32(t0, cpu_env, off);
4746 tcg_gen_ext_i32_tl(arg, t0);
4747 tcg_temp_free_i32(t0);
4f57689a
TS
4748}
4749
d9bea114 4750static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4751{
d9bea114
AJ
4752 tcg_gen_ld_tl(arg, cpu_env, off);
4753 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4754}
4755
d9bea114 4756static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4757{
d9bea114 4758 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4759
d9bea114
AJ
4760 tcg_gen_trunc_tl_i32(t0, arg);
4761 tcg_gen_st_i32(t0, cpu_env, off);
4762 tcg_temp_free_i32(t0);
f1aa6320
TS
4763}
4764
5204ea79
LA
4765static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4766{
4767 const char *rn = "invalid";
4768
4769 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4770 goto mfhc0_read_zero;
4771 }
4772
4773 switch (reg) {
4774 case 2:
4775 switch (sel) {
4776 case 0:
4777 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4778 rn = "EntryLo0";
4779 break;
4780 default:
4781 goto mfhc0_read_zero;
4782 }
4783 break;
4784 case 3:
4785 switch (sel) {
4786 case 0:
4787 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4788 rn = "EntryLo1";
4789 break;
4790 default:
4791 goto mfhc0_read_zero;
4792 }
4793 break;
4794 case 17:
4795 switch (sel) {
4796 case 0:
4797 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4798 ctx->CP0_LLAddr_shift);
4799 rn = "LLAddr";
4800 break;
4801 default:
4802 goto mfhc0_read_zero;
4803 }
4804 break;
4805 case 28:
4806 switch (sel) {
4807 case 0:
4808 case 2:
4809 case 4:
4810 case 6:
4811 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4812 rn = "TagLo";
4813 break;
4814 default:
4815 goto mfhc0_read_zero;
4816 }
4817 break;
4818 default:
4819 goto mfhc0_read_zero;
4820 }
4821
4822 (void)rn; /* avoid a compiler warning */
4823 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4824 return;
4825
4826mfhc0_read_zero:
4827 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4828 tcg_gen_movi_tl(arg, 0);
4829}
4830
4831static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4832{
4833 const char *rn = "invalid";
4834 uint64_t mask = ctx->PAMask >> 36;
4835
4836 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4837 goto mthc0_nop;
4838 }
4839
4840 switch (reg) {
4841 case 2:
4842 switch (sel) {
4843 case 0:
4844 tcg_gen_andi_tl(arg, arg, mask);
4845 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4846 rn = "EntryLo0";
4847 break;
4848 default:
4849 goto mthc0_nop;
4850 }
4851 break;
4852 case 3:
4853 switch (sel) {
4854 case 0:
4855 tcg_gen_andi_tl(arg, arg, mask);
4856 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4857 rn = "EntryLo1";
4858 break;
4859 default:
4860 goto mthc0_nop;
4861 }
4862 break;
4863 case 17:
4864 switch (sel) {
4865 case 0:
4866 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4867 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4868 relevant for modern MIPS cores supporting MTHC0, therefore
4869 treating MTHC0 to LLAddr as NOP. */
4870 rn = "LLAddr";
4871 break;
4872 default:
4873 goto mthc0_nop;
4874 }
4875 break;
4876 case 28:
4877 switch (sel) {
4878 case 0:
4879 case 2:
4880 case 4:
4881 case 6:
4882 tcg_gen_andi_tl(arg, arg, mask);
4883 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4884 rn = "TagLo";
4885 break;
4886 default:
4887 goto mthc0_nop;
4888 }
4889 break;
4890 default:
4891 goto mthc0_nop;
4892 }
4893
4894 (void)rn; /* avoid a compiler warning */
4895mthc0_nop:
4896 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4897}
4898
e98c0d17
LA
4899static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4900{
4901 if (ctx->insn_flags & ISA_MIPS32R6) {
4902 tcg_gen_movi_tl(arg, 0);
4903 } else {
4904 tcg_gen_movi_tl(arg, ~0);
4905 }
4906}
4907
f31b035a
LA
4908#define CP0_CHECK(c) \
4909 do { \
4910 if (!(c)) { \
4911 goto cp0_unimplemented; \
4912 } \
4913 } while (0)
4914
d75c135e 4915static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4916{
7a387fff 4917 const char *rn = "invalid";
873eb012 4918
e189e748 4919 if (sel != 0)
d75c135e 4920 check_insn(ctx, ISA_MIPS32);
e189e748 4921
873eb012
TS
4922 switch (reg) {
4923 case 0:
7a387fff
TS
4924 switch (sel) {
4925 case 0:
7db13fae 4926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4927 rn = "Index";
4928 break;
4929 case 1:
f31b035a 4930 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4931 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4932 rn = "MVPControl";
ead9360e 4933 break;
7a387fff 4934 case 2:
f31b035a 4935 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4936 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4937 rn = "MVPConf0";
ead9360e 4938 break;
7a387fff 4939 case 3:
f31b035a 4940 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4941 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4942 rn = "MVPConf1";
ead9360e 4943 break;
7a387fff 4944 default:
f31b035a 4945 goto cp0_unimplemented;
7a387fff 4946 }
873eb012
TS
4947 break;
4948 case 1:
7a387fff
TS
4949 switch (sel) {
4950 case 0:
f31b035a 4951 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4952 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4953 rn = "Random";
2423f660 4954 break;
7a387fff 4955 case 1:
f31b035a 4956 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4958 rn = "VPEControl";
ead9360e 4959 break;
7a387fff 4960 case 2:
f31b035a 4961 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4963 rn = "VPEConf0";
ead9360e 4964 break;
7a387fff 4965 case 3:
f31b035a 4966 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4967 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4968 rn = "VPEConf1";
ead9360e 4969 break;
7a387fff 4970 case 4:
f31b035a 4971 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4972 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4973 rn = "YQMask";
ead9360e 4974 break;
7a387fff 4975 case 5:
f31b035a 4976 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4977 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4978 rn = "VPESchedule";
ead9360e 4979 break;
7a387fff 4980 case 6:
f31b035a 4981 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4982 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4983 rn = "VPEScheFBack";
ead9360e 4984 break;
7a387fff 4985 case 7:
f31b035a 4986 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4988 rn = "VPEOpt";
ead9360e 4989 break;
7a387fff 4990 default:
f31b035a 4991 goto cp0_unimplemented;
7a387fff 4992 }
873eb012
TS
4993 break;
4994 case 2:
7a387fff
TS
4995 switch (sel) {
4996 case 0:
284b731a
LA
4997 {
4998 TCGv_i64 tmp = tcg_temp_new_i64();
4999 tcg_gen_ld_i64(tmp, cpu_env,
5000 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5001#if defined(TARGET_MIPS64)
284b731a
LA
5002 if (ctx->rxi) {
5003 /* Move RI/XI fields to bits 31:30 */
5004 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5005 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5006 }
7207c7f9 5007#endif
284b731a
LA
5008 gen_move_low32(arg, tmp);
5009 tcg_temp_free_i64(tmp);
5010 }
2423f660
TS
5011 rn = "EntryLo0";
5012 break;
7a387fff 5013 case 1:
f31b035a 5014 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5015 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5016 rn = "TCStatus";
ead9360e 5017 break;
7a387fff 5018 case 2:
f31b035a 5019 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5020 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5021 rn = "TCBind";
ead9360e 5022 break;
7a387fff 5023 case 3:
f31b035a 5024 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5025 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5026 rn = "TCRestart";
ead9360e 5027 break;
7a387fff 5028 case 4:
f31b035a 5029 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5030 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5031 rn = "TCHalt";
ead9360e 5032 break;
7a387fff 5033 case 5:
f31b035a 5034 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5035 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5036 rn = "TCContext";
ead9360e 5037 break;
7a387fff 5038 case 6:
f31b035a 5039 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5040 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5041 rn = "TCSchedule";
ead9360e 5042 break;
7a387fff 5043 case 7:
f31b035a 5044 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5045 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5046 rn = "TCScheFBack";
ead9360e 5047 break;
7a387fff 5048 default:
f31b035a 5049 goto cp0_unimplemented;
7a387fff 5050 }
873eb012
TS
5051 break;
5052 case 3:
7a387fff
TS
5053 switch (sel) {
5054 case 0:
284b731a
LA
5055 {
5056 TCGv_i64 tmp = tcg_temp_new_i64();
5057 tcg_gen_ld_i64(tmp, cpu_env,
5058 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5059#if defined(TARGET_MIPS64)
284b731a
LA
5060 if (ctx->rxi) {
5061 /* Move RI/XI fields to bits 31:30 */
5062 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5063 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5064 }
7207c7f9 5065#endif
284b731a
LA
5066 gen_move_low32(arg, tmp);
5067 tcg_temp_free_i64(tmp);
5068 }
2423f660
TS
5069 rn = "EntryLo1";
5070 break;
7a387fff 5071 default:
f31b035a 5072 goto cp0_unimplemented;
1579a72e 5073 }
873eb012
TS
5074 break;
5075 case 4:
7a387fff
TS
5076 switch (sel) {
5077 case 0:
7db13fae 5078 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5079 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5080 rn = "Context";
5081 break;
7a387fff 5082 case 1:
d9bea114 5083// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5084 rn = "ContextConfig";
f31b035a 5085 goto cp0_unimplemented;
2423f660 5086// break;
d279279e 5087 case 2:
f31b035a
LA
5088 CP0_CHECK(ctx->ulri);
5089 tcg_gen_ld32s_tl(arg, cpu_env,
5090 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5091 rn = "UserLocal";
d279279e 5092 break;
7a387fff 5093 default:
f31b035a 5094 goto cp0_unimplemented;
1579a72e 5095 }
873eb012
TS
5096 break;
5097 case 5:
7a387fff
TS
5098 switch (sel) {
5099 case 0:
7db13fae 5100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5101 rn = "PageMask";
5102 break;
7a387fff 5103 case 1:
d75c135e 5104 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5106 rn = "PageGrain";
5107 break;
7a387fff 5108 default:
f31b035a 5109 goto cp0_unimplemented;
1579a72e 5110 }
873eb012
TS
5111 break;
5112 case 6:
7a387fff
TS
5113 switch (sel) {
5114 case 0:
7db13fae 5115 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5116 rn = "Wired";
5117 break;
7a387fff 5118 case 1:
d75c135e 5119 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5121 rn = "SRSConf0";
ead9360e 5122 break;
7a387fff 5123 case 2:
d75c135e 5124 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5126 rn = "SRSConf1";
ead9360e 5127 break;
7a387fff 5128 case 3:
d75c135e 5129 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5131 rn = "SRSConf2";
ead9360e 5132 break;
7a387fff 5133 case 4:
d75c135e 5134 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5135 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5136 rn = "SRSConf3";
ead9360e 5137 break;
7a387fff 5138 case 5:
d75c135e 5139 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5140 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5141 rn = "SRSConf4";
ead9360e 5142 break;
7a387fff 5143 default:
f31b035a 5144 goto cp0_unimplemented;
1579a72e 5145 }
873eb012 5146 break;
8c0fdd85 5147 case 7:
7a387fff
TS
5148 switch (sel) {
5149 case 0:
d75c135e 5150 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5152 rn = "HWREna";
5153 break;
7a387fff 5154 default:
f31b035a 5155 goto cp0_unimplemented;
1579a72e 5156 }
8c0fdd85 5157 break;
873eb012 5158 case 8:
7a387fff
TS
5159 switch (sel) {
5160 case 0:
7db13fae 5161 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5162 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5163 rn = "BadVAddr";
2423f660 5164 break;
aea14095 5165 case 1:
f31b035a
LA
5166 CP0_CHECK(ctx->bi);
5167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5168 rn = "BadInstr";
aea14095
LA
5169 break;
5170 case 2:
f31b035a
LA
5171 CP0_CHECK(ctx->bp);
5172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5173 rn = "BadInstrP";
aea14095 5174 break;
7a387fff 5175 default:
f31b035a 5176 goto cp0_unimplemented;
aea14095 5177 }
873eb012
TS
5178 break;
5179 case 9:
7a387fff
TS
5180 switch (sel) {
5181 case 0:
2e70f6ef 5182 /* Mark as an IO operation because we read the time. */
bd79255d 5183 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5184 gen_io_start();
bd79255d 5185 }
895c2d04 5186 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5187 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5188 gen_io_end();
2e70f6ef 5189 }
55807224
EI
5190 /* Break the TB to be able to take timer interrupts immediately
5191 after reading count. */
5192 ctx->bstate = BS_STOP;
2423f660
TS
5193 rn = "Count";
5194 break;
5195 /* 6,7 are implementation dependent */
7a387fff 5196 default:
f31b035a 5197 goto cp0_unimplemented;
2423f660 5198 }
873eb012
TS
5199 break;
5200 case 10:
7a387fff
TS
5201 switch (sel) {
5202 case 0:
7db13fae 5203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5204 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5205 rn = "EntryHi";
5206 break;
7a387fff 5207 default:
f31b035a 5208 goto cp0_unimplemented;
1579a72e 5209 }
873eb012
TS
5210 break;
5211 case 11:
7a387fff
TS
5212 switch (sel) {
5213 case 0:
7db13fae 5214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5215 rn = "Compare";
5216 break;
5217 /* 6,7 are implementation dependent */
7a387fff 5218 default:
f31b035a 5219 goto cp0_unimplemented;
2423f660 5220 }
873eb012
TS
5221 break;
5222 case 12:
7a387fff
TS
5223 switch (sel) {
5224 case 0:
7db13fae 5225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5226 rn = "Status";
5227 break;
7a387fff 5228 case 1:
d75c135e 5229 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5231 rn = "IntCtl";
5232 break;
7a387fff 5233 case 2:
d75c135e 5234 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5236 rn = "SRSCtl";
5237 break;
7a387fff 5238 case 3:
d75c135e 5239 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5241 rn = "SRSMap";
fd88b6ab 5242 break;
7a387fff 5243 default:
f31b035a 5244 goto cp0_unimplemented;
7a387fff 5245 }
873eb012
TS
5246 break;
5247 case 13:
7a387fff
TS
5248 switch (sel) {
5249 case 0:
7db13fae 5250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5251 rn = "Cause";
5252 break;
7a387fff 5253 default:
f31b035a 5254 goto cp0_unimplemented;
7a387fff 5255 }
873eb012
TS
5256 break;
5257 case 14:
7a387fff
TS
5258 switch (sel) {
5259 case 0:
7db13fae 5260 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5261 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5262 rn = "EPC";
5263 break;
7a387fff 5264 default:
f31b035a 5265 goto cp0_unimplemented;
1579a72e 5266 }
873eb012
TS
5267 break;
5268 case 15:
7a387fff
TS
5269 switch (sel) {
5270 case 0:
7db13fae 5271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5272 rn = "PRid";
5273 break;
7a387fff 5274 case 1:
d75c135e 5275 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5277 rn = "EBase";
5278 break;
7a387fff 5279 default:
f31b035a 5280 goto cp0_unimplemented;
7a387fff 5281 }
873eb012
TS
5282 break;
5283 case 16:
5284 switch (sel) {
5285 case 0:
7db13fae 5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5287 rn = "Config";
5288 break;
5289 case 1:
7db13fae 5290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5291 rn = "Config1";
5292 break;
7a387fff 5293 case 2:
7db13fae 5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5295 rn = "Config2";
5296 break;
5297 case 3:
7db13fae 5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5299 rn = "Config3";
5300 break;
b4160af1
PJ
5301 case 4:
5302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5303 rn = "Config4";
5304 break;
b4dd99a3
PJ
5305 case 5:
5306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5307 rn = "Config5";
5308 break;
e397ee33
TS
5309 /* 6,7 are implementation dependent */
5310 case 6:
7db13fae 5311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5312 rn = "Config6";
5313 break;
5314 case 7:
7db13fae 5315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5316 rn = "Config7";
5317 break;
873eb012 5318 default:
f31b035a 5319 goto cp0_unimplemented;
873eb012
TS
5320 }
5321 break;
5322 case 17:
7a387fff
TS
5323 switch (sel) {
5324 case 0:
895c2d04 5325 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5326 rn = "LLAddr";
5327 break;
7a387fff 5328 default:
f31b035a 5329 goto cp0_unimplemented;
7a387fff 5330 }
873eb012
TS
5331 break;
5332 case 18:
7a387fff 5333 switch (sel) {
fd88b6ab 5334 case 0 ... 7:
895c2d04 5335 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5336 rn = "WatchLo";
5337 break;
7a387fff 5338 default:
f31b035a 5339 goto cp0_unimplemented;
7a387fff 5340 }
873eb012
TS
5341 break;
5342 case 19:
7a387fff 5343 switch (sel) {
fd88b6ab 5344 case 0 ...7:
895c2d04 5345 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5346 rn = "WatchHi";
5347 break;
7a387fff 5348 default:
f31b035a 5349 goto cp0_unimplemented;
7a387fff 5350 }
873eb012 5351 break;
8c0fdd85 5352 case 20:
7a387fff
TS
5353 switch (sel) {
5354 case 0:
d26bc211 5355#if defined(TARGET_MIPS64)
d75c135e 5356 check_insn(ctx, ISA_MIPS3);
7db13fae 5357 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5358 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5359 rn = "XContext";
5360 break;
703eaf37 5361#endif
7a387fff 5362 default:
f31b035a 5363 goto cp0_unimplemented;
7a387fff 5364 }
8c0fdd85
TS
5365 break;
5366 case 21:
7a387fff 5367 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5368 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5369 switch (sel) {
5370 case 0:
7db13fae 5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5372 rn = "Framemask";
5373 break;
7a387fff 5374 default:
f31b035a 5375 goto cp0_unimplemented;
7a387fff 5376 }
8c0fdd85
TS
5377 break;
5378 case 22:
d9bea114 5379 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5380 rn = "'Diagnostic"; /* implementation dependent */
5381 break;
873eb012 5382 case 23:
7a387fff
TS
5383 switch (sel) {
5384 case 0:
895c2d04 5385 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5386 rn = "Debug";
5387 break;
7a387fff 5388 case 1:
d9bea114 5389// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5390 rn = "TraceControl";
5391// break;
7a387fff 5392 case 2:
d9bea114 5393// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5394 rn = "TraceControl2";
5395// break;
7a387fff 5396 case 3:
d9bea114 5397// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5398 rn = "UserTraceData";
5399// break;
7a387fff 5400 case 4:
d9bea114 5401// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5402 rn = "TraceBPC";
5403// break;
7a387fff 5404 default:
f31b035a 5405 goto cp0_unimplemented;
7a387fff 5406 }
873eb012
TS
5407 break;
5408 case 24:
7a387fff
TS
5409 switch (sel) {
5410 case 0:
f0b3f3ae 5411 /* EJTAG support */
7db13fae 5412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5413 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5414 rn = "DEPC";
5415 break;
7a387fff 5416 default:
f31b035a 5417 goto cp0_unimplemented;
7a387fff 5418 }
873eb012 5419 break;
8c0fdd85 5420 case 25:
7a387fff
TS
5421 switch (sel) {
5422 case 0:
7db13fae 5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5424 rn = "Performance0";
7a387fff
TS
5425 break;
5426 case 1:
d9bea114 5427// gen_helper_mfc0_performance1(arg);
2423f660
TS
5428 rn = "Performance1";
5429// break;
7a387fff 5430 case 2:
d9bea114 5431// gen_helper_mfc0_performance2(arg);
2423f660
TS
5432 rn = "Performance2";
5433// break;
7a387fff 5434 case 3:
d9bea114 5435// gen_helper_mfc0_performance3(arg);
2423f660
TS
5436 rn = "Performance3";
5437// break;
7a387fff 5438 case 4:
d9bea114 5439// gen_helper_mfc0_performance4(arg);
2423f660
TS
5440 rn = "Performance4";
5441// break;
7a387fff 5442 case 5:
d9bea114 5443// gen_helper_mfc0_performance5(arg);
2423f660
TS
5444 rn = "Performance5";
5445// break;
7a387fff 5446 case 6:
d9bea114 5447// gen_helper_mfc0_performance6(arg);
2423f660
TS
5448 rn = "Performance6";
5449// break;
7a387fff 5450 case 7:
d9bea114 5451// gen_helper_mfc0_performance7(arg);
2423f660
TS
5452 rn = "Performance7";
5453// break;
7a387fff 5454 default:
f31b035a 5455 goto cp0_unimplemented;
7a387fff 5456 }
8c0fdd85
TS
5457 break;
5458 case 26:
d9bea114 5459 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5460 rn = "ECC";
5461 break;
8c0fdd85 5462 case 27:
7a387fff 5463 switch (sel) {
7a387fff 5464 case 0 ... 3:
d9bea114 5465 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5466 rn = "CacheErr";
5467 break;
7a387fff 5468 default:
f31b035a 5469 goto cp0_unimplemented;
7a387fff 5470 }
8c0fdd85 5471 break;
873eb012
TS
5472 case 28:
5473 switch (sel) {
5474 case 0:
7a387fff
TS
5475 case 2:
5476 case 4:
5477 case 6:
284b731a
LA
5478 {
5479 TCGv_i64 tmp = tcg_temp_new_i64();
5480 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5481 gen_move_low32(arg, tmp);
5482 tcg_temp_free_i64(tmp);
5483 }
873eb012
TS
5484 rn = "TagLo";
5485 break;
5486 case 1:
7a387fff
TS
5487 case 3:
5488 case 5:
5489 case 7:
7db13fae 5490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5491 rn = "DataLo";
5492 break;
5493 default:
f31b035a 5494 goto cp0_unimplemented;
873eb012
TS
5495 }
5496 break;
8c0fdd85 5497 case 29:
7a387fff
TS
5498 switch (sel) {
5499 case 0:
5500 case 2:
5501 case 4:
5502 case 6:
7db13fae 5503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5504 rn = "TagHi";
5505 break;
5506 case 1:
5507 case 3:
5508 case 5:
5509 case 7:
7db13fae 5510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5511 rn = "DataHi";
5512 break;
5513 default:
f31b035a 5514 goto cp0_unimplemented;
7a387fff 5515 }
8c0fdd85 5516 break;
873eb012 5517 case 30:
7a387fff
TS
5518 switch (sel) {
5519 case 0:
7db13fae 5520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5521 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5522 rn = "ErrorEPC";
5523 break;
7a387fff 5524 default:
f31b035a 5525 goto cp0_unimplemented;
7a387fff 5526 }
873eb012
TS
5527 break;
5528 case 31:
7a387fff
TS
5529 switch (sel) {
5530 case 0:
f0b3f3ae 5531 /* EJTAG support */
7db13fae 5532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5533 rn = "DESAVE";
5534 break;
e98c0d17 5535 case 2 ... 7:
f31b035a
LA
5536 CP0_CHECK(ctx->kscrexist & (1 << sel));
5537 tcg_gen_ld_tl(arg, cpu_env,
5538 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5539 tcg_gen_ext32s_tl(arg, arg);
5540 rn = "KScratch";
e98c0d17 5541 break;
7a387fff 5542 default:
f31b035a 5543 goto cp0_unimplemented;
7a387fff 5544 }
873eb012
TS
5545 break;
5546 default:
f31b035a 5547 goto cp0_unimplemented;
873eb012 5548 }
2abf314d 5549 (void)rn; /* avoid a compiler warning */
d12d51d5 5550 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5551 return;
5552
f31b035a 5553cp0_unimplemented:
d12d51d5 5554 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5555 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5556}
5557
d75c135e 5558static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5559{
7a387fff
TS
5560 const char *rn = "invalid";
5561
e189e748 5562 if (sel != 0)
d75c135e 5563 check_insn(ctx, ISA_MIPS32);
e189e748 5564
bd79255d 5565 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5566 gen_io_start();
bd79255d 5567 }
2e70f6ef 5568
8c0fdd85
TS
5569 switch (reg) {
5570 case 0:
7a387fff
TS
5571 switch (sel) {
5572 case 0:
895c2d04 5573 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5574 rn = "Index";
5575 break;
5576 case 1:
f31b035a 5577 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5578 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5579 rn = "MVPControl";
ead9360e 5580 break;
7a387fff 5581 case 2:
f31b035a 5582 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5583 /* ignored */
7a387fff 5584 rn = "MVPConf0";
ead9360e 5585 break;
7a387fff 5586 case 3:
f31b035a 5587 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5588 /* ignored */
7a387fff 5589 rn = "MVPConf1";
ead9360e 5590 break;
7a387fff 5591 default:
f31b035a 5592 goto cp0_unimplemented;
7a387fff 5593 }
8c0fdd85
TS
5594 break;
5595 case 1:
7a387fff
TS
5596 switch (sel) {
5597 case 0:
2423f660 5598 /* ignored */
7a387fff 5599 rn = "Random";
2423f660 5600 break;
7a387fff 5601 case 1:
f31b035a 5602 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5603 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5604 rn = "VPEControl";
ead9360e 5605 break;
7a387fff 5606 case 2:
f31b035a 5607 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5608 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5609 rn = "VPEConf0";
ead9360e 5610 break;
7a387fff 5611 case 3:
f31b035a 5612 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5613 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5614 rn = "VPEConf1";
ead9360e 5615 break;
7a387fff 5616 case 4:
f31b035a 5617 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5618 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5619 rn = "YQMask";
ead9360e 5620 break;
7a387fff 5621 case 5:
f31b035a 5622 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5623 tcg_gen_st_tl(arg, cpu_env,
5624 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5625 rn = "VPESchedule";
ead9360e 5626 break;
7a387fff 5627 case 6:
f31b035a 5628 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5629 tcg_gen_st_tl(arg, cpu_env,
5630 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5631 rn = "VPEScheFBack";
ead9360e 5632 break;
7a387fff 5633 case 7:
f31b035a 5634 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5635 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5636 rn = "VPEOpt";
ead9360e 5637 break;
7a387fff 5638 default:
f31b035a 5639 goto cp0_unimplemented;
7a387fff 5640 }
8c0fdd85
TS
5641 break;
5642 case 2:
7a387fff
TS
5643 switch (sel) {
5644 case 0:
895c2d04 5645 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5646 rn = "EntryLo0";
5647 break;
7a387fff 5648 case 1:
f31b035a 5649 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5650 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5651 rn = "TCStatus";
ead9360e 5652 break;
7a387fff 5653 case 2:
f31b035a 5654 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5655 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5656 rn = "TCBind";
ead9360e 5657 break;
7a387fff 5658 case 3:
f31b035a 5659 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5660 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5661 rn = "TCRestart";
ead9360e 5662 break;
7a387fff 5663 case 4:
f31b035a 5664 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5665 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5666 rn = "TCHalt";
ead9360e 5667 break;
7a387fff 5668 case 5:
f31b035a 5669 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5670 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5671 rn = "TCContext";
ead9360e 5672 break;
7a387fff 5673 case 6:
f31b035a 5674 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5675 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5676 rn = "TCSchedule";
ead9360e 5677 break;
7a387fff 5678 case 7:
f31b035a 5679 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5680 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5681 rn = "TCScheFBack";
ead9360e 5682 break;
7a387fff 5683 default:
f31b035a 5684 goto cp0_unimplemented;
7a387fff 5685 }
8c0fdd85
TS
5686 break;
5687 case 3:
7a387fff
TS
5688 switch (sel) {
5689 case 0:
895c2d04 5690 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5691 rn = "EntryLo1";
5692 break;
7a387fff 5693 default:
f31b035a 5694 goto cp0_unimplemented;
876d4b07 5695 }
8c0fdd85
TS
5696 break;
5697 case 4:
7a387fff
TS
5698 switch (sel) {
5699 case 0:
895c2d04 5700 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5701 rn = "Context";
5702 break;
7a387fff 5703 case 1:
895c2d04 5704// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5705 rn = "ContextConfig";
f31b035a 5706 goto cp0_unimplemented;
2423f660 5707// break;
d279279e 5708 case 2:
f31b035a
LA
5709 CP0_CHECK(ctx->ulri);
5710 tcg_gen_st_tl(arg, cpu_env,
5711 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5712 rn = "UserLocal";
d279279e 5713 break;
7a387fff 5714 default:
f31b035a 5715 goto cp0_unimplemented;
876d4b07 5716 }
8c0fdd85
TS
5717 break;
5718 case 5:
7a387fff
TS
5719 switch (sel) {
5720 case 0:
895c2d04 5721 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5722 rn = "PageMask";
5723 break;
7a387fff 5724 case 1:
d75c135e 5725 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5726 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5727 rn = "PageGrain";
e117f526 5728 ctx->bstate = BS_STOP;
2423f660 5729 break;
7a387fff 5730 default:
f31b035a 5731 goto cp0_unimplemented;
876d4b07 5732 }
8c0fdd85
TS
5733 break;
5734 case 6:
7a387fff
TS
5735 switch (sel) {
5736 case 0:
895c2d04 5737 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5738 rn = "Wired";
5739 break;
7a387fff 5740 case 1:
d75c135e 5741 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5742 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5743 rn = "SRSConf0";
ead9360e 5744 break;
7a387fff 5745 case 2:
d75c135e 5746 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5747 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5748 rn = "SRSConf1";
ead9360e 5749 break;
7a387fff 5750 case 3:
d75c135e 5751 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5752 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5753 rn = "SRSConf2";
ead9360e 5754 break;
7a387fff 5755 case 4:
d75c135e 5756 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5757 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5758 rn = "SRSConf3";
ead9360e 5759 break;
7a387fff 5760 case 5:
d75c135e 5761 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5762 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5763 rn = "SRSConf4";
ead9360e 5764 break;
7a387fff 5765 default:
f31b035a 5766 goto cp0_unimplemented;
876d4b07 5767 }
8c0fdd85
TS
5768 break;
5769 case 7:
7a387fff
TS
5770 switch (sel) {
5771 case 0:
d75c135e 5772 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5773 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5774 ctx->bstate = BS_STOP;
2423f660
TS
5775 rn = "HWREna";
5776 break;
7a387fff 5777 default:
f31b035a 5778 goto cp0_unimplemented;
876d4b07 5779 }
8c0fdd85
TS
5780 break;
5781 case 8:
aea14095
LA
5782 switch (sel) {
5783 case 0:
5784 /* ignored */
5785 rn = "BadVAddr";
5786 break;
5787 case 1:
5788 /* ignored */
5789 rn = "BadInstr";
5790 break;
5791 case 2:
5792 /* ignored */
5793 rn = "BadInstrP";
5794 break;
5795 default:
f31b035a 5796 goto cp0_unimplemented;
aea14095 5797 }
8c0fdd85
TS
5798 break;
5799 case 9:
7a387fff
TS
5800 switch (sel) {
5801 case 0:
895c2d04 5802 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5803 rn = "Count";
5804 break;
876d4b07 5805 /* 6,7 are implementation dependent */
7a387fff 5806 default:
f31b035a 5807 goto cp0_unimplemented;
876d4b07 5808 }
8c0fdd85
TS
5809 break;
5810 case 10:
7a387fff
TS
5811 switch (sel) {
5812 case 0:
895c2d04 5813 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5814 rn = "EntryHi";
5815 break;
7a387fff 5816 default:
f31b035a 5817 goto cp0_unimplemented;
876d4b07 5818 }
8c0fdd85
TS
5819 break;
5820 case 11:
7a387fff
TS
5821 switch (sel) {
5822 case 0:
895c2d04 5823 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5824 rn = "Compare";
5825 break;
5826 /* 6,7 are implementation dependent */
7a387fff 5827 default:
f31b035a 5828 goto cp0_unimplemented;
876d4b07 5829 }
8c0fdd85
TS
5830 break;
5831 case 12:
7a387fff
TS
5832 switch (sel) {
5833 case 0:
867abc7e 5834 save_cpu_state(ctx, 1);
895c2d04 5835 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5836 /* BS_STOP isn't good enough here, hflags may have changed. */
5837 gen_save_pc(ctx->pc + 4);
5838 ctx->bstate = BS_EXCP;
2423f660
TS
5839 rn = "Status";
5840 break;
7a387fff 5841 case 1:
d75c135e 5842 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5843 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5844 /* Stop translation as we may have switched the execution mode */
5845 ctx->bstate = BS_STOP;
2423f660
TS
5846 rn = "IntCtl";
5847 break;
7a387fff 5848 case 2:
d75c135e 5849 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5850 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5851 /* Stop translation as we may have switched the execution mode */
5852 ctx->bstate = BS_STOP;
2423f660
TS
5853 rn = "SRSCtl";
5854 break;
7a387fff 5855 case 3:
d75c135e 5856 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5857 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx->bstate = BS_STOP;
2423f660 5860 rn = "SRSMap";
fd88b6ab 5861 break;
7a387fff 5862 default:
f31b035a 5863 goto cp0_unimplemented;
876d4b07 5864 }
8c0fdd85
TS
5865 break;
5866 case 13:
7a387fff
TS
5867 switch (sel) {
5868 case 0:
867abc7e 5869 save_cpu_state(ctx, 1);
895c2d04 5870 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5871 rn = "Cause";
5872 break;
7a387fff 5873 default:
f31b035a 5874 goto cp0_unimplemented;
876d4b07 5875 }
8c0fdd85
TS
5876 break;
5877 case 14:
7a387fff
TS
5878 switch (sel) {
5879 case 0:
d54a299b 5880 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5881 rn = "EPC";
5882 break;
7a387fff 5883 default:
f31b035a 5884 goto cp0_unimplemented;
876d4b07 5885 }
8c0fdd85
TS
5886 break;
5887 case 15:
7a387fff
TS
5888 switch (sel) {
5889 case 0:
2423f660
TS
5890 /* ignored */
5891 rn = "PRid";
5892 break;
7a387fff 5893 case 1:
d75c135e 5894 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5895 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5896 rn = "EBase";
5897 break;
7a387fff 5898 default:
f31b035a 5899 goto cp0_unimplemented;
1579a72e 5900 }
8c0fdd85
TS
5901 break;
5902 case 16:
5903 switch (sel) {
5904 case 0:
895c2d04 5905 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5906 rn = "Config";
2423f660
TS
5907 /* Stop translation as we may have switched the execution mode */
5908 ctx->bstate = BS_STOP;
7a387fff
TS
5909 break;
5910 case 1:
e397ee33 5911 /* ignored, read only */
7a387fff
TS
5912 rn = "Config1";
5913 break;
5914 case 2:
895c2d04 5915 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5916 rn = "Config2";
2423f660
TS
5917 /* Stop translation as we may have switched the execution mode */
5918 ctx->bstate = BS_STOP;
8c0fdd85 5919 break;
7a387fff 5920 case 3:
90f12d73 5921 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5922 rn = "Config3";
90f12d73
MR
5923 /* Stop translation as we may have switched the execution mode */
5924 ctx->bstate = BS_STOP;
7a387fff 5925 break;
b4160af1
PJ
5926 case 4:
5927 gen_helper_mtc0_config4(cpu_env, arg);
5928 rn = "Config4";
5929 ctx->bstate = BS_STOP;
5930 break;
b4dd99a3
PJ
5931 case 5:
5932 gen_helper_mtc0_config5(cpu_env, arg);
5933 rn = "Config5";
5934 /* Stop translation as we may have switched the execution mode */
5935 ctx->bstate = BS_STOP;
5936 break;
e397ee33
TS
5937 /* 6,7 are implementation dependent */
5938 case 6:
5939 /* ignored */
5940 rn = "Config6";
5941 break;
5942 case 7:
5943 /* ignored */
5944 rn = "Config7";
5945 break;
8c0fdd85
TS
5946 default:
5947 rn = "Invalid config selector";
f31b035a 5948 goto cp0_unimplemented;
8c0fdd85
TS
5949 }
5950 break;
5951 case 17:
7a387fff
TS
5952 switch (sel) {
5953 case 0:
895c2d04 5954 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5955 rn = "LLAddr";
5956 break;
7a387fff 5957 default:
f31b035a 5958 goto cp0_unimplemented;
7a387fff 5959 }
8c0fdd85
TS
5960 break;
5961 case 18:
7a387fff 5962 switch (sel) {
fd88b6ab 5963 case 0 ... 7:
895c2d04 5964 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5965 rn = "WatchLo";
5966 break;
7a387fff 5967 default:
f31b035a 5968 goto cp0_unimplemented;
7a387fff 5969 }
8c0fdd85
TS
5970 break;
5971 case 19:
7a387fff 5972 switch (sel) {
fd88b6ab 5973 case 0 ... 7:
895c2d04 5974 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5975 rn = "WatchHi";
5976 break;
7a387fff 5977 default:
f31b035a 5978 goto cp0_unimplemented;
7a387fff 5979 }
8c0fdd85
TS
5980 break;
5981 case 20:
7a387fff
TS
5982 switch (sel) {
5983 case 0:
d26bc211 5984#if defined(TARGET_MIPS64)
d75c135e 5985 check_insn(ctx, ISA_MIPS3);
895c2d04 5986 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5987 rn = "XContext";
5988 break;
703eaf37 5989#endif
7a387fff 5990 default:
f31b035a 5991 goto cp0_unimplemented;
7a387fff 5992 }
8c0fdd85
TS
5993 break;
5994 case 21:
7a387fff 5995 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5996 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5997 switch (sel) {
5998 case 0:
895c2d04 5999 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6000 rn = "Framemask";
6001 break;
7a387fff 6002 default:
f31b035a 6003 goto cp0_unimplemented;
7a387fff
TS
6004 }
6005 break;
8c0fdd85 6006 case 22:
7a387fff
TS
6007 /* ignored */
6008 rn = "Diagnostic"; /* implementation dependent */
2423f660 6009 break;
8c0fdd85 6010 case 23:
7a387fff
TS
6011 switch (sel) {
6012 case 0:
895c2d04 6013 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6014 /* BS_STOP isn't good enough here, hflags may have changed. */
6015 gen_save_pc(ctx->pc + 4);
6016 ctx->bstate = BS_EXCP;
2423f660
TS
6017 rn = "Debug";
6018 break;
7a387fff 6019 case 1:
895c2d04 6020// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6021 rn = "TraceControl";
8487327a
TS
6022 /* Stop translation as we may have switched the execution mode */
6023 ctx->bstate = BS_STOP;
2423f660 6024// break;
7a387fff 6025 case 2:
895c2d04 6026// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6027 rn = "TraceControl2";
8487327a
TS
6028 /* Stop translation as we may have switched the execution mode */
6029 ctx->bstate = BS_STOP;
2423f660 6030// break;
7a387fff 6031 case 3:
8487327a
TS
6032 /* Stop translation as we may have switched the execution mode */
6033 ctx->bstate = BS_STOP;
895c2d04 6034// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6035 rn = "UserTraceData";
8487327a
TS
6036 /* Stop translation as we may have switched the execution mode */
6037 ctx->bstate = BS_STOP;
2423f660 6038// break;
7a387fff 6039 case 4:
895c2d04 6040// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6041 /* Stop translation as we may have switched the execution mode */
6042 ctx->bstate = BS_STOP;
2423f660
TS
6043 rn = "TraceBPC";
6044// break;
7a387fff 6045 default:
f31b035a 6046 goto cp0_unimplemented;
7a387fff 6047 }
8c0fdd85
TS
6048 break;
6049 case 24:
7a387fff
TS
6050 switch (sel) {
6051 case 0:
f1aa6320 6052 /* EJTAG support */
d54a299b 6053 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6054 rn = "DEPC";
6055 break;
7a387fff 6056 default:
f31b035a 6057 goto cp0_unimplemented;
7a387fff 6058 }
8c0fdd85
TS
6059 break;
6060 case 25:
7a387fff
TS
6061 switch (sel) {
6062 case 0:
895c2d04 6063 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6064 rn = "Performance0";
6065 break;
7a387fff 6066 case 1:
d9bea114 6067// gen_helper_mtc0_performance1(arg);
2423f660
TS
6068 rn = "Performance1";
6069// break;
7a387fff 6070 case 2:
d9bea114 6071// gen_helper_mtc0_performance2(arg);
2423f660
TS
6072 rn = "Performance2";
6073// break;
7a387fff 6074 case 3:
d9bea114 6075// gen_helper_mtc0_performance3(arg);
2423f660
TS
6076 rn = "Performance3";
6077// break;
7a387fff 6078 case 4:
d9bea114 6079// gen_helper_mtc0_performance4(arg);
2423f660
TS
6080 rn = "Performance4";
6081// break;
7a387fff 6082 case 5:
d9bea114 6083// gen_helper_mtc0_performance5(arg);
2423f660
TS
6084 rn = "Performance5";
6085// break;
7a387fff 6086 case 6:
d9bea114 6087// gen_helper_mtc0_performance6(arg);
2423f660
TS
6088 rn = "Performance6";
6089// break;
7a387fff 6090 case 7:
d9bea114 6091// gen_helper_mtc0_performance7(arg);
2423f660
TS
6092 rn = "Performance7";
6093// break;
7a387fff 6094 default:
f31b035a 6095 goto cp0_unimplemented;
7a387fff 6096 }
8c0fdd85
TS
6097 break;
6098 case 26:
2423f660 6099 /* ignored */
8c0fdd85 6100 rn = "ECC";
2423f660 6101 break;
8c0fdd85 6102 case 27:
7a387fff
TS
6103 switch (sel) {
6104 case 0 ... 3:
2423f660
TS
6105 /* ignored */
6106 rn = "CacheErr";
6107 break;
7a387fff 6108 default:
f31b035a 6109 goto cp0_unimplemented;
7a387fff 6110 }
8c0fdd85
TS
6111 break;
6112 case 28:
6113 switch (sel) {
6114 case 0:
7a387fff
TS
6115 case 2:
6116 case 4:
6117 case 6:
895c2d04 6118 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6119 rn = "TagLo";
6120 break;
7a387fff
TS
6121 case 1:
6122 case 3:
6123 case 5:
6124 case 7:
895c2d04 6125 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6126 rn = "DataLo";
6127 break;
8c0fdd85 6128 default:
f31b035a 6129 goto cp0_unimplemented;
8c0fdd85
TS
6130 }
6131 break;
6132 case 29:
7a387fff
TS
6133 switch (sel) {
6134 case 0:
6135 case 2:
6136 case 4:
6137 case 6:
895c2d04 6138 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6139 rn = "TagHi";
6140 break;
6141 case 1:
6142 case 3:
6143 case 5:
6144 case 7:
895c2d04 6145 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6146 rn = "DataHi";
6147 break;
6148 default:
6149 rn = "invalid sel";
f31b035a 6150 goto cp0_unimplemented;
7a387fff 6151 }
8c0fdd85
TS
6152 break;
6153 case 30:
7a387fff
TS
6154 switch (sel) {
6155 case 0:
d54a299b 6156 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6157 rn = "ErrorEPC";
6158 break;
7a387fff 6159 default:
f31b035a 6160 goto cp0_unimplemented;
7a387fff 6161 }
8c0fdd85
TS
6162 break;
6163 case 31:
7a387fff
TS
6164 switch (sel) {
6165 case 0:
f1aa6320 6166 /* EJTAG support */
7db13fae 6167 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6168 rn = "DESAVE";
6169 break;
e98c0d17 6170 case 2 ... 7:
f31b035a
LA
6171 CP0_CHECK(ctx->kscrexist & (1 << sel));
6172 tcg_gen_st_tl(arg, cpu_env,
6173 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6174 rn = "KScratch";
e98c0d17 6175 break;
7a387fff 6176 default:
f31b035a 6177 goto cp0_unimplemented;
7a387fff 6178 }
2423f660
TS
6179 /* Stop translation as we may have switched the execution mode */
6180 ctx->bstate = BS_STOP;
8c0fdd85
TS
6181 break;
6182 default:
f31b035a 6183 goto cp0_unimplemented;
8c0fdd85 6184 }
2abf314d 6185 (void)rn; /* avoid a compiler warning */
d12d51d5 6186 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6187 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6188 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6189 gen_io_end();
6190 ctx->bstate = BS_STOP;
6191 }
8c0fdd85
TS
6192 return;
6193
f31b035a 6194cp0_unimplemented:
d12d51d5 6195 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6196}
6197
d26bc211 6198#if defined(TARGET_MIPS64)
d75c135e 6199static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6200{
6201 const char *rn = "invalid";
6202
e189e748 6203 if (sel != 0)
d75c135e 6204 check_insn(ctx, ISA_MIPS64);
e189e748 6205
9c2149c8
TS
6206 switch (reg) {
6207 case 0:
6208 switch (sel) {
6209 case 0:
7db13fae 6210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6211 rn = "Index";
6212 break;
6213 case 1:
f31b035a 6214 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6215 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6216 rn = "MVPControl";
ead9360e 6217 break;
9c2149c8 6218 case 2:
f31b035a 6219 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6220 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6221 rn = "MVPConf0";
ead9360e 6222 break;
9c2149c8 6223 case 3:
f31b035a 6224 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6225 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6226 rn = "MVPConf1";
ead9360e 6227 break;
9c2149c8 6228 default:
f31b035a 6229 goto cp0_unimplemented;
9c2149c8
TS
6230 }
6231 break;
6232 case 1:
6233 switch (sel) {
6234 case 0:
f31b035a 6235 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6236 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6237 rn = "Random";
2423f660 6238 break;
9c2149c8 6239 case 1:
f31b035a 6240 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6242 rn = "VPEControl";
ead9360e 6243 break;
9c2149c8 6244 case 2:
f31b035a 6245 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6247 rn = "VPEConf0";
ead9360e 6248 break;
9c2149c8 6249 case 3:
f31b035a 6250 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6252 rn = "VPEConf1";
ead9360e 6253 break;
9c2149c8 6254 case 4:
f31b035a 6255 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6256 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6257 rn = "YQMask";
ead9360e 6258 break;
9c2149c8 6259 case 5:
f31b035a 6260 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6262 rn = "VPESchedule";
ead9360e 6263 break;
9c2149c8 6264 case 6:
f31b035a 6265 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6266 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6267 rn = "VPEScheFBack";
ead9360e 6268 break;
9c2149c8 6269 case 7:
f31b035a 6270 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6272 rn = "VPEOpt";
ead9360e 6273 break;
9c2149c8 6274 default:
f31b035a 6275 goto cp0_unimplemented;
9c2149c8
TS
6276 }
6277 break;
6278 case 2:
6279 switch (sel) {
6280 case 0:
7db13fae 6281 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6282 rn = "EntryLo0";
6283 break;
9c2149c8 6284 case 1:
f31b035a 6285 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6286 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6287 rn = "TCStatus";
ead9360e 6288 break;
9c2149c8 6289 case 2:
f31b035a 6290 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6291 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6292 rn = "TCBind";
ead9360e 6293 break;
9c2149c8 6294 case 3:
f31b035a 6295 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6296 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6297 rn = "TCRestart";
ead9360e 6298 break;
9c2149c8 6299 case 4:
f31b035a 6300 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6301 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6302 rn = "TCHalt";
ead9360e 6303 break;
9c2149c8 6304 case 5:
f31b035a 6305 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6306 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6307 rn = "TCContext";
ead9360e 6308 break;
9c2149c8 6309 case 6:
f31b035a 6310 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6311 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6312 rn = "TCSchedule";
ead9360e 6313 break;
9c2149c8 6314 case 7:
f31b035a 6315 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6316 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6317 rn = "TCScheFBack";
ead9360e 6318 break;
9c2149c8 6319 default:
f31b035a 6320 goto cp0_unimplemented;
9c2149c8
TS
6321 }
6322 break;
6323 case 3:
6324 switch (sel) {
6325 case 0:
7db13fae 6326 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6327 rn = "EntryLo1";
6328 break;
9c2149c8 6329 default:
f31b035a 6330 goto cp0_unimplemented;
1579a72e 6331 }
9c2149c8
TS
6332 break;
6333 case 4:
6334 switch (sel) {
6335 case 0:
7db13fae 6336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6337 rn = "Context";
6338 break;
9c2149c8 6339 case 1:
d9bea114 6340// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6341 rn = "ContextConfig";
f31b035a 6342 goto cp0_unimplemented;
2423f660 6343// break;
d279279e 6344 case 2:
f31b035a
LA
6345 CP0_CHECK(ctx->ulri);
6346 tcg_gen_ld_tl(arg, cpu_env,
6347 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6348 rn = "UserLocal";
d279279e 6349 break;
9c2149c8 6350 default:
f31b035a 6351 goto cp0_unimplemented;
876d4b07 6352 }
9c2149c8
TS
6353 break;
6354 case 5:
6355 switch (sel) {
6356 case 0:
7db13fae 6357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6358 rn = "PageMask";
6359 break;
9c2149c8 6360 case 1:
d75c135e 6361 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6363 rn = "PageGrain";
6364 break;
9c2149c8 6365 default:
f31b035a 6366 goto cp0_unimplemented;
876d4b07 6367 }
9c2149c8
TS
6368 break;
6369 case 6:
6370 switch (sel) {
6371 case 0:
7db13fae 6372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6373 rn = "Wired";
6374 break;
9c2149c8 6375 case 1:
d75c135e 6376 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6378 rn = "SRSConf0";
ead9360e 6379 break;
9c2149c8 6380 case 2:
d75c135e 6381 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6383 rn = "SRSConf1";
ead9360e 6384 break;
9c2149c8 6385 case 3:
d75c135e 6386 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6388 rn = "SRSConf2";
ead9360e 6389 break;
9c2149c8 6390 case 4:
d75c135e 6391 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6393 rn = "SRSConf3";
ead9360e 6394 break;
9c2149c8 6395 case 5:
d75c135e 6396 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6398 rn = "SRSConf4";
ead9360e 6399 break;
9c2149c8 6400 default:
f31b035a 6401 goto cp0_unimplemented;
876d4b07 6402 }
9c2149c8
TS
6403 break;
6404 case 7:
6405 switch (sel) {
6406 case 0:
d75c135e 6407 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6409 rn = "HWREna";
6410 break;
9c2149c8 6411 default:
f31b035a 6412 goto cp0_unimplemented;
876d4b07 6413 }
9c2149c8
TS
6414 break;
6415 case 8:
6416 switch (sel) {
6417 case 0:
7db13fae 6418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6419 rn = "BadVAddr";
2423f660 6420 break;
aea14095 6421 case 1:
f31b035a
LA
6422 CP0_CHECK(ctx->bi);
6423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6424 rn = "BadInstr";
aea14095
LA
6425 break;
6426 case 2:
f31b035a
LA
6427 CP0_CHECK(ctx->bp);
6428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6429 rn = "BadInstrP";
aea14095 6430 break;
9c2149c8 6431 default:
f31b035a 6432 goto cp0_unimplemented;
876d4b07 6433 }
9c2149c8
TS
6434 break;
6435 case 9:
6436 switch (sel) {
6437 case 0:
2e70f6ef 6438 /* Mark as an IO operation because we read the time. */
bd79255d 6439 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6440 gen_io_start();
bd79255d 6441 }
895c2d04 6442 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6443 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6444 gen_io_end();
2e70f6ef 6445 }
55807224
EI
6446 /* Break the TB to be able to take timer interrupts immediately
6447 after reading count. */
6448 ctx->bstate = BS_STOP;
2423f660
TS
6449 rn = "Count";
6450 break;
6451 /* 6,7 are implementation dependent */
9c2149c8 6452 default:
f31b035a 6453 goto cp0_unimplemented;
876d4b07 6454 }
9c2149c8
TS
6455 break;
6456 case 10:
6457 switch (sel) {
6458 case 0:
7db13fae 6459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6460 rn = "EntryHi";
6461 break;
9c2149c8 6462 default:
f31b035a 6463 goto cp0_unimplemented;
876d4b07 6464 }
9c2149c8
TS
6465 break;
6466 case 11:
6467 switch (sel) {
6468 case 0:
7db13fae 6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6470 rn = "Compare";
6471 break;
876d4b07 6472 /* 6,7 are implementation dependent */
9c2149c8 6473 default:
f31b035a 6474 goto cp0_unimplemented;
876d4b07 6475 }
9c2149c8
TS
6476 break;
6477 case 12:
6478 switch (sel) {
6479 case 0:
7db13fae 6480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6481 rn = "Status";
6482 break;
9c2149c8 6483 case 1:
d75c135e 6484 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6486 rn = "IntCtl";
6487 break;
9c2149c8 6488 case 2:
d75c135e 6489 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6491 rn = "SRSCtl";
6492 break;
9c2149c8 6493 case 3:
d75c135e 6494 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6496 rn = "SRSMap";
6497 break;
9c2149c8 6498 default:
f31b035a 6499 goto cp0_unimplemented;
876d4b07 6500 }
9c2149c8
TS
6501 break;
6502 case 13:
6503 switch (sel) {
6504 case 0:
7db13fae 6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6506 rn = "Cause";
6507 break;
9c2149c8 6508 default:
f31b035a 6509 goto cp0_unimplemented;
876d4b07 6510 }
9c2149c8
TS
6511 break;
6512 case 14:
6513 switch (sel) {
6514 case 0:
7db13fae 6515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6516 rn = "EPC";
6517 break;
9c2149c8 6518 default:
f31b035a 6519 goto cp0_unimplemented;
876d4b07 6520 }
9c2149c8
TS
6521 break;
6522 case 15:
6523 switch (sel) {
6524 case 0:
7db13fae 6525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6526 rn = "PRid";
6527 break;
9c2149c8 6528 case 1:
d75c135e 6529 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6531 rn = "EBase";
6532 break;
9c2149c8 6533 default:
f31b035a 6534 goto cp0_unimplemented;
876d4b07 6535 }
9c2149c8
TS
6536 break;
6537 case 16:
6538 switch (sel) {
6539 case 0:
7db13fae 6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6541 rn = "Config";
6542 break;
6543 case 1:
7db13fae 6544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6545 rn = "Config1";
6546 break;
6547 case 2:
7db13fae 6548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6549 rn = "Config2";
6550 break;
6551 case 3:
7db13fae 6552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6553 rn = "Config3";
6554 break;
faf1f68b
LA
6555 case 4:
6556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6557 rn = "Config4";
6558 break;
6559 case 5:
6560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6561 rn = "Config5";
6562 break;
9c2149c8 6563 /* 6,7 are implementation dependent */
f0b3f3ae 6564 case 6:
7db13fae 6565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6566 rn = "Config6";
6567 break;
6568 case 7:
7db13fae 6569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6570 rn = "Config7";
6571 break;
9c2149c8 6572 default:
f31b035a 6573 goto cp0_unimplemented;
9c2149c8
TS
6574 }
6575 break;
6576 case 17:
6577 switch (sel) {
6578 case 0:
895c2d04 6579 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6580 rn = "LLAddr";
6581 break;
9c2149c8 6582 default:
f31b035a 6583 goto cp0_unimplemented;
9c2149c8
TS
6584 }
6585 break;
6586 case 18:
6587 switch (sel) {
fd88b6ab 6588 case 0 ... 7:
895c2d04 6589 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6590 rn = "WatchLo";
6591 break;
9c2149c8 6592 default:
f31b035a 6593 goto cp0_unimplemented;
9c2149c8
TS
6594 }
6595 break;
6596 case 19:
6597 switch (sel) {
fd88b6ab 6598 case 0 ... 7:
895c2d04 6599 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6600 rn = "WatchHi";
6601 break;
9c2149c8 6602 default:
f31b035a 6603 goto cp0_unimplemented;
9c2149c8
TS
6604 }
6605 break;
6606 case 20:
6607 switch (sel) {
6608 case 0:
d75c135e 6609 check_insn(ctx, ISA_MIPS3);
7db13fae 6610 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6611 rn = "XContext";
6612 break;
9c2149c8 6613 default:
f31b035a 6614 goto cp0_unimplemented;
9c2149c8
TS
6615 }
6616 break;
6617 case 21:
6618 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6619 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6620 switch (sel) {
6621 case 0:
7db13fae 6622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6623 rn = "Framemask";
6624 break;
9c2149c8 6625 default:
f31b035a 6626 goto cp0_unimplemented;
9c2149c8
TS
6627 }
6628 break;
6629 case 22:
d9bea114 6630 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6631 rn = "'Diagnostic"; /* implementation dependent */
6632 break;
9c2149c8
TS
6633 case 23:
6634 switch (sel) {
6635 case 0:
895c2d04 6636 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6637 rn = "Debug";
6638 break;
9c2149c8 6639 case 1:
895c2d04 6640// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6641 rn = "TraceControl";
6642// break;
9c2149c8 6643 case 2:
895c2d04 6644// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6645 rn = "TraceControl2";
6646// break;
9c2149c8 6647 case 3:
895c2d04 6648// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6649 rn = "UserTraceData";
6650// break;
9c2149c8 6651 case 4:
895c2d04 6652// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6653 rn = "TraceBPC";
6654// break;
9c2149c8 6655 default:
f31b035a 6656 goto cp0_unimplemented;
9c2149c8
TS
6657 }
6658 break;
6659 case 24:
6660 switch (sel) {
6661 case 0:
f0b3f3ae 6662 /* EJTAG support */
7db13fae 6663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6664 rn = "DEPC";
6665 break;
9c2149c8 6666 default:
f31b035a 6667 goto cp0_unimplemented;
9c2149c8
TS
6668 }
6669 break;
6670 case 25:
6671 switch (sel) {
6672 case 0:
7db13fae 6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6674 rn = "Performance0";
9c2149c8
TS
6675 break;
6676 case 1:
d9bea114 6677// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6678 rn = "Performance1";
6679// break;
9c2149c8 6680 case 2:
d9bea114 6681// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6682 rn = "Performance2";
6683// break;
9c2149c8 6684 case 3:
d9bea114 6685// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6686 rn = "Performance3";
6687// break;
9c2149c8 6688 case 4:
d9bea114 6689// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6690 rn = "Performance4";
6691// break;
9c2149c8 6692 case 5:
d9bea114 6693// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6694 rn = "Performance5";
6695// break;
9c2149c8 6696 case 6:
d9bea114 6697// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6698 rn = "Performance6";
6699// break;
9c2149c8 6700 case 7:
d9bea114 6701// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6702 rn = "Performance7";
6703// break;
9c2149c8 6704 default:
f31b035a 6705 goto cp0_unimplemented;
9c2149c8
TS
6706 }
6707 break;
6708 case 26:
d9bea114 6709 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6710 rn = "ECC";
6711 break;
9c2149c8
TS
6712 case 27:
6713 switch (sel) {
6714 /* ignored */
6715 case 0 ... 3:
d9bea114 6716 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6717 rn = "CacheErr";
6718 break;
9c2149c8 6719 default:
f31b035a 6720 goto cp0_unimplemented;
9c2149c8
TS
6721 }
6722 break;
6723 case 28:
6724 switch (sel) {
6725 case 0:
6726 case 2:
6727 case 4:
6728 case 6:
7db13fae 6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6730 rn = "TagLo";
6731 break;
6732 case 1:
6733 case 3:
6734 case 5:
6735 case 7:
7db13fae 6736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6737 rn = "DataLo";
6738 break;
6739 default:
f31b035a 6740 goto cp0_unimplemented;
9c2149c8
TS
6741 }
6742 break;
6743 case 29:
6744 switch (sel) {
6745 case 0:
6746 case 2:
6747 case 4:
6748 case 6:
7db13fae 6749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6750 rn = "TagHi";
6751 break;
6752 case 1:
6753 case 3:
6754 case 5:
6755 case 7:
7db13fae 6756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6757 rn = "DataHi";
6758 break;
6759 default:
f31b035a 6760 goto cp0_unimplemented;
9c2149c8
TS
6761 }
6762 break;
6763 case 30:
6764 switch (sel) {
6765 case 0:
7db13fae 6766 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6767 rn = "ErrorEPC";
6768 break;
9c2149c8 6769 default:
f31b035a 6770 goto cp0_unimplemented;
9c2149c8
TS
6771 }
6772 break;
6773 case 31:
6774 switch (sel) {
6775 case 0:
f0b3f3ae 6776 /* EJTAG support */
7db13fae 6777 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6778 rn = "DESAVE";
6779 break;
e98c0d17 6780 case 2 ... 7:
f31b035a
LA
6781 CP0_CHECK(ctx->kscrexist & (1 << sel));
6782 tcg_gen_ld_tl(arg, cpu_env,
6783 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6784 rn = "KScratch";
e98c0d17 6785 break;
9c2149c8 6786 default:
f31b035a 6787 goto cp0_unimplemented;
9c2149c8
TS
6788 }
6789 break;
6790 default:
f31b035a 6791 goto cp0_unimplemented;
9c2149c8 6792 }
2abf314d 6793 (void)rn; /* avoid a compiler warning */
d12d51d5 6794 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6795 return;
6796
f31b035a 6797cp0_unimplemented:
d12d51d5 6798 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6799 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6800}
6801
d75c135e 6802static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6803{
6804 const char *rn = "invalid";
6805
e189e748 6806 if (sel != 0)
d75c135e 6807 check_insn(ctx, ISA_MIPS64);
e189e748 6808
bd79255d 6809 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6810 gen_io_start();
bd79255d 6811 }
2e70f6ef 6812
9c2149c8
TS
6813 switch (reg) {
6814 case 0:
6815 switch (sel) {
6816 case 0:
895c2d04 6817 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6818 rn = "Index";
6819 break;
6820 case 1:
f31b035a 6821 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6822 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6823 rn = "MVPControl";
ead9360e 6824 break;
9c2149c8 6825 case 2:
f31b035a 6826 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6827 /* ignored */
9c2149c8 6828 rn = "MVPConf0";
ead9360e 6829 break;
9c2149c8 6830 case 3:
f31b035a 6831 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6832 /* ignored */
9c2149c8 6833 rn = "MVPConf1";
ead9360e 6834 break;
9c2149c8 6835 default:
f31b035a 6836 goto cp0_unimplemented;
9c2149c8
TS
6837 }
6838 break;
6839 case 1:
6840 switch (sel) {
6841 case 0:
2423f660 6842 /* ignored */
9c2149c8 6843 rn = "Random";
2423f660 6844 break;
9c2149c8 6845 case 1:
f31b035a 6846 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6847 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6848 rn = "VPEControl";
ead9360e 6849 break;
9c2149c8 6850 case 2:
f31b035a 6851 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6852 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6853 rn = "VPEConf0";
ead9360e 6854 break;
9c2149c8 6855 case 3:
f31b035a 6856 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6857 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6858 rn = "VPEConf1";
ead9360e 6859 break;
9c2149c8 6860 case 4:
f31b035a 6861 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6862 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6863 rn = "YQMask";
ead9360e 6864 break;
9c2149c8 6865 case 5:
f31b035a 6866 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6867 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6868 rn = "VPESchedule";
ead9360e 6869 break;
9c2149c8 6870 case 6:
f31b035a 6871 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6872 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6873 rn = "VPEScheFBack";
ead9360e 6874 break;
9c2149c8 6875 case 7:
f31b035a 6876 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6877 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6878 rn = "VPEOpt";
ead9360e 6879 break;
9c2149c8 6880 default:
f31b035a 6881 goto cp0_unimplemented;
9c2149c8
TS
6882 }
6883 break;
6884 case 2:
6885 switch (sel) {
6886 case 0:
7207c7f9 6887 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6888 rn = "EntryLo0";
6889 break;
9c2149c8 6890 case 1:
f31b035a 6891 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6892 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6893 rn = "TCStatus";
ead9360e 6894 break;
9c2149c8 6895 case 2:
f31b035a 6896 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6897 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6898 rn = "TCBind";
ead9360e 6899 break;
9c2149c8 6900 case 3:
f31b035a 6901 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6902 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6903 rn = "TCRestart";
ead9360e 6904 break;
9c2149c8 6905 case 4:
f31b035a 6906 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6907 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6908 rn = "TCHalt";
ead9360e 6909 break;
9c2149c8 6910 case 5:
f31b035a 6911 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6912 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6913 rn = "TCContext";
ead9360e 6914 break;
9c2149c8 6915 case 6:
f31b035a 6916 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6917 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6918 rn = "TCSchedule";
ead9360e 6919 break;
9c2149c8 6920 case 7:
f31b035a 6921 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6922 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6923 rn = "TCScheFBack";
ead9360e 6924 break;
9c2149c8 6925 default:
f31b035a 6926 goto cp0_unimplemented;
9c2149c8
TS
6927 }
6928 break;
6929 case 3:
6930 switch (sel) {
6931 case 0:
7207c7f9 6932 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6933 rn = "EntryLo1";
6934 break;
9c2149c8 6935 default:
f31b035a 6936 goto cp0_unimplemented;
876d4b07 6937 }
9c2149c8
TS
6938 break;
6939 case 4:
6940 switch (sel) {
6941 case 0:
895c2d04 6942 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6943 rn = "Context";
6944 break;
9c2149c8 6945 case 1:
895c2d04 6946// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6947 rn = "ContextConfig";
f31b035a 6948 goto cp0_unimplemented;
2423f660 6949// break;
d279279e 6950 case 2:
f31b035a
LA
6951 CP0_CHECK(ctx->ulri);
6952 tcg_gen_st_tl(arg, cpu_env,
6953 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6954 rn = "UserLocal";
d279279e 6955 break;
9c2149c8 6956 default:
f31b035a 6957 goto cp0_unimplemented;
876d4b07 6958 }
9c2149c8
TS
6959 break;
6960 case 5:
6961 switch (sel) {
6962 case 0:
895c2d04 6963 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6964 rn = "PageMask";
6965 break;
9c2149c8 6966 case 1:
d75c135e 6967 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6968 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6969 rn = "PageGrain";
6970 break;
9c2149c8 6971 default:
f31b035a 6972 goto cp0_unimplemented;
876d4b07 6973 }
9c2149c8
TS
6974 break;
6975 case 6:
6976 switch (sel) {
6977 case 0:
895c2d04 6978 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6979 rn = "Wired";
6980 break;
9c2149c8 6981 case 1:
d75c135e 6982 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6983 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6984 rn = "SRSConf0";
ead9360e 6985 break;
9c2149c8 6986 case 2:
d75c135e 6987 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6988 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6989 rn = "SRSConf1";
ead9360e 6990 break;
9c2149c8 6991 case 3:
d75c135e 6992 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6993 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6994 rn = "SRSConf2";
ead9360e 6995 break;
9c2149c8 6996 case 4:
d75c135e 6997 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6998 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6999 rn = "SRSConf3";
ead9360e 7000 break;
9c2149c8 7001 case 5:
d75c135e 7002 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7003 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7004 rn = "SRSConf4";
ead9360e 7005 break;
9c2149c8 7006 default:
f31b035a 7007 goto cp0_unimplemented;
876d4b07 7008 }
9c2149c8
TS
7009 break;
7010 case 7:
7011 switch (sel) {
7012 case 0:
d75c135e 7013 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7014 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7015 ctx->bstate = BS_STOP;
2423f660
TS
7016 rn = "HWREna";
7017 break;
9c2149c8 7018 default:
f31b035a 7019 goto cp0_unimplemented;
876d4b07 7020 }
9c2149c8
TS
7021 break;
7022 case 8:
aea14095
LA
7023 switch (sel) {
7024 case 0:
7025 /* ignored */
7026 rn = "BadVAddr";
7027 break;
7028 case 1:
7029 /* ignored */
7030 rn = "BadInstr";
7031 break;
7032 case 2:
7033 /* ignored */
7034 rn = "BadInstrP";
7035 break;
7036 default:
f31b035a 7037 goto cp0_unimplemented;
aea14095 7038 }
9c2149c8
TS
7039 break;
7040 case 9:
7041 switch (sel) {
7042 case 0:
895c2d04 7043 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7044 rn = "Count";
7045 break;
876d4b07 7046 /* 6,7 are implementation dependent */
9c2149c8 7047 default:
f31b035a 7048 goto cp0_unimplemented;
876d4b07
TS
7049 }
7050 /* Stop translation as we may have switched the execution mode */
7051 ctx->bstate = BS_STOP;
9c2149c8
TS
7052 break;
7053 case 10:
7054 switch (sel) {
7055 case 0:
895c2d04 7056 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7057 rn = "EntryHi";
7058 break;
9c2149c8 7059 default:
f31b035a 7060 goto cp0_unimplemented;
876d4b07 7061 }
9c2149c8
TS
7062 break;
7063 case 11:
7064 switch (sel) {
7065 case 0:
895c2d04 7066 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7067 rn = "Compare";
7068 break;
876d4b07 7069 /* 6,7 are implementation dependent */
9c2149c8 7070 default:
f31b035a 7071 goto cp0_unimplemented;
876d4b07 7072 }
de9a95f0
AJ
7073 /* Stop translation as we may have switched the execution mode */
7074 ctx->bstate = BS_STOP;
9c2149c8
TS
7075 break;
7076 case 12:
7077 switch (sel) {
7078 case 0:
867abc7e 7079 save_cpu_state(ctx, 1);
895c2d04 7080 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7081 /* BS_STOP isn't good enough here, hflags may have changed. */
7082 gen_save_pc(ctx->pc + 4);
7083 ctx->bstate = BS_EXCP;
2423f660
TS
7084 rn = "Status";
7085 break;
9c2149c8 7086 case 1:
d75c135e 7087 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7088 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7089 /* Stop translation as we may have switched the execution mode */
7090 ctx->bstate = BS_STOP;
2423f660
TS
7091 rn = "IntCtl";
7092 break;
9c2149c8 7093 case 2:
d75c135e 7094 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7095 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7096 /* Stop translation as we may have switched the execution mode */
7097 ctx->bstate = BS_STOP;
2423f660
TS
7098 rn = "SRSCtl";
7099 break;
9c2149c8 7100 case 3:
d75c135e 7101 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7102 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7103 /* Stop translation as we may have switched the execution mode */
7104 ctx->bstate = BS_STOP;
2423f660
TS
7105 rn = "SRSMap";
7106 break;
7107 default:
f31b035a 7108 goto cp0_unimplemented;
876d4b07 7109 }
9c2149c8
TS
7110 break;
7111 case 13:
7112 switch (sel) {
7113 case 0:
867abc7e 7114 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7115 /* Mark as an IO operation because we may trigger a software
7116 interrupt. */
bd79255d 7117 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7118 gen_io_start();
7119 }
895c2d04 7120 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7121 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7122 gen_io_end();
7123 }
7124 /* Stop translation as we may have triggered an intetrupt */
7125 ctx->bstate = BS_STOP;
2423f660
TS
7126 rn = "Cause";
7127 break;
9c2149c8 7128 default:
f31b035a 7129 goto cp0_unimplemented;
876d4b07 7130 }
9c2149c8
TS
7131 break;
7132 case 14:
7133 switch (sel) {
7134 case 0:
7db13fae 7135 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7136 rn = "EPC";
7137 break;
9c2149c8 7138 default:
f31b035a 7139 goto cp0_unimplemented;
876d4b07 7140 }
9c2149c8
TS
7141 break;
7142 case 15:
7143 switch (sel) {
7144 case 0:
2423f660
TS
7145 /* ignored */
7146 rn = "PRid";
7147 break;
9c2149c8 7148 case 1:
d75c135e 7149 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7150 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7151 rn = "EBase";
7152 break;
9c2149c8 7153 default:
f31b035a 7154 goto cp0_unimplemented;
876d4b07 7155 }
9c2149c8
TS
7156 break;
7157 case 16:
7158 switch (sel) {
7159 case 0:
895c2d04 7160 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7161 rn = "Config";
2423f660
TS
7162 /* Stop translation as we may have switched the execution mode */
7163 ctx->bstate = BS_STOP;
9c2149c8
TS
7164 break;
7165 case 1:
1fc7bf6e 7166 /* ignored, read only */
9c2149c8
TS
7167 rn = "Config1";
7168 break;
7169 case 2:
895c2d04 7170 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7171 rn = "Config2";
2423f660
TS
7172 /* Stop translation as we may have switched the execution mode */
7173 ctx->bstate = BS_STOP;
9c2149c8
TS
7174 break;
7175 case 3:
90f12d73 7176 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7177 rn = "Config3";
90f12d73
MR
7178 /* Stop translation as we may have switched the execution mode */
7179 ctx->bstate = BS_STOP;
9c2149c8 7180 break;
faf1f68b
LA
7181 case 4:
7182 /* currently ignored */
7183 rn = "Config4";
7184 break;
7185 case 5:
7186 gen_helper_mtc0_config5(cpu_env, arg);
7187 rn = "Config5";
7188 /* Stop translation as we may have switched the execution mode */
7189 ctx->bstate = BS_STOP;
7190 break;
9c2149c8
TS
7191 /* 6,7 are implementation dependent */
7192 default:
7193 rn = "Invalid config selector";
f31b035a 7194 goto cp0_unimplemented;
9c2149c8 7195 }
9c2149c8
TS
7196 break;
7197 case 17:
7198 switch (sel) {
7199 case 0:
895c2d04 7200 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7201 rn = "LLAddr";
7202 break;
9c2149c8 7203 default:
f31b035a 7204 goto cp0_unimplemented;
9c2149c8
TS
7205 }
7206 break;
7207 case 18:
7208 switch (sel) {
fd88b6ab 7209 case 0 ... 7:
895c2d04 7210 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7211 rn = "WatchLo";
7212 break;
9c2149c8 7213 default:
f31b035a 7214 goto cp0_unimplemented;
9c2149c8
TS
7215 }
7216 break;
7217 case 19:
7218 switch (sel) {
fd88b6ab 7219 case 0 ... 7:
895c2d04 7220 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7221 rn = "WatchHi";
7222 break;
9c2149c8 7223 default:
f31b035a 7224 goto cp0_unimplemented;
9c2149c8
TS
7225 }
7226 break;
7227 case 20:
7228 switch (sel) {
7229 case 0:
d75c135e 7230 check_insn(ctx, ISA_MIPS3);
895c2d04 7231 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7232 rn = "XContext";
7233 break;
9c2149c8 7234 default:
f31b035a 7235 goto cp0_unimplemented;
9c2149c8
TS
7236 }
7237 break;
7238 case 21:
7239 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7240 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7241 switch (sel) {
7242 case 0:
895c2d04 7243 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7244 rn = "Framemask";
7245 break;
9c2149c8 7246 default:
f31b035a 7247 goto cp0_unimplemented;
9c2149c8
TS
7248 }
7249 break;
7250 case 22:
7251 /* ignored */
7252 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7253 break;
9c2149c8
TS
7254 case 23:
7255 switch (sel) {
7256 case 0:
895c2d04 7257 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7258 /* BS_STOP isn't good enough here, hflags may have changed. */
7259 gen_save_pc(ctx->pc + 4);
7260 ctx->bstate = BS_EXCP;
2423f660
TS
7261 rn = "Debug";
7262 break;
9c2149c8 7263 case 1:
895c2d04 7264// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7265 /* Stop translation as we may have switched the execution mode */
7266 ctx->bstate = BS_STOP;
2423f660
TS
7267 rn = "TraceControl";
7268// break;
9c2149c8 7269 case 2:
895c2d04 7270// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7271 /* Stop translation as we may have switched the execution mode */
7272 ctx->bstate = BS_STOP;
2423f660
TS
7273 rn = "TraceControl2";
7274// break;
9c2149c8 7275 case 3:
895c2d04 7276// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7277 /* Stop translation as we may have switched the execution mode */
7278 ctx->bstate = BS_STOP;
2423f660
TS
7279 rn = "UserTraceData";
7280// break;
9c2149c8 7281 case 4:
895c2d04 7282// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7283 /* Stop translation as we may have switched the execution mode */
7284 ctx->bstate = BS_STOP;
2423f660
TS
7285 rn = "TraceBPC";
7286// break;
9c2149c8 7287 default:
f31b035a 7288 goto cp0_unimplemented;
9c2149c8 7289 }
9c2149c8
TS
7290 break;
7291 case 24:
7292 switch (sel) {
7293 case 0:
f1aa6320 7294 /* EJTAG support */
7db13fae 7295 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7296 rn = "DEPC";
7297 break;
9c2149c8 7298 default:
f31b035a 7299 goto cp0_unimplemented;
9c2149c8
TS
7300 }
7301 break;
7302 case 25:
7303 switch (sel) {
7304 case 0:
895c2d04 7305 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7306 rn = "Performance0";
7307 break;
9c2149c8 7308 case 1:
895c2d04 7309// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7310 rn = "Performance1";
7311// break;
9c2149c8 7312 case 2:
895c2d04 7313// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7314 rn = "Performance2";
7315// break;
9c2149c8 7316 case 3:
895c2d04 7317// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7318 rn = "Performance3";
7319// break;
9c2149c8 7320 case 4:
895c2d04 7321// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7322 rn = "Performance4";
7323// break;
9c2149c8 7324 case 5:
895c2d04 7325// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7326 rn = "Performance5";
7327// break;
9c2149c8 7328 case 6:
895c2d04 7329// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7330 rn = "Performance6";
7331// break;
9c2149c8 7332 case 7:
895c2d04 7333// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7334 rn = "Performance7";
7335// break;
9c2149c8 7336 default:
f31b035a 7337 goto cp0_unimplemented;
9c2149c8 7338 }
876d4b07 7339 break;
9c2149c8 7340 case 26:
876d4b07 7341 /* ignored */
9c2149c8 7342 rn = "ECC";
876d4b07 7343 break;
9c2149c8
TS
7344 case 27:
7345 switch (sel) {
7346 case 0 ... 3:
2423f660
TS
7347 /* ignored */
7348 rn = "CacheErr";
7349 break;
9c2149c8 7350 default:
f31b035a 7351 goto cp0_unimplemented;
9c2149c8 7352 }
876d4b07 7353 break;
9c2149c8
TS
7354 case 28:
7355 switch (sel) {
7356 case 0:
7357 case 2:
7358 case 4:
7359 case 6:
895c2d04 7360 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7361 rn = "TagLo";
7362 break;
7363 case 1:
7364 case 3:
7365 case 5:
7366 case 7:
895c2d04 7367 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7368 rn = "DataLo";
7369 break;
7370 default:
f31b035a 7371 goto cp0_unimplemented;
9c2149c8
TS
7372 }
7373 break;
7374 case 29:
7375 switch (sel) {
7376 case 0:
7377 case 2:
7378 case 4:
7379 case 6:
895c2d04 7380 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7381 rn = "TagHi";
7382 break;
7383 case 1:
7384 case 3:
7385 case 5:
7386 case 7:
895c2d04 7387 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7388 rn = "DataHi";
7389 break;
7390 default:
7391 rn = "invalid sel";
f31b035a 7392 goto cp0_unimplemented;
9c2149c8 7393 }
876d4b07 7394 break;
9c2149c8
TS
7395 case 30:
7396 switch (sel) {
7397 case 0:
7db13fae 7398 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7399 rn = "ErrorEPC";
7400 break;
9c2149c8 7401 default:
f31b035a 7402 goto cp0_unimplemented;
9c2149c8
TS
7403 }
7404 break;
7405 case 31:
7406 switch (sel) {
7407 case 0:
f1aa6320 7408 /* EJTAG support */
7db13fae 7409 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7410 rn = "DESAVE";
7411 break;
e98c0d17 7412 case 2 ... 7:
f31b035a
LA
7413 CP0_CHECK(ctx->kscrexist & (1 << sel));
7414 tcg_gen_st_tl(arg, cpu_env,
7415 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7416 rn = "KScratch";
e98c0d17 7417 break;
9c2149c8 7418 default:
f31b035a 7419 goto cp0_unimplemented;
9c2149c8 7420 }
876d4b07
TS
7421 /* Stop translation as we may have switched the execution mode */
7422 ctx->bstate = BS_STOP;
9c2149c8
TS
7423 break;
7424 default:
f31b035a 7425 goto cp0_unimplemented;
9c2149c8 7426 }
2abf314d 7427 (void)rn; /* avoid a compiler warning */
d12d51d5 7428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7429 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7430 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7431 gen_io_end();
7432 ctx->bstate = BS_STOP;
7433 }
9c2149c8
TS
7434 return;
7435
f31b035a 7436cp0_unimplemented:
d12d51d5 7437 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7438}
d26bc211 7439#endif /* TARGET_MIPS64 */
9c2149c8 7440
7db13fae 7441static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7442 int u, int sel, int h)
7443{
7444 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7445 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7446
7447 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7448 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7449 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7450 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7451 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7452 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7453 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7454 else if (u == 0) {
7455 switch (rt) {
5a25ce94
EI
7456 case 1:
7457 switch (sel) {
7458 case 1:
895c2d04 7459 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7460 break;
7461 case 2:
895c2d04 7462 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7463 break;
7464 default:
7465 goto die;
7466 break;
7467 }
7468 break;
ead9360e
TS
7469 case 2:
7470 switch (sel) {
7471 case 1:
895c2d04 7472 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7473 break;
7474 case 2:
895c2d04 7475 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7476 break;
7477 case 3:
895c2d04 7478 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7479 break;
7480 case 4:
895c2d04 7481 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7482 break;
7483 case 5:
895c2d04 7484 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7485 break;
7486 case 6:
895c2d04 7487 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7488 break;
7489 case 7:
895c2d04 7490 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7491 break;
7492 default:
d75c135e 7493 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7494 break;
7495 }
7496 break;
7497 case 10:
7498 switch (sel) {
7499 case 0:
895c2d04 7500 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7501 break;
7502 default:
d75c135e 7503 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7504 break;
7505 }
7506 case 12:
7507 switch (sel) {
7508 case 0:
895c2d04 7509 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7510 break;
7511 default:
d75c135e 7512 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7513 break;
7514 }
5a25ce94
EI
7515 case 13:
7516 switch (sel) {
7517 case 0:
895c2d04 7518 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7519 break;
7520 default:
7521 goto die;
7522 break;
7523 }
7524 break;
7525 case 14:
7526 switch (sel) {
7527 case 0:
895c2d04 7528 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7529 break;
7530 default:
7531 goto die;
7532 break;
7533 }
7534 break;
7535 case 15:
7536 switch (sel) {
7537 case 1:
895c2d04 7538 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7539 break;
7540 default:
7541 goto die;
7542 break;
7543 }
7544 break;
7545 case 16:
7546 switch (sel) {
7547 case 0 ... 7:
895c2d04 7548 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7549 break;
7550 default:
7551 goto die;
7552 break;
7553 }
7554 break;
ead9360e
TS
7555 case 23:
7556 switch (sel) {
7557 case 0:
895c2d04 7558 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7559 break;
7560 default:
d75c135e 7561 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7562 break;
7563 }
7564 break;
7565 default:
d75c135e 7566 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7567 }
7568 } else switch (sel) {
7569 /* GPR registers. */
7570 case 0:
895c2d04 7571 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7572 break;
7573 /* Auxiliary CPU registers */
7574 case 1:
7575 switch (rt) {
7576 case 0:
895c2d04 7577 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7578 break;
7579 case 1:
895c2d04 7580 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7581 break;
7582 case 2:
895c2d04 7583 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7584 break;
7585 case 4:
895c2d04 7586 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7587 break;
7588 case 5:
895c2d04 7589 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7590 break;
7591 case 6:
895c2d04 7592 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7593 break;
7594 case 8:
895c2d04 7595 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7596 break;
7597 case 9:
895c2d04 7598 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7599 break;
7600 case 10:
895c2d04 7601 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7602 break;
7603 case 12:
895c2d04 7604 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7605 break;
7606 case 13:
895c2d04 7607 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7608 break;
7609 case 14:
895c2d04 7610 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7611 break;
7612 case 16:
895c2d04 7613 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7614 break;
7615 default:
7616 goto die;
7617 }
7618 break;
7619 /* Floating point (COP1). */
7620 case 2:
7621 /* XXX: For now we support only a single FPU context. */
7622 if (h == 0) {
a7812ae4 7623 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7624
7c979afd 7625 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7626 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7627 tcg_temp_free_i32(fp0);
ead9360e 7628 } else {
a7812ae4 7629 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7630
7f6613ce 7631 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7632 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7633 tcg_temp_free_i32(fp0);
ead9360e
TS
7634 }
7635 break;
7636 case 3:
7637 /* XXX: For now we support only a single FPU context. */
895c2d04 7638 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7639 break;
7640 /* COP2: Not implemented. */
7641 case 4:
7642 case 5:
7643 /* fall through */
7644 default:
7645 goto die;
7646 }
d12d51d5 7647 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7648 gen_store_gpr(t0, rd);
7649 tcg_temp_free(t0);
ead9360e
TS
7650 return;
7651
7652die:
1a3fd9c3 7653 tcg_temp_free(t0);
d12d51d5 7654 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7655 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7656}
7657
7db13fae 7658static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7659 int u, int sel, int h)
7660{
7661 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7662 TCGv t0 = tcg_temp_local_new();
ead9360e 7663
1a3fd9c3 7664 gen_load_gpr(t0, rt);
ead9360e 7665 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7666 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7667 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7668 /* NOP */ ;
7669 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7670 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7671 /* NOP */ ;
7672 else if (u == 0) {
7673 switch (rd) {
5a25ce94
EI
7674 case 1:
7675 switch (sel) {
7676 case 1:
895c2d04 7677 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7678 break;
7679 case 2:
895c2d04 7680 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7681 break;
7682 default:
7683 goto die;
7684 break;
7685 }
7686 break;
ead9360e
TS
7687 case 2:
7688 switch (sel) {
7689 case 1:
895c2d04 7690 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7691 break;
7692 case 2:
895c2d04 7693 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7694 break;
7695 case 3:
895c2d04 7696 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7697 break;
7698 case 4:
895c2d04 7699 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7700 break;
7701 case 5:
895c2d04 7702 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7703 break;
7704 case 6:
895c2d04 7705 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7706 break;
7707 case 7:
895c2d04 7708 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7709 break;
7710 default:
d75c135e 7711 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7712 break;
7713 }
7714 break;
7715 case 10:
7716 switch (sel) {
7717 case 0:
895c2d04 7718 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7719 break;
7720 default:
d75c135e 7721 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7722 break;
7723 }
7724 case 12:
7725 switch (sel) {
7726 case 0:
895c2d04 7727 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7728 break;
7729 default:
d75c135e 7730 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7731 break;
7732 }
5a25ce94
EI
7733 case 13:
7734 switch (sel) {
7735 case 0:
895c2d04 7736 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7737 break;
7738 default:
7739 goto die;
7740 break;
7741 }
7742 break;
7743 case 15:
7744 switch (sel) {
7745 case 1:
895c2d04 7746 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7747 break;
7748 default:
7749 goto die;
7750 break;
7751 }
7752 break;
ead9360e
TS
7753 case 23:
7754 switch (sel) {
7755 case 0:
895c2d04 7756 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7757 break;
7758 default:
d75c135e 7759 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7760 break;
7761 }
7762 break;
7763 default:
d75c135e 7764 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7765 }
7766 } else switch (sel) {
7767 /* GPR registers. */
7768 case 0:
895c2d04 7769 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7770 break;
7771 /* Auxiliary CPU registers */
7772 case 1:
7773 switch (rd) {
7774 case 0:
895c2d04 7775 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7776 break;
7777 case 1:
895c2d04 7778 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7779 break;
7780 case 2:
895c2d04 7781 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7782 break;
7783 case 4:
895c2d04 7784 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7785 break;
7786 case 5:
895c2d04 7787 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7788 break;
7789 case 6:
895c2d04 7790 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7791 break;
7792 case 8:
895c2d04 7793 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7794 break;
7795 case 9:
895c2d04 7796 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7797 break;
7798 case 10:
895c2d04 7799 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7800 break;
7801 case 12:
895c2d04 7802 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7803 break;
7804 case 13:
895c2d04 7805 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7806 break;
7807 case 14:
895c2d04 7808 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7809 break;
7810 case 16:
895c2d04 7811 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7812 break;
7813 default:
7814 goto die;
7815 }
7816 break;
7817 /* Floating point (COP1). */
7818 case 2:
7819 /* XXX: For now we support only a single FPU context. */
7820 if (h == 0) {
a7812ae4 7821 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7822
7823 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7824 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7825 tcg_temp_free_i32(fp0);
ead9360e 7826 } else {
a7812ae4 7827 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7828
7829 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7830 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7831 tcg_temp_free_i32(fp0);
ead9360e
TS
7832 }
7833 break;
7834 case 3:
7835 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7836 {
7837 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7838
7839 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7840 tcg_temp_free_i32(fs_tmp);
7841 }
4cf8a45f
YK
7842 /* Stop translation as we may have changed hflags */
7843 ctx->bstate = BS_STOP;
ead9360e
TS
7844 break;
7845 /* COP2: Not implemented. */
7846 case 4:
7847 case 5:
7848 /* fall through */
7849 default:
7850 goto die;
7851 }
d12d51d5 7852 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7853 tcg_temp_free(t0);
ead9360e
TS
7854 return;
7855
7856die:
1a3fd9c3 7857 tcg_temp_free(t0);
d12d51d5 7858 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 7859 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7860}
7861
7db13fae 7862static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7863{
287c4b84 7864 const char *opn = "ldst";
6af0bf9c 7865
2e15497c 7866 check_cp0_enabled(ctx);
6af0bf9c
FB
7867 switch (opc) {
7868 case OPC_MFC0:
7869 if (rt == 0) {
ead9360e 7870 /* Treat as NOP. */
6af0bf9c
FB
7871 return;
7872 }
d75c135e 7873 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7874 opn = "mfc0";
7875 break;
7876 case OPC_MTC0:
1a3fd9c3 7877 {
1fc7bf6e 7878 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7879
7880 gen_load_gpr(t0, rt);
d75c135e 7881 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7882 tcg_temp_free(t0);
7883 }
6af0bf9c
FB
7884 opn = "mtc0";
7885 break;
d26bc211 7886#if defined(TARGET_MIPS64)
9c2149c8 7887 case OPC_DMFC0:
d75c135e 7888 check_insn(ctx, ISA_MIPS3);
9c2149c8 7889 if (rt == 0) {
ead9360e 7890 /* Treat as NOP. */
9c2149c8
TS
7891 return;
7892 }
d75c135e 7893 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7894 opn = "dmfc0";
7895 break;
7896 case OPC_DMTC0:
d75c135e 7897 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7898 {
1fc7bf6e 7899 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7900
7901 gen_load_gpr(t0, rt);
d75c135e 7902 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7903 tcg_temp_free(t0);
7904 }
9c2149c8
TS
7905 opn = "dmtc0";
7906 break;
534ce69f 7907#endif
5204ea79
LA
7908 case OPC_MFHC0:
7909 check_mvh(ctx);
7910 if (rt == 0) {
7911 /* Treat as NOP. */
7912 return;
7913 }
7914 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7915 opn = "mfhc0";
7916 break;
7917 case OPC_MTHC0:
7918 check_mvh(ctx);
7919 {
7920 TCGv t0 = tcg_temp_new();
7921 gen_load_gpr(t0, rt);
7922 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7923 tcg_temp_free(t0);
7924 }
7925 opn = "mthc0";
7926 break;
ead9360e 7927 case OPC_MFTR:
d75c135e 7928 check_insn(ctx, ASE_MT);
ead9360e
TS
7929 if (rd == 0) {
7930 /* Treat as NOP. */
7931 return;
7932 }
6c5c1e20 7933 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7934 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7935 opn = "mftr";
7936 break;
7937 case OPC_MTTR:
d75c135e 7938 check_insn(ctx, ASE_MT);
6c5c1e20 7939 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7940 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7941 opn = "mttr";
7942 break;
6af0bf9c 7943 case OPC_TLBWI:
6af0bf9c 7944 opn = "tlbwi";
c01fccd2 7945 if (!env->tlb->helper_tlbwi)
29929e34 7946 goto die;
895c2d04 7947 gen_helper_tlbwi(cpu_env);
6af0bf9c 7948 break;
9456c2fb
LA
7949 case OPC_TLBINV:
7950 opn = "tlbinv";
7951 if (ctx->ie >= 2) {
7952 if (!env->tlb->helper_tlbinv) {
7953 goto die;
7954 }
7955 gen_helper_tlbinv(cpu_env);
7956 } /* treat as nop if TLBINV not supported */
7957 break;
7958 case OPC_TLBINVF:
7959 opn = "tlbinvf";
7960 if (ctx->ie >= 2) {
7961 if (!env->tlb->helper_tlbinvf) {
7962 goto die;
7963 }
7964 gen_helper_tlbinvf(cpu_env);
7965 } /* treat as nop if TLBINV not supported */
7966 break;
6af0bf9c 7967 case OPC_TLBWR:
6af0bf9c 7968 opn = "tlbwr";
c01fccd2 7969 if (!env->tlb->helper_tlbwr)
29929e34 7970 goto die;
895c2d04 7971 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7972 break;
7973 case OPC_TLBP:
6af0bf9c 7974 opn = "tlbp";
c01fccd2 7975 if (!env->tlb->helper_tlbp)
29929e34 7976 goto die;
895c2d04 7977 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7978 break;
7979 case OPC_TLBR:
6af0bf9c 7980 opn = "tlbr";
c01fccd2 7981 if (!env->tlb->helper_tlbr)
29929e34 7982 goto die;
895c2d04 7983 gen_helper_tlbr(cpu_env);
6af0bf9c 7984 break;
ce9782f4 7985 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
7986 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7987 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 7988 goto die;
ce9782f4
LA
7989 } else {
7990 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7991 if (ctx->opcode & (1 << bit_shift)) {
7992 /* OPC_ERETNC */
7993 opn = "eretnc";
7994 check_insn(ctx, ISA_MIPS32R5);
7995 gen_helper_eretnc(cpu_env);
7996 } else {
7997 /* OPC_ERET */
7998 opn = "eret";
7999 check_insn(ctx, ISA_MIPS2);
8000 gen_helper_eret(cpu_env);
8001 }
8002 ctx->bstate = BS_EXCP;
339cd2a8 8003 }
6af0bf9c
FB
8004 break;
8005 case OPC_DERET:
8006 opn = "deret";
d75c135e 8007 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8008 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8009 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8010 goto die;
8011 }
6af0bf9c 8012 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8013 MIPS_INVAL(opn);
9c708c7f 8014 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8015 } else {
895c2d04 8016 gen_helper_deret(cpu_env);
6af0bf9c
FB
8017 ctx->bstate = BS_EXCP;
8018 }
8019 break;
4ad40f36
FB
8020 case OPC_WAIT:
8021 opn = "wait";
d75c135e 8022 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8023 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8024 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8025 goto die;
8026 }
4ad40f36
FB
8027 /* If we get an exception, we want to restart at next instruction */
8028 ctx->pc += 4;
8029 save_cpu_state(ctx, 1);
8030 ctx->pc -= 4;
895c2d04 8031 gen_helper_wait(cpu_env);
4ad40f36
FB
8032 ctx->bstate = BS_EXCP;
8033 break;
6af0bf9c 8034 default:
29929e34 8035 die:
923617a3 8036 MIPS_INVAL(opn);
9c708c7f 8037 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8038 return;
8039 }
2abf314d 8040 (void)opn; /* avoid a compiler warning */
6af0bf9c 8041}
f1aa6320 8042#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8043
6ea83fed 8044/* CP1 Branches (before delay slot) */
d75c135e
AJ
8045static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8046 int32_t cc, int32_t offset)
6ea83fed
FB
8047{
8048 target_ulong btarget;
a7812ae4 8049 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8050
339cd2a8 8051 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8052 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8053 goto out;
8054 }
8055
e189e748 8056 if (cc != 0)
d75c135e 8057 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8058
6ea83fed
FB
8059 btarget = ctx->pc + 4 + offset;
8060
7a387fff
TS
8061 switch (op) {
8062 case OPC_BC1F:
d94536f4
AJ
8063 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8064 tcg_gen_not_i32(t0, t0);
8065 tcg_gen_andi_i32(t0, t0, 1);
8066 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8067 goto not_likely;
7a387fff 8068 case OPC_BC1FL:
d94536f4
AJ
8069 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8070 tcg_gen_not_i32(t0, t0);
8071 tcg_gen_andi_i32(t0, t0, 1);
8072 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8073 goto likely;
7a387fff 8074 case OPC_BC1T:
d94536f4
AJ
8075 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8076 tcg_gen_andi_i32(t0, t0, 1);
8077 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8078 goto not_likely;
7a387fff 8079 case OPC_BC1TL:
d94536f4
AJ
8080 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8081 tcg_gen_andi_i32(t0, t0, 1);
8082 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8083 likely:
8084 ctx->hflags |= MIPS_HFLAG_BL;
8085 break;
5a5012ec 8086 case OPC_BC1FANY2:
a16336e4 8087 {
d94536f4
AJ
8088 TCGv_i32 t1 = tcg_temp_new_i32();
8089 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8091 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8092 tcg_temp_free_i32(t1);
d94536f4
AJ
8093 tcg_gen_andi_i32(t0, t0, 1);
8094 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8095 }
5a5012ec
TS
8096 goto not_likely;
8097 case OPC_BC1TANY2:
a16336e4 8098 {
d94536f4
AJ
8099 TCGv_i32 t1 = tcg_temp_new_i32();
8100 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8102 tcg_gen_or_i32(t0, t0, t1);
8103 tcg_temp_free_i32(t1);
8104 tcg_gen_andi_i32(t0, t0, 1);
8105 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8106 }
5a5012ec
TS
8107 goto not_likely;
8108 case OPC_BC1FANY4:
a16336e4 8109 {
d94536f4
AJ
8110 TCGv_i32 t1 = tcg_temp_new_i32();
8111 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8112 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8113 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8114 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8115 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8116 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8117 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8118 tcg_temp_free_i32(t1);
d94536f4
AJ
8119 tcg_gen_andi_i32(t0, t0, 1);
8120 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8121 }
5a5012ec
TS
8122 goto not_likely;
8123 case OPC_BC1TANY4:
a16336e4 8124 {
d94536f4
AJ
8125 TCGv_i32 t1 = tcg_temp_new_i32();
8126 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8127 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8128 tcg_gen_or_i32(t0, t0, t1);
8129 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8130 tcg_gen_or_i32(t0, t0, t1);
8131 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8132 tcg_gen_or_i32(t0, t0, t1);
8133 tcg_temp_free_i32(t1);
8134 tcg_gen_andi_i32(t0, t0, 1);
8135 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8136 }
5a5012ec
TS
8137 not_likely:
8138 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8139 break;
8140 default:
9d68ac14 8141 MIPS_INVAL("cp1 cond branch");
9c708c7f 8142 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8143 goto out;
6ea83fed 8144 }
6ea83fed 8145 ctx->btarget = btarget;
b231c103 8146 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8147 out:
a7812ae4 8148 tcg_temp_free_i32(t0);
6ea83fed
FB
8149}
8150
31837be3
YK
8151/* R6 CP1 Branches */
8152static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8153 int32_t ft, int32_t offset,
8154 int delayslot_size)
31837be3
YK
8155{
8156 target_ulong btarget;
31837be3
YK
8157 TCGv_i64 t0 = tcg_temp_new_i64();
8158
8159 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8160#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8161 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8162 "\n", ctx->pc);
31837be3 8163#endif
9c708c7f 8164 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8165 goto out;
8166 }
8167
8168 gen_load_fpr64(ctx, t0, ft);
8169 tcg_gen_andi_i64(t0, t0, 1);
8170
8171 btarget = addr_add(ctx, ctx->pc + 4, offset);
8172
8173 switch (op) {
8174 case OPC_BC1EQZ:
8175 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8176 ctx->hflags |= MIPS_HFLAG_BC;
8177 break;
8178 case OPC_BC1NEZ:
8179 /* t0 already set */
31837be3
YK
8180 ctx->hflags |= MIPS_HFLAG_BC;
8181 break;
8182 default:
9d68ac14 8183 MIPS_INVAL("cp1 cond branch");
9c708c7f 8184 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8185 goto out;
8186 }
8187
8188 tcg_gen_trunc_i64_tl(bcond, t0);
8189
31837be3 8190 ctx->btarget = btarget;
65935f07
YK
8191
8192 switch (delayslot_size) {
8193 case 2:
8194 ctx->hflags |= MIPS_HFLAG_BDS16;
8195 break;
8196 case 4:
8197 ctx->hflags |= MIPS_HFLAG_BDS32;
8198 break;
8199 }
31837be3
YK
8200
8201out:
8202 tcg_temp_free_i64(t0);
8203}
8204
6af0bf9c 8205/* Coprocessor 1 (FPU) */
5a5012ec 8206
5a5012ec
TS
8207#define FOP(func, fmt) (((fmt) << 21) | (func))
8208
bf4120ad
NF
8209enum fopcode {
8210 OPC_ADD_S = FOP(0, FMT_S),
8211 OPC_SUB_S = FOP(1, FMT_S),
8212 OPC_MUL_S = FOP(2, FMT_S),
8213 OPC_DIV_S = FOP(3, FMT_S),
8214 OPC_SQRT_S = FOP(4, FMT_S),
8215 OPC_ABS_S = FOP(5, FMT_S),
8216 OPC_MOV_S = FOP(6, FMT_S),
8217 OPC_NEG_S = FOP(7, FMT_S),
8218 OPC_ROUND_L_S = FOP(8, FMT_S),
8219 OPC_TRUNC_L_S = FOP(9, FMT_S),
8220 OPC_CEIL_L_S = FOP(10, FMT_S),
8221 OPC_FLOOR_L_S = FOP(11, FMT_S),
8222 OPC_ROUND_W_S = FOP(12, FMT_S),
8223 OPC_TRUNC_W_S = FOP(13, FMT_S),
8224 OPC_CEIL_W_S = FOP(14, FMT_S),
8225 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8226 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8227 OPC_MOVCF_S = FOP(17, FMT_S),
8228 OPC_MOVZ_S = FOP(18, FMT_S),
8229 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8230 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8231 OPC_RECIP_S = FOP(21, FMT_S),
8232 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8233 OPC_SELNEZ_S = FOP(23, FMT_S),
8234 OPC_MADDF_S = FOP(24, FMT_S),
8235 OPC_MSUBF_S = FOP(25, FMT_S),
8236 OPC_RINT_S = FOP(26, FMT_S),
8237 OPC_CLASS_S = FOP(27, FMT_S),
8238 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8239 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8240 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8241 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8242 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8243 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8244 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8245 OPC_RSQRT2_S = FOP(31, FMT_S),
8246 OPC_CVT_D_S = FOP(33, FMT_S),
8247 OPC_CVT_W_S = FOP(36, FMT_S),
8248 OPC_CVT_L_S = FOP(37, FMT_S),
8249 OPC_CVT_PS_S = FOP(38, FMT_S),
8250 OPC_CMP_F_S = FOP (48, FMT_S),
8251 OPC_CMP_UN_S = FOP (49, FMT_S),
8252 OPC_CMP_EQ_S = FOP (50, FMT_S),
8253 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8254 OPC_CMP_OLT_S = FOP (52, FMT_S),
8255 OPC_CMP_ULT_S = FOP (53, FMT_S),
8256 OPC_CMP_OLE_S = FOP (54, FMT_S),
8257 OPC_CMP_ULE_S = FOP (55, FMT_S),
8258 OPC_CMP_SF_S = FOP (56, FMT_S),
8259 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8260 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8261 OPC_CMP_NGL_S = FOP (59, FMT_S),
8262 OPC_CMP_LT_S = FOP (60, FMT_S),
8263 OPC_CMP_NGE_S = FOP (61, FMT_S),
8264 OPC_CMP_LE_S = FOP (62, FMT_S),
8265 OPC_CMP_NGT_S = FOP (63, FMT_S),
8266
8267 OPC_ADD_D = FOP(0, FMT_D),
8268 OPC_SUB_D = FOP(1, FMT_D),
8269 OPC_MUL_D = FOP(2, FMT_D),
8270 OPC_DIV_D = FOP(3, FMT_D),
8271 OPC_SQRT_D = FOP(4, FMT_D),
8272 OPC_ABS_D = FOP(5, FMT_D),
8273 OPC_MOV_D = FOP(6, FMT_D),
8274 OPC_NEG_D = FOP(7, FMT_D),
8275 OPC_ROUND_L_D = FOP(8, FMT_D),
8276 OPC_TRUNC_L_D = FOP(9, FMT_D),
8277 OPC_CEIL_L_D = FOP(10, FMT_D),
8278 OPC_FLOOR_L_D = FOP(11, FMT_D),
8279 OPC_ROUND_W_D = FOP(12, FMT_D),
8280 OPC_TRUNC_W_D = FOP(13, FMT_D),
8281 OPC_CEIL_W_D = FOP(14, FMT_D),
8282 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8283 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8284 OPC_MOVCF_D = FOP(17, FMT_D),
8285 OPC_MOVZ_D = FOP(18, FMT_D),
8286 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8287 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8288 OPC_RECIP_D = FOP(21, FMT_D),
8289 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8290 OPC_SELNEZ_D = FOP(23, FMT_D),
8291 OPC_MADDF_D = FOP(24, FMT_D),
8292 OPC_MSUBF_D = FOP(25, FMT_D),
8293 OPC_RINT_D = FOP(26, FMT_D),
8294 OPC_CLASS_D = FOP(27, FMT_D),
8295 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8296 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8297 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8298 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8299 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8300 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8301 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8302 OPC_RSQRT2_D = FOP(31, FMT_D),
8303 OPC_CVT_S_D = FOP(32, FMT_D),
8304 OPC_CVT_W_D = FOP(36, FMT_D),
8305 OPC_CVT_L_D = FOP(37, FMT_D),
8306 OPC_CMP_F_D = FOP (48, FMT_D),
8307 OPC_CMP_UN_D = FOP (49, FMT_D),
8308 OPC_CMP_EQ_D = FOP (50, FMT_D),
8309 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8310 OPC_CMP_OLT_D = FOP (52, FMT_D),
8311 OPC_CMP_ULT_D = FOP (53, FMT_D),
8312 OPC_CMP_OLE_D = FOP (54, FMT_D),
8313 OPC_CMP_ULE_D = FOP (55, FMT_D),
8314 OPC_CMP_SF_D = FOP (56, FMT_D),
8315 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8316 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8317 OPC_CMP_NGL_D = FOP (59, FMT_D),
8318 OPC_CMP_LT_D = FOP (60, FMT_D),
8319 OPC_CMP_NGE_D = FOP (61, FMT_D),
8320 OPC_CMP_LE_D = FOP (62, FMT_D),
8321 OPC_CMP_NGT_D = FOP (63, FMT_D),
8322
8323 OPC_CVT_S_W = FOP(32, FMT_W),
8324 OPC_CVT_D_W = FOP(33, FMT_W),
8325 OPC_CVT_S_L = FOP(32, FMT_L),
8326 OPC_CVT_D_L = FOP(33, FMT_L),
8327 OPC_CVT_PS_PW = FOP(38, FMT_W),
8328
8329 OPC_ADD_PS = FOP(0, FMT_PS),
8330 OPC_SUB_PS = FOP(1, FMT_PS),
8331 OPC_MUL_PS = FOP(2, FMT_PS),
8332 OPC_DIV_PS = FOP(3, FMT_PS),
8333 OPC_ABS_PS = FOP(5, FMT_PS),
8334 OPC_MOV_PS = FOP(6, FMT_PS),
8335 OPC_NEG_PS = FOP(7, FMT_PS),
8336 OPC_MOVCF_PS = FOP(17, FMT_PS),
8337 OPC_MOVZ_PS = FOP(18, FMT_PS),
8338 OPC_MOVN_PS = FOP(19, FMT_PS),
8339 OPC_ADDR_PS = FOP(24, FMT_PS),
8340 OPC_MULR_PS = FOP(26, FMT_PS),
8341 OPC_RECIP2_PS = FOP(28, FMT_PS),
8342 OPC_RECIP1_PS = FOP(29, FMT_PS),
8343 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8344 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8345
8346 OPC_CVT_S_PU = FOP(32, FMT_PS),
8347 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8348 OPC_CVT_S_PL = FOP(40, FMT_PS),
8349 OPC_PLL_PS = FOP(44, FMT_PS),
8350 OPC_PLU_PS = FOP(45, FMT_PS),
8351 OPC_PUL_PS = FOP(46, FMT_PS),
8352 OPC_PUU_PS = FOP(47, FMT_PS),
8353 OPC_CMP_F_PS = FOP (48, FMT_PS),
8354 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8355 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8356 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8357 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8358 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8359 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8360 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8361 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8362 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8363 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8364 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8365 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8366 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8367 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8368 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8369};
8370
3f493883
YK
8371enum r6_f_cmp_op {
8372 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8373 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8374 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8375 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8376 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8377 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8378 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8379 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8380 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8381 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8382 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8383 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8384 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8385 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8386 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8387 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8388 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8389 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8390 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8391 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8392 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8393 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8394
8395 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8396 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8397 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8398 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8399 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8400 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8401 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8402 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8403 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8404 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8405 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8406 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8407 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8408 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8409 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8410 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8411 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8412 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8413 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8414 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8415 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8416 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8417};
7a387fff 8418static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8419{
72c3a3ee 8420 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8421
8422 switch (opc) {
8423 case OPC_MFC1:
b6d96bed 8424 {
a7812ae4 8425 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8426
7c979afd 8427 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8428 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8429 tcg_temp_free_i32(fp0);
6958549d 8430 }
6c5c1e20 8431 gen_store_gpr(t0, rt);
6ea83fed
FB
8432 break;
8433 case OPC_MTC1:
6c5c1e20 8434 gen_load_gpr(t0, rt);
b6d96bed 8435 {
a7812ae4 8436 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8437
8438 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8439 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8440 tcg_temp_free_i32(fp0);
6958549d 8441 }
6ea83fed
FB
8442 break;
8443 case OPC_CFC1:
895c2d04 8444 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8445 gen_store_gpr(t0, rt);
6ea83fed
FB
8446 break;
8447 case OPC_CTC1:
6c5c1e20 8448 gen_load_gpr(t0, rt);
9c708c7f 8449 save_cpu_state(ctx, 0);
736d120a
PJ
8450 {
8451 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8452
8453 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8454 tcg_temp_free_i32(fs_tmp);
8455 }
4cf8a45f
YK
8456 /* Stop translation as we may have changed hflags */
8457 ctx->bstate = BS_STOP;
6ea83fed 8458 break;
72c3a3ee 8459#if defined(TARGET_MIPS64)
9c2149c8 8460 case OPC_DMFC1:
72c3a3ee 8461 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8462 gen_store_gpr(t0, rt);
5a5012ec 8463 break;
9c2149c8 8464 case OPC_DMTC1:
6c5c1e20 8465 gen_load_gpr(t0, rt);
72c3a3ee 8466 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8467 break;
72c3a3ee 8468#endif
5a5012ec 8469 case OPC_MFHC1:
b6d96bed 8470 {
a7812ae4 8471 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8472
7f6613ce 8473 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8474 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8475 tcg_temp_free_i32(fp0);
6958549d 8476 }
6c5c1e20 8477 gen_store_gpr(t0, rt);
5a5012ec
TS
8478 break;
8479 case OPC_MTHC1:
6c5c1e20 8480 gen_load_gpr(t0, rt);
b6d96bed 8481 {
a7812ae4 8482 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8483
8484 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8485 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8486 tcg_temp_free_i32(fp0);
6958549d 8487 }
5a5012ec 8488 break;
6ea83fed 8489 default:
9d68ac14 8490 MIPS_INVAL("cp1 move");
9c708c7f 8491 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8492 goto out;
6ea83fed 8493 }
6c5c1e20
TS
8494
8495 out:
8496 tcg_temp_free(t0);
6ea83fed
FB
8497}
8498
5a5012ec
TS
8499static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8500{
42a268c2 8501 TCGLabel *l1;
e214b9bb 8502 TCGCond cond;
af58f9ca
AJ
8503 TCGv_i32 t0;
8504
8505 if (rd == 0) {
8506 /* Treat as NOP. */
8507 return;
8508 }
6ea83fed 8509
e214b9bb 8510 if (tf)
e214b9bb 8511 cond = TCG_COND_EQ;
27848470
TS
8512 else
8513 cond = TCG_COND_NE;
8514
af58f9ca
AJ
8515 l1 = gen_new_label();
8516 t0 = tcg_temp_new_i32();
fa31af0e 8517 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8518 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8519 tcg_temp_free_i32(t0);
af58f9ca
AJ
8520 if (rs == 0) {
8521 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8522 } else {
8523 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8524 }
e214b9bb 8525 gen_set_label(l1);
5a5012ec
TS
8526}
8527
7c979afd
LA
8528static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8529 int tf)
a16336e4 8530{
a16336e4 8531 int cond;
cbc37b28 8532 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8533 TCGLabel *l1 = gen_new_label();
a16336e4 8534
a16336e4
TS
8535 if (tf)
8536 cond = TCG_COND_EQ;
8537 else
8538 cond = TCG_COND_NE;
8539
fa31af0e 8540 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8541 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8542 gen_load_fpr32(ctx, t0, fs);
8543 gen_store_fpr32(ctx, t0, fd);
a16336e4 8544 gen_set_label(l1);
cbc37b28 8545 tcg_temp_free_i32(t0);
5a5012ec 8546}
a16336e4 8547
b6d96bed 8548static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8549{
a16336e4 8550 int cond;
cbc37b28
AJ
8551 TCGv_i32 t0 = tcg_temp_new_i32();
8552 TCGv_i64 fp0;
42a268c2 8553 TCGLabel *l1 = gen_new_label();
a16336e4 8554
a16336e4
TS
8555 if (tf)
8556 cond = TCG_COND_EQ;
8557 else
8558 cond = TCG_COND_NE;
8559
fa31af0e 8560 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8561 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8562 tcg_temp_free_i32(t0);
11f94258 8563 fp0 = tcg_temp_new_i64();
9bf3eb2c 8564 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8565 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8566 tcg_temp_free_i64(fp0);
cbc37b28 8567 gen_set_label(l1);
a16336e4
TS
8568}
8569
7f6613ce
PJ
8570static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8571 int cc, int tf)
a16336e4
TS
8572{
8573 int cond;
cbc37b28 8574 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8575 TCGLabel *l1 = gen_new_label();
8576 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8577
8578 if (tf)
8579 cond = TCG_COND_EQ;
8580 else
8581 cond = TCG_COND_NE;
8582
fa31af0e 8583 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8584 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8585 gen_load_fpr32(ctx, t0, fs);
8586 gen_store_fpr32(ctx, t0, fd);
a16336e4 8587 gen_set_label(l1);
9bf3eb2c 8588
fa31af0e 8589 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8590 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8591 gen_load_fpr32h(ctx, t0, fs);
8592 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8593 tcg_temp_free_i32(t0);
a16336e4 8594 gen_set_label(l2);
a16336e4
TS
8595}
8596
e7f16abb
LA
8597static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8598 int fs)
8599{
8600 TCGv_i32 t1 = tcg_const_i32(0);
8601 TCGv_i32 fp0 = tcg_temp_new_i32();
8602 TCGv_i32 fp1 = tcg_temp_new_i32();
8603 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8604 gen_load_fpr32(ctx, fp0, fd);
8605 gen_load_fpr32(ctx, fp1, ft);
8606 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8607
8608 switch (op1) {
8609 case OPC_SEL_S:
8610 tcg_gen_andi_i32(fp0, fp0, 1);
8611 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8612 break;
8613 case OPC_SELEQZ_S:
8614 tcg_gen_andi_i32(fp1, fp1, 1);
8615 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8616 break;
8617 case OPC_SELNEZ_S:
8618 tcg_gen_andi_i32(fp1, fp1, 1);
8619 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8620 break;
8621 default:
8622 MIPS_INVAL("gen_sel_s");
9c708c7f 8623 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8624 break;
8625 }
8626
7c979afd 8627 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8628 tcg_temp_free_i32(fp2);
8629 tcg_temp_free_i32(fp1);
8630 tcg_temp_free_i32(fp0);
8631 tcg_temp_free_i32(t1);
8632}
8633
8634static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8635 int fs)
8636{
8637 TCGv_i64 t1 = tcg_const_i64(0);
8638 TCGv_i64 fp0 = tcg_temp_new_i64();
8639 TCGv_i64 fp1 = tcg_temp_new_i64();
8640 TCGv_i64 fp2 = tcg_temp_new_i64();
8641 gen_load_fpr64(ctx, fp0, fd);
8642 gen_load_fpr64(ctx, fp1, ft);
8643 gen_load_fpr64(ctx, fp2, fs);
8644
8645 switch (op1) {
8646 case OPC_SEL_D:
8647 tcg_gen_andi_i64(fp0, fp0, 1);
8648 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8649 break;
8650 case OPC_SELEQZ_D:
8651 tcg_gen_andi_i64(fp1, fp1, 1);
8652 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8653 break;
8654 case OPC_SELNEZ_D:
8655 tcg_gen_andi_i64(fp1, fp1, 1);
8656 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8657 break;
8658 default:
8659 MIPS_INVAL("gen_sel_d");
9c708c7f 8660 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8661 break;
8662 }
8663
8664 gen_store_fpr64(ctx, fp0, fd);
8665 tcg_temp_free_i64(fp2);
8666 tcg_temp_free_i64(fp1);
8667 tcg_temp_free_i64(fp0);
8668 tcg_temp_free_i64(t1);
8669}
6ea83fed 8670
bf4120ad 8671static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8672 int ft, int fs, int fd, int cc)
6ea83fed 8673{
7a387fff 8674 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8675 switch (op1) {
8676 case OPC_ADD_S:
b6d96bed 8677 {
a7812ae4
PB
8678 TCGv_i32 fp0 = tcg_temp_new_i32();
8679 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8680
7c979afd
LA
8681 gen_load_fpr32(ctx, fp0, fs);
8682 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8683 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8684 tcg_temp_free_i32(fp1);
7c979afd 8685 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8686 tcg_temp_free_i32(fp0);
b6d96bed 8687 }
5a5012ec 8688 break;
bf4120ad 8689 case OPC_SUB_S:
b6d96bed 8690 {
a7812ae4
PB
8691 TCGv_i32 fp0 = tcg_temp_new_i32();
8692 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8693
7c979afd
LA
8694 gen_load_fpr32(ctx, fp0, fs);
8695 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8696 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8697 tcg_temp_free_i32(fp1);
7c979afd 8698 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8699 tcg_temp_free_i32(fp0);
b6d96bed 8700 }
5a5012ec 8701 break;
bf4120ad 8702 case OPC_MUL_S:
b6d96bed 8703 {
a7812ae4
PB
8704 TCGv_i32 fp0 = tcg_temp_new_i32();
8705 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8706
7c979afd
LA
8707 gen_load_fpr32(ctx, fp0, fs);
8708 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8709 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8710 tcg_temp_free_i32(fp1);
7c979afd 8711 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8712 tcg_temp_free_i32(fp0);
b6d96bed 8713 }
5a5012ec 8714 break;
bf4120ad 8715 case OPC_DIV_S:
b6d96bed 8716 {
a7812ae4
PB
8717 TCGv_i32 fp0 = tcg_temp_new_i32();
8718 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8719
7c979afd
LA
8720 gen_load_fpr32(ctx, fp0, fs);
8721 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8722 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8723 tcg_temp_free_i32(fp1);
7c979afd 8724 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8725 tcg_temp_free_i32(fp0);
b6d96bed 8726 }
5a5012ec 8727 break;
bf4120ad 8728 case OPC_SQRT_S:
b6d96bed 8729 {
a7812ae4 8730 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8731
7c979afd 8732 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8733 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8734 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8735 tcg_temp_free_i32(fp0);
b6d96bed 8736 }
5a5012ec 8737 break;
bf4120ad 8738 case OPC_ABS_S:
b6d96bed 8739 {
a7812ae4 8740 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8741
7c979afd 8742 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8743 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8744 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8745 tcg_temp_free_i32(fp0);
b6d96bed 8746 }
5a5012ec 8747 break;
bf4120ad 8748 case OPC_MOV_S:
b6d96bed 8749 {
a7812ae4 8750 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8751
7c979afd
LA
8752 gen_load_fpr32(ctx, fp0, fs);
8753 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8754 tcg_temp_free_i32(fp0);
b6d96bed 8755 }
5a5012ec 8756 break;
bf4120ad 8757 case OPC_NEG_S:
b6d96bed 8758 {
a7812ae4 8759 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8760
7c979afd 8761 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8762 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8763 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8764 tcg_temp_free_i32(fp0);
b6d96bed 8765 }
5a5012ec 8766 break;
bf4120ad 8767 case OPC_ROUND_L_S:
5e755519 8768 check_cp1_64bitmode(ctx);
b6d96bed 8769 {
a7812ae4
PB
8770 TCGv_i32 fp32 = tcg_temp_new_i32();
8771 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8772
7c979afd 8773 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8774 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8775 tcg_temp_free_i32(fp32);
b6d96bed 8776 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8777 tcg_temp_free_i64(fp64);
b6d96bed 8778 }
5a5012ec 8779 break;
bf4120ad 8780 case OPC_TRUNC_L_S:
5e755519 8781 check_cp1_64bitmode(ctx);
b6d96bed 8782 {
a7812ae4
PB
8783 TCGv_i32 fp32 = tcg_temp_new_i32();
8784 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8785
7c979afd 8786 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8787 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8788 tcg_temp_free_i32(fp32);
b6d96bed 8789 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8790 tcg_temp_free_i64(fp64);
b6d96bed 8791 }
5a5012ec 8792 break;
bf4120ad 8793 case OPC_CEIL_L_S:
5e755519 8794 check_cp1_64bitmode(ctx);
b6d96bed 8795 {
a7812ae4
PB
8796 TCGv_i32 fp32 = tcg_temp_new_i32();
8797 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8798
7c979afd 8799 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8800 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8801 tcg_temp_free_i32(fp32);
b6d96bed 8802 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8803 tcg_temp_free_i64(fp64);
b6d96bed 8804 }
5a5012ec 8805 break;
bf4120ad 8806 case OPC_FLOOR_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_floorl_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 8818 break;
bf4120ad 8819 case OPC_ROUND_W_S:
b6d96bed 8820 {
a7812ae4 8821 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8822
7c979afd 8823 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8824 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8825 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8826 tcg_temp_free_i32(fp0);
b6d96bed 8827 }
5a5012ec 8828 break;
bf4120ad 8829 case OPC_TRUNC_W_S:
b6d96bed 8830 {
a7812ae4 8831 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8832
7c979afd 8833 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8834 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8835 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8836 tcg_temp_free_i32(fp0);
b6d96bed 8837 }
5a5012ec 8838 break;
bf4120ad 8839 case OPC_CEIL_W_S:
b6d96bed 8840 {
a7812ae4 8841 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8842
7c979afd 8843 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8844 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8845 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8846 tcg_temp_free_i32(fp0);
b6d96bed 8847 }
5a5012ec 8848 break;
bf4120ad 8849 case OPC_FLOOR_W_S:
b6d96bed 8850 {
a7812ae4 8851 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8852
7c979afd 8853 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8854 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8855 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8856 tcg_temp_free_i32(fp0);
b6d96bed 8857 }
5a5012ec 8858 break;
e7f16abb
LA
8859 case OPC_SEL_S:
8860 check_insn(ctx, ISA_MIPS32R6);
8861 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8862 break;
8863 case OPC_SELEQZ_S:
8864 check_insn(ctx, ISA_MIPS32R6);
8865 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8866 break;
8867 case OPC_SELNEZ_S:
8868 check_insn(ctx, ISA_MIPS32R6);
8869 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 8870 break;
bf4120ad 8871 case OPC_MOVCF_S:
fecd2646 8872 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8873 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8874 break;
bf4120ad 8875 case OPC_MOVZ_S:
fecd2646 8876 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8877 {
42a268c2 8878 TCGLabel *l1 = gen_new_label();
c9297f4d 8879 TCGv_i32 fp0;
a16336e4 8880
c9297f4d
AJ
8881 if (ft != 0) {
8882 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8883 }
8884 fp0 = tcg_temp_new_i32();
7c979afd
LA
8885 gen_load_fpr32(ctx, fp0, fs);
8886 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8887 tcg_temp_free_i32(fp0);
a16336e4
TS
8888 gen_set_label(l1);
8889 }
5a5012ec 8890 break;
bf4120ad 8891 case OPC_MOVN_S:
fecd2646 8892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8893 {
42a268c2 8894 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8895 TCGv_i32 fp0;
8896
8897 if (ft != 0) {
8898 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8899 fp0 = tcg_temp_new_i32();
7c979afd
LA
8900 gen_load_fpr32(ctx, fp0, fs);
8901 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8902 tcg_temp_free_i32(fp0);
8903 gen_set_label(l1);
8904 }
a16336e4 8905 }
5a5012ec 8906 break;
bf4120ad 8907 case OPC_RECIP_S:
b6d96bed 8908 {
a7812ae4 8909 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8910
7c979afd 8911 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8912 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8913 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8914 tcg_temp_free_i32(fp0);
b6d96bed 8915 }
57fa1fb3 8916 break;
bf4120ad 8917 case OPC_RSQRT_S:
b6d96bed 8918 {
a7812ae4 8919 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8920
7c979afd 8921 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8922 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8923 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8924 tcg_temp_free_i32(fp0);
b6d96bed 8925 }
57fa1fb3 8926 break;
e7f16abb
LA
8927 case OPC_MADDF_S:
8928 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8929 {
a7812ae4
PB
8930 TCGv_i32 fp0 = tcg_temp_new_i32();
8931 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8932 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8933 gen_load_fpr32(ctx, fp0, fs);
8934 gen_load_fpr32(ctx, fp1, ft);
8935 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8936 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8937 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 8938 tcg_temp_free_i32(fp2);
a7812ae4 8939 tcg_temp_free_i32(fp1);
a7812ae4 8940 tcg_temp_free_i32(fp0);
b6d96bed 8941 }
57fa1fb3 8942 break;
e7f16abb
LA
8943 case OPC_MSUBF_S:
8944 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8945 {
a7812ae4 8946 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8947 TCGv_i32 fp1 = tcg_temp_new_i32();
8948 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8949 gen_load_fpr32(ctx, fp0, fs);
8950 gen_load_fpr32(ctx, fp1, ft);
8951 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8952 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8953 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8954 tcg_temp_free_i32(fp2);
8955 tcg_temp_free_i32(fp1);
a7812ae4 8956 tcg_temp_free_i32(fp0);
b6d96bed 8957 }
57fa1fb3 8958 break;
e7f16abb
LA
8959 case OPC_RINT_S:
8960 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8961 {
a7812ae4 8962 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8963 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8964 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 8965 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8966 tcg_temp_free_i32(fp0);
b6d96bed 8967 }
57fa1fb3 8968 break;
e7f16abb
LA
8969 case OPC_CLASS_S:
8970 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8971 {
e7f16abb 8972 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8973 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8974 gen_helper_float_class_s(fp0, fp0);
7c979afd 8975 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 8976 tcg_temp_free_i32(fp0);
e7f16abb
LA
8977 }
8978 break;
8979 case OPC_MIN_S: /* OPC_RECIP2_S */
8980 if (ctx->insn_flags & ISA_MIPS32R6) {
8981 /* OPC_MIN_S */
a7812ae4
PB
8982 TCGv_i32 fp0 = tcg_temp_new_i32();
8983 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8984 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8985 gen_load_fpr32(ctx, fp0, fs);
8986 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 8987 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 8988 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8989 tcg_temp_free_i32(fp2);
8990 tcg_temp_free_i32(fp1);
8991 tcg_temp_free_i32(fp0);
e7f16abb
LA
8992 } else {
8993 /* OPC_RECIP2_S */
8994 check_cp1_64bitmode(ctx);
8995 {
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8998
7c979afd
LA
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9001 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9002 tcg_temp_free_i32(fp1);
7c979afd 9003 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9004 tcg_temp_free_i32(fp0);
9005 }
e7f16abb
LA
9006 }
9007 break;
9008 case OPC_MINA_S: /* OPC_RECIP1_S */
9009 if (ctx->insn_flags & ISA_MIPS32R6) {
9010 /* OPC_MINA_S */
9011 TCGv_i32 fp0 = tcg_temp_new_i32();
9012 TCGv_i32 fp1 = tcg_temp_new_i32();
9013 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9014 gen_load_fpr32(ctx, fp0, fs);
9015 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9016 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9017 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9018 tcg_temp_free_i32(fp2);
9019 tcg_temp_free_i32(fp1);
9020 tcg_temp_free_i32(fp0);
e7f16abb
LA
9021 } else {
9022 /* OPC_RECIP1_S */
9023 check_cp1_64bitmode(ctx);
9024 {
9025 TCGv_i32 fp0 = tcg_temp_new_i32();
9026
7c979afd 9027 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9028 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9029 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9030 tcg_temp_free_i32(fp0);
9031 }
e7f16abb
LA
9032 }
9033 break;
9034 case OPC_MAX_S: /* OPC_RSQRT1_S */
9035 if (ctx->insn_flags & ISA_MIPS32R6) {
9036 /* OPC_MAX_S */
9037 TCGv_i32 fp0 = tcg_temp_new_i32();
9038 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9039 gen_load_fpr32(ctx, fp0, fs);
9040 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9041 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9042 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9043 tcg_temp_free_i32(fp1);
9044 tcg_temp_free_i32(fp0);
e7f16abb
LA
9045 } else {
9046 /* OPC_RSQRT1_S */
9047 check_cp1_64bitmode(ctx);
9048 {
9049 TCGv_i32 fp0 = tcg_temp_new_i32();
9050
7c979afd 9051 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9052 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9053 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9054 tcg_temp_free_i32(fp0);
9055 }
e7f16abb
LA
9056 }
9057 break;
9058 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9059 if (ctx->insn_flags & ISA_MIPS32R6) {
9060 /* OPC_MAXA_S */
9061 TCGv_i32 fp0 = tcg_temp_new_i32();
9062 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9063 gen_load_fpr32(ctx, fp0, fs);
9064 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9065 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9066 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9067 tcg_temp_free_i32(fp1);
a7812ae4 9068 tcg_temp_free_i32(fp0);
e7f16abb
LA
9069 } else {
9070 /* OPC_RSQRT2_S */
9071 check_cp1_64bitmode(ctx);
9072 {
9073 TCGv_i32 fp0 = tcg_temp_new_i32();
9074 TCGv_i32 fp1 = tcg_temp_new_i32();
9075
7c979afd
LA
9076 gen_load_fpr32(ctx, fp0, fs);
9077 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9078 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9079 tcg_temp_free_i32(fp1);
7c979afd 9080 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9081 tcg_temp_free_i32(fp0);
9082 }
b6d96bed 9083 }
57fa1fb3 9084 break;
bf4120ad 9085 case OPC_CVT_D_S:
5e755519 9086 check_cp1_registers(ctx, fd);
b6d96bed 9087 {
a7812ae4
PB
9088 TCGv_i32 fp32 = tcg_temp_new_i32();
9089 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9090
7c979afd 9091 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9092 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9093 tcg_temp_free_i32(fp32);
b6d96bed 9094 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9095 tcg_temp_free_i64(fp64);
b6d96bed 9096 }
5a5012ec 9097 break;
bf4120ad 9098 case OPC_CVT_W_S:
b6d96bed 9099 {
a7812ae4 9100 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9101
7c979afd 9102 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9103 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9104 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9105 tcg_temp_free_i32(fp0);
b6d96bed 9106 }
5a5012ec 9107 break;
bf4120ad 9108 case OPC_CVT_L_S:
5e755519 9109 check_cp1_64bitmode(ctx);
b6d96bed 9110 {
a7812ae4
PB
9111 TCGv_i32 fp32 = tcg_temp_new_i32();
9112 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9113
7c979afd 9114 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9115 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9116 tcg_temp_free_i32(fp32);
b6d96bed 9117 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9118 tcg_temp_free_i64(fp64);
b6d96bed 9119 }
5a5012ec 9120 break;
bf4120ad 9121 case OPC_CVT_PS_S:
e29c9628 9122 check_ps(ctx);
b6d96bed 9123 {
a7812ae4
PB
9124 TCGv_i64 fp64 = tcg_temp_new_i64();
9125 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9126 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9127
7c979afd
LA
9128 gen_load_fpr32(ctx, fp32_0, fs);
9129 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9130 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9131 tcg_temp_free_i32(fp32_1);
9132 tcg_temp_free_i32(fp32_0);
36aa55dc 9133 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9134 tcg_temp_free_i64(fp64);
b6d96bed 9135 }
5a5012ec 9136 break;
bf4120ad
NF
9137 case OPC_CMP_F_S:
9138 case OPC_CMP_UN_S:
9139 case OPC_CMP_EQ_S:
9140 case OPC_CMP_UEQ_S:
9141 case OPC_CMP_OLT_S:
9142 case OPC_CMP_ULT_S:
9143 case OPC_CMP_OLE_S:
9144 case OPC_CMP_ULE_S:
9145 case OPC_CMP_SF_S:
9146 case OPC_CMP_NGLE_S:
9147 case OPC_CMP_SEQ_S:
9148 case OPC_CMP_NGL_S:
9149 case OPC_CMP_LT_S:
9150 case OPC_CMP_NGE_S:
9151 case OPC_CMP_LE_S:
9152 case OPC_CMP_NGT_S:
fecd2646 9153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9154 if (ctx->opcode & (1 << 6)) {
9155 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9156 } else {
9157 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9158 }
5a5012ec 9159 break;
bf4120ad 9160 case OPC_ADD_D:
5e755519 9161 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9162 {
a7812ae4
PB
9163 TCGv_i64 fp0 = tcg_temp_new_i64();
9164 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9165
9166 gen_load_fpr64(ctx, fp0, fs);
9167 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9168 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9169 tcg_temp_free_i64(fp1);
b6d96bed 9170 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9171 tcg_temp_free_i64(fp0);
b6d96bed 9172 }
6ea83fed 9173 break;
bf4120ad 9174 case OPC_SUB_D:
5e755519 9175 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9176 {
a7812ae4
PB
9177 TCGv_i64 fp0 = tcg_temp_new_i64();
9178 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9179
9180 gen_load_fpr64(ctx, fp0, fs);
9181 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9182 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9183 tcg_temp_free_i64(fp1);
b6d96bed 9184 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9185 tcg_temp_free_i64(fp0);
b6d96bed 9186 }
6ea83fed 9187 break;
bf4120ad 9188 case OPC_MUL_D:
5e755519 9189 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9190 {
a7812ae4
PB
9191 TCGv_i64 fp0 = tcg_temp_new_i64();
9192 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9193
9194 gen_load_fpr64(ctx, fp0, fs);
9195 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9196 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9197 tcg_temp_free_i64(fp1);
b6d96bed 9198 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9199 tcg_temp_free_i64(fp0);
b6d96bed 9200 }
6ea83fed 9201 break;
bf4120ad 9202 case OPC_DIV_D:
5e755519 9203 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9204 {
a7812ae4
PB
9205 TCGv_i64 fp0 = tcg_temp_new_i64();
9206 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9207
9208 gen_load_fpr64(ctx, fp0, fs);
9209 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9210 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9211 tcg_temp_free_i64(fp1);
b6d96bed 9212 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9213 tcg_temp_free_i64(fp0);
b6d96bed 9214 }
6ea83fed 9215 break;
bf4120ad 9216 case OPC_SQRT_D:
5e755519 9217 check_cp1_registers(ctx, fs | fd);
b6d96bed 9218 {
a7812ae4 9219 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9220
9221 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9222 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9223 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9224 tcg_temp_free_i64(fp0);
b6d96bed 9225 }
6ea83fed 9226 break;
bf4120ad 9227 case OPC_ABS_D:
5e755519 9228 check_cp1_registers(ctx, fs | fd);
b6d96bed 9229 {
a7812ae4 9230 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9231
9232 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9233 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9234 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9235 tcg_temp_free_i64(fp0);
b6d96bed 9236 }
6ea83fed 9237 break;
bf4120ad 9238 case OPC_MOV_D:
5e755519 9239 check_cp1_registers(ctx, fs | fd);
b6d96bed 9240 {
a7812ae4 9241 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9242
9243 gen_load_fpr64(ctx, fp0, fs);
9244 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9245 tcg_temp_free_i64(fp0);
b6d96bed 9246 }
6ea83fed 9247 break;
bf4120ad 9248 case OPC_NEG_D:
5e755519 9249 check_cp1_registers(ctx, fs | fd);
b6d96bed 9250 {
a7812ae4 9251 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9252
9253 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9254 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9255 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9256 tcg_temp_free_i64(fp0);
b6d96bed 9257 }
6ea83fed 9258 break;
bf4120ad 9259 case OPC_ROUND_L_D:
5e755519 9260 check_cp1_64bitmode(ctx);
b6d96bed 9261 {
a7812ae4 9262 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9263
9264 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9265 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9266 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9267 tcg_temp_free_i64(fp0);
b6d96bed 9268 }
5a5012ec 9269 break;
bf4120ad 9270 case OPC_TRUNC_L_D:
5e755519 9271 check_cp1_64bitmode(ctx);
b6d96bed 9272 {
a7812ae4 9273 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9274
9275 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9276 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9277 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9278 tcg_temp_free_i64(fp0);
b6d96bed 9279 }
5a5012ec 9280 break;
bf4120ad 9281 case OPC_CEIL_L_D:
5e755519 9282 check_cp1_64bitmode(ctx);
b6d96bed 9283 {
a7812ae4 9284 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9285
9286 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9287 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9288 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9289 tcg_temp_free_i64(fp0);
b6d96bed 9290 }
5a5012ec 9291 break;
bf4120ad 9292 case OPC_FLOOR_L_D:
5e755519 9293 check_cp1_64bitmode(ctx);
b6d96bed 9294 {
a7812ae4 9295 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9296
9297 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9298 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9299 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9300 tcg_temp_free_i64(fp0);
b6d96bed 9301 }
5a5012ec 9302 break;
bf4120ad 9303 case OPC_ROUND_W_D:
5e755519 9304 check_cp1_registers(ctx, fs);
b6d96bed 9305 {
a7812ae4
PB
9306 TCGv_i32 fp32 = tcg_temp_new_i32();
9307 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9308
9309 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9310 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9311 tcg_temp_free_i64(fp64);
7c979afd 9312 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9313 tcg_temp_free_i32(fp32);
b6d96bed 9314 }
6ea83fed 9315 break;
bf4120ad 9316 case OPC_TRUNC_W_D:
5e755519 9317 check_cp1_registers(ctx, fs);
b6d96bed 9318 {
a7812ae4
PB
9319 TCGv_i32 fp32 = tcg_temp_new_i32();
9320 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9321
9322 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9323 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9324 tcg_temp_free_i64(fp64);
7c979afd 9325 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9326 tcg_temp_free_i32(fp32);
b6d96bed 9327 }
6ea83fed 9328 break;
bf4120ad 9329 case OPC_CEIL_W_D:
5e755519 9330 check_cp1_registers(ctx, fs);
b6d96bed 9331 {
a7812ae4
PB
9332 TCGv_i32 fp32 = tcg_temp_new_i32();
9333 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9334
9335 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9336 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9337 tcg_temp_free_i64(fp64);
7c979afd 9338 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9339 tcg_temp_free_i32(fp32);
b6d96bed 9340 }
6ea83fed 9341 break;
bf4120ad 9342 case OPC_FLOOR_W_D:
5e755519 9343 check_cp1_registers(ctx, fs);
b6d96bed 9344 {
a7812ae4
PB
9345 TCGv_i32 fp32 = tcg_temp_new_i32();
9346 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9347
9348 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9349 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9350 tcg_temp_free_i64(fp64);
7c979afd 9351 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9352 tcg_temp_free_i32(fp32);
b6d96bed 9353 }
6ea83fed 9354 break;
e7f16abb
LA
9355 case OPC_SEL_D:
9356 check_insn(ctx, ISA_MIPS32R6);
9357 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9358 break;
9359 case OPC_SELEQZ_D:
9360 check_insn(ctx, ISA_MIPS32R6);
9361 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9362 break;
9363 case OPC_SELNEZ_D:
9364 check_insn(ctx, ISA_MIPS32R6);
9365 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9366 break;
bf4120ad 9367 case OPC_MOVCF_D:
fecd2646 9368 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9369 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9370 break;
bf4120ad 9371 case OPC_MOVZ_D:
fecd2646 9372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9373 {
42a268c2 9374 TCGLabel *l1 = gen_new_label();
c9297f4d 9375 TCGv_i64 fp0;
a16336e4 9376
c9297f4d
AJ
9377 if (ft != 0) {
9378 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9379 }
9380 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9381 gen_load_fpr64(ctx, fp0, fs);
9382 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9383 tcg_temp_free_i64(fp0);
a16336e4
TS
9384 gen_set_label(l1);
9385 }
5a5012ec 9386 break;
bf4120ad 9387 case OPC_MOVN_D:
fecd2646 9388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9389 {
42a268c2 9390 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9391 TCGv_i64 fp0;
9392
9393 if (ft != 0) {
9394 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9395 fp0 = tcg_temp_new_i64();
9396 gen_load_fpr64(ctx, fp0, fs);
9397 gen_store_fpr64(ctx, fp0, fd);
9398 tcg_temp_free_i64(fp0);
9399 gen_set_label(l1);
9400 }
a16336e4 9401 }
6ea83fed 9402 break;
bf4120ad 9403 case OPC_RECIP_D:
ca6c7803 9404 check_cp1_registers(ctx, fs | fd);
b6d96bed 9405 {
a7812ae4 9406 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9407
9408 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9409 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9410 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9411 tcg_temp_free_i64(fp0);
b6d96bed 9412 }
57fa1fb3 9413 break;
bf4120ad 9414 case OPC_RSQRT_D:
ca6c7803 9415 check_cp1_registers(ctx, fs | fd);
b6d96bed 9416 {
a7812ae4 9417 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9418
9419 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9420 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9421 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9422 tcg_temp_free_i64(fp0);
b6d96bed 9423 }
57fa1fb3 9424 break;
e7f16abb
LA
9425 case OPC_MADDF_D:
9426 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9427 {
a7812ae4
PB
9428 TCGv_i64 fp0 = tcg_temp_new_i64();
9429 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9430 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9431 gen_load_fpr64(ctx, fp0, fs);
9432 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9433 gen_load_fpr64(ctx, fp2, fd);
9434 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9435 gen_store_fpr64(ctx, fp2, fd);
9436 tcg_temp_free_i64(fp2);
a7812ae4 9437 tcg_temp_free_i64(fp1);
a7812ae4 9438 tcg_temp_free_i64(fp0);
b6d96bed 9439 }
57fa1fb3 9440 break;
e7f16abb
LA
9441 case OPC_MSUBF_D:
9442 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9443 {
a7812ae4 9444 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9445 TCGv_i64 fp1 = tcg_temp_new_i64();
9446 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9447 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9448 gen_load_fpr64(ctx, fp1, ft);
9449 gen_load_fpr64(ctx, fp2, fd);
9450 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9451 gen_store_fpr64(ctx, fp2, fd);
9452 tcg_temp_free_i64(fp2);
9453 tcg_temp_free_i64(fp1);
a7812ae4 9454 tcg_temp_free_i64(fp0);
b6d96bed 9455 }
57fa1fb3 9456 break;
e7f16abb
LA
9457 case OPC_RINT_D:
9458 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9459 {
a7812ae4 9460 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9461 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9462 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9463 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9464 tcg_temp_free_i64(fp0);
b6d96bed 9465 }
57fa1fb3 9466 break;
e7f16abb
LA
9467 case OPC_CLASS_D:
9468 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9469 {
e7f16abb
LA
9470 TCGv_i64 fp0 = tcg_temp_new_i64();
9471 gen_load_fpr64(ctx, fp0, fs);
9472 gen_helper_float_class_d(fp0, fp0);
9473 gen_store_fpr64(ctx, fp0, fd);
9474 tcg_temp_free_i64(fp0);
e7f16abb
LA
9475 }
9476 break;
9477 case OPC_MIN_D: /* OPC_RECIP2_D */
9478 if (ctx->insn_flags & ISA_MIPS32R6) {
9479 /* OPC_MIN_D */
a7812ae4
PB
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9482 gen_load_fpr64(ctx, fp0, fs);
9483 gen_load_fpr64(ctx, fp1, ft);
9484 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9485 gen_store_fpr64(ctx, fp1, fd);
9486 tcg_temp_free_i64(fp1);
9487 tcg_temp_free_i64(fp0);
e7f16abb
LA
9488 } else {
9489 /* OPC_RECIP2_D */
9490 check_cp1_64bitmode(ctx);
9491 {
9492 TCGv_i64 fp0 = tcg_temp_new_i64();
9493 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9494
e7f16abb
LA
9495 gen_load_fpr64(ctx, fp0, fs);
9496 gen_load_fpr64(ctx, fp1, ft);
9497 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9498 tcg_temp_free_i64(fp1);
9499 gen_store_fpr64(ctx, fp0, fd);
9500 tcg_temp_free_i64(fp0);
9501 }
e7f16abb
LA
9502 }
9503 break;
9504 case OPC_MINA_D: /* OPC_RECIP1_D */
9505 if (ctx->insn_flags & ISA_MIPS32R6) {
9506 /* OPC_MINA_D */
9507 TCGv_i64 fp0 = tcg_temp_new_i64();
9508 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9509 gen_load_fpr64(ctx, fp0, fs);
9510 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9511 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9512 gen_store_fpr64(ctx, fp1, fd);
9513 tcg_temp_free_i64(fp1);
9514 tcg_temp_free_i64(fp0);
e7f16abb
LA
9515 } else {
9516 /* OPC_RECIP1_D */
9517 check_cp1_64bitmode(ctx);
9518 {
9519 TCGv_i64 fp0 = tcg_temp_new_i64();
9520
9521 gen_load_fpr64(ctx, fp0, fs);
9522 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9523 gen_store_fpr64(ctx, fp0, fd);
9524 tcg_temp_free_i64(fp0);
9525 }
e7f16abb
LA
9526 }
9527 break;
9528 case OPC_MAX_D: /* OPC_RSQRT1_D */
9529 if (ctx->insn_flags & ISA_MIPS32R6) {
9530 /* OPC_MAX_D */
9531 TCGv_i64 fp0 = tcg_temp_new_i64();
9532 TCGv_i64 fp1 = tcg_temp_new_i64();
9533 gen_load_fpr64(ctx, fp0, fs);
9534 gen_load_fpr64(ctx, fp1, ft);
9535 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9536 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9537 tcg_temp_free_i64(fp1);
a7812ae4 9538 tcg_temp_free_i64(fp0);
e7f16abb
LA
9539 } else {
9540 /* OPC_RSQRT1_D */
9541 check_cp1_64bitmode(ctx);
9542 {
9543 TCGv_i64 fp0 = tcg_temp_new_i64();
9544
9545 gen_load_fpr64(ctx, fp0, fs);
9546 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9547 gen_store_fpr64(ctx, fp0, fd);
9548 tcg_temp_free_i64(fp0);
9549 }
e7f16abb
LA
9550 }
9551 break;
9552 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9553 if (ctx->insn_flags & ISA_MIPS32R6) {
9554 /* OPC_MAXA_D */
9555 TCGv_i64 fp0 = tcg_temp_new_i64();
9556 TCGv_i64 fp1 = tcg_temp_new_i64();
9557 gen_load_fpr64(ctx, fp0, fs);
9558 gen_load_fpr64(ctx, fp1, ft);
9559 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9560 gen_store_fpr64(ctx, fp1, fd);
9561 tcg_temp_free_i64(fp1);
9562 tcg_temp_free_i64(fp0);
e7f16abb
LA
9563 } else {
9564 /* OPC_RSQRT2_D */
9565 check_cp1_64bitmode(ctx);
9566 {
9567 TCGv_i64 fp0 = tcg_temp_new_i64();
9568 TCGv_i64 fp1 = tcg_temp_new_i64();
9569
9570 gen_load_fpr64(ctx, fp0, fs);
9571 gen_load_fpr64(ctx, fp1, ft);
9572 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9573 tcg_temp_free_i64(fp1);
9574 gen_store_fpr64(ctx, fp0, fd);
9575 tcg_temp_free_i64(fp0);
9576 }
b6d96bed 9577 }
57fa1fb3 9578 break;
bf4120ad
NF
9579 case OPC_CMP_F_D:
9580 case OPC_CMP_UN_D:
9581 case OPC_CMP_EQ_D:
9582 case OPC_CMP_UEQ_D:
9583 case OPC_CMP_OLT_D:
9584 case OPC_CMP_ULT_D:
9585 case OPC_CMP_OLE_D:
9586 case OPC_CMP_ULE_D:
9587 case OPC_CMP_SF_D:
9588 case OPC_CMP_NGLE_D:
9589 case OPC_CMP_SEQ_D:
9590 case OPC_CMP_NGL_D:
9591 case OPC_CMP_LT_D:
9592 case OPC_CMP_NGE_D:
9593 case OPC_CMP_LE_D:
9594 case OPC_CMP_NGT_D:
fecd2646 9595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9596 if (ctx->opcode & (1 << 6)) {
9597 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9598 } else {
9599 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9600 }
6ea83fed 9601 break;
bf4120ad 9602 case OPC_CVT_S_D:
5e755519 9603 check_cp1_registers(ctx, fs);
b6d96bed 9604 {
a7812ae4
PB
9605 TCGv_i32 fp32 = tcg_temp_new_i32();
9606 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9607
9608 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9609 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9610 tcg_temp_free_i64(fp64);
7c979afd 9611 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9612 tcg_temp_free_i32(fp32);
b6d96bed 9613 }
5a5012ec 9614 break;
bf4120ad 9615 case OPC_CVT_W_D:
5e755519 9616 check_cp1_registers(ctx, fs);
b6d96bed 9617 {
a7812ae4
PB
9618 TCGv_i32 fp32 = tcg_temp_new_i32();
9619 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9620
9621 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9622 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9623 tcg_temp_free_i64(fp64);
7c979afd 9624 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9625 tcg_temp_free_i32(fp32);
b6d96bed 9626 }
5a5012ec 9627 break;
bf4120ad 9628 case OPC_CVT_L_D:
5e755519 9629 check_cp1_64bitmode(ctx);
b6d96bed 9630 {
a7812ae4 9631 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9632
9633 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9634 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9635 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9636 tcg_temp_free_i64(fp0);
b6d96bed 9637 }
5a5012ec 9638 break;
bf4120ad 9639 case OPC_CVT_S_W:
b6d96bed 9640 {
a7812ae4 9641 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9642
7c979afd 9643 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9644 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9645 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9646 tcg_temp_free_i32(fp0);
b6d96bed 9647 }
6ea83fed 9648 break;
bf4120ad 9649 case OPC_CVT_D_W:
5e755519 9650 check_cp1_registers(ctx, fd);
b6d96bed 9651 {
a7812ae4
PB
9652 TCGv_i32 fp32 = tcg_temp_new_i32();
9653 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9654
7c979afd 9655 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9656 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9657 tcg_temp_free_i32(fp32);
b6d96bed 9658 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9659 tcg_temp_free_i64(fp64);
b6d96bed 9660 }
5a5012ec 9661 break;
bf4120ad 9662 case OPC_CVT_S_L:
5e755519 9663 check_cp1_64bitmode(ctx);
b6d96bed 9664 {
a7812ae4
PB
9665 TCGv_i32 fp32 = tcg_temp_new_i32();
9666 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9667
9668 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9669 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9670 tcg_temp_free_i64(fp64);
7c979afd 9671 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9672 tcg_temp_free_i32(fp32);
b6d96bed 9673 }
5a5012ec 9674 break;
bf4120ad 9675 case OPC_CVT_D_L:
5e755519 9676 check_cp1_64bitmode(ctx);
b6d96bed 9677 {
a7812ae4 9678 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9679
9680 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9681 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9682 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9683 tcg_temp_free_i64(fp0);
b6d96bed 9684 }
5a5012ec 9685 break;
bf4120ad 9686 case OPC_CVT_PS_PW:
e29c9628 9687 check_ps(ctx);
b6d96bed 9688 {
a7812ae4 9689 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9690
9691 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9692 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9693 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9694 tcg_temp_free_i64(fp0);
b6d96bed 9695 }
5a5012ec 9696 break;
bf4120ad 9697 case OPC_ADD_PS:
e29c9628 9698 check_ps(ctx);
b6d96bed 9699 {
a7812ae4
PB
9700 TCGv_i64 fp0 = tcg_temp_new_i64();
9701 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9702
9703 gen_load_fpr64(ctx, fp0, fs);
9704 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9705 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9706 tcg_temp_free_i64(fp1);
b6d96bed 9707 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9708 tcg_temp_free_i64(fp0);
b6d96bed 9709 }
6ea83fed 9710 break;
bf4120ad 9711 case OPC_SUB_PS:
e29c9628 9712 check_ps(ctx);
b6d96bed 9713 {
a7812ae4
PB
9714 TCGv_i64 fp0 = tcg_temp_new_i64();
9715 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9716
9717 gen_load_fpr64(ctx, fp0, fs);
9718 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9719 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9720 tcg_temp_free_i64(fp1);
b6d96bed 9721 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9722 tcg_temp_free_i64(fp0);
b6d96bed 9723 }
6ea83fed 9724 break;
bf4120ad 9725 case OPC_MUL_PS:
e29c9628 9726 check_ps(ctx);
b6d96bed 9727 {
a7812ae4
PB
9728 TCGv_i64 fp0 = tcg_temp_new_i64();
9729 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9730
9731 gen_load_fpr64(ctx, fp0, fs);
9732 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9733 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9734 tcg_temp_free_i64(fp1);
b6d96bed 9735 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9736 tcg_temp_free_i64(fp0);
b6d96bed 9737 }
6ea83fed 9738 break;
bf4120ad 9739 case OPC_ABS_PS:
e29c9628 9740 check_ps(ctx);
b6d96bed 9741 {
a7812ae4 9742 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9743
9744 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9745 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9746 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9747 tcg_temp_free_i64(fp0);
b6d96bed 9748 }
6ea83fed 9749 break;
bf4120ad 9750 case OPC_MOV_PS:
e29c9628 9751 check_ps(ctx);
b6d96bed 9752 {
a7812ae4 9753 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9754
9755 gen_load_fpr64(ctx, fp0, fs);
9756 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9757 tcg_temp_free_i64(fp0);
b6d96bed 9758 }
6ea83fed 9759 break;
bf4120ad 9760 case OPC_NEG_PS:
e29c9628 9761 check_ps(ctx);
b6d96bed 9762 {
a7812ae4 9763 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9764
9765 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9766 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9767 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9768 tcg_temp_free_i64(fp0);
b6d96bed 9769 }
6ea83fed 9770 break;
bf4120ad 9771 case OPC_MOVCF_PS:
e29c9628 9772 check_ps(ctx);
7f6613ce 9773 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 9774 break;
bf4120ad 9775 case OPC_MOVZ_PS:
e29c9628 9776 check_ps(ctx);
a16336e4 9777 {
42a268c2 9778 TCGLabel *l1 = gen_new_label();
30a3848b 9779 TCGv_i64 fp0;
a16336e4 9780
c9297f4d
AJ
9781 if (ft != 0)
9782 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9783 fp0 = tcg_temp_new_i64();
9784 gen_load_fpr64(ctx, fp0, fs);
9785 gen_store_fpr64(ctx, fp0, fd);
9786 tcg_temp_free_i64(fp0);
a16336e4
TS
9787 gen_set_label(l1);
9788 }
6ea83fed 9789 break;
bf4120ad 9790 case OPC_MOVN_PS:
e29c9628 9791 check_ps(ctx);
a16336e4 9792 {
42a268c2 9793 TCGLabel *l1 = gen_new_label();
30a3848b 9794 TCGv_i64 fp0;
c9297f4d
AJ
9795
9796 if (ft != 0) {
9797 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9798 fp0 = tcg_temp_new_i64();
9799 gen_load_fpr64(ctx, fp0, fs);
9800 gen_store_fpr64(ctx, fp0, fd);
9801 tcg_temp_free_i64(fp0);
9802 gen_set_label(l1);
9803 }
a16336e4 9804 }
6ea83fed 9805 break;
bf4120ad 9806 case OPC_ADDR_PS:
e29c9628 9807 check_ps(ctx);
b6d96bed 9808 {
a7812ae4
PB
9809 TCGv_i64 fp0 = tcg_temp_new_i64();
9810 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9811
9812 gen_load_fpr64(ctx, fp0, ft);
9813 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9814 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9815 tcg_temp_free_i64(fp1);
b6d96bed 9816 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9817 tcg_temp_free_i64(fp0);
b6d96bed 9818 }
fbcc6828 9819 break;
bf4120ad 9820 case OPC_MULR_PS:
e29c9628 9821 check_ps(ctx);
b6d96bed 9822 {
a7812ae4
PB
9823 TCGv_i64 fp0 = tcg_temp_new_i64();
9824 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9825
9826 gen_load_fpr64(ctx, fp0, ft);
9827 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9828 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9829 tcg_temp_free_i64(fp1);
b6d96bed 9830 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9831 tcg_temp_free_i64(fp0);
b6d96bed 9832 }
57fa1fb3 9833 break;
bf4120ad 9834 case OPC_RECIP2_PS:
e29c9628 9835 check_ps(ctx);
b6d96bed 9836 {
a7812ae4
PB
9837 TCGv_i64 fp0 = tcg_temp_new_i64();
9838 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9839
9840 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9841 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9842 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9843 tcg_temp_free_i64(fp1);
b6d96bed 9844 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9845 tcg_temp_free_i64(fp0);
b6d96bed 9846 }
57fa1fb3 9847 break;
bf4120ad 9848 case OPC_RECIP1_PS:
e29c9628 9849 check_ps(ctx);
b6d96bed 9850 {
a7812ae4 9851 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9852
9853 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9854 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9855 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9856 tcg_temp_free_i64(fp0);
b6d96bed 9857 }
57fa1fb3 9858 break;
bf4120ad 9859 case OPC_RSQRT1_PS:
e29c9628 9860 check_ps(ctx);
b6d96bed 9861 {
a7812ae4 9862 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9863
9864 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9865 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9866 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9867 tcg_temp_free_i64(fp0);
b6d96bed 9868 }
57fa1fb3 9869 break;
bf4120ad 9870 case OPC_RSQRT2_PS:
e29c9628 9871 check_ps(ctx);
b6d96bed 9872 {
a7812ae4
PB
9873 TCGv_i64 fp0 = tcg_temp_new_i64();
9874 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9875
9876 gen_load_fpr64(ctx, fp0, fs);
9877 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9878 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9879 tcg_temp_free_i64(fp1);
b6d96bed 9880 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9881 tcg_temp_free_i64(fp0);
b6d96bed 9882 }
57fa1fb3 9883 break;
bf4120ad 9884 case OPC_CVT_S_PU:
5e755519 9885 check_cp1_64bitmode(ctx);
b6d96bed 9886 {
a7812ae4 9887 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9888
7f6613ce 9889 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9890 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 9891 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9892 tcg_temp_free_i32(fp0);
b6d96bed 9893 }
dd016883 9894 break;
bf4120ad 9895 case OPC_CVT_PW_PS:
e29c9628 9896 check_ps(ctx);
b6d96bed 9897 {
a7812ae4 9898 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9899
9900 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9901 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9902 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9903 tcg_temp_free_i64(fp0);
b6d96bed 9904 }
6ea83fed 9905 break;
bf4120ad 9906 case OPC_CVT_S_PL:
5e755519 9907 check_cp1_64bitmode(ctx);
b6d96bed 9908 {
a7812ae4 9909 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9910
7c979afd 9911 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9912 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 9913 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9914 tcg_temp_free_i32(fp0);
b6d96bed 9915 }
6ea83fed 9916 break;
bf4120ad 9917 case OPC_PLL_PS:
e29c9628 9918 check_ps(ctx);
b6d96bed 9919 {
a7812ae4
PB
9920 TCGv_i32 fp0 = tcg_temp_new_i32();
9921 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9922
7c979afd
LA
9923 gen_load_fpr32(ctx, fp0, fs);
9924 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 9925 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 9926 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
9927 tcg_temp_free_i32(fp0);
9928 tcg_temp_free_i32(fp1);
b6d96bed 9929 }
6ea83fed 9930 break;
bf4120ad 9931 case OPC_PLU_PS:
e29c9628 9932 check_ps(ctx);
b6d96bed 9933 {
a7812ae4
PB
9934 TCGv_i32 fp0 = tcg_temp_new_i32();
9935 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9936
7c979afd 9937 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 9938 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 9939 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9940 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9941 tcg_temp_free_i32(fp0);
9942 tcg_temp_free_i32(fp1);
b6d96bed 9943 }
5a5012ec 9944 break;
bf4120ad 9945 case OPC_PUL_PS:
e29c9628 9946 check_ps(ctx);
b6d96bed 9947 {
a7812ae4
PB
9948 TCGv_i32 fp0 = tcg_temp_new_i32();
9949 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9950
7f6613ce 9951 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
9952 gen_load_fpr32(ctx, fp1, ft);
9953 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9954 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9955 tcg_temp_free_i32(fp0);
9956 tcg_temp_free_i32(fp1);
b6d96bed 9957 }
5a5012ec 9958 break;
bf4120ad 9959 case OPC_PUU_PS:
e29c9628 9960 check_ps(ctx);
b6d96bed 9961 {
a7812ae4
PB
9962 TCGv_i32 fp0 = tcg_temp_new_i32();
9963 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9964
7f6613ce
PJ
9965 gen_load_fpr32h(ctx, fp0, fs);
9966 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 9967 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9968 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9969 tcg_temp_free_i32(fp0);
9970 tcg_temp_free_i32(fp1);
b6d96bed 9971 }
5a5012ec 9972 break;
bf4120ad
NF
9973 case OPC_CMP_F_PS:
9974 case OPC_CMP_UN_PS:
9975 case OPC_CMP_EQ_PS:
9976 case OPC_CMP_UEQ_PS:
9977 case OPC_CMP_OLT_PS:
9978 case OPC_CMP_ULT_PS:
9979 case OPC_CMP_OLE_PS:
9980 case OPC_CMP_ULE_PS:
9981 case OPC_CMP_SF_PS:
9982 case OPC_CMP_NGLE_PS:
9983 case OPC_CMP_SEQ_PS:
9984 case OPC_CMP_NGL_PS:
9985 case OPC_CMP_LT_PS:
9986 case OPC_CMP_NGE_PS:
9987 case OPC_CMP_LE_PS:
9988 case OPC_CMP_NGT_PS:
8153667c
NF
9989 if (ctx->opcode & (1 << 6)) {
9990 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
9991 } else {
9992 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 9993 }
6ea83fed 9994 break;
5a5012ec 9995 default:
9d68ac14 9996 MIPS_INVAL("farith");
9c708c7f 9997 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
9998 return;
9999 }
6ea83fed 10000}
6af0bf9c 10001
5a5012ec 10002/* Coprocessor 3 (FPU) */
5e755519
TS
10003static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10004 int fd, int fs, int base, int index)
7a387fff 10005{
4e2474d6 10006 TCGv t0 = tcg_temp_new();
7a387fff 10007
93b12ccc 10008 if (base == 0) {
6c5c1e20 10009 gen_load_gpr(t0, index);
93b12ccc 10010 } else if (index == 0) {
6c5c1e20 10011 gen_load_gpr(t0, base);
93b12ccc 10012 } else {
05168674 10013 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10014 }
5a5012ec 10015 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10016 memory access. */
5a5012ec
TS
10017 switch (opc) {
10018 case OPC_LWXC1:
8c0ab41f 10019 check_cop1x(ctx);
b6d96bed 10020 {
a7812ae4 10021 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10022
5f68f5ae 10023 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10024 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10025 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10026 tcg_temp_free_i32(fp0);
b6d96bed 10027 }
5a5012ec
TS
10028 break;
10029 case OPC_LDXC1:
8c0ab41f
AJ
10030 check_cop1x(ctx);
10031 check_cp1_registers(ctx, fd);
b6d96bed 10032 {
a7812ae4 10033 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10034 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10035 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10036 tcg_temp_free_i64(fp0);
b6d96bed 10037 }
5a5012ec
TS
10038 break;
10039 case OPC_LUXC1:
8c0ab41f 10040 check_cp1_64bitmode(ctx);
6c5c1e20 10041 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10042 {
a7812ae4 10043 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10044
5f68f5ae 10045 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10046 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10047 tcg_temp_free_i64(fp0);
b6d96bed 10048 }
5a5012ec
TS
10049 break;
10050 case OPC_SWXC1:
8c0ab41f 10051 check_cop1x(ctx);
b6d96bed 10052 {
a7812ae4 10053 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10054 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10055 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10056 tcg_temp_free_i32(fp0);
b6d96bed 10057 }
5a5012ec
TS
10058 break;
10059 case OPC_SDXC1:
8c0ab41f
AJ
10060 check_cop1x(ctx);
10061 check_cp1_registers(ctx, fs);
b6d96bed 10062 {
a7812ae4 10063 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10064 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10065 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10066 tcg_temp_free_i64(fp0);
b6d96bed 10067 }
5a5012ec
TS
10068 break;
10069 case OPC_SUXC1:
8c0ab41f 10070 check_cp1_64bitmode(ctx);
6c5c1e20 10071 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10072 {
a7812ae4 10073 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10074 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10075 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10076 tcg_temp_free_i64(fp0);
b6d96bed 10077 }
5a5012ec 10078 break;
5a5012ec 10079 }
6c5c1e20 10080 tcg_temp_free(t0);
5a5012ec
TS
10081}
10082
5e755519
TS
10083static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10084 int fd, int fr, int fs, int ft)
5a5012ec 10085{
5a5012ec
TS
10086 switch (opc) {
10087 case OPC_ALNV_PS:
e29c9628 10088 check_ps(ctx);
a16336e4 10089 {
a7812ae4 10090 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10091 TCGv_i32 fp = tcg_temp_new_i32();
10092 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10093 TCGLabel *l1 = gen_new_label();
10094 TCGLabel *l2 = gen_new_label();
a16336e4 10095
6c5c1e20
TS
10096 gen_load_gpr(t0, fr);
10097 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10098
10099 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10100 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10101 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10102 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10103 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10104 tcg_gen_br(l2);
10105 gen_set_label(l1);
6c5c1e20
TS
10106 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10107 tcg_temp_free(t0);
a16336e4 10108#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10109 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10110 gen_load_fpr32h(ctx, fph, ft);
10111 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10112 gen_store_fpr32(ctx, fph, fd);
a16336e4 10113#else
7f6613ce 10114 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10115 gen_load_fpr32(ctx, fp, ft);
10116 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10117 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10118#endif
10119 gen_set_label(l2);
c905fdac
AJ
10120 tcg_temp_free_i32(fp);
10121 tcg_temp_free_i32(fph);
a16336e4 10122 }
5a5012ec
TS
10123 break;
10124 case OPC_MADD_S:
b8aa4598 10125 check_cop1x(ctx);
b6d96bed 10126 {
a7812ae4
PB
10127 TCGv_i32 fp0 = tcg_temp_new_i32();
10128 TCGv_i32 fp1 = tcg_temp_new_i32();
10129 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10130
7c979afd
LA
10131 gen_load_fpr32(ctx, fp0, fs);
10132 gen_load_fpr32(ctx, fp1, ft);
10133 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10134 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10135 tcg_temp_free_i32(fp0);
10136 tcg_temp_free_i32(fp1);
7c979afd 10137 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10138 tcg_temp_free_i32(fp2);
b6d96bed 10139 }
5a5012ec
TS
10140 break;
10141 case OPC_MADD_D:
b8aa4598
TS
10142 check_cop1x(ctx);
10143 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10144 {
a7812ae4
PB
10145 TCGv_i64 fp0 = tcg_temp_new_i64();
10146 TCGv_i64 fp1 = tcg_temp_new_i64();
10147 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10148
10149 gen_load_fpr64(ctx, fp0, fs);
10150 gen_load_fpr64(ctx, fp1, ft);
10151 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10152 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10153 tcg_temp_free_i64(fp0);
10154 tcg_temp_free_i64(fp1);
b6d96bed 10155 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10156 tcg_temp_free_i64(fp2);
b6d96bed 10157 }
5a5012ec
TS
10158 break;
10159 case OPC_MADD_PS:
e29c9628 10160 check_ps(ctx);
b6d96bed 10161 {
a7812ae4
PB
10162 TCGv_i64 fp0 = tcg_temp_new_i64();
10163 TCGv_i64 fp1 = tcg_temp_new_i64();
10164 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10165
10166 gen_load_fpr64(ctx, fp0, fs);
10167 gen_load_fpr64(ctx, fp1, ft);
10168 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10169 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10170 tcg_temp_free_i64(fp0);
10171 tcg_temp_free_i64(fp1);
b6d96bed 10172 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10173 tcg_temp_free_i64(fp2);
b6d96bed 10174 }
5a5012ec
TS
10175 break;
10176 case OPC_MSUB_S:
b8aa4598 10177 check_cop1x(ctx);
b6d96bed 10178 {
a7812ae4
PB
10179 TCGv_i32 fp0 = tcg_temp_new_i32();
10180 TCGv_i32 fp1 = tcg_temp_new_i32();
10181 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10182
7c979afd
LA
10183 gen_load_fpr32(ctx, fp0, fs);
10184 gen_load_fpr32(ctx, fp1, ft);
10185 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10186 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10187 tcg_temp_free_i32(fp0);
10188 tcg_temp_free_i32(fp1);
7c979afd 10189 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10190 tcg_temp_free_i32(fp2);
b6d96bed 10191 }
5a5012ec
TS
10192 break;
10193 case OPC_MSUB_D:
b8aa4598
TS
10194 check_cop1x(ctx);
10195 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10196 {
a7812ae4
PB
10197 TCGv_i64 fp0 = tcg_temp_new_i64();
10198 TCGv_i64 fp1 = tcg_temp_new_i64();
10199 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10200
10201 gen_load_fpr64(ctx, fp0, fs);
10202 gen_load_fpr64(ctx, fp1, ft);
10203 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10204 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10205 tcg_temp_free_i64(fp0);
10206 tcg_temp_free_i64(fp1);
b6d96bed 10207 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10208 tcg_temp_free_i64(fp2);
b6d96bed 10209 }
5a5012ec
TS
10210 break;
10211 case OPC_MSUB_PS:
e29c9628 10212 check_ps(ctx);
b6d96bed 10213 {
a7812ae4
PB
10214 TCGv_i64 fp0 = tcg_temp_new_i64();
10215 TCGv_i64 fp1 = tcg_temp_new_i64();
10216 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10217
10218 gen_load_fpr64(ctx, fp0, fs);
10219 gen_load_fpr64(ctx, fp1, ft);
10220 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10221 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10222 tcg_temp_free_i64(fp0);
10223 tcg_temp_free_i64(fp1);
b6d96bed 10224 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10225 tcg_temp_free_i64(fp2);
b6d96bed 10226 }
5a5012ec
TS
10227 break;
10228 case OPC_NMADD_S:
b8aa4598 10229 check_cop1x(ctx);
b6d96bed 10230 {
a7812ae4
PB
10231 TCGv_i32 fp0 = tcg_temp_new_i32();
10232 TCGv_i32 fp1 = tcg_temp_new_i32();
10233 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10234
7c979afd
LA
10235 gen_load_fpr32(ctx, fp0, fs);
10236 gen_load_fpr32(ctx, fp1, ft);
10237 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10238 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10239 tcg_temp_free_i32(fp0);
10240 tcg_temp_free_i32(fp1);
7c979afd 10241 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10242 tcg_temp_free_i32(fp2);
b6d96bed 10243 }
5a5012ec
TS
10244 break;
10245 case OPC_NMADD_D:
b8aa4598
TS
10246 check_cop1x(ctx);
10247 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10248 {
a7812ae4
PB
10249 TCGv_i64 fp0 = tcg_temp_new_i64();
10250 TCGv_i64 fp1 = tcg_temp_new_i64();
10251 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10252
10253 gen_load_fpr64(ctx, fp0, fs);
10254 gen_load_fpr64(ctx, fp1, ft);
10255 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10256 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10257 tcg_temp_free_i64(fp0);
10258 tcg_temp_free_i64(fp1);
b6d96bed 10259 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10260 tcg_temp_free_i64(fp2);
b6d96bed 10261 }
5a5012ec
TS
10262 break;
10263 case OPC_NMADD_PS:
e29c9628 10264 check_ps(ctx);
b6d96bed 10265 {
a7812ae4
PB
10266 TCGv_i64 fp0 = tcg_temp_new_i64();
10267 TCGv_i64 fp1 = tcg_temp_new_i64();
10268 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10269
10270 gen_load_fpr64(ctx, fp0, fs);
10271 gen_load_fpr64(ctx, fp1, ft);
10272 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10273 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10274 tcg_temp_free_i64(fp0);
10275 tcg_temp_free_i64(fp1);
b6d96bed 10276 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10277 tcg_temp_free_i64(fp2);
b6d96bed 10278 }
5a5012ec
TS
10279 break;
10280 case OPC_NMSUB_S:
b8aa4598 10281 check_cop1x(ctx);
b6d96bed 10282 {
a7812ae4
PB
10283 TCGv_i32 fp0 = tcg_temp_new_i32();
10284 TCGv_i32 fp1 = tcg_temp_new_i32();
10285 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10286
7c979afd
LA
10287 gen_load_fpr32(ctx, fp0, fs);
10288 gen_load_fpr32(ctx, fp1, ft);
10289 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10290 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10291 tcg_temp_free_i32(fp0);
10292 tcg_temp_free_i32(fp1);
7c979afd 10293 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10294 tcg_temp_free_i32(fp2);
b6d96bed 10295 }
5a5012ec
TS
10296 break;
10297 case OPC_NMSUB_D:
b8aa4598
TS
10298 check_cop1x(ctx);
10299 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10300 {
a7812ae4
PB
10301 TCGv_i64 fp0 = tcg_temp_new_i64();
10302 TCGv_i64 fp1 = tcg_temp_new_i64();
10303 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10304
10305 gen_load_fpr64(ctx, fp0, fs);
10306 gen_load_fpr64(ctx, fp1, ft);
10307 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10308 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10309 tcg_temp_free_i64(fp0);
10310 tcg_temp_free_i64(fp1);
b6d96bed 10311 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10312 tcg_temp_free_i64(fp2);
b6d96bed 10313 }
5a5012ec
TS
10314 break;
10315 case OPC_NMSUB_PS:
e29c9628 10316 check_ps(ctx);
b6d96bed 10317 {
a7812ae4
PB
10318 TCGv_i64 fp0 = tcg_temp_new_i64();
10319 TCGv_i64 fp1 = tcg_temp_new_i64();
10320 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10321
10322 gen_load_fpr64(ctx, fp0, fs);
10323 gen_load_fpr64(ctx, fp1, ft);
10324 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10325 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10326 tcg_temp_free_i64(fp0);
10327 tcg_temp_free_i64(fp1);
b6d96bed 10328 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10329 tcg_temp_free_i64(fp2);
b6d96bed 10330 }
5a5012ec 10331 break;
923617a3 10332 default:
9d68ac14 10333 MIPS_INVAL("flt3_arith");
9c708c7f 10334 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10335 return;
10336 }
7a387fff
TS
10337}
10338
d75c135e 10339static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10340{
10341 TCGv t0;
10342
b3167288
RH
10343#if !defined(CONFIG_USER_ONLY)
10344 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10345 Therefore only check the ISA in system mode. */
d75c135e 10346 check_insn(ctx, ISA_MIPS32R2);
b3167288 10347#endif
26ebe468
NF
10348 t0 = tcg_temp_new();
10349
10350 switch (rd) {
10351 case 0:
895c2d04 10352 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10353 gen_store_gpr(t0, rt);
10354 break;
10355 case 1:
895c2d04 10356 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10357 gen_store_gpr(t0, rt);
10358 break;
10359 case 2:
895c2d04 10360 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10361 gen_store_gpr(t0, rt);
10362 break;
10363 case 3:
895c2d04 10364 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10365 gen_store_gpr(t0, rt);
10366 break;
10367 case 29:
10368#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10369 tcg_gen_ld_tl(t0, cpu_env,
10370 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10371 gen_store_gpr(t0, rt);
10372 break;
10373#else
d279279e
PJ
10374 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10375 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10376 tcg_gen_ld_tl(t0, cpu_env,
10377 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10378 gen_store_gpr(t0, rt);
10379 } else {
9c708c7f 10380 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10381 }
10382 break;
26ebe468
NF
10383#endif
10384 default: /* Invalid */
10385 MIPS_INVAL("rdhwr");
9c708c7f 10386 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10387 break;
10388 }
10389 tcg_temp_free(t0);
10390}
10391
a5f53390
LA
10392static inline void clear_branch_hflags(DisasContext *ctx)
10393{
10394 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10395 if (ctx->bstate == BS_NONE) {
10396 save_cpu_state(ctx, 0);
10397 } else {
10398 /* it is not safe to save ctx->hflags as hflags may be changed
10399 in execution time by the instruction in delay / forbidden slot. */
10400 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10401 }
10402}
10403
31837be3 10404static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10405{
10406 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10407 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10408 /* Branches completion */
a5f53390 10409 clear_branch_hflags(ctx);
c9602061 10410 ctx->bstate = BS_BRANCH;
c9602061 10411 /* FIXME: Need to clear can_do_io. */
364d4831 10412 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10413 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10414 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10415 break;
c9602061
NF
10416 case MIPS_HFLAG_B:
10417 /* unconditional branch */
364d4831
NF
10418 if (proc_hflags & MIPS_HFLAG_BX) {
10419 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10420 }
c9602061
NF
10421 gen_goto_tb(ctx, 0, ctx->btarget);
10422 break;
10423 case MIPS_HFLAG_BL:
10424 /* blikely taken case */
c9602061
NF
10425 gen_goto_tb(ctx, 0, ctx->btarget);
10426 break;
10427 case MIPS_HFLAG_BC:
10428 /* Conditional branch */
c9602061 10429 {
42a268c2 10430 TCGLabel *l1 = gen_new_label();
c9602061
NF
10431
10432 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10433 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10434 gen_set_label(l1);
10435 gen_goto_tb(ctx, 0, ctx->btarget);
10436 }
10437 break;
10438 case MIPS_HFLAG_BR:
10439 /* unconditional branch to register */
d75c135e 10440 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10441 TCGv t0 = tcg_temp_new();
10442 TCGv_i32 t1 = tcg_temp_new_i32();
10443
10444 tcg_gen_andi_tl(t0, btarget, 0x1);
10445 tcg_gen_trunc_tl_i32(t1, t0);
10446 tcg_temp_free(t0);
10447 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10448 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10449 tcg_gen_or_i32(hflags, hflags, t1);
10450 tcg_temp_free_i32(t1);
10451
10452 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10453 } else {
10454 tcg_gen_mov_tl(cpu_PC, btarget);
10455 }
c9602061
NF
10456 if (ctx->singlestep_enabled) {
10457 save_cpu_state(ctx, 0);
9c708c7f 10458 gen_helper_raise_exception_debug(cpu_env);
c9602061
NF
10459 }
10460 tcg_gen_exit_tb(0);
10461 break;
10462 default:
a5f53390
LA
10463 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10464 abort();
c9602061
NF
10465 }
10466 }
10467}
10468
6893f074
YK
10469/* Compact Branches */
10470static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10471 int rs, int rt, int32_t offset)
10472{
10473 int bcond_compute = 0;
10474 TCGv t0 = tcg_temp_new();
10475 TCGv t1 = tcg_temp_new();
65935f07 10476 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10477
10478 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10479#ifdef MIPS_DEBUG_DISAS
10480 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10481 "\n", ctx->pc);
10482#endif
9c708c7f 10483 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10484 goto out;
10485 }
10486
10487 /* Load needed operands and calculate btarget */
10488 switch (opc) {
10489 /* compact branch */
10490 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10491 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10492 gen_load_gpr(t0, rs);
10493 gen_load_gpr(t1, rt);
10494 bcond_compute = 1;
10495 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10496 if (rs <= rt && rs == 0) {
10497 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10498 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10499 }
10500 break;
10501 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10502 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10503 gen_load_gpr(t0, rs);
10504 gen_load_gpr(t1, rt);
10505 bcond_compute = 1;
10506 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10507 break;
10508 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10509 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10510 if (rs == 0 || rs == rt) {
10511 /* OPC_BLEZALC, OPC_BGEZALC */
10512 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10513 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10514 }
10515 gen_load_gpr(t0, rs);
10516 gen_load_gpr(t1, rt);
10517 bcond_compute = 1;
10518 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10519 break;
10520 case OPC_BC:
10521 case OPC_BALC:
10522 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10523 break;
10524 case OPC_BEQZC:
10525 case OPC_BNEZC:
10526 if (rs != 0) {
10527 /* OPC_BEQZC, OPC_BNEZC */
10528 gen_load_gpr(t0, rs);
10529 bcond_compute = 1;
10530 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10531 } else {
10532 /* OPC_JIC, OPC_JIALC */
10533 TCGv tbase = tcg_temp_new();
10534 TCGv toffset = tcg_temp_new();
10535
10536 gen_load_gpr(tbase, rt);
10537 tcg_gen_movi_tl(toffset, offset);
10538 gen_op_addr_add(ctx, btarget, tbase, toffset);
10539 tcg_temp_free(tbase);
10540 tcg_temp_free(toffset);
10541 }
10542 break;
10543 default:
10544 MIPS_INVAL("Compact branch/jump");
9c708c7f 10545 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10546 goto out;
10547 }
10548
10549 if (bcond_compute == 0) {
10550 /* Uncoditional compact branch */
10551 switch (opc) {
10552 case OPC_JIALC:
65935f07 10553 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10554 /* Fallthrough */
10555 case OPC_JIC:
10556 ctx->hflags |= MIPS_HFLAG_BR;
10557 break;
10558 case OPC_BALC:
65935f07 10559 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10560 /* Fallthrough */
10561 case OPC_BC:
10562 ctx->hflags |= MIPS_HFLAG_B;
10563 break;
10564 default:
10565 MIPS_INVAL("Compact branch/jump");
9c708c7f 10566 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10567 goto out;
10568 }
10569
10570 /* Generating branch here as compact branches don't have delay slot */
10571 gen_branch(ctx, 4);
10572 } else {
10573 /* Conditional compact branch */
10574 TCGLabel *fs = gen_new_label();
10575 save_cpu_state(ctx, 0);
10576
10577 switch (opc) {
10578 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10579 if (rs == 0 && rt != 0) {
10580 /* OPC_BLEZALC */
10581 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10582 } else if (rs != 0 && rt != 0 && rs == rt) {
10583 /* OPC_BGEZALC */
10584 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10585 } else {
10586 /* OPC_BGEUC */
10587 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10588 }
10589 break;
10590 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10591 if (rs == 0 && rt != 0) {
10592 /* OPC_BGTZALC */
10593 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10594 } else if (rs != 0 && rt != 0 && rs == rt) {
10595 /* OPC_BLTZALC */
10596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10597 } else {
10598 /* OPC_BLTUC */
10599 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10600 }
10601 break;
10602 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10603 if (rs == 0 && rt != 0) {
10604 /* OPC_BLEZC */
10605 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10606 } else if (rs != 0 && rt != 0 && rs == rt) {
10607 /* OPC_BGEZC */
10608 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10609 } else {
10610 /* OPC_BGEC */
10611 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10612 }
10613 break;
10614 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10615 if (rs == 0 && rt != 0) {
10616 /* OPC_BGTZC */
10617 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10618 } else if (rs != 0 && rt != 0 && rs == rt) {
10619 /* OPC_BLTZC */
10620 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10621 } else {
10622 /* OPC_BLTC */
10623 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10624 }
10625 break;
10626 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10627 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10628 if (rs >= rt) {
10629 /* OPC_BOVC, OPC_BNVC */
10630 TCGv t2 = tcg_temp_new();
10631 TCGv t3 = tcg_temp_new();
10632 TCGv t4 = tcg_temp_new();
10633 TCGv input_overflow = tcg_temp_new();
10634
10635 gen_load_gpr(t0, rs);
10636 gen_load_gpr(t1, rt);
10637 tcg_gen_ext32s_tl(t2, t0);
10638 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10639 tcg_gen_ext32s_tl(t3, t1);
10640 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10641 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10642
10643 tcg_gen_add_tl(t4, t2, t3);
10644 tcg_gen_ext32s_tl(t4, t4);
10645 tcg_gen_xor_tl(t2, t2, t3);
10646 tcg_gen_xor_tl(t3, t4, t3);
10647 tcg_gen_andc_tl(t2, t3, t2);
10648 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10649 tcg_gen_or_tl(t4, t4, input_overflow);
10650 if (opc == OPC_BOVC) {
10651 /* OPC_BOVC */
10652 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10653 } else {
10654 /* OPC_BNVC */
10655 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10656 }
10657 tcg_temp_free(input_overflow);
10658 tcg_temp_free(t4);
10659 tcg_temp_free(t3);
10660 tcg_temp_free(t2);
10661 } else if (rs < rt && rs == 0) {
10662 /* OPC_BEQZALC, OPC_BNEZALC */
10663 if (opc == OPC_BEQZALC) {
10664 /* OPC_BEQZALC */
10665 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10666 } else {
10667 /* OPC_BNEZALC */
10668 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10669 }
10670 } else {
10671 /* OPC_BEQC, OPC_BNEC */
10672 if (opc == OPC_BEQC) {
10673 /* OPC_BEQC */
10674 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10675 } else {
10676 /* OPC_BNEC */
10677 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10678 }
10679 }
10680 break;
10681 case OPC_BEQZC:
10682 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10683 break;
10684 case OPC_BNEZC:
10685 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10686 break;
10687 default:
10688 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 10689 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10690 goto out;
10691 }
10692
10693 /* Generating branch here as compact branches don't have delay slot */
10694 gen_goto_tb(ctx, 1, ctx->btarget);
10695 gen_set_label(fs);
10696
10697 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10698 }
10699
10700out:
10701 tcg_temp_free(t0);
10702 tcg_temp_free(t1);
10703}
10704
7a387fff 10705/* ISA extensions (ASEs) */
6af0bf9c 10706/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10707
10708/* MIPS16 major opcodes */
10709enum {
10710 M16_OPC_ADDIUSP = 0x00,
10711 M16_OPC_ADDIUPC = 0x01,
10712 M16_OPC_B = 0x02,
10713 M16_OPC_JAL = 0x03,
10714 M16_OPC_BEQZ = 0x04,
10715 M16_OPC_BNEQZ = 0x05,
10716 M16_OPC_SHIFT = 0x06,
10717 M16_OPC_LD = 0x07,
10718 M16_OPC_RRIA = 0x08,
10719 M16_OPC_ADDIU8 = 0x09,
10720 M16_OPC_SLTI = 0x0a,
10721 M16_OPC_SLTIU = 0x0b,
10722 M16_OPC_I8 = 0x0c,
10723 M16_OPC_LI = 0x0d,
10724 M16_OPC_CMPI = 0x0e,
10725 M16_OPC_SD = 0x0f,
10726 M16_OPC_LB = 0x10,
10727 M16_OPC_LH = 0x11,
10728 M16_OPC_LWSP = 0x12,
10729 M16_OPC_LW = 0x13,
10730 M16_OPC_LBU = 0x14,
10731 M16_OPC_LHU = 0x15,
10732 M16_OPC_LWPC = 0x16,
10733 M16_OPC_LWU = 0x17,
10734 M16_OPC_SB = 0x18,
10735 M16_OPC_SH = 0x19,
10736 M16_OPC_SWSP = 0x1a,
10737 M16_OPC_SW = 0x1b,
10738 M16_OPC_RRR = 0x1c,
10739 M16_OPC_RR = 0x1d,
10740 M16_OPC_EXTEND = 0x1e,
10741 M16_OPC_I64 = 0x1f
10742};
10743
10744/* I8 funct field */
10745enum {
10746 I8_BTEQZ = 0x0,
10747 I8_BTNEZ = 0x1,
10748 I8_SWRASP = 0x2,
10749 I8_ADJSP = 0x3,
10750 I8_SVRS = 0x4,
10751 I8_MOV32R = 0x5,
10752 I8_MOVR32 = 0x7
10753};
10754
10755/* RRR f field */
10756enum {
10757 RRR_DADDU = 0x0,
10758 RRR_ADDU = 0x1,
10759 RRR_DSUBU = 0x2,
10760 RRR_SUBU = 0x3
10761};
10762
10763/* RR funct field */
10764enum {
10765 RR_JR = 0x00,
10766 RR_SDBBP = 0x01,
10767 RR_SLT = 0x02,
10768 RR_SLTU = 0x03,
10769 RR_SLLV = 0x04,
10770 RR_BREAK = 0x05,
10771 RR_SRLV = 0x06,
10772 RR_SRAV = 0x07,
10773 RR_DSRL = 0x08,
10774 RR_CMP = 0x0a,
10775 RR_NEG = 0x0b,
10776 RR_AND = 0x0c,
10777 RR_OR = 0x0d,
10778 RR_XOR = 0x0e,
10779 RR_NOT = 0x0f,
10780 RR_MFHI = 0x10,
10781 RR_CNVT = 0x11,
10782 RR_MFLO = 0x12,
10783 RR_DSRA = 0x13,
10784 RR_DSLLV = 0x14,
10785 RR_DSRLV = 0x16,
10786 RR_DSRAV = 0x17,
10787 RR_MULT = 0x18,
10788 RR_MULTU = 0x19,
10789 RR_DIV = 0x1a,
10790 RR_DIVU = 0x1b,
10791 RR_DMULT = 0x1c,
10792 RR_DMULTU = 0x1d,
10793 RR_DDIV = 0x1e,
10794 RR_DDIVU = 0x1f
10795};
10796
10797/* I64 funct field */
10798enum {
10799 I64_LDSP = 0x0,
10800 I64_SDSP = 0x1,
10801 I64_SDRASP = 0x2,
10802 I64_DADJSP = 0x3,
10803 I64_LDPC = 0x4,
364d4831 10804 I64_DADDIU5 = 0x5,
6ea219d0
NF
10805 I64_DADDIUPC = 0x6,
10806 I64_DADDIUSP = 0x7
10807};
10808
10809/* RR ry field for CNVT */
10810enum {
10811 RR_RY_CNVT_ZEB = 0x0,
10812 RR_RY_CNVT_ZEH = 0x1,
10813 RR_RY_CNVT_ZEW = 0x2,
10814 RR_RY_CNVT_SEB = 0x4,
10815 RR_RY_CNVT_SEH = 0x5,
10816 RR_RY_CNVT_SEW = 0x6,
10817};
10818
364d4831
NF
10819static int xlat (int r)
10820{
10821 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10822
10823 return map[r];
10824}
10825
10826static void gen_mips16_save (DisasContext *ctx,
10827 int xsregs, int aregs,
10828 int do_ra, int do_s0, int do_s1,
10829 int framesize)
10830{
10831 TCGv t0 = tcg_temp_new();
10832 TCGv t1 = tcg_temp_new();
c48245f0 10833 TCGv t2 = tcg_temp_new();
364d4831
NF
10834 int args, astatic;
10835
10836 switch (aregs) {
10837 case 0:
10838 case 1:
10839 case 2:
10840 case 3:
10841 case 11:
10842 args = 0;
10843 break;
10844 case 4:
10845 case 5:
10846 case 6:
10847 case 7:
10848 args = 1;
10849 break;
10850 case 8:
10851 case 9:
10852 case 10:
10853 args = 2;
10854 break;
10855 case 12:
10856 case 13:
10857 args = 3;
10858 break;
10859 case 14:
10860 args = 4;
10861 break;
10862 default:
9c708c7f 10863 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
10864 return;
10865 }
10866
10867 switch (args) {
10868 case 4:
10869 gen_base_offset_addr(ctx, t0, 29, 12);
10870 gen_load_gpr(t1, 7);
5f68f5ae 10871 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10872 /* Fall through */
10873 case 3:
10874 gen_base_offset_addr(ctx, t0, 29, 8);
10875 gen_load_gpr(t1, 6);
5f68f5ae 10876 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10877 /* Fall through */
10878 case 2:
10879 gen_base_offset_addr(ctx, t0, 29, 4);
10880 gen_load_gpr(t1, 5);
5f68f5ae 10881 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10882 /* Fall through */
10883 case 1:
10884 gen_base_offset_addr(ctx, t0, 29, 0);
10885 gen_load_gpr(t1, 4);
5f68f5ae 10886 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10887 }
10888
10889 gen_load_gpr(t0, 29);
10890
5f68f5ae 10891#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10892 tcg_gen_movi_tl(t2, -4); \
10893 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10894 gen_load_gpr(t1, reg); \
10895 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10896 } while (0)
10897
10898 if (do_ra) {
10899 DECR_AND_STORE(31);
10900 }
10901
10902 switch (xsregs) {
10903 case 7:
10904 DECR_AND_STORE(30);
10905 /* Fall through */
10906 case 6:
10907 DECR_AND_STORE(23);
10908 /* Fall through */
10909 case 5:
10910 DECR_AND_STORE(22);
10911 /* Fall through */
10912 case 4:
10913 DECR_AND_STORE(21);
10914 /* Fall through */
10915 case 3:
10916 DECR_AND_STORE(20);
10917 /* Fall through */
10918 case 2:
10919 DECR_AND_STORE(19);
10920 /* Fall through */
10921 case 1:
10922 DECR_AND_STORE(18);
10923 }
10924
10925 if (do_s1) {
10926 DECR_AND_STORE(17);
10927 }
10928 if (do_s0) {
10929 DECR_AND_STORE(16);
10930 }
10931
10932 switch (aregs) {
10933 case 0:
10934 case 4:
10935 case 8:
10936 case 12:
10937 case 14:
10938 astatic = 0;
10939 break;
10940 case 1:
10941 case 5:
10942 case 9:
10943 case 13:
10944 astatic = 1;
10945 break;
10946 case 2:
10947 case 6:
10948 case 10:
10949 astatic = 2;
10950 break;
10951 case 3:
10952 case 7:
10953 astatic = 3;
10954 break;
10955 case 11:
10956 astatic = 4;
10957 break;
10958 default:
9c708c7f 10959 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
10960 return;
10961 }
10962
10963 if (astatic > 0) {
10964 DECR_AND_STORE(7);
10965 if (astatic > 1) {
10966 DECR_AND_STORE(6);
10967 if (astatic > 2) {
10968 DECR_AND_STORE(5);
10969 if (astatic > 3) {
10970 DECR_AND_STORE(4);
10971 }
10972 }
10973 }
10974 }
10975#undef DECR_AND_STORE
10976
c48245f0
MR
10977 tcg_gen_movi_tl(t2, -framesize);
10978 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10979 tcg_temp_free(t0);
10980 tcg_temp_free(t1);
c48245f0 10981 tcg_temp_free(t2);
364d4831
NF
10982}
10983
10984static void gen_mips16_restore (DisasContext *ctx,
10985 int xsregs, int aregs,
10986 int do_ra, int do_s0, int do_s1,
10987 int framesize)
10988{
10989 int astatic;
10990 TCGv t0 = tcg_temp_new();
10991 TCGv t1 = tcg_temp_new();
c48245f0 10992 TCGv t2 = tcg_temp_new();
364d4831 10993
c48245f0
MR
10994 tcg_gen_movi_tl(t2, framesize);
10995 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 10996
5f68f5ae 10997#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
10998 tcg_gen_movi_tl(t2, -4); \
10999 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11000 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11001 gen_store_gpr(t1, reg); \
364d4831
NF
11002 } while (0)
11003
11004 if (do_ra) {
11005 DECR_AND_LOAD(31);
11006 }
11007
11008 switch (xsregs) {
11009 case 7:
11010 DECR_AND_LOAD(30);
11011 /* Fall through */
11012 case 6:
11013 DECR_AND_LOAD(23);
11014 /* Fall through */
11015 case 5:
11016 DECR_AND_LOAD(22);
11017 /* Fall through */
11018 case 4:
11019 DECR_AND_LOAD(21);
11020 /* Fall through */
11021 case 3:
11022 DECR_AND_LOAD(20);
11023 /* Fall through */
11024 case 2:
11025 DECR_AND_LOAD(19);
11026 /* Fall through */
11027 case 1:
11028 DECR_AND_LOAD(18);
11029 }
11030
11031 if (do_s1) {
11032 DECR_AND_LOAD(17);
11033 }
11034 if (do_s0) {
11035 DECR_AND_LOAD(16);
11036 }
11037
11038 switch (aregs) {
11039 case 0:
11040 case 4:
11041 case 8:
11042 case 12:
11043 case 14:
11044 astatic = 0;
11045 break;
11046 case 1:
11047 case 5:
11048 case 9:
11049 case 13:
11050 astatic = 1;
11051 break;
11052 case 2:
11053 case 6:
11054 case 10:
11055 astatic = 2;
11056 break;
11057 case 3:
11058 case 7:
11059 astatic = 3;
11060 break;
11061 case 11:
11062 astatic = 4;
11063 break;
11064 default:
9c708c7f 11065 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11066 return;
11067 }
11068
11069 if (astatic > 0) {
11070 DECR_AND_LOAD(7);
11071 if (astatic > 1) {
11072 DECR_AND_LOAD(6);
11073 if (astatic > 2) {
11074 DECR_AND_LOAD(5);
11075 if (astatic > 3) {
11076 DECR_AND_LOAD(4);
11077 }
11078 }
11079 }
11080 }
11081#undef DECR_AND_LOAD
11082
c48245f0
MR
11083 tcg_gen_movi_tl(t2, framesize);
11084 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11085 tcg_temp_free(t0);
11086 tcg_temp_free(t1);
c48245f0 11087 tcg_temp_free(t2);
364d4831
NF
11088}
11089
11090static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11091 int is_64_bit, int extended)
11092{
11093 TCGv t0;
11094
11095 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11096 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11097 return;
11098 }
11099
11100 t0 = tcg_temp_new();
11101
11102 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11103 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11104 if (!is_64_bit) {
11105 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11106 }
11107
11108 tcg_temp_free(t0);
11109}
11110
11111#if defined(TARGET_MIPS64)
d75c135e 11112static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11113 int ry, int funct, int16_t offset,
11114 int extended)
11115{
11116 switch (funct) {
11117 case I64_LDSP:
d9224450 11118 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11119 check_mips_64(ctx);
11120 offset = extended ? offset : offset << 3;
d75c135e 11121 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11122 break;
11123 case I64_SDSP:
d9224450 11124 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11125 check_mips_64(ctx);
11126 offset = extended ? offset : offset << 3;
5c13fdfd 11127 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11128 break;
11129 case I64_SDRASP:
d9224450 11130 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11131 check_mips_64(ctx);
11132 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11133 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11134 break;
11135 case I64_DADJSP:
d9224450 11136 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11137 check_mips_64(ctx);
11138 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11139 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11140 break;
11141 case I64_LDPC:
d9224450
MR
11142 check_insn(ctx, ISA_MIPS3);
11143 check_mips_64(ctx);
364d4831 11144 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11145 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11146 } else {
11147 offset = extended ? offset : offset << 3;
d75c135e 11148 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11149 }
11150 break;
11151 case I64_DADDIU5:
d9224450 11152 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11153 check_mips_64(ctx);
11154 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11155 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11156 break;
11157 case I64_DADDIUPC:
d9224450 11158 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11159 check_mips_64(ctx);
11160 offset = extended ? offset : offset << 2;
11161 gen_addiupc(ctx, ry, offset, 1, extended);
11162 break;
11163 case I64_DADDIUSP:
d9224450 11164 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11165 check_mips_64(ctx);
11166 offset = extended ? offset : offset << 2;
d75c135e 11167 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11168 break;
11169 }
11170}
11171#endif
11172
240ce26a 11173static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11174{
895c2d04 11175 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11176 int op, rx, ry, funct, sa;
11177 int16_t imm, offset;
11178
11179 ctx->opcode = (ctx->opcode << 16) | extend;
11180 op = (ctx->opcode >> 11) & 0x1f;
11181 sa = (ctx->opcode >> 22) & 0x1f;
11182 funct = (ctx->opcode >> 8) & 0x7;
11183 rx = xlat((ctx->opcode >> 8) & 0x7);
11184 ry = xlat((ctx->opcode >> 5) & 0x7);
11185 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11186 | ((ctx->opcode >> 21) & 0x3f) << 5
11187 | (ctx->opcode & 0x1f));
11188
11189 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11190 counterparts. */
11191 switch (op) {
11192 case M16_OPC_ADDIUSP:
d75c135e 11193 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11194 break;
11195 case M16_OPC_ADDIUPC:
11196 gen_addiupc(ctx, rx, imm, 0, 1);
11197 break;
11198 case M16_OPC_B:
b231c103 11199 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11200 /* No delay slot, so just process as a normal instruction */
11201 break;
11202 case M16_OPC_BEQZ:
b231c103 11203 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11204 /* No delay slot, so just process as a normal instruction */
11205 break;
11206 case M16_OPC_BNEQZ:
b231c103 11207 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11208 /* No delay slot, so just process as a normal instruction */
11209 break;
11210 case M16_OPC_SHIFT:
11211 switch (ctx->opcode & 0x3) {
11212 case 0x0:
d75c135e 11213 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11214 break;
11215 case 0x1:
11216#if defined(TARGET_MIPS64)
11217 check_mips_64(ctx);
d75c135e 11218 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11219#else
9c708c7f 11220 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11221#endif
11222 break;
11223 case 0x2:
d75c135e 11224 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11225 break;
11226 case 0x3:
d75c135e 11227 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11228 break;
11229 }
11230 break;
11231#if defined(TARGET_MIPS64)
11232 case M16_OPC_LD:
d9224450 11233 check_insn(ctx, ISA_MIPS3);
d75de749 11234 check_mips_64(ctx);
d75c135e 11235 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11236 break;
11237#endif
11238 case M16_OPC_RRIA:
11239 imm = ctx->opcode & 0xf;
11240 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11241 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11242 imm = (int16_t) (imm << 1) >> 1;
11243 if ((ctx->opcode >> 4) & 0x1) {
11244#if defined(TARGET_MIPS64)
11245 check_mips_64(ctx);
d75c135e 11246 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11247#else
9c708c7f 11248 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11249#endif
11250 } else {
d75c135e 11251 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11252 }
11253 break;
11254 case M16_OPC_ADDIU8:
d75c135e 11255 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11256 break;
11257 case M16_OPC_SLTI:
d75c135e 11258 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11259 break;
11260 case M16_OPC_SLTIU:
d75c135e 11261 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11262 break;
11263 case M16_OPC_I8:
11264 switch (funct) {
11265 case I8_BTEQZ:
b231c103 11266 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11267 break;
11268 case I8_BTNEZ:
b231c103 11269 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11270 break;
11271 case I8_SWRASP:
5c13fdfd 11272 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11273 break;
11274 case I8_ADJSP:
d75c135e 11275 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11276 break;
11277 case I8_SVRS:
d9224450 11278 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11279 {
11280 int xsregs = (ctx->opcode >> 24) & 0x7;
11281 int aregs = (ctx->opcode >> 16) & 0xf;
11282 int do_ra = (ctx->opcode >> 6) & 0x1;
11283 int do_s0 = (ctx->opcode >> 5) & 0x1;
11284 int do_s1 = (ctx->opcode >> 4) & 0x1;
11285 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11286 | (ctx->opcode & 0xf)) << 3;
11287
11288 if (ctx->opcode & (1 << 7)) {
11289 gen_mips16_save(ctx, xsregs, aregs,
11290 do_ra, do_s0, do_s1,
11291 framesize);
11292 } else {
11293 gen_mips16_restore(ctx, xsregs, aregs,
11294 do_ra, do_s0, do_s1,
11295 framesize);
11296 }
11297 }
11298 break;
11299 default:
9c708c7f 11300 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11301 break;
11302 }
11303 break;
11304 case M16_OPC_LI:
11305 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11306 break;
11307 case M16_OPC_CMPI:
11308 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11309 break;
11310#if defined(TARGET_MIPS64)
11311 case M16_OPC_SD:
d9224450
MR
11312 check_insn(ctx, ISA_MIPS3);
11313 check_mips_64(ctx);
5c13fdfd 11314 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11315 break;
11316#endif
11317 case M16_OPC_LB:
d75c135e 11318 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11319 break;
11320 case M16_OPC_LH:
d75c135e 11321 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11322 break;
11323 case M16_OPC_LWSP:
d75c135e 11324 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11325 break;
11326 case M16_OPC_LW:
d75c135e 11327 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11328 break;
11329 case M16_OPC_LBU:
d75c135e 11330 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11331 break;
11332 case M16_OPC_LHU:
d75c135e 11333 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11334 break;
11335 case M16_OPC_LWPC:
d75c135e 11336 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11337 break;
11338#if defined(TARGET_MIPS64)
11339 case M16_OPC_LWU:
d9224450
MR
11340 check_insn(ctx, ISA_MIPS3);
11341 check_mips_64(ctx);
d75c135e 11342 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11343 break;
11344#endif
11345 case M16_OPC_SB:
5c13fdfd 11346 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11347 break;
11348 case M16_OPC_SH:
5c13fdfd 11349 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11350 break;
11351 case M16_OPC_SWSP:
5c13fdfd 11352 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11353 break;
11354 case M16_OPC_SW:
5c13fdfd 11355 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11356 break;
11357#if defined(TARGET_MIPS64)
11358 case M16_OPC_I64:
d75c135e 11359 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11360 break;
11361#endif
11362 default:
9c708c7f 11363 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11364 break;
11365 }
11366
11367 return 4;
11368}
11369
3b3c1694
LA
11370static inline bool is_uhi(int sdbbp_code)
11371{
11372#ifdef CONFIG_USER_ONLY
11373 return false;
11374#else
11375 return semihosting_enabled() && sdbbp_code == 1;
11376#endif
11377}
11378
240ce26a 11379static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11380{
11381 int rx, ry;
11382 int sa;
11383 int op, cnvt_op, op1, offset;
11384 int funct;
11385 int n_bytes;
11386
11387 op = (ctx->opcode >> 11) & 0x1f;
11388 sa = (ctx->opcode >> 2) & 0x7;
11389 sa = sa == 0 ? 8 : sa;
11390 rx = xlat((ctx->opcode >> 8) & 0x7);
11391 cnvt_op = (ctx->opcode >> 5) & 0x7;
11392 ry = xlat((ctx->opcode >> 5) & 0x7);
11393 op1 = offset = ctx->opcode & 0x1f;
11394
11395 n_bytes = 2;
11396
11397 switch (op) {
11398 case M16_OPC_ADDIUSP:
11399 {
11400 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11401
d75c135e 11402 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11403 }
11404 break;
11405 case M16_OPC_ADDIUPC:
11406 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11407 break;
11408 case M16_OPC_B:
11409 offset = (ctx->opcode & 0x7ff) << 1;
11410 offset = (int16_t)(offset << 4) >> 4;
b231c103 11411 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11412 /* No delay slot, so just process as a normal instruction */
11413 break;
11414 case M16_OPC_JAL:
895c2d04 11415 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11416 offset = (((ctx->opcode & 0x1f) << 21)
11417 | ((ctx->opcode >> 5) & 0x1f) << 16
11418 | offset) << 2;
b231c103
YK
11419 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11420 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11421 n_bytes = 4;
364d4831
NF
11422 break;
11423 case M16_OPC_BEQZ:
b231c103
YK
11424 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11425 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11426 /* No delay slot, so just process as a normal instruction */
11427 break;
11428 case M16_OPC_BNEQZ:
b231c103
YK
11429 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11430 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11431 /* No delay slot, so just process as a normal instruction */
11432 break;
11433 case M16_OPC_SHIFT:
11434 switch (ctx->opcode & 0x3) {
11435 case 0x0:
d75c135e 11436 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11437 break;
11438 case 0x1:
11439#if defined(TARGET_MIPS64)
d9224450 11440 check_insn(ctx, ISA_MIPS3);
364d4831 11441 check_mips_64(ctx);
d75c135e 11442 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11443#else
9c708c7f 11444 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11445#endif
11446 break;
11447 case 0x2:
d75c135e 11448 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11449 break;
11450 case 0x3:
d75c135e 11451 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11452 break;
11453 }
11454 break;
11455#if defined(TARGET_MIPS64)
11456 case M16_OPC_LD:
d9224450 11457 check_insn(ctx, ISA_MIPS3);
364d4831 11458 check_mips_64(ctx);
d75c135e 11459 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11460 break;
11461#endif
11462 case M16_OPC_RRIA:
11463 {
11464 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11465
11466 if ((ctx->opcode >> 4) & 1) {
11467#if defined(TARGET_MIPS64)
d9224450 11468 check_insn(ctx, ISA_MIPS3);
364d4831 11469 check_mips_64(ctx);
d75c135e 11470 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11471#else
9c708c7f 11472 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11473#endif
11474 } else {
d75c135e 11475 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11476 }
11477 }
11478 break;
11479 case M16_OPC_ADDIU8:
11480 {
11481 int16_t imm = (int8_t) ctx->opcode;
11482
d75c135e 11483 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11484 }
11485 break;
11486 case M16_OPC_SLTI:
11487 {
11488 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11489 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11490 }
11491 break;
11492 case M16_OPC_SLTIU:
11493 {
11494 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11495 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11496 }
11497 break;
11498 case M16_OPC_I8:
11499 {
11500 int reg32;
11501
11502 funct = (ctx->opcode >> 8) & 0x7;
11503 switch (funct) {
11504 case I8_BTEQZ:
11505 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11506 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11507 break;
11508 case I8_BTNEZ:
11509 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11510 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11511 break;
11512 case I8_SWRASP:
5c13fdfd 11513 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11514 break;
11515 case I8_ADJSP:
d75c135e 11516 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11517 ((int8_t)ctx->opcode) << 3);
11518 break;
11519 case I8_SVRS:
d9224450 11520 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11521 {
11522 int do_ra = ctx->opcode & (1 << 6);
11523 int do_s0 = ctx->opcode & (1 << 5);
11524 int do_s1 = ctx->opcode & (1 << 4);
11525 int framesize = ctx->opcode & 0xf;
11526
11527 if (framesize == 0) {
11528 framesize = 128;
11529 } else {
11530 framesize = framesize << 3;
11531 }
11532
11533 if (ctx->opcode & (1 << 7)) {
11534 gen_mips16_save(ctx, 0, 0,
11535 do_ra, do_s0, do_s1, framesize);
11536 } else {
11537 gen_mips16_restore(ctx, 0, 0,
11538 do_ra, do_s0, do_s1, framesize);
11539 }
11540 }
11541 break;
11542 case I8_MOV32R:
11543 {
11544 int rz = xlat(ctx->opcode & 0x7);
11545
11546 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11547 ((ctx->opcode >> 5) & 0x7);
d75c135e 11548 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11549 }
11550 break;
11551 case I8_MOVR32:
11552 reg32 = ctx->opcode & 0x1f;
d75c135e 11553 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11554 break;
11555 default:
9c708c7f 11556 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11557 break;
11558 }
11559 }
11560 break;
11561 case M16_OPC_LI:
11562 {
11563 int16_t imm = (uint8_t) ctx->opcode;
11564
d75c135e 11565 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11566 }
11567 break;
11568 case M16_OPC_CMPI:
11569 {
11570 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11571 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11572 }
11573 break;
11574#if defined(TARGET_MIPS64)
11575 case M16_OPC_SD:
d9224450 11576 check_insn(ctx, ISA_MIPS3);
364d4831 11577 check_mips_64(ctx);
5c13fdfd 11578 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11579 break;
11580#endif
11581 case M16_OPC_LB:
d75c135e 11582 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11583 break;
11584 case M16_OPC_LH:
d75c135e 11585 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11586 break;
11587 case M16_OPC_LWSP:
d75c135e 11588 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11589 break;
11590 case M16_OPC_LW:
d75c135e 11591 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11592 break;
11593 case M16_OPC_LBU:
d75c135e 11594 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11595 break;
11596 case M16_OPC_LHU:
d75c135e 11597 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11598 break;
11599 case M16_OPC_LWPC:
d75c135e 11600 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11601 break;
11602#if defined (TARGET_MIPS64)
11603 case M16_OPC_LWU:
d9224450 11604 check_insn(ctx, ISA_MIPS3);
364d4831 11605 check_mips_64(ctx);
d75c135e 11606 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11607 break;
11608#endif
11609 case M16_OPC_SB:
5c13fdfd 11610 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11611 break;
11612 case M16_OPC_SH:
5c13fdfd 11613 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11614 break;
11615 case M16_OPC_SWSP:
5c13fdfd 11616 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11617 break;
11618 case M16_OPC_SW:
5c13fdfd 11619 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11620 break;
11621 case M16_OPC_RRR:
11622 {
11623 int rz = xlat((ctx->opcode >> 2) & 0x7);
11624 int mips32_op;
11625
11626 switch (ctx->opcode & 0x3) {
11627 case RRR_ADDU:
11628 mips32_op = OPC_ADDU;
11629 break;
11630 case RRR_SUBU:
11631 mips32_op = OPC_SUBU;
11632 break;
11633#if defined(TARGET_MIPS64)
11634 case RRR_DADDU:
11635 mips32_op = OPC_DADDU;
d9224450 11636 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11637 check_mips_64(ctx);
11638 break;
11639 case RRR_DSUBU:
11640 mips32_op = OPC_DSUBU;
d9224450 11641 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11642 check_mips_64(ctx);
11643 break;
11644#endif
11645 default:
9c708c7f 11646 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11647 goto done;
11648 }
11649
d75c135e 11650 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11651 done:
11652 ;
11653 }
11654 break;
11655 case M16_OPC_RR:
11656 switch (op1) {
11657 case RR_JR:
11658 {
11659 int nd = (ctx->opcode >> 7) & 0x1;
11660 int link = (ctx->opcode >> 6) & 0x1;
11661 int ra = (ctx->opcode >> 5) & 0x1;
11662
d9224450
MR
11663 if (nd) {
11664 check_insn(ctx, ISA_MIPS32);
11665 }
11666
364d4831 11667 if (link) {
b231c103 11668 op = OPC_JALR;
364d4831
NF
11669 } else {
11670 op = OPC_JR;
11671 }
11672
b231c103
YK
11673 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11674 (nd ? 0 : 2));
364d4831
NF
11675 }
11676 break;
11677 case RR_SDBBP:
3b3c1694
LA
11678 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11679 gen_helper_do_semihosting(cpu_env);
11680 } else {
11681 /* XXX: not clear which exception should be raised
11682 * when in debug mode...
11683 */
11684 check_insn(ctx, ISA_MIPS32);
9c708c7f 11685 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 11686 }
364d4831
NF
11687 break;
11688 case RR_SLT:
d75c135e 11689 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11690 break;
11691 case RR_SLTU:
d75c135e 11692 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11693 break;
11694 case RR_BREAK:
9c708c7f 11695 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
11696 break;
11697 case RR_SLLV:
d75c135e 11698 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11699 break;
11700 case RR_SRLV:
d75c135e 11701 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11702 break;
11703 case RR_SRAV:
d75c135e 11704 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11705 break;
11706#if defined (TARGET_MIPS64)
11707 case RR_DSRL:
d9224450 11708 check_insn(ctx, ISA_MIPS3);
364d4831 11709 check_mips_64(ctx);
d75c135e 11710 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11711 break;
11712#endif
11713 case RR_CMP:
d75c135e 11714 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11715 break;
11716 case RR_NEG:
d75c135e 11717 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11718 break;
11719 case RR_AND:
d75c135e 11720 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11721 break;
11722 case RR_OR:
d75c135e 11723 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11724 break;
11725 case RR_XOR:
d75c135e 11726 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11727 break;
11728 case RR_NOT:
d75c135e 11729 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11730 break;
11731 case RR_MFHI:
26135ead 11732 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11733 break;
11734 case RR_CNVT:
d9224450 11735 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11736 switch (cnvt_op) {
11737 case RR_RY_CNVT_ZEB:
11738 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11739 break;
11740 case RR_RY_CNVT_ZEH:
11741 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11742 break;
11743 case RR_RY_CNVT_SEB:
11744 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11745 break;
11746 case RR_RY_CNVT_SEH:
11747 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11748 break;
11749#if defined (TARGET_MIPS64)
11750 case RR_RY_CNVT_ZEW:
d9224450 11751 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11752 check_mips_64(ctx);
11753 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11754 break;
11755 case RR_RY_CNVT_SEW:
d9224450 11756 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11757 check_mips_64(ctx);
11758 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11759 break;
11760#endif
11761 default:
9c708c7f 11762 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11763 break;
11764 }
11765 break;
11766 case RR_MFLO:
26135ead 11767 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11768 break;
11769#if defined (TARGET_MIPS64)
11770 case RR_DSRA:
d9224450 11771 check_insn(ctx, ISA_MIPS3);
364d4831 11772 check_mips_64(ctx);
d75c135e 11773 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11774 break;
11775 case RR_DSLLV:
d9224450 11776 check_insn(ctx, ISA_MIPS3);
364d4831 11777 check_mips_64(ctx);
d75c135e 11778 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11779 break;
11780 case RR_DSRLV:
d9224450 11781 check_insn(ctx, ISA_MIPS3);
364d4831 11782 check_mips_64(ctx);
d75c135e 11783 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11784 break;
11785 case RR_DSRAV:
d9224450 11786 check_insn(ctx, ISA_MIPS3);
364d4831 11787 check_mips_64(ctx);
d75c135e 11788 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11789 break;
11790#endif
11791 case RR_MULT:
26135ead 11792 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11793 break;
11794 case RR_MULTU:
26135ead 11795 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11796 break;
11797 case RR_DIV:
26135ead 11798 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11799 break;
11800 case RR_DIVU:
26135ead 11801 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11802 break;
11803#if defined (TARGET_MIPS64)
11804 case RR_DMULT:
d9224450 11805 check_insn(ctx, ISA_MIPS3);
364d4831 11806 check_mips_64(ctx);
26135ead 11807 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11808 break;
11809 case RR_DMULTU:
d9224450 11810 check_insn(ctx, ISA_MIPS3);
364d4831 11811 check_mips_64(ctx);
26135ead 11812 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11813 break;
11814 case RR_DDIV:
d9224450 11815 check_insn(ctx, ISA_MIPS3);
364d4831 11816 check_mips_64(ctx);
26135ead 11817 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11818 break;
11819 case RR_DDIVU:
d9224450 11820 check_insn(ctx, ISA_MIPS3);
364d4831 11821 check_mips_64(ctx);
26135ead 11822 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11823 break;
11824#endif
11825 default:
9c708c7f 11826 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11827 break;
11828 }
11829 break;
11830 case M16_OPC_EXTEND:
240ce26a 11831 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11832 n_bytes = 4;
11833 break;
11834#if defined(TARGET_MIPS64)
11835 case M16_OPC_I64:
11836 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11837 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11838 break;
11839#endif
11840 default:
9c708c7f 11841 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11842 break;
11843 }
11844
11845 return n_bytes;
11846}
11847
211da992 11848/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11849
211da992
CWR
11850/*
11851 * microMIPS32/microMIPS64 major opcodes
11852 *
11853 * 1. MIPS Architecture for Programmers Volume II-B:
11854 * The microMIPS32 Instruction Set (Revision 3.05)
11855 *
11856 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11857 *
11858 * 2. MIPS Architecture For Programmers Volume II-A:
11859 * The MIPS64 Instruction Set (Revision 3.51)
11860 */
6af0bf9c 11861
3c824109
NF
11862enum {
11863 POOL32A = 0x00,
11864 POOL16A = 0x01,
11865 LBU16 = 0x02,
11866 MOVE16 = 0x03,
11867 ADDI32 = 0x04,
3a1f4268
YK
11868 R6_LUI = 0x04,
11869 AUI = 0x04,
3c824109
NF
11870 LBU32 = 0x05,
11871 SB32 = 0x06,
11872 LB32 = 0x07,
11873
11874 POOL32B = 0x08,
11875 POOL16B = 0x09,
11876 LHU16 = 0x0a,
11877 ANDI16 = 0x0b,
11878 ADDIU32 = 0x0c,
11879 LHU32 = 0x0d,
11880 SH32 = 0x0e,
11881 LH32 = 0x0f,
11882
11883 POOL32I = 0x10,
11884 POOL16C = 0x11,
11885 LWSP16 = 0x12,
11886 POOL16D = 0x13,
11887 ORI32 = 0x14,
11888 POOL32F = 0x15,
211da992
CWR
11889 POOL32S = 0x16, /* MIPS64 */
11890 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
11891
11892 POOL32C = 0x18,
11893 LWGP16 = 0x19,
11894 LW16 = 0x1a,
11895 POOL16E = 0x1b,
11896 XORI32 = 0x1c,
11897 JALS32 = 0x1d,
3a1f4268
YK
11898 BOVC = 0x1d,
11899 BEQC = 0x1d,
11900 BEQZALC = 0x1d,
3c824109 11901 ADDIUPC = 0x1e,
3a1f4268
YK
11902 PCREL = 0x1e,
11903 BNVC = 0x1f,
11904 BNEC = 0x1f,
11905 BNEZALC = 0x1f,
3c824109 11906
3a1f4268
YK
11907 R6_BEQZC = 0x20,
11908 JIC = 0x20,
3c824109
NF
11909 POOL16F = 0x21,
11910 SB16 = 0x22,
11911 BEQZ16 = 0x23,
3a1f4268 11912 BEQZC16 = 0x23,
3c824109
NF
11913 SLTI32 = 0x24,
11914 BEQ32 = 0x25,
3a1f4268 11915 BC = 0x25,
3c824109
NF
11916 SWC132 = 0x26,
11917 LWC132 = 0x27,
11918
3a1f4268 11919 /* 0x29 is reserved */
3c824109 11920 RES_29 = 0x29,
3a1f4268
YK
11921 R6_BNEZC = 0x28,
11922 JIALC = 0x28,
3c824109
NF
11923 SH16 = 0x2a,
11924 BNEZ16 = 0x2b,
3a1f4268 11925 BNEZC16 = 0x2b,
3c824109
NF
11926 SLTIU32 = 0x2c,
11927 BNE32 = 0x2d,
3a1f4268 11928 BALC = 0x2d,
3c824109
NF
11929 SDC132 = 0x2e,
11930 LDC132 = 0x2f,
11931
3a1f4268 11932 /* 0x31 is reserved */
3c824109 11933 RES_31 = 0x31,
3a1f4268
YK
11934 BLEZALC = 0x30,
11935 BGEZALC = 0x30,
11936 BGEUC = 0x30,
3c824109
NF
11937 SWSP16 = 0x32,
11938 B16 = 0x33,
3a1f4268 11939 BC16 = 0x33,
3c824109
NF
11940 ANDI32 = 0x34,
11941 J32 = 0x35,
3a1f4268
YK
11942 BGTZC = 0x35,
11943 BLTZC = 0x35,
11944 BLTC = 0x35,
211da992
CWR
11945 SD32 = 0x36, /* MIPS64 */
11946 LD32 = 0x37, /* MIPS64 */
3c824109 11947
3a1f4268 11948 /* 0x39 is reserved */
3c824109 11949 RES_39 = 0x39,
3a1f4268
YK
11950 BGTZALC = 0x38,
11951 BLTZALC = 0x38,
11952 BLTUC = 0x38,
3c824109
NF
11953 SW16 = 0x3a,
11954 LI16 = 0x3b,
11955 JALX32 = 0x3c,
11956 JAL32 = 0x3d,
3a1f4268
YK
11957 BLEZC = 0x3d,
11958 BGEZC = 0x3d,
11959 BGEC = 0x3d,
3c824109
NF
11960 SW32 = 0x3e,
11961 LW32 = 0x3f
11962};
11963
3a1f4268
YK
11964/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
11965enum {
11966 ADDIUPC_00 = 0x00,
11967 ADDIUPC_07 = 0x07,
11968 AUIPC = 0x1e,
11969 ALUIPC = 0x1f,
11970 LWPC_08 = 0x08,
11971 LWPC_0F = 0x0F,
11972};
11973
3c824109
NF
11974/* POOL32A encoding of minor opcode field */
11975
11976enum {
11977 /* These opcodes are distinguished only by bits 9..6; those bits are
11978 * what are recorded below. */
11979 SLL32 = 0x0,
11980 SRL32 = 0x1,
11981 SRA = 0x2,
11982 ROTR = 0x3,
3a1f4268
YK
11983 SELEQZ = 0x5,
11984 SELNEZ = 0x6,
3c824109
NF
11985
11986 SLLV = 0x0,
11987 SRLV = 0x1,
11988 SRAV = 0x2,
11989 ROTRV = 0x3,
11990 ADD = 0x4,
11991 ADDU32 = 0x5,
11992 SUB = 0x6,
11993 SUBU32 = 0x7,
11994 MUL = 0x8,
11995 AND = 0x9,
11996 OR32 = 0xa,
11997 NOR = 0xb,
11998 XOR32 = 0xc,
11999 SLT = 0xd,
12000 SLTU = 0xe,
12001
12002 MOVN = 0x0,
3a1f4268 12003 R6_MUL = 0x0,
3c824109 12004 MOVZ = 0x1,
3a1f4268
YK
12005 MUH = 0x1,
12006 MULU = 0x2,
12007 MUHU = 0x3,
3c824109 12008 LWXS = 0x4,
3a1f4268
YK
12009 R6_DIV = 0x4,
12010 MOD = 0x5,
12011 R6_DIVU = 0x6,
12012 MODU = 0x7,
3c824109
NF
12013
12014 /* The following can be distinguished by their lower 6 bits. */
12015 INS = 0x0c,
3a1f4268
YK
12016 LSA = 0x0f,
12017 ALIGN = 0x1f,
3c824109
NF
12018 EXT = 0x2c,
12019 POOL32AXF = 0x3c
12020};
12021
12022/* POOL32AXF encoding of minor opcode field extension */
12023
d132c79f
CWR
12024/*
12025 * 1. MIPS Architecture for Programmers Volume II-B:
12026 * The microMIPS32 Instruction Set (Revision 3.05)
12027 *
12028 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12029 *
12030 * 2. MIPS Architecture for Programmers VolumeIV-e:
12031 * The MIPS DSP Application-Specific Extension
12032 * to the microMIPS32 Architecture (Revision 2.34)
12033 *
12034 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12035 */
12036
3c824109
NF
12037enum {
12038 /* bits 11..6 */
12039 TEQ = 0x00,
12040 TGE = 0x08,
12041 TGEU = 0x10,
12042 TLT = 0x20,
12043 TLTU = 0x28,
12044 TNE = 0x30,
12045
12046 MFC0 = 0x03,
12047 MTC0 = 0x0b,
12048
d132c79f
CWR
12049 /* begin of microMIPS32 DSP */
12050
3c824109
NF
12051 /* bits 13..12 for 0x01 */
12052 MFHI_ACC = 0x0,
12053 MFLO_ACC = 0x1,
12054 MTHI_ACC = 0x2,
12055 MTLO_ACC = 0x3,
12056
12057 /* bits 13..12 for 0x2a */
12058 MADD_ACC = 0x0,
12059 MADDU_ACC = 0x1,
12060 MSUB_ACC = 0x2,
12061 MSUBU_ACC = 0x3,
12062
12063 /* bits 13..12 for 0x32 */
12064 MULT_ACC = 0x0,
6801038b 12065 MULTU_ACC = 0x1,
3c824109 12066
d132c79f
CWR
12067 /* end of microMIPS32 DSP */
12068
3c824109 12069 /* bits 15..12 for 0x2c */
3a1f4268 12070 BITSWAP = 0x0,
3c824109
NF
12071 SEB = 0x2,
12072 SEH = 0x3,
12073 CLO = 0x4,
12074 CLZ = 0x5,
12075 RDHWR = 0x6,
12076 WSBH = 0x7,
12077 MULT = 0x8,
12078 MULTU = 0x9,
12079 DIV = 0xa,
12080 DIVU = 0xb,
12081 MADD = 0xc,
12082 MADDU = 0xd,
12083 MSUB = 0xe,
12084 MSUBU = 0xf,
12085
12086 /* bits 15..12 for 0x34 */
12087 MFC2 = 0x4,
12088 MTC2 = 0x5,
12089 MFHC2 = 0x8,
12090 MTHC2 = 0x9,
12091 CFC2 = 0xc,
12092 CTC2 = 0xd,
12093
12094 /* bits 15..12 for 0x3c */
12095 JALR = 0x0,
12096 JR = 0x0, /* alias */
3a1f4268
YK
12097 JALRC = 0x0,
12098 JRC = 0x0,
3c824109 12099 JALR_HB = 0x1,
3a1f4268 12100 JALRC_HB = 0x1,
3c824109
NF
12101 JALRS = 0x4,
12102 JALRS_HB = 0x5,
12103
12104 /* bits 15..12 for 0x05 */
12105 RDPGPR = 0xe,
12106 WRPGPR = 0xf,
12107
12108 /* bits 15..12 for 0x0d */
12109 TLBP = 0x0,
12110 TLBR = 0x1,
12111 TLBWI = 0x2,
12112 TLBWR = 0x3,
e60ec063
YK
12113 TLBINV = 0x4,
12114 TLBINVF = 0x5,
3c824109
NF
12115 WAIT = 0x9,
12116 IRET = 0xd,
12117 DERET = 0xe,
12118 ERET = 0xf,
12119
12120 /* bits 15..12 for 0x15 */
12121 DMT = 0x0,
12122 DVPE = 0x1,
12123 EMT = 0x2,
12124 EVPE = 0x3,
12125
12126 /* bits 15..12 for 0x1d */
12127 DI = 0x4,
12128 EI = 0x5,
12129
12130 /* bits 15..12 for 0x2d */
12131 SYNC = 0x6,
12132 SYSCALL = 0x8,
12133 SDBBP = 0xd,
12134
12135 /* bits 15..12 for 0x35 */
12136 MFHI32 = 0x0,
12137 MFLO32 = 0x1,
12138 MTHI32 = 0x2,
12139 MTLO32 = 0x3,
12140};
12141
12142/* POOL32B encoding of minor opcode field (bits 15..12) */
12143
12144enum {
12145 LWC2 = 0x0,
12146 LWP = 0x1,
12147 LDP = 0x4,
12148 LWM32 = 0x5,
12149 CACHE = 0x6,
12150 LDM = 0x7,
12151 SWC2 = 0x8,
12152 SWP = 0x9,
12153 SDP = 0xc,
12154 SWM32 = 0xd,
12155 SDM = 0xf
12156};
12157
12158/* POOL32C encoding of minor opcode field (bits 15..12) */
12159
12160enum {
12161 LWL = 0x0,
12162 SWL = 0x8,
12163 LWR = 0x1,
12164 SWR = 0x9,
12165 PREF = 0x2,
12166 /* 0xa is reserved */
12167 LL = 0x3,
12168 SC = 0xb,
12169 LDL = 0x4,
12170 SDL = 0xc,
12171 LDR = 0x5,
12172 SDR = 0xd,
12173 /* 0x6 is reserved */
12174 LWU = 0xe,
12175 LLD = 0x7,
12176 SCD = 0xf
12177};
12178
12179/* POOL32F encoding of minor opcode field (bits 5..0) */
12180
12181enum {
12182 /* These are the bit 7..6 values */
12183 ADD_FMT = 0x0,
3c824109
NF
12184
12185 SUB_FMT = 0x1,
3c824109
NF
12186
12187 MUL_FMT = 0x2,
12188
12189 DIV_FMT = 0x3,
12190
12191 /* These are the bit 8..6 values */
3a1f4268 12192 MOVN_FMT = 0x0,
3c824109
NF
12193 RSQRT2_FMT = 0x0,
12194 MOVF_FMT = 0x0,
3a1f4268
YK
12195 RINT_FMT = 0x0,
12196 SELNEZ_FMT = 0x0,
3c824109 12197
3a1f4268 12198 MOVZ_FMT = 0x1,
3c824109
NF
12199 LWXC1 = 0x1,
12200 MOVT_FMT = 0x1,
3a1f4268
YK
12201 CLASS_FMT = 0x1,
12202 SELEQZ_FMT = 0x1,
3c824109
NF
12203
12204 PLL_PS = 0x2,
12205 SWXC1 = 0x2,
3a1f4268 12206 SEL_FMT = 0x2,
3c824109
NF
12207
12208 PLU_PS = 0x3,
12209 LDXC1 = 0x3,
12210
3a1f4268 12211 MOVN_FMT_04 = 0x4,
3c824109
NF
12212 PUL_PS = 0x4,
12213 SDXC1 = 0x4,
12214 RECIP2_FMT = 0x4,
12215
3a1f4268 12216 MOVZ_FMT_05 = 0x05,
3c824109
NF
12217 PUU_PS = 0x5,
12218 LUXC1 = 0x5,
12219
12220 CVT_PS_S = 0x6,
12221 SUXC1 = 0x6,
12222 ADDR_PS = 0x6,
12223 PREFX = 0x6,
3a1f4268 12224 MADDF_FMT = 0x6,
3c824109
NF
12225
12226 MULR_PS = 0x7,
3a1f4268 12227 MSUBF_FMT = 0x7,
3c824109
NF
12228
12229 MADD_S = 0x01,
12230 MADD_D = 0x09,
12231 MADD_PS = 0x11,
12232 ALNV_PS = 0x19,
12233 MSUB_S = 0x21,
12234 MSUB_D = 0x29,
12235 MSUB_PS = 0x31,
12236
12237 NMADD_S = 0x02,
12238 NMADD_D = 0x0a,
12239 NMADD_PS = 0x12,
12240 NMSUB_S = 0x22,
12241 NMSUB_D = 0x2a,
12242 NMSUB_PS = 0x32,
12243
3a1f4268
YK
12244 MIN_FMT = 0x3,
12245 MAX_FMT = 0xb,
12246 MINA_FMT = 0x23,
12247 MAXA_FMT = 0x2b,
3c824109
NF
12248 POOL32FXF = 0x3b,
12249
12250 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12251 C_COND_FMT = 0x3c,
12252
12253 CMP_CONDN_S = 0x5,
12254 CMP_CONDN_D = 0x15
3c824109
NF
12255};
12256
12257/* POOL32Fxf encoding of minor opcode extension field */
12258
12259enum {
12260 CVT_L = 0x04,
12261 RSQRT_FMT = 0x08,
12262 FLOOR_L = 0x0c,
12263 CVT_PW_PS = 0x1c,
12264 CVT_W = 0x24,
12265 SQRT_FMT = 0x28,
12266 FLOOR_W = 0x2c,
12267 CVT_PS_PW = 0x3c,
12268 CFC1 = 0x40,
12269 RECIP_FMT = 0x48,
12270 CEIL_L = 0x4c,
12271 CTC1 = 0x60,
12272 CEIL_W = 0x6c,
12273 MFC1 = 0x80,
12274 CVT_S_PL = 0x84,
12275 TRUNC_L = 0x8c,
12276 MTC1 = 0xa0,
12277 CVT_S_PU = 0xa4,
12278 TRUNC_W = 0xac,
12279 MFHC1 = 0xc0,
12280 ROUND_L = 0xcc,
12281 MTHC1 = 0xe0,
12282 ROUND_W = 0xec,
12283
12284 MOV_FMT = 0x01,
12285 MOVF = 0x05,
12286 ABS_FMT = 0x0d,
12287 RSQRT1_FMT = 0x1d,
12288 MOVT = 0x25,
12289 NEG_FMT = 0x2d,
12290 CVT_D = 0x4d,
12291 RECIP1_FMT = 0x5d,
12292 CVT_S = 0x6d
12293};
12294
12295/* POOL32I encoding of minor opcode field (bits 25..21) */
12296
12297enum {
12298 BLTZ = 0x00,
12299 BLTZAL = 0x01,
12300 BGEZ = 0x02,
12301 BGEZAL = 0x03,
12302 BLEZ = 0x04,
12303 BNEZC = 0x05,
12304 BGTZ = 0x06,
12305 BEQZC = 0x07,
12306 TLTI = 0x08,
3a1f4268 12307 BC1EQZC = 0x08,
3c824109 12308 TGEI = 0x09,
3a1f4268 12309 BC1NEZC = 0x09,
3c824109 12310 TLTIU = 0x0a,
3a1f4268 12311 BC2EQZC = 0x0a,
3c824109 12312 TGEIU = 0x0b,
3a1f4268 12313 BC2NEZC = 0x0a,
3c824109 12314 TNEI = 0x0c,
3a1f4268 12315 R6_SYNCI = 0x0c,
3c824109
NF
12316 LUI = 0x0d,
12317 TEQI = 0x0e,
12318 SYNCI = 0x10,
12319 BLTZALS = 0x11,
12320 BGEZALS = 0x13,
12321 BC2F = 0x14,
12322 BC2T = 0x15,
12323 BPOSGE64 = 0x1a,
12324 BPOSGE32 = 0x1b,
12325 /* These overlap and are distinguished by bit16 of the instruction */
12326 BC1F = 0x1c,
12327 BC1T = 0x1d,
12328 BC1ANY2F = 0x1c,
12329 BC1ANY2T = 0x1d,
12330 BC1ANY4F = 0x1e,
12331 BC1ANY4T = 0x1f
12332};
12333
12334/* POOL16A encoding of minor opcode field */
12335
12336enum {
12337 ADDU16 = 0x0,
12338 SUBU16 = 0x1
12339};
12340
12341/* POOL16B encoding of minor opcode field */
12342
12343enum {
12344 SLL16 = 0x0,
12345 SRL16 = 0x1
12346};
12347
12348/* POOL16C encoding of minor opcode field */
12349
12350enum {
12351 NOT16 = 0x00,
12352 XOR16 = 0x04,
12353 AND16 = 0x08,
12354 OR16 = 0x0c,
12355 LWM16 = 0x10,
12356 SWM16 = 0x14,
12357 JR16 = 0x18,
12358 JRC16 = 0x1a,
12359 JALR16 = 0x1c,
12360 JALR16S = 0x1e,
12361 MFHI16 = 0x20,
12362 MFLO16 = 0x24,
12363 BREAK16 = 0x28,
12364 SDBBP16 = 0x2c,
12365 JRADDIUSP = 0x30
12366};
12367
3a1f4268
YK
12368/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12369
12370enum {
12371 R6_NOT16 = 0x00,
12372 R6_AND16 = 0x01,
12373 R6_LWM16 = 0x02,
12374 R6_JRC16 = 0x03,
12375 MOVEP = 0x04,
12376 MOVEP_07 = 0x07,
12377 R6_XOR16 = 0x08,
12378 R6_OR16 = 0x09,
12379 R6_SWM16 = 0x0a,
12380 JALRC16 = 0x0b,
12381 MOVEP_0C = 0x0c,
12382 MOVEP_0F = 0x0f,
12383 JRCADDIUSP = 0x13,
12384 R6_BREAK16 = 0x1b,
12385 R6_SDBBP16 = 0x3b
12386};
12387
3c824109
NF
12388/* POOL16D encoding of minor opcode field */
12389
12390enum {
12391 ADDIUS5 = 0x0,
12392 ADDIUSP = 0x1
12393};
12394
12395/* POOL16E encoding of minor opcode field */
12396
12397enum {
12398 ADDIUR2 = 0x0,
12399 ADDIUR1SP = 0x1
12400};
12401
12402static int mmreg (int r)
12403{
12404 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12405
12406 return map[r];
12407}
12408
12409/* Used for 16-bit store instructions. */
12410static int mmreg2 (int r)
12411{
12412 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12413
12414 return map[r];
12415}
12416
12417#define uMIPS_RD(op) ((op >> 7) & 0x7)
12418#define uMIPS_RS(op) ((op >> 4) & 0x7)
12419#define uMIPS_RS2(op) uMIPS_RS(op)
12420#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12421#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12422#define uMIPS_RS5(op) (op & 0x1f)
12423
12424/* Signed immediate */
12425#define SIMM(op, start, width) \
12426 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12427 << (32-width)) \
12428 >> (32-width))
12429/* Zero-extended immediate */
12430#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12431
d75c135e 12432static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12433{
12434 int rd = mmreg(uMIPS_RD(ctx->opcode));
12435
d75c135e 12436 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12437}
12438
d75c135e 12439static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12440{
12441 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12442 int rd = mmreg(uMIPS_RD(ctx->opcode));
12443 int rs = mmreg(uMIPS_RS(ctx->opcode));
12444
d75c135e 12445 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12446}
12447
d75c135e 12448static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12449{
12450 int encoded = ZIMM(ctx->opcode, 1, 9);
12451 int decoded;
12452
12453 if (encoded <= 1) {
12454 decoded = 256 + encoded;
12455 } else if (encoded <= 255) {
12456 decoded = encoded;
12457 } else if (encoded <= 509) {
12458 decoded = encoded - 512;
12459 } else {
12460 decoded = encoded - 768;
12461 }
12462
d75c135e 12463 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12464}
12465
d75c135e 12466static void gen_addius5(DisasContext *ctx)
3c824109
NF
12467{
12468 int imm = SIMM(ctx->opcode, 1, 4);
12469 int rd = (ctx->opcode >> 5) & 0x1f;
12470
d75c135e 12471 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12472}
12473
d75c135e 12474static void gen_andi16(DisasContext *ctx)
3c824109
NF
12475{
12476 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12477 31, 32, 63, 64, 255, 32768, 65535 };
12478 int rd = mmreg(uMIPS_RD(ctx->opcode));
12479 int rs = mmreg(uMIPS_RS(ctx->opcode));
12480 int encoded = ZIMM(ctx->opcode, 0, 4);
12481
d75c135e 12482 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12483}
12484
12485static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12486 int base, int16_t offset)
12487{
12488 TCGv t0, t1;
12489 TCGv_i32 t2;
12490
12491 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12492 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12493 return;
12494 }
12495
12496 t0 = tcg_temp_new();
12497
12498 gen_base_offset_addr(ctx, t0, base, offset);
12499
12500 t1 = tcg_const_tl(reglist);
12501 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12502
3c824109
NF
12503 save_cpu_state(ctx, 1);
12504 switch (opc) {
12505 case LWM32:
895c2d04 12506 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12507 break;
12508 case SWM32:
895c2d04 12509 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12510 break;
12511#ifdef TARGET_MIPS64
12512 case LDM:
895c2d04 12513 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12514 break;
12515 case SDM:
895c2d04 12516 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12517 break;
6af0bf9c 12518#endif
3c824109 12519 }
3c824109 12520 tcg_temp_free(t0);
33087598 12521 tcg_temp_free(t1);
3c824109
NF
12522 tcg_temp_free_i32(t2);
12523}
6af0bf9c 12524
3c824109 12525
240ce26a 12526static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12527{
3c824109
NF
12528 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12529 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12530
3c824109
NF
12531 switch (((ctx->opcode) >> 4) & 0x3f) {
12532 case NOT16 + 0:
12533 case NOT16 + 1:
12534 case NOT16 + 2:
12535 case NOT16 + 3:
d75c135e 12536 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12537 break;
12538 case XOR16 + 0:
12539 case XOR16 + 1:
12540 case XOR16 + 2:
12541 case XOR16 + 3:
d75c135e 12542 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12543 break;
12544 case AND16 + 0:
12545 case AND16 + 1:
12546 case AND16 + 2:
12547 case AND16 + 3:
d75c135e 12548 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12549 break;
12550 case OR16 + 0:
12551 case OR16 + 1:
12552 case OR16 + 2:
12553 case OR16 + 3:
d75c135e 12554 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12555 break;
12556 case LWM16 + 0:
12557 case LWM16 + 1:
12558 case LWM16 + 2:
12559 case LWM16 + 3:
12560 {
12561 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12562 int offset = ZIMM(ctx->opcode, 0, 4);
12563
12564 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12565 29, offset << 2);
12566 }
12567 break;
12568 case SWM16 + 0:
12569 case SWM16 + 1:
12570 case SWM16 + 2:
12571 case SWM16 + 3:
12572 {
12573 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12574 int offset = ZIMM(ctx->opcode, 0, 4);
12575
12576 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12577 29, offset << 2);
12578 }
12579 break;
12580 case JR16 + 0:
12581 case JR16 + 1:
12582 {
12583 int reg = ctx->opcode & 0x1f;
12584
b231c103 12585 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12586 }
3c824109
NF
12587 break;
12588 case JRC16 + 0:
12589 case JRC16 + 1:
12590 {
12591 int reg = ctx->opcode & 0x1f;
b231c103 12592 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12593 /* Let normal delay slot handling in our caller take us
12594 to the branch target. */
12595 }
12596 break;
12597 case JALR16 + 0:
12598 case JALR16 + 1:
b231c103
YK
12599 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12600 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12601 break;
3c824109
NF
12602 case JALR16S + 0:
12603 case JALR16S + 1:
b231c103
YK
12604 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12605 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12606 break;
12607 case MFHI16 + 0:
12608 case MFHI16 + 1:
26135ead 12609 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12610 break;
12611 case MFLO16 + 0:
12612 case MFLO16 + 1:
26135ead 12613 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12614 break;
12615 case BREAK16:
9c708c7f 12616 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
12617 break;
12618 case SDBBP16:
3b3c1694
LA
12619 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12620 gen_helper_do_semihosting(cpu_env);
12621 } else {
12622 /* XXX: not clear which exception should be raised
12623 * when in debug mode...
12624 */
12625 check_insn(ctx, ISA_MIPS32);
9c708c7f 12626 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12627 }
3c824109
NF
12628 break;
12629 case JRADDIUSP + 0:
12630 case JRADDIUSP + 1:
12631 {
12632 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12633 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12634 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12635 /* Let normal delay slot handling in our caller take us
12636 to the branch target. */
12637 }
12638 break;
12639 default:
9c708c7f 12640 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12641 break;
12642 }
12643}
12644
ed7ce6c0
YK
12645static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12646 int enc_rs)
12647{
12648 int rd, rs, re, rt;
12649 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12650 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12651 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12652 rd = rd_enc[enc_dest];
12653 re = re_enc[enc_dest];
12654 rs = rs_rt_enc[enc_rs];
12655 rt = rs_rt_enc[enc_rt];
12656 if (rs) {
12657 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12658 } else {
12659 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12660 }
12661 if (rt) {
12662 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12663 } else {
12664 tcg_gen_movi_tl(cpu_gpr[re], 0);
12665 }
12666}
12667
12668static void gen_pool16c_r6_insn(DisasContext *ctx)
12669{
12670 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12671 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12672
12673 switch (ctx->opcode & 0xf) {
12674 case R6_NOT16:
12675 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12676 break;
12677 case R6_AND16:
12678 gen_logic(ctx, OPC_AND, rt, rt, rs);
12679 break;
12680 case R6_LWM16:
12681 {
12682 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12683 int offset = extract32(ctx->opcode, 4, 4);
12684 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12685 }
12686 break;
12687 case R6_JRC16: /* JRCADDIUSP */
12688 if ((ctx->opcode >> 4) & 1) {
12689 /* JRCADDIUSP */
12690 int imm = extract32(ctx->opcode, 5, 5);
12691 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12692 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12693 } else {
12694 /* JRC16 */
12695 int rs = extract32(ctx->opcode, 5, 5);
12696 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12697 }
12698 break;
12699 case MOVEP ... MOVEP_07:
12700 case MOVEP_0C ... MOVEP_0F:
12701 {
12702 int enc_dest = uMIPS_RD(ctx->opcode);
12703 int enc_rt = uMIPS_RS2(ctx->opcode);
12704 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12705 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12706 }
12707 break;
12708 case R6_XOR16:
12709 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12710 break;
12711 case R6_OR16:
12712 gen_logic(ctx, OPC_OR, rt, rt, rs);
12713 break;
12714 case R6_SWM16:
12715 {
12716 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12717 int offset = extract32(ctx->opcode, 4, 4);
12718 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12719 }
12720 break;
12721 case JALRC16: /* BREAK16, SDBBP16 */
12722 switch (ctx->opcode & 0x3f) {
12723 case JALRC16:
12724 case JALRC16 + 0x20:
12725 /* JALRC16 */
12726 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12727 31, 0, 0);
12728 break;
12729 case R6_BREAK16:
12730 /* BREAK16 */
12731 generate_exception(ctx, EXCP_BREAK);
12732 break;
12733 case R6_SDBBP16:
12734 /* SDBBP16 */
060ebfef
LA
12735 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12736 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 12737 } else {
060ebfef
LA
12738 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12739 generate_exception(ctx, EXCP_RI);
12740 } else {
12741 generate_exception(ctx, EXCP_DBp);
12742 }
ed7ce6c0
YK
12743 }
12744 break;
12745 }
12746 break;
12747 default:
12748 generate_exception(ctx, EXCP_RI);
12749 break;
12750 }
12751}
12752
3c824109
NF
12753static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12754{
12755 TCGv t0 = tcg_temp_new();
12756 TCGv t1 = tcg_temp_new();
12757
12758 gen_load_gpr(t0, base);
12759
12760 if (index != 0) {
12761 gen_load_gpr(t1, index);
12762 tcg_gen_shli_tl(t1, t1, 2);
12763 gen_op_addr_add(ctx, t0, t1, t0);
12764 }
12765
5f68f5ae 12766 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12767 gen_store_gpr(t1, rd);
12768
12769 tcg_temp_free(t0);
12770 tcg_temp_free(t1);
12771}
12772
12773static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12774 int base, int16_t offset)
12775{
3c824109
NF
12776 TCGv t0, t1;
12777
36c6711b 12778 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 12779 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
12780 return;
12781 }
12782
3c824109
NF
12783 t0 = tcg_temp_new();
12784 t1 = tcg_temp_new();
8e9ade68 12785
3c824109
NF
12786 gen_base_offset_addr(ctx, t0, base, offset);
12787
12788 switch (opc) {
12789 case LWP:
36c6711b 12790 if (rd == base) {
9c708c7f 12791 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12792 return;
12793 }
5f68f5ae 12794 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12795 gen_store_gpr(t1, rd);
12796 tcg_gen_movi_tl(t1, 4);
12797 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12798 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 12799 gen_store_gpr(t1, rd+1);
3c824109
NF
12800 break;
12801 case SWP:
3c824109 12802 gen_load_gpr(t1, rd);
5f68f5ae 12803 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12804 tcg_gen_movi_tl(t1, 4);
12805 gen_op_addr_add(ctx, t0, t0, t1);
12806 gen_load_gpr(t1, rd+1);
5f68f5ae 12807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12808 break;
12809#ifdef TARGET_MIPS64
12810 case LDP:
36c6711b 12811 if (rd == base) {
9c708c7f 12812 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12813 return;
12814 }
5f68f5ae 12815 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12816 gen_store_gpr(t1, rd);
12817 tcg_gen_movi_tl(t1, 8);
12818 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12819 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 12820 gen_store_gpr(t1, rd+1);
3c824109
NF
12821 break;
12822 case SDP:
3c824109 12823 gen_load_gpr(t1, rd);
5f68f5ae 12824 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12825 tcg_gen_movi_tl(t1, 8);
12826 gen_op_addr_add(ctx, t0, t0, t1);
12827 gen_load_gpr(t1, rd+1);
5f68f5ae 12828 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12829 break;
12830#endif
6af0bf9c 12831 }
3c824109
NF
12832 tcg_temp_free(t0);
12833 tcg_temp_free(t1);
12834}
618b0fe9 12835
240ce26a 12836static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12837{
12838 int extension = (ctx->opcode >> 6) & 0x3f;
12839 int minor = (ctx->opcode >> 12) & 0xf;
12840 uint32_t mips32_op;
12841
12842 switch (extension) {
12843 case TEQ:
12844 mips32_op = OPC_TEQ;
12845 goto do_trap;
12846 case TGE:
12847 mips32_op = OPC_TGE;
12848 goto do_trap;
12849 case TGEU:
12850 mips32_op = OPC_TGEU;
12851 goto do_trap;
12852 case TLT:
12853 mips32_op = OPC_TLT;
12854 goto do_trap;
12855 case TLTU:
12856 mips32_op = OPC_TLTU;
12857 goto do_trap;
12858 case TNE:
12859 mips32_op = OPC_TNE;
12860 do_trap:
12861 gen_trap(ctx, mips32_op, rs, rt, -1);
12862 break;
12863#ifndef CONFIG_USER_ONLY
12864 case MFC0:
12865 case MFC0 + 32:
2e15497c 12866 check_cp0_enabled(ctx);
3c824109
NF
12867 if (rt == 0) {
12868 /* Treat as NOP. */
12869 break;
12870 }
d75c135e 12871 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12872 break;
12873 case MTC0:
12874 case MTC0 + 32:
2e15497c 12875 check_cp0_enabled(ctx);
3c824109
NF
12876 {
12877 TCGv t0 = tcg_temp_new();
618b0fe9 12878
3c824109 12879 gen_load_gpr(t0, rt);
d75c135e 12880 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12881 tcg_temp_free(t0);
12882 }
12883 break;
12884#endif
a1fc6246
LA
12885 case 0x2a:
12886 switch (minor & 3) {
12887 case MADD_ACC:
12888 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12889 break;
12890 case MADDU_ACC:
12891 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12892 break;
12893 case MSUB_ACC:
12894 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12895 break;
12896 case MSUBU_ACC:
12897 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12898 break;
12899 default:
12900 goto pool32axf_invalid;
12901 }
12902 break;
12903 case 0x32:
12904 switch (minor & 3) {
12905 case MULT_ACC:
12906 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12907 break;
12908 case MULTU_ACC:
12909 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12910 break;
12911 default:
12912 goto pool32axf_invalid;
12913 }
12914 break;
3c824109
NF
12915 case 0x2c:
12916 switch (minor) {
e0332095
YK
12917 case BITSWAP:
12918 check_insn(ctx, ISA_MIPS32R6);
12919 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
12920 break;
3c824109
NF
12921 case SEB:
12922 gen_bshfl(ctx, OPC_SEB, rs, rt);
12923 break;
12924 case SEH:
12925 gen_bshfl(ctx, OPC_SEH, rs, rt);
12926 break;
12927 case CLO:
12928 mips32_op = OPC_CLO;
12929 goto do_cl;
12930 case CLZ:
12931 mips32_op = OPC_CLZ;
12932 do_cl:
d75c135e 12933 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12934 gen_cl(ctx, mips32_op, rt, rs);
12935 break;
12936 case RDHWR:
d75c135e 12937 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12938 break;
12939 case WSBH:
12940 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12941 break;
12942 case MULT:
9e8f441a 12943 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12944 mips32_op = OPC_MULT;
26135ead 12945 goto do_mul;
3c824109 12946 case MULTU:
9e8f441a 12947 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12948 mips32_op = OPC_MULTU;
26135ead 12949 goto do_mul;
3c824109 12950 case DIV:
9e8f441a 12951 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12952 mips32_op = OPC_DIV;
26135ead 12953 goto do_div;
3c824109 12954 case DIVU:
9e8f441a 12955 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12956 mips32_op = OPC_DIVU;
26135ead
RS
12957 goto do_div;
12958 do_div:
12959 check_insn(ctx, ISA_MIPS32);
12960 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12961 break;
3c824109 12962 case MADD:
9e8f441a 12963 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12964 mips32_op = OPC_MADD;
26135ead 12965 goto do_mul;
3c824109 12966 case MADDU:
9e8f441a 12967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12968 mips32_op = OPC_MADDU;
26135ead 12969 goto do_mul;
3c824109 12970 case MSUB:
9e8f441a 12971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12972 mips32_op = OPC_MSUB;
26135ead 12973 goto do_mul;
3c824109 12974 case MSUBU:
9e8f441a 12975 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12976 mips32_op = OPC_MSUBU;
26135ead 12977 do_mul:
d75c135e 12978 check_insn(ctx, ISA_MIPS32);
a1fc6246 12979 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12980 break;
12981 default:
12982 goto pool32axf_invalid;
12983 }
12984 break;
12985 case 0x34:
12986 switch (minor) {
12987 case MFC2:
12988 case MTC2:
12989 case MFHC2:
12990 case MTHC2:
12991 case CFC2:
12992 case CTC2:
12993 generate_exception_err(ctx, EXCP_CpU, 2);
12994 break;
12995 default:
12996 goto pool32axf_invalid;
12997 }
12998 break;
12999 case 0x3c:
13000 switch (minor) {
65935f07
YK
13001 case JALR: /* JALRC */
13002 case JALR_HB: /* JALRC_HB */
13003 if (ctx->insn_flags & ISA_MIPS32R6) {
13004 /* JALRC, JALRC_HB */
13005 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13006 } else {
13007 /* JALR, JALR_HB */
13008 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13009 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13010 }
3c824109
NF
13011 break;
13012 case JALRS:
13013 case JALRS_HB:
9e8f441a 13014 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13015 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13016 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13017 break;
13018 default:
13019 goto pool32axf_invalid;
13020 }
13021 break;
13022 case 0x05:
13023 switch (minor) {
13024 case RDPGPR:
2e15497c 13025 check_cp0_enabled(ctx);
d75c135e 13026 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13027 gen_load_srsgpr(rs, rt);
3c824109
NF
13028 break;
13029 case WRPGPR:
2e15497c 13030 check_cp0_enabled(ctx);
d75c135e 13031 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13032 gen_store_srsgpr(rs, rt);
3c824109
NF
13033 break;
13034 default:
13035 goto pool32axf_invalid;
13036 }
13037 break;
13038#ifndef CONFIG_USER_ONLY
13039 case 0x0d:
13040 switch (minor) {
13041 case TLBP:
13042 mips32_op = OPC_TLBP;
13043 goto do_cp0;
13044 case TLBR:
13045 mips32_op = OPC_TLBR;
13046 goto do_cp0;
13047 case TLBWI:
13048 mips32_op = OPC_TLBWI;
13049 goto do_cp0;
13050 case TLBWR:
13051 mips32_op = OPC_TLBWR;
13052 goto do_cp0;
e60ec063
YK
13053 case TLBINV:
13054 mips32_op = OPC_TLBINV;
13055 goto do_cp0;
13056 case TLBINVF:
13057 mips32_op = OPC_TLBINVF;
13058 goto do_cp0;
3c824109
NF
13059 case WAIT:
13060 mips32_op = OPC_WAIT;
13061 goto do_cp0;
13062 case DERET:
13063 mips32_op = OPC_DERET;
13064 goto do_cp0;
13065 case ERET:
13066 mips32_op = OPC_ERET;
13067 do_cp0:
13068 gen_cp0(env, ctx, mips32_op, rt, rs);
13069 break;
13070 default:
13071 goto pool32axf_invalid;
13072 }
13073 break;
13074 case 0x1d:
13075 switch (minor) {
13076 case DI:
2e15497c 13077 check_cp0_enabled(ctx);
3c824109
NF
13078 {
13079 TCGv t0 = tcg_temp_new();
13080
13081 save_cpu_state(ctx, 1);
895c2d04 13082 gen_helper_di(t0, cpu_env);
3c824109
NF
13083 gen_store_gpr(t0, rs);
13084 /* Stop translation as we may have switched the execution mode */
13085 ctx->bstate = BS_STOP;
13086 tcg_temp_free(t0);
13087 }
13088 break;
13089 case EI:
2e15497c 13090 check_cp0_enabled(ctx);
3c824109
NF
13091 {
13092 TCGv t0 = tcg_temp_new();
13093
13094 save_cpu_state(ctx, 1);
895c2d04 13095 gen_helper_ei(t0, cpu_env);
3c824109
NF
13096 gen_store_gpr(t0, rs);
13097 /* Stop translation as we may have switched the execution mode */
13098 ctx->bstate = BS_STOP;
13099 tcg_temp_free(t0);
13100 }
13101 break;
13102 default:
13103 goto pool32axf_invalid;
13104 }
13105 break;
13106#endif
13107 case 0x2d:
13108 switch (minor) {
13109 case SYNC:
13110 /* NOP */
13111 break;
13112 case SYSCALL:
9c708c7f 13113 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13114 break;
13115 case SDBBP:
3b3c1694
LA
13116 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13117 gen_helper_do_semihosting(cpu_env);
13118 } else {
13119 check_insn(ctx, ISA_MIPS32);
e0332095 13120 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13121 generate_exception_end(ctx, EXCP_RI);
e0332095 13122 } else {
9c708c7f 13123 generate_exception_end(ctx, EXCP_DBp);
e0332095 13124 }
3b3c1694 13125 }
3c824109
NF
13126 break;
13127 default:
13128 goto pool32axf_invalid;
13129 }
13130 break;
a1fc6246 13131 case 0x01:
26135ead 13132 switch (minor & 3) {
a1fc6246 13133 case MFHI_ACC:
26135ead 13134 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13135 break;
a1fc6246 13136 case MFLO_ACC:
26135ead 13137 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13138 break;
a1fc6246 13139 case MTHI_ACC:
26135ead 13140 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13141 break;
a1fc6246 13142 case MTLO_ACC:
26135ead 13143 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13144 break;
13145 default:
13146 goto pool32axf_invalid;
13147 }
13148 break;
a1fc6246 13149 case 0x35:
9e8f441a 13150 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13151 switch (minor) {
13152 case MFHI32:
13153 gen_HILO(ctx, OPC_MFHI, 0, rs);
13154 break;
13155 case MFLO32:
13156 gen_HILO(ctx, OPC_MFLO, 0, rs);
13157 break;
13158 case MTHI32:
13159 gen_HILO(ctx, OPC_MTHI, 0, rs);
13160 break;
13161 case MTLO32:
13162 gen_HILO(ctx, OPC_MTLO, 0, rs);
13163 break;
13164 default:
13165 goto pool32axf_invalid;
13166 }
13167 break;
3c824109
NF
13168 default:
13169 pool32axf_invalid:
13170 MIPS_INVAL("pool32axf");
9c708c7f 13171 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13172 break;
13173 }
13174}
13175
13176/* Values for microMIPS fmt field. Variable-width, depending on which
13177 formats the instruction supports. */
13178
13179enum {
13180 FMT_SD_S = 0,
13181 FMT_SD_D = 1,
13182
13183 FMT_SDPS_S = 0,
13184 FMT_SDPS_D = 1,
13185 FMT_SDPS_PS = 2,
13186
13187 FMT_SWL_S = 0,
13188 FMT_SWL_W = 1,
13189 FMT_SWL_L = 2,
13190
13191 FMT_DWL_D = 0,
13192 FMT_DWL_W = 1,
13193 FMT_DWL_L = 2
13194};
13195
d75c135e 13196static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13197{
13198 int extension = (ctx->opcode >> 6) & 0x3ff;
13199 uint32_t mips32_op;
13200
13201#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13202#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13203#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13204
13205 switch (extension) {
13206 case FLOAT_1BIT_FMT(CFC1, 0):
13207 mips32_op = OPC_CFC1;
13208 goto do_cp1;
13209 case FLOAT_1BIT_FMT(CTC1, 0):
13210 mips32_op = OPC_CTC1;
13211 goto do_cp1;
13212 case FLOAT_1BIT_FMT(MFC1, 0):
13213 mips32_op = OPC_MFC1;
13214 goto do_cp1;
13215 case FLOAT_1BIT_FMT(MTC1, 0):
13216 mips32_op = OPC_MTC1;
13217 goto do_cp1;
13218 case FLOAT_1BIT_FMT(MFHC1, 0):
13219 mips32_op = OPC_MFHC1;
13220 goto do_cp1;
13221 case FLOAT_1BIT_FMT(MTHC1, 0):
13222 mips32_op = OPC_MTHC1;
13223 do_cp1:
13224 gen_cp1(ctx, mips32_op, rt, rs);
13225 break;
13226
13227 /* Reciprocal square root */
13228 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13229 mips32_op = OPC_RSQRT_S;
13230 goto do_unaryfp;
13231 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13232 mips32_op = OPC_RSQRT_D;
13233 goto do_unaryfp;
13234
13235 /* Square root */
13236 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13237 mips32_op = OPC_SQRT_S;
13238 goto do_unaryfp;
13239 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13240 mips32_op = OPC_SQRT_D;
13241 goto do_unaryfp;
13242
13243 /* Reciprocal */
13244 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13245 mips32_op = OPC_RECIP_S;
13246 goto do_unaryfp;
13247 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13248 mips32_op = OPC_RECIP_D;
13249 goto do_unaryfp;
13250
13251 /* Floor */
13252 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13253 mips32_op = OPC_FLOOR_L_S;
13254 goto do_unaryfp;
13255 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13256 mips32_op = OPC_FLOOR_L_D;
13257 goto do_unaryfp;
13258 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13259 mips32_op = OPC_FLOOR_W_S;
13260 goto do_unaryfp;
13261 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13262 mips32_op = OPC_FLOOR_W_D;
13263 goto do_unaryfp;
13264
13265 /* Ceiling */
13266 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13267 mips32_op = OPC_CEIL_L_S;
13268 goto do_unaryfp;
13269 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13270 mips32_op = OPC_CEIL_L_D;
13271 goto do_unaryfp;
13272 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13273 mips32_op = OPC_CEIL_W_S;
13274 goto do_unaryfp;
13275 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13276 mips32_op = OPC_CEIL_W_D;
13277 goto do_unaryfp;
13278
13279 /* Truncation */
13280 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13281 mips32_op = OPC_TRUNC_L_S;
13282 goto do_unaryfp;
13283 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13284 mips32_op = OPC_TRUNC_L_D;
13285 goto do_unaryfp;
13286 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13287 mips32_op = OPC_TRUNC_W_S;
13288 goto do_unaryfp;
13289 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13290 mips32_op = OPC_TRUNC_W_D;
13291 goto do_unaryfp;
13292
13293 /* Round */
13294 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13295 mips32_op = OPC_ROUND_L_S;
13296 goto do_unaryfp;
13297 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13298 mips32_op = OPC_ROUND_L_D;
13299 goto do_unaryfp;
13300 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13301 mips32_op = OPC_ROUND_W_S;
13302 goto do_unaryfp;
13303 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13304 mips32_op = OPC_ROUND_W_D;
13305 goto do_unaryfp;
13306
13307 /* Integer to floating-point conversion */
13308 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13309 mips32_op = OPC_CVT_L_S;
13310 goto do_unaryfp;
13311 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13312 mips32_op = OPC_CVT_L_D;
13313 goto do_unaryfp;
13314 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13315 mips32_op = OPC_CVT_W_S;
13316 goto do_unaryfp;
13317 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13318 mips32_op = OPC_CVT_W_D;
13319 goto do_unaryfp;
13320
13321 /* Paired-foo conversions */
13322 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13323 mips32_op = OPC_CVT_S_PL;
13324 goto do_unaryfp;
13325 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13326 mips32_op = OPC_CVT_S_PU;
13327 goto do_unaryfp;
13328 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13329 mips32_op = OPC_CVT_PW_PS;
13330 goto do_unaryfp;
13331 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13332 mips32_op = OPC_CVT_PS_PW;
13333 goto do_unaryfp;
13334
13335 /* Floating-point moves */
13336 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13337 mips32_op = OPC_MOV_S;
13338 goto do_unaryfp;
13339 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13340 mips32_op = OPC_MOV_D;
13341 goto do_unaryfp;
13342 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13343 mips32_op = OPC_MOV_PS;
13344 goto do_unaryfp;
13345
13346 /* Absolute value */
13347 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13348 mips32_op = OPC_ABS_S;
13349 goto do_unaryfp;
13350 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13351 mips32_op = OPC_ABS_D;
13352 goto do_unaryfp;
13353 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13354 mips32_op = OPC_ABS_PS;
13355 goto do_unaryfp;
13356
13357 /* Negation */
13358 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13359 mips32_op = OPC_NEG_S;
13360 goto do_unaryfp;
13361 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13362 mips32_op = OPC_NEG_D;
13363 goto do_unaryfp;
13364 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13365 mips32_op = OPC_NEG_PS;
13366 goto do_unaryfp;
13367
13368 /* Reciprocal square root step */
13369 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13370 mips32_op = OPC_RSQRT1_S;
13371 goto do_unaryfp;
13372 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13373 mips32_op = OPC_RSQRT1_D;
13374 goto do_unaryfp;
13375 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13376 mips32_op = OPC_RSQRT1_PS;
13377 goto do_unaryfp;
13378
13379 /* Reciprocal step */
13380 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13381 mips32_op = OPC_RECIP1_S;
13382 goto do_unaryfp;
13383 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13384 mips32_op = OPC_RECIP1_S;
13385 goto do_unaryfp;
13386 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13387 mips32_op = OPC_RECIP1_PS;
13388 goto do_unaryfp;
13389
13390 /* Conversions from double */
13391 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13392 mips32_op = OPC_CVT_D_S;
13393 goto do_unaryfp;
13394 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13395 mips32_op = OPC_CVT_D_W;
13396 goto do_unaryfp;
13397 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13398 mips32_op = OPC_CVT_D_L;
13399 goto do_unaryfp;
13400
13401 /* Conversions from single */
13402 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13403 mips32_op = OPC_CVT_S_D;
13404 goto do_unaryfp;
13405 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13406 mips32_op = OPC_CVT_S_W;
13407 goto do_unaryfp;
13408 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13409 mips32_op = OPC_CVT_S_L;
13410 do_unaryfp:
13411 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13412 break;
13413
13414 /* Conditional moves on floating-point codes */
13415 case COND_FLOAT_MOV(MOVT, 0):
13416 case COND_FLOAT_MOV(MOVT, 1):
13417 case COND_FLOAT_MOV(MOVT, 2):
13418 case COND_FLOAT_MOV(MOVT, 3):
13419 case COND_FLOAT_MOV(MOVT, 4):
13420 case COND_FLOAT_MOV(MOVT, 5):
13421 case COND_FLOAT_MOV(MOVT, 6):
13422 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13424 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13425 break;
13426 case COND_FLOAT_MOV(MOVF, 0):
13427 case COND_FLOAT_MOV(MOVF, 1):
13428 case COND_FLOAT_MOV(MOVF, 2):
13429 case COND_FLOAT_MOV(MOVF, 3):
13430 case COND_FLOAT_MOV(MOVF, 4):
13431 case COND_FLOAT_MOV(MOVF, 5):
13432 case COND_FLOAT_MOV(MOVF, 6):
13433 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13435 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13436 break;
13437 default:
13438 MIPS_INVAL("pool32fxf");
9c708c7f 13439 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13440 break;
13441 }
13442}
13443
f60eeb0c 13444static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13445{
13446 int32_t offset;
13447 uint16_t insn;
13448 int rt, rs, rd, rr;
13449 int16_t imm;
13450 uint32_t op, minor, mips32_op;
13451 uint32_t cond, fmt, cc;
13452
895c2d04 13453 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13454 ctx->opcode = (ctx->opcode << 16) | insn;
13455
13456 rt = (ctx->opcode >> 21) & 0x1f;
13457 rs = (ctx->opcode >> 16) & 0x1f;
13458 rd = (ctx->opcode >> 11) & 0x1f;
13459 rr = (ctx->opcode >> 6) & 0x1f;
13460 imm = (int16_t) ctx->opcode;
13461
13462 op = (ctx->opcode >> 26) & 0x3f;
13463 switch (op) {
13464 case POOL32A:
13465 minor = ctx->opcode & 0x3f;
13466 switch (minor) {
13467 case 0x00:
13468 minor = (ctx->opcode >> 6) & 0xf;
13469 switch (minor) {
13470 case SLL32:
13471 mips32_op = OPC_SLL;
13472 goto do_shifti;
13473 case SRA:
13474 mips32_op = OPC_SRA;
13475 goto do_shifti;
13476 case SRL32:
13477 mips32_op = OPC_SRL;
13478 goto do_shifti;
13479 case ROTR:
13480 mips32_op = OPC_ROTR;
13481 do_shifti:
d75c135e 13482 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13483 break;
e0332095
YK
13484 case SELEQZ:
13485 check_insn(ctx, ISA_MIPS32R6);
13486 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13487 break;
13488 case SELNEZ:
13489 check_insn(ctx, ISA_MIPS32R6);
13490 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13491 break;
3c824109
NF
13492 default:
13493 goto pool32a_invalid;
13494 }
13495 break;
13496 case 0x10:
13497 minor = (ctx->opcode >> 6) & 0xf;
13498 switch (minor) {
13499 /* Arithmetic */
13500 case ADD:
13501 mips32_op = OPC_ADD;
13502 goto do_arith;
13503 case ADDU32:
13504 mips32_op = OPC_ADDU;
13505 goto do_arith;
13506 case SUB:
13507 mips32_op = OPC_SUB;
13508 goto do_arith;
13509 case SUBU32:
13510 mips32_op = OPC_SUBU;
13511 goto do_arith;
13512 case MUL:
9e8f441a 13513 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13514 mips32_op = OPC_MUL;
13515 do_arith:
d75c135e 13516 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13517 break;
13518 /* Shifts */
13519 case SLLV:
13520 mips32_op = OPC_SLLV;
13521 goto do_shift;
13522 case SRLV:
13523 mips32_op = OPC_SRLV;
13524 goto do_shift;
13525 case SRAV:
13526 mips32_op = OPC_SRAV;
13527 goto do_shift;
13528 case ROTRV:
13529 mips32_op = OPC_ROTRV;
13530 do_shift:
d75c135e 13531 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13532 break;
13533 /* Logical operations */
13534 case AND:
13535 mips32_op = OPC_AND;
13536 goto do_logic;
13537 case OR32:
13538 mips32_op = OPC_OR;
13539 goto do_logic;
13540 case NOR:
13541 mips32_op = OPC_NOR;
13542 goto do_logic;
13543 case XOR32:
13544 mips32_op = OPC_XOR;
13545 do_logic:
d75c135e 13546 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13547 break;
13548 /* Set less than */
13549 case SLT:
13550 mips32_op = OPC_SLT;
13551 goto do_slt;
13552 case SLTU:
13553 mips32_op = OPC_SLTU;
13554 do_slt:
d75c135e 13555 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13556 break;
13557 default:
13558 goto pool32a_invalid;
13559 }
13560 break;
13561 case 0x18:
13562 minor = (ctx->opcode >> 6) & 0xf;
13563 switch (minor) {
13564 /* Conditional moves */
e0332095
YK
13565 case MOVN: /* MUL */
13566 if (ctx->insn_flags & ISA_MIPS32R6) {
13567 /* MUL */
13568 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13569 } else {
13570 /* MOVN */
13571 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13572 }
13573 break;
13574 case MOVZ: /* MUH */
13575 if (ctx->insn_flags & ISA_MIPS32R6) {
13576 /* MUH */
13577 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13578 } else {
13579 /* MOVZ */
13580 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13581 }
13582 break;
13583 case MULU:
13584 check_insn(ctx, ISA_MIPS32R6);
13585 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13586 break;
13587 case MUHU:
13588 check_insn(ctx, ISA_MIPS32R6);
13589 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13590 break;
13591 case LWXS: /* DIV */
13592 if (ctx->insn_flags & ISA_MIPS32R6) {
13593 /* DIV */
13594 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13595 } else {
13596 /* LWXS */
13597 gen_ldxs(ctx, rs, rt, rd);
13598 }
13599 break;
13600 case MOD:
13601 check_insn(ctx, ISA_MIPS32R6);
13602 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13603 break;
13604 case R6_DIVU:
13605 check_insn(ctx, ISA_MIPS32R6);
13606 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13607 break;
e0332095
YK
13608 case MODU:
13609 check_insn(ctx, ISA_MIPS32R6);
13610 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13611 break;
13612 default:
13613 goto pool32a_invalid;
13614 }
13615 break;
13616 case INS:
13617 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13618 return;
e0332095
YK
13619 case LSA:
13620 check_insn(ctx, ISA_MIPS32R6);
13621 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13622 extract32(ctx->opcode, 9, 2));
13623 break;
13624 case ALIGN:
13625 check_insn(ctx, ISA_MIPS32R6);
13626 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13627 extract32(ctx->opcode, 9, 2));
13628 break;
3c824109
NF
13629 case EXT:
13630 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13631 return;
13632 case POOL32AXF:
240ce26a 13633 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13634 break;
13635 case 0x07:
9c708c7f 13636 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13637 break;
13638 default:
13639 pool32a_invalid:
13640 MIPS_INVAL("pool32a");
9c708c7f 13641 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13642 break;
13643 }
13644 break;
13645 case POOL32B:
13646 minor = (ctx->opcode >> 12) & 0xf;
13647 switch (minor) {
13648 case CACHE:
2e15497c 13649 check_cp0_enabled(ctx);
3c824109
NF
13650 /* Treat as no-op. */
13651 break;
13652 case LWC2:
13653 case SWC2:
13654 /* COP2: Not implemented. */
13655 generate_exception_err(ctx, EXCP_CpU, 2);
13656 break;
3c824109
NF
13657#ifdef TARGET_MIPS64
13658 case LDP:
13659 case SDP:
d9224450
MR
13660 check_insn(ctx, ISA_MIPS3);
13661 check_mips_64(ctx);
13662 /* Fallthrough */
3c824109 13663#endif
d9224450
MR
13664 case LWP:
13665 case SWP:
3c824109
NF
13666 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13667 break;
3c824109
NF
13668#ifdef TARGET_MIPS64
13669 case LDM:
13670 case SDM:
d9224450
MR
13671 check_insn(ctx, ISA_MIPS3);
13672 check_mips_64(ctx);
13673 /* Fallthrough */
3c824109 13674#endif
d9224450
MR
13675 case LWM32:
13676 case SWM32:
3c824109
NF
13677 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13678 break;
13679 default:
13680 MIPS_INVAL("pool32b");
9c708c7f 13681 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13682 break;
13683 }
13684 break;
13685 case POOL32F:
5ab5c041 13686 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13687 minor = ctx->opcode & 0x3f;
13688 check_cp1_enabled(ctx);
13689 switch (minor) {
13690 case ALNV_PS:
9e8f441a 13691 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13692 mips32_op = OPC_ALNV_PS;
13693 goto do_madd;
13694 case MADD_S:
9e8f441a 13695 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13696 mips32_op = OPC_MADD_S;
13697 goto do_madd;
13698 case MADD_D:
9e8f441a 13699 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13700 mips32_op = OPC_MADD_D;
13701 goto do_madd;
13702 case MADD_PS:
9e8f441a 13703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13704 mips32_op = OPC_MADD_PS;
13705 goto do_madd;
13706 case MSUB_S:
9e8f441a 13707 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13708 mips32_op = OPC_MSUB_S;
13709 goto do_madd;
13710 case MSUB_D:
9e8f441a 13711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13712 mips32_op = OPC_MSUB_D;
13713 goto do_madd;
13714 case MSUB_PS:
9e8f441a 13715 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13716 mips32_op = OPC_MSUB_PS;
13717 goto do_madd;
13718 case NMADD_S:
9e8f441a 13719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13720 mips32_op = OPC_NMADD_S;
13721 goto do_madd;
13722 case NMADD_D:
9e8f441a 13723 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13724 mips32_op = OPC_NMADD_D;
13725 goto do_madd;
13726 case NMADD_PS:
9e8f441a 13727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13728 mips32_op = OPC_NMADD_PS;
13729 goto do_madd;
13730 case NMSUB_S:
9e8f441a 13731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13732 mips32_op = OPC_NMSUB_S;
13733 goto do_madd;
13734 case NMSUB_D:
9e8f441a 13735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13736 mips32_op = OPC_NMSUB_D;
13737 goto do_madd;
13738 case NMSUB_PS:
9e8f441a 13739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13740 mips32_op = OPC_NMSUB_PS;
13741 do_madd:
13742 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13743 break;
13744 case CABS_COND_FMT:
9e8f441a 13745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13746 cond = (ctx->opcode >> 6) & 0xf;
13747 cc = (ctx->opcode >> 13) & 0x7;
13748 fmt = (ctx->opcode >> 10) & 0x3;
13749 switch (fmt) {
13750 case 0x0:
13751 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13752 break;
13753 case 0x1:
13754 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13755 break;
13756 case 0x2:
13757 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13758 break;
13759 default:
13760 goto pool32f_invalid;
13761 }
13762 break;
13763 case C_COND_FMT:
9e8f441a 13764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13765 cond = (ctx->opcode >> 6) & 0xf;
13766 cc = (ctx->opcode >> 13) & 0x7;
13767 fmt = (ctx->opcode >> 10) & 0x3;
13768 switch (fmt) {
13769 case 0x0:
13770 gen_cmp_s(ctx, cond, rt, rs, cc);
13771 break;
13772 case 0x1:
13773 gen_cmp_d(ctx, cond, rt, rs, cc);
13774 break;
13775 case 0x2:
13776 gen_cmp_ps(ctx, cond, rt, rs, cc);
13777 break;
13778 default:
13779 goto pool32f_invalid;
13780 }
13781 break;
2a24a7ba
YK
13782 case CMP_CONDN_S:
13783 check_insn(ctx, ISA_MIPS32R6);
13784 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13785 break;
13786 case CMP_CONDN_D:
13787 check_insn(ctx, ISA_MIPS32R6);
13788 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13789 break;
3c824109 13790 case POOL32FXF:
d75c135e 13791 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13792 break;
13793 case 0x00:
13794 /* PLL foo */
13795 switch ((ctx->opcode >> 6) & 0x7) {
13796 case PLL_PS:
13797 mips32_op = OPC_PLL_PS;
13798 goto do_ps;
13799 case PLU_PS:
13800 mips32_op = OPC_PLU_PS;
13801 goto do_ps;
13802 case PUL_PS:
13803 mips32_op = OPC_PUL_PS;
13804 goto do_ps;
13805 case PUU_PS:
13806 mips32_op = OPC_PUU_PS;
13807 goto do_ps;
13808 case CVT_PS_S:
9e8f441a 13809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13810 mips32_op = OPC_CVT_PS_S;
13811 do_ps:
13812 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13813 break;
13814 default:
13815 goto pool32f_invalid;
13816 }
13817 break;
2a24a7ba
YK
13818 case MIN_FMT:
13819 check_insn(ctx, ISA_MIPS32R6);
13820 switch ((ctx->opcode >> 9) & 0x3) {
13821 case FMT_SDPS_S:
13822 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13823 break;
13824 case FMT_SDPS_D:
13825 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13826 break;
13827 default:
13828 goto pool32f_invalid;
13829 }
13830 break;
3c824109
NF
13831 case 0x08:
13832 /* [LS][WDU]XC1 */
13833 switch ((ctx->opcode >> 6) & 0x7) {
13834 case LWXC1:
9e8f441a 13835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13836 mips32_op = OPC_LWXC1;
13837 goto do_ldst_cp1;
13838 case SWXC1:
9e8f441a 13839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13840 mips32_op = OPC_SWXC1;
13841 goto do_ldst_cp1;
13842 case LDXC1:
9e8f441a 13843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13844 mips32_op = OPC_LDXC1;
13845 goto do_ldst_cp1;
13846 case SDXC1:
9e8f441a 13847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13848 mips32_op = OPC_SDXC1;
13849 goto do_ldst_cp1;
13850 case LUXC1:
9e8f441a 13851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13852 mips32_op = OPC_LUXC1;
13853 goto do_ldst_cp1;
13854 case SUXC1:
9e8f441a 13855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13856 mips32_op = OPC_SUXC1;
13857 do_ldst_cp1:
13858 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13859 break;
13860 default:
13861 goto pool32f_invalid;
13862 }
13863 break;
2a24a7ba
YK
13864 case MAX_FMT:
13865 check_insn(ctx, ISA_MIPS32R6);
13866 switch ((ctx->opcode >> 9) & 0x3) {
13867 case FMT_SDPS_S:
13868 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13869 break;
13870 case FMT_SDPS_D:
13871 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13872 break;
13873 default:
13874 goto pool32f_invalid;
13875 }
13876 break;
3c824109
NF
13877 case 0x18:
13878 /* 3D insns */
9e8f441a 13879 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13880 fmt = (ctx->opcode >> 9) & 0x3;
13881 switch ((ctx->opcode >> 6) & 0x7) {
13882 case RSQRT2_FMT:
13883 switch (fmt) {
13884 case FMT_SDPS_S:
13885 mips32_op = OPC_RSQRT2_S;
13886 goto do_3d;
13887 case FMT_SDPS_D:
13888 mips32_op = OPC_RSQRT2_D;
13889 goto do_3d;
13890 case FMT_SDPS_PS:
13891 mips32_op = OPC_RSQRT2_PS;
13892 goto do_3d;
13893 default:
13894 goto pool32f_invalid;
13895 }
13896 break;
13897 case RECIP2_FMT:
13898 switch (fmt) {
13899 case FMT_SDPS_S:
13900 mips32_op = OPC_RECIP2_S;
13901 goto do_3d;
13902 case FMT_SDPS_D:
13903 mips32_op = OPC_RECIP2_D;
13904 goto do_3d;
13905 case FMT_SDPS_PS:
13906 mips32_op = OPC_RECIP2_PS;
13907 goto do_3d;
13908 default:
13909 goto pool32f_invalid;
13910 }
13911 break;
13912 case ADDR_PS:
13913 mips32_op = OPC_ADDR_PS;
13914 goto do_3d;
13915 case MULR_PS:
13916 mips32_op = OPC_MULR_PS;
13917 do_3d:
13918 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13919 break;
13920 default:
13921 goto pool32f_invalid;
13922 }
13923 break;
13924 case 0x20:
2a24a7ba 13925 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
13926 cc = (ctx->opcode >> 13) & 0x7;
13927 fmt = (ctx->opcode >> 9) & 0x3;
13928 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
13929 case MOVF_FMT: /* RINT_FMT */
13930 if (ctx->insn_flags & ISA_MIPS32R6) {
13931 /* RINT_FMT */
13932 switch (fmt) {
13933 case FMT_SDPS_S:
13934 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
13935 break;
13936 case FMT_SDPS_D:
13937 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
13938 break;
13939 default:
13940 goto pool32f_invalid;
13941 }
13942 } else {
13943 /* MOVF_FMT */
13944 switch (fmt) {
13945 case FMT_SDPS_S:
13946 gen_movcf_s(ctx, rs, rt, cc, 0);
13947 break;
13948 case FMT_SDPS_D:
13949 gen_movcf_d(ctx, rs, rt, cc, 0);
13950 break;
13951 case FMT_SDPS_PS:
13952 check_ps(ctx);
13953 gen_movcf_ps(ctx, rs, rt, cc, 0);
13954 break;
13955 default:
13956 goto pool32f_invalid;
13957 }
3c824109
NF
13958 }
13959 break;
2a24a7ba
YK
13960 case MOVT_FMT: /* CLASS_FMT */
13961 if (ctx->insn_flags & ISA_MIPS32R6) {
13962 /* CLASS_FMT */
13963 switch (fmt) {
13964 case FMT_SDPS_S:
13965 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
13966 break;
13967 case FMT_SDPS_D:
13968 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
13969 break;
13970 default:
13971 goto pool32f_invalid;
13972 }
13973 } else {
13974 /* MOVT_FMT */
13975 switch (fmt) {
13976 case FMT_SDPS_S:
13977 gen_movcf_s(ctx, rs, rt, cc, 1);
13978 break;
13979 case FMT_SDPS_D:
13980 gen_movcf_d(ctx, rs, rt, cc, 1);
13981 break;
13982 case FMT_SDPS_PS:
13983 check_ps(ctx);
13984 gen_movcf_ps(ctx, rs, rt, cc, 1);
13985 break;
13986 default:
13987 goto pool32f_invalid;
13988 }
3c824109
NF
13989 }
13990 break;
13991 case PREFX:
9e8f441a 13992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13993 break;
13994 default:
13995 goto pool32f_invalid;
13996 }
13997 break;
13998#define FINSN_3ARG_SDPS(prfx) \
13999 switch ((ctx->opcode >> 8) & 0x3) { \
14000 case FMT_SDPS_S: \
14001 mips32_op = OPC_##prfx##_S; \
14002 goto do_fpop; \
14003 case FMT_SDPS_D: \
14004 mips32_op = OPC_##prfx##_D; \
14005 goto do_fpop; \
14006 case FMT_SDPS_PS: \
e29c9628 14007 check_ps(ctx); \
3c824109
NF
14008 mips32_op = OPC_##prfx##_PS; \
14009 goto do_fpop; \
14010 default: \
14011 goto pool32f_invalid; \
14012 }
2a24a7ba
YK
14013 case MINA_FMT:
14014 check_insn(ctx, ISA_MIPS32R6);
14015 switch ((ctx->opcode >> 9) & 0x3) {
14016 case FMT_SDPS_S:
14017 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14018 break;
14019 case FMT_SDPS_D:
14020 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14021 break;
14022 default:
14023 goto pool32f_invalid;
14024 }
14025 break;
14026 case MAXA_FMT:
14027 check_insn(ctx, ISA_MIPS32R6);
14028 switch ((ctx->opcode >> 9) & 0x3) {
14029 case FMT_SDPS_S:
14030 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14031 break;
14032 case FMT_SDPS_D:
14033 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14034 break;
14035 default:
14036 goto pool32f_invalid;
14037 }
14038 break;
3c824109
NF
14039 case 0x30:
14040 /* regular FP ops */
14041 switch ((ctx->opcode >> 6) & 0x3) {
14042 case ADD_FMT:
14043 FINSN_3ARG_SDPS(ADD);
14044 break;
14045 case SUB_FMT:
14046 FINSN_3ARG_SDPS(SUB);
14047 break;
14048 case MUL_FMT:
14049 FINSN_3ARG_SDPS(MUL);
14050 break;
14051 case DIV_FMT:
14052 fmt = (ctx->opcode >> 8) & 0x3;
14053 if (fmt == 1) {
14054 mips32_op = OPC_DIV_D;
14055 } else if (fmt == 0) {
14056 mips32_op = OPC_DIV_S;
14057 } else {
14058 goto pool32f_invalid;
14059 }
14060 goto do_fpop;
14061 default:
14062 goto pool32f_invalid;
14063 }
14064 break;
14065 case 0x38:
14066 /* cmovs */
2a24a7ba
YK
14067 switch ((ctx->opcode >> 6) & 0x7) {
14068 case MOVN_FMT: /* SELNEZ_FMT */
14069 if (ctx->insn_flags & ISA_MIPS32R6) {
14070 /* SELNEZ_FMT */
14071 switch ((ctx->opcode >> 9) & 0x3) {
14072 case FMT_SDPS_S:
14073 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14074 break;
14075 case FMT_SDPS_D:
14076 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14077 break;
14078 default:
14079 goto pool32f_invalid;
14080 }
14081 } else {
14082 /* MOVN_FMT */
14083 FINSN_3ARG_SDPS(MOVN);
14084 }
14085 break;
14086 case MOVN_FMT_04:
14087 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14088 FINSN_3ARG_SDPS(MOVN);
14089 break;
2a24a7ba
YK
14090 case MOVZ_FMT: /* SELEQZ_FMT */
14091 if (ctx->insn_flags & ISA_MIPS32R6) {
14092 /* SELEQZ_FMT */
14093 switch ((ctx->opcode >> 9) & 0x3) {
14094 case FMT_SDPS_S:
14095 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14096 break;
14097 case FMT_SDPS_D:
14098 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14099 break;
14100 default:
14101 goto pool32f_invalid;
14102 }
14103 } else {
14104 /* MOVZ_FMT */
14105 FINSN_3ARG_SDPS(MOVZ);
14106 }
14107 break;
14108 case MOVZ_FMT_05:
14109 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14110 FINSN_3ARG_SDPS(MOVZ);
14111 break;
2a24a7ba
YK
14112 case SEL_FMT:
14113 check_insn(ctx, ISA_MIPS32R6);
14114 switch ((ctx->opcode >> 9) & 0x3) {
14115 case FMT_SDPS_S:
14116 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14117 break;
14118 case FMT_SDPS_D:
14119 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14120 break;
14121 default:
14122 goto pool32f_invalid;
14123 }
14124 break;
14125 case MADDF_FMT:
14126 check_insn(ctx, ISA_MIPS32R6);
14127 switch ((ctx->opcode >> 9) & 0x3) {
14128 case FMT_SDPS_S:
14129 mips32_op = OPC_MADDF_S;
14130 goto do_fpop;
14131 case FMT_SDPS_D:
14132 mips32_op = OPC_MADDF_D;
14133 goto do_fpop;
14134 default:
14135 goto pool32f_invalid;
14136 }
14137 break;
14138 case MSUBF_FMT:
14139 check_insn(ctx, ISA_MIPS32R6);
14140 switch ((ctx->opcode >> 9) & 0x3) {
14141 case FMT_SDPS_S:
14142 mips32_op = OPC_MSUBF_S;
14143 goto do_fpop;
14144 case FMT_SDPS_D:
14145 mips32_op = OPC_MSUBF_D;
14146 goto do_fpop;
14147 default:
14148 goto pool32f_invalid;
14149 }
14150 break;
3c824109
NF
14151 default:
14152 goto pool32f_invalid;
14153 }
14154 break;
14155 do_fpop:
14156 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14157 break;
14158 default:
14159 pool32f_invalid:
14160 MIPS_INVAL("pool32f");
9c708c7f 14161 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14162 break;
14163 }
14164 } else {
14165 generate_exception_err(ctx, EXCP_CpU, 1);
14166 }
14167 break;
14168 case POOL32I:
14169 minor = (ctx->opcode >> 21) & 0x1f;
14170 switch (minor) {
14171 case BLTZ:
9e8f441a 14172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14173 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14174 break;
3c824109 14175 case BLTZAL:
9e8f441a 14176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14177 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14178 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14179 break;
3c824109 14180 case BLTZALS:
9e8f441a 14181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14182 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14183 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14184 break;
3c824109 14185 case BGEZ:
9e8f441a 14186 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14187 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14188 break;
3c824109 14189 case BGEZAL:
9e8f441a 14190 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14191 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14192 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14193 break;
3c824109 14194 case BGEZALS:
9e8f441a 14195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14196 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14197 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14198 break;
3c824109 14199 case BLEZ:
9e8f441a 14200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14201 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14202 break;
3c824109 14203 case BGTZ:
9e8f441a 14204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14205 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14206 break;
14207
14208 /* Traps */
65935f07
YK
14209 case TLTI: /* BC1EQZC */
14210 if (ctx->insn_flags & ISA_MIPS32R6) {
14211 /* BC1EQZC */
14212 check_cp1_enabled(ctx);
14213 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14214 } else {
14215 /* TLTI */
14216 mips32_op = OPC_TLTI;
14217 goto do_trapi;
14218 }
14219 break;
14220 case TGEI: /* BC1NEZC */
14221 if (ctx->insn_flags & ISA_MIPS32R6) {
14222 /* BC1NEZC */
14223 check_cp1_enabled(ctx);
14224 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14225 } else {
14226 /* TGEI */
14227 mips32_op = OPC_TGEI;
14228 goto do_trapi;
14229 }
14230 break;
3c824109 14231 case TLTIU:
9e8f441a 14232 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14233 mips32_op = OPC_TLTIU;
14234 goto do_trapi;
14235 case TGEIU:
9e8f441a 14236 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14237 mips32_op = OPC_TGEIU;
14238 goto do_trapi;
3b4a5489
YK
14239 case TNEI: /* SYNCI */
14240 if (ctx->insn_flags & ISA_MIPS32R6) {
14241 /* SYNCI */
14242 /* Break the TB to be able to sync copied instructions
14243 immediately */
14244 ctx->bstate = BS_STOP;
14245 } else {
14246 /* TNEI */
14247 mips32_op = OPC_TNEI;
14248 goto do_trapi;
14249 }
14250 break;
3c824109 14251 case TEQI:
9e8f441a 14252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14253 mips32_op = OPC_TEQI;
14254 do_trapi:
14255 gen_trap(ctx, mips32_op, rs, -1, imm);
14256 break;
14257
14258 case BNEZC:
14259 case BEQZC:
9e8f441a 14260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14261 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14262 4, rs, 0, imm << 1, 0);
3c824109
NF
14263 /* Compact branches don't have a delay slot, so just let
14264 the normal delay slot handling take us to the branch
14265 target. */
14266 break;
14267 case LUI:
9e8f441a 14268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14269 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14270 break;
14271 case SYNCI:
9e8f441a 14272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14273 /* Break the TB to be able to sync copied instructions
14274 immediately */
14275 ctx->bstate = BS_STOP;
3c824109
NF
14276 break;
14277 case BC2F:
14278 case BC2T:
9e8f441a 14279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14280 /* COP2: Not implemented. */
14281 generate_exception_err(ctx, EXCP_CpU, 2);
14282 break;
14283 case BC1F:
9e8f441a 14284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14285 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14286 goto do_cp1branch;
14287 case BC1T:
9e8f441a 14288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14289 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14290 goto do_cp1branch;
14291 case BC1ANY4F:
9e8f441a 14292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14293 mips32_op = OPC_BC1FANY4;
14294 goto do_cp1mips3d;
14295 case BC1ANY4T:
9e8f441a 14296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14297 mips32_op = OPC_BC1TANY4;
14298 do_cp1mips3d:
14299 check_cop1x(ctx);
d75c135e 14300 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14301 /* Fall through */
14302 do_cp1branch:
272f458d
MR
14303 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14304 check_cp1_enabled(ctx);
14305 gen_compute_branch1(ctx, mips32_op,
14306 (ctx->opcode >> 18) & 0x7, imm << 1);
14307 } else {
14308 generate_exception_err(ctx, EXCP_CpU, 1);
14309 }
3c824109
NF
14310 break;
14311 case BPOSGE64:
14312 case BPOSGE32:
14313 /* MIPS DSP: not implemented */
14314 /* Fall through */
14315 default:
14316 MIPS_INVAL("pool32i");
9c708c7f 14317 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14318 break;
14319 }
14320 break;
14321 case POOL32C:
14322 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14323 offset = sextract32(ctx->opcode, 0,
14324 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14325 switch (minor) {
14326 case LWL:
9e8f441a 14327 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14328 mips32_op = OPC_LWL;
5c13fdfd 14329 goto do_ld_lr;
3c824109 14330 case SWL:
9e8f441a 14331 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14332 mips32_op = OPC_SWL;
5c13fdfd 14333 goto do_st_lr;
3c824109 14334 case LWR:
9e8f441a 14335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14336 mips32_op = OPC_LWR;
5c13fdfd 14337 goto do_ld_lr;
3c824109 14338 case SWR:
9e8f441a 14339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14340 mips32_op = OPC_SWR;
5c13fdfd 14341 goto do_st_lr;
3c824109
NF
14342#if defined(TARGET_MIPS64)
14343 case LDL:
d9224450
MR
14344 check_insn(ctx, ISA_MIPS3);
14345 check_mips_64(ctx);
9e8f441a 14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14347 mips32_op = OPC_LDL;
5c13fdfd 14348 goto do_ld_lr;
3c824109 14349 case SDL:
d9224450
MR
14350 check_insn(ctx, ISA_MIPS3);
14351 check_mips_64(ctx);
9e8f441a 14352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14353 mips32_op = OPC_SDL;
5c13fdfd 14354 goto do_st_lr;
3c824109 14355 case LDR:
d9224450
MR
14356 check_insn(ctx, ISA_MIPS3);
14357 check_mips_64(ctx);
9e8f441a 14358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14359 mips32_op = OPC_LDR;
5c13fdfd 14360 goto do_ld_lr;
3c824109 14361 case SDR:
d9224450
MR
14362 check_insn(ctx, ISA_MIPS3);
14363 check_mips_64(ctx);
9e8f441a 14364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14365 mips32_op = OPC_SDR;
5c13fdfd 14366 goto do_st_lr;
3c824109 14367 case LWU:
d9224450
MR
14368 check_insn(ctx, ISA_MIPS3);
14369 check_mips_64(ctx);
3c824109 14370 mips32_op = OPC_LWU;
5c13fdfd 14371 goto do_ld_lr;
3c824109 14372 case LLD:
d9224450
MR
14373 check_insn(ctx, ISA_MIPS3);
14374 check_mips_64(ctx);
3c824109 14375 mips32_op = OPC_LLD;
5c13fdfd 14376 goto do_ld_lr;
3c824109
NF
14377#endif
14378 case LL:
14379 mips32_op = OPC_LL;
5c13fdfd
AJ
14380 goto do_ld_lr;
14381 do_ld_lr:
3b4a5489 14382 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14383 break;
14384 do_st_lr:
14385 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14386 break;
14387 case SC:
3b4a5489 14388 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14389 break;
14390#if defined(TARGET_MIPS64)
14391 case SCD:
d9224450
MR
14392 check_insn(ctx, ISA_MIPS3);
14393 check_mips_64(ctx);
3b4a5489 14394 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14395 break;
14396#endif
14397 case PREF:
14398 /* Treat as no-op */
3b4a5489
YK
14399 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14400 /* hint codes 24-31 are reserved and signal RI */
14401 generate_exception(ctx, EXCP_RI);
14402 }
3c824109
NF
14403 break;
14404 default:
14405 MIPS_INVAL("pool32c");
9c708c7f 14406 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14407 break;
14408 }
14409 break;
ab39ee45
YK
14410 case ADDI32: /* AUI, LUI */
14411 if (ctx->insn_flags & ISA_MIPS32R6) {
14412 /* AUI, LUI */
14413 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14414 } else {
14415 /* ADDI32 */
14416 mips32_op = OPC_ADDI;
14417 goto do_addi;
14418 }
14419 break;
3c824109
NF
14420 case ADDIU32:
14421 mips32_op = OPC_ADDIU;
14422 do_addi:
d75c135e 14423 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14424 break;
14425
14426 /* Logical operations */
14427 case ORI32:
14428 mips32_op = OPC_ORI;
14429 goto do_logici;
14430 case XORI32:
14431 mips32_op = OPC_XORI;
14432 goto do_logici;
14433 case ANDI32:
14434 mips32_op = OPC_ANDI;
14435 do_logici:
d75c135e 14436 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14437 break;
14438
14439 /* Set less than immediate */
14440 case SLTI32:
14441 mips32_op = OPC_SLTI;
14442 goto do_slti;
14443 case SLTIU32:
14444 mips32_op = OPC_SLTIU;
14445 do_slti:
d75c135e 14446 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14447 break;
14448 case JALX32:
9e8f441a 14449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14450 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14451 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14452 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14453 break;
65935f07
YK
14454 case JALS32: /* BOVC, BEQC, BEQZALC */
14455 if (ctx->insn_flags & ISA_MIPS32R6) {
14456 if (rs >= rt) {
14457 /* BOVC */
14458 mips32_op = OPC_BOVC;
14459 } else if (rs < rt && rs == 0) {
14460 /* BEQZALC */
14461 mips32_op = OPC_BEQZALC;
14462 } else {
14463 /* BEQC */
14464 mips32_op = OPC_BEQC;
14465 }
14466 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14467 } else {
14468 /* JALS32 */
14469 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14470 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14471 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14472 }
3c824109 14473 break;
65935f07
YK
14474 case BEQ32: /* BC */
14475 if (ctx->insn_flags & ISA_MIPS32R6) {
14476 /* BC */
14477 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14478 sextract32(ctx->opcode << 1, 0, 27));
14479 } else {
14480 /* BEQ32 */
14481 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14482 }
3c824109 14483 break;
65935f07
YK
14484 case BNE32: /* BALC */
14485 if (ctx->insn_flags & ISA_MIPS32R6) {
14486 /* BALC */
14487 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14488 sextract32(ctx->opcode << 1, 0, 27));
14489 } else {
14490 /* BNE32 */
14491 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14492 }
3c824109 14493 break;
65935f07
YK
14494 case J32: /* BGTZC, BLTZC, BLTC */
14495 if (ctx->insn_flags & ISA_MIPS32R6) {
14496 if (rs == 0 && rt != 0) {
14497 /* BGTZC */
14498 mips32_op = OPC_BGTZC;
14499 } else if (rs != 0 && rt != 0 && rs == rt) {
14500 /* BLTZC */
14501 mips32_op = OPC_BLTZC;
14502 } else {
14503 /* BLTC */
14504 mips32_op = OPC_BLTC;
14505 }
14506 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14507 } else {
14508 /* J32 */
14509 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14510 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14511 }
3c824109 14512 break;
65935f07
YK
14513 case JAL32: /* BLEZC, BGEZC, BGEC */
14514 if (ctx->insn_flags & ISA_MIPS32R6) {
14515 if (rs == 0 && rt != 0) {
14516 /* BLEZC */
14517 mips32_op = OPC_BLEZC;
14518 } else if (rs != 0 && rt != 0 && rs == rt) {
14519 /* BGEZC */
14520 mips32_op = OPC_BGEZC;
14521 } else {
14522 /* BGEC */
14523 mips32_op = OPC_BGEC;
14524 }
14525 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14526 } else {
14527 /* JAL32 */
14528 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14529 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14530 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14531 }
3c824109
NF
14532 break;
14533 /* Floating point (COP1) */
14534 case LWC132:
14535 mips32_op = OPC_LWC1;
14536 goto do_cop1;
14537 case LDC132:
14538 mips32_op = OPC_LDC1;
14539 goto do_cop1;
14540 case SWC132:
14541 mips32_op = OPC_SWC1;
14542 goto do_cop1;
14543 case SDC132:
14544 mips32_op = OPC_SDC1;
14545 do_cop1:
5ab5c041 14546 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14547 break;
ab39ee45
YK
14548 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14549 if (ctx->insn_flags & ISA_MIPS32R6) {
14550 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14551 switch ((ctx->opcode >> 16) & 0x1f) {
14552 case ADDIUPC_00 ... ADDIUPC_07:
14553 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14554 break;
14555 case AUIPC:
14556 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14557 break;
14558 case ALUIPC:
14559 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14560 break;
14561 case LWPC_08 ... LWPC_0F:
14562 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14563 break;
14564 default:
14565 generate_exception(ctx, EXCP_RI);
14566 break;
14567 }
14568 } else {
14569 /* ADDIUPC */
3c824109
NF
14570 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14571 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14572
14573 gen_addiupc(ctx, reg, offset, 0, 0);
14574 }
14575 break;
65935f07
YK
14576 case BNVC: /* BNEC, BNEZALC */
14577 check_insn(ctx, ISA_MIPS32R6);
14578 if (rs >= rt) {
14579 /* BNVC */
14580 mips32_op = OPC_BNVC;
14581 } else if (rs < rt && rs == 0) {
14582 /* BNEZALC */
14583 mips32_op = OPC_BNEZALC;
14584 } else {
14585 /* BNEC */
14586 mips32_op = OPC_BNEC;
14587 }
14588 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14589 break;
14590 case R6_BNEZC: /* JIALC */
14591 check_insn(ctx, ISA_MIPS32R6);
14592 if (rt != 0) {
14593 /* BNEZC */
14594 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14595 sextract32(ctx->opcode << 1, 0, 22));
14596 } else {
14597 /* JIALC */
14598 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14599 }
14600 break;
14601 case R6_BEQZC: /* JIC */
14602 check_insn(ctx, ISA_MIPS32R6);
14603 if (rt != 0) {
14604 /* BEQZC */
14605 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14606 sextract32(ctx->opcode << 1, 0, 22));
14607 } else {
14608 /* JIC */
14609 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14610 }
14611 break;
14612 case BLEZALC: /* BGEZALC, BGEUC */
14613 check_insn(ctx, ISA_MIPS32R6);
14614 if (rs == 0 && rt != 0) {
14615 /* BLEZALC */
14616 mips32_op = OPC_BLEZALC;
14617 } else if (rs != 0 && rt != 0 && rs == rt) {
14618 /* BGEZALC */
14619 mips32_op = OPC_BGEZALC;
14620 } else {
14621 /* BGEUC */
14622 mips32_op = OPC_BGEUC;
14623 }
14624 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14625 break;
14626 case BGTZALC: /* BLTZALC, BLTUC */
14627 check_insn(ctx, ISA_MIPS32R6);
14628 if (rs == 0 && rt != 0) {
14629 /* BGTZALC */
14630 mips32_op = OPC_BGTZALC;
14631 } else if (rs != 0 && rt != 0 && rs == rt) {
14632 /* BLTZALC */
14633 mips32_op = OPC_BLTZALC;
14634 } else {
14635 /* BLTUC */
14636 mips32_op = OPC_BLTUC;
14637 }
14638 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14639 break;
3c824109
NF
14640 /* Loads and stores */
14641 case LB32:
14642 mips32_op = OPC_LB;
5c13fdfd 14643 goto do_ld;
3c824109
NF
14644 case LBU32:
14645 mips32_op = OPC_LBU;
5c13fdfd 14646 goto do_ld;
3c824109
NF
14647 case LH32:
14648 mips32_op = OPC_LH;
5c13fdfd 14649 goto do_ld;
3c824109
NF
14650 case LHU32:
14651 mips32_op = OPC_LHU;
5c13fdfd 14652 goto do_ld;
3c824109
NF
14653 case LW32:
14654 mips32_op = OPC_LW;
5c13fdfd 14655 goto do_ld;
3c824109
NF
14656#ifdef TARGET_MIPS64
14657 case LD32:
d9224450
MR
14658 check_insn(ctx, ISA_MIPS3);
14659 check_mips_64(ctx);
3c824109 14660 mips32_op = OPC_LD;
5c13fdfd 14661 goto do_ld;
3c824109 14662 case SD32:
d9224450
MR
14663 check_insn(ctx, ISA_MIPS3);
14664 check_mips_64(ctx);
3c824109 14665 mips32_op = OPC_SD;
5c13fdfd 14666 goto do_st;
3c824109
NF
14667#endif
14668 case SB32:
14669 mips32_op = OPC_SB;
5c13fdfd 14670 goto do_st;
3c824109
NF
14671 case SH32:
14672 mips32_op = OPC_SH;
5c13fdfd 14673 goto do_st;
3c824109
NF
14674 case SW32:
14675 mips32_op = OPC_SW;
5c13fdfd
AJ
14676 goto do_st;
14677 do_ld:
d75c135e 14678 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
14679 break;
14680 do_st:
14681 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14682 break;
14683 default:
9c708c7f 14684 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14685 break;
14686 }
14687}
14688
240ce26a 14689static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14690{
14691 uint32_t op;
14692
14693 /* make sure instructions are on a halfword boundary */
14694 if (ctx->pc & 0x1) {
14695 env->CP0_BadVAddr = ctx->pc;
9c708c7f 14696 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
14697 return 2;
14698 }
14699
14700 op = (ctx->opcode >> 10) & 0x3f;
14701 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
14702 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14703 switch (op & 0x7) { /* MSB-3..MSB-5 */
14704 case 0:
14705 /* POOL32A, POOL32B, POOL32I, POOL32C */
14706 case 4:
14707 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14708 case 5:
14709 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14710 case 6:
14711 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14712 case 7:
14713 /* LB32, LH32, LWC132, LDC132, LW32 */
14714 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 14715 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14716 return 2;
14717 }
14718 break;
b231c103
YK
14719 case 1:
14720 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14721 case 2:
14722 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14723 case 3:
14724 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14725 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 14726 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14727 return 2;
14728 }
14729 break;
3c824109
NF
14730 }
14731 }
b231c103 14732
3c824109
NF
14733 switch (op) {
14734 case POOL16A:
14735 {
14736 int rd = mmreg(uMIPS_RD(ctx->opcode));
14737 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14738 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14739 uint32_t opc = 0;
14740
14741 switch (ctx->opcode & 0x1) {
14742 case ADDU16:
14743 opc = OPC_ADDU;
14744 break;
14745 case SUBU16:
14746 opc = OPC_SUBU;
14747 break;
14748 }
ed7ce6c0
YK
14749 if (ctx->insn_flags & ISA_MIPS32R6) {
14750 /* In the Release 6 the register number location in
14751 * the instruction encoding has changed.
14752 */
14753 gen_arith(ctx, opc, rs1, rd, rs2);
14754 } else {
14755 gen_arith(ctx, opc, rd, rs1, rs2);
14756 }
3c824109
NF
14757 }
14758 break;
14759 case POOL16B:
14760 {
14761 int rd = mmreg(uMIPS_RD(ctx->opcode));
14762 int rs = mmreg(uMIPS_RS(ctx->opcode));
14763 int amount = (ctx->opcode >> 1) & 0x7;
14764 uint32_t opc = 0;
14765 amount = amount == 0 ? 8 : amount;
14766
14767 switch (ctx->opcode & 0x1) {
14768 case SLL16:
14769 opc = OPC_SLL;
14770 break;
14771 case SRL16:
14772 opc = OPC_SRL;
14773 break;
14774 }
14775
d75c135e 14776 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14777 }
14778 break;
14779 case POOL16C:
ed7ce6c0
YK
14780 if (ctx->insn_flags & ISA_MIPS32R6) {
14781 gen_pool16c_r6_insn(ctx);
14782 } else {
14783 gen_pool16c_insn(ctx);
14784 }
3c824109
NF
14785 break;
14786 case LWGP16:
14787 {
14788 int rd = mmreg(uMIPS_RD(ctx->opcode));
14789 int rb = 28; /* GP */
14790 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14791
d75c135e 14792 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14793 }
14794 break;
14795 case POOL16F:
9e8f441a 14796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14797 if (ctx->opcode & 1) {
9c708c7f 14798 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14799 } else {
14800 /* MOVEP */
14801 int enc_dest = uMIPS_RD(ctx->opcode);
14802 int enc_rt = uMIPS_RS2(ctx->opcode);
14803 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 14804 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
14805 }
14806 break;
14807 case LBU16:
14808 {
14809 int rd = mmreg(uMIPS_RD(ctx->opcode));
14810 int rb = mmreg(uMIPS_RS(ctx->opcode));
14811 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14812 offset = (offset == 0xf ? -1 : offset);
14813
d75c135e 14814 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14815 }
14816 break;
14817 case LHU16:
14818 {
14819 int rd = mmreg(uMIPS_RD(ctx->opcode));
14820 int rb = mmreg(uMIPS_RS(ctx->opcode));
14821 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14822
d75c135e 14823 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14824 }
14825 break;
14826 case LWSP16:
14827 {
14828 int rd = (ctx->opcode >> 5) & 0x1f;
14829 int rb = 29; /* SP */
14830 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14831
d75c135e 14832 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14833 }
14834 break;
14835 case LW16:
14836 {
14837 int rd = mmreg(uMIPS_RD(ctx->opcode));
14838 int rb = mmreg(uMIPS_RS(ctx->opcode));
14839 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14840
d75c135e 14841 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14842 }
14843 break;
14844 case SB16:
14845 {
14846 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14847 int rb = mmreg(uMIPS_RS(ctx->opcode));
14848 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14849
5c13fdfd 14850 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14851 }
14852 break;
14853 case SH16:
14854 {
14855 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14856 int rb = mmreg(uMIPS_RS(ctx->opcode));
14857 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14858
5c13fdfd 14859 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14860 }
14861 break;
14862 case SWSP16:
14863 {
14864 int rd = (ctx->opcode >> 5) & 0x1f;
14865 int rb = 29; /* SP */
14866 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14867
5c13fdfd 14868 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14869 }
14870 break;
14871 case SW16:
14872 {
14873 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14874 int rb = mmreg(uMIPS_RS(ctx->opcode));
14875 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14876
5c13fdfd 14877 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14878 }
14879 break;
14880 case MOVE16:
14881 {
14882 int rd = uMIPS_RD5(ctx->opcode);
14883 int rs = uMIPS_RS5(ctx->opcode);
14884
7215d7e7 14885 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14886 }
14887 break;
14888 case ANDI16:
d75c135e 14889 gen_andi16(ctx);
3c824109
NF
14890 break;
14891 case POOL16D:
14892 switch (ctx->opcode & 0x1) {
14893 case ADDIUS5:
d75c135e 14894 gen_addius5(ctx);
3c824109
NF
14895 break;
14896 case ADDIUSP:
d75c135e 14897 gen_addiusp(ctx);
3c824109
NF
14898 break;
14899 }
14900 break;
14901 case POOL16E:
14902 switch (ctx->opcode & 0x1) {
14903 case ADDIUR2:
d75c135e 14904 gen_addiur2(ctx);
3c824109
NF
14905 break;
14906 case ADDIUR1SP:
d75c135e 14907 gen_addiur1sp(ctx);
3c824109
NF
14908 break;
14909 }
14910 break;
65935f07 14911 case B16: /* BC16 */
3c824109 14912 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
14913 sextract32(ctx->opcode, 0, 10) << 1,
14914 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 14915 break;
65935f07
YK
14916 case BNEZ16: /* BNEZC16 */
14917 case BEQZ16: /* BEQZC16 */
3c824109
NF
14918 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14919 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
14920 0, sextract32(ctx->opcode, 0, 7) << 1,
14921 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14922
3c824109
NF
14923 break;
14924 case LI16:
14925 {
14926 int reg = mmreg(uMIPS_RD(ctx->opcode));
14927 int imm = ZIMM(ctx->opcode, 0, 7);
14928
14929 imm = (imm == 0x7f ? -1 : imm);
14930 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14931 }
14932 break;
3c824109 14933 case RES_29:
3c824109 14934 case RES_31:
3c824109 14935 case RES_39:
9c708c7f 14936 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14937 break;
14938 default:
f60eeb0c 14939 decode_micromips32_opc(env, ctx);
3c824109
NF
14940 return 4;
14941 }
14942
14943 return 2;
14944}
14945
14946/* SmartMIPS extension to MIPS32 */
14947
14948#if defined(TARGET_MIPS64)
14949
14950/* MDMX extension to MIPS64 */
14951
14952#endif
14953
9b1a1d68 14954/* MIPSDSP functions. */
d75c135e 14955static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14956 int rd, int base, int offset)
14957{
9b1a1d68
JL
14958 TCGv t0;
14959
9b1a1d68
JL
14960 check_dsp(ctx);
14961 t0 = tcg_temp_new();
14962
14963 if (base == 0) {
14964 gen_load_gpr(t0, offset);
14965 } else if (offset == 0) {
14966 gen_load_gpr(t0, base);
14967 } else {
14968 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14969 }
14970
9b1a1d68
JL
14971 switch (opc) {
14972 case OPC_LBUX:
5f68f5ae 14973 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 14974 gen_store_gpr(t0, rd);
9b1a1d68
JL
14975 break;
14976 case OPC_LHX:
5f68f5ae 14977 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 14978 gen_store_gpr(t0, rd);
9b1a1d68
JL
14979 break;
14980 case OPC_LWX:
5f68f5ae 14981 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 14982 gen_store_gpr(t0, rd);
9b1a1d68
JL
14983 break;
14984#if defined(TARGET_MIPS64)
14985 case OPC_LDX:
5f68f5ae 14986 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 14987 gen_store_gpr(t0, rd);
9b1a1d68
JL
14988 break;
14989#endif
14990 }
9b1a1d68
JL
14991 tcg_temp_free(t0);
14992}
14993
461c08df
JL
14994static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14995 int ret, int v1, int v2)
14996{
461c08df
JL
14997 TCGv v1_t;
14998 TCGv v2_t;
14999
15000 if (ret == 0) {
15001 /* Treat as NOP. */
461c08df
JL
15002 return;
15003 }
15004
15005 v1_t = tcg_temp_new();
15006 v2_t = tcg_temp_new();
15007
15008 gen_load_gpr(v1_t, v1);
15009 gen_load_gpr(v2_t, v2);
15010
15011 switch (op1) {
15012 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15013 case OPC_MULT_G_2E:
15014 check_dspr2(ctx);
15015 switch (op2) {
15016 case OPC_ADDUH_QB:
15017 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15018 break;
15019 case OPC_ADDUH_R_QB:
15020 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15021 break;
15022 case OPC_ADDQH_PH:
15023 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15024 break;
15025 case OPC_ADDQH_R_PH:
15026 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15027 break;
15028 case OPC_ADDQH_W:
15029 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15030 break;
15031 case OPC_ADDQH_R_W:
15032 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15033 break;
15034 case OPC_SUBUH_QB:
15035 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15036 break;
15037 case OPC_SUBUH_R_QB:
15038 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15039 break;
15040 case OPC_SUBQH_PH:
15041 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15042 break;
15043 case OPC_SUBQH_R_PH:
15044 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15045 break;
15046 case OPC_SUBQH_W:
15047 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15048 break;
15049 case OPC_SUBQH_R_W:
15050 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15051 break;
15052 }
15053 break;
15054 case OPC_ABSQ_S_PH_DSP:
15055 switch (op2) {
15056 case OPC_ABSQ_S_QB:
15057 check_dspr2(ctx);
15058 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15059 break;
15060 case OPC_ABSQ_S_PH:
15061 check_dsp(ctx);
15062 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15063 break;
15064 case OPC_ABSQ_S_W:
15065 check_dsp(ctx);
15066 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15067 break;
15068 case OPC_PRECEQ_W_PHL:
15069 check_dsp(ctx);
15070 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15071 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15072 break;
15073 case OPC_PRECEQ_W_PHR:
15074 check_dsp(ctx);
15075 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15076 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15077 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15078 break;
15079 case OPC_PRECEQU_PH_QBL:
15080 check_dsp(ctx);
15081 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15082 break;
15083 case OPC_PRECEQU_PH_QBR:
15084 check_dsp(ctx);
15085 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15086 break;
15087 case OPC_PRECEQU_PH_QBLA:
15088 check_dsp(ctx);
15089 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15090 break;
15091 case OPC_PRECEQU_PH_QBRA:
15092 check_dsp(ctx);
15093 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15094 break;
15095 case OPC_PRECEU_PH_QBL:
15096 check_dsp(ctx);
15097 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15098 break;
15099 case OPC_PRECEU_PH_QBR:
15100 check_dsp(ctx);
15101 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15102 break;
15103 case OPC_PRECEU_PH_QBLA:
15104 check_dsp(ctx);
15105 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15106 break;
15107 case OPC_PRECEU_PH_QBRA:
15108 check_dsp(ctx);
15109 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15110 break;
15111 }
15112 break;
15113 case OPC_ADDU_QB_DSP:
15114 switch (op2) {
15115 case OPC_ADDQ_PH:
15116 check_dsp(ctx);
15117 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15118 break;
15119 case OPC_ADDQ_S_PH:
15120 check_dsp(ctx);
15121 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15122 break;
15123 case OPC_ADDQ_S_W:
15124 check_dsp(ctx);
15125 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15126 break;
15127 case OPC_ADDU_QB:
15128 check_dsp(ctx);
15129 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15130 break;
15131 case OPC_ADDU_S_QB:
15132 check_dsp(ctx);
15133 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15134 break;
15135 case OPC_ADDU_PH:
15136 check_dspr2(ctx);
15137 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15138 break;
15139 case OPC_ADDU_S_PH:
15140 check_dspr2(ctx);
15141 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15142 break;
15143 case OPC_SUBQ_PH:
15144 check_dsp(ctx);
15145 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15146 break;
15147 case OPC_SUBQ_S_PH:
15148 check_dsp(ctx);
15149 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15150 break;
15151 case OPC_SUBQ_S_W:
15152 check_dsp(ctx);
15153 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15154 break;
15155 case OPC_SUBU_QB:
15156 check_dsp(ctx);
15157 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15158 break;
15159 case OPC_SUBU_S_QB:
15160 check_dsp(ctx);
15161 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15162 break;
15163 case OPC_SUBU_PH:
15164 check_dspr2(ctx);
15165 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15166 break;
15167 case OPC_SUBU_S_PH:
15168 check_dspr2(ctx);
15169 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15170 break;
15171 case OPC_ADDSC:
15172 check_dsp(ctx);
15173 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15174 break;
15175 case OPC_ADDWC:
15176 check_dsp(ctx);
15177 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15178 break;
15179 case OPC_MODSUB:
15180 check_dsp(ctx);
15181 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15182 break;
15183 case OPC_RADDU_W_QB:
15184 check_dsp(ctx);
15185 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15186 break;
15187 }
15188 break;
15189 case OPC_CMPU_EQ_QB_DSP:
15190 switch (op2) {
15191 case OPC_PRECR_QB_PH:
15192 check_dspr2(ctx);
15193 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15194 break;
15195 case OPC_PRECRQ_QB_PH:
15196 check_dsp(ctx);
15197 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15198 break;
15199 case OPC_PRECR_SRA_PH_W:
15200 check_dspr2(ctx);
15201 {
15202 TCGv_i32 sa_t = tcg_const_i32(v2);
15203 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15204 cpu_gpr[ret]);
15205 tcg_temp_free_i32(sa_t);
15206 break;
15207 }
15208 case OPC_PRECR_SRA_R_PH_W:
15209 check_dspr2(ctx);
15210 {
15211 TCGv_i32 sa_t = tcg_const_i32(v2);
15212 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15213 cpu_gpr[ret]);
15214 tcg_temp_free_i32(sa_t);
15215 break;
15216 }
15217 case OPC_PRECRQ_PH_W:
15218 check_dsp(ctx);
15219 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15220 break;
15221 case OPC_PRECRQ_RS_PH_W:
15222 check_dsp(ctx);
15223 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15224 break;
15225 case OPC_PRECRQU_S_QB_PH:
15226 check_dsp(ctx);
15227 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15228 break;
15229 }
15230 break;
15231#ifdef TARGET_MIPS64
15232 case OPC_ABSQ_S_QH_DSP:
15233 switch (op2) {
15234 case OPC_PRECEQ_L_PWL:
15235 check_dsp(ctx);
15236 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15237 break;
15238 case OPC_PRECEQ_L_PWR:
15239 check_dsp(ctx);
15240 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15241 break;
15242 case OPC_PRECEQ_PW_QHL:
15243 check_dsp(ctx);
15244 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15245 break;
15246 case OPC_PRECEQ_PW_QHR:
15247 check_dsp(ctx);
15248 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15249 break;
15250 case OPC_PRECEQ_PW_QHLA:
15251 check_dsp(ctx);
15252 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15253 break;
15254 case OPC_PRECEQ_PW_QHRA:
15255 check_dsp(ctx);
15256 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15257 break;
15258 case OPC_PRECEQU_QH_OBL:
15259 check_dsp(ctx);
15260 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15261 break;
15262 case OPC_PRECEQU_QH_OBR:
15263 check_dsp(ctx);
15264 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15265 break;
15266 case OPC_PRECEQU_QH_OBLA:
15267 check_dsp(ctx);
15268 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15269 break;
15270 case OPC_PRECEQU_QH_OBRA:
15271 check_dsp(ctx);
15272 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15273 break;
15274 case OPC_PRECEU_QH_OBL:
15275 check_dsp(ctx);
15276 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15277 break;
15278 case OPC_PRECEU_QH_OBR:
15279 check_dsp(ctx);
15280 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15281 break;
15282 case OPC_PRECEU_QH_OBLA:
15283 check_dsp(ctx);
15284 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15285 break;
15286 case OPC_PRECEU_QH_OBRA:
15287 check_dsp(ctx);
15288 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15289 break;
15290 case OPC_ABSQ_S_OB:
15291 check_dspr2(ctx);
15292 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15293 break;
15294 case OPC_ABSQ_S_PW:
15295 check_dsp(ctx);
15296 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15297 break;
15298 case OPC_ABSQ_S_QH:
15299 check_dsp(ctx);
15300 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15301 break;
15302 }
15303 break;
15304 case OPC_ADDU_OB_DSP:
15305 switch (op2) {
15306 case OPC_RADDU_L_OB:
15307 check_dsp(ctx);
15308 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15309 break;
15310 case OPC_SUBQ_PW:
15311 check_dsp(ctx);
15312 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15313 break;
15314 case OPC_SUBQ_S_PW:
15315 check_dsp(ctx);
15316 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15317 break;
15318 case OPC_SUBQ_QH:
15319 check_dsp(ctx);
15320 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15321 break;
15322 case OPC_SUBQ_S_QH:
15323 check_dsp(ctx);
15324 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15325 break;
15326 case OPC_SUBU_OB:
15327 check_dsp(ctx);
15328 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15329 break;
15330 case OPC_SUBU_S_OB:
15331 check_dsp(ctx);
15332 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15333 break;
15334 case OPC_SUBU_QH:
15335 check_dspr2(ctx);
15336 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15337 break;
15338 case OPC_SUBU_S_QH:
15339 check_dspr2(ctx);
15340 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15341 break;
15342 case OPC_SUBUH_OB:
15343 check_dspr2(ctx);
15344 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15345 break;
15346 case OPC_SUBUH_R_OB:
15347 check_dspr2(ctx);
15348 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15349 break;
15350 case OPC_ADDQ_PW:
15351 check_dsp(ctx);
15352 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15353 break;
15354 case OPC_ADDQ_S_PW:
15355 check_dsp(ctx);
15356 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15357 break;
15358 case OPC_ADDQ_QH:
15359 check_dsp(ctx);
15360 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15361 break;
15362 case OPC_ADDQ_S_QH:
15363 check_dsp(ctx);
15364 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15365 break;
15366 case OPC_ADDU_OB:
15367 check_dsp(ctx);
15368 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15369 break;
15370 case OPC_ADDU_S_OB:
15371 check_dsp(ctx);
15372 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15373 break;
15374 case OPC_ADDU_QH:
15375 check_dspr2(ctx);
15376 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15377 break;
15378 case OPC_ADDU_S_QH:
15379 check_dspr2(ctx);
15380 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15381 break;
15382 case OPC_ADDUH_OB:
15383 check_dspr2(ctx);
15384 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15385 break;
15386 case OPC_ADDUH_R_OB:
15387 check_dspr2(ctx);
15388 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15389 break;
15390 }
15391 break;
15392 case OPC_CMPU_EQ_OB_DSP:
15393 switch (op2) {
15394 case OPC_PRECR_OB_QH:
15395 check_dspr2(ctx);
15396 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15397 break;
15398 case OPC_PRECR_SRA_QH_PW:
15399 check_dspr2(ctx);
15400 {
15401 TCGv_i32 ret_t = tcg_const_i32(ret);
15402 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15403 tcg_temp_free_i32(ret_t);
15404 break;
15405 }
15406 case OPC_PRECR_SRA_R_QH_PW:
15407 check_dspr2(ctx);
15408 {
15409 TCGv_i32 sa_v = tcg_const_i32(ret);
15410 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15411 tcg_temp_free_i32(sa_v);
15412 break;
15413 }
15414 case OPC_PRECRQ_OB_QH:
15415 check_dsp(ctx);
15416 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15417 break;
15418 case OPC_PRECRQ_PW_L:
15419 check_dsp(ctx);
15420 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15421 break;
15422 case OPC_PRECRQ_QH_PW:
15423 check_dsp(ctx);
15424 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15425 break;
15426 case OPC_PRECRQ_RS_QH_PW:
15427 check_dsp(ctx);
15428 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15429 break;
15430 case OPC_PRECRQU_S_OB_QH:
15431 check_dsp(ctx);
15432 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15433 break;
15434 }
15435 break;
15436#endif
15437 }
15438
15439 tcg_temp_free(v1_t);
15440 tcg_temp_free(v2_t);
461c08df 15441}
9b1a1d68 15442
77c5fa8b
JL
15443static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15444 int ret, int v1, int v2)
15445{
15446 uint32_t op2;
77c5fa8b
JL
15447 TCGv t0;
15448 TCGv v1_t;
15449 TCGv v2_t;
15450
15451 if (ret == 0) {
15452 /* Treat as NOP. */
77c5fa8b
JL
15453 return;
15454 }
15455
15456 t0 = tcg_temp_new();
15457 v1_t = tcg_temp_new();
15458 v2_t = tcg_temp_new();
15459
15460 tcg_gen_movi_tl(t0, v1);
15461 gen_load_gpr(v1_t, v1);
15462 gen_load_gpr(v2_t, v2);
15463
15464 switch (opc) {
15465 case OPC_SHLL_QB_DSP:
15466 {
15467 op2 = MASK_SHLL_QB(ctx->opcode);
15468 switch (op2) {
15469 case OPC_SHLL_QB:
15470 check_dsp(ctx);
15471 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15472 break;
15473 case OPC_SHLLV_QB:
15474 check_dsp(ctx);
15475 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15476 break;
15477 case OPC_SHLL_PH:
15478 check_dsp(ctx);
15479 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15480 break;
15481 case OPC_SHLLV_PH:
15482 check_dsp(ctx);
15483 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15484 break;
15485 case OPC_SHLL_S_PH:
15486 check_dsp(ctx);
15487 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15488 break;
15489 case OPC_SHLLV_S_PH:
15490 check_dsp(ctx);
15491 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15492 break;
15493 case OPC_SHLL_S_W:
15494 check_dsp(ctx);
15495 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15496 break;
15497 case OPC_SHLLV_S_W:
15498 check_dsp(ctx);
15499 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15500 break;
15501 case OPC_SHRL_QB:
15502 check_dsp(ctx);
15503 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15504 break;
15505 case OPC_SHRLV_QB:
15506 check_dsp(ctx);
15507 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15508 break;
15509 case OPC_SHRL_PH:
15510 check_dspr2(ctx);
15511 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15512 break;
15513 case OPC_SHRLV_PH:
15514 check_dspr2(ctx);
15515 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15516 break;
15517 case OPC_SHRA_QB:
15518 check_dspr2(ctx);
15519 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15520 break;
15521 case OPC_SHRA_R_QB:
15522 check_dspr2(ctx);
15523 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15524 break;
15525 case OPC_SHRAV_QB:
15526 check_dspr2(ctx);
15527 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15528 break;
15529 case OPC_SHRAV_R_QB:
15530 check_dspr2(ctx);
15531 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15532 break;
15533 case OPC_SHRA_PH:
15534 check_dsp(ctx);
15535 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15536 break;
15537 case OPC_SHRA_R_PH:
15538 check_dsp(ctx);
15539 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15540 break;
15541 case OPC_SHRAV_PH:
15542 check_dsp(ctx);
15543 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15544 break;
15545 case OPC_SHRAV_R_PH:
15546 check_dsp(ctx);
15547 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15548 break;
15549 case OPC_SHRA_R_W:
15550 check_dsp(ctx);
15551 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15552 break;
15553 case OPC_SHRAV_R_W:
15554 check_dsp(ctx);
15555 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15556 break;
15557 default: /* Invalid */
15558 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 15559 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15560 break;
15561 }
15562 break;
15563 }
15564#ifdef TARGET_MIPS64
15565 case OPC_SHLL_OB_DSP:
15566 op2 = MASK_SHLL_OB(ctx->opcode);
15567 switch (op2) {
15568 case OPC_SHLL_PW:
15569 check_dsp(ctx);
15570 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15571 break;
15572 case OPC_SHLLV_PW:
15573 check_dsp(ctx);
15574 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15575 break;
15576 case OPC_SHLL_S_PW:
15577 check_dsp(ctx);
15578 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15579 break;
15580 case OPC_SHLLV_S_PW:
15581 check_dsp(ctx);
15582 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15583 break;
15584 case OPC_SHLL_OB:
15585 check_dsp(ctx);
15586 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15587 break;
15588 case OPC_SHLLV_OB:
15589 check_dsp(ctx);
15590 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15591 break;
15592 case OPC_SHLL_QH:
15593 check_dsp(ctx);
15594 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15595 break;
15596 case OPC_SHLLV_QH:
15597 check_dsp(ctx);
15598 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15599 break;
15600 case OPC_SHLL_S_QH:
15601 check_dsp(ctx);
15602 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15603 break;
15604 case OPC_SHLLV_S_QH:
15605 check_dsp(ctx);
15606 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15607 break;
15608 case OPC_SHRA_OB:
15609 check_dspr2(ctx);
15610 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15611 break;
15612 case OPC_SHRAV_OB:
15613 check_dspr2(ctx);
15614 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15615 break;
15616 case OPC_SHRA_R_OB:
15617 check_dspr2(ctx);
15618 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15619 break;
15620 case OPC_SHRAV_R_OB:
15621 check_dspr2(ctx);
15622 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15623 break;
15624 case OPC_SHRA_PW:
15625 check_dsp(ctx);
15626 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15627 break;
15628 case OPC_SHRAV_PW:
15629 check_dsp(ctx);
15630 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15631 break;
15632 case OPC_SHRA_R_PW:
15633 check_dsp(ctx);
15634 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15635 break;
15636 case OPC_SHRAV_R_PW:
15637 check_dsp(ctx);
15638 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15639 break;
15640 case OPC_SHRA_QH:
15641 check_dsp(ctx);
15642 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15643 break;
15644 case OPC_SHRAV_QH:
15645 check_dsp(ctx);
15646 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15647 break;
15648 case OPC_SHRA_R_QH:
15649 check_dsp(ctx);
15650 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15651 break;
15652 case OPC_SHRAV_R_QH:
15653 check_dsp(ctx);
15654 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15655 break;
15656 case OPC_SHRL_OB:
15657 check_dsp(ctx);
15658 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15659 break;
15660 case OPC_SHRLV_OB:
15661 check_dsp(ctx);
15662 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15663 break;
15664 case OPC_SHRL_QH:
15665 check_dspr2(ctx);
15666 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15667 break;
15668 case OPC_SHRLV_QH:
15669 check_dspr2(ctx);
15670 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15671 break;
15672 default: /* Invalid */
15673 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 15674 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15675 break;
15676 }
15677 break;
15678#endif
15679 }
15680
15681 tcg_temp_free(t0);
15682 tcg_temp_free(v1_t);
15683 tcg_temp_free(v2_t);
77c5fa8b
JL
15684}
15685
a22260ae
JL
15686static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15687 int ret, int v1, int v2, int check_ret)
15688{
a22260ae
JL
15689 TCGv_i32 t0;
15690 TCGv v1_t;
15691 TCGv v2_t;
15692
15693 if ((ret == 0) && (check_ret == 1)) {
15694 /* Treat as NOP. */
a22260ae
JL
15695 return;
15696 }
15697
15698 t0 = tcg_temp_new_i32();
15699 v1_t = tcg_temp_new();
15700 v2_t = tcg_temp_new();
15701
15702 tcg_gen_movi_i32(t0, ret);
15703 gen_load_gpr(v1_t, v1);
15704 gen_load_gpr(v2_t, v2);
15705
15706 switch (op1) {
15707 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15708 * the same mask and op1. */
15709 case OPC_MULT_G_2E:
639eadb9 15710 check_dspr2(ctx);
a22260ae
JL
15711 switch (op2) {
15712 case OPC_MUL_PH:
15713 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15714 break;
15715 case OPC_MUL_S_PH:
15716 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15717 break;
15718 case OPC_MULQ_S_W:
15719 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15720 break;
15721 case OPC_MULQ_RS_W:
15722 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15723 break;
15724 }
15725 break;
15726 case OPC_DPA_W_PH_DSP:
15727 switch (op2) {
15728 case OPC_DPAU_H_QBL:
15729 check_dsp(ctx);
15730 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15731 break;
15732 case OPC_DPAU_H_QBR:
15733 check_dsp(ctx);
15734 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15735 break;
15736 case OPC_DPSU_H_QBL:
15737 check_dsp(ctx);
15738 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15739 break;
15740 case OPC_DPSU_H_QBR:
15741 check_dsp(ctx);
15742 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15743 break;
15744 case OPC_DPA_W_PH:
15745 check_dspr2(ctx);
15746 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15747 break;
15748 case OPC_DPAX_W_PH:
15749 check_dspr2(ctx);
15750 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15751 break;
15752 case OPC_DPAQ_S_W_PH:
15753 check_dsp(ctx);
15754 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15755 break;
15756 case OPC_DPAQX_S_W_PH:
15757 check_dspr2(ctx);
15758 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15759 break;
15760 case OPC_DPAQX_SA_W_PH:
15761 check_dspr2(ctx);
15762 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15763 break;
15764 case OPC_DPS_W_PH:
15765 check_dspr2(ctx);
15766 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15767 break;
15768 case OPC_DPSX_W_PH:
15769 check_dspr2(ctx);
15770 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15771 break;
15772 case OPC_DPSQ_S_W_PH:
15773 check_dsp(ctx);
15774 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15775 break;
15776 case OPC_DPSQX_S_W_PH:
15777 check_dspr2(ctx);
15778 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15779 break;
15780 case OPC_DPSQX_SA_W_PH:
15781 check_dspr2(ctx);
15782 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15783 break;
15784 case OPC_MULSAQ_S_W_PH:
15785 check_dsp(ctx);
15786 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15787 break;
15788 case OPC_DPAQ_SA_L_W:
15789 check_dsp(ctx);
15790 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15791 break;
15792 case OPC_DPSQ_SA_L_W:
15793 check_dsp(ctx);
15794 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15795 break;
15796 case OPC_MAQ_S_W_PHL:
15797 check_dsp(ctx);
15798 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15799 break;
15800 case OPC_MAQ_S_W_PHR:
15801 check_dsp(ctx);
15802 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15803 break;
15804 case OPC_MAQ_SA_W_PHL:
15805 check_dsp(ctx);
15806 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15807 break;
15808 case OPC_MAQ_SA_W_PHR:
15809 check_dsp(ctx);
15810 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_MULSA_W_PH:
15813 check_dspr2(ctx);
15814 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15815 break;
15816 }
15817 break;
15818#ifdef TARGET_MIPS64
15819 case OPC_DPAQ_W_QH_DSP:
15820 {
15821 int ac = ret & 0x03;
15822 tcg_gen_movi_i32(t0, ac);
15823
15824 switch (op2) {
15825 case OPC_DMADD:
15826 check_dsp(ctx);
15827 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15828 break;
15829 case OPC_DMADDU:
15830 check_dsp(ctx);
15831 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15832 break;
15833 case OPC_DMSUB:
15834 check_dsp(ctx);
15835 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15836 break;
15837 case OPC_DMSUBU:
15838 check_dsp(ctx);
15839 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15840 break;
15841 case OPC_DPA_W_QH:
15842 check_dspr2(ctx);
15843 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15844 break;
15845 case OPC_DPAQ_S_W_QH:
15846 check_dsp(ctx);
15847 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15848 break;
15849 case OPC_DPAQ_SA_L_PW:
15850 check_dsp(ctx);
15851 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15852 break;
15853 case OPC_DPAU_H_OBL:
15854 check_dsp(ctx);
15855 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15856 break;
15857 case OPC_DPAU_H_OBR:
15858 check_dsp(ctx);
15859 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15860 break;
15861 case OPC_DPS_W_QH:
15862 check_dspr2(ctx);
15863 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15864 break;
15865 case OPC_DPSQ_S_W_QH:
15866 check_dsp(ctx);
15867 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15868 break;
15869 case OPC_DPSQ_SA_L_PW:
15870 check_dsp(ctx);
15871 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15872 break;
15873 case OPC_DPSU_H_OBL:
15874 check_dsp(ctx);
15875 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15876 break;
15877 case OPC_DPSU_H_OBR:
15878 check_dsp(ctx);
15879 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15880 break;
15881 case OPC_MAQ_S_L_PWL:
15882 check_dsp(ctx);
15883 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15884 break;
15885 case OPC_MAQ_S_L_PWR:
15886 check_dsp(ctx);
15887 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15888 break;
15889 case OPC_MAQ_S_W_QHLL:
15890 check_dsp(ctx);
15891 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15892 break;
15893 case OPC_MAQ_SA_W_QHLL:
15894 check_dsp(ctx);
15895 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15896 break;
15897 case OPC_MAQ_S_W_QHLR:
15898 check_dsp(ctx);
15899 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15900 break;
15901 case OPC_MAQ_SA_W_QHLR:
15902 check_dsp(ctx);
15903 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15904 break;
15905 case OPC_MAQ_S_W_QHRL:
15906 check_dsp(ctx);
15907 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15908 break;
15909 case OPC_MAQ_SA_W_QHRL:
15910 check_dsp(ctx);
15911 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15912 break;
15913 case OPC_MAQ_S_W_QHRR:
15914 check_dsp(ctx);
15915 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15916 break;
15917 case OPC_MAQ_SA_W_QHRR:
15918 check_dsp(ctx);
15919 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15920 break;
15921 case OPC_MULSAQ_S_L_PW:
15922 check_dsp(ctx);
15923 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15924 break;
15925 case OPC_MULSAQ_S_W_QH:
15926 check_dsp(ctx);
15927 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15928 break;
15929 }
15930 }
15931 break;
15932#endif
15933 case OPC_ADDU_QB_DSP:
15934 switch (op2) {
15935 case OPC_MULEU_S_PH_QBL:
15936 check_dsp(ctx);
15937 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15938 break;
15939 case OPC_MULEU_S_PH_QBR:
15940 check_dsp(ctx);
15941 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15942 break;
15943 case OPC_MULQ_RS_PH:
15944 check_dsp(ctx);
15945 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15946 break;
15947 case OPC_MULEQ_S_W_PHL:
15948 check_dsp(ctx);
15949 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15950 break;
15951 case OPC_MULEQ_S_W_PHR:
15952 check_dsp(ctx);
15953 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15954 break;
15955 case OPC_MULQ_S_PH:
15956 check_dspr2(ctx);
15957 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15958 break;
15959 }
15960 break;
15961#ifdef TARGET_MIPS64
15962 case OPC_ADDU_OB_DSP:
15963 switch (op2) {
15964 case OPC_MULEQ_S_PW_QHL:
15965 check_dsp(ctx);
15966 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15967 break;
15968 case OPC_MULEQ_S_PW_QHR:
15969 check_dsp(ctx);
15970 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15971 break;
15972 case OPC_MULEU_S_QH_OBL:
15973 check_dsp(ctx);
15974 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15975 break;
15976 case OPC_MULEU_S_QH_OBR:
15977 check_dsp(ctx);
15978 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15979 break;
15980 case OPC_MULQ_RS_QH:
15981 check_dsp(ctx);
15982 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15983 break;
15984 }
15985 break;
15986#endif
15987 }
15988
15989 tcg_temp_free_i32(t0);
15990 tcg_temp_free(v1_t);
15991 tcg_temp_free(v2_t);
a22260ae
JL
15992}
15993
d75c135e 15994static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15995 int ret, int val)
15996{
1cb6686c
JL
15997 int16_t imm;
15998 TCGv t0;
15999 TCGv val_t;
16000
16001 if (ret == 0) {
16002 /* Treat as NOP. */
1cb6686c
JL
16003 return;
16004 }
16005
16006 t0 = tcg_temp_new();
16007 val_t = tcg_temp_new();
16008 gen_load_gpr(val_t, val);
16009
16010 switch (op1) {
16011 case OPC_ABSQ_S_PH_DSP:
16012 switch (op2) {
16013 case OPC_BITREV:
16014 check_dsp(ctx);
16015 gen_helper_bitrev(cpu_gpr[ret], val_t);
16016 break;
16017 case OPC_REPL_QB:
16018 check_dsp(ctx);
16019 {
16020 target_long result;
16021 imm = (ctx->opcode >> 16) & 0xFF;
16022 result = (uint32_t)imm << 24 |
16023 (uint32_t)imm << 16 |
16024 (uint32_t)imm << 8 |
16025 (uint32_t)imm;
16026 result = (int32_t)result;
16027 tcg_gen_movi_tl(cpu_gpr[ret], result);
16028 }
16029 break;
16030 case OPC_REPLV_QB:
16031 check_dsp(ctx);
16032 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16033 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16034 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16035 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16036 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16037 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16038 break;
16039 case OPC_REPL_PH:
16040 check_dsp(ctx);
16041 {
16042 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16043 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16044 tcg_gen_movi_tl(cpu_gpr[ret], \
16045 (target_long)((int32_t)imm << 16 | \
c4aaba92 16046 (uint16_t)imm));
1cb6686c
JL
16047 }
16048 break;
16049 case OPC_REPLV_PH:
16050 check_dsp(ctx);
16051 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16052 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16053 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16054 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16055 break;
16056 }
16057 break;
16058#ifdef TARGET_MIPS64
16059 case OPC_ABSQ_S_QH_DSP:
16060 switch (op2) {
16061 case OPC_REPL_OB:
16062 check_dsp(ctx);
16063 {
16064 target_long temp;
16065
16066 imm = (ctx->opcode >> 16) & 0xFF;
16067 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16068 temp = (temp << 16) | temp;
16069 temp = (temp << 32) | temp;
16070 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16071 break;
16072 }
16073 case OPC_REPL_PW:
16074 check_dsp(ctx);
16075 {
16076 target_long temp;
16077
16078 imm = (ctx->opcode >> 16) & 0x03FF;
16079 imm = (int16_t)(imm << 6) >> 6;
16080 temp = ((target_long)imm << 32) \
16081 | ((target_long)imm & 0xFFFFFFFF);
16082 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16083 break;
16084 }
16085 case OPC_REPL_QH:
16086 check_dsp(ctx);
16087 {
16088 target_long temp;
16089
16090 imm = (ctx->opcode >> 16) & 0x03FF;
16091 imm = (int16_t)(imm << 6) >> 6;
16092
16093 temp = ((uint64_t)(uint16_t)imm << 48) |
16094 ((uint64_t)(uint16_t)imm << 32) |
16095 ((uint64_t)(uint16_t)imm << 16) |
16096 (uint64_t)(uint16_t)imm;
16097 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16098 break;
16099 }
16100 case OPC_REPLV_OB:
16101 check_dsp(ctx);
16102 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16103 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16104 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16105 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16106 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16107 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16108 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16109 break;
16110 case OPC_REPLV_PW:
16111 check_dsp(ctx);
16112 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16113 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16114 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16115 break;
16116 case OPC_REPLV_QH:
16117 check_dsp(ctx);
16118 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16119 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16120 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16121 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16122 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16123 break;
16124 }
16125 break;
16126#endif
16127 }
16128 tcg_temp_free(t0);
16129 tcg_temp_free(val_t);
1cb6686c
JL
16130}
16131
26690560
JL
16132static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16133 uint32_t op1, uint32_t op2,
16134 int ret, int v1, int v2, int check_ret)
16135{
26690560
JL
16136 TCGv t1;
16137 TCGv v1_t;
16138 TCGv v2_t;
16139
16140 if ((ret == 0) && (check_ret == 1)) {
16141 /* Treat as NOP. */
26690560
JL
16142 return;
16143 }
16144
26690560
JL
16145 t1 = tcg_temp_new();
16146 v1_t = tcg_temp_new();
16147 v2_t = tcg_temp_new();
16148
16149 gen_load_gpr(v1_t, v1);
16150 gen_load_gpr(v2_t, v2);
16151
16152 switch (op1) {
26690560
JL
16153 case OPC_CMPU_EQ_QB_DSP:
16154 switch (op2) {
16155 case OPC_CMPU_EQ_QB:
16156 check_dsp(ctx);
16157 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16158 break;
16159 case OPC_CMPU_LT_QB:
16160 check_dsp(ctx);
16161 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16162 break;
16163 case OPC_CMPU_LE_QB:
16164 check_dsp(ctx);
16165 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16166 break;
16167 case OPC_CMPGU_EQ_QB:
16168 check_dsp(ctx);
16169 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16170 break;
16171 case OPC_CMPGU_LT_QB:
16172 check_dsp(ctx);
16173 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16174 break;
16175 case OPC_CMPGU_LE_QB:
16176 check_dsp(ctx);
16177 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16178 break;
16179 case OPC_CMPGDU_EQ_QB:
16180 check_dspr2(ctx);
16181 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16182 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16183 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16184 tcg_gen_shli_tl(t1, t1, 24);
16185 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16186 break;
16187 case OPC_CMPGDU_LT_QB:
16188 check_dspr2(ctx);
16189 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16190 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16191 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16192 tcg_gen_shli_tl(t1, t1, 24);
16193 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16194 break;
16195 case OPC_CMPGDU_LE_QB:
16196 check_dspr2(ctx);
16197 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16198 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16199 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16200 tcg_gen_shli_tl(t1, t1, 24);
16201 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16202 break;
16203 case OPC_CMP_EQ_PH:
16204 check_dsp(ctx);
16205 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16206 break;
16207 case OPC_CMP_LT_PH:
16208 check_dsp(ctx);
16209 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16210 break;
16211 case OPC_CMP_LE_PH:
16212 check_dsp(ctx);
16213 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16214 break;
16215 case OPC_PICK_QB:
16216 check_dsp(ctx);
16217 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16218 break;
16219 case OPC_PICK_PH:
16220 check_dsp(ctx);
16221 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16222 break;
16223 case OPC_PACKRL_PH:
16224 check_dsp(ctx);
16225 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16226 break;
16227 }
16228 break;
16229#ifdef TARGET_MIPS64
16230 case OPC_CMPU_EQ_OB_DSP:
16231 switch (op2) {
16232 case OPC_CMP_EQ_PW:
16233 check_dsp(ctx);
16234 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16235 break;
16236 case OPC_CMP_LT_PW:
16237 check_dsp(ctx);
16238 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16239 break;
16240 case OPC_CMP_LE_PW:
16241 check_dsp(ctx);
16242 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16243 break;
16244 case OPC_CMP_EQ_QH:
16245 check_dsp(ctx);
16246 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16247 break;
16248 case OPC_CMP_LT_QH:
16249 check_dsp(ctx);
16250 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16251 break;
16252 case OPC_CMP_LE_QH:
16253 check_dsp(ctx);
16254 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16255 break;
16256 case OPC_CMPGDU_EQ_OB:
16257 check_dspr2(ctx);
16258 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16259 break;
16260 case OPC_CMPGDU_LT_OB:
16261 check_dspr2(ctx);
16262 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16263 break;
16264 case OPC_CMPGDU_LE_OB:
16265 check_dspr2(ctx);
16266 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16267 break;
16268 case OPC_CMPGU_EQ_OB:
16269 check_dsp(ctx);
16270 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16271 break;
16272 case OPC_CMPGU_LT_OB:
16273 check_dsp(ctx);
16274 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16275 break;
16276 case OPC_CMPGU_LE_OB:
16277 check_dsp(ctx);
16278 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16279 break;
16280 case OPC_CMPU_EQ_OB:
16281 check_dsp(ctx);
16282 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16283 break;
16284 case OPC_CMPU_LT_OB:
16285 check_dsp(ctx);
16286 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16287 break;
16288 case OPC_CMPU_LE_OB:
16289 check_dsp(ctx);
16290 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16291 break;
16292 case OPC_PACKRL_PW:
16293 check_dsp(ctx);
16294 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16295 break;
16296 case OPC_PICK_OB:
16297 check_dsp(ctx);
16298 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16299 break;
16300 case OPC_PICK_PW:
16301 check_dsp(ctx);
16302 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16303 break;
16304 case OPC_PICK_QH:
16305 check_dsp(ctx);
16306 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16307 break;
16308 }
16309 break;
df6126a7
AJ
16310#endif
16311 }
16312
16313 tcg_temp_free(t1);
16314 tcg_temp_free(v1_t);
16315 tcg_temp_free(v2_t);
df6126a7
AJ
16316}
16317
16318static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16319 uint32_t op1, int rt, int rs, int sa)
16320{
df6126a7
AJ
16321 TCGv t0;
16322
16323 check_dspr2(ctx);
16324
16325 if (rt == 0) {
16326 /* Treat as NOP. */
df6126a7
AJ
16327 return;
16328 }
16329
16330 t0 = tcg_temp_new();
16331 gen_load_gpr(t0, rs);
16332
16333 switch (op1) {
16334 case OPC_APPEND_DSP:
16335 switch (MASK_APPEND(ctx->opcode)) {
16336 case OPC_APPEND:
16337 if (sa != 0) {
16338 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16339 }
16340 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16341 break;
16342 case OPC_PREPEND:
16343 if (sa != 0) {
16344 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16345 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16346 tcg_gen_shli_tl(t0, t0, 32 - sa);
16347 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16348 }
16349 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16350 break;
16351 case OPC_BALIGN:
16352 sa &= 3;
16353 if (sa != 0 && sa != 2) {
16354 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16355 tcg_gen_ext32u_tl(t0, t0);
16356 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16357 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16358 }
16359 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16360 break;
16361 default: /* Invalid */
16362 MIPS_INVAL("MASK APPEND");
9c708c7f 16363 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16364 break;
16365 }
16366 break;
16367#ifdef TARGET_MIPS64
26690560 16368 case OPC_DAPPEND_DSP:
df6126a7 16369 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16370 case OPC_DAPPEND:
df6126a7
AJ
16371 if (sa != 0) {
16372 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16373 }
26690560
JL
16374 break;
16375 case OPC_PREPENDD:
df6126a7
AJ
16376 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16377 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16378 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16379 break;
16380 case OPC_PREPENDW:
df6126a7
AJ
16381 if (sa != 0) {
16382 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16383 tcg_gen_shli_tl(t0, t0, 64 - sa);
16384 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16385 }
26690560
JL
16386 break;
16387 case OPC_DBALIGN:
df6126a7
AJ
16388 sa &= 7;
16389 if (sa != 0 && sa != 2 && sa != 4) {
16390 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16391 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16392 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16393 }
26690560
JL
16394 break;
16395 default: /* Invalid */
16396 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16397 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16398 break;
16399 }
16400 break;
16401#endif
16402 }
df6126a7 16403 tcg_temp_free(t0);
26690560
JL
16404}
16405
b53371ed
JL
16406static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16407 int ret, int v1, int v2, int check_ret)
16408
16409{
b53371ed
JL
16410 TCGv t0;
16411 TCGv t1;
16412 TCGv v1_t;
16413 TCGv v2_t;
16414 int16_t imm;
16415
16416 if ((ret == 0) && (check_ret == 1)) {
16417 /* Treat as NOP. */
b53371ed
JL
16418 return;
16419 }
16420
16421 t0 = tcg_temp_new();
16422 t1 = tcg_temp_new();
16423 v1_t = tcg_temp_new();
16424 v2_t = tcg_temp_new();
16425
16426 gen_load_gpr(v1_t, v1);
16427 gen_load_gpr(v2_t, v2);
16428
16429 switch (op1) {
16430 case OPC_EXTR_W_DSP:
16431 check_dsp(ctx);
16432 switch (op2) {
16433 case OPC_EXTR_W:
16434 tcg_gen_movi_tl(t0, v2);
16435 tcg_gen_movi_tl(t1, v1);
16436 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16437 break;
16438 case OPC_EXTR_R_W:
16439 tcg_gen_movi_tl(t0, v2);
16440 tcg_gen_movi_tl(t1, v1);
16441 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16442 break;
16443 case OPC_EXTR_RS_W:
16444 tcg_gen_movi_tl(t0, v2);
16445 tcg_gen_movi_tl(t1, v1);
16446 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16447 break;
16448 case OPC_EXTR_S_H:
16449 tcg_gen_movi_tl(t0, v2);
16450 tcg_gen_movi_tl(t1, v1);
16451 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16452 break;
16453 case OPC_EXTRV_S_H:
16454 tcg_gen_movi_tl(t0, v2);
16455 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16456 break;
16457 case OPC_EXTRV_W:
16458 tcg_gen_movi_tl(t0, v2);
16459 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16460 break;
16461 case OPC_EXTRV_R_W:
16462 tcg_gen_movi_tl(t0, v2);
16463 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16464 break;
16465 case OPC_EXTRV_RS_W:
16466 tcg_gen_movi_tl(t0, v2);
16467 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16468 break;
16469 case OPC_EXTP:
16470 tcg_gen_movi_tl(t0, v2);
16471 tcg_gen_movi_tl(t1, v1);
16472 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16473 break;
16474 case OPC_EXTPV:
16475 tcg_gen_movi_tl(t0, v2);
16476 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16477 break;
16478 case OPC_EXTPDP:
16479 tcg_gen_movi_tl(t0, v2);
16480 tcg_gen_movi_tl(t1, v1);
16481 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16482 break;
16483 case OPC_EXTPDPV:
16484 tcg_gen_movi_tl(t0, v2);
16485 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16486 break;
16487 case OPC_SHILO:
16488 imm = (ctx->opcode >> 20) & 0x3F;
16489 tcg_gen_movi_tl(t0, ret);
16490 tcg_gen_movi_tl(t1, imm);
16491 gen_helper_shilo(t0, t1, cpu_env);
16492 break;
16493 case OPC_SHILOV:
16494 tcg_gen_movi_tl(t0, ret);
16495 gen_helper_shilo(t0, v1_t, cpu_env);
16496 break;
16497 case OPC_MTHLIP:
16498 tcg_gen_movi_tl(t0, ret);
16499 gen_helper_mthlip(t0, v1_t, cpu_env);
16500 break;
16501 case OPC_WRDSP:
16502 imm = (ctx->opcode >> 11) & 0x3FF;
16503 tcg_gen_movi_tl(t0, imm);
16504 gen_helper_wrdsp(v1_t, t0, cpu_env);
16505 break;
16506 case OPC_RDDSP:
16507 imm = (ctx->opcode >> 16) & 0x03FF;
16508 tcg_gen_movi_tl(t0, imm);
16509 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16510 break;
16511 }
16512 break;
16513#ifdef TARGET_MIPS64
16514 case OPC_DEXTR_W_DSP:
16515 check_dsp(ctx);
16516 switch (op2) {
16517 case OPC_DMTHLIP:
16518 tcg_gen_movi_tl(t0, ret);
16519 gen_helper_dmthlip(v1_t, t0, cpu_env);
16520 break;
16521 case OPC_DSHILO:
16522 {
16523 int shift = (ctx->opcode >> 19) & 0x7F;
16524 int ac = (ctx->opcode >> 11) & 0x03;
16525 tcg_gen_movi_tl(t0, shift);
16526 tcg_gen_movi_tl(t1, ac);
16527 gen_helper_dshilo(t0, t1, cpu_env);
16528 break;
16529 }
16530 case OPC_DSHILOV:
16531 {
16532 int ac = (ctx->opcode >> 11) & 0x03;
16533 tcg_gen_movi_tl(t0, ac);
16534 gen_helper_dshilo(v1_t, t0, cpu_env);
16535 break;
16536 }
16537 case OPC_DEXTP:
16538 tcg_gen_movi_tl(t0, v2);
16539 tcg_gen_movi_tl(t1, v1);
16540
16541 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16542 break;
16543 case OPC_DEXTPV:
16544 tcg_gen_movi_tl(t0, v2);
16545 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16546 break;
16547 case OPC_DEXTPDP:
16548 tcg_gen_movi_tl(t0, v2);
16549 tcg_gen_movi_tl(t1, v1);
16550 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16551 break;
16552 case OPC_DEXTPDPV:
16553 tcg_gen_movi_tl(t0, v2);
16554 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16555 break;
16556 case OPC_DEXTR_L:
16557 tcg_gen_movi_tl(t0, v2);
16558 tcg_gen_movi_tl(t1, v1);
16559 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16560 break;
16561 case OPC_DEXTR_R_L:
16562 tcg_gen_movi_tl(t0, v2);
16563 tcg_gen_movi_tl(t1, v1);
16564 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16565 break;
16566 case OPC_DEXTR_RS_L:
16567 tcg_gen_movi_tl(t0, v2);
16568 tcg_gen_movi_tl(t1, v1);
16569 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16570 break;
16571 case OPC_DEXTR_W:
16572 tcg_gen_movi_tl(t0, v2);
16573 tcg_gen_movi_tl(t1, v1);
16574 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16575 break;
16576 case OPC_DEXTR_R_W:
16577 tcg_gen_movi_tl(t0, v2);
16578 tcg_gen_movi_tl(t1, v1);
16579 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16580 break;
16581 case OPC_DEXTR_RS_W:
16582 tcg_gen_movi_tl(t0, v2);
16583 tcg_gen_movi_tl(t1, v1);
16584 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16585 break;
16586 case OPC_DEXTR_S_H:
16587 tcg_gen_movi_tl(t0, v2);
16588 tcg_gen_movi_tl(t1, v1);
16589 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16590 break;
16591 case OPC_DEXTRV_S_H:
16592 tcg_gen_movi_tl(t0, v2);
16593 tcg_gen_movi_tl(t1, v1);
16594 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16595 break;
16596 case OPC_DEXTRV_L:
16597 tcg_gen_movi_tl(t0, v2);
16598 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16599 break;
16600 case OPC_DEXTRV_R_L:
16601 tcg_gen_movi_tl(t0, v2);
16602 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16603 break;
16604 case OPC_DEXTRV_RS_L:
16605 tcg_gen_movi_tl(t0, v2);
16606 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16607 break;
16608 case OPC_DEXTRV_W:
16609 tcg_gen_movi_tl(t0, v2);
16610 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16611 break;
16612 case OPC_DEXTRV_R_W:
16613 tcg_gen_movi_tl(t0, v2);
16614 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16615 break;
16616 case OPC_DEXTRV_RS_W:
16617 tcg_gen_movi_tl(t0, v2);
16618 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16619 break;
16620 }
16621 break;
16622#endif
16623 }
16624
16625 tcg_temp_free(t0);
16626 tcg_temp_free(t1);
16627 tcg_temp_free(v1_t);
16628 tcg_temp_free(v2_t);
b53371ed
JL
16629}
16630
9b1a1d68
JL
16631/* End MIPSDSP functions. */
16632
10dc65db
LA
16633static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16634{
4267d3e6 16635 int rs, rt, rd, sa;
b42ee5e1 16636 uint32_t op1, op2;
10dc65db
LA
16637
16638 rs = (ctx->opcode >> 21) & 0x1f;
16639 rt = (ctx->opcode >> 16) & 0x1f;
16640 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16641 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16642
16643 op1 = MASK_SPECIAL(ctx->opcode);
16644 switch (op1) {
d4ea6acd 16645 case OPC_LSA:
1f1b4c00 16646 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16647 break;
b42ee5e1
LA
16648 case OPC_MULT ... OPC_DIVU:
16649 op2 = MASK_R6_MULDIV(ctx->opcode);
16650 switch (op2) {
16651 case R6_OPC_MUL:
16652 case R6_OPC_MUH:
16653 case R6_OPC_MULU:
16654 case R6_OPC_MUHU:
16655 case R6_OPC_DIV:
16656 case R6_OPC_MOD:
16657 case R6_OPC_DIVU:
16658 case R6_OPC_MODU:
16659 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16660 break;
16661 default:
16662 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16663 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16664 break;
16665 }
16666 break;
10dc65db
LA
16667 case OPC_SELEQZ:
16668 case OPC_SELNEZ:
16669 gen_cond_move(ctx, op1, rd, rs, rt);
16670 break;
4267d3e6
LA
16671 case R6_OPC_CLO:
16672 case R6_OPC_CLZ:
16673 if (rt == 0 && sa == 1) {
16674 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16675 We need additionally to check other fields */
16676 gen_cl(ctx, op1, rd, rs);
16677 } else {
9c708c7f 16678 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16679 }
16680 break;
16681 case R6_OPC_SDBBP:
3b3c1694
LA
16682 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16683 gen_helper_do_semihosting(cpu_env);
faf1f68b 16684 } else {
3b3c1694 16685 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 16686 generate_exception_end(ctx, EXCP_RI);
3b3c1694 16687 } else {
9c708c7f 16688 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 16689 }
faf1f68b 16690 }
4267d3e6 16691 break;
b42ee5e1 16692#if defined(TARGET_MIPS64)
d4ea6acd
LA
16693 case OPC_DLSA:
16694 check_mips_64(ctx);
1f1b4c00 16695 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16696 break;
4267d3e6
LA
16697 case R6_OPC_DCLO:
16698 case R6_OPC_DCLZ:
16699 if (rt == 0 && sa == 1) {
16700 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16701 We need additionally to check other fields */
16702 check_mips_64(ctx);
16703 gen_cl(ctx, op1, rd, rs);
16704 } else {
9c708c7f 16705 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16706 }
16707 break;
b42ee5e1
LA
16708 case OPC_DMULT ... OPC_DDIVU:
16709 op2 = MASK_R6_MULDIV(ctx->opcode);
16710 switch (op2) {
16711 case R6_OPC_DMUL:
16712 case R6_OPC_DMUH:
16713 case R6_OPC_DMULU:
16714 case R6_OPC_DMUHU:
16715 case R6_OPC_DDIV:
16716 case R6_OPC_DMOD:
16717 case R6_OPC_DDIVU:
16718 case R6_OPC_DMODU:
16719 check_mips_64(ctx);
16720 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16721 break;
16722 default:
16723 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16724 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16725 break;
16726 }
16727 break;
16728#endif
10dc65db
LA
16729 default: /* Invalid */
16730 MIPS_INVAL("special_r6");
9c708c7f 16731 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16732 break;
16733 }
16734}
16735
16736static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16737{
b42ee5e1 16738 int rs, rt, rd, sa;
10dc65db
LA
16739 uint32_t op1;
16740
16741 rs = (ctx->opcode >> 21) & 0x1f;
16742 rt = (ctx->opcode >> 16) & 0x1f;
16743 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16744 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16745
16746 op1 = MASK_SPECIAL(ctx->opcode);
16747 switch (op1) {
16748 case OPC_MOVN: /* Conditional move */
16749 case OPC_MOVZ:
16750 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16751 INSN_LOONGSON2E | INSN_LOONGSON2F);
16752 gen_cond_move(ctx, op1, rd, rs, rt);
16753 break;
16754 case OPC_MFHI: /* Move from HI/LO */
16755 case OPC_MFLO:
16756 gen_HILO(ctx, op1, rs & 3, rd);
16757 break;
16758 case OPC_MTHI:
16759 case OPC_MTLO: /* Move to HI/LO */
16760 gen_HILO(ctx, op1, rd & 3, rs);
16761 break;
16762 case OPC_MOVCI:
16763 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16764 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16765 check_cp1_enabled(ctx);
16766 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16767 (ctx->opcode >> 16) & 1);
16768 } else {
16769 generate_exception_err(ctx, EXCP_CpU, 1);
16770 }
16771 break;
b42ee5e1
LA
16772 case OPC_MULT:
16773 case OPC_MULTU:
16774 if (sa) {
16775 check_insn(ctx, INSN_VR54XX);
16776 op1 = MASK_MUL_VR54XX(ctx->opcode);
16777 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16778 } else {
16779 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16780 }
16781 break;
16782 case OPC_DIV:
16783 case OPC_DIVU:
16784 gen_muldiv(ctx, op1, 0, rs, rt);
16785 break;
16786#if defined(TARGET_MIPS64)
16787 case OPC_DMULT ... OPC_DDIVU:
16788 check_insn(ctx, ISA_MIPS3);
16789 check_mips_64(ctx);
16790 gen_muldiv(ctx, op1, 0, rs, rt);
16791 break;
16792#endif
0aefa333 16793 case OPC_JR:
b231c103 16794 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16795 break;
4267d3e6
LA
16796 case OPC_SPIM:
16797#ifdef MIPS_STRICT_STANDARD
16798 MIPS_INVAL("SPIM");
9c708c7f 16799 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16800#else
16801 /* Implemented as RI exception for now. */
16802 MIPS_INVAL("spim (unofficial)");
9c708c7f 16803 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16804#endif
16805 break;
10dc65db
LA
16806 default: /* Invalid */
16807 MIPS_INVAL("special_legacy");
9c708c7f 16808 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16809 break;
16810 }
16811}
16812
099e5b4d 16813static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16814{
3c824109 16815 int rs, rt, rd, sa;
099e5b4d 16816 uint32_t op1;
3c824109 16817
3c824109
NF
16818 rs = (ctx->opcode >> 21) & 0x1f;
16819 rt = (ctx->opcode >> 16) & 0x1f;
16820 rd = (ctx->opcode >> 11) & 0x1f;
16821 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16822
16823 op1 = MASK_SPECIAL(ctx->opcode);
16824 switch (op1) {
16825 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16826 if (sa == 5 && rd == 0 &&
16827 rs == 0 && rt == 0) { /* PAUSE */
16828 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16829 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 16830 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
16831 break;
16832 }
16833 }
16834 /* Fallthrough */
099e5b4d
LA
16835 case OPC_SRA:
16836 gen_shift_imm(ctx, op1, rd, rt, sa);
16837 break;
16838 case OPC_SRL:
16839 switch ((ctx->opcode >> 21) & 0x1f) {
16840 case 1:
16841 /* rotr is decoded as srl on non-R2 CPUs */
16842 if (ctx->insn_flags & ISA_MIPS32R2) {
16843 op1 = OPC_ROTR;
ea63e2c3 16844 }
099e5b4d
LA
16845 /* Fallthrough */
16846 case 0:
16847 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16848 break;
099e5b4d 16849 default:
9c708c7f 16850 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 16851 break;
099e5b4d
LA
16852 }
16853 break;
099e5b4d
LA
16854 case OPC_ADD ... OPC_SUBU:
16855 gen_arith(ctx, op1, rd, rs, rt);
16856 break;
16857 case OPC_SLLV: /* Shifts */
16858 case OPC_SRAV:
16859 gen_shift(ctx, op1, rd, rs, rt);
16860 break;
16861 case OPC_SRLV:
16862 switch ((ctx->opcode >> 6) & 0x1f) {
16863 case 1:
16864 /* rotrv is decoded as srlv on non-R2 CPUs */
16865 if (ctx->insn_flags & ISA_MIPS32R2) {
16866 op1 = OPC_ROTRV;
26135ead 16867 }
099e5b4d
LA
16868 /* Fallthrough */
16869 case 0:
16870 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16871 break;
099e5b4d 16872 default:
9c708c7f 16873 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 16874 break;
099e5b4d
LA
16875 }
16876 break;
16877 case OPC_SLT: /* Set on less than */
16878 case OPC_SLTU:
16879 gen_slt(ctx, op1, rd, rs, rt);
16880 break;
16881 case OPC_AND: /* Logic*/
16882 case OPC_OR:
16883 case OPC_NOR:
16884 case OPC_XOR:
16885 gen_logic(ctx, op1, rd, rs, rt);
16886 break;
0aefa333 16887 case OPC_JALR:
b231c103 16888 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16889 break;
16890 case OPC_TGE ... OPC_TEQ: /* Traps */
16891 case OPC_TNE:
d9224450 16892 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16893 gen_trap(ctx, op1, rs, rt, -1);
16894 break;
d4ea6acd 16895 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16896 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16897 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16898 decode_opc_special_r6(env, ctx);
16899 } else {
16900 /* Pmon entry point, also R4010 selsl */
b48cfdff 16901#ifdef MIPS_STRICT_STANDARD
d4ea6acd 16902 MIPS_INVAL("PMON / selsl");
9c708c7f 16903 generate_exception_end(ctx, EXCP_RI);
b48cfdff 16904#else
d4ea6acd 16905 gen_helper_0e0i(pmon, sa);
b48cfdff 16906#endif
d4ea6acd 16907 }
099e5b4d
LA
16908 break;
16909 case OPC_SYSCALL:
9c708c7f 16910 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
16911 break;
16912 case OPC_BREAK:
9c708c7f 16913 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 16914 break;
099e5b4d 16915 case OPC_SYNC:
d9224450 16916 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16917 /* Treat as NOP. */
16918 break;
4ad40f36 16919
d26bc211 16920#if defined(TARGET_MIPS64)
099e5b4d
LA
16921 /* MIPS64 specific opcodes */
16922 case OPC_DSLL:
16923 case OPC_DSRA:
16924 case OPC_DSLL32:
16925 case OPC_DSRA32:
16926 check_insn(ctx, ISA_MIPS3);
16927 check_mips_64(ctx);
16928 gen_shift_imm(ctx, op1, rd, rt, sa);
16929 break;
16930 case OPC_DSRL:
16931 switch ((ctx->opcode >> 21) & 0x1f) {
16932 case 1:
16933 /* drotr is decoded as dsrl on non-R2 CPUs */
16934 if (ctx->insn_flags & ISA_MIPS32R2) {
16935 op1 = OPC_DROTR;
ea63e2c3 16936 }
099e5b4d
LA
16937 /* Fallthrough */
16938 case 0:
d75c135e 16939 check_insn(ctx, ISA_MIPS3);
e189e748 16940 check_mips_64(ctx);
099e5b4d 16941 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16942 break;
099e5b4d 16943 default:
9c708c7f 16944 generate_exception_end(ctx, EXCP_RI);
460f00c4 16945 break;
099e5b4d
LA
16946 }
16947 break;
16948 case OPC_DSRL32:
16949 switch ((ctx->opcode >> 21) & 0x1f) {
16950 case 1:
16951 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16952 if (ctx->insn_flags & ISA_MIPS32R2) {
16953 op1 = OPC_DROTR32;
ea63e2c3 16954 }
099e5b4d
LA
16955 /* Fallthrough */
16956 case 0:
d75c135e 16957 check_insn(ctx, ISA_MIPS3);
e189e748 16958 check_mips_64(ctx);
099e5b4d 16959 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16960 break;
099e5b4d 16961 default:
9c708c7f 16962 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
16963 break;
16964 }
16965 break;
099e5b4d
LA
16966 case OPC_DADD ... OPC_DSUBU:
16967 check_insn(ctx, ISA_MIPS3);
16968 check_mips_64(ctx);
16969 gen_arith(ctx, op1, rd, rs, rt);
16970 break;
16971 case OPC_DSLLV:
16972 case OPC_DSRAV:
16973 check_insn(ctx, ISA_MIPS3);
16974 check_mips_64(ctx);
16975 gen_shift(ctx, op1, rd, rs, rt);
16976 break;
16977 case OPC_DSRLV:
16978 switch ((ctx->opcode >> 6) & 0x1f) {
16979 case 1:
16980 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16981 if (ctx->insn_flags & ISA_MIPS32R2) {
16982 op1 = OPC_DROTRV;
6af0bf9c 16983 }
099e5b4d
LA
16984 /* Fallthrough */
16985 case 0:
16986 check_insn(ctx, ISA_MIPS3);
e189e748 16987 check_mips_64(ctx);
099e5b4d 16988 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16989 break;
099e5b4d 16990 default:
9c708c7f 16991 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
16992 break;
16993 }
16994 break;
f7685877
YK
16995 case OPC_DLSA:
16996 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16997 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16998 decode_opc_special_r6(env, ctx);
16999 }
17000 break;
099e5b4d 17001#endif
10dc65db
LA
17002 default:
17003 if (ctx->insn_flags & ISA_MIPS32R6) {
17004 decode_opc_special_r6(env, ctx);
17005 } else {
17006 decode_opc_special_legacy(env, ctx);
17007 }
17008 }
17009}
17010
10dc65db 17011static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17012{
17013 int rs, rt, rd;
17014 uint32_t op1;
6c5c1e20 17015
4267d3e6
LA
17016 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17017
099e5b4d
LA
17018 rs = (ctx->opcode >> 21) & 0x1f;
17019 rt = (ctx->opcode >> 16) & 0x1f;
17020 rd = (ctx->opcode >> 11) & 0x1f;
17021
17022 op1 = MASK_SPECIAL2(ctx->opcode);
17023 switch (op1) {
17024 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17025 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17026 check_insn(ctx, ISA_MIPS32);
17027 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17028 break;
17029 case OPC_MUL:
099e5b4d
LA
17030 gen_arith(ctx, op1, rd, rs, rt);
17031 break;
fac5a073
LA
17032 case OPC_DIV_G_2F:
17033 case OPC_DIVU_G_2F:
17034 case OPC_MULT_G_2F:
17035 case OPC_MULTU_G_2F:
17036 case OPC_MOD_G_2F:
17037 case OPC_MODU_G_2F:
17038 check_insn(ctx, INSN_LOONGSON2F);
17039 gen_loongson_integer(ctx, op1, rd, rs, rt);
17040 break;
099e5b4d
LA
17041 case OPC_CLO:
17042 case OPC_CLZ:
17043 check_insn(ctx, ISA_MIPS32);
17044 gen_cl(ctx, op1, rd, rs);
17045 break;
17046 case OPC_SDBBP:
3b3c1694
LA
17047 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17048 gen_helper_do_semihosting(cpu_env);
17049 } else {
17050 /* XXX: not clear which exception should be raised
17051 * when in debug mode...
17052 */
17053 check_insn(ctx, ISA_MIPS32);
9c708c7f 17054 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17055 }
099e5b4d 17056 break;
9b1a1d68 17057#if defined(TARGET_MIPS64)
099e5b4d
LA
17058 case OPC_DCLO:
17059 case OPC_DCLZ:
17060 check_insn(ctx, ISA_MIPS64);
17061 check_mips_64(ctx);
17062 gen_cl(ctx, op1, rd, rs);
17063 break;
4267d3e6
LA
17064 case OPC_DMULT_G_2F:
17065 case OPC_DMULTU_G_2F:
17066 case OPC_DDIV_G_2F:
17067 case OPC_DDIVU_G_2F:
17068 case OPC_DMOD_G_2F:
17069 case OPC_DMODU_G_2F:
17070 check_insn(ctx, INSN_LOONGSON2F);
17071 gen_loongson_integer(ctx, op1, rd, rs, rt);
17072 break;
10dc65db 17073#endif
4267d3e6
LA
17074 default: /* Invalid */
17075 MIPS_INVAL("special2_legacy");
9c708c7f 17076 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17077 break;
10dc65db
LA
17078 }
17079}
17080
17081static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17082{
15eacb9b
YK
17083 int rs, rt, rd, sa;
17084 uint32_t op1, op2;
10dc65db
LA
17085 int16_t imm;
17086
17087 rs = (ctx->opcode >> 21) & 0x1f;
17088 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17089 rd = (ctx->opcode >> 11) & 0x1f;
17090 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17091 imm = (int16_t)ctx->opcode >> 7;
17092
17093 op1 = MASK_SPECIAL3(ctx->opcode);
17094 switch (op1) {
bf7910c6
LA
17095 case R6_OPC_PREF:
17096 if (rt >= 24) {
17097 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17098 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17099 }
17100 /* Treat as NOP. */
17101 break;
17102 case R6_OPC_CACHE:
17103 /* Treat as NOP. */
17104 break;
10dc65db
LA
17105 case R6_OPC_SC:
17106 gen_st_cond(ctx, op1, rt, rs, imm);
17107 break;
17108 case R6_OPC_LL:
17109 gen_ld(ctx, op1, rt, rs, imm);
17110 break;
15eacb9b
YK
17111 case OPC_BSHFL:
17112 {
17113 if (rd == 0) {
17114 /* Treat as NOP. */
17115 break;
17116 }
15eacb9b
YK
17117 op2 = MASK_BSHFL(ctx->opcode);
17118 switch (op2) {
17119 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17120 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17121 break;
17122 case OPC_BITSWAP:
1f1b4c00 17123 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17124 break;
17125 }
15eacb9b
YK
17126 }
17127 break;
bf7910c6
LA
17128#if defined(TARGET_MIPS64)
17129 case R6_OPC_SCD:
17130 gen_st_cond(ctx, op1, rt, rs, imm);
17131 break;
17132 case R6_OPC_LLD:
17133 gen_ld(ctx, op1, rt, rs, imm);
17134 break;
15eacb9b
YK
17135 case OPC_DBSHFL:
17136 check_mips_64(ctx);
17137 {
17138 if (rd == 0) {
17139 /* Treat as NOP. */
17140 break;
17141 }
15eacb9b
YK
17142 op2 = MASK_DBSHFL(ctx->opcode);
17143 switch (op2) {
17144 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17145 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17146 break;
17147 case OPC_DBITSWAP:
1f1b4c00 17148 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17149 break;
17150 }
1f1b4c00 17151
15eacb9b
YK
17152 }
17153 break;
bf7910c6 17154#endif
10dc65db
LA
17155 default: /* Invalid */
17156 MIPS_INVAL("special3_r6");
9c708c7f 17157 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17158 break;
17159 }
17160}
17161
17162static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17163{
fac5a073 17164 int rs, rt, rd;
099e5b4d 17165 uint32_t op1, op2;
099e5b4d
LA
17166
17167 rs = (ctx->opcode >> 21) & 0x1f;
17168 rt = (ctx->opcode >> 16) & 0x1f;
17169 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17170
17171 op1 = MASK_SPECIAL3(ctx->opcode);
17172 switch (op1) {
099e5b4d
LA
17173 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17174 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17175 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17176 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17177 * the same mask and op1. */
17178 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17179 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17180 switch (op2) {
099e5b4d
LA
17181 case OPC_ADDUH_QB:
17182 case OPC_ADDUH_R_QB:
17183 case OPC_ADDQH_PH:
17184 case OPC_ADDQH_R_PH:
17185 case OPC_ADDQH_W:
17186 case OPC_ADDQH_R_W:
17187 case OPC_SUBUH_QB:
17188 case OPC_SUBUH_R_QB:
17189 case OPC_SUBQH_PH:
17190 case OPC_SUBQH_R_PH:
17191 case OPC_SUBQH_W:
17192 case OPC_SUBQH_R_W:
461c08df
JL
17193 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17194 break;
099e5b4d
LA
17195 case OPC_MUL_PH:
17196 case OPC_MUL_S_PH:
17197 case OPC_MULQ_S_W:
17198 case OPC_MULQ_RS_W:
17199 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17200 break;
461c08df 17201 default:
099e5b4d 17202 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17203 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17204 break;
17205 }
099e5b4d
LA
17206 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17207 gen_loongson_integer(ctx, op1, rd, rs, rt);
17208 } else {
9c708c7f 17209 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17210 }
17211 break;
17212 case OPC_LX_DSP:
17213 op2 = MASK_LX(ctx->opcode);
17214 switch (op2) {
17215#if defined(TARGET_MIPS64)
17216 case OPC_LDX:
17217#endif
17218 case OPC_LBUX:
17219 case OPC_LHX:
17220 case OPC_LWX:
17221 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17222 break;
17223 default: /* Invalid */
17224 MIPS_INVAL("MASK LX");
9c708c7f 17225 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17226 break;
17227 }
17228 break;
17229 case OPC_ABSQ_S_PH_DSP:
17230 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17231 switch (op2) {
17232 case OPC_ABSQ_S_QB:
17233 case OPC_ABSQ_S_PH:
17234 case OPC_ABSQ_S_W:
17235 case OPC_PRECEQ_W_PHL:
17236 case OPC_PRECEQ_W_PHR:
17237 case OPC_PRECEQU_PH_QBL:
17238 case OPC_PRECEQU_PH_QBR:
17239 case OPC_PRECEQU_PH_QBLA:
17240 case OPC_PRECEQU_PH_QBRA:
17241 case OPC_PRECEU_PH_QBL:
17242 case OPC_PRECEU_PH_QBR:
17243 case OPC_PRECEU_PH_QBLA:
17244 case OPC_PRECEU_PH_QBRA:
17245 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17246 break;
17247 case OPC_BITREV:
17248 case OPC_REPL_QB:
17249 case OPC_REPLV_QB:
17250 case OPC_REPL_PH:
17251 case OPC_REPLV_PH:
17252 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17253 break;
17254 default:
17255 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17256 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17257 break;
17258 }
17259 break;
17260 case OPC_ADDU_QB_DSP:
17261 op2 = MASK_ADDU_QB(ctx->opcode);
17262 switch (op2) {
17263 case OPC_ADDQ_PH:
17264 case OPC_ADDQ_S_PH:
17265 case OPC_ADDQ_S_W:
17266 case OPC_ADDU_QB:
17267 case OPC_ADDU_S_QB:
17268 case OPC_ADDU_PH:
17269 case OPC_ADDU_S_PH:
17270 case OPC_SUBQ_PH:
17271 case OPC_SUBQ_S_PH:
17272 case OPC_SUBQ_S_W:
17273 case OPC_SUBU_QB:
17274 case OPC_SUBU_S_QB:
17275 case OPC_SUBU_PH:
17276 case OPC_SUBU_S_PH:
17277 case OPC_ADDSC:
17278 case OPC_ADDWC:
17279 case OPC_MODSUB:
17280 case OPC_RADDU_W_QB:
17281 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17282 break;
17283 case OPC_MULEU_S_PH_QBL:
17284 case OPC_MULEU_S_PH_QBR:
17285 case OPC_MULQ_RS_PH:
17286 case OPC_MULEQ_S_W_PHL:
17287 case OPC_MULEQ_S_W_PHR:
17288 case OPC_MULQ_S_PH:
17289 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17290 break;
17291 default: /* Invalid */
17292 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17293 generate_exception_end(ctx, EXCP_RI);
461c08df 17294 break;
461c08df 17295
099e5b4d
LA
17296 }
17297 break;
17298 case OPC_CMPU_EQ_QB_DSP:
17299 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17300 switch (op2) {
17301 case OPC_PRECR_SRA_PH_W:
17302 case OPC_PRECR_SRA_R_PH_W:
17303 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17304 break;
099e5b4d
LA
17305 case OPC_PRECR_QB_PH:
17306 case OPC_PRECRQ_QB_PH:
17307 case OPC_PRECRQ_PH_W:
17308 case OPC_PRECRQ_RS_PH_W:
17309 case OPC_PRECRQU_S_QB_PH:
17310 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17311 break;
099e5b4d
LA
17312 case OPC_CMPU_EQ_QB:
17313 case OPC_CMPU_LT_QB:
17314 case OPC_CMPU_LE_QB:
17315 case OPC_CMP_EQ_PH:
17316 case OPC_CMP_LT_PH:
17317 case OPC_CMP_LE_PH:
17318 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17319 break;
099e5b4d
LA
17320 case OPC_CMPGU_EQ_QB:
17321 case OPC_CMPGU_LT_QB:
17322 case OPC_CMPGU_LE_QB:
17323 case OPC_CMPGDU_EQ_QB:
17324 case OPC_CMPGDU_LT_QB:
17325 case OPC_CMPGDU_LE_QB:
17326 case OPC_PICK_QB:
17327 case OPC_PICK_PH:
17328 case OPC_PACKRL_PH:
17329 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17330 break;
17331 default: /* Invalid */
17332 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17333 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17334 break;
17335 }
17336 break;
17337 case OPC_SHLL_QB_DSP:
17338 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17339 break;
17340 case OPC_DPA_W_PH_DSP:
17341 op2 = MASK_DPA_W_PH(ctx->opcode);
17342 switch (op2) {
17343 case OPC_DPAU_H_QBL:
17344 case OPC_DPAU_H_QBR:
17345 case OPC_DPSU_H_QBL:
17346 case OPC_DPSU_H_QBR:
17347 case OPC_DPA_W_PH:
17348 case OPC_DPAX_W_PH:
17349 case OPC_DPAQ_S_W_PH:
17350 case OPC_DPAQX_S_W_PH:
17351 case OPC_DPAQX_SA_W_PH:
17352 case OPC_DPS_W_PH:
17353 case OPC_DPSX_W_PH:
17354 case OPC_DPSQ_S_W_PH:
17355 case OPC_DPSQX_S_W_PH:
17356 case OPC_DPSQX_SA_W_PH:
17357 case OPC_MULSAQ_S_W_PH:
17358 case OPC_DPAQ_SA_L_W:
17359 case OPC_DPSQ_SA_L_W:
17360 case OPC_MAQ_S_W_PHL:
17361 case OPC_MAQ_S_W_PHR:
17362 case OPC_MAQ_SA_W_PHL:
17363 case OPC_MAQ_SA_W_PHR:
17364 case OPC_MULSA_W_PH:
17365 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17366 break;
17367 default: /* Invalid */
17368 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17369 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17370 break;
17371 }
17372 break;
17373 case OPC_INSV_DSP:
17374 op2 = MASK_INSV(ctx->opcode);
17375 switch (op2) {
17376 case OPC_INSV:
17377 check_dsp(ctx);
17378 {
17379 TCGv t0, t1;
17380
17381 if (rt == 0) {
099e5b4d
LA
17382 break;
17383 }
17384
17385 t0 = tcg_temp_new();
17386 t1 = tcg_temp_new();
17387
17388 gen_load_gpr(t0, rt);
17389 gen_load_gpr(t1, rs);
17390
17391 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17392
17393 tcg_temp_free(t0);
17394 tcg_temp_free(t1);
a22260ae
JL
17395 break;
17396 }
099e5b4d
LA
17397 default: /* Invalid */
17398 MIPS_INVAL("MASK INSV");
9c708c7f 17399 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17400 break;
17401 }
17402 break;
17403 case OPC_APPEND_DSP:
17404 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17405 break;
17406 case OPC_EXTR_W_DSP:
17407 op2 = MASK_EXTR_W(ctx->opcode);
17408 switch (op2) {
17409 case OPC_EXTR_W:
17410 case OPC_EXTR_R_W:
17411 case OPC_EXTR_RS_W:
17412 case OPC_EXTR_S_H:
17413 case OPC_EXTRV_S_H:
17414 case OPC_EXTRV_W:
17415 case OPC_EXTRV_R_W:
17416 case OPC_EXTRV_RS_W:
17417 case OPC_EXTP:
17418 case OPC_EXTPV:
17419 case OPC_EXTPDP:
17420 case OPC_EXTPDPV:
17421 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17422 break;
17423 case OPC_RDDSP:
17424 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17425 break;
17426 case OPC_SHILO:
17427 case OPC_SHILOV:
17428 case OPC_MTHLIP:
17429 case OPC_WRDSP:
17430 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17431 break;
17432 default: /* Invalid */
17433 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17434 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17435 break;
17436 }
17437 break;
099e5b4d 17438#if defined(TARGET_MIPS64)
fac5a073
LA
17439 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17440 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17441 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17442 check_insn(ctx, INSN_LOONGSON2E);
17443 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17444 break;
099e5b4d
LA
17445 case OPC_ABSQ_S_QH_DSP:
17446 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17447 switch (op2) {
17448 case OPC_PRECEQ_L_PWL:
17449 case OPC_PRECEQ_L_PWR:
17450 case OPC_PRECEQ_PW_QHL:
17451 case OPC_PRECEQ_PW_QHR:
17452 case OPC_PRECEQ_PW_QHLA:
17453 case OPC_PRECEQ_PW_QHRA:
17454 case OPC_PRECEQU_QH_OBL:
17455 case OPC_PRECEQU_QH_OBR:
17456 case OPC_PRECEQU_QH_OBLA:
17457 case OPC_PRECEQU_QH_OBRA:
17458 case OPC_PRECEU_QH_OBL:
17459 case OPC_PRECEU_QH_OBR:
17460 case OPC_PRECEU_QH_OBLA:
17461 case OPC_PRECEU_QH_OBRA:
17462 case OPC_ABSQ_S_OB:
17463 case OPC_ABSQ_S_PW:
17464 case OPC_ABSQ_S_QH:
17465 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17466 break;
17467 case OPC_REPL_OB:
17468 case OPC_REPL_PW:
17469 case OPC_REPL_QH:
17470 case OPC_REPLV_OB:
17471 case OPC_REPLV_PW:
17472 case OPC_REPLV_QH:
17473 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17474 break;
17475 default: /* Invalid */
17476 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 17477 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17478 break;
17479 }
17480 break;
17481 case OPC_ADDU_OB_DSP:
17482 op2 = MASK_ADDU_OB(ctx->opcode);
17483 switch (op2) {
17484 case OPC_RADDU_L_OB:
17485 case OPC_SUBQ_PW:
17486 case OPC_SUBQ_S_PW:
17487 case OPC_SUBQ_QH:
17488 case OPC_SUBQ_S_QH:
17489 case OPC_SUBU_OB:
17490 case OPC_SUBU_S_OB:
17491 case OPC_SUBU_QH:
17492 case OPC_SUBU_S_QH:
17493 case OPC_SUBUH_OB:
17494 case OPC_SUBUH_R_OB:
17495 case OPC_ADDQ_PW:
17496 case OPC_ADDQ_S_PW:
17497 case OPC_ADDQ_QH:
17498 case OPC_ADDQ_S_QH:
17499 case OPC_ADDU_OB:
17500 case OPC_ADDU_S_OB:
17501 case OPC_ADDU_QH:
17502 case OPC_ADDU_S_QH:
17503 case OPC_ADDUH_OB:
17504 case OPC_ADDUH_R_OB:
17505 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17506 break;
099e5b4d
LA
17507 case OPC_MULEQ_S_PW_QHL:
17508 case OPC_MULEQ_S_PW_QHR:
17509 case OPC_MULEU_S_QH_OBL:
17510 case OPC_MULEU_S_QH_OBR:
17511 case OPC_MULQ_RS_QH:
17512 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17513 break;
099e5b4d
LA
17514 default: /* Invalid */
17515 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 17516 generate_exception_end(ctx, EXCP_RI);
26690560 17517 break;
099e5b4d
LA
17518 }
17519 break;
17520 case OPC_CMPU_EQ_OB_DSP:
17521 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17522 switch (op2) {
17523 case OPC_PRECR_SRA_QH_PW:
17524 case OPC_PRECR_SRA_R_QH_PW:
17525 /* Return value is rt. */
17526 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17527 break;
099e5b4d
LA
17528 case OPC_PRECR_OB_QH:
17529 case OPC_PRECRQ_OB_QH:
17530 case OPC_PRECRQ_PW_L:
17531 case OPC_PRECRQ_QH_PW:
17532 case OPC_PRECRQ_RS_QH_PW:
17533 case OPC_PRECRQU_S_OB_QH:
17534 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17535 break;
099e5b4d
LA
17536 case OPC_CMPU_EQ_OB:
17537 case OPC_CMPU_LT_OB:
17538 case OPC_CMPU_LE_OB:
17539 case OPC_CMP_EQ_QH:
17540 case OPC_CMP_LT_QH:
17541 case OPC_CMP_LE_QH:
17542 case OPC_CMP_EQ_PW:
17543 case OPC_CMP_LT_PW:
17544 case OPC_CMP_LE_PW:
17545 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17546 break;
099e5b4d
LA
17547 case OPC_CMPGDU_EQ_OB:
17548 case OPC_CMPGDU_LT_OB:
17549 case OPC_CMPGDU_LE_OB:
17550 case OPC_CMPGU_EQ_OB:
17551 case OPC_CMPGU_LT_OB:
17552 case OPC_CMPGU_LE_OB:
17553 case OPC_PACKRL_PW:
17554 case OPC_PICK_OB:
17555 case OPC_PICK_PW:
17556 case OPC_PICK_QH:
17557 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17558 break;
099e5b4d
LA
17559 default: /* Invalid */
17560 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 17561 generate_exception_end(ctx, EXCP_RI);
161f85e6 17562 break;
099e5b4d
LA
17563 }
17564 break;
17565 case OPC_DAPPEND_DSP:
17566 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17567 break;
17568 case OPC_DEXTR_W_DSP:
17569 op2 = MASK_DEXTR_W(ctx->opcode);
17570 switch (op2) {
17571 case OPC_DEXTP:
17572 case OPC_DEXTPDP:
17573 case OPC_DEXTPDPV:
17574 case OPC_DEXTPV:
17575 case OPC_DEXTR_L:
17576 case OPC_DEXTR_R_L:
17577 case OPC_DEXTR_RS_L:
17578 case OPC_DEXTR_W:
17579 case OPC_DEXTR_R_W:
17580 case OPC_DEXTR_RS_W:
17581 case OPC_DEXTR_S_H:
17582 case OPC_DEXTRV_L:
17583 case OPC_DEXTRV_R_L:
17584 case OPC_DEXTRV_RS_L:
17585 case OPC_DEXTRV_S_H:
17586 case OPC_DEXTRV_W:
17587 case OPC_DEXTRV_R_W:
17588 case OPC_DEXTRV_RS_W:
17589 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17590 break;
099e5b4d
LA
17591 case OPC_DMTHLIP:
17592 case OPC_DSHILO:
17593 case OPC_DSHILOV:
17594 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17595 break;
099e5b4d
LA
17596 default: /* Invalid */
17597 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17598 generate_exception_end(ctx, EXCP_RI);
461c08df 17599 break;
099e5b4d
LA
17600 }
17601 break;
17602 case OPC_DPAQ_W_QH_DSP:
17603 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17604 switch (op2) {
17605 case OPC_DPAU_H_OBL:
17606 case OPC_DPAU_H_OBR:
17607 case OPC_DPSU_H_OBL:
17608 case OPC_DPSU_H_OBR:
17609 case OPC_DPA_W_QH:
17610 case OPC_DPAQ_S_W_QH:
17611 case OPC_DPS_W_QH:
17612 case OPC_DPSQ_S_W_QH:
17613 case OPC_MULSAQ_S_W_QH:
17614 case OPC_DPAQ_SA_L_PW:
17615 case OPC_DPSQ_SA_L_PW:
17616 case OPC_MULSAQ_S_L_PW:
17617 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17618 break;
17619 case OPC_MAQ_S_W_QHLL:
17620 case OPC_MAQ_S_W_QHLR:
17621 case OPC_MAQ_S_W_QHRL:
17622 case OPC_MAQ_S_W_QHRR:
17623 case OPC_MAQ_SA_W_QHLL:
17624 case OPC_MAQ_SA_W_QHLR:
17625 case OPC_MAQ_SA_W_QHRL:
17626 case OPC_MAQ_SA_W_QHRR:
17627 case OPC_MAQ_S_L_PWL:
17628 case OPC_MAQ_S_L_PWR:
17629 case OPC_DMADD:
17630 case OPC_DMADDU:
17631 case OPC_DMSUB:
17632 case OPC_DMSUBU:
17633 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17634 break;
099e5b4d
LA
17635 default: /* Invalid */
17636 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 17637 generate_exception_end(ctx, EXCP_RI);
b53371ed 17638 break;
099e5b4d
LA
17639 }
17640 break;
17641 case OPC_DINSV_DSP:
17642 op2 = MASK_INSV(ctx->opcode);
17643 switch (op2) {
17644 case OPC_DINSV:
17645 {
17646 TCGv t0, t1;
17647
17648 if (rt == 0) {
a22260ae
JL
17649 break;
17650 }
099e5b4d 17651 check_dsp(ctx);
1cb6686c 17652
099e5b4d
LA
17653 t0 = tcg_temp_new();
17654 t1 = tcg_temp_new();
1cb6686c 17655
099e5b4d
LA
17656 gen_load_gpr(t0, rt);
17657 gen_load_gpr(t1, rs);
1cb6686c 17658
099e5b4d 17659 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17660
099e5b4d
LA
17661 tcg_temp_free(t0);
17662 tcg_temp_free(t1);
77c5fa8b 17663 break;
099e5b4d 17664 }
7a387fff 17665 default: /* Invalid */
099e5b4d 17666 MIPS_INVAL("MASK DINSV");
9c708c7f 17667 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
17668 break;
17669 }
17670 break;
099e5b4d
LA
17671 case OPC_SHLL_OB_DSP:
17672 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17673 break;
17674#endif
fac5a073
LA
17675 default: /* Invalid */
17676 MIPS_INVAL("special3_legacy");
9c708c7f 17677 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
17678 break;
17679 }
17680}
17681
17682static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17683{
17684 int rs, rt, rd, sa;
17685 uint32_t op1, op2;
17686
17687 rs = (ctx->opcode >> 21) & 0x1f;
17688 rt = (ctx->opcode >> 16) & 0x1f;
17689 rd = (ctx->opcode >> 11) & 0x1f;
17690 sa = (ctx->opcode >> 6) & 0x1f;
17691
17692 op1 = MASK_SPECIAL3(ctx->opcode);
17693 switch (op1) {
17694 case OPC_EXT:
17695 case OPC_INS:
17696 check_insn(ctx, ISA_MIPS32R2);
17697 gen_bitops(ctx, op1, rt, rs, sa, rd);
17698 break;
17699 case OPC_BSHFL:
fac5a073 17700 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17701 switch (op2) {
17702 case OPC_ALIGN ... OPC_ALIGN_END:
17703 case OPC_BITSWAP:
17704 check_insn(ctx, ISA_MIPS32R6);
17705 decode_opc_special3_r6(env, ctx);
17706 break;
17707 default:
17708 check_insn(ctx, ISA_MIPS32R2);
17709 gen_bshfl(ctx, op2, rt, rd);
17710 break;
17711 }
fac5a073
LA
17712 break;
17713#if defined(TARGET_MIPS64)
17714 case OPC_DEXTM ... OPC_DEXT:
17715 case OPC_DINSM ... OPC_DINS:
17716 check_insn(ctx, ISA_MIPS64R2);
17717 check_mips_64(ctx);
17718 gen_bitops(ctx, op1, rt, rs, sa, rd);
17719 break;
17720 case OPC_DBSHFL:
fac5a073 17721 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17722 switch (op2) {
17723 case OPC_DALIGN ... OPC_DALIGN_END:
17724 case OPC_DBITSWAP:
17725 check_insn(ctx, ISA_MIPS32R6);
17726 decode_opc_special3_r6(env, ctx);
17727 break;
17728 default:
17729 check_insn(ctx, ISA_MIPS64R2);
17730 check_mips_64(ctx);
17731 op2 = MASK_DBSHFL(ctx->opcode);
17732 gen_bshfl(ctx, op2, rt, rd);
17733 break;
17734 }
fac5a073
LA
17735 break;
17736#endif
17737 case OPC_RDHWR:
17738 gen_rdhwr(ctx, rt, rd);
17739 break;
17740 case OPC_FORK:
17741 check_insn(ctx, ASE_MT);
17742 {
17743 TCGv t0 = tcg_temp_new();
17744 TCGv t1 = tcg_temp_new();
17745
17746 gen_load_gpr(t0, rt);
17747 gen_load_gpr(t1, rs);
17748 gen_helper_fork(t0, t1);
17749 tcg_temp_free(t0);
17750 tcg_temp_free(t1);
17751 }
17752 break;
17753 case OPC_YIELD:
17754 check_insn(ctx, ASE_MT);
17755 {
17756 TCGv t0 = tcg_temp_new();
17757
fac5a073
LA
17758 gen_load_gpr(t0, rs);
17759 gen_helper_yield(t0, cpu_env, t0);
17760 gen_store_gpr(t0, rd);
17761 tcg_temp_free(t0);
17762 }
17763 break;
10dc65db
LA
17764 default:
17765 if (ctx->insn_flags & ISA_MIPS32R6) {
17766 decode_opc_special3_r6(env, ctx);
17767 } else {
17768 decode_opc_special3_legacy(env, ctx);
17769 }
099e5b4d
LA
17770 }
17771}
17772
863f264d
YK
17773/* MIPS SIMD Architecture (MSA) */
17774static inline int check_msa_access(DisasContext *ctx)
17775{
17776 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17777 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 17778 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17779 return 0;
17780 }
17781
17782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17783 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 17784 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
17785 return 0;
17786 } else {
9c708c7f 17787 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17788 return 0;
17789 }
17790 }
17791 return 1;
17792}
17793
5692c6e1
YK
17794static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17795{
17796 /* generates tcg ops to check if any element is 0 */
17797 /* Note this function only works with MSA_WRLEN = 128 */
17798 uint64_t eval_zero_or_big = 0;
17799 uint64_t eval_big = 0;
17800 TCGv_i64 t0 = tcg_temp_new_i64();
17801 TCGv_i64 t1 = tcg_temp_new_i64();
17802 switch (df) {
17803 case DF_BYTE:
17804 eval_zero_or_big = 0x0101010101010101ULL;
17805 eval_big = 0x8080808080808080ULL;
17806 break;
17807 case DF_HALF:
17808 eval_zero_or_big = 0x0001000100010001ULL;
17809 eval_big = 0x8000800080008000ULL;
17810 break;
17811 case DF_WORD:
17812 eval_zero_or_big = 0x0000000100000001ULL;
17813 eval_big = 0x8000000080000000ULL;
17814 break;
17815 case DF_DOUBLE:
17816 eval_zero_or_big = 0x0000000000000001ULL;
17817 eval_big = 0x8000000000000000ULL;
17818 break;
17819 }
17820 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17821 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17822 tcg_gen_andi_i64(t0, t0, eval_big);
17823 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17824 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17825 tcg_gen_andi_i64(t1, t1, eval_big);
17826 tcg_gen_or_i64(t0, t0, t1);
17827 /* if all bits are zero then all elements are not zero */
17828 /* if some bit is non-zero then some element is zero */
17829 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17830 tcg_gen_trunc_i64_tl(tresult, t0);
17831 tcg_temp_free_i64(t0);
17832 tcg_temp_free_i64(t1);
17833}
17834
17835static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17836{
17837 uint8_t df = (ctx->opcode >> 21) & 0x3;
17838 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17839 int64_t s16 = (int16_t)ctx->opcode;
17840
17841 check_msa_access(ctx);
17842
17843 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 17844 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
17845 return;
17846 }
17847 switch (op1) {
17848 case OPC_BZ_V:
17849 case OPC_BNZ_V:
17850 {
17851 TCGv_i64 t0 = tcg_temp_new_i64();
17852 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17853 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17854 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17855 tcg_gen_trunc_i64_tl(bcond, t0);
17856 tcg_temp_free_i64(t0);
17857 }
17858 break;
17859 case OPC_BZ_B:
17860 case OPC_BZ_H:
17861 case OPC_BZ_W:
17862 case OPC_BZ_D:
17863 gen_check_zero_element(bcond, df, wt);
17864 break;
17865 case OPC_BNZ_B:
17866 case OPC_BNZ_H:
17867 case OPC_BNZ_W:
17868 case OPC_BNZ_D:
17869 gen_check_zero_element(bcond, df, wt);
17870 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17871 break;
17872 }
17873
17874 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17875
17876 ctx->hflags |= MIPS_HFLAG_BC;
17877 ctx->hflags |= MIPS_HFLAG_BDS32;
17878}
17879
4c789546
YK
17880static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17881{
17882#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17883 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17884 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17885 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17886
17887 TCGv_i32 twd = tcg_const_i32(wd);
17888 TCGv_i32 tws = tcg_const_i32(ws);
17889 TCGv_i32 ti8 = tcg_const_i32(i8);
17890
17891 switch (MASK_MSA_I8(ctx->opcode)) {
17892 case OPC_ANDI_B:
17893 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17894 break;
17895 case OPC_ORI_B:
17896 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17897 break;
17898 case OPC_NORI_B:
17899 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17900 break;
17901 case OPC_XORI_B:
17902 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17903 break;
17904 case OPC_BMNZI_B:
17905 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17906 break;
17907 case OPC_BMZI_B:
17908 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17909 break;
17910 case OPC_BSELI_B:
17911 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17912 break;
17913 case OPC_SHF_B:
17914 case OPC_SHF_H:
17915 case OPC_SHF_W:
17916 {
17917 uint8_t df = (ctx->opcode >> 24) & 0x3;
17918 if (df == DF_DOUBLE) {
9c708c7f 17919 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
17920 } else {
17921 TCGv_i32 tdf = tcg_const_i32(df);
17922 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17923 tcg_temp_free_i32(tdf);
17924 }
17925 }
17926 break;
17927 default:
17928 MIPS_INVAL("MSA instruction");
9c708c7f 17929 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
17930 break;
17931 }
17932
17933 tcg_temp_free_i32(twd);
17934 tcg_temp_free_i32(tws);
17935 tcg_temp_free_i32(ti8);
17936}
17937
80e71591
YK
17938static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17939{
17940#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17941 uint8_t df = (ctx->opcode >> 21) & 0x3;
17942 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17943 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17944 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17945 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17946
17947 TCGv_i32 tdf = tcg_const_i32(df);
17948 TCGv_i32 twd = tcg_const_i32(wd);
17949 TCGv_i32 tws = tcg_const_i32(ws);
17950 TCGv_i32 timm = tcg_temp_new_i32();
17951 tcg_gen_movi_i32(timm, u5);
17952
17953 switch (MASK_MSA_I5(ctx->opcode)) {
17954 case OPC_ADDVI_df:
17955 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17956 break;
17957 case OPC_SUBVI_df:
17958 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17959 break;
17960 case OPC_MAXI_S_df:
17961 tcg_gen_movi_i32(timm, s5);
17962 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17963 break;
17964 case OPC_MAXI_U_df:
17965 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17966 break;
17967 case OPC_MINI_S_df:
17968 tcg_gen_movi_i32(timm, s5);
17969 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17970 break;
17971 case OPC_MINI_U_df:
17972 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17973 break;
17974 case OPC_CEQI_df:
17975 tcg_gen_movi_i32(timm, s5);
17976 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17977 break;
17978 case OPC_CLTI_S_df:
17979 tcg_gen_movi_i32(timm, s5);
17980 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17981 break;
17982 case OPC_CLTI_U_df:
17983 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17984 break;
17985 case OPC_CLEI_S_df:
17986 tcg_gen_movi_i32(timm, s5);
17987 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17988 break;
17989 case OPC_CLEI_U_df:
17990 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17991 break;
17992 case OPC_LDI_df:
17993 {
17994 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17995 tcg_gen_movi_i32(timm, s10);
17996 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17997 }
17998 break;
17999 default:
18000 MIPS_INVAL("MSA instruction");
9c708c7f 18001 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18002 break;
18003 }
18004
18005 tcg_temp_free_i32(tdf);
18006 tcg_temp_free_i32(twd);
18007 tcg_temp_free_i32(tws);
18008 tcg_temp_free_i32(timm);
18009}
18010
d4cf28de
YK
18011static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18012{
18013#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18014 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18015 uint32_t df = 0, m = 0;
18016 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18017 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18018
18019 TCGv_i32 tdf;
18020 TCGv_i32 tm;
18021 TCGv_i32 twd;
18022 TCGv_i32 tws;
18023
18024 if ((dfm & 0x40) == 0x00) {
18025 m = dfm & 0x3f;
18026 df = DF_DOUBLE;
18027 } else if ((dfm & 0x60) == 0x40) {
18028 m = dfm & 0x1f;
18029 df = DF_WORD;
18030 } else if ((dfm & 0x70) == 0x60) {
18031 m = dfm & 0x0f;
18032 df = DF_HALF;
18033 } else if ((dfm & 0x78) == 0x70) {
18034 m = dfm & 0x7;
18035 df = DF_BYTE;
18036 } else {
9c708c7f 18037 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18038 return;
18039 }
18040
18041 tdf = tcg_const_i32(df);
18042 tm = tcg_const_i32(m);
18043 twd = tcg_const_i32(wd);
18044 tws = tcg_const_i32(ws);
18045
18046 switch (MASK_MSA_BIT(ctx->opcode)) {
18047 case OPC_SLLI_df:
18048 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18049 break;
18050 case OPC_SRAI_df:
18051 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18052 break;
18053 case OPC_SRLI_df:
18054 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18055 break;
18056 case OPC_BCLRI_df:
18057 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18058 break;
18059 case OPC_BSETI_df:
18060 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18061 break;
18062 case OPC_BNEGI_df:
18063 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18064 break;
18065 case OPC_BINSLI_df:
18066 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18067 break;
18068 case OPC_BINSRI_df:
18069 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18070 break;
18071 case OPC_SAT_S_df:
18072 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18073 break;
18074 case OPC_SAT_U_df:
18075 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18076 break;
18077 case OPC_SRARI_df:
18078 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18079 break;
18080 case OPC_SRLRI_df:
18081 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18082 break;
18083 default:
18084 MIPS_INVAL("MSA instruction");
9c708c7f 18085 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18086 break;
18087 }
18088
18089 tcg_temp_free_i32(tdf);
18090 tcg_temp_free_i32(tm);
18091 tcg_temp_free_i32(twd);
18092 tcg_temp_free_i32(tws);
18093}
18094
28f99f08
YK
18095static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18096{
18097#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18098 uint8_t df = (ctx->opcode >> 21) & 0x3;
18099 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18100 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18101 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18102
18103 TCGv_i32 tdf = tcg_const_i32(df);
18104 TCGv_i32 twd = tcg_const_i32(wd);
18105 TCGv_i32 tws = tcg_const_i32(ws);
18106 TCGv_i32 twt = tcg_const_i32(wt);
18107
18108 switch (MASK_MSA_3R(ctx->opcode)) {
18109 case OPC_SLL_df:
18110 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18111 break;
18112 case OPC_ADDV_df:
18113 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18114 break;
18115 case OPC_CEQ_df:
18116 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18117 break;
18118 case OPC_ADD_A_df:
18119 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18120 break;
18121 case OPC_SUBS_S_df:
18122 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18123 break;
18124 case OPC_MULV_df:
18125 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18126 break;
18127 case OPC_SLD_df:
18128 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18129 break;
18130 case OPC_VSHF_df:
18131 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18132 break;
18133 case OPC_SRA_df:
18134 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18135 break;
18136 case OPC_SUBV_df:
18137 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18138 break;
18139 case OPC_ADDS_A_df:
18140 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18141 break;
18142 case OPC_SUBS_U_df:
18143 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18144 break;
18145 case OPC_MADDV_df:
18146 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18147 break;
18148 case OPC_SPLAT_df:
18149 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18150 break;
18151 case OPC_SRAR_df:
18152 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18153 break;
18154 case OPC_SRL_df:
18155 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18156 break;
18157 case OPC_MAX_S_df:
18158 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18159 break;
18160 case OPC_CLT_S_df:
18161 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18162 break;
18163 case OPC_ADDS_S_df:
18164 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18165 break;
18166 case OPC_SUBSUS_U_df:
18167 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18168 break;
18169 case OPC_MSUBV_df:
18170 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18171 break;
18172 case OPC_PCKEV_df:
18173 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18174 break;
18175 case OPC_SRLR_df:
18176 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18177 break;
18178 case OPC_BCLR_df:
18179 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18180 break;
18181 case OPC_MAX_U_df:
18182 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18183 break;
18184 case OPC_CLT_U_df:
18185 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18186 break;
18187 case OPC_ADDS_U_df:
18188 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18189 break;
18190 case OPC_SUBSUU_S_df:
18191 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18192 break;
18193 case OPC_PCKOD_df:
18194 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18195 break;
18196 case OPC_BSET_df:
18197 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18198 break;
18199 case OPC_MIN_S_df:
18200 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18201 break;
18202 case OPC_CLE_S_df:
18203 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18204 break;
18205 case OPC_AVE_S_df:
18206 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18207 break;
18208 case OPC_ASUB_S_df:
18209 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18210 break;
18211 case OPC_DIV_S_df:
18212 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18213 break;
18214 case OPC_ILVL_df:
18215 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18216 break;
18217 case OPC_BNEG_df:
18218 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18219 break;
18220 case OPC_MIN_U_df:
18221 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18222 break;
18223 case OPC_CLE_U_df:
18224 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18225 break;
18226 case OPC_AVE_U_df:
18227 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18228 break;
18229 case OPC_ASUB_U_df:
18230 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18231 break;
18232 case OPC_DIV_U_df:
18233 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18234 break;
18235 case OPC_ILVR_df:
18236 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18237 break;
18238 case OPC_BINSL_df:
18239 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18240 break;
18241 case OPC_MAX_A_df:
18242 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18243 break;
18244 case OPC_AVER_S_df:
18245 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18246 break;
18247 case OPC_MOD_S_df:
18248 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18249 break;
18250 case OPC_ILVEV_df:
18251 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18252 break;
18253 case OPC_BINSR_df:
18254 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18255 break;
18256 case OPC_MIN_A_df:
18257 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18258 break;
18259 case OPC_AVER_U_df:
18260 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18261 break;
18262 case OPC_MOD_U_df:
18263 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18264 break;
18265 case OPC_ILVOD_df:
18266 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18267 break;
18268
18269 case OPC_DOTP_S_df:
18270 case OPC_DOTP_U_df:
18271 case OPC_DPADD_S_df:
18272 case OPC_DPADD_U_df:
18273 case OPC_DPSUB_S_df:
18274 case OPC_HADD_S_df:
18275 case OPC_DPSUB_U_df:
18276 case OPC_HADD_U_df:
18277 case OPC_HSUB_S_df:
18278 case OPC_HSUB_U_df:
18279 if (df == DF_BYTE) {
9c708c7f
PD
18280 generate_exception_end(ctx, EXCP_RI);
18281 break;
28f99f08
YK
18282 }
18283 switch (MASK_MSA_3R(ctx->opcode)) {
18284 case OPC_DOTP_S_df:
18285 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18286 break;
18287 case OPC_DOTP_U_df:
18288 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18289 break;
18290 case OPC_DPADD_S_df:
18291 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18292 break;
18293 case OPC_DPADD_U_df:
18294 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18295 break;
18296 case OPC_DPSUB_S_df:
18297 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18298 break;
18299 case OPC_HADD_S_df:
18300 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18301 break;
18302 case OPC_DPSUB_U_df:
18303 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18304 break;
18305 case OPC_HADD_U_df:
18306 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18307 break;
18308 case OPC_HSUB_S_df:
18309 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18310 break;
18311 case OPC_HSUB_U_df:
18312 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18313 break;
18314 }
18315 break;
18316 default:
18317 MIPS_INVAL("MSA instruction");
9c708c7f 18318 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18319 break;
18320 }
18321 tcg_temp_free_i32(twd);
18322 tcg_temp_free_i32(tws);
18323 tcg_temp_free_i32(twt);
18324 tcg_temp_free_i32(tdf);
18325}
18326
1e608ec1
YK
18327static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18328{
18329#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18330 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18331 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18332 TCGv telm = tcg_temp_new();
18333 TCGv_i32 tsr = tcg_const_i32(source);
18334 TCGv_i32 tdt = tcg_const_i32(dest);
18335
18336 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18337 case OPC_CTCMSA:
18338 gen_load_gpr(telm, source);
18339 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18340 break;
18341 case OPC_CFCMSA:
18342 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18343 gen_store_gpr(telm, dest);
18344 break;
18345 case OPC_MOVE_V:
18346 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18347 break;
18348 default:
18349 MIPS_INVAL("MSA instruction");
9c708c7f 18350 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18351 break;
18352 }
18353
18354 tcg_temp_free(telm);
18355 tcg_temp_free_i32(tdt);
18356 tcg_temp_free_i32(tsr);
18357}
18358
18359static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18360 uint32_t n)
18361{
18362#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18363 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18364 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18365
18366 TCGv_i32 tws = tcg_const_i32(ws);
18367 TCGv_i32 twd = tcg_const_i32(wd);
18368 TCGv_i32 tn = tcg_const_i32(n);
18369 TCGv_i32 tdf = tcg_const_i32(df);
18370
18371 switch (MASK_MSA_ELM(ctx->opcode)) {
18372 case OPC_SLDI_df:
18373 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18374 break;
18375 case OPC_SPLATI_df:
18376 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18377 break;
18378 case OPC_INSVE_df:
18379 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18380 break;
18381 case OPC_COPY_S_df:
18382 case OPC_COPY_U_df:
18383 case OPC_INSERT_df:
18384#if !defined(TARGET_MIPS64)
18385 /* Double format valid only for MIPS64 */
18386 if (df == DF_DOUBLE) {
9c708c7f 18387 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18388 break;
18389 }
18390#endif
18391 switch (MASK_MSA_ELM(ctx->opcode)) {
18392 case OPC_COPY_S_df:
18393 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18394 break;
18395 case OPC_COPY_U_df:
18396 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18397 break;
18398 case OPC_INSERT_df:
18399 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18400 break;
18401 }
18402 break;
18403 default:
18404 MIPS_INVAL("MSA instruction");
9c708c7f 18405 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18406 }
18407 tcg_temp_free_i32(twd);
18408 tcg_temp_free_i32(tws);
18409 tcg_temp_free_i32(tn);
18410 tcg_temp_free_i32(tdf);
18411}
18412
18413static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18414{
18415 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18416 uint32_t df = 0, n = 0;
18417
18418 if ((dfn & 0x30) == 0x00) {
18419 n = dfn & 0x0f;
18420 df = DF_BYTE;
18421 } else if ((dfn & 0x38) == 0x20) {
18422 n = dfn & 0x07;
18423 df = DF_HALF;
18424 } else if ((dfn & 0x3c) == 0x30) {
18425 n = dfn & 0x03;
18426 df = DF_WORD;
18427 } else if ((dfn & 0x3e) == 0x38) {
18428 n = dfn & 0x01;
18429 df = DF_DOUBLE;
18430 } else if (dfn == 0x3E) {
18431 /* CTCMSA, CFCMSA, MOVE.V */
18432 gen_msa_elm_3e(env, ctx);
18433 return;
18434 } else {
9c708c7f 18435 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18436 return;
18437 }
18438
18439 gen_msa_elm_df(env, ctx, df, n);
18440}
18441
7d05b9c8
YK
18442static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18443{
18444#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18445 uint8_t df = (ctx->opcode >> 21) & 0x1;
18446 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18447 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18448 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18449
18450 TCGv_i32 twd = tcg_const_i32(wd);
18451 TCGv_i32 tws = tcg_const_i32(ws);
18452 TCGv_i32 twt = tcg_const_i32(wt);
18453 TCGv_i32 tdf = tcg_temp_new_i32();
18454
18455 /* adjust df value for floating-point instruction */
18456 tcg_gen_movi_i32(tdf, df + 2);
18457
18458 switch (MASK_MSA_3RF(ctx->opcode)) {
18459 case OPC_FCAF_df:
18460 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18461 break;
18462 case OPC_FADD_df:
18463 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18464 break;
18465 case OPC_FCUN_df:
18466 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18467 break;
18468 case OPC_FSUB_df:
18469 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18470 break;
18471 case OPC_FCOR_df:
18472 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18473 break;
18474 case OPC_FCEQ_df:
18475 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18476 break;
18477 case OPC_FMUL_df:
18478 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18479 break;
18480 case OPC_FCUNE_df:
18481 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18482 break;
18483 case OPC_FCUEQ_df:
18484 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18485 break;
18486 case OPC_FDIV_df:
18487 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18488 break;
18489 case OPC_FCNE_df:
18490 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18491 break;
18492 case OPC_FCLT_df:
18493 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18494 break;
18495 case OPC_FMADD_df:
18496 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18497 break;
18498 case OPC_MUL_Q_df:
18499 tcg_gen_movi_i32(tdf, df + 1);
18500 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18501 break;
18502 case OPC_FCULT_df:
18503 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18504 break;
18505 case OPC_FMSUB_df:
18506 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18507 break;
18508 case OPC_MADD_Q_df:
18509 tcg_gen_movi_i32(tdf, df + 1);
18510 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18511 break;
18512 case OPC_FCLE_df:
18513 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18514 break;
18515 case OPC_MSUB_Q_df:
18516 tcg_gen_movi_i32(tdf, df + 1);
18517 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18518 break;
18519 case OPC_FCULE_df:
18520 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18521 break;
18522 case OPC_FEXP2_df:
18523 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18524 break;
18525 case OPC_FSAF_df:
18526 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18527 break;
18528 case OPC_FEXDO_df:
18529 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18530 break;
18531 case OPC_FSUN_df:
18532 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18533 break;
18534 case OPC_FSOR_df:
18535 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18536 break;
18537 case OPC_FSEQ_df:
18538 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18539 break;
18540 case OPC_FTQ_df:
18541 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18542 break;
18543 case OPC_FSUNE_df:
18544 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18545 break;
18546 case OPC_FSUEQ_df:
18547 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18548 break;
18549 case OPC_FSNE_df:
18550 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18551 break;
18552 case OPC_FSLT_df:
18553 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18554 break;
18555 case OPC_FMIN_df:
18556 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18557 break;
18558 case OPC_MULR_Q_df:
18559 tcg_gen_movi_i32(tdf, df + 1);
18560 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18561 break;
18562 case OPC_FSULT_df:
18563 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18564 break;
18565 case OPC_FMIN_A_df:
18566 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18567 break;
18568 case OPC_MADDR_Q_df:
18569 tcg_gen_movi_i32(tdf, df + 1);
18570 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_FSLE_df:
18573 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_FMAX_df:
18576 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_MSUBR_Q_df:
18579 tcg_gen_movi_i32(tdf, df + 1);
18580 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18581 break;
18582 case OPC_FSULE_df:
18583 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18584 break;
18585 case OPC_FMAX_A_df:
18586 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18587 break;
18588 default:
18589 MIPS_INVAL("MSA instruction");
9c708c7f 18590 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
18591 break;
18592 }
18593
18594 tcg_temp_free_i32(twd);
18595 tcg_temp_free_i32(tws);
18596 tcg_temp_free_i32(twt);
18597 tcg_temp_free_i32(tdf);
18598}
18599
cbe50b9a
YK
18600static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18601{
18602#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18603 (op & (0x7 << 18)))
18604 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18605 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18606 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18607 uint8_t df = (ctx->opcode >> 16) & 0x3;
18608 TCGv_i32 twd = tcg_const_i32(wd);
18609 TCGv_i32 tws = tcg_const_i32(ws);
18610 TCGv_i32 twt = tcg_const_i32(wt);
18611 TCGv_i32 tdf = tcg_const_i32(df);
18612
18613 switch (MASK_MSA_2R(ctx->opcode)) {
18614 case OPC_FILL_df:
18615#if !defined(TARGET_MIPS64)
18616 /* Double format valid only for MIPS64 */
18617 if (df == DF_DOUBLE) {
9c708c7f 18618 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18619 break;
18620 }
18621#endif
18622 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18623 break;
18624 case OPC_PCNT_df:
18625 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18626 break;
18627 case OPC_NLOC_df:
18628 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18629 break;
18630 case OPC_NLZC_df:
18631 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18632 break;
18633 default:
18634 MIPS_INVAL("MSA instruction");
9c708c7f 18635 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18636 break;
18637 }
18638
18639 tcg_temp_free_i32(twd);
18640 tcg_temp_free_i32(tws);
18641 tcg_temp_free_i32(twt);
18642 tcg_temp_free_i32(tdf);
18643}
18644
3bdeb688
YK
18645static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18646{
18647#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18648 (op & (0xf << 17)))
18649 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18650 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18651 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18652 uint8_t df = (ctx->opcode >> 16) & 0x1;
18653 TCGv_i32 twd = tcg_const_i32(wd);
18654 TCGv_i32 tws = tcg_const_i32(ws);
18655 TCGv_i32 twt = tcg_const_i32(wt);
18656 /* adjust df value for floating-point instruction */
18657 TCGv_i32 tdf = tcg_const_i32(df + 2);
18658
18659 switch (MASK_MSA_2RF(ctx->opcode)) {
18660 case OPC_FCLASS_df:
18661 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18662 break;
18663 case OPC_FTRUNC_S_df:
18664 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18665 break;
18666 case OPC_FTRUNC_U_df:
18667 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18668 break;
18669 case OPC_FSQRT_df:
18670 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18671 break;
18672 case OPC_FRSQRT_df:
18673 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18674 break;
18675 case OPC_FRCP_df:
18676 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18677 break;
18678 case OPC_FRINT_df:
18679 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18680 break;
18681 case OPC_FLOG2_df:
18682 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18683 break;
18684 case OPC_FEXUPL_df:
18685 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18686 break;
18687 case OPC_FEXUPR_df:
18688 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18689 break;
18690 case OPC_FFQL_df:
18691 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18692 break;
18693 case OPC_FFQR_df:
18694 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18695 break;
18696 case OPC_FTINT_S_df:
18697 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18698 break;
18699 case OPC_FTINT_U_df:
18700 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18701 break;
18702 case OPC_FFINT_S_df:
18703 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18704 break;
18705 case OPC_FFINT_U_df:
18706 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18707 break;
18708 }
18709
18710 tcg_temp_free_i32(twd);
18711 tcg_temp_free_i32(tws);
18712 tcg_temp_free_i32(twt);
18713 tcg_temp_free_i32(tdf);
18714}
18715
cbe50b9a
YK
18716static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18717{
18718#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18719 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18720 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18721 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18722 TCGv_i32 twd = tcg_const_i32(wd);
18723 TCGv_i32 tws = tcg_const_i32(ws);
18724 TCGv_i32 twt = tcg_const_i32(wt);
18725
18726 switch (MASK_MSA_VEC(ctx->opcode)) {
18727 case OPC_AND_V:
18728 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18729 break;
18730 case OPC_OR_V:
18731 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18732 break;
18733 case OPC_NOR_V:
18734 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18735 break;
18736 case OPC_XOR_V:
18737 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18738 break;
18739 case OPC_BMNZ_V:
18740 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18741 break;
18742 case OPC_BMZ_V:
18743 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18744 break;
18745 case OPC_BSEL_V:
18746 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18747 break;
18748 default:
18749 MIPS_INVAL("MSA instruction");
9c708c7f 18750 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18751 break;
18752 }
18753
18754 tcg_temp_free_i32(twd);
18755 tcg_temp_free_i32(tws);
18756 tcg_temp_free_i32(twt);
18757}
18758
18759static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18760{
18761 switch (MASK_MSA_VEC(ctx->opcode)) {
18762 case OPC_AND_V:
18763 case OPC_OR_V:
18764 case OPC_NOR_V:
18765 case OPC_XOR_V:
18766 case OPC_BMNZ_V:
18767 case OPC_BMZ_V:
18768 case OPC_BSEL_V:
18769 gen_msa_vec_v(env, ctx);
18770 break;
18771 case OPC_MSA_2R:
18772 gen_msa_2r(env, ctx);
18773 break;
3bdeb688
YK
18774 case OPC_MSA_2RF:
18775 gen_msa_2rf(env, ctx);
18776 break;
cbe50b9a
YK
18777 default:
18778 MIPS_INVAL("MSA instruction");
9c708c7f 18779 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18780 break;
18781 }
18782}
18783
4c789546
YK
18784static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18785{
18786 uint32_t opcode = ctx->opcode;
18787 check_insn(ctx, ASE_MSA);
18788 check_msa_access(ctx);
18789
18790 switch (MASK_MSA_MINOR(opcode)) {
18791 case OPC_MSA_I8_00:
18792 case OPC_MSA_I8_01:
18793 case OPC_MSA_I8_02:
18794 gen_msa_i8(env, ctx);
18795 break;
80e71591
YK
18796 case OPC_MSA_I5_06:
18797 case OPC_MSA_I5_07:
18798 gen_msa_i5(env, ctx);
18799 break;
d4cf28de
YK
18800 case OPC_MSA_BIT_09:
18801 case OPC_MSA_BIT_0A:
18802 gen_msa_bit(env, ctx);
18803 break;
28f99f08
YK
18804 case OPC_MSA_3R_0D:
18805 case OPC_MSA_3R_0E:
18806 case OPC_MSA_3R_0F:
18807 case OPC_MSA_3R_10:
18808 case OPC_MSA_3R_11:
18809 case OPC_MSA_3R_12:
18810 case OPC_MSA_3R_13:
18811 case OPC_MSA_3R_14:
18812 case OPC_MSA_3R_15:
18813 gen_msa_3r(env, ctx);
18814 break;
1e608ec1
YK
18815 case OPC_MSA_ELM:
18816 gen_msa_elm(env, ctx);
18817 break;
7d05b9c8
YK
18818 case OPC_MSA_3RF_1A:
18819 case OPC_MSA_3RF_1B:
18820 case OPC_MSA_3RF_1C:
18821 gen_msa_3rf(env, ctx);
18822 break;
cbe50b9a
YK
18823 case OPC_MSA_VEC:
18824 gen_msa_vec(env, ctx);
18825 break;
f7685877
YK
18826 case OPC_LD_B:
18827 case OPC_LD_H:
18828 case OPC_LD_W:
18829 case OPC_LD_D:
18830 case OPC_ST_B:
18831 case OPC_ST_H:
18832 case OPC_ST_W:
18833 case OPC_ST_D:
18834 {
18835 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18836 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18837 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18838 uint8_t df = (ctx->opcode >> 0) & 0x3;
18839
f7685877 18840 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18841 TCGv taddr = tcg_temp_new();
18842 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18843
18844 switch (MASK_MSA_MINOR(opcode)) {
18845 case OPC_LD_B:
adc370a4
YK
18846 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18847 break;
f7685877 18848 case OPC_LD_H:
adc370a4
YK
18849 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18850 break;
f7685877 18851 case OPC_LD_W:
adc370a4
YK
18852 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18853 break;
f7685877 18854 case OPC_LD_D:
adc370a4 18855 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18856 break;
18857 case OPC_ST_B:
adc370a4
YK
18858 gen_helper_msa_st_b(cpu_env, twd, taddr);
18859 break;
f7685877 18860 case OPC_ST_H:
adc370a4
YK
18861 gen_helper_msa_st_h(cpu_env, twd, taddr);
18862 break;
f7685877 18863 case OPC_ST_W:
adc370a4
YK
18864 gen_helper_msa_st_w(cpu_env, twd, taddr);
18865 break;
f7685877 18866 case OPC_ST_D:
adc370a4 18867 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18868 break;
18869 }
18870
18871 tcg_temp_free_i32(twd);
adc370a4 18872 tcg_temp_free(taddr);
f7685877
YK
18873 }
18874 break;
4c789546
YK
18875 default:
18876 MIPS_INVAL("MSA instruction");
9c708c7f 18877 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18878 break;
18879 }
18880
18881}
18882
d2bfa6e6 18883static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18884{
18885 int32_t offset;
18886 int rs, rt, rd, sa;
18887 uint32_t op, op1;
18888 int16_t imm;
18889
18890 /* make sure instructions are on a word boundary */
18891 if (ctx->pc & 0x3) {
18892 env->CP0_BadVAddr = ctx->pc;
aea14095 18893 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
18894 return;
18895 }
18896
18897 /* Handle blikely not taken case */
18898 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18899 TCGLabel *l1 = gen_new_label();
099e5b4d 18900
099e5b4d
LA
18901 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18902 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18903 gen_goto_tb(ctx, 1, ctx->pc + 4);
18904 gen_set_label(l1);
18905 }
18906
099e5b4d
LA
18907 op = MASK_OP_MAJOR(ctx->opcode);
18908 rs = (ctx->opcode >> 21) & 0x1f;
18909 rt = (ctx->opcode >> 16) & 0x1f;
18910 rd = (ctx->opcode >> 11) & 0x1f;
18911 sa = (ctx->opcode >> 6) & 0x1f;
18912 imm = (int16_t)ctx->opcode;
18913 switch (op) {
18914 case OPC_SPECIAL:
18915 decode_opc_special(env, ctx);
18916 break;
18917 case OPC_SPECIAL2:
4267d3e6 18918 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18919 break;
18920 case OPC_SPECIAL3:
18921 decode_opc_special3(env, ctx);
18922 break;
7a387fff
TS
18923 case OPC_REGIMM:
18924 op1 = MASK_REGIMM(ctx->opcode);
18925 switch (op1) {
fecd2646
LA
18926 case OPC_BLTZL: /* REGIMM branches */
18927 case OPC_BGEZL:
18928 case OPC_BLTZALL:
18929 case OPC_BGEZALL:
d9224450 18930 check_insn(ctx, ISA_MIPS2);
fecd2646 18931 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18932 /* Fallthrough */
fecd2646
LA
18933 case OPC_BLTZ:
18934 case OPC_BGEZ:
b231c103 18935 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18936 break;
fecd2646
LA
18937 case OPC_BLTZAL:
18938 case OPC_BGEZAL:
0aefa333
YK
18939 if (ctx->insn_flags & ISA_MIPS32R6) {
18940 if (rs == 0) {
18941 /* OPC_NAL, OPC_BAL */
b231c103 18942 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 18943 } else {
9c708c7f 18944 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
18945 }
18946 } else {
b231c103 18947 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18948 }
c9602061 18949 break;
7a387fff
TS
18950 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18951 case OPC_TNEI:
d9224450 18952 check_insn(ctx, ISA_MIPS2);
fecd2646 18953 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18954 gen_trap(ctx, op1, rs, -1, imm);
18955 break;
18956 case OPC_SYNCI:
d75c135e 18957 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18958 /* Break the TB to be able to sync copied instructions
18959 immediately */
18960 ctx->bstate = BS_STOP;
6af0bf9c 18961 break;
e45a93e2
JL
18962 case OPC_BPOSGE32: /* MIPS DSP branch */
18963#if defined(TARGET_MIPS64)
18964 case OPC_BPOSGE64:
18965#endif
18966 check_dsp(ctx);
b231c103 18967 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18968 break;
d4ea6acd
LA
18969#if defined(TARGET_MIPS64)
18970 case OPC_DAHI:
18971 check_insn(ctx, ISA_MIPS32R6);
18972 check_mips_64(ctx);
18973 if (rs != 0) {
18974 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18975 }
d4ea6acd
LA
18976 break;
18977 case OPC_DATI:
18978 check_insn(ctx, ISA_MIPS32R6);
18979 check_mips_64(ctx);
18980 if (rs != 0) {
18981 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18982 }
d4ea6acd
LA
18983 break;
18984#endif
6af0bf9c 18985 default: /* Invalid */
923617a3 18986 MIPS_INVAL("regimm");
9c708c7f 18987 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
18988 break;
18989 }
18990 break;
7a387fff 18991 case OPC_CP0:
387a8fe5 18992 check_cp0_enabled(ctx);
7a387fff 18993 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18994 switch (op1) {
7a387fff
TS
18995 case OPC_MFC0:
18996 case OPC_MTC0:
ead9360e
TS
18997 case OPC_MFTR:
18998 case OPC_MTTR:
5204ea79
LA
18999 case OPC_MFHC0:
19000 case OPC_MTHC0:
d26bc211 19001#if defined(TARGET_MIPS64)
7a387fff
TS
19002 case OPC_DMFC0:
19003 case OPC_DMTC0:
19004#endif
f1aa6320 19005#ifndef CONFIG_USER_ONLY
932e71cd 19006 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19007#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19008 break;
19009 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19010#ifndef CONFIG_USER_ONLY
932e71cd 19011 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19012#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19013 break;
19014 case OPC_MFMC0:
8706c382 19015#ifndef CONFIG_USER_ONLY
932e71cd 19016 {
099e5b4d 19017 uint32_t op2;
35fbce2c 19018 TCGv t0 = tcg_temp_new();
6c5c1e20 19019
0eaef5aa 19020 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19021 switch (op2) {
19022 case OPC_DMT:
d75c135e 19023 check_insn(ctx, ASE_MT);
9ed5726c 19024 gen_helper_dmt(t0);
35fbce2c 19025 gen_store_gpr(t0, rt);
6c5c1e20
TS
19026 break;
19027 case OPC_EMT:
d75c135e 19028 check_insn(ctx, ASE_MT);
9ed5726c 19029 gen_helper_emt(t0);
35fbce2c 19030 gen_store_gpr(t0, rt);
da80682b 19031 break;
6c5c1e20 19032 case OPC_DVPE:
d75c135e 19033 check_insn(ctx, ASE_MT);
895c2d04 19034 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19035 gen_store_gpr(t0, rt);
6c5c1e20
TS
19036 break;
19037 case OPC_EVPE:
d75c135e 19038 check_insn(ctx, ASE_MT);
895c2d04 19039 gen_helper_evpe(t0, cpu_env);
35fbce2c 19040 gen_store_gpr(t0, rt);
6c5c1e20
TS
19041 break;
19042 case OPC_DI:
d75c135e 19043 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19044 save_cpu_state(ctx, 1);
895c2d04 19045 gen_helper_di(t0, cpu_env);
35fbce2c 19046 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19047 /* Stop translation as we may have switched
19048 the execution mode. */
6c5c1e20
TS
19049 ctx->bstate = BS_STOP;
19050 break;
19051 case OPC_EI:
d75c135e 19052 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19053 save_cpu_state(ctx, 1);
895c2d04 19054 gen_helper_ei(t0, cpu_env);
35fbce2c 19055 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19056 /* Stop translation as we may have switched
19057 the execution mode. */
6c5c1e20
TS
19058 ctx->bstate = BS_STOP;
19059 break;
19060 default: /* Invalid */
19061 MIPS_INVAL("mfmc0");
9c708c7f 19062 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19063 break;
19064 }
6c5c1e20 19065 tcg_temp_free(t0);
7a387fff 19066 }
0eaef5aa 19067#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19068 break;
7a387fff 19069 case OPC_RDPGPR:
d75c135e 19070 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19071 gen_load_srsgpr(rt, rd);
ead9360e 19072 break;
7a387fff 19073 case OPC_WRPGPR:
d75c135e 19074 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19075 gen_store_srsgpr(rt, rd);
38121543 19076 break;
6af0bf9c 19077 default:
923617a3 19078 MIPS_INVAL("cp0");
9c708c7f 19079 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19080 break;
19081 }
19082 break;
31837be3
YK
19083 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19084 if (ctx->insn_flags & ISA_MIPS32R6) {
19085 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19086 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19087 } else {
19088 /* OPC_ADDI */
19089 /* Arithmetic with immediate opcode */
19090 gen_arith_imm(ctx, op, rt, rs, imm);
19091 }
19092 break;
324d9e32 19093 case OPC_ADDIU:
d75c135e 19094 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19095 break;
324d9e32
AJ
19096 case OPC_SLTI: /* Set on less than with immediate opcode */
19097 case OPC_SLTIU:
d75c135e 19098 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19099 break;
19100 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19101 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19102 case OPC_ORI:
19103 case OPC_XORI:
d75c135e 19104 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19105 break;
7a387fff
TS
19106 case OPC_J ... OPC_JAL: /* Jump */
19107 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19108 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19109 break;
31837be3
YK
19110 /* Branch */
19111 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19112 if (ctx->insn_flags & ISA_MIPS32R6) {
19113 if (rt == 0) {
9c708c7f 19114 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19115 break;
19116 }
19117 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19118 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19119 } else {
19120 /* OPC_BLEZL */
b231c103 19121 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19122 }
19123 break;
19124 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19125 if (ctx->insn_flags & ISA_MIPS32R6) {
19126 if (rt == 0) {
9c708c7f 19127 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19128 break;
19129 }
19130 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19131 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19132 } else {
19133 /* OPC_BGTZL */
b231c103 19134 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19135 }
19136 break;
19137 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19138 if (rt == 0) {
19139 /* OPC_BLEZ */
b231c103 19140 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19141 } else {
19142 check_insn(ctx, ISA_MIPS32R6);
19143 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19144 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19145 }
19146 break;
19147 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19148 if (rt == 0) {
19149 /* OPC_BGTZ */
b231c103 19150 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19151 } else {
19152 check_insn(ctx, ISA_MIPS32R6);
19153 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19154 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19155 }
19156 break;
19157 case OPC_BEQL:
19158 case OPC_BNEL:
d9224450 19159 check_insn(ctx, ISA_MIPS2);
fecd2646 19160 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19161 /* Fallthrough */
31837be3
YK
19162 case OPC_BEQ:
19163 case OPC_BNE:
b231c103 19164 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19165 break;
d9224450
MR
19166 case OPC_LL: /* Load and stores */
19167 check_insn(ctx, ISA_MIPS2);
19168 /* Fallthrough */
19169 case OPC_LWL:
fecd2646
LA
19170 case OPC_LWR:
19171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19172 /* Fallthrough */
fecd2646
LA
19173 case OPC_LB ... OPC_LH:
19174 case OPC_LW ... OPC_LHU:
d75c135e 19175 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19176 break;
fecd2646 19177 case OPC_SWL:
7a387fff 19178 case OPC_SWR:
fecd2646 19179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19180 /* fall through */
fecd2646
LA
19181 case OPC_SB ... OPC_SH:
19182 case OPC_SW:
5c13fdfd 19183 gen_st(ctx, op, rt, rs, imm);
7a387fff 19184 break;
d66c7132 19185 case OPC_SC:
d9224450 19186 check_insn(ctx, ISA_MIPS2);
4368b29a 19187 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19188 gen_st_cond(ctx, op, rt, rs, imm);
19189 break;
7a387fff 19190 case OPC_CACHE:
bf7910c6 19191 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19192 check_cp0_enabled(ctx);
d75c135e 19193 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 19194 /* Treat as NOP. */
34ae7b51 19195 break;
7a387fff 19196 case OPC_PREF:
bf7910c6 19197 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19198 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19199 /* Treat as NOP. */
6af0bf9c 19200 break;
4ad40f36 19201
923617a3 19202 /* Floating point (COP1). */
7a387fff
TS
19203 case OPC_LWC1:
19204 case OPC_LDC1:
19205 case OPC_SWC1:
19206 case OPC_SDC1:
5ab5c041 19207 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19208 break;
19209
7a387fff 19210 case OPC_CP1:
5692c6e1
YK
19211 op1 = MASK_CP1(ctx->opcode);
19212
19213 switch (op1) {
19214 case OPC_MFHC1:
19215 case OPC_MTHC1:
5e755519 19216 check_cp1_enabled(ctx);
5692c6e1
YK
19217 check_insn(ctx, ISA_MIPS32R2);
19218 case OPC_MFC1:
19219 case OPC_CFC1:
19220 case OPC_MTC1:
19221 case OPC_CTC1:
19222 check_cp1_enabled(ctx);
19223 gen_cp1(ctx, op1, rt, rd);
19224 break;
d26bc211 19225#if defined(TARGET_MIPS64)
5692c6e1
YK
19226 case OPC_DMFC1:
19227 case OPC_DMTC1:
19228 check_cp1_enabled(ctx);
19229 check_insn(ctx, ISA_MIPS3);
d9224450 19230 check_mips_64(ctx);
5692c6e1
YK
19231 gen_cp1(ctx, op1, rt, rd);
19232 break;
e189e748 19233#endif
5692c6e1
YK
19234 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19235 check_cp1_enabled(ctx);
19236 if (ctx->insn_flags & ISA_MIPS32R6) {
19237 /* OPC_BC1EQZ */
31837be3 19238 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19239 rt, imm << 2, 4);
5692c6e1
YK
19240 } else {
19241 /* OPC_BC1ANY2 */
b8aa4598 19242 check_cop1x(ctx);
d75c135e 19243 check_insn(ctx, ASE_MIPS3D);
d75c135e 19244 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19245 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19246 }
19247 break;
19248 case OPC_BC1NEZ:
19249 check_cp1_enabled(ctx);
19250 check_insn(ctx, ISA_MIPS32R6);
19251 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19252 rt, imm << 2, 4);
5692c6e1
YK
19253 break;
19254 case OPC_BC1ANY4:
19255 check_cp1_enabled(ctx);
19256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19257 check_cop1x(ctx);
19258 check_insn(ctx, ASE_MIPS3D);
19259 /* fall through */
19260 case OPC_BC1:
19261 check_cp1_enabled(ctx);
19262 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19263 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19264 (rt >> 2) & 0x7, imm << 2);
19265 break;
19266 case OPC_PS_FMT:
e29c9628 19267 check_ps(ctx);
b6f3b233 19268 /* fall through */
5692c6e1
YK
19269 case OPC_S_FMT:
19270 case OPC_D_FMT:
19271 check_cp1_enabled(ctx);
19272 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19273 (imm >> 8) & 0x7);
19274 break;
19275 case OPC_W_FMT:
19276 case OPC_L_FMT:
19277 {
19278 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19279 check_cp1_enabled(ctx);
19280 if (ctx->insn_flags & ISA_MIPS32R6) {
19281 switch (r6_op) {
19282 case R6_OPC_CMP_AF_S:
19283 case R6_OPC_CMP_UN_S:
19284 case R6_OPC_CMP_EQ_S:
19285 case R6_OPC_CMP_UEQ_S:
19286 case R6_OPC_CMP_LT_S:
19287 case R6_OPC_CMP_ULT_S:
19288 case R6_OPC_CMP_LE_S:
19289 case R6_OPC_CMP_ULE_S:
19290 case R6_OPC_CMP_SAF_S:
19291 case R6_OPC_CMP_SUN_S:
19292 case R6_OPC_CMP_SEQ_S:
19293 case R6_OPC_CMP_SEUQ_S:
19294 case R6_OPC_CMP_SLT_S:
19295 case R6_OPC_CMP_SULT_S:
19296 case R6_OPC_CMP_SLE_S:
19297 case R6_OPC_CMP_SULE_S:
19298 case R6_OPC_CMP_OR_S:
19299 case R6_OPC_CMP_UNE_S:
19300 case R6_OPC_CMP_NE_S:
19301 case R6_OPC_CMP_SOR_S:
19302 case R6_OPC_CMP_SUNE_S:
19303 case R6_OPC_CMP_SNE_S:
19304 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19305 break;
19306 case R6_OPC_CMP_AF_D:
19307 case R6_OPC_CMP_UN_D:
19308 case R6_OPC_CMP_EQ_D:
19309 case R6_OPC_CMP_UEQ_D:
19310 case R6_OPC_CMP_LT_D:
19311 case R6_OPC_CMP_ULT_D:
19312 case R6_OPC_CMP_LE_D:
19313 case R6_OPC_CMP_ULE_D:
19314 case R6_OPC_CMP_SAF_D:
19315 case R6_OPC_CMP_SUN_D:
19316 case R6_OPC_CMP_SEQ_D:
19317 case R6_OPC_CMP_SEUQ_D:
19318 case R6_OPC_CMP_SLT_D:
19319 case R6_OPC_CMP_SULT_D:
19320 case R6_OPC_CMP_SLE_D:
19321 case R6_OPC_CMP_SULE_D:
19322 case R6_OPC_CMP_OR_D:
19323 case R6_OPC_CMP_UNE_D:
19324 case R6_OPC_CMP_NE_D:
19325 case R6_OPC_CMP_SOR_D:
19326 case R6_OPC_CMP_SUNE_D:
19327 case R6_OPC_CMP_SNE_D:
19328 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19329 break;
19330 default:
d2bfa6e6
MR
19331 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19332 rt, rd, sa, (imm >> 8) & 0x7);
19333
5692c6e1 19334 break;
3f493883 19335 }
5692c6e1
YK
19336 } else {
19337 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19338 (imm >> 8) & 0x7);
36d23958 19339 }
5692c6e1
YK
19340 break;
19341 }
19342 case OPC_BZ_V:
19343 case OPC_BNZ_V:
19344 case OPC_BZ_B:
19345 case OPC_BZ_H:
19346 case OPC_BZ_W:
19347 case OPC_BZ_D:
19348 case OPC_BNZ_B:
19349 case OPC_BNZ_H:
19350 case OPC_BNZ_W:
19351 case OPC_BNZ_D:
19352 check_insn(ctx, ASE_MSA);
19353 gen_msa_branch(env, ctx, op1);
19354 break;
19355 default:
19356 MIPS_INVAL("cp1");
9c708c7f 19357 generate_exception_end(ctx, EXCP_RI);
5692c6e1 19358 break;
6ea83fed 19359 }
4ad40f36
FB
19360 break;
19361
31837be3
YK
19362 /* Compact branches [R6] and COP2 [non-R6] */
19363 case OPC_BC: /* OPC_LWC2 */
19364 case OPC_BALC: /* OPC_SWC2 */
19365 if (ctx->insn_flags & ISA_MIPS32R6) {
19366 /* OPC_BC, OPC_BALC */
19367 gen_compute_compact_branch(ctx, op, 0, 0,
19368 sextract32(ctx->opcode << 2, 0, 28));
19369 } else {
19370 /* OPC_LWC2, OPC_SWC2 */
19371 /* COP2: Not implemented. */
19372 generate_exception_err(ctx, EXCP_CpU, 2);
19373 }
19374 break;
19375 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19376 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19377 if (ctx->insn_flags & ISA_MIPS32R6) {
19378 if (rs != 0) {
19379 /* OPC_BEQZC, OPC_BNEZC */
19380 gen_compute_compact_branch(ctx, op, rs, 0,
19381 sextract32(ctx->opcode << 2, 0, 23));
19382 } else {
19383 /* OPC_JIC, OPC_JIALC */
19384 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19385 }
19386 } else {
19387 /* OPC_LWC2, OPC_SWC2 */
19388 /* COP2: Not implemented. */
19389 generate_exception_err(ctx, EXCP_CpU, 2);
19390 }
4ad40f36 19391 break;
bd277fa1 19392 case OPC_CP2:
d75c135e 19393 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19394 /* Note that these instructions use different fields. */
19395 gen_loongson_multimedia(ctx, sa, rd, rt);
19396 break;
4ad40f36 19397
7a387fff 19398 case OPC_CP3:
fecd2646 19399 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19400 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19401 check_cp1_enabled(ctx);
36d23958
TS
19402 op1 = MASK_CP3(ctx->opcode);
19403 switch (op1) {
d9224450
MR
19404 case OPC_LUXC1:
19405 case OPC_SUXC1:
19406 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19407 /* Fallthrough */
5a5012ec
TS
19408 case OPC_LWXC1:
19409 case OPC_LDXC1:
5a5012ec
TS
19410 case OPC_SWXC1:
19411 case OPC_SDXC1:
d9224450 19412 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19413 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19414 break;
e0c84da7 19415 case OPC_PREFX:
d9224450 19416 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19417 /* Treat as NOP. */
e0c84da7 19418 break;
5a5012ec 19419 case OPC_ALNV_PS:
d9224450
MR
19420 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19421 /* Fallthrough */
5a5012ec
TS
19422 case OPC_MADD_S:
19423 case OPC_MADD_D:
19424 case OPC_MADD_PS:
19425 case OPC_MSUB_S:
19426 case OPC_MSUB_D:
19427 case OPC_MSUB_PS:
19428 case OPC_NMADD_S:
19429 case OPC_NMADD_D:
19430 case OPC_NMADD_PS:
19431 case OPC_NMSUB_S:
19432 case OPC_NMSUB_D:
19433 case OPC_NMSUB_PS:
d9224450 19434 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19435 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19436 break;
36d23958 19437 default:
923617a3 19438 MIPS_INVAL("cp3");
9c708c7f 19439 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
19440 break;
19441 }
19442 } else {
e397ee33 19443 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19444 }
4ad40f36
FB
19445 break;
19446
d26bc211 19447#if defined(TARGET_MIPS64)
7a387fff 19448 /* MIPS64 opcodes */
7a387fff 19449 case OPC_LDL ... OPC_LDR:
bf7910c6 19450 case OPC_LLD:
fecd2646 19451 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19452 /* fall through */
fecd2646 19453 case OPC_LWU:
7a387fff 19454 case OPC_LD:
d75c135e 19455 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19456 check_mips_64(ctx);
d75c135e 19457 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19458 break;
19459 case OPC_SDL ... OPC_SDR:
fecd2646 19460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19461 /* fall through */
7a387fff 19462 case OPC_SD:
d75c135e 19463 check_insn(ctx, ISA_MIPS3);
e189e748 19464 check_mips_64(ctx);
5c13fdfd 19465 gen_st(ctx, op, rt, rs, imm);
7a387fff 19466 break;
d66c7132 19467 case OPC_SCD:
bf7910c6 19468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19469 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19470 check_mips_64(ctx);
19471 gen_st_cond(ctx, op, rt, rs, imm);
19472 break;
31837be3
YK
19473 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19474 if (ctx->insn_flags & ISA_MIPS32R6) {
19475 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19476 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19477 } else {
19478 /* OPC_DADDI */
19479 check_insn(ctx, ISA_MIPS3);
19480 check_mips_64(ctx);
19481 gen_arith_imm(ctx, op, rt, rs, imm);
19482 }
19483 break;
324d9e32 19484 case OPC_DADDIU:
d75c135e 19485 check_insn(ctx, ISA_MIPS3);
e189e748 19486 check_mips_64(ctx);
d75c135e 19487 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19488 break;
31837be3
YK
19489#else
19490 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19491 if (ctx->insn_flags & ISA_MIPS32R6) {
19492 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19493 } else {
19494 MIPS_INVAL("major opcode");
9c708c7f 19495 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19496 }
19497 break;
6af0bf9c 19498#endif
d4ea6acd
LA
19499 case OPC_DAUI: /* OPC_JALX */
19500 if (ctx->insn_flags & ISA_MIPS32R6) {
19501#if defined(TARGET_MIPS64)
19502 /* OPC_DAUI */
19503 check_mips_64(ctx);
db77d852
LA
19504 if (rs == 0) {
19505 generate_exception(ctx, EXCP_RI);
19506 } else if (rt != 0) {
d4ea6acd
LA
19507 TCGv t0 = tcg_temp_new();
19508 gen_load_gpr(t0, rs);
19509 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19510 tcg_temp_free(t0);
19511 }
d4ea6acd 19512#else
9c708c7f 19513 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
19514 MIPS_INVAL("major opcode");
19515#endif
19516 } else {
19517 /* OPC_JALX */
19518 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19519 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19520 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19521 }
364d4831 19522 break;
4c789546 19523 case OPC_MSA: /* OPC_MDMX */
7a387fff 19524 /* MDMX: Not implemented. */
4c789546 19525 gen_msa(env, ctx);
d4ea6acd
LA
19526 break;
19527 case OPC_PCREL:
19528 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19529 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19530 break;
6af0bf9c 19531 default: /* Invalid */
923617a3 19532 MIPS_INVAL("major opcode");
9c708c7f 19533 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19534 break;
19535 }
6af0bf9c
FB
19536}
19537
2cfc5f17 19538static inline void
6429db34
AF
19539gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19540 bool search_pc)
6af0bf9c 19541{
ed2803da 19542 CPUState *cs = CPU(cpu);
6429db34 19543 CPUMIPSState *env = &cpu->env;
278d0702 19544 DisasContext ctx;
6af0bf9c 19545 target_ulong pc_start;
fe237291 19546 target_ulong next_page_start;
a1d1bb31 19547 CPUBreakpoint *bp;
6af0bf9c 19548 int j, lj = -1;
2e70f6ef
PB
19549 int num_insns;
19550 int max_insns;
c9602061 19551 int insn_bytes;
339cd2a8 19552 int is_slot;
6af0bf9c 19553
93fcfe39
AL
19554 if (search_pc)
19555 qemu_log("search pc %d\n", search_pc);
4ad40f36 19556
6af0bf9c 19557 pc_start = tb->pc;
fe237291 19558 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19559 ctx.pc = pc_start;
4ad40f36 19560 ctx.saved_pc = -1;
ed2803da 19561 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19562 ctx.insn_flags = env->insn_flags;
5ab5c041 19563 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19564 ctx.tb = tb;
19565 ctx.bstate = BS_NONE;
e98c0d17 19566 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19567 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19568 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19569 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19570 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19571 ctx.PAMask = env->PAMask;
19572 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19573 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
4ad40f36 19574 /* Restore delay slot state from the tb context. */
c068688b 19575 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19576 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19577 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19578 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
fd4a04eb 19579 restore_cpu_state(env, &ctx);
932e71cd 19580#ifdef CONFIG_USER_ONLY
0eaef5aa 19581 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19582#else
0eaef5aa 19583 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19584#endif
be3a8c53
YK
19585 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19586 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19587 num_insns = 0;
19588 max_insns = tb->cflags & CF_COUNT_MASK;
19589 if (max_insns == 0)
19590 max_insns = CF_COUNT_MASK;
d12d51d5 19591 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19592 gen_tb_start(tb);
faf7aaa9 19593 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19594 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19595 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19596 if (bp->pc == ctx.pc) {
278d0702 19597 save_cpu_state(&ctx, 1);
4ad40f36 19598 ctx.bstate = BS_BRANCH;
9c708c7f 19599 gen_helper_raise_exception_debug(cpu_env);
ce62e5ba
TS
19600 /* Include the breakpoint location or the tb won't
19601 * be flushed when it must be. */
19602 ctx.pc += 4;
4ad40f36
FB
19603 goto done_generating;
19604 }
19605 }
19606 }
19607
6af0bf9c 19608 if (search_pc) {
fe700adb 19609 j = tcg_op_buf_count();
6af0bf9c
FB
19610 if (lj < j) {
19611 lj++;
19612 while (lj < j)
ab1103de 19613 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19614 }
25983cad 19615 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19616 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19617 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19618 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19619 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19620 }
667b8e29
RH
19621 tcg_gen_insn_start(ctx.pc);
19622
19623 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 19624 gen_io_start();
667b8e29 19625 }
c9602061 19626
339cd2a8 19627 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19628 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19629 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19630 insn_bytes = 4;
240ce26a 19631 decode_opc(env, &ctx);
d75c135e 19632 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19633 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19634 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19635 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19636 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19637 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 19638 } else {
9c708c7f 19639 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
19640 break;
19641 }
31837be3 19642
b231c103 19643 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19644 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19645 MIPS_HFLAG_FBNSLOT))) {
19646 /* force to generate branch as there is neither delay nor
19647 forbidden slot */
19648 is_slot = 1;
b231c103 19649 }
65935f07
YK
19650 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19651 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19652 /* Force to generate branch as microMIPS R6 doesn't restrict
19653 branches in the forbidden slot. */
19654 is_slot = 1;
19655 }
b231c103 19656 }
339cd2a8 19657 if (is_slot) {
31837be3 19658 gen_branch(&ctx, insn_bytes);
c9602061
NF
19659 }
19660 ctx.pc += insn_bytes;
19661
2e70f6ef 19662 num_insns++;
4ad40f36 19663
7b270ef2
NF
19664 /* Execute a branch and its delay slot as a single instruction.
19665 This is what GDB expects and is consistent with what the
19666 hardware does (e.g. if a delay slot instruction faults, the
19667 reported PC is the PC of the branch). */
ed2803da 19668 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19669 break;
ed2803da 19670 }
4ad40f36 19671
fe237291 19672 if (ctx.pc >= next_page_start) {
6af0bf9c 19673 break;
fe237291 19674 }
4ad40f36 19675
fe700adb 19676 if (tcg_op_buf_full()) {
faf7aaa9 19677 break;
efd7f486 19678 }
faf7aaa9 19679
2e70f6ef
PB
19680 if (num_insns >= max_insns)
19681 break;
1b530a6d
AJ
19682
19683 if (singlestep)
19684 break;
6af0bf9c 19685 }
ed2803da 19686 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19687 gen_io_end();
ed2803da
AF
19688 }
19689 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19690 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 19691 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 19692 } else {
6958549d 19693 switch (ctx.bstate) {
16c00cb2 19694 case BS_STOP:
df1561e2
TS
19695 gen_goto_tb(&ctx, 0, ctx.pc);
19696 break;
16c00cb2 19697 case BS_NONE:
278d0702 19698 save_cpu_state(&ctx, 0);
16c00cb2
TS
19699 gen_goto_tb(&ctx, 0, ctx.pc);
19700 break;
5a5012ec 19701 case BS_EXCP:
57fec1fe 19702 tcg_gen_exit_tb(0);
16c00cb2 19703 break;
5a5012ec
TS
19704 case BS_BRANCH:
19705 default:
19706 break;
6958549d 19707 }
6af0bf9c 19708 }
4ad40f36 19709done_generating:
806f352d 19710 gen_tb_end(tb, num_insns);
0a7df5da 19711
6af0bf9c 19712 if (search_pc) {
fe700adb 19713 j = tcg_op_buf_count();
6af0bf9c
FB
19714 lj++;
19715 while (lj <= j)
ab1103de 19716 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19717 } else {
19718 tb->size = ctx.pc - pc_start;
2e70f6ef 19719 tb->icount = num_insns;
6af0bf9c
FB
19720 }
19721#ifdef DEBUG_DISAS
d12d51d5 19722 LOG_DISAS("\n");
8fec2b8c 19723 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19724 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 19725 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19726 qemu_log("\n");
6af0bf9c
FB
19727 }
19728#endif
6af0bf9c
FB
19729}
19730
7db13fae 19731void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19732{
6429db34 19733 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19734}
19735
7db13fae 19736void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19737{
6429db34 19738 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19739}
19740
7db13fae 19741static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19742 int flags)
6ea83fed
FB
19743{
19744 int i;
5e755519 19745 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19746
2a5612e6
SW
19747#define printfpr(fp) \
19748 do { \
19749 if (is_fpu64) \
19750 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19751 " fd:%13g fs:%13g psu: %13g\n", \
19752 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19753 (double)(fp)->fd, \
19754 (double)(fp)->fs[FP_ENDIAN_IDX], \
19755 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19756 else { \
19757 fpr_t tmp; \
19758 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19759 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19760 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19761 " fd:%13g fs:%13g psu:%13g\n", \
19762 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19763 (double)tmp.fd, \
19764 (double)tmp.fs[FP_ENDIAN_IDX], \
19765 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19766 } \
6ea83fed
FB
19767 } while(0)
19768
5a5012ec 19769
9a78eead
SW
19770 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19771 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19772 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19773 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19774 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19775 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19776 }
19777
19778#undef printfpr
19779}
19780
878096ee
AF
19781void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19782 int flags)
6af0bf9c 19783{
878096ee
AF
19784 MIPSCPU *cpu = MIPS_CPU(cs);
19785 CPUMIPSState *env = &cpu->env;
6af0bf9c 19786 int i;
3b46e624 19787
a7200c9f
SW
19788 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19789 " LO=0x" TARGET_FMT_lx " ds %04x "
19790 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19791 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19792 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19793 for (i = 0; i < 32; i++) {
19794 if ((i & 3) == 0)
19795 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19796 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19797 if ((i & 3) == 3)
19798 cpu_fprintf(f, "\n");
19799 }
568b600d 19800
3594c774 19801 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19802 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
19803 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19804 PRIx64 "\n",
5499b6ff 19805 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19806 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19807 env->CP0_Config2, env->CP0_Config3);
19808 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19809 env->CP0_Config4, env->CP0_Config5);
5e755519 19810 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19811 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
19812}
19813
78ce64f4 19814void mips_tcg_init(void)
39454628 19815{
f01be154 19816 int i;
39454628
TS
19817 static int inited;
19818
19819 /* Initialize various static tables. */
19820 if (inited)
6958549d 19821 return;
39454628 19822
a7812ae4 19823 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19824 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19825 for (i = 1; i < 32; i++)
a7812ae4 19826 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19827 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19828 regnames[i]);
d73ee8a2 19829
863f264d
YK
19830 for (i = 0; i < 32; i++) {
19831 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19832 msa_wr_d[i * 2] =
19833 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19834 /* The scalar floating-point unit (FPU) registers are mapped on
19835 * the MSA vector registers. */
19836 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19837 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19838 msa_wr_d[i * 2 + 1] =
19839 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19840 }
19841
a7812ae4 19842 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19843 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19844 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19845 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19846 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19847 regnames_HI[i]);
a7812ae4 19848 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19849 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19850 regnames_LO[i]);
4b2eb8d2 19851 }
a7812ae4 19852 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19853 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19854 "DSPControl");
1ba74fb8 19855 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19856 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19857 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19858 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19859 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19860 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19861
a7812ae4 19862 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19863 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19864 "fcr0");
19865 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19866 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19867 "fcr31");
39454628
TS
19868
19869 inited = 1;
19870}
19871
aaed909a
FB
19872#include "translate_init.c"
19873
30bf942d 19874MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19875{
0f71a709 19876 MIPSCPU *cpu;
6af0bf9c 19877 CPUMIPSState *env;
c227f099 19878 const mips_def_t *def;
6af0bf9c 19879
aaed909a
FB
19880 def = cpu_mips_find_by_name(cpu_model);
19881 if (!def)
19882 return NULL;
0f71a709
AF
19883 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19884 env = &cpu->env;
aaed909a
FB
19885 env->cpu_model = def;
19886
51cc2e78
BS
19887#ifndef CONFIG_USER_ONLY
19888 mmu_init(env, def);
19889#endif
19890 fpu_init(env, def);
19891 mvp_init(env, def);
c1caf1d9
AF
19892
19893 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19894
30bf942d 19895 return cpu;
6ae81775
TS
19896}
19897
1bba0dc9 19898void cpu_state_reset(CPUMIPSState *env)
6ae81775 19899{
55e5c285
AF
19900 MIPSCPU *cpu = mips_env_get_cpu(env);
19901 CPUState *cs = CPU(cpu);
6ae81775 19902
51cc2e78
BS
19903 /* Reset registers to their default values */
19904 env->CP0_PRid = env->cpu_model->CP0_PRid;
19905 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19906#ifdef TARGET_WORDS_BIGENDIAN
19907 env->CP0_Config0 |= (1 << CP0C0_BE);
19908#endif
19909 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19910 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19911 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19912 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19913 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19914 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19915 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19916 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19917 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19918 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19919 << env->cpu_model->CP0_LLAddr_shift;
19920 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19921 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19922 env->CCRes = env->cpu_model->CCRes;
19923 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19924 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19925 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19926 env->current_tc = 0;
19927 env->SEGBITS = env->cpu_model->SEGBITS;
19928 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19929#if defined(TARGET_MIPS64)
19930 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19931 env->SEGMask |= 3ULL << 62;
19932 }
19933#endif
19934 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
19935 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19936 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19937 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19938 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19939 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19940 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19941 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19942 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19943 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19944 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19945 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19946 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19947 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19948 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19949 env->insn_flags = env->cpu_model->insn_flags;
19950
0eaef5aa 19951#if defined(CONFIG_USER_ONLY)
03e6e501 19952 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19953# ifdef TARGET_MIPS64
19954 /* Enable 64-bit register mode. */
19955 env->CP0_Status |= (1 << CP0St_PX);
19956# endif
19957# ifdef TARGET_ABI_MIPSN64
19958 /* Enable 64-bit address mode. */
19959 env->CP0_Status |= (1 << CP0St_UX);
19960# endif
94159135
MI
19961 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19962 hardware registers. */
19963 env->CP0_HWREna |= 0x0000000F;
91a75935 19964 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19965 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19966 }
6f0af304
PJ
19967 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19968 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19969 }
4d66261f
PJ
19970# if defined(TARGET_MIPS64)
19971 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19972 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19973 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19974 env->CP0_Status |= (1 << CP0St_FR);
19975 }
4d66261f 19976# endif
932e71cd
AJ
19977#else
19978 if (env->hflags & MIPS_HFLAG_BMASK) {
19979 /* If the exception was raised from a delay slot,
19980 come back to the jump. */
c3577479
MR
19981 env->CP0_ErrorEPC = (env->active_tc.PC
19982 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 19983 } else {
932e71cd
AJ
19984 env->CP0_ErrorEPC = env->active_tc.PC;
19985 }
19986 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19987 env->CP0_Random = env->tlb->nb_tlb - 1;
19988 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19989 env->CP0_Wired = 0;
0a2672b7
JH
19990 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19991 if (kvm_enabled()) {
19992 env->CP0_EBase |= 0x40000000;
19993 } else {
19994 env->CP0_EBase |= 0x80000000;
19995 }
932e71cd
AJ
19996 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19997 /* vectored interrupts not implemented, timer on int 7,
19998 no performance counters. */
19999 env->CP0_IntCtl = 0xe0000000;
20000 {
20001 int i;
20002
20003 for (i = 0; i < 7; i++) {
20004 env->CP0_WatchLo[i] = 0;
20005 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20006 }
932e71cd
AJ
20007 env->CP0_WatchLo[7] = 0;
20008 env->CP0_WatchHi[7] = 0;
fd88b6ab 20009 }
932e71cd
AJ
20010 /* Count register increments in debug mode, EJTAG version 1 */
20011 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20012
4b69c7e2
JH
20013 cpu_mips_store_count(env, 1);
20014
9e56e756
EI
20015 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20016 int i;
20017
20018 /* Only TC0 on VPE 0 starts as active. */
20019 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20020 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20021 env->tcs[i].CP0_TCHalt = 1;
20022 }
20023 env->active_tc.CP0_TCHalt = 1;
259186a7 20024 cs->halted = 1;
9e56e756 20025
55e5c285 20026 if (cs->cpu_index == 0) {
9e56e756
EI
20027 /* VPE0 starts up enabled. */
20028 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20029 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20030
20031 /* TC0 starts up unhalted. */
259186a7 20032 cs->halted = 0;
9e56e756
EI
20033 env->active_tc.CP0_TCHalt = 0;
20034 env->tcs[0].CP0_TCHalt = 0;
20035 /* With thread 0 active. */
20036 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20037 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20038 }
20039 }
51cc2e78 20040#endif
ddc584bd
LA
20041 if ((env->insn_flags & ISA_MIPS32R6) &&
20042 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20043 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20044 env->CP0_Status |= (1 << CP0St_FR);
20045 }
20046
863f264d
YK
20047 /* MSA */
20048 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20049 msa_reset(env);
20050 }
20051
03e6e501 20052 compute_hflags(env);
bb962386
MR
20053 restore_rounding_mode(env);
20054 restore_flush_mode(env);
e117f526 20055 restore_pamask(env);
27103424 20056 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20057
20058 if (semihosting_get_argc()) {
20059 /* UHI interface can be used to obtain argc and argv */
20060 env->active_tc.gpr[4] = -1;
20061 }
6af0bf9c 20062}
d2856f1a 20063
7db13fae 20064void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 20065{
25983cad 20066 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
20067 env->hflags &= ~MIPS_HFLAG_BMASK;
20068 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
20069 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20070 case MIPS_HFLAG_BR:
20071 break;
20072 case MIPS_HFLAG_BC:
20073 case MIPS_HFLAG_BL:
20074 case MIPS_HFLAG_B:
20075 env->btarget = gen_opc_btarget[pc_pos];
20076 break;
20077 }
d2856f1a 20078}
This page took 4.466868 seconds and 4 git commands to generate.